forked from n64decomp/sm64
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrash.inc.s
158 lines (147 loc) · 4.06 KB
/
crash.inc.s
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# SM64 Crash Handler
# See Readme below.
.set COP0_CAUSE, 13
.set COP0_EPC, 14
.set COP0_BADVADDR, 8
/* ---------------------------------------------------------------
* IMPORTANT README:
* ---------------------------------------------------------------
* To use this crash screen, in lib/__osExceptionPreamble.s, change
* the function to use the following assembly:
*
* lui $k0, %hi(__crash_handler_entry)
* addiu $k0, $k0, %lo(__crash_handler_entry)
* jr $k0
* nop
*
* Doing just a jal __crash_handler_entry will cause mupen recompiler
* errors, so be sure to use the original exception style assembly
* above!
*
* Be sure to add #include "../../enhancements/crash.inc.c" to
* the top of game.c. Add .include "../enhancements/crash.inc.s" to
* the bottom of asm/decompress.s. Add "../enhancements/crash.h" to
* the top of sm64.h, above the CRASH_SCREEN_INCLUDED condition.
*
* See the DEBUG_ASSERT macro on how to call the crash screen for
* detected exceptions.
*/
glabel crashFont
.incbin "enhancements/crash_font.bin"
.align 4
glabel exceptionRegContext
.fill 0x108
glabel pAssertFile
.dword 0
glabel nAssertLine
.dword 0
glabel pAssertExpression
.dword 0
glabel nAssertStopProgram
.dword 0
glabel _n64_assert
lui $at, %hi(pAssertFile)
sw $a0, %lo(pAssertFile)($at)
lui $at, %hi(nAssertLine)
sw $a1, %lo(nAssertLine)($at)
lui $at, %hi(pAssertExpression)
sw $a2, %lo(pAssertExpression)($at)
lui $at, %hi(nAssertStopProgram)
sw $a3, %lo(nAssertStopProgram)($at)
beqz $a3, .end_2
nop
syscall # trigger crash screen
.end_2:
jr $ra
nop
glabel cop0_get_cause
jr $ra
mfc0 $v0, $13 # COP0_CAUSE
glabel cop0_get_epc
jr $ra
mfc0 $v0, $14 # COP0_EPC
glabel cop0_get_badvaddr
jr $ra
mfc0 $v0, $8 # COP0_BADVADDR
# If the error code field of cop0's cause register is non-zero,
# draw crash details to the screen and hang
#
# If there wasn't an error, continue to the original handler
glabel __crash_handler_entry
la $k0, exceptionRegContext
sd $zero, 0x018 ($k0)
sd $at, 0x020 ($k0)
sd $v0, 0x028 ($k0)
sd $v1, 0x030 ($k0)
sd $a0, 0x038 ($k0)
sd $a1, 0x040 ($k0)
sd $a2, 0x048 ($k0)
sd $a3, 0x050 ($k0)
sd $t0, 0x058 ($k0)
sd $t1, 0x060 ($k0)
sd $t2, 0x068 ($k0)
sd $t3, 0x070 ($k0)
sd $t4, 0x078 ($k0)
sd $t5, 0x080 ($k0)
sd $t6, 0x088 ($k0)
sd $t7, 0x090 ($k0)
sd $s0, 0x098 ($k0)
sd $s1, 0x0A0 ($k0)
sd $s2, 0x0A8 ($k0)
sd $s3, 0x0B0 ($k0)
sd $s4, 0x0B8 ($k0)
sd $s5, 0x0C0 ($k0)
sd $s6, 0x0C8 ($k0)
sd $s7, 0x0D0 ($k0)
sd $t8, 0x0D8 ($k0)
sd $t9, 0x0E0 ($k0)
sd $gp, 0x0E8 ($k0)
sd $sp, 0x0F0 ($k0)
sd $s8, 0x0F8 ($k0)
sd $ra, 0x100 ($k0)
mfc0 $t0, $13 # COP0_CAUSE
srl $t0, $t0, 2
andi $t0, $t0, 0x1F
beqz $t0, .end
nop
# cop unusable exception fired twice on startup so we'll ignore it for now
li $at, 0x0B
beq $t0, $at, .end
nop
jal show_crash_screen_and_hang
nop
.end:
ld $zero, 0x018 ($k0)
ld $at, 0x020 ($k0)
ld $v0, 0x028 ($k0)
ld $v1, 0x030 ($k0)
ld $a0, 0x038 ($k0)
ld $a1, 0x040 ($k0)
ld $a2, 0x048 ($k0)
ld $a3, 0x050 ($k0)
ld $t0, 0x058 ($k0)
ld $t1, 0x060 ($k0)
ld $t2, 0x068 ($k0)
ld $t3, 0x070 ($k0)
ld $t4, 0x078 ($k0)
ld $t5, 0x080 ($k0)
ld $t6, 0x088 ($k0)
ld $t7, 0x090 ($k0)
ld $s0, 0x098 ($k0)
ld $s1, 0x0A0 ($k0)
ld $s2, 0x0A8 ($k0)
ld $s3, 0x0B0 ($k0)
ld $s4, 0x0B8 ($k0)
ld $s5, 0x0C0 ($k0)
ld $s6, 0x0C8 ($k0)
ld $s7, 0x0D0 ($k0)
ld $t8, 0x0D8 ($k0)
ld $t9, 0x0E0 ($k0)
ld $gp, 0x0E8 ($k0)
ld $sp, 0x0F0 ($k0)
ld $s8, 0x0F8 ($k0)
ld $ra, 0x100 ($k0)
lui $k0, %hi(__osException)
addiu $k0, $k0, %lo(__osException)
jr $k0 # run the original handler
nop