Без опису

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413
  1. @ created by ~ipatix~
  2. @ revision 2.1
  3. /* globals */
  4. .global main_mixer
  5. .global mixer_size
  6. .set mixer_size, (main_mixer_end - main_mixer) / 4
  7. /* game code definitions */
  8. .equ GAME_BPED, 0
  9. .equ GAME_BPEE, 1
  10. .equ GAME_BPRE, 2
  11. .equ GAME_KWJ6, 3
  12. .equ GAME_AE7E, 4
  13. .equ GAME_BPRD, 5
  14. /* SELECT USED GAME HERE */
  15. .equ USED_GAME, GAME_BPRE
  16. .equ FRAME_LENGTH_5734, 0x60
  17. .equ FRAME_LENGTH_7884, 0x84 @ THIS MODE IS NOT SUPPORTED BY THIS ENGINE BECAUSE IT DOESN'T USE AN 8 ALIGNED BUFFER LENGTH
  18. .equ FRAME_LENGTH_10512, 0xB0
  19. .equ FRAME_LENGTH_13379, 0xE0 @ DEFAULT
  20. .equ FRAME_LENGTH_15768, 0x108
  21. .equ FRAME_LENGTH_18157, 0x130
  22. .equ FRAME_LENGTH_21024, 0x160
  23. .equ FRAME_LENGTH_26758, 0x1C0
  24. .equ FRAME_LENGTH_31536, 0x210
  25. .equ FRAME_LENGTH_36314, 0x260
  26. .equ FRAME_LENGTH_40137, 0x2A0
  27. .equ FRAME_LENGTH_42048, 0x2C0
  28. .equ DECODER_BUFFER_BPE, 0x03001300
  29. .equ DECODER_BUFFER_BPR, 0x03002088
  30. .equ DECODER_BUFFER_KWJ, 0x03005800
  31. .equ BUFFER_IRAM_BPE, 0x03001AA8
  32. .equ BUFFER_IRAM_BPR, 0x030028E0
  33. .equ BUFFER_IRAM_KWJ, 0x03005840
  34. .equ BUFFER_IRAM_AE7, 0x03006D60
  35. /* stack variables */
  36. .equ ARG_FRAME_LENGTH, 0x0 @ TODO actually use this variable
  37. .equ ARG_REMAIN_CHN, 0x4 @ This is the channel count variable
  38. .equ ARG_BUFFER_POS, 0x8 @ stores the current output buffer pointer
  39. .equ ARG_LOOP_START_POS, 0xC @ stores wave loop start position in channel loop
  40. .equ ARG_LOOP_LENGTH, 0x10 @ '' '' '' end position
  41. @ .equ ARG_UKNOWN, 0x14
  42. .equ ARG_PCM_STRUCT, 0x18 @ pointer to engine the main work area
  43. /* channel struct */
  44. .equ CHN_STATUS, 0x0 @ [byte] channel status bitfield
  45. .equ CHN_MODE, 0x1 @ [byte] channel mode bitfield
  46. .equ CHN_VOL_1, 0x2 @ [byte] volume right
  47. .equ CHN_VOL_2, 0x3 @ [byte] volume left
  48. .equ CHN_ATTACK, 0x4 @ [byte] wave attack summand
  49. .equ CHN_DECAY, 0x5 @ [byte] wave decay factor
  50. .equ CHN_SUSTAIN, 0x6 @ [byte] wave sustain level
  51. .equ CHN_RELEASE, 0x7 @ [byte] wave release factor
  52. .equ CHN_ADSR_LEVEL, 0x9 @ [byte] current envelope level
  53. .equ CHN_FINAL_VOL_1, 0xA @ [byte] not used anymore!
  54. .equ CHN_FINAL_VOL_2, 0xB @ [byte] not used anymore!
  55. .equ CHN_ECHO_VOL, 0xC @ [byte] pseudo echo volume
  56. .equ CHN_ECHO_REMAIN, 0xD @ [byte] pseudo echo length
  57. .equ CHN_SAMPLE_COUNTDOWN, 0x18 @ [word] sample countdown in mixing loop
  58. .equ CHN_FINE_POSITION, 0x1C @ [word] inter sample position (23 bits)
  59. .equ CHN_FREQUENCY, 0x20 @ [word] sample rate (in Hz)
  60. .equ CHN_WAVE_OFFSET, 0x24 @ [word] wave header pointer
  61. .equ CHN_POSITION_ABS, 0x28 @ [word] points to the current position in the wave data (relative offset for compressed samples)
  62. .equ CHN_BLOCK_COUNT, 0x3C @ [word] only used for compressed samples: contains the value of the block that is currently decoded
  63. /* wave header struct */
  64. .equ WAVE_LOOP_FLAG, 0x3 @ [byte] 0x0 = oneshot; 0x40 = looped
  65. .equ WAVE_FREQ, 0x4 @ [word] pitch adjustment value = mid-C samplerate * 1024
  66. .equ WAVE_LOOP_START, 0x8 @ [word] loop start position
  67. .equ WAVE_LENGTH, 0xC @ [word] loop end / wave end position
  68. .equ WAVE_DATA, 0x10 @ [byte array] actual wave data
  69. /* pulse wave synth configuration offset */
  70. .equ SYNTH_BASE_WAVE_DUTY, 0x1 @ [byte]
  71. .equ SYNTH_WIDTH_CHANGE_1, 0x2 @ [byte]
  72. .equ SYNTH_MOD_AMOUNT, 0x3 @ [byte]
  73. .equ SYNTH_WIDTH_CHANGE_2, 0x4 @ [byte]
  74. /* CHN_STATUS flags - 0x0 = OFF */
  75. .equ FLAG_CHN_INIT, 0x80 @ [bit] write this value to init a channel
  76. .equ FLAG_CHN_RELEASE, 0x40 @ [bit] write this value to release (fade out) the channel
  77. .equ FLAG_CHN_COMP, 0x20 @ [bit] is wave being played compressed (yes/no)
  78. .equ FLAG_CHN_LOOP, 0x10 @ [bit] loop (yes/no)
  79. .equ FLAG_CHN_ECHO, 0x4 @ [bit] echo phase
  80. .equ FLAG_CHN_ATTACK, 0x3 @ [bit] attack phase
  81. .equ FLAG_CHN_DECAY, 0x2 @ [bit] decay phase
  82. .equ FLAG_CHN_SUSTAIN, 0x1 @ [bit] sustain phase
  83. /* CHN_MODE flags */
  84. .equ MODE_FIXED_FREQ, 0x8 @ [bit] set to disable resampling (i.e. playback with output rate)
  85. .equ MODE_REVERSE, 0x10 @ [bit] set to reverse sample playback
  86. .equ MODE_COMP, 0x30 @ [bit] is wave being played compressed or reversed (TODO: rename flag)
  87. .equ MODE_SYNTH, 0x40 @ [bit] READ ONLY, indicates synthzied output
  88. /* variables of the engine work area */
  89. .equ VAR_REVERB, 0x5 @ [byte] 0-127 = reverb level
  90. .equ VAR_MAX_CHN, 0x6 @ [byte] maximum channels to process
  91. .equ VAR_MASTER_VOL, 0x7 @ [byte] PCM master volume
  92. .equ VAR_DEF_PITCH_FAC, 0x18 @ [word] this value get's multiplied with the samplerate for the inter sample distance
  93. .equ VAR_FIRST_CHN, 0x50 @ [CHN struct] relative offset to channel array
  94. /* just some more defines */
  95. .equ REG_DMA3_SRC, 0x040000D4
  96. .equ ARM_OP_LEN, 0x4
  97. @#######################################
  98. @*********** GAME CONFIGS **************
  99. @ add the game's name above to the ASM .equ-s before creating new configs
  100. @#######################################
  101. @*********** IF GERMAN POKEMON EMERALD
  102. .if USED_GAME==GAME_BPED
  103. .equ hq_buffer_ptr, BUFFER_IRAM_BPE
  104. .equ decoder_buffer_target, DECODER_BUFFER_BPE
  105. .equ POKE_INIT, 1
  106. .equ DMA_FIX, 1
  107. .equ ENABLE_DECOMPRESSION, 1
  108. .equ ENABLE_CLIPPING, 1
  109. .endif
  110. @*********** IF ENGLISH POKEMON FIRE RED
  111. .if USED_GAME==GAME_BPRD
  112. .equ hq_buffer_ptr, 0x03002830
  113. .equ decoder_buffer_target, DECODER_BUFFER_BPR
  114. .equ POKE_INIT, 1
  115. .equ DMA_FIX, 1
  116. .equ ENABLE_DECOMPRESSION, 1
  117. .equ ENABLE_CLIPPING, 1
  118. .endif
  119. @*********** IF ENGLISH POKEMON EMERALD
  120. .if USED_GAME==GAME_BPEE
  121. .equ hq_buffer_ptr, BUFFER_IRAM_BPE
  122. .equ decoder_buffer_target, DECODER_BUFFER_BPE
  123. .equ POKE_INIT, 1
  124. .equ DMA_FIX, 1
  125. .equ ENABLE_DECOMPRESSION, 1
  126. .equ ENABLE_CLIPPING, 1
  127. .endif
  128. @*********** IF ENGLISH POKEMON FIRE RED
  129. .if USED_GAME==GAME_BPRE
  130. .equ hq_buffer_ptr, BUFFER_IRAM_BPR
  131. .equ decoder_buffer_target, DECODER_BUFFER_BPR
  132. .equ POKE_INIT, 1
  133. .equ DMA_FIX, 1
  134. .equ ENABLE_DECOMPRESSION, 1
  135. .equ ENABLE_CLIPPING, 1
  136. .endif
  137. @*********** IF KAWAs JUKEBOX 2006
  138. .if USED_GAME==GAME_KWJ6
  139. .equ hq_buffer_ptr, BUFFER_IRAM_KWJ
  140. .equ decoder_buffer_target, DECODER_BUFFER_KWJ
  141. .equ POKE_INIT, 0
  142. .equ DMA_FIX, 0
  143. .equ ENABLE_DECOMPRESSION, 0
  144. .equ ENABLE_CLIPPING, 1
  145. .endif
  146. @*********** IF US FIRE EMBLEM
  147. .if USED_GAME==GAME_AE7E
  148. .equ hq_buffer_ptr, BUFFER_IRAM_AE7
  149. .equ POKE_INIT, 0
  150. .equ DMA_FIX, 0
  151. .equ ENABLE_DECOMPRESSION, 0
  152. .equ ENABLE_CLIPPING, 0
  153. .endif
  154. @***********
  155. .thumb
  156. main_mixer:
  157. /* load Reverb level and check if we need to apply it */
  158. LDRB R3, [R0, #VAR_REVERB]
  159. LSR R3, R3, #2
  160. BEQ C_clear_hq_buffer
  161. ADR R1, C_setup_reverb_loop
  162. BX R1
  163. .arm
  164. .align 2
  165. C_setup_reverb_loop:
  166. /*
  167. * reverb is calculated by the following: new_sample = old_sample * reverb_level / 127
  168. * note that reverb is mono (both sides get mixed together)
  169. *
  170. * reverb get's applied to the frame we are currently looking at and the one after that
  171. * the magic below simply calculateds the pointer for the one after the current one
  172. */
  173. CMP R4, #2
  174. ADDEQ R7, R0, #0x350
  175. ADDNE R7, R5, R8
  176. MOV R4, R8
  177. ORR R3, R3, R3, LSL#16
  178. STMFD SP!, {R8, LR}
  179. LDR LR, hq_buffer
  180. C_reverb_loop:
  181. /* This loop does the reverb processing */
  182. LDRSB R0, [R5, R6]
  183. LDRSB R1, [R5], #1
  184. LDRSB R2, [R7, R6]
  185. LDRSB R8, [R7], #1
  186. LDRSB R9, [R5, R6]
  187. LDRSB R10, [R5], #1
  188. LDRSB R11, [R7, R6]
  189. LDRSB R12, [R7], #1
  190. ADD R0, R0, R1
  191. ADD R0, R0, R2
  192. ADD R0, R0, R8
  193. ADDMI R0, R0, #0x4
  194. ADD R1, R9, R10
  195. ADD R1, R1, R11
  196. ADDS R1, R1, R12
  197. ADDMI R1, R1, #0x4
  198. MUL R0, R3, R0
  199. MUL R1, R3, R1
  200. STMIA LR!, {R0, R1}
  201. SUBS R4, R4, #2
  202. BGT C_reverb_loop
  203. /* end of loop */
  204. LDMFD SP!, {R8, LR}
  205. ADR R0, (C_setup_channel_state_loop+1)
  206. BX R0
  207. .thumb
  208. C_clear_hq_buffer:
  209. /* Incase reverb is disabled the buffer get's set to zero */
  210. LDR R3, hq_buffer
  211. MOV R1, R8
  212. MOV R4, #0
  213. MOV R5, #0
  214. MOV R6, #0
  215. MOV R7, #0
  216. /*
  217. * Setting the buffer to zero happens in a very efficient loop
  218. * Depending on the alignment of the buffer length, twice or quadruple the amount of bytes
  219. * get cleared at once
  220. */
  221. LSR R1, #3
  222. BCC C_clr_hq_buffer_align_8
  223. STMIA R3!, {R4, R5, R6, R7}
  224. C_clr_hq_buffer_align_8:
  225. LSR R1, #1
  226. BCC C_clr_hq_buffer_align_16
  227. STMIA R3!, {R4, R5, R6, R7}
  228. STMIA R3!, {R4, R5, R6, R7}
  229. C_clr_hq_buffer_align_16:
  230. /* This repeats until the buffer has been cleared */
  231. STMIA R3!, {R4, R5, R6, R7}
  232. STMIA R3!, {R4, R5, R6, R7}
  233. STMIA R3!, {R4, R5, R6, R7}
  234. STMIA R3!, {R4, R5, R6, R7}
  235. SUB R1, #1
  236. BGT C_clr_hq_buffer_align_16
  237. /* loop end */
  238. C_setup_channel_state_loop:
  239. /*
  240. * okay, before the actual mixing starts
  241. * the volume and envelope calculation takes place
  242. */
  243. MOV R4, R8 @ R4 = buffer length
  244. /*
  245. * this stroes the buffer length to a backup location
  246. */
  247. ADR R0, hq_buffer_length
  248. STR R4, [R0]
  249. /* init channel loop */
  250. LDR R4, [SP, #ARG_PCM_STRUCT] @ R4 = main work area pointer
  251. LDR R0, [R4, #VAR_DEF_PITCH_FAC] @ R0 = samplingrate pitch factor
  252. MOV R12, R0
  253. LDRB R0, [R4, #VAR_MAX_CHN]
  254. ADD R4, #VAR_FIRST_CHN @ R4 = Base channel Offset (Channel #0)
  255. C_channel_state_loop:
  256. /* this is the main channel processing loop */
  257. STR R0, [SP, #ARG_REMAIN_CHN]
  258. LDR R3, [R4, #CHN_WAVE_OFFSET]
  259. LDRB R6, [R4, #CHN_STATUS] @ R6 will hold the channel status
  260. MOVS R0, #0xC7 @ check if any of the channel status flags is set
  261. TST R0, R6 @ check if none of the flags is set
  262. BEQ C_skip_channel
  263. /* check channel flags */
  264. LSL R0, R6, #25 @ shift over the FLAG_CHN_INIT to CARRY
  265. BCC C_adsr_echo_check @ continue with normal channel procedure
  266. /* check leftmost bit */
  267. BMI C_stop_channel @ FLAG_CHN_INIT | FLAG_CHN_RELEASE -> stop directly
  268. /* channel init procedure */
  269. MOVS R6, #FLAG_CHN_ATTACK
  270. MOVS R0, R3 @ R0 = CHN_WAVE_OFFSET
  271. ADD R0, #WAVE_DATA @ R0 = wave data offset
  272. /* Pokemon games seem to init channels differently than other m4a games */
  273. .if POKE_INIT==0
  274. STR R0, [R4, #CHN_POSITION_ABS]
  275. LDR R0, [R3, #WAVE_LENGTH]
  276. STR R0, [R4, #CHN_SAMPLE_COUNTDOWN]
  277. .else
  278. LDR R1, [R4, #CHN_SAMPLE_COUNTDOWN]
  279. ADD R0, R0, R1
  280. STR R0, [R4, #CHN_POSITION_ABS]
  281. LDR R0, [R3, #WAVE_LENGTH]
  282. SUB R0, R0, R1
  283. STR R0, [R4, #CHN_SAMPLE_COUNTDOWN]
  284. .endif
  285. MOVS R5, #0 @ initial envelope = #0
  286. STRB R5, [R4, #CHN_ADSR_LEVEL]
  287. STR R5, [R4, #CHN_FINE_POSITION]
  288. LDRB R2, [R3, #WAVE_LOOP_FLAG]
  289. LSR R0, R2, #6
  290. BEQ C_adsr_attack
  291. /* loop enabled here */
  292. MOVS R0, #FLAG_CHN_LOOP
  293. ORR R6, R0
  294. B C_adsr_attack
  295. C_adsr_echo_check:
  296. /* this is the normal ADSR procedure without init */
  297. LDRB R5, [R4, #CHN_ADSR_LEVEL]
  298. LSL R0, R6, #29 @ FLAG_CHN_ECHO --> bit 31 (sign bit)
  299. BPL C_adsr_release_check
  300. /* pseudo echo handler */
  301. LDRB R0, [R4, #CHN_ECHO_REMAIN]
  302. SUB R0, #1
  303. STRB R0, [R4, #CHN_ECHO_REMAIN]
  304. BHI C_channel_vol_calc @ continue normal if channel is still on
  305. C_stop_channel:
  306. MOVS R0, #0
  307. STRB R0, [R4, #CHN_STATUS]
  308. C_skip_channel:
  309. /* go to end of the channel loop */
  310. B C_end_channel_state_loop
  311. C_adsr_release_check:
  312. LSL R0, R6, #25 @ FLAG_CHN_RELEASE --> bit 31 (sign bit)
  313. BPL C_adsr_decay_check
  314. /* release handler */
  315. LDRB R0, [R4, #CHN_RELEASE]
  316. @SUB R0, #0xFF @ linear decay; TODO make option for triggering it
  317. @SUB R0, #1
  318. @ADD R5, R5, R0
  319. MUL R5, R5, R0
  320. LSR R5, #8
  321. BLE C_adsr_released
  322. /* pseudo echo init handler */
  323. LDRB R0, [R4, #CHN_ECHO_VOL]
  324. CMP R5, R0
  325. BHI C_channel_vol_calc
  326. C_adsr_released:
  327. /* if volume released to #0 */
  328. LDRB R5, [R4, #CHN_ECHO_VOL]
  329. CMP R5, #0
  330. BEQ C_stop_channel
  331. /* pseudo echo volume handler */
  332. MOVS R0, #FLAG_CHN_ECHO
  333. ORR R6, R0 @ set the echo flag
  334. B C_adsr_save_and_finalize
  335. C_adsr_decay_check:
  336. /* check if decay is active */
  337. MOVS R2, #(FLAG_CHN_DECAY+FLAG_CHN_SUSTAIN)
  338. AND R2, R6
  339. CMP R2, #FLAG_CHN_DECAY
  340. BNE C_adsr_attack_check @ decay not active yet
  341. /* decay handler */
  342. LDRB R0, [R4, #CHN_DECAY]
  343. MUL R5, R5, R0
  344. LSR R5, R5, #8
  345. LDRB R0, [R4, #CHN_SUSTAIN]
  346. CMP R5, R0
  347. BHI C_channel_vol_calc @ sample didn't decay yet
  348. /* sustain handler */
  349. MOVS R5, R0 @ current level = sustain level
  350. BEQ C_adsr_released @ sustain level #0 --> branch
  351. /* step to next phase otherweise */
  352. B C_adsr_next_state
  353. C_adsr_attack_check:
  354. /* attack handler */
  355. CMP R2, #FLAG_CHN_ATTACK
  356. BNE C_channel_vol_calc @ if it isn't in attack attack phase, it has to be in sustain (keep vol) --> branch
  357. C_adsr_attack:
  358. /* apply attack summand */
  359. LDRB R0, [R4, #CHN_ATTACK]
  360. ADD R5, R0
  361. CMP R5, #0xFF
  362. BLO C_adsr_save_and_finalize
  363. /* cap attack at 0xFF */
  364. MOVS R5, #0xFF
  365. C_adsr_next_state:
  366. /* switch to next adsr phase */
  367. SUB R6, #1
  368. C_adsr_save_and_finalize:
  369. /* store channel status */
  370. STRB R6, [R4, #CHN_STATUS]
  371. C_channel_vol_calc:
  372. /* store the calculated ADSR level */
  373. STRB R5, [R4, #CHN_ADSR_LEVEL]
  374. /* apply master volume */
  375. LDR R0, [SP, #ARG_PCM_STRUCT]
  376. LDRB R0, [R0, #VAR_MASTER_VOL]
  377. ADD R0, #1
  378. MUL R5, R0
  379. /* left side volume */
  380. LDRB R0, [R4, #CHN_VOL_2]
  381. MUL R0, R5
  382. LSR R0, #13
  383. MOV R10, R0 @ R10 = left volume
  384. /* right side volume */
  385. LDRB R0, [R4, #CHN_VOL_1]
  386. MUL R0, R5
  387. LSR R0, #13
  388. MOV R11, R0 @ R11 = right volume
  389. /*
  390. * Now we get closer to actual mixing:
  391. * For looped samples some additional operations are required
  392. */
  393. MOVS R0, #FLAG_CHN_LOOP
  394. AND R0, R6
  395. BEQ C_skip_sample_loop_setup
  396. /* loop setup handler */
  397. ADD R3, #WAVE_LOOP_START
  398. LDMIA R3!, {R0, R1} @ R0 = loop start, R1 = loop end
  399. ADD R3, R0 @ R3 = loop start position (absolute)
  400. STR R3, [SP, #ARG_LOOP_START_POS]
  401. SUB R0, R1, R0
  402. C_skip_sample_loop_setup:
  403. /* do the rest of the setup */
  404. STR R0, [SP, #ARG_LOOP_LENGTH] @ if loop is off --> R0 = 0x0
  405. LDR R5, hq_buffer
  406. LDR R2, [R4, #CHN_SAMPLE_COUNTDOWN]
  407. LDR R3, [R4, #CHN_POSITION_ABS]
  408. LDRB R0, [R4, #CHN_MODE]
  409. ADR R1, C_mixing_setup
  410. BX R1
  411. .align 2
  412. hq_buffer:
  413. .word hq_buffer_ptr
  414. hq_buffer_length: @ TODO: Replace with variable on stack
  415. .word 0xFFFFFFFF
  416. .arm
  417. .align 2
  418. C_mixing_setup:
  419. /* frequency and mixing loading routine */
  420. LDR R8, hq_buffer_length
  421. ORRS R11, R10, R11, LSL#16 @ R11 = 00RR00LL
  422. BEQ C_mixing_epilogue @ volume #0 --> branch and skip channel processing
  423. /* normal processing otherwise */
  424. TST R0, #MODE_FIXED_FREQ
  425. BNE C_setup_fixed_freq_mixing
  426. TST R0, #MODE_COMP
  427. BNE C_setup_special_mixing @ compressed? --> branch
  428. STMFD SP!, {R4, R9, R12}
  429. /*
  430. * This mixer supports 4 different kind of synthesized sounds
  431. * They are triggered if there is no samples to play
  432. * This get's checked below
  433. */
  434. MOVS R2, R2
  435. ORREQ R0, R0, #MODE_SYNTH
  436. STREQB R0, [R4, #CHN_MODE]
  437. ADD R4, R4, #CHN_FINE_POSITION
  438. LDMIA R4, {R7, LR} @ R7 = Fine Position, LR = Frequency
  439. MUL R4, LR, R12 @ R4 = inter sample steps = output rate factor * samplerate
  440. /* now the first samples get loaded */
  441. LDRSB R6, [R3], #1
  442. LDRSB R12, [R3]
  443. TST R0, #MODE_SYNTH
  444. BNE C_setup_synth
  445. /* incase no synth mode should be used, code contiues here */
  446. SUB R12, R12, R6 @ R12 = DELTA
  447. /*
  448. * Mixing goes with volume ranges 0-127
  449. * They come in 0-255 --> divide by 2
  450. */
  451. MOVS R11, R11, LSR#1
  452. ADC R11, R11, #0x8000
  453. BIC R11, R11, #0xFF00
  454. MOV R1, R7 @ R1 = inter sample position
  455. /*
  456. * There is 2 different mixing codepaths for uncompressed data
  457. * path 1: fast mixing, but doesn't supports loop or stop
  458. * path 2: not so fast but supports sample loops / stop
  459. * This checks if there is enough samples aviable for path 1.
  460. * important: R0 is expected to be #0
  461. */
  462. UMLAL R1, R0, R4, R8
  463. MOV R1, R1, LSR#23
  464. ORR R0, R1, R0, LSL#9
  465. CMP R2, R0 @ actual comparison
  466. BLE C_setup_unbuffered_mixing @ if not enough samples are available for path 1 --> branch
  467. /*
  468. * This is the mixer path 1.
  469. * The interesting thing here is that the code will
  470. * buffer enough samples on stack if enough space
  471. * on stack is available (or goes over the limit of 0x400 bytes)
  472. */
  473. SUB R2, R2, R0
  474. LDR R10, upper_stack_bounds
  475. ADD R10, R10, R0
  476. CMP R10, SP
  477. ADD R10, R3, R0
  478. ADR R9, stack_backup
  479. /*
  480. * R2 = remaining samples after processing
  481. * R10 = final sample position
  482. * SP = original stack location
  483. * These values will get reloaded after channel processing
  484. * due to the lack of registers.
  485. */
  486. STMIA R9, {R2, R10, SP}
  487. CMPCC R0, #0x400 @ > 0x400 bytes --> read directly from ROM rather than buffered
  488. BCS C_select_highspeed_codepath
  489. /*
  490. * The code below inits the DMA to read word aligned
  491. * samples from ROM to stack
  492. */
  493. BIC R1, R3, #3
  494. MOV R9, #0x04000000
  495. ADD R9, R9, #0xD4
  496. ADD R0, R0, #7
  497. MOV R0, R0, LSR#2
  498. SUB SP, SP, R0, LSL#2
  499. AND R3, R3, #3
  500. ADD R3, R3, SP
  501. ORR LR, R0, #0x84000000
  502. STMIA R9, {R1, SP, LR} @ actually starts the DMA
  503. /* Somehow is neccesary for some games not to break */
  504. .if DMA_FIX==1
  505. MOV R0, #0
  506. MOV R1, #0
  507. MOV R2, #0
  508. STMIA R9, {R0, R1, R2}
  509. .endif
  510. C_select_highspeed_codepath:
  511. /*
  512. * This code decides which piece of code to load
  513. * depending on playback-rate / default-rate ratio.
  514. * Modes > 1.0 run with different volume levels.
  515. * R4 = inter sample step
  516. */
  517. ADR R0, high_speed_code_resource @ loads the base pointer of the code
  518. SUBS R4, R4, #0x800000
  519. MOVPL R11, R11, LSL#1 @ if >= 1.0* 0-127 --> 0-254 volume level
  520. ADDPL R0, R0, #(ARM_OP_LEN*6) @ 6 instructions further
  521. SUBPLS R4, R4, #0x800000 @ if >= 2.0*
  522. ADDPL R0, R0, #(ARM_OP_LEN*6)
  523. ADDPL R4, R4, #0x800000
  524. LDR R2, previous_fast_code
  525. CMP R0, R2 @ code doesn't need to be reloaded if it's already in place
  526. BEQ C_skip_fast_mixing_creation
  527. /* This loads the needed code to RAM */
  528. STR R0, previous_fast_code
  529. LDMIA R0, {R0-R2, R8-R10} @ load 6 opcodes
  530. ADR LR, fast_mixing_instructions
  531. C_fast_mixing_creation_loop:
  532. /* paste code to destination, see below for patterns */
  533. STMIA LR, {R0, R1}
  534. ADD LR, LR, #(ARM_OP_LEN*38)
  535. STMIA LR, {R0, R1}
  536. SUB LR, LR, #(ARM_OP_LEN*35)
  537. STMIA LR, {R2, R8-R10}
  538. ADD LR, LR, #(ARM_OP_LEN*38)
  539. STMIA LR, {R2, R8-R10}
  540. SUB LR, LR, #(ARM_OP_LEN*32)
  541. ADDS R5, R5, #0x40000000 @ do that for 4 blocks
  542. BCC C_fast_mixing_creation_loop
  543. LDR R8, hq_buffer_length
  544. C_skip_fast_mixing_creation:
  545. MOV R2, #0xFF000000 @ load the fine position overflow bitmask
  546. C_fast_mixing_loop:
  547. /* This is the actual processing and interpolation code loop; NOPs will be replaced by the code above */
  548. LDMIA R5, {R0, R1, R10, LR} @ load 4 stereo samples to Registers
  549. MUL R9, R7, R12
  550. fast_mixing_instructions:
  551. NOP @ Block #1
  552. NOP
  553. MLANE R0, R11, R9, R0
  554. NOP
  555. NOP
  556. NOP
  557. NOP
  558. BIC R7, R7, R2, ASR#1
  559. MULNE R9, R7, R12
  560. NOP @ Block #2
  561. NOP
  562. MLANE R1, R11, R9, R1
  563. NOP
  564. NOP
  565. NOP
  566. NOP
  567. BIC R7, R7, R2, ASR#1
  568. MULNE R9, R7, R12
  569. NOP @ Block #3
  570. NOP
  571. MLANE R10, R11, R9, R10
  572. NOP
  573. NOP
  574. NOP
  575. NOP
  576. BIC R7, R7, R2, ASR#1
  577. MULNE R9, R7, R12
  578. NOP @ Block #4
  579. NOP
  580. MLANE LR, R11, R9, LR
  581. NOP
  582. NOP
  583. NOP
  584. NOP
  585. BIC R7, R7, R2, ASR#1
  586. STMIA R5!, {R0, R1, R10, LR} @ write 4 stereo samples
  587. LDMIA R5, {R0, R1, R10, LR} @ load the next 4 stereo samples
  588. MULNE R9, R7, R12
  589. NOP @ Block #1
  590. NOP
  591. MLANE R0, R11, R9, R0
  592. NOP
  593. NOP
  594. NOP
  595. NOP
  596. BIC R7, R7, R2, ASR#1
  597. MULNE R9, R7, R12
  598. NOP @ Block #2
  599. NOP
  600. MLANE R1, R11, R9, R1
  601. NOP
  602. NOP
  603. NOP
  604. NOP
  605. BIC R7, R7, R2, ASR#1
  606. MULNE R9, R7, R12
  607. NOP @ Block #3
  608. NOP
  609. MLANE R10, R11, R9, R10
  610. NOP
  611. NOP
  612. NOP
  613. NOP
  614. BIC R7, R7, R2, ASR#1
  615. MULNE R9, R7, R12
  616. NOP @ Block #4
  617. NOP
  618. MLANE LR, R11, R9, LR
  619. NOP
  620. NOP
  621. NOP
  622. NOP
  623. BIC R7, R7, R2, ASR#1
  624. STMIA R5!, {R0, R1, R10, LR} @ write 4 stereo samples
  625. SUBS R8, R8, #8
  626. BGT C_fast_mixing_loop
  627. /* restore previously saved values */
  628. ADR R12, stack_backup
  629. LDMIA R12, {R2, R3, SP}
  630. B C_end_mixing
  631. /* Various variables for the cached mixer */
  632. .align 2
  633. stack_backup:
  634. .word 0x0, 0x0, 0x0
  635. upper_stack_bounds:
  636. .word 0x03007910
  637. previous_fast_code:
  638. .word 0x0 /* mark as invalid initially */
  639. /* Those instructions below are used by the high speed loop self modifying code */
  640. high_speed_code_resource:
  641. /* Block for Mix Freq < 1.0 * Output Frequency */
  642. MOV R9, R9, ASR#22
  643. ADDS R9, R9, R6, LSL#1
  644. ADDS R7, R7, R4
  645. ADDPL R6, R12, R6
  646. LDRPLSB R12, [R3, #1]!
  647. SUBPLS R12, R12, R6
  648. /* Block for Mix Freq > 1.0 AND < 2.0 * Output Frequency */
  649. ADDS R9, R6, R9, ASR#23
  650. ADD R6, R12, R6
  651. ADDS R7, R7, R4
  652. LDRPLSB R6, [R3, #1]!
  653. LDRSB R12, [R3, #1]!
  654. SUBS R12, R12, R6
  655. /* Block for Mix Freq > 2.0 * Output Frequency */
  656. ADDS R9, R6, R9, ASR#23
  657. ADD R7, R7, R4
  658. ADD R3, R3, R7, LSR#23
  659. LDRSB R6, [R3]
  660. LDRSB R12, [R3, #1]!
  661. SUBS R12, R12, R6
  662. /* incase a loop or end occurs during mixing, this code is used */
  663. C_setup_unbuffered_mixing:
  664. ADD R5, R5, R8, LSL#2 @ R5 = End of HQ buffer
  665. /* This below is the unbuffered mixing loop. R6 = base sample, R12 diff to next */
  666. C_unbuffered_mixing_loop:
  667. MUL R9, R7, R12
  668. MOV R9, R9, ASR#22
  669. ADDS R9, R9, R6, LSL#1
  670. LDRNE R0, [R5, -R8, LSL#2]
  671. MLANE R0, R11, R9, R0
  672. STRNE R0, [R5, -R8, LSL#2]
  673. ADD R7, R7, R4
  674. MOVS R9, R7, LSR#23
  675. BEQ C_unbuffered_mixing_skip_load @ skip the mixing load if it isn't required
  676. SUBS R2, R2, R7, LSR#23
  677. BLLE C_mixing_loop_or_end
  678. SUBS R9, R9, #1
  679. ADDEQ R6, R12, R6
  680. @RETURN LOCATION FROM LOOP HANDLER
  681. LDRNESB R6, [R3, R9]!
  682. LDRSB R12, [R3, #1]!
  683. SUB R12, R12, R6
  684. BIC R7, R7, #0x3F800000
  685. C_unbuffered_mixing_skip_load:
  686. SUBS R8, R8, #1 @ reduce the sample count for the buffer by #1
  687. BGT C_unbuffered_mixing_loop
  688. C_end_mixing:
  689. SUB R3, R3, #1 @ because the mixer always needs 1 byte lookahead, this reverts it
  690. LDMFD SP!, {R4, R9, R12}
  691. STR R7, [R4, #CHN_FINE_POSITION]
  692. B C_mixing_end_store
  693. C_mixing_loop_or_end:
  694. /* This loads the loop information end loops incase it should */
  695. ADD R3, SP, #ARG_LOOP_START_POS+0xC
  696. LDMIA R3, {R3, R6} @ R3 = Loop Start; R6 = Loop Length
  697. CMP R6, #0 @ check if loop is enabled; if Loop is enabled R6 is != 0
  698. RSBNE R9, R2, #0 @ loop wraparound logic
  699. ADDNE R2, R6, R2
  700. ADDNE PC, LR, #(ARM_OP_LEN*2)
  701. LDMFD SP!, {R4, R9, R12}
  702. B C_mixing_end_and_stop_channel @ R6 == 0 (always)
  703. C_fixed_mixing_loop_or_end:
  704. LDR R2, [SP, #ARG_LOOP_LENGTH+0x8]
  705. MOVS R6, R2 @ copy it to R6 and check whether loop is disabled
  706. LDRNE R3, [SP, #ARG_LOOP_START_POS+0x8]
  707. BXNE LR @ if it loops return to mixing function, if it doesn't go on end mixing
  708. LDMFD SP!, {R4, R9}
  709. C_mixing_end_and_stop_channel:
  710. STRB R6, [R4] @ update channel flag with chn halt
  711. B C_mixing_epilogue
  712. /* These are used for the fixed freq mixer */
  713. fixed_mixing_code_resource:
  714. MOVS R6, R10, LSL#24
  715. MOVS R6, R6, ASR#24
  716. MOVS R6, R10, LSL#16
  717. MOVS R6, R6, ASR#24
  718. MOVS R6, R10, LSL#8
  719. MOVS R6, R6, ASR#24
  720. MOVS R6, R10, ASR#24
  721. LDMIA R3!, {R10} @ load chunk of samples
  722. MOVS R6, R10, LSL#24
  723. MOVS R6, R6, ASR#24
  724. MOVS R6, R10, LSL#16
  725. MOVS R6, R6, ASR#24
  726. MOVS R6, R10, LSL#8
  727. MOVS R6, R6, ASR#24
  728. LDMFD SP!, {R4, R9, R12}
  729. C_setup_fixed_freq_mixing:
  730. STMFD SP!, {R4, R9}
  731. C_fixed_mixing_length_check:
  732. MOV LR, R2 @ sample countdown
  733. CMP R2, R8
  734. MOVGT LR, R8 @ min(buffer_size, sample_countdown)
  735. SUB LR, LR, #1
  736. MOVS LR, LR, LSR#2
  737. BEQ C_fixed_mixing_process_rest @ <= 3 samples to process
  738. SUB R8, R8, LR, LSL#2 @ subtract the amount of samples we need to process from the buffer length
  739. SUB R2, R2, LR, LSL#2 @ subtract the amount of samples we need to process from the remaining samples
  740. ADR R1, fixed_mixing_instructions
  741. ADR R0, fixed_mixing_code_resource
  742. MOV R9, R3, LSL#30
  743. ADD R0, R0, R9, LSR#27 @ alignment * 8 + resource offset = new resource offset
  744. LDMIA R0!, {R6, R7, R9, R10} @ load and write instructions
  745. STMIA R1, {R6, R7}
  746. ADD R1, R1, #0xC
  747. STMIA R1, {R9, R10}
  748. ADD R1, R1, #0xC
  749. LDMIA R0, {R6, R7, R9, R10}
  750. STMIA R1, {R6, R7}
  751. ADD R1, R1, #0xC
  752. STMIA R1, {R9, R10}
  753. LDMIA R3!, {R10} @ load 4 samples from ROM
  754. C_fixed_mixing_loop:
  755. LDMIA R5, {R0, R1, R7, R9} @ load 4 samples from hq buffer
  756. fixed_mixing_instructions:
  757. NOP
  758. NOP
  759. MLANE R0, R11, R6, R0 @ add new sample if neccessary
  760. NOP
  761. NOP
  762. MLANE R1, R11, R6, R1
  763. NOP
  764. NOP
  765. MLANE R7, R11, R6, R7
  766. NOP
  767. NOP
  768. MLANE R9, R11, R6, R9
  769. STMIA R5!, {R0, R1, R7, R9} @ write samples to the mixing buffer
  770. SUBS LR, LR, #1
  771. BNE C_fixed_mixing_loop
  772. SUB R3, R3, #4 @ we'll need to load this block again, so rewind a bit
  773. C_fixed_mixing_process_rest:
  774. MOV R1, #4 @ repeat the loop #4 times to completley get rid of alignment errors
  775. C_fixed_mixing_unaligned_loop:
  776. LDR R0, [R5]
  777. LDRSB R6, [R3], #1
  778. MLA R0, R11, R6, R0
  779. STR R0, [R5], #4
  780. SUBS R2, R2, #1
  781. BLEQ C_fixed_mixing_loop_or_end
  782. SUBS R1, R1, #1
  783. BGT C_fixed_mixing_unaligned_loop
  784. SUBS R8, R8, #4
  785. BGT C_fixed_mixing_length_check @ repeat the mixing procedure until the buffer is filled
  786. LDMFD SP!, {R4, R9}
  787. C_mixing_end_store:
  788. STR R2, [R4, #CHN_SAMPLE_COUNTDOWN]
  789. STR R3, [R4, #CHN_POSITION_ABS]
  790. C_mixing_epilogue:
  791. ADR R0, (C_end_channel_state_loop+1)
  792. BX R0
  793. .thumb
  794. C_end_channel_state_loop:
  795. LDR R0, [SP, #ARG_REMAIN_CHN]
  796. SUB R0, #1
  797. BLE C_main_mixer_return
  798. ADD R4, #0x40
  799. B C_channel_state_loop
  800. C_main_mixer_return:
  801. ADR R0, C_downsampler
  802. BX R0
  803. .arm
  804. .align 2
  805. C_downsampler:
  806. LDR R10, hq_buffer
  807. LDR R9, [SP, #ARG_BUFFER_POS]
  808. LDR R8, hq_buffer_length
  809. MOV R11, #0xFF
  810. .if ENABLE_CLIPPING==1
  811. MOV R12, #0xFFFFFFFF
  812. MOV R12, R12, LSL#14
  813. MOV R7, #0x630
  814. C_downsampler_loop:
  815. LDRSH R2, [R10], #2
  816. LDRSH R0, [R10], #2
  817. LDRSH R3, [R10], #2
  818. LDRSH R1, [R10], #2
  819. CMP R0, #0x4000
  820. MOVGE R0, #0x3F80
  821. CMP R0, #-0x4000
  822. MOVLT R0, R12
  823. CMP R1, #0x4000
  824. MOVGE R1, #0x3F80
  825. CMP R1, #-0x4000
  826. MOVLT R1, R12
  827. CMP R2, #0x4000
  828. MOVGE R2, #0x3F80
  829. CMP R2, #-0x4000
  830. MOVLT R2, R12
  831. CMP R3, #0x4000
  832. MOVGE R3, #0x3F80
  833. CMP R3, #-0x4000
  834. MOVLT R3, R12
  835. AND R0, R11, R0, ASR#7
  836. AND R1, R11, R1, ASR#7
  837. AND R2, R11, R2, ASR#7
  838. AND R3, R11, R3, ASR#7
  839. ORR R2, R2, R3, LSL#8
  840. ORR R0, R0, R1, LSL#8
  841. STRH R2, [R9, R7]
  842. STRH R0, [R9], #2
  843. SUBS R8, #2
  844. BGT C_downsampler_loop
  845. .else
  846. C_downsampler_loop:
  847. LDRH R4, [R10], #2
  848. LDRH R0, [R10], #2
  849. LDRH R5, [R10], #2
  850. LDRH R1, [R10], #2
  851. LDRH R6, [R10], #2
  852. LDRH R2, [R10], #2
  853. LDRH R7, [R10], #2
  854. LDRH R3, [R10], #2
  855. AND R0, R11, R0, LSR#7
  856. AND R1, R11, R1, LSR#7
  857. AND R2, R11, R2, LSR#7
  858. AND R3, R11, R3, LSR#7
  859. AND R4, R11, R4, LSR#7
  860. AND R5, R11, R5, LSR#7
  861. AND R6, R11, R6, LSR#7
  862. AND R7, R11, R7, LSR#7
  863. ORR R4, R4, R5, LSL#8
  864. ORR R4, R4, R6, LSL#16
  865. ORR R4, R4, R7, LSL#24
  866. ORR R0, R0, R1, LSL#8
  867. ORR R0, R0, R2, LSL#16
  868. ORR R0, R0, R3, LSL#24
  869. STR R4, [R9, #0x630]
  870. STR R0, [R9], #4
  871. SUBS R8, #4
  872. BGT C_downsampler_loop
  873. .endif
  874. ADR R0, (C_downsampler_return+1)
  875. BX R0
  876. .thumb
  877. C_downsampler_return:
  878. LDR R0, [SP, #ARG_PCM_STRUCT]
  879. LDR R3, mixer_finished_status @ this is used to indicate the interrupt handler the rendering was finished properly
  880. STR R3, [R0]
  881. ADD SP, SP, #0x1C
  882. POP {R0-R7}
  883. MOV R8, R0
  884. MOV R9, R1
  885. MOV R10, R2
  886. MOV R11, R3
  887. POP {R3}
  888. BX R3
  889. .align 2
  890. mixer_finished_status:
  891. .word 0x68736D53
  892. .arm
  893. .align 2
  894. C_setup_synth:
  895. CMP R12, #0
  896. BNE C_check_synth_saw
  897. /* modulating pulse wave */
  898. LDRB R6, [R3, #SYNTH_WIDTH_CHANGE_1]
  899. ADD R2, R2, R6, LSL#24
  900. LDRB R6, [R3, #SYNTH_WIDTH_CHANGE_2]
  901. ADDS R6, R2, R6, LSL#24
  902. MVNMI R6, R6
  903. MOV R10, R6, LSR#8
  904. LDRB R1, [R3, #SYNTH_MOD_AMOUNT]
  905. LDRB R0, [R3, #SYNTH_BASE_WAVE_DUTY]
  906. MOV R0, R0, LSL#24
  907. MLA R6, R10, R1, R0 @ calculate the final duty cycle with the offset, and intensity * rotating duty cycle amount
  908. STMFD SP!, {R2, R3, R9, R12}
  909. C_synth_pulse_loop:
  910. LDMIA R5, {R0-R3, R9, R10, R12, LR} @ load 8 samples
  911. CMP R7, R6 @ Block #1
  912. ADDLO R0, R0, R11, LSL#6
  913. SUBHS R0, R0, R11, LSL#6
  914. ADDS R7, R7, R4, LSL#3
  915. CMP R7, R6 @ Block #2
  916. ADDLO R1, R1, R11, LSL#6
  917. SUBHS R1, R1, R11, LSL#6
  918. ADDS R7, R7, R4, LSL#3
  919. CMP R7, R6 @ Block #3
  920. ADDLO R2, R2, R11, LSL#6
  921. SUBHS R2, R2, R11, LSL#6
  922. ADDS R7, R7, R4, LSL#3
  923. CMP R7, R6 @ Block #4
  924. ADDLO R3, R3, R11, LSL#6
  925. SUBHS R3, R3, R11, LSL#6
  926. ADDS R7, R7, R4, LSL#3
  927. CMP R7, R6 @ Block #5
  928. ADDLO R9, R9, R11, LSL#6
  929. SUBHS R9, R9, R11, LSL#6
  930. ADDS R7, R7, R4, LSL#3
  931. CMP R7, R6 @ Block #6
  932. ADDLO R10, R10, R11, LSL#6
  933. SUBHS R10, R10, R11, LSL#6
  934. ADDS R7, R7, R4, LSL#3
  935. CMP R7, R6 @ Block #7
  936. ADDLO R12, R12, R11, LSL#6
  937. SUBHS R12, R12, R11, LSL#6
  938. ADDS R7, R7, R4, LSL#3
  939. CMP R7, R6 @ Block #8
  940. ADDLO LR, LR, R11, LSL#6
  941. SUBHS LR, LR, R11, LSL#6
  942. ADDS R7, R7, R4, LSL#3
  943. STMIA R5!, {R0-R3, R9, R10, R12, LR} @ write 8 samples
  944. SUBS R8, R8, #8
  945. BGT C_synth_pulse_loop
  946. LDMFD SP!, {R2, R3, R9, R12}
  947. B C_end_mixing
  948. C_check_synth_saw:
  949. /*
  950. * This is actually not a true saw wave
  951. * but looks pretty similar
  952. * (has a jump in the middle of the wave)
  953. */
  954. SUBS R12, R12, #1
  955. BNE C_synth_triangle
  956. MOV R6, #0x300
  957. MOV R11, R11, LSR#1
  958. BIC R11, R11, #0xFF00
  959. MOV R12, #0x70
  960. C_synth_saw_loop:
  961. LDMIA R5, {R0, R1, R10, LR} @ load 4 samples from memory
  962. ADDS R7, R7, R4, LSL#3 @ Block #1 (some oscillator type code)
  963. RSB R9, R12, R7, LSR#24
  964. MOV R6, R7, LSL#1
  965. SUB R9, R9, R6, LSR#27
  966. ADDS R2, R9, R2, ASR#1
  967. MLANE R0, R11, R2, R0
  968. ADDS R7, R7, R4, LSL#3 @ Block #2
  969. RSB R9, R12, R7, LSR#24
  970. MOV R6, R7, LSL#1
  971. SUB R9, R9, R6, LSR#27
  972. ADDS R2, R9, R2, ASR#1
  973. MLANE R1, R11, R2, R1
  974. ADDS R7, R7, R4, LSL#3 @ Block #3
  975. RSB R9, R12, R7, LSR#24
  976. MOV R6, R7, LSL#1
  977. SUB R9, R9, R6, LSR#27
  978. ADDS R2, R9, R2, ASR#1
  979. MLANE R10, R11, R2, R10
  980. ADDS R7, R7, R4, LSL#3 @ Block #4
  981. RSB R9, R12, R7, LSR#24
  982. MOV R6, R7, LSL#1
  983. SUB R9, R9, R6, LSR#27
  984. ADDS R2, R9, R2, ASR#1
  985. MLANE LR, R11, R2, LR
  986. STMIA R5!, {R0, R1, R10, LR}
  987. SUBS R8, R8, #4
  988. BGT C_synth_saw_loop
  989. B C_end_mixing
  990. C_synth_triangle:
  991. MOV R6, #0x80
  992. MOV R12, #0x180
  993. C_synth_triangle_loop:
  994. LDMIA R5, {R0, R1, R10, LR} @ load samples from work buffer
  995. ADDS R7, R7, R4, LSL#3 @ Block #1
  996. RSBPL R9, R6, R7, ASR#23
  997. SUBMI R9, R12, R7, LSR#23
  998. MLA R0, R11, R9, R0
  999. ADDS R7, R7, R4, LSL#3 @ Block #2
  1000. RSBPL R9, R6, R7, ASR#23
  1001. SUBMI R9, R12, R7, LSR#23
  1002. MLA R1, R11, R9, R1
  1003. ADDS R7, R7, R4, LSL#3 @ Block #3
  1004. RSBPL R9, R6, R7, ASR#23
  1005. SUBMI R9, R12, R7, LSR#23
  1006. MLA R10, R11, R9, R10
  1007. ADDS R7, R7, R4, LSL#3 @ Block #4
  1008. RSBPL R9, R6, R7, ASR#23
  1009. SUBMI R9, R12, R7, LSR#23
  1010. MLA LR, R11, R9, LR
  1011. STMIA R5!, {R0, R1, R10, LR}
  1012. SUBS R8, R8, #4 @ subtract #4 from the remainging samples
  1013. BGT C_synth_triangle_loop
  1014. B C_end_mixing
  1015. .if ENABLE_DECOMPRESSION==1
  1016. C_setup_special_mixing:
  1017. LDR R6, [R4, #CHN_WAVE_OFFSET]
  1018. LDRB R0, [R4]
  1019. TST R0, #FLAG_CHN_COMP
  1020. BNE C_setup_special_mixing_freq @ skip the setup procedure if it's running in compressed mode already
  1021. ORR R0, #FLAG_CHN_COMP
  1022. STRB R0, [R4]
  1023. LDRB R0, [R4, #CHN_MODE]
  1024. TST R0, #MODE_REVERSE
  1025. BEQ C_check_compression @ reversed mode not enabled?
  1026. LDR R1, [R6, #WAVE_LENGTH] @ calculate seek position for reverse playback
  1027. ADD R1, R1, R6, LSL#1 @ sorry, I don't actually understand that piece of code myself
  1028. ADD R1, R1, #0x20
  1029. SUB R3, R1, R3
  1030. STR R3, [R4, #CHN_POSITION_ABS]
  1031. C_check_compression:
  1032. LDRH R0, [R6]
  1033. CMP R0, #0
  1034. BEQ C_setup_special_mixing_freq
  1035. SUB R3, R3, R6
  1036. SUB R3, R3, #0x10
  1037. STR R3, [R4, #CHN_POSITION_ABS]
  1038. C_setup_special_mixing_freq:
  1039. LDR R0, [R6, #WAVE_LOOP_START]
  1040. STR R0, [SP, #ARG_LOOP_START_POS]
  1041. STMFD SP!, {R4, R9, R12}
  1042. MOVS R11, R11, LSR#1
  1043. ADC R11, R11, #0x8000
  1044. BIC R11, R11, #0xFF00
  1045. LDR R7, [R4, #CHN_FINE_POSITION]
  1046. LDR R1, [R4, #CHN_FREQUENCY]
  1047. LDRB R0, [R4, #CHN_MODE]
  1048. TST R0, #MODE_FIXED_FREQ
  1049. MOVNE R1, #0x800000
  1050. MULEQ R1, R12, R1 @ default rate factor * frequency = sample steps
  1051. ADD R5, R5, R8, LSL#2 @ set the buffer pointer to the end of the channel, same as slow mixing mode
  1052. LDRH R0, [R6]
  1053. CMP R0, #0
  1054. BEQ C_uncompressed_reverse_mixing_check
  1055. MOV R0, #0xFF000000 @ --> invalid channel mod
  1056. STR R0, [R4, #CHN_BLOCK_COUNT]
  1057. LDRB R0, [R4, #CHN_MODE]
  1058. TST R0, #MODE_REVERSE
  1059. BNE C_setup_compressed_reverse_mixing @ check again of reverse mixing is enabled
  1060. /* forward compressed mixing */
  1061. BL F_bdpcm_decoder
  1062. MOV R6, R12
  1063. ADD R3, R3, #1
  1064. BL F_bdpcm_decoder
  1065. SUB R12, R12, R6
  1066. @***** MIXING LOOP REGISTER USAGE ***********@
  1067. @ R0: Sample to modify from buffer
  1068. @ R1: sample steps (MOVED FROM R4)
  1069. @ R2: remaining samples before loop/end
  1070. @ R3: sample position
  1071. @ R4: channel pointer
  1072. @ R5: pointer to the end of buffer
  1073. @ R6: Base sample
  1074. @ R7: fine position
  1075. @ R8: remaining samples for current buffer
  1076. @ R9: interpolated sample
  1077. @ R10: not used
  1078. @ R11: volume
  1079. @ R12: Delta Sample
  1080. @ LR: not used
  1081. @********************************************@
  1082. C_compressed_mixing_loop:
  1083. MUL R9, R7, R12 @ check slow mixing for details, same procedure here
  1084. MOV R9, R9, ASR#22
  1085. ADDS R9, R9, R6, LSL#1
  1086. LDRNE R0, [R5, -R8, LSL#2]
  1087. MLANE R0, R11, R9, R0
  1088. STRNE R0, [R5, -R8, LSL#2]
  1089. ADD R7, R7, R1 @ ### changed from R4 to R1
  1090. MOVS R9, R7, LSR#23
  1091. BEQ C_compressed_mixing_skip_load
  1092. SUBS R2, R2, R7, LSR#23
  1093. BLLE C_mixing_loop_or_end
  1094. SUBS R9, R9, #1
  1095. ADDEQ R6, R12, R6
  1096. BEQ C_compressed_mixing_skip_base_load
  1097. ADD R3, R3, R9 @ equivalent to LDRNESB R6, [R3, R9]!
  1098. BL F_bdpcm_decoder
  1099. MOV R6, R12
  1100. C_compressed_mixing_skip_base_load:
  1101. ADD R3, R3, #1 @ equivalent to LDRSB R12, [R3, #1]!
  1102. BL F_bdpcm_decoder
  1103. SUB R12, R12, R6
  1104. BIC R7, R7, #0x3F800000
  1105. C_compressed_mixing_skip_load:
  1106. SUBS R8, R8, #1
  1107. BGT C_compressed_mixing_loop
  1108. B C_end_mixing
  1109. C_setup_compressed_reverse_mixing:
  1110. SUB R3, R3, #1
  1111. BL F_bdpcm_decoder
  1112. MOV R6, R12
  1113. SUB R3, R3, #1
  1114. BL F_bdpcm_decoder
  1115. SUB R12, R12, R6
  1116. C_compressed_reverse_mixing_loop:
  1117. MUL R9, R7, R12
  1118. MOV R9, R9, ASR#22
  1119. ADDS R9, R9, R6, LSL#1
  1120. LDRNE R0, [R5, -R8, LSL#2]
  1121. MLANE R0, R11, R9, R0
  1122. STRNE R0, [R5, -R8, LSL#2]
  1123. ADD R7, R7, R1 @ ### changed from R4 to R1
  1124. MOVS R9, R7, LSR#23
  1125. BEQ C_compressed_reverse_mixing_skip_load
  1126. SUBS R2, R2, R7, LSR#23
  1127. BLLE C_mixing_loop_or_end
  1128. SUBS R9, R9, #1
  1129. ADDEQ R6, R12, R6
  1130. BEQ C_compressed_reverse_mixing_skip_base_load
  1131. SUB R3, R3, R9
  1132. BL F_bdpcm_decoder
  1133. MOV R6, R12
  1134. C_compressed_reverse_mixing_skip_base_load:
  1135. SUB R3, R3, #1
  1136. BL F_bdpcm_decoder
  1137. SUB R12, R12, R6
  1138. BIC R7, R7, #0x3F800000
  1139. C_compressed_reverse_mixing_skip_load:
  1140. SUBS R8, R8, #1
  1141. BGT C_compressed_reverse_mixing_loop
  1142. ADD R3, R3, #3
  1143. B C_end_mixing
  1144. C_uncompressed_reverse_mixing_check:
  1145. LDRB R0, [R4, #1]
  1146. TST R0, #MODE_REVERSE @ check if reverse mode is even enabled (consistency)
  1147. BEQ C_end_mixing
  1148. LDRSB R6, [R3, #-1]!
  1149. LDRSB R12, [R3, #-1]
  1150. SUB R12, R12, R6
  1151. C_uncompressed_reverse_mixing_loop:
  1152. MUL R9, R7, R12
  1153. MOV R9, R9, ASR#22
  1154. ADDS R9, R9, R6, LSL#1
  1155. LDRNE R0, [R5, -R8, LSL#2]
  1156. MLANE R0, R11, R9, R0
  1157. STRNE R0, [R5, -R8, LSL#2]
  1158. ADD R7, R7, R1 @ ### changed from R4 to R1
  1159. MOVS R9, R7, LSR#23
  1160. BEQ C_uncompressed_reverse_mixing_load_skip
  1161. SUBS R2, R2, R7, LSR#23
  1162. BLLE C_mixing_loop_or_end
  1163. MOVS R9, R9
  1164. ADDEQ R6, R12, R6
  1165. LDRNESB R6, [R3, -R9]!
  1166. LDRSB R12, [R3, #-1]
  1167. SUB R12, R12, R6
  1168. BIC R7, R7, #0x3F800000
  1169. C_uncompressed_reverse_mixing_load_skip:
  1170. SUBS R8, R8, #1
  1171. BGT C_uncompressed_reverse_mixing_loop
  1172. ADD R3, R3, #2
  1173. B C_end_mixing
  1174. /*
  1175. * This is the main BDPCM Decoder
  1176. * It decodes and caches a block of PCM data
  1177. * and returns them in R12
  1178. */
  1179. F_bdpcm_decoder:
  1180. STMFD SP!, {R0, R2, R5-R7, LR}
  1181. MOV R0, R3, LSR#6 @ clip off everything but the block offset, each block is 0x40 samples long
  1182. LDR R12, [R4, #CHN_BLOCK_COUNT]
  1183. CMP R0, R12
  1184. BEQ C_bdpcm_decoder_return @ block already decoded -> skip
  1185. STR R0, [R4, #CHN_BLOCK_COUNT]
  1186. MOV R12, #0x21 @ 1 Block = 0x21 Bytes, 0x40 decoded samples
  1187. MUL R2, R12, R0
  1188. LDR R12, [R4, #CHN_WAVE_OFFSET]
  1189. ADD R2, R2, R12 @ calc block ROM position
  1190. ADD R2, R2, #0x10
  1191. LDR R5, decoder_buffer
  1192. ADR R6, delta_lookup_table
  1193. MOV R7, #0x40 @ 1 block = 0x40 samples
  1194. LDRB LR, [R2], #1
  1195. STRB LR, [R5], #1
  1196. LDRB R12, [R2], #1
  1197. B C_bdpcm_decoder_lsb
  1198. C_bdpcm_decoder_msb:
  1199. LDRB R12, [R2], #1
  1200. MOV R0, R12, LSR#4
  1201. LDRSB R0, [R6, R0]
  1202. ADD LR, LR, R0
  1203. STRB LR, [R5], #1
  1204. C_bdpcm_decoder_lsb:
  1205. AND R0, R12, #0xF
  1206. LDRSB R0, [R6, R0]
  1207. ADD LR, LR, R0
  1208. STRB LR, [R5], #1
  1209. SUBS R7, R7, #2
  1210. BGT C_bdpcm_decoder_msb
  1211. C_bdpcm_decoder_return:
  1212. LDR R5, decoder_buffer
  1213. AND R0, R3, #0x3F
  1214. LDRSB R12, [R5, R0]
  1215. LDMFD SP!, {R0, R2, R5-R7, PC}
  1216. .align 2
  1217. decoder_buffer:
  1218. .word decoder_buffer_target
  1219. delta_lookup_table:
  1220. .byte 0x0, 0x1, 0x4, 0x9, 0x10, 0x19, 0x24, 0x31, 0xC0, 0xCF, 0xDC, 0xE7, 0xF0, 0xF7, 0xFC, 0xFF
  1221. .endif /* ENABLE_DECOMPRESSION*/
  1222. main_mixer_end:
  1223. .end