summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--blastem.c10
-rw-r--r--blastem.h1
-rw-r--r--zruntime.S65
3 files changed, 74 insertions, 2 deletions
diff --git a/blastem.c b/blastem.c
index 05a1b4f..489ce62 100644
--- a/blastem.c
+++ b/blastem.c
@@ -312,10 +312,12 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
//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 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
//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 @@ m68k_context * vdp_port_write(uint32_t vdp_port, m68k_context * context, uint16_
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 --git a/blastem.h b/blastem.h
index 6f8786f..ff05a69 100644
--- a/blastem.h
+++ b/blastem.h
@@ -34,6 +34,7 @@ typedef struct {
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 --git a/zruntime.S b/zruntime.S
index 122f058..fa803fe 100644
--- a/zruntime.S
+++ b/zruntime.S
@@ -34,6 +34,21 @@ sync_io:
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 @@ z80_read_ram:
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 @@ z80_read_bank:
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 @@ z80_write_vdp:
.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 @@ z80_read_word:
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