47 lines
1.8 KiB
Python
47 lines
1.8 KiB
Python
from emulator import impl
|
|
from emulator.operations import zero_extend32, sign_extend32
|
|
from decode import decode_instruction, decode_variables
|
|
|
|
def delay_slot_state(cpu, ins):
|
|
if instruction_properties.has_delay_slot(ins):
|
|
assert cpu.is_delay_slot == False
|
|
cpu.is_delay_slot = True
|
|
else:
|
|
cpu.is_delay_slot = False
|
|
|
|
def step(cpu, mem):
|
|
# 3 Fetch the instruction bytes from the address in memory, as
|
|
# indicated by the current program counter, 2 bytes need to be
|
|
# fetched for each instruction.
|
|
address = zero_extend32(sign_extend32(cpu.pc))
|
|
assert address & 0b1 == 0, address
|
|
instruction = mem.read16(address)
|
|
|
|
# 4 Calculate the default values of PC’ and PR’. PC’ is set to the
|
|
# value of PC”, PR’ is set to the value of PR”.
|
|
cpu.pc1 = cpu.pc2
|
|
cpu.pr1 = cpu.pr2
|
|
|
|
# 5 Calculate the default values of PC” and PR” assuming continued
|
|
# sequential execution without procedure call or mode switch: PC”
|
|
# is PC’+2, while PR” is unchanged.
|
|
cpu.pc2 = cpu.pc1 + 2
|
|
cpu.pr2 = cpu.pr2
|
|
|
|
# 6 Decode and execute the instruction. This includes checks for
|
|
# synchronous events, such as exceptions and panics, and
|
|
# initiation of handling if required. Synchronous events are not
|
|
# accepted between a delayed branch and a delay slot. They are
|
|
# detected either before the delayed branch or after the delay
|
|
# slot.
|
|
ins = decode_instruction(instruction)
|
|
variables = decode_variables(instruction, ins)
|
|
func = impl.lookup[(ins.instruction, ins.operands)]
|
|
func(cpu, mem, *variables)
|
|
delay_slot_state(cpu, ins)
|
|
|
|
# 7 Set the current program counter (PC) to the value of the next
|
|
# program counter (PC’) and PR to the value of PR’.
|
|
cpu.pc = cpu.pc1
|
|
cpu.pr = cpu.pr1
|