summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--blastem.c63
-rw-r--r--genesis.c91
-rw-r--r--genesis.h2
-rw-r--r--psg.c2
-rw-r--r--render.h2
-rw-r--r--saves.h1
-rw-r--r--serialize.c9
-rw-r--r--system.c21
-rw-r--r--system.h6
-rw-r--r--vdp.c99
-rw-r--r--vdp.h1
-rw-r--r--ym2612.c3
13 files changed, 241 insertions, 63 deletions
diff --git a/Makefile b/Makefile
index 7794c9d..1fcc94e 100644
--- a/Makefile
+++ b/Makefile
@@ -195,7 +195,7 @@ TRANSOBJS+= gen_x86.o backend_x86.o
endif
endif
endif
-AUDIOOBJS=ym2612.o psg.o wave.o vgm.o render_audio.o
+AUDIOOBJS=ym2612.o psg.o wave.o vgm.o event_log.o render_audio.o
CONFIGOBJS=config.o tern.o util.o paths.o
NUKLEAROBJS=$(FONT) nuklear_ui/blastem_nuklear.o nuklear_ui/sfnt.o
RENDEROBJS=ppm.o controller_info.o
@@ -213,7 +213,7 @@ endif
MAINOBJS=blastem.o system.o genesis.o debug.o gdb_remote.o vdp.o $(RENDEROBJS) io.o romdb.o hash.o menu.o xband.o \
realtec.o i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
- $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o jcart.o
+ $(M68KOBJS) $(TRANSOBJS) $(AUDIOOBJS) saves.o zip.o bindings.o jcart.o gen_player.o
LIBOBJS=libblastem.o system.o genesis.o debug.o gdb_remote.o vdp.o io.o romdb.o hash.o xband.o realtec.o \
i2c.o nor.o sega_mapper.o multi_game.o megawifi.o $(NET) serialize.o $(TERMINAL) $(CONFIGOBJS) gst.o \
diff --git a/blastem.c b/blastem.c
index e06163f..8939f94 100644
--- a/blastem.c
+++ b/blastem.c
@@ -30,6 +30,7 @@
#include "bindings.h"
#include "menu.h"
#include "zip.h"
+#include "event_log.h"
#ifndef DISABLE_NUKLEAR
#include "nuklear_ui/blastem_nuklear.h"
#endif
@@ -430,6 +431,23 @@ void init_system_with_media(const char *path, system_type force_stype)
update_title(game_system->info.name);
}
+char *parse_addr_port(char *arg)
+{
+ while (*arg && *arg != ':') {
+ ++arg;
+ }
+ if (!*arg) {
+ return NULL;
+ }
+ char *end;
+ int port = strtol(arg + 1, &end, 10);
+ if (port && !*end) {
+ *arg = 0;
+ return arg + 1;
+ }
+ return NULL;
+}
+
int main(int argc, char ** argv)
{
set_exe_str(argv[0]);
@@ -441,10 +459,12 @@ int main(int argc, char ** argv)
system_type stype = SYSTEM_UNKNOWN, force_stype = SYSTEM_UNKNOWN;
char * romfname = NULL;
char * statefile = NULL;
+ event_reader reader = {0};
debugger_type dtype = DEBUGGER_NATIVE;
uint8_t start_in_debugger = 0;
uint8_t fullscreen = FULLSCREEN_DEFAULT, use_gl = 1;
uint8_t debug_target = 0;
+ char *port;
for (int i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch(argv[i][1]) {
@@ -468,6 +488,18 @@ int main(int argc, char ** argv)
dtype = DEBUGGER_GDB;
start_in_debugger = 1;
break;
+ case 'e':
+ i++;
+ if (i >= argc) {
+ fatal_error("-e must be followed by a file name\n");
+ }
+ port = parse_addr_port(argv[i]);
+ if (port) {
+ event_log_tcp(argv[i], port);
+ } else {
+ event_log_file(argv[i]);
+ }
+ break;
case 'f':
fullscreen = !fullscreen;
break;
@@ -555,18 +587,24 @@ int main(int argc, char ** argv)
" -v Display version number and exit\n"
" -l Log 68K code addresses (useful for assemblers)\n"
" -y Log individual YM-2612 channels to WAVE files\n"
+ " -e FILE Write hardware event log to FILE\n"
);
return 0;
default:
fatal_error("Unrecognized switch %s\n", argv[i]);
}
} else if (!loaded) {
- if (!(cart.size = load_rom(argv[i], &cart.buffer, stype == SYSTEM_UNKNOWN ? &stype : NULL))) {
- fatal_error("Failed to open %s for reading\n", argv[i]);
+ char *port = parse_addr_port(argv[i]);
+ if (port) {
+ init_event_reader_tcp(&reader, argv[i], port);
+ } else {
+ if (!(cart.size = load_rom(argv[i], &cart.buffer, stype == SYSTEM_UNKNOWN ? &stype : NULL))) {
+ fatal_error("Failed to open %s for reading\n", argv[i]);
+ }
+ cart.dir = path_dirname(argv[i]);
+ cart.name = basename_no_extension(argv[i]);
+ cart.extension = path_extension(argv[i]);
}
- cart.dir = path_dirname(argv[i]);
- cart.name = basename_no_extension(argv[i]);
- cart.extension = path_extension(argv[i]);
romfname = argv[i];
loaded = 1;
} else if (width < 0) {
@@ -645,13 +683,22 @@ int main(int argc, char ** argv)
}
if (loaded) {
- if (stype == SYSTEM_UNKNOWN) {
- stype = detect_system_type(&cart);
+ if (stype == SYSTEM_UNKNOWN || reader.socket) {
+ if (reader.socket) {
+ stype = reader_system_type(&reader);
+ } else {
+ stype = detect_system_type(&cart);
+ }
}
if (stype == SYSTEM_UNKNOWN) {
fatal_error("Failed to detect system type for %s\n", romfname);
}
- current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region);
+
+ if (reader.socket) {
+ current_system = alloc_config_player(stype, &reader);
+ } else {
+ current_system = alloc_config_system(stype, &cart, menu ? 0 : opts, force_region);
+ }
if (!current_system) {
fatal_error("Failed to configure emulated machine for %s\n", romfname);
}
diff --git a/genesis.c b/genesis.c
index 20eb5b1..2942b74 100644
--- a/genesis.c
+++ b/genesis.c
@@ -19,6 +19,7 @@
#include "bindings.h"
#include "jcart.h"
#include "config.h"
+#include "event_log.h"
#define MCLKS_NTSC 53693175
#define MCLKS_PAL 53203395
@@ -49,15 +50,17 @@ uint32_t MCLKS_PER_68K;
#define Z80_OPTS options
#endif
-void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc)
+void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc, uint8_t all)
{
- start_section(buf, SECTION_68000);
- m68k_serialize(gen->m68k, m68k_pc, buf);
- end_section(buf);
-
- start_section(buf, SECTION_Z80);
- z80_serialize(gen->z80, buf);
- end_section(buf);
+ if (all) {
+ start_section(buf, SECTION_68000);
+ m68k_serialize(gen->m68k, m68k_pc, buf);
+ end_section(buf);
+
+ start_section(buf, SECTION_Z80);
+ z80_serialize(gen->z80, buf);
+ end_section(buf);
+ }
start_section(buf, SECTION_VDP);
vdp_serialize(gen->vdp, buf);
@@ -71,35 +74,37 @@ void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68
psg_serialize(gen->psg, buf);
end_section(buf);
- start_section(buf, SECTION_GEN_BUS_ARBITER);
- save_int8(buf, gen->z80->reset);
- save_int8(buf, gen->z80->busreq);
- save_int16(buf, gen->z80_bank_reg);
- end_section(buf);
-
- start_section(buf, SECTION_SEGA_IO_1);
- io_serialize(gen->io.ports, buf);
- end_section(buf);
-
- start_section(buf, SECTION_SEGA_IO_2);
- io_serialize(gen->io.ports + 1, buf);
- end_section(buf);
-
- start_section(buf, SECTION_SEGA_IO_EXT);
- io_serialize(gen->io.ports + 2, buf);
- end_section(buf);
-
- start_section(buf, SECTION_MAIN_RAM);
- save_int8(buf, RAM_WORDS * 2 / 1024);
- save_buffer16(buf, gen->work_ram, RAM_WORDS);
- end_section(buf);
-
- start_section(buf, SECTION_SOUND_RAM);
- save_int8(buf, Z80_RAM_BYTES / 1024);
- save_buffer8(buf, gen->zram, Z80_RAM_BYTES);
- end_section(buf);
-
- cart_serialize(&gen->header, buf);
+ if (all) {
+ start_section(buf, SECTION_GEN_BUS_ARBITER);
+ save_int8(buf, gen->z80->reset);
+ save_int8(buf, gen->z80->busreq);
+ save_int16(buf, gen->z80_bank_reg);
+ end_section(buf);
+
+ start_section(buf, SECTION_SEGA_IO_1);
+ io_serialize(gen->io.ports, buf);
+ end_section(buf);
+
+ start_section(buf, SECTION_SEGA_IO_2);
+ io_serialize(gen->io.ports + 1, buf);
+ end_section(buf);
+
+ start_section(buf, SECTION_SEGA_IO_EXT);
+ io_serialize(gen->io.ports + 2, buf);
+ end_section(buf);
+
+ start_section(buf, SECTION_MAIN_RAM);
+ save_int8(buf, RAM_WORDS * 2 / 1024);
+ save_buffer16(buf, gen->work_ram, RAM_WORDS);
+ end_section(buf);
+
+ start_section(buf, SECTION_SOUND_RAM);
+ save_int8(buf, Z80_RAM_BYTES / 1024);
+ save_buffer8(buf, gen->zram, Z80_RAM_BYTES);
+ end_section(buf);
+
+ cart_serialize(&gen->header, buf);
+ }
}
static uint8_t *serialize(system_header *sys, size_t *size_out)
@@ -119,7 +124,7 @@ static uint8_t *serialize(system_header *sys, size_t *size_out)
init_serialize(&state);
uint32_t address = read_word(4, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k) << 16;
address |= read_word(6, (void **)gen->m68k->mem_pointers, &gen->m68k->options->gen, gen->m68k);
- genesis_serialize(gen, &state, address);
+ genesis_serialize(gen, &state, address, 1);
if (size_out) {
*size_out = state.size;
}
@@ -411,6 +416,7 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
if (gen->reset_cycle != CYCLE_NEVER) {
gen->reset_cycle -= deduction;
}
+ event_cycle_adjust(mclks, deduction);
}
}
gen->frame_end = vdp_cycles_to_frame_end(v_context);
@@ -449,16 +455,18 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
}
}
#endif
- char *save_path = slot == SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
- if (use_native_states || slot == SERIALIZE_SLOT) {
+ char *save_path = slot >= SERIALIZE_SLOT ? NULL : get_slot_name(&gen->header, slot, use_native_states ? "state" : "gst");
+ if (use_native_states || slot >= SERIALIZE_SLOT) {
serialize_buffer state;
init_serialize(&state);
- genesis_serialize(gen, &state, address);
+ genesis_serialize(gen, &state, address, slot != EVENTLOG_SLOT);
if (slot == SERIALIZE_SLOT) {
gen->serialize_tmp = state.data;
gen->serialize_size = state.size;
context->sync_cycle = context->current_cycle;
context->should_return = 1;
+ } else if (slot == EVENTLOG_SLOT) {
+ event_state(context->current_cycle, &state);
} else {
save_to_file(&state, save_path);
free(state.data);
@@ -1533,6 +1541,7 @@ genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on
gen->int_latency_prev2 = MCLKS_PER_68K * 16;
render_set_video_standard((gen->version_reg & HZ50) ? VID_PAL : VID_NTSC);
+ event_system_start(SYSTEM_GENESIS, (gen->version_reg & HZ50) ? VID_PAL : VID_NTSC, rom->name);
gen->ym = malloc(sizeof(ym2612_context));
char *fm = tern_find_ptr_default(model, "fm", "discrete 2612");
diff --git a/genesis.h b/genesis.h
index a129ddc..9070cc6 100644
--- a/genesis.h
+++ b/genesis.h
@@ -71,7 +71,7 @@ struct genesis_context {
m68k_context * sync_components(m68k_context *context, uint32_t address);
genesis_context *alloc_config_genesis(void *rom, uint32_t rom_size, void *lock_on, uint32_t lock_on_size, uint32_t system_opts, uint8_t force_region);
-void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc);
+void genesis_serialize(genesis_context *gen, serialize_buffer *buf, uint32_t m68k_pc, uint8_t all);
void genesis_deserialize(deserialize_buffer *buf, genesis_context *gen);
#endif //GENESIS_H_
diff --git a/psg.c b/psg.c
index a165f3b..7893208 100644
--- a/psg.c
+++ b/psg.c
@@ -5,6 +5,7 @@
*/
#include "psg.h"
#include "blastem.h"
+#include "event_log.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
@@ -35,6 +36,7 @@ void psg_write(psg_context * context, uint8_t value)
if (context->vgm) {
vgm_sn76489_write(context->vgm, context->cycles, value);
}
+ event_log(EVENT_PSG_REG, context->cycles, sizeof(value), &value);
if (value & 0x80) {
context->latch = value & 0x70;
uint8_t channel = value >> 5 & 0x3;
diff --git a/render.h b/render.h
index 4a1f23b..2bd7724 100644
--- a/render.h
+++ b/render.h
@@ -77,8 +77,6 @@
#define FRAMEBUFFER_UI 2
#define FRAMEBUFFER_USER_START 3
-#include "vdp.h"
-
typedef enum {
VID_NTSC,
VID_PAL,
diff --git a/saves.h b/saves.h
index 8dac45a..0e6483b 100644
--- a/saves.h
+++ b/saves.h
@@ -7,6 +7,7 @@
#define QUICK_SAVE_SLOT 10
#define SERIALIZE_SLOT 11
+#define EVENTLOG_SLOT 12
typedef struct {
char *desc;
diff --git a/serialize.c b/serialize.c
index dc54bb8..a59151f 100644
--- a/serialize.c
+++ b/serialize.c
@@ -20,8 +20,13 @@ void init_serialize(serialize_buffer *buf)
static void reserve(serialize_buffer *buf, size_t amount)
{
if (amount > (buf->storage - buf->size)) {
- buf->storage *= 2;
- buf = realloc(buf, buf->storage + sizeof(*buf));
+ if (amount < buf->storage) {
+ buf->storage *= 2;
+ } else {
+ //doublign isn't enough, increase by the precise amount needed
+ buf->storage += amount - (buf->storage - buf->size);
+ }
+ buf->data = realloc(buf->data, buf->storage + sizeof(*buf));
}
}
diff --git a/system.c b/system.c
index ebfd346..4e92b21 100644
--- a/system.c
+++ b/system.c
@@ -1,6 +1,7 @@
#include <string.h>
#include "system.h"
#include "genesis.h"
+#include "gen_player.h"
#include "sms.h"
uint8_t safe_cmp(char *str, long offset, uint8_t *buffer, long filesize)
@@ -21,6 +22,14 @@ system_type detect_system_type(system_media *media)
) {
return SYSTEM_SMS;
}
+ if (safe_cmp("BLSTEL\x02", 0, media->buffer, media->size)) {
+ uint8_t *buffer = media->buffer;
+ if (media->size > 9 && buffer[7] == 0) {
+ return buffer[8] + 1;
+ }
+ }
+
+
//TODO: Detect Jaguar ROMs here
//Header based detection failed, examine filename for clues
@@ -60,6 +69,8 @@ system_header *alloc_config_system(system_type stype, system_media *media, uint3
{
case SYSTEM_GENESIS:
return &(alloc_config_genesis(media->buffer, media->size, lock_on, lock_on_size, opts, force_region))->header;
+ case SYSTEM_GENESIS_PLAYER:
+ return &(alloc_config_gen_player(media->buffer, media->size))->header;
#ifndef NO_Z80
case SYSTEM_SMS:
return &(alloc_configure_sms(media, opts, force_region))->header;
@@ -68,3 +79,13 @@ system_header *alloc_config_system(system_type stype, system_media *media, uint3
return NULL;
}
}
+
+system_header *alloc_config_player(system_type stype, event_reader *reader)
+{
+ switch(stype)
+ {
+ case SYSTEM_GENESIS:
+ return &(alloc_config_gen_player_reader(reader))->header;
+ }
+ return NULL;
+}
diff --git a/system.h b/system.h
index 508e29a..1fbd61b 100644
--- a/system.h
+++ b/system.h
@@ -9,8 +9,10 @@ typedef struct system_media system_media;
typedef enum {
SYSTEM_UNKNOWN,
SYSTEM_GENESIS,
+ SYSTEM_GENESIS_PLAYER,
SYSTEM_SMS,
- SYSTEM_JAGUAR
+ SYSTEM_SMS_PLAYER,
+ SYSTEM_JAGUAR,
} system_type;
typedef enum {
@@ -33,6 +35,7 @@ typedef void (*system_ptr8_sizet_fun)(system_header *, uint8_t *, size_t);
#include "arena.h"
#include "romdb.h"
+#include "event_log.h"
struct system_header {
system_header *next_context;
@@ -87,5 +90,6 @@ struct system_media {
system_type detect_system_type(system_media *media);
system_header *alloc_config_system(system_type stype, system_media *media, uint32_t opts, uint8_t force_region);
+system_header *alloc_config_player(system_type stype, event_reader *reader);
#endif //SYSTEM_H_
diff --git a/vdp.c b/vdp.c
index defc1ff..3b6677f 100644
--- a/vdp.c
+++ b/vdp.c
@@ -9,6 +9,7 @@
#include <string.h>
#include "render.h"
#include "util.h"
+#include "event_log.h"
#define NTSC_INACTIVE_START 224
#define PAL_INACTIVE_START 240
@@ -908,14 +909,17 @@ static void external_slot(vdp_context * context)
{
case VRAM_WRITE:
if ((context->regs[REG_MODE_2] & (BIT_128K_VRAM|BIT_MODE_5)) == (BIT_128K_VRAM|BIT_MODE_5)) {
+ event_vram_word(context->cycles, start->address, start->value);
vdp_check_update_sat(context, start->address, start->value);
write_vram_word(context, start->address, start->value);
} else {
uint8_t byte = start->partial == 1 ? start->value >> 8 : start->value;
- vdp_check_update_sat_byte(context, start->address ^ 1, byte);
- write_vram_byte(context, start->address ^ 1, byte);
+ uint32_t address = start->address ^ 1;
+ event_vram_byte(context->cycles, start->address, byte, context->regs[REG_AUTOINC]);
+ vdp_check_update_sat_byte(context, address, byte);
+ write_vram_byte(context, address, byte);
if (!start->partial) {
- start->address = start->address ^ 1;
+ start->address = address;
start->partial = 1;
//skip auto-increment and removal of entry from fifo
return;
@@ -924,18 +928,20 @@ static void external_slot(vdp_context * context)
break;
case CRAM_WRITE: {
//printf("CRAM Write | %X to %X\n", start->value, (start->address/2) & (CRAM_SIZE-1));
+ uint16_t val;
if (start->partial == 3) {
- uint16_t val;
if ((start->address & 1) && (context->regs[REG_MODE_2] & BIT_MODE_5)) {
val = (context->cram[start->address >> 1 & (CRAM_SIZE-1)] & 0xFF) | start->value << 8;
} else {
uint16_t address = (context->regs[REG_MODE_2] & BIT_MODE_5) ? start->address >> 1 & (CRAM_SIZE-1) : start->address & 0x1F;
val = (context->cram[address] & 0xFF00) | start->value;
}
- write_cram(context, start->address, val);
} else {
- write_cram(context, start->address, start->partial ? context->fifo[context->fifo_write].value : start->value);
+ val = start->partial ? context->fifo[context->fifo_write].value : start->value;
}
+ uint8_t buffer[3] = {start->address, val >> 8, val};
+ event_log(EVENT_CRAM, context->cycles, sizeof(buffer), buffer);
+ write_cram(context, start->address, val);
break;
}
case VSRAM_WRITE:
@@ -952,6 +958,8 @@ static void external_slot(vdp_context * context)
} else {
context->vsram[(start->address/2) & 63] = start->partial ? context->fifo[context->fifo_write].value : start->value;
}
+ uint8_t buffer[3] = {(start->address/2) & 63, context->vsram[(start->address/2) & 63] >> 8, context->vsram[(start->address/2) & 63]};
+ event_log(EVENT_VSRAM, context->cycles, sizeof(buffer), buffer);
}
break;
@@ -2110,6 +2118,8 @@ static void advance_output_line(vdp_context *context)
context->pushed_frame = 1;
context->fb = NULL;
}
+ //TODO: Check whether this happens before or after the cycle increment
+ event_flush(context->cycles);
vdp_update_per_frame_debug(context);
context->h40_lines = 0;
context->frame++;
@@ -3760,6 +3770,8 @@ int vdp_control_port_write(vdp_context * context, uint16_t value)
/*if (reg == REG_MODE_4 && ((value ^ context->regs[reg]) & BIT_H40)) {
printf("Mode changed from H%d to H%d @ %d, frame: %d\n", context->regs[reg] & BIT_H40 ? 40 : 32, value & BIT_H40 ? 40 : 32, context->cycles, context->frame);
}*/
+ uint8_t buffer[2] = {reg, value};
+ event_log(EVENT_VDP_REG, context->cycles, sizeof(buffer), buffer);
context->regs[reg] = value;
if (reg == REG_MODE_4) {
context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES);
@@ -4551,3 +4563,78 @@ void vdp_inc_debug_mode(vdp_context *context)
}
}
}
+
+void vdp_replay_event(vdp_context *context, uint8_t event, event_reader *reader)
+{
+ uint32_t address;
+ deserialize_buffer *buffer = &reader->buffer;
+ switch (event)
+ {
+ case EVENT_VRAM_BYTE:
+ address = load_int16(buffer);
+ break;
+ case EVENT_VRAM_BYTE_DELTA:
+ address = reader->last_byte_address + load_int8(buffer);
+ break;
+ case EVENT_VRAM_BYTE_ONE:
+ address = reader->last_byte_address + 1;
+ break;
+ case EVENT_VRAM_BYTE_AUTO:
+ address = reader->last_byte_address + context->regs[REG_AUTOINC];
+ break;
+ case EVENT_VRAM_WORD:
+ address = load_int8(buffer) << 16;
+ address |= load_int16(buffer);
+ break;
+ case EVENT_VRAM_WORD_DELTA:
+ address = reader->last_word_address + load_int8(buffer);
+ break;
+ case EVENT_VDP_REG:
+ case EVENT_CRAM:
+ case EVENT_VSRAM:
+ address = load_int8(buffer);
+ break;
+ }
+
+ switch (event)
+ {
+ case EVENT_VDP_REG: {
+ uint8_t value = load_int8(buffer);
+ context->regs[address] = value;
+ if (address == REG_MODE_4) {
+ context->double_res = (value & (BIT_INTERLACE | BIT_DOUBLE_RES)) == (BIT_INTERLACE | BIT_DOUBLE_RES);
+ if (!context->double_res) {
+ context->flags2 &= ~FLAG2_EVEN_FIELD;
+ }
+ }
+ if (address == REG_MODE_1 || address == REG_MODE_2 || address == REG_MODE_4) {
+ update_video_params(context);
+ }
+ break;
+ }
+ case EVENT_VRAM_BYTE:
+ case EVENT_VRAM_BYTE_DELTA:
+ case EVENT_VRAM_BYTE_ONE:
+ case EVENT_VRAM_BYTE_AUTO: {
+ uint8_t byte = load_int8(buffer);
+ reader->last_byte_address = address;
+ vdp_check_update_sat_byte(context, address ^ 1, byte);
+ write_vram_byte(context, address ^ 1, byte);
+ break;
+ }
+ case EVENT_VRAM_WORD:
+ case EVENT_VRAM_WORD_DELTA: {
+ uint16_t value = load_int16(buffer);
+ reader->last_word_address = address;
+ vdp_check_update_sat(context, address, value);
+ write_vram_word(context, address, value);
+ break;
+ }
+ case EVENT_CRAM:
+ write_cram(context, address, load_int16(buffer));
+ break;
+ case EVENT_VSRAM:
+ context->vsram[address] = load_int16(buffer);
+ break;
+ }
+}
diff --git a/vdp.h b/vdp.h
index 44dc46c..28a132e 100644
--- a/vdp.h
+++ b/vdp.h
@@ -285,5 +285,6 @@ void vdp_toggle_debug_view(vdp_context *context, uint8_t debug_type);
void vdp_inc_debug_mode(vdp_context *context);
//to be implemented by the host system
uint16_t read_dma_value(uint32_t address);
+void vdp_replay_event(vdp_context *context, uint8_t event, event_reader *reader);
#endif //VDP_H_
diff --git a/ym2612.c b/ym2612.c
index fdcfb9d..7e3237d 100644
--- a/ym2612.c
+++ b/ym2612.c
@@ -11,6 +11,7 @@
#include "render.h"
#include "wave.h"
#include "blastem.h"
+#include "event_log.h"
//#define DO_DEBUG_PRINT
#ifdef DO_DEBUG_PRINT
@@ -825,6 +826,8 @@ void ym_data_write(ym2612_context * context, uint8_t value)
}
context->part1_regs[context->selected_reg - YM_PART1_START] = value;
}
+ uint8_t buffer[3] = {context->selected_part, context->selected_reg, value};
+ event_log(EVENT_YM_REG, context->current_cycle, sizeof(buffer), buffer);
dfprintf(debug_file, "write of %X to reg %X in part %d\n", value, context->selected_reg, context->selected_part+1);
if (context->selected_reg < 0x30) {
//Shared regs