summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcpu_dsl.py105
-rw-r--r--z80.cpu115
2 files changed, 209 insertions, 11 deletions
diff --git a/cpu_dsl.py b/cpu_dsl.py
index f277962..3806741 100755
--- a/cpu_dsl.py
+++ b/cpu_dsl.py
@@ -157,11 +157,12 @@ class SubRoutine(Block):
self.arg_map = {}
self.locals = {}
self.regValues = {}
+ self.argValues = {}
def addOp(self, op):
if op.op == 'arg':
name = op.params[0]
- size = op.params[1]
+ size = int(op.params[1])
self.arg_map[name] = len(self.args)
self.args.append((name, size))
elif op.op == 'local':
@@ -180,7 +181,12 @@ class SubRoutine(Block):
self.locals[name] = size
def localSize(self, name):
- return self.locals.get(name)
+ if name in self.locals:
+ return self.locals[name]
+ if name in self.arg_map:
+ argIndex = self.arg_map[name]
+ return self.args[argIndex][1]
+ return None
def inline(self, prog, params, output, otype, parent):
if len(params) != len(self.args):
@@ -196,6 +202,7 @@ class SubRoutine(Block):
for name in self.locals:
size = self.locals[name]
output.append('\n\tuint{size}_t {sub}_{local};'.format(size=size, sub=self.name, local=name))
+ self.argValues = argValues
self.processOps(prog, argValues, output, otype, self.implementation)
prog.popScope()
@@ -355,6 +362,10 @@ def _updateFlagsCImpl(prog, params, rawParams):
else:
output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit))
elif calc == 'zero':
+ if prog.carryFlowDst:
+ realSize = prog.paramSize(prog.lastDst)
+ if realSize != prog.paramSize(prog.carryFlowDst):
+ lastDst = '({res} & {mask})'.format(res=lastDst, mask = (1 << realSize) - 1)
if type(storage) is tuple:
reg,storageBit = storage
reg = prog.resolveParam(reg, None, {})
@@ -528,6 +539,80 @@ def _sbcCImpl(prog, params, rawParams, flagUpdates):
return decl + '\n\t{dst} = {b} - {a} - ({check} ? 1 : 0);'.format(dst = dst,
a = params[0], b = params[1], check=_getCarryCheck(prog)
)
+
+def _rolCImpl(prog, params, rawParams, flagUpdates):
+ needsCarry = False
+ if flagUpdates:
+ for flag in flagUpdates:
+ calc = prog.flags.flagCalc[flag]
+ if calc == 'carry':
+ needsCarry = True
+ decl = ''
+ size = prog.paramSize(rawParams[2])
+ if needsCarry:
+ decl,name = prog.getTemp(size * 2)
+ dst = prog.carryFlowDst = name
+ else:
+ dst = params[2]
+ return decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} - {b});'.format(dst = dst,
+ a = params[0], b = params[1], size=size
+ )
+
+def _rlcCImpl(prog, params, rawParams, flagUpdates):
+ needsCarry = False
+ if flagUpdates:
+ for flag in flagUpdates:
+ calc = prog.flags.flagCalc[flag]
+ if calc == 'carry':
+ needsCarry = True
+ decl = ''
+ carryCheck = _getCarryCheck(prog)
+ size = prog.paramSize(rawParams[2])
+ if needsCarry:
+ decl,name = prog.getTemp(size * 2)
+ dst = prog.carryFlowDst = name
+ else:
+ dst = params[2]
+ return decl + '\n\t{dst} = {a} << {b} | {a} >> ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({b} - 1);'.format(dst = dst,
+ a = params[0], b = params[1], size=size, check=carryCheck
+ )
+
+def _rorCImpl(prog, params, rawParams, flagUpdates):
+ needsCarry = False
+ if flagUpdates:
+ for flag in flagUpdates:
+ calc = prog.flags.flagCalc[flag]
+ if calc == 'carry':
+ needsCarry = True
+ decl = ''
+ size = prog.paramSize(rawParams[2])
+ if needsCarry:
+ decl,name = prog.getTemp(size)
+ dst = prog.carryFlowDst = name
+ else:
+ dst = params[2]
+ return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} - {b});'.format(dst = dst,
+ a = params[0], b = params[1], size=size
+ )
+
+def _rrcCImpl(prog, params, rawParams, flagUpdates):
+ needsCarry = False
+ if flagUpdates:
+ for flag in flagUpdates:
+ calc = prog.flags.flagCalc[flag]
+ if calc == 'carry':
+ needsCarry = True
+ decl = ''
+ carryCheck = _getCarryCheck(prog)
+ size = prog.paramSize(rawParams[2])
+ if needsCarry:
+ decl,name = prog.getTemp(size * 2)
+ dst = prog.carryFlowDst = name
+ else:
+ dst = params[2]
+ return decl + '\n\t{dst} = {a} >> {b} | {a} << ({size} + 1 - {b}) | ({check} ? 1 : 0) << ({size}-{b});'.format(dst = dst,
+ a = params[0], b = params[1], size=size, check=carryCheck
+ )
_opMap = {
'mov': Op(lambda val: val).cUnaryOperator(''),
@@ -541,6 +626,10 @@ _opMap = {
'lsl': Op(lambda a, b: a << b).cBinaryOperator('<<'),
'lsr': Op(lambda a, b: a >> b).cBinaryOperator('>>'),
'asr': Op(lambda a, b: a >> b).addImplementation('c', 2, _asrCImpl),
+ 'rol': Op().addImplementation('c', 2, _rolCImpl),
+ 'rlc': Op().addImplementation('c', 2, _rlcCImpl),
+ 'ror': Op().addImplementation('c', 2, _rorCImpl),
+ 'rrc': Op().addImplementation('c', 2, _rrcCImpl),
'and': Op(lambda a, b: a & b).cBinaryOperator('&'),
'or': Op(lambda a, b: a | b).cBinaryOperator('|'),
'xor': Op(lambda a, b: a ^ b).cBinaryOperator('^'),
@@ -628,6 +717,16 @@ class NormalOp:
else:
output.append(opDef.generate(otype, prog, procParams, self.params, flagUpdates))
elif self.op in prog.subroutines:
+ procParams = []
+ for param in self.params:
+ begin,sep,end = param.partition('.')
+ if sep:
+ if end in fieldVals:
+ param = begin + '.' + str(fieldVals[end])
+ else:
+ if param in fieldVals:
+ param = fieldVals[param]
+ procParams.append(param)
prog.subroutines[self.op].inline(prog, procParams, output, otype, parent)
else:
output.append('\n\t' + self.op + '(' + ', '.join([str(p) for p in procParams]) + ');')
@@ -1210,6 +1309,8 @@ class Program:
return maybeLocal
if param in fieldVals:
param = fieldVals[param]
+ fieldVals = {}
+ keepGoing = True
elif param in self.meta:
param = self.meta[param]
keepGoing = True
diff --git a/z80.cpu b/z80.cpu
index 58b17e3..dcbd880 100644
--- a/z80.cpu
+++ b/z80.cpu
@@ -1,7 +1,7 @@
info
prefix z80_
opcode_size 8
- extra_tables cb ed dded fded dd fd
+ extra_tables cb ed dded fded ddcb fdcb dd fd
body z80_run_op
include z80_util.c
header z80.h
@@ -67,6 +67,22 @@ z80_run_op
z80_op_fetch
dispatch scratch1 fd
+dd 11001011 ddcb_prefix
+ z80_calc_index ix
+ cycles 2
+ mov pc scratch1
+ ocall read_8
+ add 1 pc pc
+ dispatch scratch1 ddcb
+
+fd 11001011 fdcb_prefix
+ z80_calc_index iy
+ cycles 2
+ mov pc scratch1
+ ocall read_8
+ add 1 pc pc
+ dispatch scratch1 fdcb
+
z80_check_cond
arg cond 8
local invert 8
@@ -867,13 +883,11 @@ dd 10100110 and_ixd
z80_fetch_index ix
and a scratch1 a
update_flags SZYH1PXN0C0
- cycles 3
fd 10100110 and_iyd
z80_fetch_index iy
and a scratch1 a
update_flags SZYH1PXN0C0
- cycles 3
11100110 and_immed
z80_fetch_immed
@@ -911,13 +925,11 @@ dd 10110110 or_ixd
z80_fetch_index ix
or a scratch1 a
update_flags SZYH0PXN0C0
- cycles 3
fd 10110110 or_iyd
z80_fetch_index iy
or a scratch1 a
update_flags SZYH0PXN0C0
- cycles 3
11110110 or_immed
z80_fetch_immed
@@ -955,13 +967,11 @@ dd 10101110 xor_ixd
z80_fetch_index ix
xor a scratch1 a
update_flags SZYH0PXN0C0
- cycles 3
fd 10101110 xor_iyd
z80_fetch_index iy
xor a scratch1 a
update_flags SZYH0PXN0C0
- cycles 3
11101110 xor_immed
z80_fetch_immed
@@ -1004,14 +1014,12 @@ dd 10111110 cp_ixd
mov scratch1 last_flag_result
cmp scratch1 a
update_flags SZHVN1C
- cycles 3
fd 10111110 cp_iyd
z80_fetch_index iy
mov scratch1 last_flag_result
cmp scratch1 a
update_flags SZHVN1C
- cycles 3
11111110 cp_immed
z80_fetch_immed
@@ -1328,3 +1336,92 @@ ed 01RRR001 out_bc
or c scratch2 scratch2
mov main.R scratch1
ocall io_write8
+
+00000111 rlca
+ rol a 1 a
+ update_flags YH0XN0C
+
+00010111 rla
+ rlc a 1 a
+ update_flags YH0XN0C
+
+00001111 rrca
+ ror a 1 a
+ update_flags YH0XN0C
+
+00011111 rra
+ rrc a 1 a
+ update_flags YH0XN0C
+
+cb 00000RRR rlc
+ rol main.R 1 main.R
+ update_flags SZYH0PXN0C
+
+cb 00000110 rlc_hl
+ local tmp 8
+ z80_fetch_hl
+ mov scratch1 tmp
+ rol tmp 1 tmp
+ update_flags SZYH0PXN0C
+ mov tmp scratch1
+ z80_store_hl
+
+z80_rlc_index
+ arg tmp 8
+ mov wz scratch1
+ ocall read_8
+ cycles 1
+ mov scratch1 tmp
+ rol tmp 1 tmp
+ update_flags SZYH0PXN0C
+ mov tmp scratch1
+ z80_store_index
+
+ddcb 00000110 rlc_ixd
+ local tmp 8
+ z80_rlc_index tmp
+
+ddcb 00000RRR rlc_ixd_reg
+ z80_rlc_index main.R
+
+fdcb 00000110 rlc_iyd
+ local tmp 8
+ z80_rlc_index tmp
+
+fdcb 00000RRR rlc_iyd_reg
+ z80_rlc_index main.R
+
+cb 00010RRR rl
+ rlc main.R 1 main.R
+ update_flags SZYH0PXN0C
+
+cb 00010110 rl_hl
+ local tmp 8
+ z80_fetch_hl
+ mov scratch1 tmp
+ rlc tmp 1 tmp
+ update_flags SZYH0PXN0C
+ mov tmp scratch1
+ z80_store_hl
+
+ddcb 00010110 rl_ixd
+ local tmp 8
+ mov wz scratch1
+ ocall read_8
+ cycles 1
+ mov scratch1 tmp
+ rlc tmp 1 tmp
+ update_flags SZYH0PXN0C
+ mov tmp scratch1
+ z80_store_index
+
+fdcb 00010110 rl_iyd
+ local tmp 8
+ mov wz scratch1
+ ocall read_8
+ cycles 1
+ mov scratch1 tmp
+ rlc tmp 1 tmp
+ update_flags SZYH0PXN0C
+ mov tmp scratch1
+ z80_store_index \ No newline at end of file