Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/tools/asm/crash.s
7858 views
1
# SM64 Crash Handler
2
# See Readme below.
3
4
.include "macros.inc"
5
6
/* ---------------------------------------------------------------
7
* IMPORTANT README:
8
* ---------------------------------------------------------------
9
* Frame buffer emulation is required. To enable it in GlideN64,
10
* check "Emulate frame buffer" and "Render frame buffer to output"
11
* in the "Frame buffer" tab.
12
*
13
* Your emulator's CPU core style should be set to interpreter for best results.
14
*
15
* See the DEBUG_ASSERT macro on how to call the crash screen for
16
* detected exceptions.
17
*
18
*/
19
20
.set noat
21
.set noreorder
22
.set gp=64
23
24
.set COP0_CAUSE, $13
25
.set COP0_EPC, $14
26
.set COP0_BADVADDR, $8
27
28
glabel crashFont
29
.incbin "enhancements/crash_font.bin"
30
.align 4
31
32
glabel exceptionRegContext
33
.fill 0x108
34
35
glabel pAssertFile
36
.dword 0
37
glabel nAssertLine
38
.dword 0
39
glabel pAssertExpression
40
.dword 0
41
glabel nAssertStopProgram
42
.dword 0
43
44
glabel _n64_assert
45
lui $at, %hi(pAssertFile)
46
sw $a0, %lo(pAssertFile)($at)
47
lui $at, %hi(nAssertLine)
48
sw $a1, %lo(nAssertLine)($at)
49
lui $at, %hi(pAssertExpression)
50
sw $a2, %lo(pAssertExpression)($at)
51
lui $at, %hi(nAssertStopProgram)
52
sw $a3, %lo(nAssertStopProgram)($at)
53
beqz $a3, .end_2
54
nop
55
syscall # trigger crash screen
56
.end_2:
57
jr $ra
58
nop
59
60
glabel cop0_get_cause
61
jr $ra
62
mfc0 $v0, COP0_CAUSE
63
64
glabel cop0_get_epc
65
jr $ra
66
mfc0 $v0, COP0_EPC
67
68
glabel cop0_get_badvaddr
69
jr $ra
70
mfc0 $v0, COP0_BADVADDR
71
72
# If the error code field of cop0's cause register is non-zero,
73
# draw crash details to the screen and hang
74
#
75
# If there wasn't an error, continue to the original handler
76
77
glabel __crash_handler_entry
78
mfc0 $k1, COP0_CAUSE
79
andi $k1, $k1, (0x1F << 2)
80
beqzl $k1, .end2 # exit if ExCode is 0
81
lui $k0, %hi(__osException)
82
la $k0, exceptionRegContext
83
sd $zero, 0x018 ($k0)
84
sd $at, 0x020 ($k0)
85
sd $v0, 0x028 ($k0)
86
sd $v1, 0x030 ($k0)
87
sd $a0, 0x038 ($k0)
88
sd $a1, 0x040 ($k0)
89
sd $a2, 0x048 ($k0)
90
sd $a3, 0x050 ($k0)
91
sd $t0, 0x058 ($k0)
92
sd $t1, 0x060 ($k0)
93
sd $t2, 0x068 ($k0)
94
sd $t3, 0x070 ($k0)
95
sd $t4, 0x078 ($k0)
96
sd $t5, 0x080 ($k0)
97
sd $t6, 0x088 ($k0)
98
sd $t7, 0x090 ($k0)
99
sd $s0, 0x098 ($k0)
100
sd $s1, 0x0A0 ($k0)
101
sd $s2, 0x0A8 ($k0)
102
sd $s3, 0x0B0 ($k0)
103
sd $s4, 0x0B8 ($k0)
104
sd $s5, 0x0C0 ($k0)
105
sd $s6, 0x0C8 ($k0)
106
sd $s7, 0x0D0 ($k0)
107
sd $t8, 0x0D8 ($k0)
108
sd $t9, 0x0E0 ($k0)
109
sd $gp, 0x0E8 ($k0)
110
sd $sp, 0x0F0 ($k0)
111
sd $fp, 0x0F8 ($k0)
112
sd $ra, 0x100 ($k0)
113
# cop unusable exception fired twice on startup so we'll ignore it for now
114
li $t0, (0x0B << 2)
115
beq $k1, $t0, .end
116
nop
117
jal show_crash_screen_and_hang
118
nop
119
.end:
120
ld $at, 0x020 ($k0)
121
ld $v0, 0x028 ($k0)
122
ld $v1, 0x030 ($k0)
123
ld $a0, 0x038 ($k0)
124
ld $a1, 0x040 ($k0)
125
ld $a2, 0x048 ($k0)
126
ld $a3, 0x050 ($k0)
127
ld $t0, 0x058 ($k0)
128
ld $t1, 0x060 ($k0)
129
ld $t2, 0x068 ($k0)
130
ld $t3, 0x070 ($k0)
131
ld $t4, 0x078 ($k0)
132
ld $t5, 0x080 ($k0)
133
ld $t6, 0x088 ($k0)
134
ld $t7, 0x090 ($k0)
135
ld $s0, 0x098 ($k0)
136
ld $s1, 0x0A0 ($k0)
137
ld $s2, 0x0A8 ($k0)
138
ld $s3, 0x0B0 ($k0)
139
ld $s4, 0x0B8 ($k0)
140
ld $s5, 0x0C0 ($k0)
141
ld $s6, 0x0C8 ($k0)
142
ld $s7, 0x0D0 ($k0)
143
ld $t8, 0x0D8 ($k0)
144
ld $t9, 0x0E0 ($k0)
145
ld $gp, 0x0E8 ($k0)
146
ld $sp, 0x0F0 ($k0)
147
ld $fp, 0x0F8 ($k0)
148
ld $ra, 0x100 ($k0)
149
lui $k0, %hi(__osException)
150
.end2:
151
addiu $k0, $k0, %lo(__osException)
152
jr $k0 # run the original handler
153
nop
154
155