# HG changeset patch # User Michael Pavone # Date 1391447890 28800 # Node ID b976c6d6e5fb77570db2d0b366f184ffe2d6f55e # Parent cc6030bd04c6936e6fb4ec900973a4dc0c6ed36a Initial attempt at emulating extended bank area access delays when 68K bus is busy with VDP stuff. Also emulate the extra delay on the second access of a word-wide read to the bank area. Needs work as it seems to break stuff. diff -r cc6030bd04c6 -r b976c6d6e5fb blastem.c --- a/blastem.c Tue Jan 28 08:36:06 2014 -0800 +++ b/blastem.c Mon Feb 03 09:18:10 2014 -0800 @@ -312,10 +312,12 @@ //printf("vdp_port write: %X, value: %X, cycle: %d\n", vdp_port, value, context->current_cycle); sync_components(context, 0); vdp_context * v_context = context->video_context; + genesis_context * gen = context->system; if (vdp_port < 0x10) { int blocked; uint32_t before_cycle = v_context->cycles; if (vdp_port < 4) { + gen->bus_busy = 1; while (vdp_data_port_write(v_context, value) < 0) { while(v_context->flags & FLAG_DMA_RUN) { vdp_run_dma_done(v_context, mclks_per_frame); @@ -347,6 +349,7 @@ //context->current_cycle = v_context->cycles / MCLKS_PER_68K; } } else if(vdp_port < 8) { + gen->bus_busy = 1; blocked = vdp_control_port_write(v_context, value); if (blocked) { while (blocked) { @@ -394,12 +397,17 @@ context->current_cycle = v_context->cycles / MCLKS_PER_68K; } } else if (vdp_port < 0x18) { - genesis_context * gen = context->system; sync_sound(gen, context->current_cycle * MCLKS_PER_68K); psg_write(gen->psg, value); } else { //TODO: Implement undocumented test register(s) } + if (gen->bus_busy) + { + //Lock the Z80 out of the bus until the VDP access is complete + sync_z80(gen->z80, v_context->cycles); + gen->bus_busy = 0; + } return context; } diff -r cc6030bd04c6 -r b976c6d6e5fb blastem.h --- a/blastem.h Tue Jan 28 08:36:06 2014 -0800 +++ b/blastem.h Mon Feb 03 09:18:10 2014 -0800 @@ -34,6 +34,7 @@ uint32_t normal_clock; //Normal master clock (used to restore master clock after turbo mode) uint8_t bank_regs[8]; io_port ports[3]; + uint8_t bus_busy; } genesis_context; extern genesis_context * genesis; diff -r cc6030bd04c6 -r b976c6d6e5fb zruntime.S --- a/zruntime.S Tue Jan 28 08:36:06 2014 -0800 +++ b/zruntime.S Mon Feb 03 09:18:10 2014 -0800 @@ -34,6 +34,21 @@ pop %rbx ret /* return to caller of z80_run */ +forced_sync: + movw $0, 164(%rsi) + call z80_save_context_scratch + pop %rax /*return address in read/write func*/ + pop 104(%rsi) /*return address in native code*/ + mov %rax, (%rsi) + + pop %r15 /* restore callee saved regsiters */ + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + ret /* return to caller of z80_run */ + .global z80_handle_cycle_limit_int z80_handle_cycle_limit_int: cmp 116(%rsi), %ebp @@ -107,8 +122,14 @@ mov (%r11, %r13), %r13b ret z80_read_bank: - /* approximation of wait states for 68K bus access */ + push %rsi + mov 144(%rsi), %rsi /* get system context pointer */ + cmp $0, 120(%rsi) /* check bus busy flag */ + pop %rsi + jne bus_busy + /* approximation of wait states for normal 68K bus access */ add $3, %ebp +z80_read_bank_cont: and $0x7FFF, %r13 cmp $0, %r12 je slow_bank_read @@ -119,6 +140,10 @@ slow_bank_read: /* TODO: Call into C to implement this */ ret +bus_busy: + mov %edi, %ebp + call forced_sync + jp z80_read_bank_cont z80_read_ym2612: call z80_save_context mov %r13w, %di @@ -199,6 +224,8 @@ .global z80_read_word z80_read_word: call z_inccycles + cmp $0x8000, %r13w + jae z80_read_bank_word push %r13 call z80_read_byte_noinc mov %r13b, %r14b @@ -210,6 +237,42 @@ mov %r14b, %r13b ret +z80_read_bank_word: + push %rsi + mov 144(%rsi), %rsi /* get system context pointer */ + cmp $0, 120(%rsi) /* check bus busy flag */ + pop %rsi + jne bus_busy_word + add $3, %ebp /* first read typically has 3 wait states */ +z80_read_bank_word_cont: + push %r13 + call z80_read_bank_cont + mov %r13b, %r14b + pop %r13 + inc %r13 + call z_inccycles + push %rsi + mov 144(%rsi), %rsi /* get system context pointer */ + cmp $0, 120(%rsi) /* check bus busy flag */ + pop %rsi + jne bus_busy_word2 + add $4, %ebp /* second read typically has 4 wait states */ +z80_read_bank_word_cont2: + call z80_read_bank_cont + shl $8, %r13w + mov %r14b, %r13b + ret + +bus_busy_word: + mov %edi, %ebp + call forced_sync + jp z80_read_bank_word_cont + +bus_busy_word2: + mov %edi, %ebp + call forced_sync + jp z80_read_bank_word_cont2 + .global z80_write_word_highfirst z80_write_word_highfirst: call z_inccycles