Mercurial > repos > blastem
changeset 2621:ce9386a7b21e
Fix V flag for asl in new CPU core
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 22 Feb 2025 01:31:51 -0800 |
parents | b58ca7af1e60 |
children | adff015dc94f |
files | cpu_dsl.py m68k.cpu |
diffstat | 2 files changed, 61 insertions(+), 63 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Fri Feb 21 23:28:07 2025 -0800 +++ b/cpu_dsl.py Sat Feb 22 01:31:51 2025 -0800 @@ -613,7 +613,10 @@ myRes = '({a} ^ {b} ^ {res})'.format(a = prog.lastA, b = prog.lastB, res = lastDst) elif calc == 'overflow': resultBit = prog.getLastSize() - 1 - myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst) + if prog.lastOp.op == 'lsl': + myRes = f'({prog.lastA} ^ {lastDst})' + else: + myRes = '((({a} ^ {b})) & ({a} ^ {res}))'.format(a = prog.lastA, b = prog.lastBFlow, res = lastDst) else: #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 @@ -1726,11 +1729,32 @@ def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): self.regValues = parent.regValues + for op in self.body: + if op.op in _opMap: + opDef = _opMap[op.op] + if len(opDef.outOp): + for index in opDef.outOp: + dst = op.params[index] + while dst in prog.meta: + dst = prog.meta[dst] + if dst in self.regValues: + #value changes in loop body + #so we need to prevent constant folding + maybeLocal = self.resolveLocal(dst) + if maybeLocal: + #for locals, we also need to persist + #the current constant fold value to the actual variable + output.append(f'\n\t{maybeLocal} = {self.regValues[dst]};') + del self.regValues[dst] + else: + #TODO: handle block types here + pass if self.count: count = prog.resolveParam(self.count, self, fieldVals) - output.append('\n\tfor (uint32_t loop_counter__ = 0; loop_counter__ < {count}; loop_counter__++) {') + output.append(f'\n\tfor (uint32_t loop_counter__ = 0; loop_counter__ < {count}; loop_counter__++) {{') else: output.append('\n\tfor (;;) {') + self.processOps(prog, fieldVals, output, otype, self.body) output.append('\n\t}')
--- a/m68k.cpu Fri Feb 21 23:28:07 2025 -0800 +++ b/m68k.cpu Sat Feb 22 01:31:51 2025 -0800 @@ -1732,14 +1732,25 @@ 1110CCC1ZZ000RRR asli invalid Z 3 + local vtmp 8 + local shift 8 + vtmp = 0 switch C case 0 - meta shift 8 + shift = 8 default - meta shift C + shift = C end - lsl dregs.R shift dregs.R Z - update_flags XNZV0C + shift -= 1 + loop shift + lsl dregs.R 1 dregs.R Z + update_flags V + vtmp |= vflag + end + shift += 1 + lsl dregs.R 1 dregs.R Z + update_flags XNZVC + vflag |= vtmp local cyc 32 cyc = shift + shift switch Z @@ -1755,67 +1766,30 @@ 1110CCC1ZZ100RRR asl_dn invalid Z 3 local shift 8 + local vtmp 8 and dregs.C 63 shift - #TODO: implement loops and do this a bit at a time to implement V flag + vtmp = 0 + if shift + shift -= 1 + loop shift + lsl dregs.R 1 dregs.R Z + update_flags V + vtmp |= vflag + end + shift += 1 + lsl dregs.R 1 dregs.R Z + update_flags XNZVC + vflag |= vtmp + else + cmp 0 dregs.R Z + update_flags NZV0C + end + shift += shift switch Z case 2 - if shift >=U 32 - if shift = 32 - lsl dregs.R 31 dregs.R Z - lsl dregs.R 1 dregs.R Z - update_flags XNZ1V0C - else - dregs.R:Z = 0 - update_flags X0N0Z1V0C0 - end - else - lsl dregs.R shift dregs.R Z - update_flags NZV0C - if shift - xflag = cflag - end - end - case 1 - if shift >=U 16 - if shift = 16 - lsl dregs.R 15 dregs.R Z - lsl dregs.R 1 dregs.R Z - update_flags XN0Z1V0C - else - dregs.R:Z = 0 - update_flags X0N0Z1V0C0 - end - else - lsl dregs.R shift dregs.R Z - update_flags NZV0C - if shift - xflag = cflag - end - end - case 0 - if shift >=U 8 - if shift = 8 - lsl dregs.R 7 dregs.R Z - lsl dregs.R 1 dregs.R Z - update_flags XN0Z1V0C - else - dregs.R:Z = 0 - update_flags X0N0Z1V0C0 - end - else - lsl dregs.R shift dregs.R Z - update_flags NZV0C - if shift - xflag = cflag - end - end - end - add shift shift shift - switch Z - case 2 - add 4 shift shift + shift += 4 default - add 2 shift shift + shift += 2 end cycles shift #TODO: should this happen before or after the majority of the shift?