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

392 lines
6.9 KiB
C

#include <stdio.h>
#include "exception.h"
#define SR state->sr.bits
#define _SR state->sr.value
#define VBR state->vbr
#define PC state->pc[0] = state->pc[1]
#define SPC state->spc
#define SSR state->ssr
#define SGR state->sgr
#define R15 state->general_register[15]
#define BL bl
#define FD fd
#define IMASK imask
#define MD md
#define RB rb
#pragma GCC diagnostic ignored "-Wunused-variable"
#define EXPEVT int32_t expevt
#define INTEVT int32_t intevt
#define TEA int32_t tea
#define TRA int32_t tra
#define EXCEPTION_ADDRESS 0
void exception(struct architectural_state * state, const char * name)
{
printf("exception: %s\n", name);
state->is_delay_slot = 0;
}
void POWERON(struct architectural_state * state)
{
exception(state, "POWERON");
//Initialize_Module(PowerOn);
EXPEVT = 0x00000000;
VBR = 0x00000000;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
SR.IMASK = 0xF;
SR.FD = 0;
PC = 0xA0000000;
}
void MANRESET(struct architectural_state * state)
{
exception(state, "MANRESET");
//Initialize_Module(Manual);
EXPEVT = 0x00000020;
VBR = 0x00000000;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
SR.IMASK = 0xF;
SR.FD = 0;
PC = 0xA0000000;
}
void HUIDRESET(struct architectural_state * state)
{
exception(state, "HUIDRESET");
//Initialize_Module(PowerOn);
EXPEVT = 0x00000000;
VBR = 0x00000000;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
SR.IMASK = 0xF;
SR.FD = 0;
PC = 0xA0000000;
}
void ITLBMULTIHIT(struct architectural_state * state)
{
exception(state, "ITLBMULTIHIT");
//Initialize_Module(Manual);
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
EXPEVT = 0x00000140;
VBR = 0x00000000;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
SR.IMASK = 0xF;
SR.FD = 0;
PC = 0xA0000000;
}
void OTLBMULTIHIT(struct architectural_state * state)
{
exception(state, "OTLBMULTIHIT");
//Initialize_Module(Manual);
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
EXPEVT = 0x00000140;
VBR = 0x00000000;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
SR.IMASK = 0xF;
SR.FD = 0;
PC = 0xA0000000;
}
/* General exceptions */
void RTLBMISS(struct architectural_state * state, int32_t op1)
{
exception(state, "RTLBMISS");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000040;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000400;
}
void WTLBMISS(struct architectural_state * state, int32_t op1)
{
exception(state, "WTLBMISS");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000060;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000400;
}
void ITLBMISS(struct architectural_state * state)
{
exception(state, "ITLBMISS");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000040;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000400;
}
void FIRSTWRITE(struct architectural_state * state, int32_t op1)
{
exception(state, "FIRSTWRITE");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000080;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void READPROT(struct architectural_state * state, int32_t op1)
{
exception(state, "READPROT");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000000A0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void WRITEPROT(struct architectural_state * state, int32_t op1)
{
exception(state, "WRITEPROT");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000000C0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void EXECPROT(struct architectural_state * state)
{
exception(state, "EXECPROT");
TEA = EXCEPTION_ADDRESS;
//PTEH.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000000A0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void RADDERR(struct architectural_state * state, int32_t op1)
{
exception(state, "RADDERR");
TEA = EXCEPTION_ADDRESS;
//PTEN.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000000E0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void WADDERR(struct architectural_state * state, int32_t op1)
{
exception(state, "WADDERR");
TEA = EXCEPTION_ADDRESS;
//PTEN.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000100;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void IADDERR(struct architectural_state * state)
{
exception(state, "IADDERR");
TEA = EXCEPTION_ADDRESS;
//PTEN.VPN = PAGE_NUMBER;
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000000E0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void TRAP(struct architectural_state * state, int32_t imm)
{
exception(state, "TRAP");
SPC = PC + 2;
SSR = _SR;
SGR = R15;
TRA = imm << 2;
EXPEVT = 0x00000160;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void RESINST(struct architectural_state * state)
{
exception(state, "RESINST");
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000180;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void ILLSLOT(struct architectural_state * state)
{
exception(state, "ILLSLOT");
SPC = PC - 2;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000001A0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void FPUDIS(struct architectural_state * state)
{
exception(state, "FPUDIS");
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000800;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void SLOTFPUDIS(struct architectural_state * state)
{
exception(state, "SLOTFPUDIS");
SPC = PC - 2;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000820;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
void UBRKBEFORE(struct architectural_state * state)
{
exception(state, "UBRKBEFORE");
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000001E0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
//PC = (BRCR.UBDE==1 ? DBR : VBR + H00000100);
}
void UBRKAFTER(struct architectural_state * state)
{
exception(state, "UBRKAFTER");
SPC = PC + 2;
SSR = _SR;
SGR = R15;
EXPEVT = 0x000001E0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
//PC = (BRCR.UBDE==1 ? DBR : VBR + H00000100);
}
void FPUEXC(struct architectural_state * state)
{
exception(state, "FPUEXC");
SPC = PC;
SSR = _SR;
SGR = R15;
EXPEVT = 0x00000120;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000100;
}
/* interrupts */
void NMI(struct architectural_state * state)
{
exception(state, "NMI");
SPC = PC;
SSR = _SR;
SGR = R15;
INTEVT = 0x000001C0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000600;
}
void IRLINT(struct architectural_state * state)
{
exception(state, "IRLINT");
SPC = PC;
SSR = _SR;
SGR = R15;
//INTEVT = 0x00000200 ~ 0x000003C0;
SR.MD = 1;
SR.RB = 1;
SR.BL = 1;
PC = VBR + 0x00000600;
}