diff --git a/src/simudator/core/processor.py b/src/simudator/core/processor.py index c1983ca8f6da33b39d5c7bc9fd68255570373c02..543e578af369779931865c95988d799214f194c5 100644 --- a/src/simudator/core/processor.py +++ b/src/simudator/core/processor.py @@ -48,6 +48,9 @@ class Processor: ] self.lambdas: dict[str, Callable[..., bool]] = {} + # List containing all clock cycles where a new asm instruction started + self.assembly_cycles = [] + def do_tick(self) -> None: """ Simulate one clock cycle of the processor. @@ -96,6 +99,16 @@ class Processor: raise NotImplemented + def undo_asm_instruction(self, num_instructions = 1) -> None: + """ + Undos 'num_instructions' numbers of assembler instructions on the processors. + + Default argument is one, but it is possible to specify any number of instructions. + This should be implemented per processor and thus we raise NotImplemented. + """ + + raise NotImplemented + def run_continuously(self) -> None: """ Run the processor until it halts, is stopped or reaches a breakpoint. @@ -228,9 +241,9 @@ class Processor: def load_cycle(self, cycle: int) -> None: """ - Load the state of all modules as they were at the specified - clock cycle. This does not erase the history of states for the - later cycles. + Load the state of all modules as they were at the specified clock cycle. + + This does not erase the history of states for the later cycles. """ cycle_index = cycle - self.removed_cycles diff --git a/src/simudator/gui/gui.py b/src/simudator/gui/gui.py index 9910e33cd463cf6db9b11446f75fa3c772a6f07f..ebab5d4a6e2f14703a8be800518ed366ba076dfc 100644 --- a/src/simudator/gui/gui.py +++ b/src/simudator/gui/gui.py @@ -928,9 +928,10 @@ class GUI(QMainWindow): """ Undos as many processor cycles as the number entered in the box. """ + print(self.cpu.assembly_cycles) try: steps = self.asm_jump_value_box.value() - self.cpu.load_cycle(max(self.cpu.get_clock() - steps, 0)) + self.cpu.undo_asm_instruction(steps) self.updateCpuListeners() except (ValueError, IndexError): self.errorBox("Unable to undo the cycle.") diff --git a/src/simudator/processor/mia/mia.py b/src/simudator/processor/mia/mia.py index b5c100385f55e5568ea899b0bdf243e367c1e6a4..632248c87c7aee629a2847d377638e23ce769618 100644 --- a/src/simudator/processor/mia/mia.py +++ b/src/simudator/processor/mia/mia.py @@ -280,8 +280,6 @@ class MIA_CPU(Processor): self.micro_memory = uM - # List containing all clock cycles where a new asm instruction started - self.assembly_cycles = [] self.lambdas = {} @@ -296,6 +294,7 @@ class MIA_CPU(Processor): self.new_instruction = True self.current_instruction = self.get_current_instrution() self.assembly_cycles.append(self.get_clock()) + self.finished_assembly_instructions += 1 else: self.new_instruction = False @@ -323,6 +322,31 @@ class MIA_CPU(Processor): self.do_tick() + def undo_asm_instruction(self, num_instructions = 1) -> None: + """ + Undos 'num_instructions' numbers of assembler instructions on Mia. + + Default argument is one, but it is possible to specify any number of instructions. + Undo assembler instrucion assumes the CPU is always at the end of the list + 'self.assembly_cycles'. + + Undos asm instructions by finding the corresponding clock cycle before + said number of asm intructions started and loading that clock cycle. + """ + + index = len(self.assembly_cycles) + index -= num_instructions + + # We cant undo more instructions than we have performed. + if index < 0: + raise IndexError + + clockcycle = self.assembly_cycles[index] + self.assembly_cycles = self.assembly_cycles[:index] + + self.load_cycle(clockcycle) + + def should_halt(self) -> bool: micro_memory_state = self.micro_memory.get_state() return micro_memory_state["halt"]