Mercurial > repos > blastem
changeset 2618:1579b840a1af
Implement stop in new 68K core
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Fri, 21 Feb 2025 01:45:04 -0800 |
parents | ad9e074c8901 |
children | ba2aba23b48e |
files | cpu_dsl.py m68k.cpu |
diffstat | 2 files changed, 85 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/cpu_dsl.py Fri Feb 21 00:50:31 2025 -0800 +++ b/cpu_dsl.py Fri Feb 21 01:45:04 2025 -0800 @@ -45,6 +45,10 @@ o = If(self, cond) self.addOp(o) return o + elif parts[0] == 'loop': + o = Loop(self, None if len(parts) == 1 else parts[1]) + self.addOp(o) + return o elif parts[0] == 'end': raise Exception('end is only allowed inside a switch or if block') else: @@ -1284,7 +1288,8 @@ 'xchg': Op().addImplementation('c', (0,1), _xchgCImpl), 'dispatch': Op().addImplementation('c', None, _dispatchCImpl), 'update_flags': Op().addImplementation('c', None, _updateFlagsCImpl), - 'update_sync': Op().addImplementation('c', None, _updateSyncCImpl) + 'update_sync': Op().addImplementation('c', None, _updateSyncCImpl), + 'break': Op().addImplementation('c', None, lambda prog, params: '\n\tbreak;') } #represents a simple DSL instruction @@ -1688,6 +1693,56 @@ lines.append('\n\tend') return ''.join(lines) +class Loop(ChildBlock): + def __init__(self, parent, count): + self.op = 'loop' + self.parent = parent + self.count = count + self.body = [] + self.locals = {} + self.regValues = None + + def addOp(self, op): + if op.op in ('case', 'arg', 'else'): + raise Exception(op + ' is not allows inside an loop block') + if op.op == 'local': + name = op.params[0] + size = op.params[1] + self.locals[name] = size + else: + self.body.append(op) + + def localSize(self, name): + return self.locals.get(name) + + def resolveLocal(self, name): + if name in self.locals: + return name + return self.parent.resolveLocal(name) + + def processDispatch(self, prog): + for op in self.body: + op.processDispatch(prog) + + def generate(self, prog, parent, fieldVals, output, otype, flagUpdates): + self.regValues = parent.regValues + if self.count: + count = prog.resolveParam(self.count, self, fieldVals) + output.append('\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}') + + def __str__(self): + lines = ['\n\tloop'] + if self.count: + lines[0] += f' {self.count}' + for op in self.body: + lines.append(str(op)) + lines.append('\n\tend') + return ''.join(lines) + class Registers: def __init__(self): self.regs = {}
--- a/m68k.cpu Fri Feb 21 00:50:31 2025 -0800 +++ b/m68k.cpu Fri Feb 21 01:45:04 2025 -0800 @@ -60,6 +60,7 @@ wp_hit 8 trace_pending 8 should_return 8 + stopped 8 system ptrvoid reset_handler ptrvoid int_ack_handler ptrvoid @@ -167,7 +168,6 @@ int_pending = int_priority int_pending_num = int_num else - #INT_PENDING_SR_CHANGE if 254 = int_pending int_pending = int_priority @@ -202,7 +202,12 @@ #save pc scratch2 = a7 + 2 - scratch1 = pc - 2 + if stopped + scratch1 = pc + stopped = 0 + else + scratch1 = pc - 2 + end m68k_write32_lowfirst scratch1 scratch1 = int_pending_num << 2 @@ -2687,6 +2692,28 @@ 0100111001110001 nop m68k_prefetch +0100111001110010 stop + if stopped + else + mov pc scratch1 + ocall read_16 + pc += 2 + ccr = scratch1 + status = scratch1 >> 8 + check_user_mode_swap_ssp_usp + update_sync + stopped = 1 + end + loop + cycles 4 + if cycles >=U int_cycle + break + end + if cycles >=U target_cycle + break + end + end + 0100111001110011 rte #TODO: privilege violation exception if in user mode #Read saved SR