well this code will handle all interrupts when it comes across a "break" op il update my post later to only handle your own ones.
fairly simple stuff:
1-The "break" op is a level 1 exception and has an ID of 9
2-We handle all exceptions with the ID of 9 by setting a handler to handle the exception vector 0x80000180 (afaik for user mode)
3-The handler for the "break" op must get the EPC(exception programme counter) Then once finished add 4 to this(so it does not re-excute the same line), exit exception mode and jump to the EPC.
setting the exception handler
the handler
as you can see it calls a function to save the registers then print them.
yeah yeah it doesn't save all registers but really i cant be bothered coding all that now!
fairly simple stuff:
1-The "break" op is a level 1 exception and has an ID of 9
2-We handle all exceptions with the ID of 9 by setting a handler to handle the exception vector 0x80000180 (afaik for user mode)
3-The handler for the "break" op must get the EPC(exception programme counter) Then once finished add 4 to this(so it does not re-excute the same line), exit exception mode and jump to the EPC.
setting the exception handler
Code:
SetVCommonHandler(9, &breakPoint);//breakPoint is the handler
Code:
void breakPoint(void)
{
__asm volatile("addiu $sp, $sp, -0x0010");
save_regs();
print_regs();
__asm volatile("ld $ra, 0x0($sp)");
__asm volatile("addiu $sp, $sp, 0x0010");
__asm volatile("mfc0 $t7, $14");//get EPC
__asm("addu $t7, $t7, 0x4");//add 4 to EPC
__asm volatile("mtc0 $t7, $14");//put back new EPC
__asm volatile("eret");//exception return
__asm volatile("jr $t7");//jump to new EPC
__asm volatile("nop");
__asm volatile("nop");
}
Code:
void save_regs(void)
{
__asm("li $t7, 0x00200000");
__asm volatile("sq $ra, 0x0($t7)");
__asm volatile("sq $s0, 0x10($t7)");
__asm volatile("sq $s1, 0x20($t7)");
__asm volatile("sq $s2, 0x30($t7)");
__asm volatile("sq $s3, 0x40($t7)");
__asm volatile("sq $s4, 0x50($t7)");
__asm volatile("sq $s5, 0x60($t7)");
__asm volatile("sq $s6, 0x70($t7)");
__asm volatile("sq $s7, 0x80($t7)");
__asm volatile("sq $a0, 0x90($t7)");
__asm volatile("sq $a1, 0xA0($t7)");
__asm volatile("sq $a2, 0xB0($t7)");
__asm volatile("sq $a3, 0xC0($t7)");
__asm volatile("sq $v0, 0xD0($t7)");
__asm volatile("sq $v1, 0xE0($t7)");
__asm volatile("sq $t0, 0xF0($t7)");
__asm volatile("sq $t1, 0x100($t7)");
__asm volatile("sq $t2, 0x110($t7)");
__asm volatile("sq $t3, 0x120($t7)");
}
void print_regs(void)
{
__asm("addiu $sp, $sp, -0x20");
__asm("li $t7, 0x00200000");
__asm volatile("lq $a1, 0x00($t7)");//ra
__asm volatile("lq $a2, 0x10($t7)");//s0
__asm volatile("lq $a3, 0x20($t7)");//s1
__asm volatile("lq $t0, 0x30($t7)");//s2
__asm volatile("lq $t1, 0x40($t7)");//s3
__asm volatile("lq $t2, 0x50($t7)");//s4
__asm volatile("lq $t3, 0x60($t7)");//s5
__asm volatile("lq $at, 0x70($t7)");//s6
__asm volatile("sw $at, 0x00($sp)");
__asm volatile("lq $at, 0x80($t7)");//s7
__asm volatile("sw $at, 0x08($sp)");
__asm volatile("lq $at, 0x90($t7)");//a0
__asm volatile("sw $at, 0x10($sp)");
printf("reg ra %0x, s0 %0x, s1 %0x, s2 %0x, s3 %0x, s4 %0x, s5 %0x, s6 %0x, s7 %0x, a0 %0x\n");
__asm("li $t7, 0x00200000");
__asm volatile("lq $a1, 0xA0($t7)");//a1
__asm volatile("lq $a2, 0xB0($t7)");//a2
__asm volatile("lq $a3, 0xC0($t7)");//a3
__asm volatile("lq $t0, 0xD0($t7)");//v0
__asm volatile("lq $t1, 0xE0($t7)");//v1
__asm volatile("lq $t2, 0xF0($t7)");//t0
__asm volatile("lq $t3, 0x100($t7)");//t1
__asm volatile("lq $at, 0x110($t7)");//t2
__asm volatile("sw $at, 0x00($sp)");
__asm volatile("lq $at, 0x120($t7)");//t3
__asm volatile("sw $at, 0x80($sp)");
printf("reg a1 %0x, a2 %0x, a3 %0x, v0 %0x, v1 %0x, t0 %0x, t1 %0x, t2 %0x, t3 %0x");
__asm("addiu $sp, $sp, 0x20");
}