pcsx2/fps2bios/kernel/eeload/eeirq.c

337 lines
6.5 KiB
C

// EE core interrupt and exception handlers
// most functions here can only use $at, $k0, and $k1
// [made by] [RO]man, zerofrog
#include "eekernel.h"
#include "eeirq.h"
#define LOAD_KERNELSTACK \
"lui $sp, %hi(g_kernelstackend)\n" \
"addiu $sp, %lo(g_kernelstackend)\n"
__asm__(".org 0x0000");
__asm__(".set noreorder");
void CpuException0() {
__asm__ (
"lui $26, %hi(SavedT9)\n"
"sd $25, %lo(SavedT9)($26)\n"
"mfc0 $25, $13\n"
"andi $25, 0x7C\n"
"lui $26, %hi(VCRTable)\n"
"addu $26, $25\n"
"lw $26, %lo(VCRTable)($26)\n"
"lui $25, %hi(SavedT9)\n"
"jr $26\n"
"ld $25, %lo(SavedT9)($25)\n"
);
}
__asm__(".org 0x0180");
__asm__(".set noreorder");
void CpuException() {
__asm__ (
"lui $26, %hi(SavedT9)\n"
"sd $25, %lo(SavedT9)($26)\n"
"mfc0 $25, $13\n"
"andi $25, 0x7C\n"
"lui $26, %hi(VCRTable)\n"
"addu $26, $25\n"
"lw $26, %lo(VCRTable)($26)\n"
"lui $25, %hi(SavedT9)\n"
"jr $26\n"
"ld $25, %lo(SavedT9)($25)\n"
);
}
__asm__(".org 0x0200");
__asm__(".set noreorder");
__asm__(".set noat");
void CpuException2() {
__asm__ (
"lui $26, %hi(SavedSP)\n"
"sq $sp, %lo(SavedSP)($26)\n"
"lui $26, %hi(SavedRA)\n"
"sq $31, %lo(SavedRA)($26)\n"
"lui $26, %hi(SavedAT)\n"
"sq $1, %lo(SavedAT)($26)\n"
"mfc0 $1, $13\n"
"mfc0 $26, $14\n"
"and $1, $26\n"
"srl $1, 8\n"
"andi $1, 0xFF\n"
"plzcw $26, $1\n"
"andi $26, 0xFF\n"
"ori $1, $0, 0x1E\n"
"subu $1, $26\n"
"sll $1, 2\n"
"lui $26, %hi(VIntTable)\n"
"addu $26, $25\n"
"lw $26, %lo(VIntTable)($26)\n"
"jr $26\n"
"nop\n"
);
}
extern char call_used_regs[];
extern char fixed_regs[];
__asm__(".org 0x0280");
__asm__(".set noreorder");
void SyscException()
{
const register int code __asm__("$3"); // $v1
if (code < 0) {
__asm__(
"addiu $sp, -0x10\n"
"sw $31, 0($sp)\n"
"mfc0 $26, $14\n"
"addiu $26, 4\n"
"sw $26, 4($sp)\n"
"mtc0 $26, $14\n"
"sync\n");
table_SYSCALL[-code]();
__asm__(
"lw $26, 4($sp)\n"
"lw $31, 0($sp)\n"
"addiu $sp, 0x10\n"
"mtc0 $26, $14\n"
"sync\n"
"eret\n"
"nop\n");
}
if (code == 0x7c) {
_Deci2Call();
return;
}
__asm__(
"lui $26, %hi(SavedSP)\n"
"sq $sp, %lo(SavedSP)($26)\n"
"lui $26, %hi(SavedRA)\n"
"sq $31, %lo(SavedRA)($26)\n"
"lui $26, %hi(SavedAT)\n"
"sq $1, %lo(SavedAT)($26)\n"
"mfc0 $1, $12\n"
"addiu $26, $0, 0xFFE4\n"
"and $1, $26\n"
"mtc0 $1, $12\n"
"sync\n"
"move $26, $sp\n"
LOAD_KERNELSTACK
"addiu $sp, -0x10\n"
"sw $31, 0($sp)\n"
"sw $26, 4($sp)\n"
"mfc0 $26, $14\n"
"addiu $26, 4\n"
"sw $26, 8($sp)\n"
"mtc0 $26, $14\n"
"sync\n");
table_SYSCALL[code]();
__asm__(
"lw $26, 8($sp)\n"
"lw $31, 0($sp)\n"
"lw $sp, 4($sp)\n"
"mtc0 $26, $14\n"
"sync\n"
"mfc0 $26, $12\n"
"ori $26, 0x13\n"
"mtc0 $26, $12\n"
"sync\n"
"eret\n"
"nop\n");
}
void _Deci2Call() {
__puts("_Deci2Call called\n");
}
void __ThreadHandler();
void INTCException() {
u32 code;
u32 temp;
code = INTC_STAT & INTC_MASK;
if (code & 0xC0) {
int VpuStat;
__asm__("cfc2 %0, $29\n" : "=r"(VpuStat) : );
if (VpuStat & 0x202) {
__asm__(
".set noat\n"
"lui $26, %hi(SavedAT)\n"
"lq $1, %lo(SavedAT)($26)\n"
".set at\n");
__exception();
}
}
__asm__ (
"mfc0 $26, $14\n"
"li $27, 0xFFFFFFE4\n"
"and $26, $27\n"
"mtc0 $26, $14\n"
"sync\n"
LOAD_KERNELSTACK
"addiu $sp, -0x10\n"
"mfc0 $26, $14\n"
"sw $26, 0($sp)\n"
);
saveContext2();
__asm__ (
"plzcw %0, %1"
: "=r"(temp) : "r"(code)
);
temp = 0x1e - (temp & 0xff);
INTC_STAT = 1 << temp;
threadStatus = 0;
INTCTable[temp](temp);
restoreContext2();
__asm__ (
".set noat\n"
"lw $26, 0($sp)\n"
"mtc0 $26, $14\n"
"lui $26, %hi(SavedSP)\n"
"lq $sp, %lo(SavedSP)($26)\n"
"lui $26, %hi(SavedRA)\n"
"lq $31, %lo(SavedRA)($26)\n"
"lui $26, %hi(SavedAT)\n"
"lq $1, %lo(SavedAT)($26)\n"
".set at\n"
);
if (!threadStatus) {
__asm__ (
"mfc0 $26, $12\n"
"ori $26, 0x13\n"
"mtc0 $26, $12\n"
"sync\n"
"eret\n"
);
}
__asm__(LOAD_KERNELSTACK);
threadStatus = 0;
__ThreadHandler();
}
////////////////////////////////////////////////////////////////////
//800004C0
////////////////////////////////////////////////////////////////////
void DMACException() {
unsigned int code;
unsigned int temp;
code = (DMAC_STAT >> 16) | 0x8000;
code&= DMAC_STAT & 0xFFFF;
if (code & 0x80) {
//__printf("%s: code & 0x80\n", __FUNCTION__);
__asm__(
".set noat\n"
"lui $26, %hi(SavedAT)\n"
"lq $1, %lo(SavedAT)($26)\n"
".set at\n");
__exception1();
}
__asm__ (
"mfc0 $26, $14\n"
"li $27, 0xFFFFFFE4\n"
"and $26, $27\n"
"mtc0 $26, $14\n"
"sync\n"
LOAD_KERNELSTACK
"addiu $sp, -0x10\n"
"mfc0 $26, $14\n"
"sw $26, 0($sp)\n"
);
saveContext2();
__asm__ (
"plzcw %0, %1"
: "=r"(temp) : "r"(code)
);
temp = 0x1e - (temp & 0xff);
DMAC_STAT = 1 << temp;
threadStatus = 0;
DMACTable[temp](temp);
restoreContext2();
__asm__ (
".set noat\n"
"lw $26, 0($sp)\n"
"mtc0 $26, $14\n"
"lui $26, %hi(SavedSP)\n"
"lq $sp, %lo(SavedSP)($26)\n"
"lui $26, %hi(SavedRA)\n"
"lq $31, %lo(SavedRA)($26)\n"
"lui $26, %hi(SavedAT)\n"
"lq $1, %lo(SavedAT)($26)\n"
".set at\n"
);
if (!threadStatus) {
__asm__ (
"mfc0 $26, $12\n"
"ori $26, 0x13\n"
"mtc0 $26, $12\n"
"sync\n"
"eret\n"
);
}
__asm__(LOAD_KERNELSTACK);
threadStatus = 0;
__ThreadHandler();
}
////////////////////////////////////////////////////////////////////
//80000600
////////////////////////////////////////////////////////////////////
void TIMERException()
{
}
////////////////////////////////////////////////////////////////////
//80000700
////////////////////////////////////////////////////////////////////
void setINTCHandler(int n, void (*phandler)(int))
{
INTCTable[n] = phandler;
}
////////////////////////////////////////////////////////////////////
//80000780
////////////////////////////////////////////////////////////////////
void setDMACHandler(int n, void (*phandler)(int))
{
DMACTable[n] = phandler;
}