sh-dis/python/emulator/execute.py
Zack Buhman 8a300ba4c6 initial SH4 emulator implementation in C
This currently only implements the SH2 instructions.
2024-04-22 20:53:36 +08:00

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