started working on interrupts
[psx_test1] / src / intr_asm.S
diff --git a/src/intr_asm.S b/src/intr_asm.S
new file mode 100644 (file)
index 0000000..6b23a2d
--- /dev/null
@@ -0,0 +1,145 @@
+#include <regdef.h>
+       .text
+       .set noreorder
+
+       .equ C0_SR, $12
+       .equ C0_CAUSE, $13
+       .equ C0_EPC, $14
+
+       .macro enable_intr
+       mfc0 C0_SR, t0
+       nop
+       ori t0, t0, 0xff00
+       nop
+       mtc0 C0_SR, t0
+       .endm
+
+       .macro disable_intr
+       lui t1, 0xffff
+       mfc0 C0_SR, t0
+       ori t1, t1, 0x00ff
+       nop
+       and t0, t0, t1
+       nop
+       mtc0 C0_SR, t0
+       .endm
+
+       .extern intr_dispatch
+
+       .globl intr_init
+intr_init:
+       disable_intr
+       la t0, intr_entry
+       nop
+       sw t0, 0x80(zero)
+       enable_intr
+       jr ra
+       nop
+       
+
+       .equ IFRM_SR, 0
+       .equ IFRM_CAUSE, 4
+       .equ IFRM_EPC, 8
+       .equ IFRM_R1, 12
+       .equ IFRM_LO, 128
+       .equ IFRM_HI, 132
+       .equ IFRM_SIZE, 136
+
+       .set noat
+       .globl intr_entry
+intr_entry:
+       addi k1, sp, -IFRM_SIZE
+       # save registers
+       sw $1, IFRM_R1(k1)      # at
+       sw $2, IFRM_R1+4(k1)    # v0
+       sw $3, IFRM_R1+8(k1)    # v1
+       sw $4, IFRM_R1+12(k1)   # a0
+       sw $5, IFRM_R1+16(k1)   # a1
+       sw $6, IFRM_R1+20(k1)   # a2
+       sw $7, IFRM_R1+24(k1)   # a3
+       sw $8, IFRM_R1+28(k1)   # t0
+       sw $9, IFRM_R1+32(k1)   # t1
+       sw $10, IFRM_R1+36(k1)  # t2
+       sw $11, IFRM_R1+40(k1)  # t3
+       sw $12, IFRM_R1+44(k1)  # t4
+       sw $13, IFRM_R1+48(k1)  # t5
+       sw $14, IFRM_R1+52(k1)  # t6
+       sw $15, IFRM_R1+56(k1)  # t7
+       sw $16, IFRM_R1+60(k1)  # s0
+       sw $17, IFRM_R1+64(k1)  # s1
+       sw $18, IFRM_R1+68(k1)  # s2
+       sw $19, IFRM_R1+72(k1)  # s3
+       sw $20, IFRM_R1+76(k1)  # s4
+       sw $21, IFRM_R1+80(k1)  # s5
+       sw $22, IFRM_R1+84(k1)  # s6
+       sw $23, IFRM_R1+88(k1)  # s7
+       sw $24, IFRM_R1+92(k1)  # t8
+       sw $25, IFRM_R1+96(k1)  # t9
+       sw $28, IFRM_R1+100(k1) # gp
+       sw $29, IFRM_R1+104(k1) # sp
+       sw $30, IFRM_R1+108(k1) # fp
+       sw $31, IFRM_R1+112(k1) # ra
+       move sp, k1
+       # save sr/cause/epc
+       mfc0 k0, C0_SR
+       mfc0 k1, C0_CAUSE
+       sw k0, IFRM_SR(sp)
+       mfc0 k0, C0_EPC
+       sw k1, IFRM_CAUSE(sp)
+       sw k0, IFRM_EPC(sp)
+       # save hi/lo
+       mfhi k1
+       mflo k0
+       sw k1, IFRM_HI(sp)
+       sw k0, IFRM_LO(sp)
+
+       # call C dispatch
+       la gp, _gp      # make sure gp points where the compiler expects
+       move a0, sp
+       jal intr_dispatch
+       addi sp, -16
+       move k1, sp
+       addi sp, 16
+
+       # restore registers
+       lw $1, IFRM_R1(k1)      # at
+       lw $2, IFRM_R1+4(k1)    # v0
+       lw $3, IFRM_R1+8(k1)    # v1
+       lw $4, IFRM_R1+12(k1)   # a0
+       lw $5, IFRM_R1+16(k1)   # a1
+       lw $6, IFRM_R1+20(k1)   # a2
+       lw $7, IFRM_R1+24(k1)   # a3
+       lw $8, IFRM_R1+28(k1)   # t0
+       lw $9, IFRM_R1+32(k1)   # t1
+       lw $10, IFRM_R1+36(k1)  # t2
+       lw $11, IFRM_R1+40(k1)  # t3
+       lw $12, IFRM_R1+44(k1)  # t4
+       lw $13, IFRM_R1+48(k1)  # t5
+       lw $14, IFRM_R1+52(k1)  # t6
+       lw $15, IFRM_R1+56(k1)  # t7
+       lw $16, IFRM_R1+60(k1)  # s0
+       lw $17, IFRM_R1+64(k1)  # s1
+       lw $18, IFRM_R1+68(k1)  # s2
+       lw $19, IFRM_R1+72(k1)  # s3
+       lw $20, IFRM_R1+76(k1)  # s4
+       lw $21, IFRM_R1+80(k1)  # s5
+       lw $22, IFRM_R1+84(k1)  # s6
+       lw $23, IFRM_R1+88(k1)  # s7
+       lw $24, IFRM_R1+92(k1)  # t8
+       lw $25, IFRM_R1+96(k1)  # t9
+       lw $28, IFRM_R1+100(k1) # gp
+       lw $29, IFRM_R1+104(k1) # sp
+       lw $30, IFRM_R1+108(k1) # fp
+       lw k0, IFRM_SR(k1)
+       lw $31, IFRM_R1+112(k1) # ra
+
+       # restore sr
+       mtc0 k0, C0_SR
+
+       lw k0, IFRM_EPC(k1)
+       nop
+       j k0
+       rfe             # bd
+       .set at
+
+# vi:ts=8 sts=8 sw=8 ft=mips: