# HG changeset patch # User Michael Pavone # Date 1548835008 28800 # Node ID 4fd84c3efc72d831a1eb9bfc0f10a84190df417c # Parent e170a0f75c4f439bfe9c94cd47431edaabcb49d2 Implement 16-bit addition in new Z80 core along with necessary CPU DSL fixes to make them work right diff -r e170a0f75c4f -r 4fd84c3efc72 cpu_dsl.py --- a/cpu_dsl.py Tue Jan 29 22:17:15 2019 -0800 +++ b/cpu_dsl.py Tue Jan 29 23:56:48 2019 -0800 @@ -55,7 +55,7 @@ def addOp(self, op): if op.op == 'local': name = op.params[0] - size = op.params[1] + size = int(op.params[1]) self.locals[name] = size elif op.op == 'invalid': name = op.params[0] @@ -312,13 +312,15 @@ elif calc == 'carry': resultBit = prog.paramSize(prog.lastDst) elif calc == 'half': - resultBit = 4 + resultBit = prog.paramSize(prog.lastDst) - 4 myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst) elif calc == 'overflow': resultBit = prog.paramSize(prog.lastDst) - 1 myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst) else: - resultBit = int(resultBit) + #Note: offsetting this by the operation size - 8 makes sense for the Z80 + #but might not for other CPUs with this kind of fixed bit flag behavior + resultBit = int(resultBit) + prog.paramSize(prog.lastDst) - 8 if type(storage) is tuple: reg,storageBit = storage reg = prog.resolveParam(reg, None, {}) @@ -339,7 +341,11 @@ )) else: reg = prog.resolveParam(storage, None, {}) - output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit)) + maxBit = prog.paramSize(storage) - 1 + if resultBit > maxBit: + output.append('\n\t{reg} = {res} >> {shift} & {mask}U;'.format(reg=reg, res=myRes, shift = resultBit - maxBit, mask = 1 << maxBit)) + else: + output.append('\n\t{reg} = {res} & {mask}U;'.format(reg=reg, res=myRes, mask = 1 << resultBit)) elif calc == 'zero': if type(storage) is tuple: reg,storageBit = storage @@ -1176,6 +1182,8 @@ return parent.regValues[param] maybeLocal = parent.resolveLocal(param) if maybeLocal: + if isdst: + self.lastDst = param return maybeLocal if param in fieldVals: param = fieldVals[param] @@ -1183,7 +1191,9 @@ param = self.meta[param] keepGoing = True elif self.isReg(param): - param = self.resolveReg(param, parent, fieldVals, isdst) + return self.resolveReg(param, parent, fieldVals, isdst) + if isdst: + self.lastDst = param return param def isReg(self, name): @@ -1233,9 +1243,12 @@ def paramSize(self, name): - size = self.currentScope.localSize(name) - if size: - return size + if name in self.meta: + return self.paramSize(self.meta[name]) + for i in range(len(self.scopes) -1, -1, -1): + size = self.scopes[i].localSize(name) + if size: + return size begin,sep,_ = name.partition('.') if sep and self.regs.isRegArray(begin): return self.regs.regArrays[begin][0] diff -r e170a0f75c4f -r 4fd84c3efc72 z80.cpu --- a/z80.cpu Tue Jan 29 22:17:15 2019 -0800 +++ b/z80.cpu Tue Jan 29 23:56:48 2019 -0800 @@ -525,6 +525,43 @@ add a scratch1 a update_flags SZYHVXN0C +z80_add16_hl + arg src 16 + lsl h 8 hlt + or l hlt hlt + add 1 hlt wz + add src hlt hlt + update_flags YHXN0C + mov hlt l + lsr hlt 8 h + +00001001 add_hl_bc + local hlw 16 + local bcw 16 + meta hlt hlw + lsl b 8 bcw + or c bcw bcw + z80_add16_hl bcw + +00011001 add_hl_de + local hlw 16 + local dew 16 + meta hlt hlw + lsl d 8 dew + or e dew dew + z80_add16_hl dew + +00101001 add_hl_hl + local hlw 16 + meta hlt hlw + z80_add16_hl hlw + + +00111001 add_hl_sp + local hlw 16 + meta hlt hlw + z80_add16_hl sp + 10001RRR adc_reg adc a main.R a update_flags SZYHVXN0C @@ -538,6 +575,43 @@ z80_fetch_immed adc a scratch1 a update_flags SZYHVXN0C + +z80_adc16_hl + arg src 16 + lsl h 8 hlt + or l hlt hlt + add 1 hlt wz + adc src hlt hlt + update_flags SZYHVXN0C + mov hlt l + lsr hlt 8 h + +ed 01001010 adc_hl_bc + local hlw 16 + local bcw 16 + meta hlt hlw + lsl b 8 bcw + or c bcw bcw + z80_adc16_hl bcw + +ed 01011010 adc_hl_de + local hlw 16 + local dew 16 + meta hlt hlw + lsl d 8 dew + or e dew dew + z80_adc16_hl dew + +ed 01101010 adc_hl_hl + local hlw 16 + meta hlt hlw + z80_adc16_hl hlw + + +ed 01111010 adc_hl_sp + local hlw 16 + meta hlt hlw + z80_adc16_hl sp 10010RRR sub_reg sub main.R a a diff -r e170a0f75c4f -r 4fd84c3efc72 z80_util.c --- a/z80_util.c Tue Jan 29 22:17:15 2019 -0800 +++ b/z80_util.c Tue Jan 29 23:56:48 2019 -0800 @@ -1,11 +1,13 @@ void z80_read_8(z80_context *context) { + context->cycles += 3 * context->opts->gen.clock_divider; context->scratch1 = read_byte(context->scratch1, NULL, &context->opts->gen, context); } void z80_write_8(z80_context *context) { + context->cycles += 3 * context->opts->gen.clock_divider; write_byte(context->scratch2, context->scratch1, NULL, &context->opts->gen, context); }