Guest User

Untitled

a guest
Dec 19th, 2018
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 56.14 KB | None | 0 0
  1. .include "asm/macros.inc"
  2. .include "constants/gba_constants.inc"
  3. .include "constants/m4a_constants.inc"
  4.  
  5. .syntax unified
  6.  
  7. .text
  8.  
  9. thumb_func_start umul3232H32
  10. umul3232H32:
  11. adr r2, __umul3232H32
  12. bx r2
  13. .arm
  14. __umul3232H32:
  15. umull r2, r3, r0, r1
  16. add r0, r3, 0
  17. bx lr
  18. thumb_func_end umul3232H32
  19.  
  20. thumb_func_start SoundMain
  21. SoundMain:
  22. ldr r0, lt_SOUND_INFO_PTR
  23. ldr r0, [r0]
  24. ldr r2, lt_ID_NUMBER
  25. ldr r3, [r0, o_SoundInfo_ident]
  26. cmp r2, r3
  27. beq SoundMain_1
  28. bx lr @ Exit the function if ident doesn't match ID_NUMBER.
  29. SoundMain_1:
  30. adds r3, 1
  31. str r3, [r0, o_SoundInfo_ident]
  32. push {r4-r7,lr}
  33. mov r1, r8
  34. mov r2, r9
  35. mov r3, r10
  36. mov r4, r11
  37. push {r0-r4}
  38. sub sp, 0x18
  39. ldrb r1, [r0, o_SoundInfo_maxLines]
  40. cmp r1, 0 @ if maxLines is 0, there is no maximum
  41. beq SoundMain_3
  42. ldr r2, lt_REG_VCOUNT
  43. ldrb r2, [r2]
  44. cmp r2, VCOUNT_VBLANK
  45. bhs SoundMain_2
  46. adds r2, TOTAL_SCANLINES
  47. SoundMain_2:
  48. adds r1, r2
  49. SoundMain_3:
  50. str r1, [sp, 0x14]
  51. ldr r3, [r0, o_SoundInfo_func]
  52. cmp r3, 0
  53. beq SoundMain_4
  54. ldr r0, [r0, o_SoundInfo_intp]
  55. bl call_r3
  56. ldr r0, [sp, 0x18]
  57. SoundMain_4:
  58. ldr r3, [r0, o_SoundInfo_CgbSound]
  59. bl call_r3
  60. ldr r0, [sp, 0x18]
  61. ldr r3, [r0, o_SoundInfo_pcmSamplesPerVBlank]
  62. mov r8, r3
  63. ldr r5, lt_o_SoundInfo_pcmBuffer
  64. adds r5, r0
  65. ldrb r4, [r0, o_SoundInfo_pcmDmaCounter]
  66. subs r7, r4, 1
  67. bls SoundMain_5
  68. ldrb r1, [r0, o_SoundInfo_pcmDmaPeriod]
  69. subs r1, r7
  70. mov r2, r8
  71. muls r2, r1
  72. adds r5, r2
  73. SoundMain_5:
  74. str r5, [sp, 0x8]
  75. ldr r6, lt_PCM_DMA_BUF_SIZE
  76. ldr r3, lt_SoundMainRAM_Buffer
  77. bx r3
  78.  
  79. .align 2, 0
  80. lt_SOUND_INFO_PTR: .word SOUND_INFO_PTR
  81. lt_ID_NUMBER: .word ID_NUMBER
  82. lt_SoundMainRAM_Buffer: .word SoundMainRAM_Buffer + 1
  83. lt_REG_VCOUNT: .word REG_VCOUNT
  84. lt_o_SoundInfo_pcmBuffer: .word o_SoundInfo_pcmBuffer
  85. lt_PCM_DMA_BUF_SIZE: .word PCM_DMA_BUF_SIZE
  86. thumb_func_end SoundMain
  87.  
  88. .equ POKE_INIT, 1
  89. .equ DMA_FIX, 0
  90. .equ ENABLE_DECOMPRESSION, 1
  91.  
  92. @ stack variables
  93. .equ ARG_FRAME_LENGTH, 0x0 @ TODO actually use this variable
  94. .equ ARG_REMAIN_CHN, 0x4 @ This is the channel count variable
  95. .equ ARG_BUFFER_POS, 0x8 @ stores the current output buffer pointer
  96. .equ ARG_LOOP_START_POS, 0xC @ stores wave loop start position in channel loop
  97. .equ ARG_LOOP_LENGTH, 0x10 @ '' '' '' end position
  98. .equ ARG_BUFFER_POS_INDEX_HINT, 0x14
  99. .equ ARG_PCM_STRUCT, 0x18 @ pointer to engine the main work area
  100.  
  101. @ channel struct
  102. .equ CHN_STATUS, 0x0 @ [byte] channel status bitfield
  103. .equ CHN_MODE, 0x1 @ [byte] channel mode bitfield
  104. .equ CHN_VOL_1, 0x2 @ [byte] volume right
  105. .equ CHN_VOL_2, 0x3 @ [byte] volume left
  106. .equ CHN_ATTACK, 0x4 @ [byte] wave attack summand
  107. .equ CHN_DECAY, 0x5 @ [byte] wave decay factor
  108. .equ CHN_SUSTAIN, 0x6 @ [byte] wave sustain level
  109. .equ CHN_RELEASE, 0x7 @ [byte] wave release factor
  110. .equ CHN_ADSR_LEVEL, 0x9 @ [byte] current envelope level
  111. .equ CHN_FINAL_VOL_1, 0xA @ [byte] not used anymore!
  112. .equ CHN_FINAL_VOL_2, 0xB @ [byte] not used anymore!
  113. .equ CHN_ECHO_VOL, 0xC @ [byte] pseudo echo volume
  114. .equ CHN_ECHO_REMAIN, 0xD @ [byte] pseudo echo length
  115. .equ CHN_SAMPLE_COUNTDOWN, 0x18 @ [word] sample countdown in mixing loop
  116. .equ CHN_FINE_POSITION, 0x1C @ [word] inter sample position (23 bits)
  117. .equ CHN_FREQUENCY, 0x20 @ [word] sample rate (in Hz)
  118. .equ CHN_WAVE_OFFSET, 0x24 @ [word] wave header pointer
  119. .equ CHN_POSITION_ABS, 0x28 @ [word] points to the current position in the wave data (relative offset for compressed samples)
  120. .equ CHN_BLOCK_COUNT, 0x3C @ [word] only used for compressed samples: contains the value of the block that is currently decoded
  121.  
  122. @ wave header struct
  123. .equ WAVE_LOOP_FLAG, 0x3 @ [byte] 0x0 = oneshot @ 0x40 = looped
  124. .equ WAVE_FREQ, 0x4 @ [word] pitch adjustment value = mid-C samplerate * 1024
  125. .equ WAVE_LOOP_START, 0x8 @ [word] loop start position
  126. .equ WAVE_LENGTH, 0xC @ [word] loop end / wave end position
  127. .equ WAVE_DATA, 0x10 @ [byte array] actual wave data
  128.  
  129. @ pulse wave synth configuration offset
  130. .equ SYNTH_BASE_WAVE_DUTY, 0x1 @ [byte]
  131. .equ SYNTH_WIDTH_CHANGE_1, 0x2 @ [byte]
  132. .equ SYNTH_MOD_AMOUNT, 0x3 @ [byte]
  133. .equ SYNTH_WIDTH_CHANGE_2, 0x4 @ [byte]
  134.  
  135. @ CHN_STATUS flags - 0x0 = OFF
  136. .equ FLAG_CHN_INIT, 0x80 @ [bit] write this value to init a channel
  137. .equ FLAG_CHN_RELEASE, 0x40 @ [bit] write this value to release (fade out) the channel
  138. .equ FLAG_CHN_COMP, 0x20 @ [bit] is wave being played compressed (yes/no)
  139. .equ FLAG_CHN_LOOP, 0x10 @ [bit] loop (yes/no)
  140. .equ FLAG_CHN_ECHO, 0x4 @ [bit] echo phase
  141. .equ FLAG_CHN_ATTACK, 0x3 @ [bit] attack phase
  142. .equ FLAG_CHN_DECAY, 0x2 @ [bit] decay phase
  143. .equ FLAG_CHN_SUSTAIN, 0x1 @ [bit] sustain phase
  144.  
  145. @ CHN_MODE flags
  146. .equ MODE_FIXED_FREQ, 0x8 @ [bit] set to disable resampling (i.e. playback with output rate)
  147. .equ MODE_REVERSE, 0x10 @ [bit] set to reverse sample playback
  148. .equ MODE_COMP, 0x30 @ [bit] is wave being played compressed or reversed (TODO: rename flag)
  149. .equ MODE_SYNTH, 0x40 @ [bit] READ ONLY, indicates synthzied output
  150.  
  151. @ variables of the engine work area
  152. .equ VAR_REVERB, 0x5 @ [byte] 0-127 = reverb level
  153. .equ VAR_MAX_CHN, 0x6 @ [byte] maximum channels to process
  154. .equ VAR_MASTER_VOL, 0x7 @ [byte] PCM master volume
  155. .equ VAR_DEF_PITCH_FAC, 0x18 @ [word] this value gets multiplied with the samplerate for the inter sample distance
  156. .equ VAR_FIRST_CHN, 0x50 @ [CHN struct] relative offset to channel array
  157.  
  158. @ just some more defines
  159. .equ REG_DMA3_SRC, 0x040000D4
  160. .equ ARM_OP_LEN, 0x4
  161.  
  162. .syntax divided
  163.  
  164. thumb_func_start SoundMainRAM
  165. SoundMainRAM:
  166. main_mixer:
  167. @ load Reverb level and check if we need to apply it
  168. LDRB R3, [R0, #VAR_REVERB]
  169. LSR R3, R3, #2
  170. BEQ clear_buffer
  171.  
  172. ADR R1, do_reverb
  173. BX R1
  174.  
  175. .align 2
  176. .arm
  177.  
  178. do_reverb:
  179.  
  180. @ Reverb is calculated by the following: new_sample = old_sample * reverb_level / 127
  181. @ note that reverb is mono (both sides get mixed together)
  182.  
  183. @ Reverb gets applied to the frame we are currently looking at and the one after that
  184. @ the magic below simply calculateds the pointer for the one after the current one
  185.  
  186.  
  187. cmp R4, #2
  188. addeq r7, r0, #0x350
  189. addne r7, r5, r8
  190. mov r4, r8
  191. orr r3, r3, r3, lsl#16
  192. stmfd sp!, {r8, lr}
  193. ldr lr, hq_buffer
  194.  
  195. reverb_loop:
  196. @ This loop does the reverb processing
  197. ldrsb r0, [r5, r6]
  198. ldrsb r1, [r5], #1
  199. ldrsb r2, [r7, r6]
  200. ldrsb r8, [r7], #1
  201. ldrsb r9, [r5, r6]
  202. ldrsb r10, [r5], #1
  203. ldrsb r11, [r7, r6]
  204. ldrsb r12, [r7], #1
  205. add r0, r0, r1
  206. add r0, r0, r2
  207. adds r0, r0, r8
  208. addmi r0, r0, #0x4
  209. add r1, r9, r10
  210. add r1, r1, r11
  211. adds r1, r1, r12
  212. addmi r1, r1, #0x4
  213. mul r0, r3, r0
  214. mul r1, r3, r1
  215. stmia lr!, {r0, r1}
  216. subs r4, r4, #2
  217. bgt reverb_loop
  218. @ end of loop
  219. ldmfd sp!, {r8, lr}
  220. adr r0, (C_setup_channel_state_loop+1)
  221. bx r0
  222.  
  223. .thumb
  224.  
  225. clear_buffer:
  226. @ In case reverb is disabled the buffer gets set to zero
  227. ldr r3, hq_buffer
  228. mov r1, r8
  229. mov r4, #0
  230. mov r5, #0
  231. mov r6, #0
  232. mov r7, #0
  233.  
  234. @ Setting the buffer to zero happens in a very efficient loop
  235. @ Depending on the alignment of the buffer length, twice or quadruple the amount of bytes
  236. @ get cleared at once
  237.  
  238. lsr r1, #3
  239. bcc C_clear_buffer_align_8
  240.  
  241. stmia r3!, {r4, r5, r6, r7}
  242.  
  243. C_clear_buffer_align_8:
  244. lsr r1, #1
  245. bcc C_clear_buffer_align_16
  246.  
  247. STMIA R3!, {R4, R5, R6, R7}
  248. STMIA R3!, {R4, R5, R6, R7}
  249.  
  250. C_clear_buffer_align_16:
  251. stmia r3!, {r4, r5, r6, r7}
  252. stmia r3!, {r4, r5, r6, r7}
  253. stmia r3!, {r4, r5, r6, r7}
  254. stmia r3!, {r4, r5, r6, r7}
  255.  
  256. sub r1, #1
  257. bgt C_clear_buffer_align_16
  258. mov r1, #1
  259. strb r1, [r2]
  260. b C_setup_channel_state_loop
  261.  
  262. .align 2
  263. is_buffer_init:
  264. .byte 0x0
  265.  
  266. .align 1
  267.  
  268. C_setup_channel_state_loop:
  269.  
  270. @ Before the actual mixing starts,
  271. @ the volume and envelope calculation take place
  272.  
  273. mov r4, r8 @ r4 = buffer length
  274.  
  275. @ this stroes the buffer length to a backup location
  276.  
  277. str r4, [sp, #ARG_FRAME_LENGTH]
  278. @ init channel loop
  279. ldr r4, [sp, #ARG_PCM_STRUCT] @ r4 = main work area pointer
  280. ldr r0, [r4, #VAR_DEF_PITCH_FAC] @ r0 = samplingrate pitch factor
  281. mov r12, r0
  282. ldrb r0, [r4, #VAR_MAX_CHN]
  283. add r4, #VAR_FIRST_CHN @ R4 = Base channel Offset (Channel #0)
  284.  
  285. C_channel_state_loop:
  286. @ this is the main channel processing loop
  287. str r0, [sp, #ARG_REMAIN_CHN]
  288. ldr r3, [r4, #CHN_WAVE_OFFSET]
  289. ldrb r6, [r4, #CHN_STATUS] @ r6 will hold the channel status
  290. movs r0, #0xC7 @ check if any of the channel status flags is set
  291. tst r0, r6 @ check if none of the flags is set
  292. beq C_skip_channel
  293. @ check channel flags
  294. lsl r0, r6, #25 @ shift over the FLAG_CHN_INIT to CARRY
  295. bcc C_adsr_echo_check @ continue with normal channel procedure
  296. @ check leftmost bit
  297. bmi C_stop_channel @ FLAG_CHN_INIT | FLAG_CHN_RELEASE -> stop directly
  298. @ channel init procedure
  299. movs r6, #FLAG_CHN_ATTACK
  300. movs r0, r3 @ r0 = CHN_WAVE_OFFSET
  301. add r0, #WAVE_DATA @ r0 = wave data offset
  302.  
  303. @ Pokemon games seem to init channels differently than other m4a games
  304. .if POKE_INIT==0
  305. str r0, [r4, #CHN_POSITION_ABS]
  306. ldr r0, [r3, #WAVE_LENGTH]
  307. str r0, [r4, #CHN_SAMPLE_COUNTDOWN]
  308. .else
  309. ldr r1, [r4, #CHN_SAMPLE_COUNTDOWN]
  310. add r0, r0, r1
  311. str r0, [r4, #CHN_POSITION_ABS]
  312. ldr r0, [r3, #WAVE_LENGTH]
  313. sub r0, r0, r1
  314. str r0, [r4, #CHN_SAMPLE_COUNTDOWN]
  315. .endif
  316.  
  317. movs r5, #0 @ initial envelope = #0
  318. strb r5, [r4, #CHN_ADSR_LEVEL]
  319. str r5, [r4, #CHN_FINE_POSITION]
  320. ldrb r2, [r3, #WAVE_LOOP_FLAG]
  321. lsr r0, r2, #6
  322. beq C_adsr_attack
  323. @ loop enabled here
  324. movs r0, #FLAG_CHN_LOOP
  325. orr r6, r0
  326. b C_adsr_attack
  327.  
  328. C_adsr_echo_check:
  329. @ this is the normal ADSR procedure without init
  330. ldrb r5, [r4, #CHN_ADSR_LEVEL]
  331. lsl r0, r6, #29 @ FLAG_CHN_ECHO --> bit 31 (sign bit)
  332. bpl C_adsr_release_check
  333. @ pseudo echo handler
  334. ldrb r0, [r4, #CHN_ECHO_REMAIN]
  335. sub r0, #1
  336. strb r0, [r4, #CHN_ECHO_REMAIN]
  337. bhi C_channel_vol_calc @ continue normal if channel is still on
  338.  
  339. C_stop_channel:
  340. movs r0, #0
  341. strb r0, [r4, #CHN_STATUS]
  342.  
  343. C_skip_channel:
  344. @ Go to end of the channel loop
  345. b C_end_channel_state_loop
  346.  
  347. C_adsr_release_check:
  348. lsl r0, r6, #25 @ FLAG_CHN_RELEASE --> bit 31 (sign bit)
  349. bpl C_adsr_decay_check
  350. @ release handler
  351. ldrb r0, [r4, #CHN_RELEASE]
  352. @sub r0, #0xFF @ linear decay @ TODO: make option for triggering it
  353. @sub r0, #1
  354. @add r5, r5, r0
  355. mul r5, r5, r0
  356. lsr r5, #8
  357. ble C_adsr_released
  358. @ pseudo echo init handler
  359. ldrb r0, [r4, #CHN_ECHO_VOL]
  360. cmp r5, r0
  361. bhi C_channel_vol_calc
  362.  
  363. C_adsr_released:
  364. @ if volume released to #0
  365. ldrb r5, [r4, #CHN_ECHO_VOL]
  366. cmp r5, #0
  367. beq C_stop_channel
  368. @ pseudo echo volume handler
  369. movs r0, #FLAG_CHN_ECHO
  370. orr r6, r0 @ set the echo flag
  371. b C_adsr_save_and_finalize
  372.  
  373. C_adsr_decay_check:
  374. @ check if decay is active
  375. movs r2, #(FLAG_CHN_DECAY+FLAG_CHN_SUSTAIN)
  376. and r2, r6
  377. cmp r2, #FLAG_CHN_DECAY
  378. bne C_adsr_attack_check @ Decay not active yet
  379. @ decay handler
  380. ldrb r0, [r4, #CHN_DECAY]
  381. mul r5, r5, r0
  382. lsr r5, r5, #8
  383. ldrb r0, [r4, #CHN_SUSTAIN]
  384. cmp r5, r0
  385. bhi C_channel_vol_calc @ Sample didn't decay yet
  386. @ sustain handler
  387. movs r5, r0 @ Current level = sustain level
  388. beq C_adsr_released @ sustain level #0 --> branch
  389. @ step to next phase otherweise
  390. b C_adsr_next_state
  391.  
  392. C_adsr_attack_check:
  393. @ attack handler
  394. cmp r2, #FLAG_CHN_ATTACK
  395. bne C_channel_vol_calc @ If it isn't in attack attack phase, it has to be in sustain (keep vol) --> branch
  396.  
  397. C_adsr_attack:
  398. @ apply attack summand
  399. ldrb r0, [r4, #CHN_ATTACK]
  400. add r5, r0
  401. cmp r5, #0xFF
  402. blo C_adsr_save_and_finalize
  403. @ cap attack at 0xFF
  404. movs r5, #0xFF
  405.  
  406. C_adsr_next_state:
  407. @ switch to next adsr phase
  408. sub r6, #1
  409.  
  410. C_adsr_save_and_finalize:
  411. @ store channel status
  412. strb r6, [r4, #CHN_STATUS]
  413.  
  414. C_channel_vol_calc:
  415. @ store the calculated ADSR level
  416. strb r5, [r4, #CHN_ADSR_LEVEL]
  417. @ apply master volume
  418. ldr r0, [sp, #ARG_PCM_STRUCT]
  419. ldrb r0, [r0, #VAR_MASTER_VOL]
  420. add r0, #1
  421. mul r5, r0
  422. @ left side volume
  423. ldrb r0, [r4, #CHN_VOL_2]
  424. mul r0, r5
  425. lsr r0, #13
  426. mov r10, r0 @ r10 = Left volume
  427. @ right side volume
  428. ldrb r0, [r4, #CHN_VOL_1]
  429. mul r0, r5
  430. lsr r0, #13
  431. mov r11, r0 @ r11 = Right volume
  432.  
  433. @ Now we get closer to actual mixing:
  434. @ For looped samples some additional operations are required
  435.  
  436. movs r0, #FLAG_CHN_LOOP
  437. and r0, r6
  438. beq C_skip_sample_loop_setup
  439. @ loop setup handler
  440. add r3, #WAVE_LOOP_START
  441. ldmia r3!, {r0, r1} @ r0 = loop start, r1 = loop end
  442. add r3, r0 @ r3 = loop start position (absolute)
  443. str r3, [sp, #ARG_LOOP_START_POS]
  444. sub r0, r1, r0
  445.  
  446. C_skip_sample_loop_setup:
  447. @ do the rest of the setup
  448. str r0, [sp, #ARG_LOOP_LENGTH] @ if loop is off --> r0 = 0x0
  449. ldr r5, hq_buffer
  450. ldr r2, [r4, #CHN_SAMPLE_COUNTDOWN]
  451. ldr r3, [r4, #CHN_POSITION_ABS]
  452. ldrb r0, [r4, #CHN_MODE]
  453. adr r1, C_mixing_setup
  454. bx r1
  455.  
  456. .align 2
  457. hq_buffer:
  458. .word hq_buffer_ptr
  459.  
  460. .arm
  461. .align 2
  462.  
  463. C_mixing_setup:
  464. @ frequency and mixing loading routine
  465. ldr r8, [sp, #ARG_FRAME_LENGTH]
  466. orrs r11, r11, r10, lsl#16 @ r11 = 00LL00RR
  467. beq C_mixing_epilogue @ volume #0 --> branch and skip channel processing
  468. @ normal processing otherwise
  469. tst r0, #MODE_FIXED_FREQ
  470. bne C_setup_fixed_freq_mixing
  471. tst r0, #MODE_COMP
  472. bne C_setup_special_mixing @ compressed? --> branch
  473.  
  474. stmfd sp!, {r4, r9, r12}
  475.  
  476. @ This mixer supports 4 different kind of synthesized sounds
  477. @ They are triggered if there is no samples to play
  478. @ This gets checked below
  479.  
  480. movs r2, r2
  481. orreq r0, r0, #MODE_SYNTH
  482. streqb r0, [r4, #CHN_MODE]
  483. add r4, r4, #CHN_FINE_POSITION
  484. ldmia r4, {r7, lr} @ r7 = Fine Position, lr = Frequency
  485. mul r4, lr, r12 @ r4 = inter sample steps = output rate factor * samplerate
  486. @ now the first samples get loaded
  487. ldrsb r6, [r3], #1
  488. ldrsb r12, [r3]
  489. tst r0, #MODE_SYNTH
  490. bne C_setup_synth
  491. @ In case no synth mode should be used, code contiues here
  492. sub r12, r12, r6 @ r12 = DELTA
  493.  
  494. @ Mixing goes with volume ranges 0-127
  495. @ They come in 0-255 --> divide by 2
  496.  
  497. movs r11, r11, lsr#1
  498. adc r11, r11, #0x8000
  499. bic r11, r11, #0xff00
  500. mov r1, r7 @ r1 = inter sample position
  501.  
  502. @ There is 2 different mixing codepaths for uncompressed data
  503. @ Path 1: fast mixing, but doesn't supports loop or stop
  504. @ Path 2: not so fast but supports sample loops / stop
  505. @ This checks if there is enough samples aviable for path 1.
  506. @ Important: r0 is expected to be #0
  507.  
  508. umlal r1, r0, r4, r8
  509. mov r1, r1, lsr#23
  510. orr r0, r1, r0, lsl#9
  511. cmp r2, r0 @ actual comparison
  512. ble C_setup_unbuffered_mixing @ if not enough samples are available for path 1 --> branch
  513.  
  514. @ This is the mixer path 1.
  515. @ The interesting thing here is that the code will
  516. @ buffer enough samples on stack if enough space
  517. @ on stack is available (or goes over the limit of 0x400 bytes)
  518.  
  519. sub r2, r2, r0
  520. ldr r10, upper_stack_bounds
  521. add r10, r10, r0
  522. cmp r10, sp
  523. add r10, r3, r0
  524.  
  525. @ r2 = Remaining samples after processing
  526. @ r10 = Final sample position
  527. @ sp = Original stack location
  528. @ These values will get reloaded after channel processing
  529. @ due to the lack of registers.
  530.  
  531. stmfd sp!, {r2, r10}
  532. cmpcc r0, #0x400 @ > 0x400 bytes --> read directly from ROM rather than buffered
  533. mov r10, sp
  534. bcs C_select_highspeed_codepath
  535.  
  536. @ The code below inits the DMA to read word aligned
  537. @ samples from ROM to stack
  538.  
  539. bic r1, r3, #3
  540. mov r9, #0x04000000
  541. add r9, r9, #0xD4
  542. add r0, r0, #7
  543. mov r0, r0, lsr#2
  544. sub sp, sp, r0, lsl#2
  545. and r3, r3, #3
  546. add r3, r3, sp
  547. orr lr, r0, #0x84000000
  548. stmia r9, {r1, sp, lr} @ Actually starts the DMA
  549.  
  550. @ Somehow is neccesary for some games not to break
  551. .if DMA_FIX==1
  552. mov r0, #0
  553. mov r1, #0
  554. mov r2, #0
  555. stmia r9, {r0, r1, r2}
  556. .endif
  557.  
  558. C_select_highspeed_codepath:
  559. stmfd sp!, {r10} @ save original sp for VLA
  560.  
  561. @ This code decides which piece of code to load
  562. @ depending on playback-rate / default-rate ratio.
  563. @ Modes > 1.0 run with different volume levels.
  564. @ r4 = inter sample step
  565.  
  566. adr r0, high_speed_code_resource @ loads the base pointer of the code
  567. subs r4, r4, #0x800000
  568. movpl r11, r11, lsl#1 @ if >= 1.0* 0-127 --> 0-254 volume level
  569. addpl r0, r0, #(ARM_OP_LEN*6) @ 6 instructions further
  570. subpls r4, r4, #0x800000 @ if >= 2.0*
  571. addpl r0, r0, #(ARM_OP_LEN*6)
  572. addpl r4, r4, #0x800000
  573. ldr r2, previous_fast_code
  574. cmp r0, r2 @ code doesn't need to be reloaded if it's already in place
  575. beq C_skip_fast_mixing_creation
  576. @ This loads the needed code to RAM
  577. str r0, previous_fast_code
  578. ldmia r0, {r0-r2, r8-r10} @ load 6 opcodes
  579. adr lr, fast_mixing_instructions
  580.  
  581. C_fast_mixing_creation_loop:
  582. @ Paste code to destination, see below for patterns
  583. stmia lr, {r0, r1}
  584. add lr, lr, #(ARM_OP_LEN*38)
  585. stmia lr, {r0, r1}
  586. sub lr, lr, #(ARM_OP_LEN*35)
  587. stmia lr, {r2, r8-r10}
  588. add lr, lr, #(ARM_OP_LEN*38)
  589. stmia lr, {r2, r8-r10}
  590. sub lr, lr, #(ARM_OP_LEN*32)
  591. adds r5, r5, #0x40000000 @ do that for 4 blocks
  592. bcc C_fast_mixing_creation_loop
  593.  
  594. ldr r8, [sp] @ Restore r8 with the frame length
  595. ldr r8, [r8, #(ARG_FRAME_LENGTH + 0x8 + 0xC)]
  596.  
  597. C_skip_fast_mixing_creation:
  598. mov r2, #0xFF000000 @ load the fine position overflow bitmask
  599. C_fast_mixing_loop:
  600. @ This is the actual processing and interpolation code loop @ NOPs will be replaced by the code above
  601. ldmia r5, {r0, r1, r10, lr} @ load 4 stereo samples to Registers
  602. mul r9, r7, r12
  603. fast_mixing_instructions:
  604. nop @ Block #1
  605. nop
  606. mlane r0, r11, r9, r0
  607. nop
  608. nop
  609. nop
  610. nop
  611. bic r7, r7, r2, asr#1
  612. mulne r9, r7, r12
  613. nop @ Block #2
  614. nop
  615. mlane r1, r11, r9, r1
  616. nop
  617. nop
  618. nop
  619. nop
  620. bic r7, r7, r2, asr#1
  621. mulne r9, r7, r12
  622. nop @ Block #3
  623. nop
  624. mlane r10, r11, r9, r10
  625. nop
  626. nop
  627. nop
  628. nop
  629. bic r7, r7, r2, asr#1
  630. mulne r9, r7, r12
  631. nop @ Block #4
  632. nop
  633. mlane lr, r11, r9, lr
  634. nop
  635. nop
  636. nop
  637. nop
  638. bic r7, r7, r2, asr#1
  639. stmia r5!, {r0, r1, r10, lr} @ Write 4 stereo samples
  640.  
  641. ldmia r5, {r0, r1, r10, lr} @ Load the next 4 stereo samples
  642. mulne r9, r7, r12
  643. nop @ Block #1
  644. nop
  645. mlane r0, r11, r9, r0
  646. nop
  647. nop
  648. nop
  649. nop
  650. bic r7, r7, r2, asr#1
  651. mulne r9, r7, r12
  652. nop @ Block #2
  653. nop
  654. mlane r1, r11, r9, r1
  655. nop
  656. nop
  657. nop
  658. nop
  659. bic r7, r7, r2, asr#1
  660. mulne r9, r7, r12
  661. nop @ Block #3
  662. nop
  663. mlane r10, r11, r9, r10
  664. nop
  665. nop
  666. nop
  667. nop
  668. bic r7, r7, r2, asr#1
  669. mulne r9, r7, r12
  670. nop @ Block #4
  671. nop
  672. mlane lr, r11, r9, lr
  673. nop
  674. nop
  675. nop
  676. nop
  677. bic r7, r7, r2, asr#1
  678. stmia r5!, {r0, r1, r10, lr} @ write 4 stereo samples
  679. subs r8, r8, #8
  680. bgt C_fast_mixing_loop
  681. @ restore previously saved values
  682. ldmfd sp, {sp} @ Reload original stack pointer from VLA
  683. ldmfd sp!, {r2, r3}
  684. b C_end_mixing
  685.  
  686. @ Various variables for the cached mixer
  687.  
  688. .align 2
  689. upper_stack_bounds:
  690. .word 0x03007910
  691. previous_fast_code:
  692. .word 0x0 @ Mark as invalid initially
  693.  
  694. @ These instructions are used by the high speed loop self modifying code
  695. high_speed_code_resource:
  696. @ Block for Mix Freq < 1.0 * Output Frequency
  697. mov r9, r9, asr#22
  698. adds r9, r9, r6, lsl#1
  699. adds r7, r7, r4
  700. addpl r6, r12, r6
  701. ldrplsb r12, [r3, #1]!
  702. subpls r12, r12, r6
  703.  
  704. @ Block for Mix Freq > 1.0 AND < 2.0 * Output Frequency
  705. adds r9, r6, r9, asr#23
  706. add r6, r12, r6
  707. adds r7, r7, r4
  708. ldrplsb r6, [r3, #1]!
  709. ldrsb r12, [r3, #1]!
  710. subs r12, r12, r6
  711.  
  712. @ Block for Mix Freq > 2.0 * Output Frequency
  713. adds r9, r6, r9, asr#23
  714. add r7, r7, r4
  715. add r3, r3, r7, lsr#23
  716. ldrsb r6, [r3]
  717. ldrsb r12, [r3, #1]!
  718. subs r12, r12, r6
  719.  
  720. @ In case a loop or end occurs during mixing, this code is used
  721. C_setup_unbuffered_mixing:
  722. add r5, r5, r8, lsl#2 @ r5 = End of HQ buffer
  723.  
  724. @ This below is the unbuffered mixing loop. R6 = base sample, R12 diff to next
  725. C_unbuffered_mixing_loop:
  726.  
  727. mul r9, r7, r12
  728. mov r9, r9, asr#22
  729. adds r9, r9, r6, lsl#1
  730. ldrne r0, [r5, -r8, lsl#2]
  731. mlane r0, r11, r9, r0
  732. strne r0, [r5, -r8, lsl#2]
  733. add r7, r7, r4
  734. movs r9, r7, lsr#23
  735. beq C_unbuffered_mixing_skip_load @ skip the mixing load if it isn't required
  736.  
  737. subs r2, r2, r7, lsr#23
  738. blle C_mixing_loop_or_end
  739. subs r9, r9, #1
  740. addeq r6, r12, r6
  741. @ Return location from loop handler
  742. ldrnesb r6, [r3, r9]!
  743. ldrsb r12, [r3, #1]!
  744. sub r12, r12, r6
  745. bic r7, r7, #0x3F800000
  746.  
  747. C_unbuffered_mixing_skip_load:
  748. subs r8, r8, #1 @ Reduce the sample count for the buffer by #1
  749. bgt C_unbuffered_mixing_loop
  750.  
  751. C_end_mixing:
  752. sub r3, r3, #1 @ Because the mixer always needs 1 byte lookahead, this reverts it
  753. ldmfd sp!, {r4, r9, r12}
  754. str r7, [r4, #CHN_FINE_POSITION]
  755. b C_mixing_end_store
  756.  
  757. C_mixing_loop_or_end:
  758. @ This loads the loop information end loops incase it should
  759. add r3, sp, #ARG_LOOP_START_POS+0xC
  760. ldmia r3, {r3, r6} @ r3 = Loop Start @ r6 = loop length
  761. cmp r6, #0 @ Check if loop is enabled @ If loop is enabled r6 is != 0
  762. rsbne r9, r2, #0 @ Loop wraparound logic
  763. addne r2, r6, r2
  764. addne pc, lr, #(ARM_OP_LEN*2)
  765. ldmfd sp!, {r4, r9, r12}
  766. b C_mixing_end_and_stop_channel @ R6 == 0 (always)
  767.  
  768. C_fixed_mixing_loop_or_end:
  769. ldr r2, [sp, #ARG_LOOP_LENGTH+0x8]
  770. movs r6, r2 @ Copy it to r6 and check whether loop is disabled
  771. ldrne r3, [sp, #ARG_LOOP_START_POS+0x8]
  772. bxne lr @ If it loops, return to mixing function if it doesn't go on end mixing
  773.  
  774. ldmfd sp!, {r4, r9}
  775.  
  776. C_mixing_end_and_stop_channel:
  777. strb r6, [r4] @ update channel flag with chn halt
  778. B C_mixing_epilogue
  779.  
  780. @ These are used for the fixed freq mixer
  781. fixed_mixing_code_resource:
  782. movs r6, r10, lsl#24
  783. movs r6, r6, asr#24
  784. movs r6, r10, lsl#16
  785. movs r6, r6, asr#24
  786. movs r6, r10, lsl#8
  787. movs r6, r6, asr#24
  788. movs r6, r10, asr#24
  789. ldmia r3!, {r10} @ Load chunk of samples
  790. movs r6, r10, lsl#24
  791. movs r6, r6, asr#24
  792. movs r6, r10, lsl#16
  793. movs r6, r6, asr#24
  794. movs r6, r10, lsl#8
  795. movs r6, r6, asr#24
  796. ldmfd sp!, {r4, r9, r12}
  797.  
  798. C_setup_fixed_freq_mixing:
  799. stmfd sp!, {r4, r9}
  800.  
  801. C_fixed_mixing_length_check:
  802. mov lr, r2 @ Sample countdown
  803. cmp r2, r8
  804. movgt lr, r8 @ Min(buffer_size, sample_countdown)
  805. sub lr, lr, #1
  806. movs lr, lr, lsr#2
  807. beq C_fixed_mixing_process_rest @ <= 3 samples to process
  808.  
  809. sub r8, r8, lr, lsl#2 @ subtract the amount of samples we need to process from the buffer length
  810. sub r2, r2, lr, lsl#2 @ subtract the amount of samples we need to process from the remaining samples
  811. adr r1, fixed_mixing_instructions
  812. adr r0, fixed_mixing_code_resource
  813. mov r9, r3, lsl#30
  814. add r0, r0, r9, lsr#27 @ Alignment * 8 + resource offset = new resource offset
  815. ldmia r0!, {r6, r7, r9, r10} @ load and write instructions
  816. stmia r1, {r6, r7}
  817. add r1, r1, #0xc
  818. stmia r1, {r9, r10}
  819. add r1, r1, #0xc
  820. ldmia r0, {r6, r7, r9, r10}
  821. stmia r1, {r6, r7}
  822. add r1, r1, #0xc
  823. stmia r1, {r9, r10}
  824. ldmia r3!, {r10} @ load 4 samples from ROM
  825.  
  826. C_fixed_mixing_loop:
  827. ldmia r5, {r0, r1, r7, r9} @ load 4 samples from hq buffer
  828.  
  829. fixed_mixing_instructions:
  830. nop
  831. nop
  832. mlane r0, r11, r6, r0 @ add new sample if neccessary
  833. nop
  834. nop
  835. mlane r1, r11, r6, r1
  836. nop
  837. nop
  838. mlane r7, r11, r6, r7
  839. nop
  840. nop
  841. mlane r9, r11, r6, r9
  842. stmia r5!, {r0, r1, r7, r9} @ Write samples to the mixing buffer
  843. subs lr, lr, #1
  844. bne C_fixed_mixing_loop
  845.  
  846. sub r3, r3, #4 @ We'll need to load this block again, so rewind a bit
  847.  
  848. C_fixed_mixing_process_rest:
  849. mov r1, #4 @ Repeat the loop #4 times to completely get rid of alignment errors
  850.  
  851. C_fixed_mixing_unaligned_loop:
  852. ldr r0, [r5]
  853. ldrsb r6, [r3], #1
  854. mla r0, r11, r6, r0
  855. str r0, [r5], #4
  856. subs r2, r2, #1
  857. bleq C_fixed_mixing_loop_or_end
  858. subs r1, r1, #1
  859. bgt C_fixed_mixing_unaligned_loop
  860.  
  861. subs r8, r8, #4
  862. bgt C_fixed_mixing_length_check @ repeat the mixing procedure until the buffer is filled
  863.  
  864. ldmfd sp!, {r4, r9}
  865.  
  866. C_mixing_end_store:
  867. str r2, [r4, #CHN_SAMPLE_COUNTDOWN]
  868. str r3, [r4, #CHN_POSITION_ABS]
  869.  
  870. C_mixing_epilogue:
  871. adr r0, (C_end_channel_state_loop+1)
  872. bx r0
  873.  
  874. .thumb
  875.  
  876. C_end_channel_state_loop:
  877. ldr r0, [sp, #ARG_REMAIN_CHN]
  878. sub r0, #1
  879. ble C_main_mixer_return
  880.  
  881. add r4, #0x40
  882. b C_channel_state_loop
  883.  
  884. C_main_mixer_return:
  885. adr r5, V_noise_shape
  886. ldrb r4, [r5, #0] @ left noise shape
  887. lsl r4, r4, #16
  888. ldrb r5, [r5, #1] @ right noise shape
  889. lsl r5, r5, #16
  890. adr r0, C_downsampler
  891. bx r0
  892.  
  893.  
  894. V_noise_shape:
  895. .byte 0, 0
  896.  
  897. .arm
  898. .align 2
  899.  
  900. C_downsampler:
  901. ldr r8, [sp, #ARG_FRAME_LENGTH]
  902. ldr r9, [sp, #ARG_BUFFER_POS]
  903. LDR R10, hq_buffer
  904. mov r11, #0xFF000000
  905. mov lr, #0xC0000000
  906.  
  907. C_downsampler_loop:
  908. ldmia r10, {r0, r1, r2, r3}
  909. add r12, r4, r0 @ left sample #1
  910. adds r4, r12, r12
  911. eorvs r12, lr, r4, asr#31
  912. and r4, r12, #0x007F0000
  913. and r6, r11, r12, lsl#1
  914.  
  915. add r0, r5, r0, lsl#16 @ right
  916. adds r5, r0, r0
  917. eorvs r0, lr, r5, asr#31
  918. and r5, r0, #0x007F0000
  919. and r7, r11, r0, lsl#1
  920.  
  921. add r12, r4, r1 @ left sample #2
  922. adds r4, r12, r12
  923. eorvs r12, lr, r4, asr#31
  924. and r4, r12, #0x007F0000
  925. and r12, r11, r12, lsl#1
  926. orr r6, r12, r6, lsr#8
  927.  
  928. add r1, r5, r1, lsl#16 @ right
  929. adds r5, r1, r1
  930. eorvs r1, lr, r5, asr#31
  931. and r5, r1, #0x007F0000
  932. and r1, r11, r1, lsl#1
  933. orr r7, r1, r7, lsr#8
  934.  
  935. add r12, r4, r2 @ left sample #3
  936. adds r4, r12, r12
  937. eorvs r12, lr, r4, asr#31
  938. and r4, r12, #0x007F0000
  939. and r12, r11, r12, lsl#1
  940. orr r6, r12, r6, lsr#8
  941.  
  942. add r2, r5, r2, lsl#16 @ right
  943. adds r5, r2, r2
  944. eorvs r2, lr, r5, asr#31
  945. and r5, r2, #0x007F0000
  946. and r2, r11, r2, lsl#1
  947. orr r7, r2, r7, lsr#8
  948.  
  949. add r12, r4, r3 @ left sample #4
  950. adds r4, r12, r12
  951. eorvs r12, lr, r4, asr#31
  952. and r4, r12, #0x007F0000
  953. and r12, r11, r12, lsl#1
  954. orr r6, r12, r6, lsr#8
  955.  
  956. add r3, r5, r3, lsl#16 @ right
  957. adds r5, r3, r3
  958. eorvs r3, lr, r5, asr#31
  959. and r5, r3, #0x007F0000
  960. and r3, r11, r3, lsl#1
  961. orr r7, r3, r7, lsr#8
  962.  
  963. str r6, [r9, #0x630]
  964. str r7, [r9], #4
  965. mov r0, #0
  966. mov r1, #0
  967. mov r2, #0
  968. mov r3, #0
  969.  
  970. stmia r10!, {r0, r1, r2, r3}
  971.  
  972. subs r8, #4
  973. bgt C_downsampler_loop
  974.  
  975. adr r1, V_noise_shape
  976. adr r0, (C_downsampler_return+1)
  977. bx r0
  978.  
  979. .pool
  980.  
  981. .align 1
  982. .thumb
  983.  
  984. C_downsampler_return:
  985. lsr r4, #16
  986. strb r4, [r1, #0]
  987. lsr r5, #16
  988. strb r5, [r1, #1]
  989. ldr r0, [sp, #ARG_PCM_STRUCT]
  990. ldr r3, mixer_finished_status @ this is used to indicate the interrupt handler the rendering was finished properly
  991. str r3, [r0]
  992. add sp, sp, #0x1C
  993. pop {r0-r7}
  994. mov r8, r0
  995. mov r9, r1
  996. mov r10, r2
  997. mov r11, r3
  998. pop {r3}
  999. bx r3
  1000.  
  1001. .align 2
  1002.  
  1003. mixer_finished_status:
  1004. .word 0x68736D53
  1005.  
  1006. .arm
  1007. .align 2
  1008.  
  1009. C_setup_synth:
  1010. cmp r12, #0
  1011. bne C_check_synth_saw
  1012.  
  1013. @ modulating pulse wave
  1014. ldrb r6, [r3, #SYNTH_WIDTH_CHANGE_1]
  1015. add r2, r2, r6, lsl#24
  1016. ldrb r6, [r3, #SYNTH_WIDTH_CHANGE_2]
  1017. adds r6, r2, r6, lsl#24
  1018. mvnmi r6, r6
  1019. mov r10, r6, lsr#8
  1020. ldrb r1, [r3, #SYNTH_MOD_AMOUNT]
  1021. ldrb r0, [r3, #SYNTH_BASE_WAVE_DUTY]
  1022. mov r0, r0, lsl#24
  1023. mla r6, r10, r1, r0 @ calculate the final duty cycle with the offset, and intensity, rotating the duty cycle amount
  1024. stmfd sp!, {r2, r3, r9, r12}
  1025.  
  1026. C_synth_pulse_loop:
  1027. ldmia r5, {r0-r3, r9, r10, r12, lr} @ load 8 samples
  1028. cmp r7, r6 @ block #1
  1029. addlo r0, r0, r11, lsl#6
  1030. subhs r0, r0, r11, lsl#6
  1031. adds r7, r7, r4, lsl#3
  1032. cmp r7, r6 @ block #2
  1033. addlo r1, r1, r11, lsl#6
  1034. subhs r1, r1, r11, lsl#6
  1035. adds r7, r7, r4, lsl#3
  1036. cmp r7, r6 @ block #3
  1037. addlo r2, r2, r11, lsl#6
  1038. subhs r2, r2, r11, lsl#6
  1039. adds r7, r7, r4, lsl#3
  1040. cmp r7, r6 @ block #4
  1041. addlo r3, r3, r11, lsl#6
  1042. subhs r3, r3, r11, lsl#6
  1043. adds r7, r7, r4, lsl#3
  1044. cmp r7, r6 @ block #5
  1045. addlo r9, r9, r11, lsl#6
  1046. subhs r9, r9, r11, lsl#6
  1047. adds r7, r7, r4, lsl#3
  1048. cmp r7, r6 @ block #6
  1049. addlo r10, r10, r11, lsl#6
  1050. subhs r10, r10, r11, lsl#6
  1051. adds r7, r7, r4, lsl#3
  1052. cmp r7, r6 @ block #7
  1053. addlo r12, r12, r11, lsl#6
  1054. subhs r12, r12, r11, lsl#6
  1055. adds r7, r7, r4, lsl#3
  1056. cmp r7, r6 @ block #8
  1057. addlo lr, lr, r11, lsl#6
  1058. subhs lr, lr, r11, lsl#6
  1059. adds r7, r7, r4, lsl#3
  1060.  
  1061. stmia r5!, {r0-r3, r9, r10, r12, lr} @ write 8 samples
  1062. subs r8, r8, #8
  1063. bgt C_synth_pulse_loop
  1064.  
  1065. ldmfd sp!, {r2, r3, r9, r12}
  1066. b C_end_mixing
  1067.  
  1068. C_check_synth_saw:
  1069.  
  1070. @ This is actually not a true saw wave
  1071. @ but looks pretty similar
  1072. @ (has a jump in the middle of the wave)
  1073.  
  1074. subs r12, r12, #1
  1075. bne C_synth_triangle
  1076.  
  1077. mov r6, #0x300
  1078. mov r11, r11, lsr#1
  1079. bic r11, r11, #0xFF00
  1080. mov r12, #0x70
  1081.  
  1082. C_synth_saw_loop:
  1083.  
  1084. ldmia r5, {r0, r1, r10, lr} @ load 4 samples from memory
  1085. adds r7, r7, r4, lsl#3 @ Block #1 (some oscillator type code)
  1086. rsb r9, r12, r7, lsr#24
  1087. mov r6, r7, lsl#1
  1088. sub r9, r9, r6, lsr#27
  1089. adds r2, r9, r2, asr#1
  1090. mlane r0, r11, r2, r0
  1091.  
  1092. adds r7, r7, r4, lsl#3 @ Block #2
  1093. rsb r9, r12, r7, lsr#24
  1094. mov r6, r7, lsl#1
  1095. sub r9, r9, r6, lsr#27
  1096. adds r2, r9, r2, asr#1
  1097. mlane r1, r11, r2, r1
  1098.  
  1099. adds r7, r7, r4, lsl#3 @ Block #3
  1100. rsb r9, r12, r7, lsr#24
  1101. mov r6, r7, lsl#1
  1102. sub r9, r9, r6, lsr#27
  1103. adds r2, r9, r2, asr#1
  1104. mlane r10, r11, r2, r10
  1105.  
  1106. adds r7, r7, r4, lsl#3 @ Block #4
  1107. rsb r9, r12, r7, lsr#24
  1108. mov r6, r7, lsl#1
  1109. sub r9, r9, r6, lsr#27
  1110. adds r2, r9, r2, asr#1
  1111. mlane lr, r11, r2, lr
  1112.  
  1113. stmia r5!, {r0, r1, r10, lr}
  1114. subs r8, r8, #4
  1115. bgt C_synth_saw_loop
  1116.  
  1117. B C_end_mixing
  1118.  
  1119. C_synth_triangle:
  1120. mov r6, #0x80
  1121. mov r12, #0x180
  1122.  
  1123. C_synth_triangle_loop:
  1124. ldmia r5, {r0, r1, r10, lr} @ load samples from work buffer
  1125. adds r7, r7, r4, lsl#3 @ block #1
  1126. rsbpl r9, r6, r7, asr#23
  1127. submi r9, r12, r7, lsr#23
  1128. mla r0, r11, r9, r0
  1129.  
  1130. adds r7, r7, r4, lsl#3 @ block #2
  1131. rsbpl r9, r6, r7, asr#23
  1132. submi r9, r12, r7, lsr#23
  1133. mla r1, r11, r9, r1
  1134.  
  1135. adds r7, r7, r4, lsl#3 @ block #3
  1136. rsbpl r9, r6, r7, asr#23
  1137. submi r9, r12, r7, lsr#23
  1138. mla r10, r11, r9, r10
  1139.  
  1140. adds r7, r7, r4, lsl#3 @ block #4
  1141. rsbpl r9, r6, r7, asr#23
  1142. submi r9, r12, r7, lsr#23
  1143. mla lr, r11, r9, lr
  1144.  
  1145. stmia r5!, {r0, r1, r10, lr}
  1146. subs r8, r8, #4 @ subtract #4 from the remainging samples
  1147. bgt C_synth_triangle_loop
  1148.  
  1149. b C_end_mixing
  1150.  
  1151. .if ENABLE_DECOMPRESSION==1
  1152. C_setup_special_mixing:
  1153. ldr r6, [r4, #CHN_WAVE_OFFSET]
  1154. ldrb r0, [r4]
  1155. tst r0, #FLAG_CHN_COMP
  1156. bne C_setup_special_mixing_freq @ skip the setup procedure if it's running in compressed mode already
  1157.  
  1158. orr r0, #FLAG_CHN_COMP
  1159. strb r0, [r4]
  1160. ldrb r0, [r4, #CHN_MODE]
  1161. tst r0, #MODE_REVERSE
  1162. beq C_check_compression @ reversed mode not enabled?
  1163.  
  1164. ldr r1, [r6, #WAVE_LENGTH] @ calculate seek position for reverse playback
  1165. add r1, r1, r6, lsl#1 @ I don't actually understand that piece of code myself
  1166. add r1, r1, #0x20
  1167. sub r3, r1, r3
  1168. str r3, [r4, #CHN_POSITION_ABS]
  1169.  
  1170. C_check_compression:
  1171. ldrh r0, [r6]
  1172. cmp r0, #0
  1173. beq C_setup_special_mixing_freq
  1174.  
  1175. sub r3, r3, r6
  1176. sub r3, r3, #0x10
  1177. str r3, [r4, #CHN_POSITION_ABS]
  1178.  
  1179. C_setup_special_mixing_freq:
  1180. ldr r0, [r6, #WAVE_LOOP_START]
  1181. str r0, [sp, #ARG_LOOP_START_POS]
  1182.  
  1183. STMFD SP!, {R4, R9, R12}
  1184.  
  1185. movs r11, r11, lsr#1
  1186. adc r11, r11, #0x8000
  1187. bic r11, r11, #0xFF00
  1188.  
  1189. ldr r7, [r4, #CHN_FINE_POSITION]
  1190. ldr r1, [r4, #CHN_FREQUENCY]
  1191. ldrb r0, [r4, #CHN_MODE]
  1192. tst r0, #MODE_FIXED_FREQ
  1193. movne r1, #0x800000
  1194. muleq r1, r12, r1 @ default rate factor * frequency = sample steps
  1195.  
  1196. add r5, r5, r8, lsl#2 @ set the buffer pointer to the end of the channel, same as slow mixing mode
  1197.  
  1198. ldrh r0, [r6]
  1199. cmp r0, #0
  1200. beq C_uncompressed_reverse_mixing_check
  1201.  
  1202. mov r0, #0xFF000000 @ --> invalid channel mod
  1203. str r0, [r4, #CHN_BLOCK_COUNT]
  1204. ldrb r0, [r4, #CHN_MODE]
  1205. tst r0, #MODE_REVERSE
  1206. bne C_setup_compressed_reverse_mixing @ check again of reverse mixing is enabled
  1207.  
  1208. @ forward compressed mixing
  1209. bl F_bdpcm_decoder
  1210. mov r6, r12
  1211. add r3, r3, #1
  1212. bl F_bdpcm_decoder
  1213. sub r12, r12, r6
  1214.  
  1215. @***** MIXING LOOP REGISTER USAGE ***********@
  1216. @ r0: sample to modify from buffer
  1217. @ r1: sample steps (moved from r4)
  1218. @ r2: remaining samples before loop/end
  1219. @ r3: sample position
  1220. @ r4: channel pointer
  1221. @ r5: pointer to the end of buffer
  1222. @ r6: base sample
  1223. @ r7: fine position
  1224. @ r8: remaining samples for current buffer
  1225. @ r9: interpolated sample
  1226. @ r10: not used
  1227. @ r11: volume
  1228. @ r12: delta sample
  1229. @ lr: not used
  1230. @********************************************@
  1231.  
  1232. C_compressed_mixing_loop:
  1233. mul r9, r7, r12 @ check slow mixing for details, same procedure here
  1234. mov r9, r9, asr#22
  1235. adds r9, r9, r6, lsl#1
  1236. ldrne r0, [r5, -r8, lsl#2]
  1237. mlane r0, r11, r9, r0
  1238. strne r0, [r5, -r8, lsl#2]
  1239. add r7, r7, r1 @ ### changed from r4 to r1
  1240. movs r9, r7, lsr#23
  1241. beq C_compressed_mixing_skip_load
  1242.  
  1243. subs r2, r2, r7, lsr#23
  1244. blle C_mixing_loop_or_end
  1245. subs r9, r9, #1
  1246. addeq r6, r12, r6
  1247. beq C_compressed_mixing_skip_base_load
  1248.  
  1249. add r3, r3, r9 @ equivalent to ldrnesb r6, [r3, r9]!
  1250. bl F_bdpcm_decoder
  1251. mov r6, r12
  1252.  
  1253. C_compressed_mixing_skip_base_load:
  1254. add r3, r3, #1 @ equivalent to ldrsb r12, [r3, #1]!
  1255. bl F_bdpcm_decoder
  1256. sub r12, r12, r6
  1257. bic r7, r7, #0x3F800000
  1258.  
  1259. C_compressed_mixing_skip_load:
  1260. subs r8, r8, #1
  1261. bgt C_compressed_mixing_loop
  1262.  
  1263. B C_end_mixing
  1264.  
  1265. C_setup_compressed_reverse_mixing:
  1266. sub r3, r3, #1
  1267. bl F_bdpcm_decoder
  1268. mov r6, r12
  1269. sub r3, r3, #1
  1270. bl F_bdpcm_decoder
  1271. sub r12, r12, r6
  1272.  
  1273. C_compressed_reverse_mixing_loop:
  1274. mul r9, r7, r12
  1275. mov r9, r9, asr#22
  1276. adds r9, r9, r6, lsl#1
  1277. ldrne r0, [r5, -r8, lsl#2]
  1278. mlane r0, r11, r9, r0
  1279. strne r0, [r5, -r8, lsl#2]
  1280. add r7, r7, r1 @ ### changed from r4 to r1
  1281. movs r9, r7, lsr#23
  1282. beq C_compressed_reverse_mixing_skip_load
  1283.  
  1284. subs r2, r2, r7, lsr#23
  1285. BLLE C_mixing_loop_or_end
  1286. subs r9, r9, #1
  1287. addeq r6, r12, r6
  1288. beq C_compressed_reverse_mixing_skip_base_load
  1289.  
  1290. sub r3, r3, r9
  1291. bl F_bdpcm_decoder
  1292. mov r6, r12
  1293.  
  1294. C_compressed_reverse_mixing_skip_base_load:
  1295. sub r3, r3, #1
  1296. bl F_bdpcm_decoder
  1297. sub r12, r12, r6
  1298. bic r7, r7, #0x3F800000
  1299.  
  1300. C_compressed_reverse_mixing_skip_load:
  1301. subs r8, r8, #1
  1302. bgt C_compressed_reverse_mixing_loop
  1303.  
  1304. add r3, r3, #3
  1305. b C_end_mixing
  1306.  
  1307. C_uncompressed_reverse_mixing_check:
  1308. ldrb r0, [r4, #1]
  1309. tst r0, #MODE_REVERSE @ check if reverse mode is even enabled (consistency)
  1310. beq C_end_mixing
  1311.  
  1312. ldrsb r6, [r3, #-1]!
  1313. ldrsb r12, [r3, #-1]
  1314. sub r12, r12, r6
  1315.  
  1316. C_uncompressed_reverse_mixing_loop:
  1317. mul r9, r7, r12
  1318. mov r9, r9, asr#22
  1319. adds r9, r9, r6, lsl#1
  1320. ldrne r0, [r5, -r8, lsl#2]
  1321. mlane r0, r11, r9, r0
  1322. strne r0, [r5, -r8, lsl#2]
  1323. add r7, r7, r1 @ ### changed from r4 to r1
  1324. movs r9, r7, lsr#23
  1325. beq C_uncompressed_reverse_mixing_load_skip
  1326.  
  1327. subs r2, r2, r7, lsr#23
  1328. blle C_mixing_loop_or_end
  1329.  
  1330. movs r9, r9
  1331. addeq r6, r12, r6
  1332. ldrnesb r6, [r3, -r9]!
  1333. ldrsb r12, [r3, #-1]
  1334. sub r12, r12, r6
  1335. bic r7, r7, #0x3F800000
  1336.  
  1337. C_uncompressed_reverse_mixing_load_skip:
  1338. subs r8, r8, #1
  1339. bgt C_uncompressed_reverse_mixing_loop
  1340.  
  1341. add r3, r3, #2
  1342. b C_end_mixing
  1343.  
  1344. @ This is the main BDPCM Decoder
  1345. @ It decodes and caches a block of PCM data
  1346. @ and returns them in R12
  1347.  
  1348. F_bdpcm_decoder:
  1349.  
  1350. stmfd sp!, {r0, lr}
  1351. mov r0, r3, lsr#6 @ clip off everything but the block offset, each block is 0x40 samples long
  1352. ldr r12, [r4, #CHN_BLOCK_COUNT]
  1353. cmp r0, r12
  1354. beq C_bdpcm_decoder_return @ block already decoded -> skip
  1355.  
  1356. stmfd sp!, {r2, r5-r7}
  1357. str r0, [r4, #CHN_BLOCK_COUNT]
  1358. mov r12, #0x21 @ 1 block = 0x21 bytes, 0x40 decoded samples
  1359. mul r2, r12, r0
  1360. ldr r12, [r4, #CHN_WAVE_OFFSET]
  1361. add r2, r2, r12 @ calc block rom position
  1362. add r2, r2, #0x10
  1363. ldr r5, decoder_buffer
  1364. adr r6, delta_lookup_table
  1365. mov r7, #0x40 @ 1 block = 0x40 samples
  1366. ldrb lr, [r2], #1
  1367. strb lr, [r5], #1
  1368. ldrb r12, [r2], #1
  1369. b C_bdpcm_decoder_lsb
  1370.  
  1371. C_bdpcm_decoder_msb:
  1372. ldrb r12, [r2], #1
  1373. mov r0, r12, lsr#4
  1374. ldrsb r0, [r6, r0]
  1375. add lr, lr, r0
  1376. strb lr, [r5], #1
  1377.  
  1378. C_bdpcm_decoder_lsb:
  1379. and r0, r12, #0xf
  1380. ldrsb r0, [r6, r0]
  1381. add lr, lr, r0
  1382. strb lr, [r5], #1
  1383. subs r7, r7, #2
  1384. bgt C_bdpcm_decoder_msb
  1385.  
  1386. ldmfd sp!, {r2, r5-r7}
  1387. C_bdpcm_decoder_return:
  1388. ldr r12, decoder_buffer
  1389. and r0, r3, #0x3f
  1390. ldrsb r12, [r12, r0]
  1391. ldmfd sp!, {r0, pc}
  1392.  
  1393. .align 2
  1394.  
  1395. decoder_buffer:
  1396. .word gUnknown_03001300
  1397.  
  1398. delta_lookup_table:
  1399. .byte 0x0, 0x1, 0x4, 0x9, 0x10, 0x19, 0x24, 0x31, 0xC0, 0xCF, 0xDC, 0xE7, 0xF0, 0xF7, 0xFC, 0xFF
  1400.  
  1401. .endif @ ENABLE_DECOMPRESSION*/
  1402.  
  1403. main_mixer_end:
  1404. .syntax unified
  1405.  
  1406. thumb_func_start SoundMainBTM
  1407. SoundMainBTM:
  1408. mov r12, r4
  1409. movs r1, 0
  1410. movs r2, 0
  1411. movs r3, 0
  1412. movs r4, 0
  1413. stm r0!, {r1-r4}
  1414. stm r0!, {r1-r4}
  1415. stm r0!, {r1-r4}
  1416. stm r0!, {r1-r4}
  1417. mov r4, r12
  1418. bx lr
  1419. thumb_func_end SoundMainBTM
  1420.  
  1421. thumb_func_start RealClearChain
  1422. RealClearChain:
  1423. ldr r3, [r0, 0x2C]
  1424. cmp r3, 0
  1425. beq _081DD5E2
  1426. ldr r1, [r0, 0x34]
  1427. ldr r2, [r0, 0x30]
  1428. cmp r2, 0
  1429. beq _081DD5D6
  1430. str r1, [r2, 0x34]
  1431. b _081DD5D8
  1432. _081DD5D6:
  1433. str r1, [r3, 0x20]
  1434. _081DD5D8:
  1435. cmp r1, 0
  1436. beq _081DD5DE
  1437. str r2, [r1, 0x30]
  1438. _081DD5DE:
  1439. movs r1, 0
  1440. str r1, [r0, 0x2C]
  1441. _081DD5E2:
  1442. bx lr
  1443. thumb_func_end RealClearChain
  1444.  
  1445. thumb_func_start ply_fine
  1446. ply_fine:
  1447. push {r4,r5,lr}
  1448. adds r5, r1, 0
  1449. ldr r4, [r5, o_MusicPlayerTrack_chan]
  1450. cmp r4, 0
  1451. beq ply_fine_done
  1452. ply_fine_loop:
  1453. ldrb r1, [r4]
  1454. movs r0, 0xC7
  1455. tst r0, r1
  1456. beq ply_fine_ok
  1457. movs r0, 0x40
  1458. orrs r1, r0
  1459. strb r1, [r4]
  1460. ply_fine_ok:
  1461. adds r0, r4, 0
  1462. bl RealClearChain
  1463. ldr r4, [r4, 0x34]
  1464. cmp r4, 0
  1465. bne ply_fine_loop
  1466. ply_fine_done:
  1467. movs r0, 0
  1468. strb r0, [r5]
  1469. pop {r4,r5}
  1470. pop {r0}
  1471. bx r0
  1472. thumb_func_end ply_fine
  1473.  
  1474. thumb_func_start MPlayJumpTableCopy
  1475. MPlayJumpTableCopy:
  1476. mov r12, lr
  1477. movs r1, 0x24
  1478. ldr r2, lt_MPlayJumpTableTemplate
  1479. MPlayJumpTableCopy_Loop:
  1480. ldr r3, [r2]
  1481. bl chk_adr_r2
  1482. stm r0!, {r3}
  1483. adds r2, 0x4
  1484. subs r1, 0x1
  1485. bgt MPlayJumpTableCopy_Loop
  1486. bx r12
  1487. thumb_func_end MPlayJumpTableCopy
  1488.  
  1489. .align 2, 0
  1490. .thumb_func
  1491. ldrb_r3_r2:
  1492. ldrb r3, [r2]
  1493.  
  1494. @ This attempts to protect against reading anything from the BIOS ROM
  1495. @ besides the jump table template.
  1496. @ It assumes that the jump table template is located at the end of the ROM.
  1497. .thumb_func
  1498. chk_adr_r2:
  1499. push {r0}
  1500. lsrs r0, r2, 25
  1501. bne chk_adr_r2_done @ if adr >= 0x2000000 (i.e. not in BIOS ROM), accept it
  1502. ldr r0, lt_MPlayJumpTableTemplate
  1503. cmp r2, r0
  1504. blo chk_adr_r2_reject @ if adr < gMPlayJumpTableTemplate, reject it
  1505. lsrs r0, r2, 14
  1506. beq chk_adr_r2_done @ if adr < 0x40000 (i.e. in BIOS ROM), accept it
  1507. chk_adr_r2_reject:
  1508. movs r3, 0
  1509. chk_adr_r2_done:
  1510. pop {r0}
  1511. bx lr
  1512.  
  1513. .align 2, 0
  1514. lt_MPlayJumpTableTemplate: .word gMPlayJumpTableTemplate
  1515.  
  1516. thumb_func_start ld_r3_tp_adr_i
  1517. ld_r3_tp_adr_i:
  1518. ldr r2, [r1, 0x40]
  1519. _081DD64A:
  1520. adds r3, r2, 0x1
  1521. str r3, [r1, 0x40]
  1522. ldrb r3, [r2]
  1523. b chk_adr_r2
  1524. thumb_func_end ld_r3_tp_adr_i
  1525.  
  1526. thumb_func_start ply_goto
  1527. ply_goto:
  1528. push {lr}
  1529. ply_goto_1:
  1530. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1531. ldrb r0, [r2, 0x3]
  1532. lsls r0, 8
  1533. ldrb r3, [r2, 0x2]
  1534. orrs r0, r3
  1535. lsls r0, 8
  1536. ldrb r3, [r2, 0x1]
  1537. orrs r0, r3
  1538. lsls r0, 8
  1539. bl ldrb_r3_r2
  1540. orrs r0, r3
  1541. str r0, [r1, o_MusicPlayerTrack_cmdPtr]
  1542. pop {r0}
  1543. bx r0
  1544. thumb_func_end ply_goto
  1545.  
  1546. thumb_func_start ply_patt
  1547. ply_patt:
  1548. ldrb r2, [r1, o_MusicPlayerTrack_patternLevel]
  1549. cmp r2, 3
  1550. bhs ply_patt_done
  1551. lsls r2, 2
  1552. adds r3, r1, r2
  1553. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1554. adds r2, 0x4
  1555. str r2, [r3, o_MusicPlayerTrack_patternStack]
  1556. ldrb r2, [r1, o_MusicPlayerTrack_patternLevel]
  1557. adds r2, 1
  1558. strb r2, [r1, o_MusicPlayerTrack_patternLevel]
  1559. b ply_goto
  1560. ply_patt_done:
  1561. b ply_fine
  1562. thumb_func_end ply_patt
  1563.  
  1564. thumb_func_start ply_pend
  1565. ply_pend:
  1566. ldrb r2, [r1, o_MusicPlayerTrack_patternLevel]
  1567. cmp r2, 0
  1568. beq ply_pend_done
  1569. subs r2, 1
  1570. strb r2, [r1, o_MusicPlayerTrack_patternLevel]
  1571. lsls r2, 2
  1572. adds r3, r1, r2
  1573. ldr r2, [r3, o_MusicPlayerTrack_patternStack]
  1574. str r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1575. ply_pend_done:
  1576. bx lr
  1577. thumb_func_end ply_pend
  1578.  
  1579. thumb_func_start ply_rept
  1580. ply_rept:
  1581. push {lr}
  1582. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1583. ldrb r3, [r2]
  1584. cmp r3, 0
  1585. bne ply_rept_1
  1586. adds r2, 1
  1587. str r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1588. b ply_goto_1
  1589. ply_rept_1:
  1590. ldrb r3, [r1, o_MusicPlayerTrack_repN]
  1591. adds r3, 1
  1592. strb r3, [r1, o_MusicPlayerTrack_repN]
  1593. mov r12, r3
  1594. bl ld_r3_tp_adr_i
  1595. cmp r12, r3
  1596. bhs ply_rept_2
  1597. b ply_goto_1
  1598. ply_rept_2:
  1599. movs r3, 0
  1600. strb r3, [r1, o_MusicPlayerTrack_repN]
  1601. adds r2, 5
  1602. str r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1603. pop {r0}
  1604. bx r0
  1605. thumb_func_end ply_rept
  1606.  
  1607. thumb_func_start ply_prio
  1608. ply_prio:
  1609. mov r12, lr
  1610. bl ld_r3_tp_adr_i
  1611. strb r3, [r1, o_MusicPlayerTrack_priority]
  1612. bx r12
  1613. thumb_func_end ply_prio
  1614.  
  1615. thumb_func_start ply_tempo
  1616. ply_tempo:
  1617. mov r12, lr
  1618. bl ld_r3_tp_adr_i
  1619. lsls r3, 1
  1620. strh r3, [r0, o_MusicPlayerInfo_tempoD]
  1621. ldrh r2, [r0, o_MusicPlayerInfo_tempoU]
  1622. muls r3, r2
  1623. lsrs r3, 8
  1624. strh r3, [r0, o_MusicPlayerInfo_tempoI]
  1625. bx r12
  1626. thumb_func_end ply_tempo
  1627.  
  1628. thumb_func_start ply_keysh
  1629. ply_keysh:
  1630. mov r12, lr
  1631. bl ld_r3_tp_adr_i
  1632. strb r3, [r1, o_MusicPlayerTrack_keyShift]
  1633. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1634. movs r2, 0xC
  1635. orrs r3, r2
  1636. strb r3, [r1, o_MusicPlayerTrack_flags]
  1637. bx r12
  1638. thumb_func_end ply_keysh
  1639.  
  1640. thumb_func_start ply_voice
  1641. ply_voice:
  1642. mov r12, lr
  1643. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1644. ldrb r3, [r2]
  1645. adds r2, 1
  1646. str r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1647. lsls r2, r3, 1
  1648. adds r2, r3
  1649. lsls r2, 2
  1650. ldr r3, [r0, o_MusicPlayerInfo_tone]
  1651. adds r2, r3
  1652. ldr r3, [r2]
  1653. bl chk_adr_r2
  1654. str r3, [r1, o_MusicPlayerTrack_ToneData_type]
  1655. ldr r3, [r2, 0x4]
  1656. bl chk_adr_r2
  1657. str r3, [r1, o_MusicPlayerTrack_ToneData_wav]
  1658. ldr r3, [r2, 0x8]
  1659. bl chk_adr_r2
  1660. str r3, [r1, o_MusicPlayerTrack_ToneData_attack]
  1661. bx r12
  1662. thumb_func_end ply_voice
  1663.  
  1664. thumb_func_start ply_vol
  1665. ply_vol:
  1666. mov r12, lr
  1667. bl ld_r3_tp_adr_i
  1668. strb r3, [r1, o_MusicPlayerTrack_vol]
  1669. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1670. movs r2, 0x3
  1671. orrs r3, r2
  1672. strb r3, [r1, o_MusicPlayerTrack_flags]
  1673. bx r12
  1674. thumb_func_end ply_vol
  1675.  
  1676. thumb_func_start ply_pan
  1677. ply_pan:
  1678. mov r12, lr
  1679. bl ld_r3_tp_adr_i
  1680. subs r3, 0x40
  1681. strb r3, [r1, o_MusicPlayerTrack_pan]
  1682. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1683. movs r2, 0x3
  1684. orrs r3, r2
  1685. strb r3, [r1, o_MusicPlayerTrack_flags]
  1686. bx r12
  1687. thumb_func_end ply_pan
  1688.  
  1689. thumb_func_start ply_bend
  1690. ply_bend:
  1691. mov r12, lr
  1692. bl ld_r3_tp_adr_i
  1693. subs r3, 0x40
  1694. strb r3, [r1, o_MusicPlayerTrack_bend]
  1695. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1696. movs r2, 0xC
  1697. orrs r3, r2
  1698. strb r3, [r1, o_MusicPlayerTrack_flags]
  1699. bx r12
  1700. thumb_func_end ply_bend
  1701.  
  1702. thumb_func_start ply_bendr
  1703. ply_bendr:
  1704. mov r12, lr
  1705. bl ld_r3_tp_adr_i
  1706. strb r3, [r1, o_MusicPlayerTrack_bendRange]
  1707. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1708. movs r2, 0xC
  1709. orrs r3, r2
  1710. strb r3, [r1, o_MusicPlayerTrack_flags]
  1711. bx r12
  1712. thumb_func_end ply_bendr
  1713.  
  1714. thumb_func_start ply_lfodl
  1715. ply_lfodl:
  1716. mov r12, lr
  1717. bl ld_r3_tp_adr_i
  1718. strb r3, [r1, o_MusicPlayerTrack_lfoDelay]
  1719. bx r12
  1720. thumb_func_end ply_lfodl
  1721.  
  1722. thumb_func_start ply_modt
  1723. ply_modt:
  1724. mov r12, lr
  1725. bl ld_r3_tp_adr_i
  1726. ldrb r0, [r1, o_MusicPlayerTrack_modT]
  1727. cmp r0, r3
  1728. beq _081DD7AA
  1729. strb r3, [r1, o_MusicPlayerTrack_modT]
  1730. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1731. movs r2, 0xF
  1732. orrs r3, r2
  1733. strb r3, [r1, o_MusicPlayerTrack_flags]
  1734. _081DD7AA:
  1735. bx r12
  1736. thumb_func_end ply_modt
  1737.  
  1738. thumb_func_start ply_tune
  1739. ply_tune:
  1740. mov r12, lr
  1741. bl ld_r3_tp_adr_i
  1742. subs r3, 0x40
  1743. strb r3, [r1, o_MusicPlayerTrack_tune]
  1744. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  1745. movs r2, 0xC
  1746. orrs r3, r2
  1747. strb r3, [r1, o_MusicPlayerTrack_flags]
  1748. bx r12
  1749. thumb_func_end ply_tune
  1750.  
  1751. thumb_func_start ply_port
  1752. ply_port:
  1753. mov r12, lr
  1754. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  1755. ldrb r3, [r2]
  1756. adds r2, 1
  1757. ldr r0, =REG_SOUND1CNT_L @ sound register base address
  1758. adds r0, r3
  1759. bl _081DD64A
  1760. strb r3, [r0]
  1761. bx r12
  1762. .pool
  1763. thumb_func_end ply_port
  1764.  
  1765. thumb_func_start m4aSoundVSync
  1766. m4aSoundVSync:
  1767. ldr r0, lt2_SOUND_INFO_PTR
  1768. ldr r0, [r0]
  1769.  
  1770. @ Exit the function if ident is not ID_NUMBER or ID_NUMBER+1.
  1771. ldr r2, lt2_ID_NUMBER
  1772. ldr r3, [r0, o_SoundInfo_ident]
  1773. subs r3, r2
  1774. cmp r3, 1
  1775. bhi m4aSoundVSync_Done
  1776.  
  1777. @ Decrement the PCM DMA counter. If it reaches 0, we need to do a DMA.
  1778. ldrb r1, [r0, o_SoundInfo_pcmDmaCounter]
  1779. subs r1, 1
  1780. strb r1, [r0, o_SoundInfo_pcmDmaCounter]
  1781. bgt m4aSoundVSync_Done
  1782.  
  1783. @ Reload the PCM DMA counter.
  1784. ldrb r1, [r0, o_SoundInfo_pcmDmaPeriod]
  1785. strb r1, [r0, o_SoundInfo_pcmDmaCounter]
  1786.  
  1787. ldr r2, =REG_DMA1
  1788.  
  1789. ldr r1, [r2, 0x8] @ DMA1CNT
  1790. lsls r1, 7
  1791. bcc m4aSoundVSync_SkipDMA1 @ branch if repeat bit isn't set
  1792.  
  1793. ldr r1, =((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4
  1794. str r1, [r2, 0x8] @ DMA1CNT
  1795.  
  1796. m4aSoundVSync_SkipDMA1:
  1797. ldr r1, [r2, 0xC + 0x8] @ DMA2CNT
  1798. lsls r1, 7
  1799. bcc m4aSoundVSync_SkipDMA2 @ branch if repeat bit isn't set
  1800.  
  1801. ldr r1, =((DMA_ENABLE | DMA_START_NOW | DMA_32BIT | DMA_SRC_INC | DMA_DEST_FIXED) << 16) | 4
  1802. str r1, [r2, 0xC + 0x8] @ DMA2CNT
  1803.  
  1804. m4aSoundVSync_SkipDMA2:
  1805.  
  1806. @ turn off DMA1/DMA2
  1807. movs r1, DMA_32BIT >> 8
  1808. lsls r1, 8
  1809. strh r1, [r2, 0xA] @ DMA1CNT_H
  1810. strh r1, [r2, 0xC + 0xA] @ DMA2CNT_H
  1811.  
  1812. @ turn on DMA1/DMA2 direct-sound FIFO mode
  1813. movs r1, (DMA_ENABLE | DMA_START_SPECIAL | DMA_32BIT | DMA_REPEAT) >> 8
  1814. lsls r1, 8 @ LSB is 0, so DMA_SRC_INC is used (destination is always fixed in FIFO mode)
  1815. strh r1, [r2, 0xA] @ DMA1CNT_H
  1816. strh r1, [r2, 0xC + 0xA] @ DMA2CNT_H
  1817.  
  1818. m4aSoundVSync_Done:
  1819. bx lr
  1820.  
  1821. .pool
  1822. thumb_func_end m4aSoundVSync
  1823.  
  1824. thumb_func_start MPlayMain
  1825. MPlayMain:
  1826. ldr r2, lt2_ID_NUMBER
  1827. ldr r3, [r0, o_MusicPlayerInfo_ident]
  1828. cmp r2, r3
  1829. beq _081DD82E
  1830. bx lr
  1831. _081DD82E:
  1832. adds r3, 0x1
  1833. str r3, [r0, o_MusicPlayerInfo_ident]
  1834. push {r0,lr}
  1835. ldr r3, [r0, o_MusicPlayerInfo_func]
  1836. cmp r3, 0
  1837. beq _081DD840
  1838. ldr r0, [r0, o_MusicPlayerInfo_intp]
  1839. bl call_r3
  1840. _081DD840:
  1841. pop {r0}
  1842. push {r4-r7}
  1843. mov r4, r8
  1844. mov r5, r9
  1845. mov r6, r10
  1846. mov r7, r11
  1847. push {r4-r7}
  1848. adds r7, r0, 0
  1849. ldr r0, [r7, o_MusicPlayerInfo_status]
  1850. cmp r0, 0
  1851. bge _081DD858
  1852. b _081DDA6C
  1853. _081DD858:
  1854. ldr r0, lt2_SOUND_INFO_PTR
  1855. ldr r0, [r0]
  1856. mov r8, r0
  1857. adds r0, r7, 0
  1858. bl FadeOutBody
  1859. ldr r0, [r7, o_MusicPlayerInfo_status]
  1860. cmp r0, 0
  1861. bge _081DD86C
  1862. b _081DDA6C
  1863. _081DD86C:
  1864. ldrh r0, [r7, o_MusicPlayerInfo_tempoC]
  1865. ldrh r1, [r7, o_MusicPlayerInfo_tempoI]
  1866. adds r0, r1
  1867. b _081DD9BC
  1868. _081DD874:
  1869. ldrb r6, [r7, o_MusicPlayerInfo_trackCount]
  1870. ldr r5, [r7, o_MusicPlayerInfo_tracks]
  1871. movs r3, 0x1
  1872. movs r4, 0
  1873. _081DD87C:
  1874. ldrb r0, [r5]
  1875. movs r1, 0x80
  1876. tst r1, r0
  1877. bne _081DD886
  1878. b _081DD998
  1879. _081DD886:
  1880. mov r10, r3
  1881. orrs r4, r3
  1882. mov r11, r4
  1883. ldr r4, [r5, o_MusicPlayerTrack_chan]
  1884. cmp r4, 0
  1885. beq _081DD8BA
  1886. _081DD892:
  1887. ldrb r1, [r4]
  1888. movs r0, 0xC7
  1889. tst r0, r1
  1890. beq _081DD8AE
  1891. ldrb r0, [r4, 0x10]
  1892. cmp r0, 0
  1893. beq _081DD8B4
  1894. subs r0, 0x1
  1895. strb r0, [r4, 0x10]
  1896. bne _081DD8B4
  1897. movs r0, 0x40
  1898. orrs r1, r0
  1899. strb r1, [r4]
  1900. b _081DD8B4
  1901. _081DD8AE:
  1902. adds r0, r4, 0
  1903. bl ClearChain
  1904. _081DD8B4:
  1905. ldr r4, [r4, 0x34]
  1906. cmp r4, 0
  1907. bne _081DD892
  1908. _081DD8BA:
  1909. ldrb r3, [r5, o_MusicPlayerTrack_flags]
  1910. movs r0, 0x40
  1911. tst r0, r3
  1912. beq _081DD938
  1913. adds r0, r5, 0
  1914. bl Clear64byte
  1915. movs r0, 0x80
  1916. strb r0, [r5]
  1917. movs r0, 0x2
  1918. strb r0, [r5, o_MusicPlayerTrack_bendRange]
  1919. movs r0, 0x40
  1920. strb r0, [r5, o_MusicPlayerTrack_volX]
  1921. movs r0, 0x16
  1922. strb r0, [r5, o_MusicPlayerTrack_lfoSpeed]
  1923. movs r0, 0x1
  1924. adds r1, r5, 0x6
  1925. strb r0, [r1, o_MusicPlayerTrack_ToneData_type - 0x6]
  1926. b _081DD938
  1927. _081DD8E0:
  1928. ldr r2, [r5, o_MusicPlayerTrack_cmdPtr]
  1929. ldrb r1, [r2]
  1930. cmp r1, 0x80
  1931. bhs _081DD8EC
  1932. ldrb r1, [r5, o_MusicPlayerTrack_runningStatus]
  1933. b _081DD8F6
  1934. _081DD8EC:
  1935. adds r2, 0x1
  1936. str r2, [r5, o_MusicPlayerTrack_cmdPtr]
  1937. cmp r1, 0xBD
  1938. bcc _081DD8F6
  1939. strb r1, [r5, o_MusicPlayerTrack_runningStatus]
  1940. _081DD8F6:
  1941. cmp r1, 0xCF
  1942. bcc _081DD90C
  1943. mov r0, r8
  1944. ldr r3, [r0, o_SoundInfo_plynote]
  1945. adds r0, r1, 0
  1946. subs r0, 0xCF
  1947. adds r1, r7, 0
  1948. adds r2, r5, 0
  1949. bl call_r3
  1950. b _081DD938
  1951. _081DD90C:
  1952. cmp r1, 0xB0
  1953. bls _081DD92E
  1954. adds r0, r1, 0
  1955. subs r0, 0xB1
  1956. strb r0, [r7, o_MusicPlayerInfo_cmd]
  1957. mov r3, r8
  1958. ldr r3, [r3, o_SoundInfo_MPlayJumpTable]
  1959. lsls r0, 2
  1960. ldr r3, [r3, r0]
  1961. adds r0, r7, 0
  1962. adds r1, r5, 0
  1963. bl call_r3
  1964. ldrb r0, [r5, o_MusicPlayerTrack_flags]
  1965. cmp r0, 0
  1966. beq _081DD994
  1967. b _081DD938
  1968. _081DD92E:
  1969. ldr r0, lt_gClockTable
  1970. subs r1, 0x80
  1971. adds r1, r0
  1972. ldrb r0, [r1]
  1973. strb r0, [r5, o_MusicPlayerTrack_wait]
  1974. _081DD938:
  1975. ldrb r0, [r5, o_MusicPlayerTrack_wait]
  1976. cmp r0, 0
  1977. beq _081DD8E0
  1978. subs r0, 0x1
  1979. strb r0, [r5, o_MusicPlayerTrack_wait]
  1980. ldrb r1, [r5, o_MusicPlayerTrack_lfoSpeed]
  1981. cmp r1, 0
  1982. beq _081DD994
  1983. ldrb r0, [r5, o_MusicPlayerTrack_mod]
  1984. cmp r0, 0
  1985. beq _081DD994
  1986. ldrb r0, [r5, o_MusicPlayerTrack_lfoDelayC]
  1987. cmp r0, 0
  1988. beq _081DD95A
  1989. subs r0, 0x1
  1990. strb r0, [r5, o_MusicPlayerTrack_lfoDelayC]
  1991. b _081DD994
  1992. _081DD95A:
  1993. ldrb r0, [r5, o_MusicPlayerTrack_lfoSpeedC]
  1994. adds r0, r1
  1995. strb r0, [r5, o_MusicPlayerTrack_lfoSpeedC]
  1996. adds r1, r0, 0
  1997. subs r0, 0x40
  1998. lsls r0, 24
  1999. bpl _081DD96E
  2000. lsls r2, r1, 24
  2001. asrs r2, 24
  2002. b _081DD972
  2003. _081DD96E:
  2004. movs r0, 0x80
  2005. subs r2, r0, r1
  2006. _081DD972:
  2007. ldrb r0, [r5, o_MusicPlayerTrack_mod]
  2008. muls r0, r2
  2009. asrs r2, r0, 6
  2010. ldrb r0, [r5, o_MusicPlayerTrack_modM]
  2011. eors r0, r2
  2012. lsls r0, 24
  2013. beq _081DD994
  2014. strb r2, [r5, o_MusicPlayerTrack_modM]
  2015. ldrb r0, [r5]
  2016. ldrb r1, [r5, o_MusicPlayerTrack_modT]
  2017. cmp r1, 0
  2018. bne _081DD98E
  2019. movs r1, 0xC
  2020. b _081DD990
  2021. _081DD98E:
  2022. movs r1, 0x3
  2023. _081DD990:
  2024. orrs r0, r1
  2025. strb r0, [r5, o_MusicPlayerTrack_flags]
  2026. _081DD994:
  2027. mov r3, r10
  2028. mov r4, r11
  2029. _081DD998:
  2030. subs r6, 0x1
  2031. ble _081DD9A4
  2032. movs r0, 0x50
  2033. adds r5, r0
  2034. lsls r3, 1
  2035. b _081DD87C
  2036. _081DD9A4:
  2037. ldr r0, [r7, o_MusicPlayerInfo_clock]
  2038. adds r0, 0x1
  2039. str r0, [r7, o_MusicPlayerInfo_clock]
  2040. cmp r4, 0
  2041. bne _081DD9B6
  2042. movs r0, 0x80
  2043. lsls r0, 24
  2044. str r0, [r7, o_MusicPlayerInfo_status]
  2045. b _081DDA6C
  2046. _081DD9B6:
  2047. str r4, [r7, o_MusicPlayerInfo_status]
  2048. ldrh r0, [r7, o_MusicPlayerInfo_tempoC]
  2049. subs r0, 0x96
  2050. _081DD9BC:
  2051. strh r0, [r7, o_MusicPlayerInfo_tempoC]
  2052. cmp r0, 0x96
  2053. bcc _081DD9C4
  2054. b _081DD874
  2055. _081DD9C4:
  2056. ldrb r2, [r7, o_MusicPlayerInfo_trackCount]
  2057. ldr r5, [r7, o_MusicPlayerInfo_tracks]
  2058. _081DD9C8:
  2059. ldrb r0, [r5, o_MusicPlayerTrack_flags]
  2060. movs r1, 0x80
  2061. tst r1, r0
  2062. beq _081DDA62
  2063. movs r1, 0xF
  2064. tst r1, r0
  2065. beq _081DDA62
  2066. mov r9, r2
  2067. adds r0, r7, 0
  2068. adds r1, r5, 0
  2069. bl TrkVolPitSet
  2070. ldr r4, [r5, o_MusicPlayerTrack_chan]
  2071. cmp r4, 0
  2072. beq _081DDA58
  2073. _081DD9E6:
  2074. ldrb r1, [r4, o_SoundChannel_status]
  2075. movs r0, 0xC7
  2076. tst r0, r1
  2077. bne _081DD9F6
  2078. adds r0, r4, 0
  2079. bl ClearChain
  2080. b _081DDA52
  2081. _081DD9F6:
  2082. ldrb r0, [r4, o_SoundChannel_type]
  2083. movs r6, 0x7
  2084. ands r6, r0
  2085. ldrb r3, [r5, o_MusicPlayerTrack_flags]
  2086. movs r0, 0x3
  2087. tst r0, r3
  2088. beq _081DDA14
  2089. bl ChnVolSetAsm
  2090. cmp r6, 0
  2091. beq _081DDA14
  2092. ldrb r0, [r4, o_CgbChannel_mo]
  2093. movs r1, 0x1
  2094. orrs r0, r1
  2095. strb r0, [r4, o_CgbChannel_mo]
  2096. _081DDA14:
  2097. ldrb r3, [r5, o_MusicPlayerTrack_flags]
  2098. movs r0, 0xC
  2099. tst r0, r3
  2100. beq _081DDA52
  2101. ldrb r1, [r4, o_SoundChannel_ky]
  2102. movs r0, 0x8
  2103. ldrsb r0, [r5, r0]
  2104. adds r2, r1, r0
  2105. bpl _081DDA28
  2106. movs r2, 0
  2107. _081DDA28:
  2108. cmp r6, 0
  2109. beq _081DDA46
  2110. mov r0, r8
  2111. ldr r3, [r0, o_SoundInfo_MidiKeyToCgbFreq]
  2112. adds r1, r2, 0
  2113. ldrb r2, [r5, o_MusicPlayerTrack_pitM]
  2114. adds r0, r6, 0
  2115. bl call_r3
  2116. str r0, [r4, o_CgbChannel_fr]
  2117. ldrb r0, [r4, o_CgbChannel_mo]
  2118. movs r1, 0x2
  2119. orrs r0, r1
  2120. strb r0, [r4, o_CgbChannel_mo]
  2121. b _081DDA52
  2122. _081DDA46:
  2123. adds r1, r2, 0
  2124. ldrb r2, [r5, o_MusicPlayerTrack_pitM]
  2125. ldr r0, [r4, o_SoundChannel_wav]
  2126. bl MidiKeyToFreq
  2127. str r0, [r4, o_SoundChannel_freq]
  2128. _081DDA52:
  2129. ldr r4, [r4, o_SoundChannel_np]
  2130. cmp r4, 0
  2131. bne _081DD9E6
  2132. _081DDA58:
  2133. ldrb r0, [r5, o_MusicPlayerTrack_flags]
  2134. movs r1, 0xF0
  2135. ands r0, r1
  2136. strb r0, [r5, o_MusicPlayerTrack_flags]
  2137. mov r2, r9
  2138. _081DDA62:
  2139. subs r2, 0x1
  2140. ble _081DDA6C
  2141. movs r0, 0x50
  2142. adds r5, r0
  2143. bgt _081DD9C8
  2144. _081DDA6C:
  2145. ldr r0, lt2_ID_NUMBER
  2146. str r0, [r7, o_MusicPlayerInfo_ident]
  2147. pop {r0-r7}
  2148. mov r8, r0
  2149. mov r9, r1
  2150. mov r10, r2
  2151. mov r11, r3
  2152. pop {r3}
  2153.  
  2154. call_r3:
  2155. bx r3
  2156.  
  2157. .align 2, 0
  2158. lt_gClockTable: .word gClockTable
  2159. lt2_SOUND_INFO_PTR: .word SOUND_INFO_PTR
  2160. lt2_ID_NUMBER: .word ID_NUMBER
  2161. thumb_func_end MPlayMain
  2162.  
  2163. thumb_func_start TrackStop
  2164. TrackStop:
  2165. push {r4-r6,lr}
  2166. adds r5, r1, 0
  2167. ldrb r1, [r5, o_MusicPlayerTrack_flags]
  2168. movs r0, 0x80
  2169. tst r0, r1
  2170. beq TrackStop_Done
  2171. ldr r4, [r5, o_MusicPlayerTrack_chan]
  2172. cmp r4, 0
  2173. beq TrackStop_3
  2174. movs r6, 0
  2175. TrackStop_Loop:
  2176. ldrb r0, [r4, o_SoundChannel_status]
  2177. cmp r0, 0
  2178. beq TrackStop_2
  2179. ldrb r0, [r4, o_SoundChannel_type]
  2180. movs r3, 0x7
  2181. ands r0, r3
  2182. beq TrackStop_1
  2183. ldr r3, =SOUND_INFO_PTR
  2184. ldr r3, [r3]
  2185. ldr r3, [r3, o_SoundInfo_CgbOscOff]
  2186. bl call_r3
  2187. TrackStop_1:
  2188. strb r6, [r4, o_SoundChannel_status]
  2189. TrackStop_2:
  2190. str r6, [r4, o_SoundChannel_track]
  2191. ldr r4, [r4, o_SoundChannel_np]
  2192. cmp r4, 0
  2193. bne TrackStop_Loop
  2194. TrackStop_3:
  2195. str r4, [r5, o_MusicPlayerTrack_chan]
  2196. TrackStop_Done:
  2197. pop {r4-r6}
  2198. pop {r0}
  2199. bx r0
  2200. .pool
  2201. thumb_func_end TrackStop
  2202.  
  2203. thumb_func_start ChnVolSetAsm
  2204. ChnVolSetAsm:
  2205. ldrb r1, [r4, 0x12]
  2206. movs r0, 0x14
  2207. ldrsb r2, [r4, r0]
  2208. movs r3, 0x80
  2209. adds r3, r2
  2210. muls r3, r1
  2211. ldrb r0, [r5, 0x10]
  2212. muls r0, r3
  2213. asrs r0, 14
  2214. cmp r0, 0xFF
  2215. bls _081DDAE8
  2216. movs r0, 0xFF
  2217. _081DDAE8:
  2218. strb r0, [r4, 0x2]
  2219. movs r3, 0x7F
  2220. subs r3, r2
  2221. muls r3, r1
  2222. ldrb r0, [r5, 0x11]
  2223. muls r0, r3
  2224. asrs r0, 14
  2225. cmp r0, 0xFF
  2226. bls _081DDAFC
  2227. movs r0, 0xFF
  2228. _081DDAFC:
  2229. strb r0, [r4, 0x3]
  2230. bx lr
  2231. thumb_func_end ChnVolSetAsm
  2232.  
  2233. thumb_func_start ply_note
  2234. ply_note:
  2235. push {r4-r7,lr}
  2236. mov r4, r8
  2237. mov r5, r9
  2238. mov r6, r10
  2239. mov r7, r11
  2240. push {r4-r7}
  2241. sub sp, 0x18
  2242. str r1, [sp]
  2243. adds r5, r2, 0
  2244. ldr r1, =SOUND_INFO_PTR
  2245. ldr r1, [r1]
  2246. str r1, [sp, 0x4]
  2247. ldr r1, =gClockTable
  2248. adds r0, r1
  2249. ldrb r0, [r0]
  2250. strb r0, [r5, o_MusicPlayerTrack_gateTime]
  2251. ldr r3, [r5, o_MusicPlayerTrack_cmdPtr]
  2252. ldrb r0, [r3]
  2253. cmp r0, 0x80
  2254. bhs _081DDB46
  2255. strb r0, [r5, o_MusicPlayerTrack_key]
  2256. adds r3, 0x1
  2257. ldrb r0, [r3]
  2258. cmp r0, 0x80
  2259. bhs _081DDB44
  2260. strb r0, [r5, o_MusicPlayerTrack_velocity]
  2261. adds r3, 0x1
  2262. ldrb r0, [r3]
  2263. cmp r0, 0x80
  2264. bhs _081DDB44
  2265. ldrb r1, [r5, o_MusicPlayerTrack_gateTime]
  2266. adds r1, r0
  2267. strb r1, [r5, o_MusicPlayerTrack_gateTime]
  2268. adds r3, 0x1
  2269. _081DDB44:
  2270. str r3, [r5, o_MusicPlayerTrack_cmdPtr]
  2271. _081DDB46:
  2272. movs r0, 0
  2273. str r0, [sp, 0x14]
  2274. adds r4, r5, 0
  2275. adds r4, o_MusicPlayerTrack_ToneData_type
  2276. ldrb r2, [r4]
  2277. movs r0, TONEDATA_TYPE_RHY | TONEDATA_TYPE_SPL
  2278. tst r0, r2
  2279. beq _081DDB98
  2280. ldrb r3, [r5, o_MusicPlayerTrack_key]
  2281. movs r0, TONEDATA_TYPE_SPL
  2282. tst r0, r2
  2283. beq _081DDB66
  2284. ldr r1, [r5, o_MusicPlayerTrack_ToneData_keySplitTable]
  2285. adds r1, r3
  2286. ldrb r0, [r1]
  2287. b _081DDB68
  2288. _081DDB66:
  2289. adds r0, r3, 0
  2290. _081DDB68:
  2291. lsls r1, r0, 1
  2292. adds r1, r0
  2293. lsls r1, 2
  2294. ldr r0, [r5, o_MusicPlayerTrack_ToneData_wav]
  2295. adds r1, r0
  2296. mov r9, r1
  2297. mov r6, r9
  2298. ldrb r1, [r6]
  2299. movs r0, 0xC0
  2300. tst r0, r1
  2301. beq _081DDB80
  2302. b _081DDCEA
  2303. _081DDB80:
  2304. movs r0, 0x80
  2305. tst r0, r2
  2306. beq _081DDB9C
  2307. ldrb r1, [r6, 0x3]
  2308. movs r0, 0x80
  2309. tst r0, r1
  2310. beq _081DDB94
  2311. subs r1, 0xC0
  2312. lsls r1, 1
  2313. str r1, [sp, 0x14]
  2314. _081DDB94:
  2315. ldrb r3, [r6, 0x1]
  2316. b _081DDB9C
  2317. _081DDB98:
  2318. mov r9, r4
  2319. ldrb r3, [r5, 0x5]
  2320. _081DDB9C:
  2321. str r3, [sp, 0x8]
  2322. ldr r6, [sp]
  2323. ldrb r1, [r6, 0x9]
  2324. ldrb r0, [r5, 0x1D]
  2325. adds r0, r1
  2326. cmp r0, 0xFF
  2327. bls _081DDBAC
  2328. movs r0, 0xFF
  2329. _081DDBAC:
  2330. str r0, [sp, 0x10]
  2331. mov r6, r9
  2332. ldrb r0, [r6]
  2333. movs r6, 0x7
  2334. ands r6, r0
  2335. str r6, [sp, 0xC]
  2336. beq _081DDBEC
  2337. ldr r0, [sp, 0x4]
  2338. ldr r4, [r0, 0x1C]
  2339. cmp r4, 0
  2340. bne _081DDBC4
  2341. b _081DDCEA
  2342. _081DDBC4:
  2343. subs r6, 0x1
  2344. lsls r0, r6, 6
  2345. adds r4, r0
  2346. ldrb r1, [r4]
  2347. movs r0, 0xC7
  2348. tst r0, r1
  2349. beq _081DDC40
  2350. movs r0, 0x40
  2351. tst r0, r1
  2352. bne _081DDC40
  2353. ldrb r1, [r4, 0x13]
  2354. ldr r0, [sp, 0x10]
  2355. cmp r1, r0
  2356. bcc _081DDC40
  2357. beq _081DDBE4
  2358. b _081DDCEA
  2359. _081DDBE4:
  2360. ldr r0, [r4, 0x2C]
  2361. cmp r0, r5
  2362. bcs _081DDC40
  2363. b _081DDCEA
  2364. _081DDBEC:
  2365. ldr r6, [sp, 0x10]
  2366. adds r7, r5, 0
  2367. movs r2, 0
  2368. mov r8, r2
  2369. ldr r4, [sp, 0x4]
  2370. ldrb r3, [r4, 0x6]
  2371. adds r4, 0x50
  2372. _081DDBFA:
  2373. ldrb r1, [r4]
  2374. movs r0, 0xC7
  2375. tst r0, r1
  2376. beq _081DDC40
  2377. movs r0, 0x40
  2378. tst r0, r1
  2379. beq _081DDC14
  2380. cmp r2, 0
  2381. bne _081DDC18
  2382. adds r2, 0x1
  2383. ldrb r6, [r4, 0x13]
  2384. ldr r7, [r4, 0x2C]
  2385. b _081DDC32
  2386. _081DDC14:
  2387. cmp r2, 0
  2388. bne _081DDC34
  2389. _081DDC18:
  2390. ldrb r0, [r4, 0x13]
  2391. cmp r0, r6
  2392. bcs _081DDC24
  2393. adds r6, r0, 0
  2394. ldr r7, [r4, 0x2C]
  2395. b _081DDC32
  2396. _081DDC24:
  2397. bhi _081DDC34
  2398. ldr r0, [r4, 0x2C]
  2399. cmp r0, r7
  2400. bls _081DDC30
  2401. adds r7, r0, 0
  2402. b _081DDC32
  2403. _081DDC30:
  2404. bcc _081DDC34
  2405. _081DDC32:
  2406. mov r8, r4
  2407. _081DDC34:
  2408. adds r4, 0x40
  2409. subs r3, 0x1
  2410. bgt _081DDBFA
  2411. mov r4, r8
  2412. cmp r4, 0
  2413. beq _081DDCEA
  2414. _081DDC40:
  2415. adds r0, r4, 0
  2416. bl ClearChain
  2417. movs r1, 0
  2418. str r1, [r4, 0x30]
  2419. ldr r3, [r5, 0x20]
  2420. str r3, [r4, 0x34]
  2421. cmp r3, 0
  2422. beq _081DDC54
  2423. str r4, [r3, 0x30]
  2424. _081DDC54:
  2425. str r4, [r5, 0x20]
  2426. str r5, [r4, 0x2C]
  2427. ldrb r0, [r5, 0x1B]
  2428. strb r0, [r5, 0x1C]
  2429. cmp r0, r1
  2430. beq _081DDC66
  2431. adds r1, r5, 0
  2432. bl clear_modM
  2433. _081DDC66:
  2434. ldr r0, [sp]
  2435. adds r1, r5, 0
  2436. bl TrkVolPitSet
  2437. ldr r0, [r5, 0x4]
  2438. str r0, [r4, 0x10]
  2439. ldr r0, [sp, 0x10]
  2440. strb r0, [r4, 0x13]
  2441. ldr r0, [sp, 0x8]
  2442. strb r0, [r4, 0x8]
  2443. ldr r0, [sp, 0x14]
  2444. strb r0, [r4, 0x14]
  2445. mov r6, r9
  2446. ldrb r0, [r6]
  2447. strb r0, [r4, 0x1]
  2448. ldr r7, [r6, 0x4]
  2449. str r7, [r4, 0x24]
  2450. ldr r0, [r6, 0x8]
  2451. str r0, [r4, 0x4]
  2452. ldrh r0, [r5, 0x1E]
  2453. strh r0, [r4, 0xC]
  2454. bl ChnVolSetAsm
  2455. ldrb r1, [r4, 0x8]
  2456. movs r0, 0x8
  2457. ldrsb r0, [r5, r0]
  2458. adds r3, r1, r0
  2459. bpl _081DDCA0
  2460. movs r3, 0
  2461. _081DDCA0:
  2462. ldr r6, [sp, 0xC]
  2463. cmp r6, 0
  2464. beq _081DDCCE
  2465. mov r6, r9
  2466. ldrb r0, [r6, 0x2]
  2467. strb r0, [r4, 0x1E]
  2468. ldrb r1, [r6, 0x3]
  2469. movs r0, 0x80
  2470. tst r0, r1
  2471. bne _081DDCBA
  2472. movs r0, 0x70
  2473. tst r0, r1
  2474. bne _081DDCBC
  2475. _081DDCBA:
  2476. movs r1, 0x8
  2477. _081DDCBC:
  2478. strb r1, [r4, 0x1F]
  2479. ldrb r2, [r5, 0x9]
  2480. adds r1, r3, 0
  2481. ldr r0, [sp, 0xC]
  2482. ldr r3, [sp, 0x4]
  2483. ldr r3, [r3, 0x30]
  2484. bl call_r3
  2485. b _081DDCDC
  2486. _081DDCCE:
  2487. ldr r0, [r5, o_MusicPlayerTrack_unk_3C]
  2488. str r0, [r4, 0x18]
  2489. ldrb r2, [r5, 0x9]
  2490. adds r1, r3, 0
  2491. adds r0, r7, 0
  2492. bl MidiKeyToFreq
  2493. _081DDCDC:
  2494. str r0, [r4, 0x20]
  2495. movs r0, 0x80
  2496. strb r0, [r4]
  2497. ldrb r1, [r5]
  2498. movs r0, 0xF0
  2499. ands r0, r1
  2500. strb r0, [r5]
  2501. _081DDCEA:
  2502. add sp, 0x18
  2503. pop {r0-r7}
  2504. mov r8, r0
  2505. mov r9, r1
  2506. mov r10, r2
  2507. mov r11, r3
  2508. pop {r0}
  2509. bx r0
  2510. .pool
  2511. thumb_func_end ply_note
  2512.  
  2513. thumb_func_start ply_endtie
  2514. ply_endtie:
  2515. push {r4,r5}
  2516. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  2517. ldrb r3, [r2]
  2518. cmp r3, 0x80
  2519. bhs _081DDD16
  2520. strb r3, [r1, o_MusicPlayerTrack_key]
  2521. adds r2, 0x1
  2522. str r2, [r1, o_MusicPlayerTrack_cmdPtr]
  2523. b _081DDD18
  2524. _081DDD16:
  2525. ldrb r3, [r1, o_MusicPlayerTrack_key]
  2526. _081DDD18:
  2527. ldr r1, [r1, o_MusicPlayerTrack_chan]
  2528. cmp r1, 0
  2529. beq _081DDD40
  2530. movs r4, 0x83
  2531. movs r5, 0x40
  2532. _081DDD22:
  2533. ldrb r2, [r1, o_SoundChannel_status]
  2534. tst r2, r4
  2535. beq _081DDD3A
  2536. tst r2, r5
  2537. bne _081DDD3A
  2538. ldrb r0, [r1, o_SoundChannel_mk]
  2539. cmp r0, r3
  2540. bne _081DDD3A
  2541. movs r0, 0x40
  2542. orrs r2, r0
  2543. strb r2, [r1, o_SoundChannel_status]
  2544. b _081DDD40
  2545. _081DDD3A:
  2546. ldr r1, [r1, o_SoundChannel_np]
  2547. cmp r1, 0
  2548. bne _081DDD22
  2549. _081DDD40:
  2550. pop {r4,r5}
  2551. bx lr
  2552. thumb_func_end ply_endtie
  2553.  
  2554. thumb_func_start clear_modM
  2555. clear_modM:
  2556. movs r2, 0
  2557. strb r2, [r1, o_MusicPlayerTrack_modM]
  2558. strb r2, [r1, o_MusicPlayerTrack_lfoSpeedC]
  2559. ldrb r2, [r1, o_MusicPlayerTrack_modT]
  2560. cmp r2, 0
  2561. bne _081DDD54
  2562. movs r2, 0xC
  2563. b _081DDD56
  2564. _081DDD54:
  2565. movs r2, 0x3
  2566. _081DDD56:
  2567. ldrb r3, [r1, o_MusicPlayerTrack_flags]
  2568. orrs r3, r2
  2569. strb r3, [r1, o_MusicPlayerTrack_flags]
  2570. bx lr
  2571. thumb_func_end clear_modM
  2572.  
  2573. thumb_func_start ld_r3_tp_adr_i
  2574. ld_r3_tp_adr_i_unchecked:
  2575. ldr r2, [r1, o_MusicPlayerTrack_cmdPtr]
  2576. adds r3, r2, 1
  2577. str r3, [r1, o_MusicPlayerTrack_cmdPtr]
  2578. ldrb r3, [r2]
  2579. bx lr
  2580. thumb_func_end ld_r3_tp_adr_i
  2581.  
  2582. thumb_func_start ply_lfos
  2583. ply_lfos:
  2584. mov r12, lr
  2585. bl ld_r3_tp_adr_i_unchecked
  2586. strb r3, [r1, o_MusicPlayerTrack_lfoSpeed]
  2587. cmp r3, 0
  2588. bne _081DDD7C
  2589. bl clear_modM
  2590. _081DDD7C:
  2591. bx r12
  2592. thumb_func_end ply_lfos
  2593.  
  2594. thumb_func_start ply_mod
  2595. ply_mod:
  2596. mov r12, lr
  2597. bl ld_r3_tp_adr_i_unchecked
  2598. strb r3, [r1, o_MusicPlayerTrack_mod]
  2599. cmp r3, 0
  2600. bne _081DDD90
  2601. bl clear_modM
  2602. _081DDD90:
  2603. bx r12
  2604. thumb_func_end ply_mod
  2605.  
  2606. .align 2, 0 @ Don't pad with nop.
Add Comment
Please, Sign In to add comment