# HG changeset patch # User Michael Pavone # Date 1549003297 28800 # Node ID 0e5df2bc0f9f9b6f3ed65c70c6dce162dc43e796 # Parent 1648c685083a1ee4d0b847fc81325e8f4bf4a7d4 Implementation of some of the rotate instructions in new Z80 core diff -r 1648c685083a -r 0e5df2bc0f9f cpu_dsl.py --- a/cpu_dsl.py Wed Jan 30 22:11:12 2019 -0800 +++ b/cpu_dsl.py Thu Jan 31 22:41:37 2019 -0800 @@ -157,11 +157,12 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ '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 @@ 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 @@ return maybeLocal if param in fieldVals: param = fieldVals[param] + fieldVals = {} + keepGoing = True elif param in self.meta: param = self.meta[param] keepGoing = True diff -r 1648c685083a -r 0e5df2bc0f9f z80.cpu --- a/z80.cpu Wed Jan 30 22:11:12 2019 -0800 +++ b/z80.cpu Thu Jan 31 22:41:37 2019 -0800 @@ -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_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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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