392 lines
6.9 KiB
C
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;
|
|
}
|