sh-dis/c/execute.c
Zack Buhman b6c629baad initial SH4 emulator implementation in C
This currently only implements the SH2 instructions.
2024-04-21 20:54:32 +08:00

70 lines
2.0 KiB
C

#include <assert.h>
#include "execute.h"
#include "operations.h"
#include "state_helpers.h"
#include "decode_execute.h"
#include "exception.h"
uint16_t fetch(struct architectural_state * state, struct memory_map * map)
{
uint32_t address = zero_extend32(sign_extend32(state->pc[0]));
assert((address & 0b1) == 0);
return read_memory16(map, address);
}
void step(struct architectural_state * state, struct memory_map * map)
{
/*
* 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.
*/
uint16_t instruction_code = fetch(state, map);
/*
* 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”.
*/
state->pc[1] = state->pc[2];
state->pr[1] = state->pr[2];
/*
* 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.
*/
state->pc[2] = state->pc[1] + 2;
state->pr[2] = state->pr[2]; // unchanged
/*
* 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.
*/
enum decode_status status = decode_and_execute_instruction(state, map, instruction_code);
switch (status) {
case DECODE__DEFINED:
break;
case DECODE__UNDEFINED: // undefined instruction
if (state->is_delay_slot)
ILLSLOT(state);
else
RESINST(state);
break;
default:
assert(false);
break;
}
/*
* 7 Set the current program counter (PC) to the value of the next
* program counter (PC’) and PR to the value of PR’.
*/
state->pc[0] = state->pc[1];
state->pr[0] = state->pr[1];
}