summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2015-05-11 00:28:47 -0700
committerMichael Pavone <pavone@retrodev.com>2015-05-11 00:28:47 -0700
commitb3e40bd29176e1c4cf53f8542628e48e1eb5dcb0 (patch)
treee1571120d6b1f62b29bbe4973d719c8c7ff25889
parent89ca3bce585f06927569ed1f18ad433d33e320e9 (diff)
Sync fixes and logging to fix more sync issues
-rw-r--r--backend.h1
-rw-r--r--backend_x86.c17
-rw-r--r--blastem.c71
-rw-r--r--m68k_core.c1
-rw-r--r--vdp.c22
-rw-r--r--vdp.h3
-rw-r--r--z80_to_x86.c3
7 files changed, 67 insertions, 51 deletions
diff --git a/backend.h b/backend.h
index 2b95d06..6c18675 100644
--- a/backend.h
+++ b/backend.h
@@ -113,6 +113,7 @@ void cycles(cpu_options *opts, uint32_t num);
void check_cycles_int(cpu_options *opts, uint32_t address);
void check_cycles(cpu_options * opts);
void check_code_prologue(code_info *code);
+void log_address(cpu_options *opts, uint32_t address, char * format);
code_ptr gen_mem_fun(cpu_options * opts, memmap_chunk const * memmap, uint32_t num_chunks, ftype fun_type, code_ptr *after_inc);
void * get_native_pointer(uint32_t address, void ** mem_pointers, cpu_options * opts);
diff --git a/backend_x86.c b/backend_x86.c
index d606886..75eece9 100644
--- a/backend_x86.c
+++ b/backend_x86.c
@@ -11,7 +11,7 @@ void check_cycles_int(cpu_options *opts, uint32_t address)
code_info *code = &opts->code;
cmp_rr(code, opts->cycles, opts->limit, SZ_D);
code_ptr jmp_off = code->cur+1;
- jcc(code, CC_NC, jmp_off+1);
+ jcc(code, CC_A, jmp_off+1);
mov_ir(code, address, opts->scratch1, SZ_D);
call(code, opts->handle_cycle_limit_int);
*jmp_off = code->cur - (jmp_off+1);
@@ -23,11 +23,24 @@ void check_cycles(cpu_options * opts)
cmp_rr(code, opts->cycles, opts->limit, SZ_D);
check_alloc_code(code, MAX_INST_LEN*2);
code_ptr jmp_off = code->cur+1;
- jcc(code, CC_NC, jmp_off+1);
+ jcc(code, CC_A, jmp_off+1);
call(code, opts->handle_cycle_limit);
*jmp_off = code->cur - (jmp_off+1);
}
+void log_address(cpu_options *opts, uint32_t address, char * format)
+{
+ code_info *code = &opts->code;
+ call(code, opts->save_context);
+ push_r(code, opts->context_reg);
+ mov_rr(code, opts->cycles, RDX, SZ_D);
+ mov_ir(code, (int64_t)format, RDI, SZ_PTR);
+ mov_ir(code, address, RSI, SZ_D);
+ call_args_abi(code, (code_ptr)printf, 3, RDI, RSI, RDX);
+ pop_r(code, opts->context_reg);
+ call(code, opts->load_context);
+}
+
void check_code_prologue(code_info *code)
{
check_alloc_code(code, MAX_INST_LEN*4);
diff --git a/blastem.c b/blastem.c
index 51a39b1..9a26e4b 100644
--- a/blastem.c
+++ b/blastem.c
@@ -203,7 +203,7 @@ void sync_sound(genesis_context * gen, uint32_t target)
//printf("Target: %d, YM bufferpos: %d, PSG bufferpos: %d\n", target, gen->ym->buffer_pos, gen->psg->buffer_pos * 2);
}
-uint32_t frame=0;
+uint32_t last_frame_num;
m68k_context * sync_components(m68k_context * context, uint32_t address)
{
genesis_context * gen = context->system;
@@ -212,45 +212,37 @@ m68k_context * sync_components(m68k_context * context, uint32_t address)
uint32_t mclks = context->current_cycle;
sync_z80(z_context, mclks);
sync_sound(gen, mclks);
- if (mclks >= gen->frame_end) {
- vdp_run_context(v_context, gen->frame_end);
- if (vdp_is_frame_over(v_context)) {
- //printf("reached frame end | MCLK Cycles: %d, Target: %d, VDP cycles: %d\n", mclks, gen->frame_end, v_context->cycles);
-
- if (!headless) {
- break_on_sync |= wait_render_frame(v_context, frame_limit);
- } else if(exit_after){
- --exit_after;
- if (!exit_after) {
- exit(0);
- }
- }
- frame++;
- mclks -= gen->frame_end;
- vdp_adjust_cycles(v_context, gen->frame_end);
- io_adjust_cycles(gen->ports, context->current_cycle, gen->frame_end);
- io_adjust_cycles(gen->ports+1, context->current_cycle, gen->frame_end);
- io_adjust_cycles(gen->ports+2, context->current_cycle, gen->frame_end);
- context->current_cycle -= gen->frame_end;
- z80_adjust_cycles(z_context, gen->frame_end);
- gen->ym->current_cycle -= gen->frame_end;
- gen->psg->cycles -= gen->frame_end;
- if (gen->ym->write_cycle != CYCLE_NEVER) {
- gen->ym->write_cycle = gen->ym->write_cycle >= gen->frame_end ? gen->ym->write_cycle - gen->frame_end : 0;
- }
- if (mclks) {
- vdp_run_context(v_context, mclks);
+ vdp_run_context(v_context, mclks);
+ if (v_context->frame != last_frame_num) {
+ //printf("reached frame end %d | MCLK Cycles: %d, Target: %d, VDP cycles: %d, vcounter: %d, hslot: %d\n", last_frame_num, mclks, gen->frame_end, v_context->cycles, v_context->vcounter, v_context->hslot);
+ last_frame_num = v_context->frame;
+
+ if (!headless) {
+ break_on_sync |= wait_render_frame(v_context, frame_limit);
+ } else if(exit_after){
+ --exit_after;
+ if (!exit_after) {
+ exit(0);
}
- gen->frame_end = vdp_cycles_to_frame_end(v_context);
- } else {
- vdp_run_context(v_context, mclks);
- gen->frame_end = vdp_cycles_to_frame_end(v_context);
}
- context->sync_cycle = gen->frame_end;
+
+ vdp_adjust_cycles(v_context, mclks);
+ io_adjust_cycles(gen->ports, context->current_cycle, mclks);
+ io_adjust_cycles(gen->ports+1, context->current_cycle, mclks);
+ io_adjust_cycles(gen->ports+2, context->current_cycle, mclks);
+ context->current_cycle -= mclks;
+ z80_adjust_cycles(z_context, mclks);
+ gen->ym->current_cycle -= mclks;
+ gen->psg->cycles -= mclks;
+ if (gen->ym->write_cycle != CYCLE_NEVER) {
+ gen->ym->write_cycle = gen->ym->write_cycle >= mclks ? gen->ym->write_cycle - mclks : 0;
+ }
+ gen->frame_end = vdp_cycles_to_frame_end(v_context);
} else {
- //printf("running VDP for %d cycles\n", mclks - v_context->cycles);
- vdp_run_context(v_context, mclks);
+ gen->frame_end = vdp_cycles_to_frame_end(v_context);
}
+ context->sync_cycle = gen->frame_end;
+ //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
if (context->int_ack) {
vdp_int_ack(v_context, context->int_ack);
context->int_ack = 0;
@@ -289,12 +281,15 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
int blocked;
uint32_t before_cycle = v_context->cycles;
if (vdp_port < 4) {
+
while (vdp_data_port_write(v_context, value) < 0) {
while(v_context->flags & FLAG_DMA_RUN) {
vdp_run_dma_done(v_context, gen->frame_end);
if (v_context->cycles >= gen->frame_end) {
context->current_cycle = v_context->cycles;
+ gen->bus_busy = 1;
sync_components(context, 0);
+ gen->bus_busy = 0;
}
}
//context->current_cycle = v_context->cycles;
@@ -307,7 +302,9 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
vdp_run_dma_done(v_context, gen->frame_end);
if (v_context->cycles >= gen->frame_end) {
context->current_cycle = v_context->cycles;
+ gen->bus_busy = 1;
sync_components(context, 0);
+ gen->bus_busy = 0;
}
}
if (blocked < 0) {
@@ -317,6 +314,8 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
}
}
} else {
+ context->sync_cycle = gen->frame_end = vdp_cycles_to_frame_end(v_context);
+ //printf("Set sync cycle to: %d @ %d, vcounter: %d, hslot: %d\n", context->sync_cycle, context->current_cycle, v_context->vcounter, v_context->hslot);
adjust_int_cycle(context, v_context);
}
} else {
diff --git a/m68k_core.c b/m68k_core.c
index d3125a9..b56b58b 100644
--- a/m68k_core.c
+++ b/m68k_core.c
@@ -801,6 +801,7 @@ impl_info m68k_impls[] = {
void translate_m68k(m68k_options * opts, m68kinst * inst)
{
check_cycles_int(&opts->gen, inst->address);
+ log_address(&opts->gen, inst->address, "M68K: %X @ %d\n");
impl_info * info = m68k_impls + inst->op;
if (info->itype == RAW_FUNC) {
info->impl.raw(opts, inst);
diff --git a/vdp.c b/vdp.c
index 710d2ab..c760529 100644
--- a/vdp.c
+++ b/vdp.c
@@ -24,8 +24,8 @@
#define MCLKS_SLOT_H32 20
#define VINT_SLOT_H40 4 //21 slots before HSYNC, 16 during, 10 after
#define VINT_SLOT_H32 23 //33 slots before HSYNC, 20 during, 7 after TODO: confirm final number
-#define HSYNC_SLOT_H40 240
-#define HSYNC_END_H40 (240+17)
+#define HSYNC_SLOT_H40 234
+#define HSYNC_END_H40 (HSYNC_SLOT_H40+17)
#define HSYNC_END_H32 (33 * MCLKS_SLOT_H32)
#define HBLANK_START_H40 178 //should be 179 according to Nemesis, but 178 seems to fit slightly better with my test ROM results
#define HBLANK_END_H40 0 //should be 5.5 according to Nemesis, but 0 seems to fit better with my test ROM results
@@ -1420,7 +1420,7 @@ void check_render_bg(vdp_context * context, int32_t line, uint32_t slot)
}
}
-uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 19, 20, 20, 20, 19, 20, 20, 20, 19, 20, 20, 20, 19};
+uint32_t const h40_hsync_cycles[] = {19, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 18, 20, 20, 20, 19};
void vdp_run_context(vdp_context * context, uint32_t target_cycles)
{
@@ -1428,12 +1428,13 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
{
context->flags &= ~FLAG_UNUSED_SLOT;
uint32_t line = context->vcounter;
- uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START;
uint32_t slot = context->hslot;
- //TODO: Figure out when this actually happens
+
if (!line && !slot) {
+ //TODO: Figure out when this actually happens
latch_mode(context);
}
+ uint32_t inactive_start = context->latched_mode & BIT_PAL ? PAL_INACTIVE_START : NTSC_INACTIVE_START;
uint8_t is_h40 = context->regs[REG_MODE_4] & BIT_H40;
if (is_h40) {
@@ -1455,6 +1456,9 @@ void vdp_run_context(vdp_context * context, uint32_t target_cycles)
}
if (is_h40 && slot == LINE_CHANGE_H40 || !is_h40 && slot == LINE_CHANGE_H32) {
if (line >= inactive_start) {
+ if (line == (inactive_start + 8)) {
+ context->frame++;
+ }
context->hint_counter = context->regs[REG_HINT];
} else if (context->hint_counter) {
context->hint_counter--;
@@ -1824,7 +1828,7 @@ uint32_t vdp_cycles_next_line(vdp_context * context)
{
if (context->regs[REG_MODE_4] & BIT_H40) {
if (context->hslot < LINE_CHANGE_H40) {
- return (HBLANK_START_H40 - context->hslot) * MCLKS_SLOT_H40;
+ return (LINE_CHANGE_H40 - context->hslot) * MCLKS_SLOT_H40;
} else if (context->hslot < 183) {
return MCLKS_LINE - (context->hslot - LINE_CHANGE_H40) * MCLKS_SLOT_H40;
} else if (context->hslot < HSYNC_END_H40){
@@ -1916,12 +1920,6 @@ uint32_t vdp_cycles_to_frame_end(vdp_context * context)
return context->cycles + vdp_cycles_to_line(context, vdp_frame_end_line(context));
}
-uint8_t vdp_is_frame_over(vdp_context * context)
-{
- uint32_t frame_end = vdp_frame_end_line(context);
- return context->vcounter >= frame_end && context->vcounter < (frame_end + 8);
-}
-
uint32_t vdp_next_hint(vdp_context * context)
{
if (!(context->regs[REG_MODE_1] & BIT_HINT_EN)) {
diff --git a/vdp.h b/vdp.h
index 70c0953..31bd4e7 100644
--- a/vdp.h
+++ b/vdp.h
@@ -143,6 +143,7 @@ typedef struct {
uint32_t colors[CRAM_SIZE*3];
uint32_t debugcolors[1 << (3 + 1 + 1 + 1)];//3 bits for source, 1 bit for priority, 1 bit for shadow, 1 bit for hilight
uint16_t vsram[VSRAM_SIZE];
+ uint32_t frame;
uint16_t vcounter;
uint16_t hslot; //hcounter/2
uint16_t hscroll_a;
@@ -194,7 +195,7 @@ void vdp_print_sprite_table(vdp_context * context);
void vdp_print_reg_explain(vdp_context * context);
void latch_mode(vdp_context * context);
uint32_t vdp_cycles_to_frame_end(vdp_context * context);
-uint8_t vdp_is_frame_over(vdp_context * context);
+uint32_t vdp_frame_end_line(vdp_context *context);
extern int32_t color_map[1 << 12];
diff --git a/z80_to_x86.c b/z80_to_x86.c
index fab31da..6b498f5 100644
--- a/z80_to_x86.c
+++ b/z80_to_x86.c
@@ -309,6 +309,7 @@ void translate_z80inst(z80inst * inst, z80_context * context, uint16_t address,
if (context->breakpoint_flags[address / sizeof(uint8_t)] & (1 << (address % sizeof(uint8_t)))) {
zbreakpoint_patch(context, address, start);
}
+ //log_address(&opts->gen, address, "Z80: %X @ %d\n");
}
switch(inst->op)
{
@@ -2293,7 +2294,9 @@ void z80_clear_reset(z80_context * context, uint32_t cycle)
void z80_assert_busreq(z80_context * context, uint32_t cycle)
{
+ printf("bus requested at %d\n", cycle);
z80_run(context, cycle);
+ printf("asserted busreq at %d\n", context->current_cycle);
context->busreq = 1;
}