/
mk_msu.asm
336 lines (301 loc) · 6.13 KB
/
mk_msu.asm
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
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
//**********************************************************
//* Super Mario Kart MSU-1 Audio Hack
//*
//* Copyright qwertymodo, 2017
//*
//* Assembler: bass v14
//* bass -d input=in.sfc -o out.sfc -create mk_msu.asm
//*
//* Song List:
//* 01: Race Fanfare
//* 05: Final Lap Notice
//* 08: Super Star Theme
//* 09: New Record
//* 10: No Record
//* 11: Ranked Out
//* 12: Mario's Rank
//* 13: Luigi's Rank
//* 14: Bowser's Rank
//* 15: Peach's Rank
//* 16: DK's Rank
//* 17: Koopa's Rank
//* 18: Toad's Rank
//* 19: Yoshi's Rank
//* 20: Game Over
//*
//* 32: Title Screen
//* 35: Kart Select
//* 36: Staff Roll
//* 38: Mario Circuit**
//* 41: Donut Plains**
//* 44: Choco Island**
//* 47: Koopa Beach**
//* 50: Vanilla Lake**
//* 53: Ghost Valley**
//* 56: Bowser Castle**
//* 59: Battle Mode**
//* 62: Tournament Win
//* 65: Tournament Lose
//* 71: Rainbow Road**
//*
//* 80: Mario Circuit 3*
//* 82: Ghost Valley 2*
//* 84: Donut Plains 2*
//* 86: Bowser Castle 2*
//* 88: Vanilla Lake 2*
//* 90: Rainbow Road*
//* 92: Koopa Beach 2*
//* 94: Mario Circuit 1*
//* 96: Ghost Valley 3*
//* 98: Bowser Castle 3*
//* 100: Choco Island 2*
//* 102: Donut Plains 3*
//* 104: Vanilla Lake 1*
//* 106: Koopa Beach 1*
//* 108: Mario Circuit 4*
//* 110: Mario Circuit 2*
//* 112: Ghost Valley 1*
//* 114: Bowser Castle 1*
//* 116: Choco Island 1*
//* 118: Donut Plains 1*
//*
//* [*] Song number +1 for fast version
//* [**] Same song for all songs, +1 for fast version
//**********************************************************
arch snes.cpu
define hirom()
define CHECKSUM($FD22)
include "snes_utils.inc"
include "msu-1_defs.inc"
warning "These RAM addresses are not confirmed to be unused"
define REG_CURRENT_VOLUME($7E012A)
define REG_TARGET_VOLUME($7E012B)
define REG_CURRENT_SONG($7E012C)
define REG_CURRENT_SONG_SHORT($012C)
define REG_CURRENT_TRACK($7E0124)
define VAL_VOLUME_INCREMENT(#$10)
define VAL_VOLUME_DECREMENT(#$10)
define VAL_VOLUME_MUTE(#$0F)
define VAL_VOLUME_HALF(#$80)
define VAL_VOLUME_FULL(#$FF)
scope {
seek($81F435)
jsl store_bank
nop; nop; nop;
assert_end($81F43C)
seek($C11FA0)
store_bank:
phb
phx
ldx #$0000
phx
plb
plb
plx
stx {REG_CURRENT_SONG_SHORT}
ldx #$C000
plb
jml continue
assert_end($C12000)
seek($84E09E)
continue:
}
scope {
seek($8097A3)
jsl msu_main
nop
assert_end($8097A8)
seek($C09615)
jsr msu_short_jump
assert_end($C0961A)
seek($C09300)
msu_short_jump:
jsl msu_main
rts
assert_end($C093F0)
seek($C21E60)
msu_main:
pha
phb
pha
lda #$00
pha
plb
pla
CHECK_FOR_MSU(spc_continue)
cmp #$00
beq do_fade
// Command $1D: Mute
+; cmp #$1D
bne +
lda #$00
sta {REG_TARGET_VOLUME}
sta {REG_MSU_VOLUME}
bra do_fade
// Command $1E: Fade Out
+; cmp #$1E
bne +
lda #$00
sta {REG_TARGET_VOLUME}
bra do_fade
// Command $1F: Fade In
+; cmp #$1F
bne +
lda #$FF
sta {REG_TARGET_VOLUME}
bra do_fade
// Command $04/$16: Play Song (Normal Speed)
+; cmp #$04
beq +
cmp #$16
bne ++
+; brl play_song_normal
// Command $06/07/15: Play Song (Fast Speed)
+; cmp #$06
beq +
cmp #$07
beq +
cmp #$15
bne ++
+; brl play_song_fast
// Command $08: Invincible
+; cmp #$08
// Resume??
bne +
brl play_song_normal
// Commands >= $20: Send to SPC normally
+; cmp #$20
bcc +
bra spc_continue
// Ranks
+; jsr check_song_exists
bcc spc_continue
cmp #$0C
bcc play_once
cmp #$14
bcs play_once
bra play_loop
do_fade:
lda {REG_CURRENT_VOLUME}
cmp {REG_TARGET_VOLUME}
beq spc_continue
bcc +
sbc {VAL_VOLUME_DECREMENT}
// cmp {VAL_VOLUME_MUTE}
bcs ++
lda #$00
sta {REG_CURRENT_VOLUME}
sta {REG_MSU_CONTROL} // Stop playback when fade completes
bra ++
+; adc {VAL_VOLUME_INCREMENT}
bcc +
lda {VAL_VOLUME_FULL}
+; sta {REG_CURRENT_VOLUME}
sta {REG_MSU_VOLUME}
bra spc_continue
play_loop:
lda {VAL_VOLUME_FULL}
sta {REG_TARGET_VOLUME}
sta {REG_CURRENT_VOLUME}
sta {REG_MSU_VOLUME}
lda #$03
sta {REG_MSU_CONTROL}
bra spc_mute
play_once:
lda {VAL_VOLUME_FULL}
sta {REG_TARGET_VOLUME}
sta {REG_CURRENT_VOLUME}
sta {REG_MSU_VOLUME}
lda #$01
sta {REG_MSU_CONTROL}
bra spc_mute
spc_mute:
plb
pla
lda #$1D
sta {REG_APU_PORT_0}
rep #$30
rtl
spc_continue:
plb
pla
sta {REG_APU_PORT_0}
rep #$30
rtl
spc_skip:
plb
pla
rep #$30
rtl
play_song_normal:
// Check special tracks
lda {REG_CURRENT_SONG}
// Title Screen
beq ++
// Select Screen
cmp #$03
beq ++
// Battle Mode
cmp #$1B
beq ++
// Tournament Win
cmp #$1E
beq ++
// Tournament Lose
cmp #$21
beq ++
// Staff Roll
cmp #$24
bne +
jsr check_song_exists
bcc spc_continue
bra play_once
// Check Track-Specific Songs
+; lda {REG_CURRENT_TRACK}
asl
clc
adc #$50
jsr check_song_exists
bcs play_loop
// Check Shared Songs
lda {REG_CURRENT_SONG}
+; clc
adc #$20
jsr check_song_exists
bcc spc_continue
bra play_loop
play_song_fast:
// Check Track-Specific Songs
lda {REG_CURRENT_TRACK}
asl
clc
adc #$51
jsr check_song_exists
bcc +
brl play_loop
// Check Shared Songs
+; lda {REG_CURRENT_SONG}
clc
adc #$21
jsr check_song_exists
bcc spc_continue
brl play_loop
// Input: Song # (A, 8-bit)
// Output: Carry flag, set = true, clear = false
check_song_exists:
pha
sta {REG_MSU_TRACK_LO}
stz {REG_MSU_TRACK_HI}
-; lda {REG_MSU_STATUS}
bit {FLAG_MSU_STATUS_AUDIO_BUSY}
bne -
bit {FLAG_MSU_STATUS_TRACK_MISSING}
bne +
pla
sec
rts
+; pla
clc
rts
assert_end($C22000)
}