
# ASM exception handlers

#include "r5900_regs.h"
        
.set noat
.set noreorder


.text
.p2align 4

        .global _savedRegs
        
     
        # Save all user regs
        # Save HI/LO, SR, BadVAddr, Cause, EPC, ErrorEPC, 
        # ShiftAmount, cop0: $24, $25
        # Save float regs??
        # Set EPC to debugger
        # Set stack to 'exception stack'
        # eret
        .global ExceptionHandler
        .ent	ExceptionHandler
ExceptionHandler:
        la      k0, _savedRegs
        sq      $0,  0x00(k0)
        sq      at,  0x10(k0)
        sq      v0,  0x20(k0)
        sq      v1,  0x30(k0)
        sq      a0,  0x40(k0)
        sq      a1,  0x50(k0)
        sq      a2,  0x60(k0)
        sq      a3,  0x70(k0)
        sq      t0,  0x80(k0)
        sq      t1,  0x90(k0)
        sq      t2,  0xa0(k0)
        sq      t3,  0xb0(k0)
        sq      t4,  0xc0(k0)
        sq      t5,  0xd0(k0)
        sq      t6,  0xe0(k0)
        sq      t7,  0xf0(k0)
        sq      t8,  0x100(k0)
        sq      t9,  0x110(k0)
        sq      s0,  0x120(k0)
        sq      s1,  0x130(k0)
        sq      s2,  0x140(k0)
        sq      s3,  0x150(k0)
        sq      s4,  0x160(k0)
        sq      s5,  0x170(k0)
        sq      s6,  0x180(k0)
        sq      s7,  0x190(k0)
#        sq      k0,  0x1a0(k0)          # $k0
        sq      zero, 0x1a0(k0)         # zero instead
        sq      k1,  0x1b0(k0)          # $k1
        sq      gp,  0x1c0(k0)
        sq      sp,  0x1d0(k0)          # sp
        sq      fp,  0x1e0(k0)
        sq      ra,  0x1f0(k0)          # $ra

        pmfhi   t0                      # HI
        pmflo   t1                      # LO
        sq      t0, 0x200(k0)
        sq      t1, 0x210(k0)
       
        mfc0    t0, BadVAddr            # Cop0 state regs
        mfc0    t1, Status
        sw      t0, 0x220(k0)
        sw      t1, 0x224(k0)

        mfc0    t0, Cause
        mfc0    t1, EPC
        sw      t0, 0x228(k0)
        sw      t1, 0x22c(k0)

        # Kernel saves these two also..
        mfc0    t0, DEPC
        mfc0    t1, PerfCnt
        sw      t0, 0x230(k0)
        sw      t1, 0x234(k0)

        mfsa    t0
        sw      t0, 0x238(k0)

        # Use our own stack..
        la      sp, _exceptionStack+0x2000-16
        la       gp, _gp                 # Use exception handlers _gp
        
        # Return from exception and start 'debugger'
        mfc0    a0, Cause               # arg0
        mfc0    a1, BadVAddr
        mfc0    a2, Status
        mfc0    a3, EPC
        addu    t0, zero, k0            # arg4 = registers
        move    t1, sp
        la      k0, TrapException
        mtc0    k0, EPC                 # eret return address
        sync.p
        mfc0    k0, Status                  # check this out..
        li      v0, 0xfffffffe
        and     k0, v0
        mtc0    k0, Status
        sync.p
        nop
        nop
        nop
        nop
        eret
        nop
        .end	ExceptionHandler


        
