summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Pavone <pavone@retrodev.com>2019-02-19 22:51:33 -0800
committerMichael Pavone <pavone@retrodev.com>2019-02-19 22:51:33 -0800
commita7792f6ea9784f9a085ecb50861f32082aa53518 (patch)
treee64293a6810c08026697c807843c8e8c3f6e3c98
parent405fd7b0318a6982339ef89ef1c066754adab1ee (diff)
Store sync_cycle in context rather than in a local in CPU DSL. Fix the timing of a number of instructions in new Z80 core
-rwxr-xr-xcpu_dsl.py11
-rw-r--r--sms.c1
-rw-r--r--z80.cpu19
-rw-r--r--z80_util.c4
4 files changed, 24 insertions, 11 deletions
diff --git a/cpu_dsl.py b/cpu_dsl.py
index 651a5b0..44f8b7e 100755
--- a/cpu_dsl.py
+++ b/cpu_dsl.py
@@ -668,7 +668,7 @@ def _rrcCImpl(prog, params, rawParams, flagUpdates):
)
def _updateSyncCImpl(prog, params):
- return '\n\tsync_cycle = {sync}(context, target_cycle);'.format(sync=prog.sync_cycle)
+ return '\n\t{sync}(context, target_cycle);'.format(sync=prog.sync_cycle)
_opMap = {
'mov': Op(lambda val: val).cUnaryOperator(''),
@@ -696,7 +696,7 @@ _opMap = {
'sext': Op(_sext).addImplementation('c', 2, _sextCImpl),
'ocall': Op().addImplementation('c', None, lambda prog, params: '\n\t{pre}{fun}({args});'.format(
pre = prog.prefix, fun = params[0], args = ', '.join(['context'] + [str(p) for p in params[1:]])
- ) + _updateSyncCImpl(prog, params)),
+ )),
'cycles': Op().addImplementation('c', None,
lambda prog, params: '\n\tcontext->cycles += context->opts->gen.clock_divider * {0};'.format(
params[0]
@@ -1033,6 +1033,7 @@ class Registers:
self.regArrays = {}
self.regToArray = {}
self.addReg('cycles', 32)
+ self.addReg('sync_cycle', 32)
def addReg(self, name, size):
self.regs[name] = size
@@ -1387,7 +1388,7 @@ class Program:
output = []
if self.dispatch == 'goto':
if self.interrupt in self.subroutines:
- output.append('\n\tif (context->cycles >= sync_cycle) {')
+ output.append('\n\tif (context->cycles >= context->sync_cycle) {')
output.append('\n\tif (context->cycles >= target_cycle) { return; }')
if self.interrupt in self.subroutines:
self.meta = {}
@@ -1424,7 +1425,7 @@ class Program:
if self.dispatch == 'call' and self.body in self.subroutines:
pieces.append('\nvoid {pre}execute({type} *context, uint32_t target_cycle)'.format(pre = self.prefix, type = self.context_type))
pieces.append('\n{')
- pieces.append('\n\tuint32_t sync_cycle = {sync}(context, target_cycle);'.format(sync=self.sync_cycle))
+ pieces.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle))
pieces.append('\n\twhile (context->cycles < target_cycle)')
pieces.append('\n\t{')
#TODO: Handle interrupts in call dispatch mode
@@ -1434,7 +1435,7 @@ class Program:
pieces.append('\n\t}')
pieces.append('\n}')
elif self.dispatch == 'goto':
- body.append('\n\tuint32_t sync_cycle = {sync}(context, target_cycle);'.format(sync=self.sync_cycle))
+ body.append('\n\t{sync}(context, target_cycle);'.format(sync=self.sync_cycle))
body += self.nextInstruction(otype)
pieces.append('\nunimplemented:')
pieces.append('\n\tfatal_error("Unimplemented instruction\\n");')
diff --git a/sms.c b/sms.c
index 7ceb7a4..1f9b888 100644
--- a/sms.c
+++ b/sms.c
@@ -72,6 +72,7 @@ static void update_interrupts(sms_context *sms)
uint32_t hint = vdp_next_hint(sms->vdp);
#ifdef NEW_CORE
sms->z80->int_cycle = vint < hint ? vint : hint;
+ z80_sync_cycle(sms->z80, sms->z80->sync_cycle);
#else
sms->z80->int_pulse_start = vint < hint ? vint : hint;
#endif
diff --git a/z80.cpu b/z80.cpu
index fc5a25c..7772538 100644
--- a/z80.cpu
+++ b/z80.cpu
@@ -25,6 +25,7 @@ declare
void zinsert_breakpoint(z80_context * context, uint16_t address, uint8_t * bp_handler);
void zremove_breakpoint(z80_context * context, uint16_t address);
void z80_options_free(z80_options *opts);
+ void z80_sync_cycle(z80_context *context, uint32_t target_cycle);
regs
main 8 b c d e h l f a
@@ -83,6 +84,7 @@ z80_op_fetch
add 1 pc pc
z80_run_op
+ printf "Z80: %X @ %d\n" pc cycles
#printf "Z80: %X - A: %X, B: %X, C: %X D: %X, E: %X, H: %X, L: %X, SP: %X, IX: %X, IY: %X @ %d\n" pc a b c d e h l sp ix iy cycles
z80_op_fetch
dispatch scratch1
@@ -856,6 +858,7 @@ z80_add16_hl
update_flags YHXN0C
mov hlt l
lsr hlt 8 h
+ cycles 7
00001001 add_hl_bc
local hlw 16
@@ -888,40 +891,48 @@ dd 00001001 add_ix_bc
or c scratch1 scratch1
add scratch1 ix ix
update_flags YHXN0C
+ cycles 7
dd 00011001 add_ix_de
lsl d 8 scratch1
or e scratch1 scratch1
add scratch1 ix ix
update_flags YHXN0C
+ cycles 7
dd 00101001 add_ix_ix
add ix ix ix
update_flags YHXN0C
+ cycles 7
dd 00111001 add_ix_sp
add sp ix ix
update_flags YHXN0C
+ cycles 7
fd 00001001 add_iy_bc
lsl b 8 scratch1
or c scratch1 scratch1
add scratch1 iy iy
update_flags YHXN0C
+ cycles 7
fd 00011001 add_iy_de
lsl d 8 scratch1
or e scratch1 scratch1
add scratch1 iy iy
update_flags YHXN0C
+ cycles 7
fd 00101001 add_iy_iy
add iy iy iy
update_flags YHXN0C
+ cycles 7
fd 00111001 add_iy_sp
add sp iy iy
update_flags YHXN0C
+ cycles 7
10001RRR adc_reg
adc a main.R a
@@ -1387,6 +1398,7 @@ fd 00110100 inc_iyd
z80_inc_pair
arg high 8
arg low 8
+ cycles 2
local word 16
lsl high 8 word
or low word word
@@ -1484,6 +1496,7 @@ z80_dec_pair
sub 1 word word
mov word low
lsr word 8 high
+ cycles 2
00001011 dec_bc
z80_dec_pair b c
@@ -1655,7 +1668,6 @@ fd 11101001 jp_iy
11001001 ret
local pch 16
- cycles 1
meta high pch
meta low pc
z80_pop
@@ -2169,6 +2181,7 @@ cb 01BBBRRR bit_reg
cb 01BBB110 bit_hl
local tmp 8
z80_fetch_hl
+ cycles 1
lsl 1 B tmp
lsr wz 8 last_flag_result
and scratch1 tmp tmp
@@ -2284,7 +2297,7 @@ z80_fetch_mod_hl
mov tmp l
lsr tmp 8 h
ocall read_8
- cycles 1
+ cycles 2
z80_ldd_ldi
arg change 16
@@ -2317,8 +2330,6 @@ z80_ldd_ldi
mov c pvflag
or b pvflag pvflag
- cycles 5
-
ed 10100000 ldi
z80_ldd_ldi 1
diff --git a/z80_util.c b/z80_util.c
index 949d55e..9802809 100644
--- a/z80_util.c
+++ b/z80_util.c
@@ -91,7 +91,7 @@ z80_context * init_z80_context(z80_options *options)
return context;
}
-uint32_t z80_sync_cycle(z80_context *context, uint32_t target_cycle)
+void z80_sync_cycle(z80_context *context, uint32_t target_cycle)
{
if (context->iff1 && context->int_cycle < target_cycle) {
if (context->cycles > context->int_end_cycle) {
@@ -103,7 +103,7 @@ uint32_t z80_sync_cycle(z80_context *context, uint32_t target_cycle)
if (context->nmi_cycle < target_cycle) {
target_cycle = context->nmi_cycle;
}
- return target_cycle;
+ context->sync_cycle = target_cycle;
}
void z80_run(z80_context *context, uint32_t target_cycle)