engine_1.asm 32 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730
  1. ; The first of three duplicated sound engines.
  2. Audio1_UpdateMusic::
  3. ld c, Ch0
  4. .loop
  5. ld b, 0
  6. ld hl, wChannelSoundIDs
  7. add hl, bc
  8. ld a, [hl]
  9. and a
  10. jr z, .nextChannel
  11. ld a, c
  12. cp Ch4
  13. jr nc, .applyAffects ; if sfx channel
  14. ld a, [wMuteAudioAndPauseMusic]
  15. and a
  16. jr z, .applyAffects
  17. bit 7, a
  18. jr nz, .nextChannel
  19. set 7, a
  20. ld [wMuteAudioAndPauseMusic], a
  21. xor a ; disable all channels' output
  22. ld [rNR51], a
  23. ld [rNR30], a
  24. ld a, $80
  25. ld [rNR30], a
  26. jr .nextChannel
  27. .applyAffects
  28. call Audio1_ApplyMusicAffects
  29. .nextChannel
  30. ld a, c
  31. inc c ; inc channel number
  32. cp Ch7
  33. jr nz, .loop
  34. ret
  35. ; this routine checks flags for music effects currently applied
  36. ; to the channel and calls certain functions based on flags.
  37. Audio1_ApplyMusicAffects:
  38. ld b, $0
  39. ld hl, wChannelNoteDelayCounters ; delay until next note
  40. add hl, bc
  41. ld a, [hl]
  42. cp $1 ; if the delay is 1, play next note
  43. jp z, Audio1_PlayNextNote
  44. dec a ; otherwise, decrease the delay timer
  45. ld [hl], a
  46. ld a, c
  47. cp Ch4
  48. jr nc, .startChecks ; if a sfx channel
  49. ld hl, wChannelSoundIDs + Ch4
  50. add hl, bc
  51. ld a, [hl]
  52. and a
  53. jr z, .startChecks
  54. ret
  55. .startChecks
  56. ld hl, wChannelFlags1
  57. add hl, bc
  58. bit BIT_ROTATE_DUTY, [hl]
  59. jr z, .checkForExecuteMusic
  60. call Audio1_ApplyDutyCycle
  61. .checkForExecuteMusic
  62. ld b, 0
  63. ld hl, wChannelFlags2
  64. add hl, bc
  65. bit BIT_EXECUTE_MUSIC, [hl]
  66. jr nz, .checkForPitchBend
  67. ld hl, wChannelFlags1
  68. add hl, bc
  69. bit BIT_NOISE_OR_SFX, [hl]
  70. jr nz, .skipPitchBendVibrato
  71. .checkForPitchBend
  72. ld hl, wChannelFlags1
  73. add hl, bc
  74. bit BIT_PITCH_BEND_ON, [hl]
  75. jr z, .checkVibratoDelay
  76. jp Audio1_ApplyPitchBend
  77. .checkVibratoDelay
  78. ld hl, wChannelVibratoDelayCounters
  79. add hl, bc
  80. ld a, [hl]
  81. and a ; check if delay is over
  82. jr z, .checkForVibrato
  83. dec [hl] ; otherwise, dec delay
  84. .skipPitchBendVibrato
  85. ret
  86. .checkForVibrato
  87. ld hl, wChannelVibratoExtents
  88. add hl, bc
  89. ld a, [hl]
  90. and a
  91. jr nz, .vibrato
  92. ret ; no vibrato
  93. .vibrato
  94. ld d, a
  95. ld hl, wChannelVibratoRates
  96. add hl, bc
  97. ld a, [hl]
  98. and $f
  99. and a
  100. jr z, .applyVibrato
  101. dec [hl] ; decrement counter
  102. ret
  103. .applyVibrato
  104. ld a, [hl]
  105. swap [hl]
  106. or [hl]
  107. ld [hl], a ; reload the counter
  108. ld hl, wChannelFrequencyLowBytes
  109. add hl, bc
  110. ld e, [hl] ; get note pitch
  111. ld hl, wChannelFlags1
  112. add hl, bc
  113. ; This is the only code that sets/resets the vibrato direction bit, so it
  114. ; continuously alternates which path it takes.
  115. bit BIT_VIBRATO_DIRECTION, [hl]
  116. jr z, .unset
  117. res BIT_VIBRATO_DIRECTION, [hl]
  118. ld a, d
  119. and $f
  120. ld d, a
  121. ld a, e
  122. sub d
  123. jr nc, .noCarry
  124. ld a, 0
  125. .noCarry
  126. jr .done
  127. .unset
  128. set BIT_VIBRATO_DIRECTION, [hl]
  129. ld a, d
  130. and $f0
  131. swap a
  132. add e
  133. jr nc, .done
  134. ld a, $ff
  135. .done
  136. ld d, a
  137. ld b, REG_FREQUENCY_LO
  138. call Audio1_GetRegisterPointer
  139. ld [hl], d
  140. ret
  141. ; this routine executes all music commands that take up no time,
  142. ; like tempo changes, duty changes etc. and doesn't return
  143. ; until the first note is reached
  144. Audio1_PlayNextNote:
  145. ; reload the vibrato delay counter
  146. ld hl, wChannelVibratoDelayCounterReloadValues
  147. add hl, bc
  148. ld a, [hl]
  149. ld hl, wChannelVibratoDelayCounters
  150. add hl, bc
  151. ld [hl], a
  152. ld hl, wChannelFlags1
  153. add hl, bc
  154. res BIT_PITCH_BEND_ON, [hl]
  155. res BIT_PITCH_BEND_DECREASING, [hl]
  156. call Audio1_endchannel
  157. ret
  158. Audio1_endchannel:
  159. call Audio1_GetNextMusicByte
  160. ld d, a
  161. cp $ff ; is this command an endchannel?
  162. jp nz, Audio1_callchannel ; no
  163. ld b, 0
  164. ld hl, wChannelFlags1
  165. add hl, bc
  166. bit BIT_CHANNEL_CALL, [hl]
  167. jr nz, .returnFromCall
  168. ld a, c
  169. cp Ch3
  170. jr nc, .noiseOrSfxChannel
  171. jr .disableChannelOutput
  172. .noiseOrSfxChannel
  173. res BIT_NOISE_OR_SFX, [hl]
  174. ld hl, wChannelFlags2
  175. add hl, bc
  176. res BIT_EXECUTE_MUSIC, [hl]
  177. cp Ch6
  178. jr nz, .skipSfxChannel3
  179. ; restart hardware channel 3 (wave channel) output
  180. ld a, $0
  181. ld [rNR30], a
  182. ld a, $80
  183. ld [rNR30], a
  184. .skipSfxChannel3
  185. jr nz, .asm_9222
  186. ld a, [wDisableChannelOutputWhenSfxEnds]
  187. and a
  188. jr z, .asm_9222
  189. xor a
  190. ld [wDisableChannelOutputWhenSfxEnds], a
  191. jr .disableChannelOutput
  192. .asm_9222
  193. jr .asm_9248
  194. .returnFromCall
  195. res 1, [hl]
  196. ld d, $0
  197. ld a, c
  198. add a
  199. ld e, a
  200. ld hl, wChannelCommandPointers
  201. add hl, de
  202. push hl ; store current channel address
  203. ld hl, wChannelReturnAddresses
  204. add hl, de
  205. ld e, l
  206. ld d, h
  207. pop hl
  208. ld a, [de]
  209. ld [hli], a
  210. inc de
  211. ld a, [de]
  212. ld [hl], a ; loads channel address to return to
  213. jp Audio1_endchannel
  214. .disableChannelOutput
  215. ld hl, Audio1_HWChannelDisableMasks
  216. add hl, bc
  217. ld a, [rNR51]
  218. and [hl]
  219. ld [rNR51], a
  220. .asm_9248
  221. ld a, [wChannelSoundIDs + Ch4]
  222. cp CRY_SFX_START
  223. jr nc, .asm_9251
  224. jr .skipCry
  225. .asm_9251
  226. ld a, [wChannelSoundIDs + Ch4]
  227. cp CRY_SFX_END
  228. jr z, .skipCry
  229. jr c, .cry
  230. jr .skipCry
  231. .cry
  232. ld a, c
  233. cp Ch4
  234. jr z, .asm_9265
  235. call Audio1_GoBackOneCommandIfCry
  236. ret c
  237. .asm_9265
  238. ld a, [wSavedVolume]
  239. ld [rNR50], a
  240. xor a
  241. ld [wSavedVolume], a
  242. .skipCry
  243. ld hl, wChannelSoundIDs
  244. add hl, bc
  245. ld [hl], b
  246. ret
  247. Audio1_callchannel:
  248. cp $fd ; is this command a callchannel?
  249. jp nz, Audio1_loopchannel ; no
  250. call Audio1_GetNextMusicByte
  251. push af
  252. call Audio1_GetNextMusicByte
  253. ld d, a
  254. pop af
  255. ld e, a
  256. push de ; store pointer
  257. ld d, $0
  258. ld a, c
  259. add a
  260. ld e, a
  261. ld hl, wChannelCommandPointers
  262. add hl, de
  263. push hl
  264. ld hl, wChannelReturnAddresses
  265. add hl, de
  266. ld e, l
  267. ld d, h
  268. pop hl
  269. ld a, [hli]
  270. ld [de], a
  271. inc de
  272. ld a, [hld]
  273. ld [de], a ; copy current channel address
  274. pop de
  275. ld [hl], e
  276. inc hl
  277. ld [hl], d ; overwrite current address with pointer
  278. ld b, $0
  279. ld hl, wChannelFlags1
  280. add hl, bc
  281. set BIT_CHANNEL_CALL, [hl] ; set the call flag
  282. jp Audio1_endchannel
  283. Audio1_loopchannel:
  284. cp $fe ; is this command a loopchannel?
  285. jp nz, Audio1_notetype ; no
  286. call Audio1_GetNextMusicByte
  287. ld e, a
  288. and a
  289. jr z, .infiniteLoop
  290. ld b, 0
  291. ld hl, wChannelLoopCounters
  292. add hl, bc
  293. ld a, [hl]
  294. cp e
  295. jr nz, .loopAgain
  296. ld a, $1 ; if no more loops to make,
  297. ld [hl], a
  298. call Audio1_GetNextMusicByte ; skip pointer
  299. call Audio1_GetNextMusicByte
  300. jp Audio1_endchannel
  301. .loopAgain ; inc loop count
  302. inc a
  303. ld [hl], a
  304. ; fall through
  305. .infiniteLoop ; overwrite current address with pointer
  306. call Audio1_GetNextMusicByte
  307. push af
  308. call Audio1_GetNextMusicByte
  309. ld b, a
  310. ld d, $0
  311. ld a, c
  312. add a
  313. ld e, a
  314. ld hl, wChannelCommandPointers
  315. add hl, de
  316. pop af
  317. ld [hli], a
  318. ld [hl], b
  319. jp Audio1_endchannel
  320. Audio1_notetype:
  321. and $f0
  322. cp $d0 ; is this command a notetype?
  323. jp nz, Audio1_toggleperfectpitch ; no
  324. ld a, d
  325. and $f
  326. ld b, $0
  327. ld hl, wChannelNoteSpeeds
  328. add hl, bc
  329. ld [hl], a ; store low nibble as speed
  330. ld a, c
  331. cp Ch3
  332. jr z, .noiseChannel ; noise channel has 0 params
  333. call Audio1_GetNextMusicByte
  334. ld d, a
  335. ld a, c
  336. cp Ch2
  337. jr z, .musicChannel3
  338. cp Ch6
  339. jr nz, .skipChannel3
  340. ld hl, wSfxWaveInstrument
  341. jr .channel3
  342. .musicChannel3
  343. ld hl, wMusicWaveInstrument
  344. .channel3
  345. ld a, d
  346. and $f
  347. ld [hl], a ; store low nibble of param as wave instrument
  348. ld a, d
  349. and $30
  350. sla a
  351. ld d, a
  352. ; fall through
  353. ; if channel 3, store high nibble as volume
  354. ; else, store volume (high nibble) and fade (low nibble)
  355. .skipChannel3
  356. ld b, 0
  357. ld hl, wChannelVolumes
  358. add hl, bc
  359. ld [hl], d
  360. .noiseChannel
  361. jp Audio1_endchannel
  362. Audio1_toggleperfectpitch:
  363. ld a, d
  364. cp $e8 ; is this command a toggleperfectpitch?
  365. jr nz, Audio1_vibrato ; no
  366. ld b, 0
  367. ld hl, wChannelFlags1
  368. add hl, bc
  369. ld a, [hl]
  370. xor $1
  371. ld [hl], a ; flip bit 0 of wChannelFlags1
  372. jp Audio1_endchannel
  373. Audio1_vibrato:
  374. cp $ea ; is this command a vibrato?
  375. jr nz, Audio1_pitchbend ; no
  376. call Audio1_GetNextMusicByte
  377. ld b, 0
  378. ld hl, wChannelVibratoDelayCounters
  379. add hl, bc
  380. ld [hl], a ; store delay
  381. ld hl, wChannelVibratoDelayCounterReloadValues
  382. add hl, bc
  383. ld [hl], a ; store delay
  384. call Audio1_GetNextMusicByte
  385. ld d, a
  386. ; The high nybble of the command byte is the extent of the vibrato.
  387. ; Let n be the extent.
  388. ; The upper nybble of the channel's byte in the wChannelVibratoExtents
  389. ; array will store the extent above the note: (n / 2) + (n % 2).
  390. ; The lower nybble will store the extent below the note: (n / 2).
  391. ; These two values add to the total extent, n.
  392. and $f0
  393. swap a
  394. ld b, 0
  395. ld hl, wChannelVibratoExtents
  396. add hl, bc
  397. srl a
  398. ld e, a
  399. adc b
  400. swap a
  401. or e
  402. ld [hl], a
  403. ; The low nybble of the command byte is the rate of the vibrato.
  404. ; The high and low nybbles of the channel's byte in the wChannelVibratoRates
  405. ; array are both initialised to this value because the high nybble is the
  406. ; counter reload value and the low nybble is the counter itself, which should
  407. ; start at its value upon reload.
  408. ld a, d
  409. and $f
  410. ld d, a
  411. ld hl, wChannelVibratoRates
  412. add hl, bc
  413. swap a
  414. or d
  415. ld [hl], a
  416. jp Audio1_endchannel
  417. Audio1_pitchbend:
  418. cp $eb ; is this command a pitchbend?
  419. jr nz, Audio1_duty ; no
  420. call Audio1_GetNextMusicByte
  421. ld b, 0
  422. ld hl, wChannelPitchBendLengthModifiers
  423. add hl, bc
  424. ld [hl], a
  425. call Audio1_GetNextMusicByte
  426. ld d, a
  427. and $f0
  428. swap a
  429. ld b, a
  430. ld a, d
  431. and $f
  432. call Audio1_CalculateFrequency
  433. ld b, 0
  434. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  435. add hl, bc
  436. ld [hl], d
  437. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  438. add hl, bc
  439. ld [hl], e
  440. ld b, 0
  441. ld hl, wChannelFlags1
  442. add hl, bc
  443. set BIT_PITCH_BEND_ON, [hl]
  444. call Audio1_GetNextMusicByte
  445. ld d, a
  446. jp Audio1_notelength
  447. Audio1_duty:
  448. cp $ec ; is this command a duty?
  449. jr nz, Audio1_tempo ; no
  450. call Audio1_GetNextMusicByte
  451. rrca
  452. rrca
  453. and $c0
  454. ld b, 0
  455. ld hl, wChannelDuties
  456. add hl, bc
  457. ld [hl], a ; store duty
  458. jp Audio1_endchannel
  459. Audio1_tempo:
  460. cp $ed ; is this command a tempo?
  461. jr nz, Audio1_stereopanning ; no
  462. ld a, c
  463. cp Ch4
  464. jr nc, .sfxChannel
  465. call Audio1_GetNextMusicByte
  466. ld [wMusicTempo], a ; store first param
  467. call Audio1_GetNextMusicByte
  468. ld [wMusicTempo + 1], a ; store second param
  469. xor a
  470. ld [wChannelNoteDelayCountersFractionalPart], a ; clear RAM
  471. ld [wChannelNoteDelayCountersFractionalPart + 1], a
  472. ld [wChannelNoteDelayCountersFractionalPart + 2], a
  473. ld [wChannelNoteDelayCountersFractionalPart + 3], a
  474. jr .musicChannelDone
  475. .sfxChannel
  476. call Audio1_GetNextMusicByte
  477. ld [wSfxTempo], a ; store first param
  478. call Audio1_GetNextMusicByte
  479. ld [wSfxTempo + 1], a ; store second param
  480. xor a
  481. ld [wChannelNoteDelayCountersFractionalPart + 4], a ; clear RAM
  482. ld [wChannelNoteDelayCountersFractionalPart + 5], a
  483. ld [wChannelNoteDelayCountersFractionalPart + 6], a
  484. ld [wChannelNoteDelayCountersFractionalPart + 7], a
  485. .musicChannelDone
  486. jp Audio1_endchannel
  487. Audio1_stereopanning:
  488. cp $ee ; is this command a stereopanning?
  489. jr nz, Audio1_unknownmusic0xef ; no
  490. call Audio1_GetNextMusicByte
  491. ld [wStereoPanning], a ; store panning
  492. jp Audio1_endchannel
  493. ; this appears to never be used
  494. Audio1_unknownmusic0xef:
  495. cp $ef ; is this command an unknownmusic0xef?
  496. jr nz, Audio1_dutycycle ; no
  497. call Audio1_GetNextMusicByte
  498. push bc
  499. call Audio1_PlaySound
  500. pop bc
  501. ld a, [wDisableChannelOutputWhenSfxEnds]
  502. and a
  503. jr nz, .skip
  504. ld a, [wChannelSoundIDs + Ch7]
  505. ld [wDisableChannelOutputWhenSfxEnds], a
  506. xor a
  507. ld [wChannelSoundIDs + Ch7], a
  508. .skip
  509. jp Audio1_endchannel
  510. Audio1_dutycycle:
  511. cp $fc ; is this command a dutycycle?
  512. jr nz, Audio1_volume ; no
  513. call Audio1_GetNextMusicByte
  514. ld b, 0
  515. ld hl, wChannelDutyCycles
  516. add hl, bc
  517. ld [hl], a ; store full cycle
  518. and $c0
  519. ld hl, wChannelDuties
  520. add hl, bc
  521. ld [hl], a ; store first duty
  522. ld hl, wChannelFlags1
  523. add hl, bc
  524. set BIT_ROTATE_DUTY, [hl]
  525. jp Audio1_endchannel
  526. Audio1_volume:
  527. cp $f0 ; is this command a volume?
  528. jr nz, Audio1_executemusic ; no
  529. call Audio1_GetNextMusicByte
  530. ld [rNR50], a ; store volume
  531. jp Audio1_endchannel
  532. Audio1_executemusic:
  533. cp $f8 ; is this command an executemusic?
  534. jr nz, Audio1_octave ; no
  535. ld b, $0
  536. ld hl, wChannelFlags2
  537. add hl, bc
  538. set BIT_EXECUTE_MUSIC, [hl]
  539. jp Audio1_endchannel
  540. Audio1_octave:
  541. and $f0
  542. cp $e0 ; is this command an octave?
  543. jr nz, Audio1_sfxnote ; no
  544. ld hl, wChannelOctaves
  545. ld b, 0
  546. add hl, bc
  547. ld a, d
  548. and $f
  549. ld [hl], a ; store low nibble as octave
  550. jp Audio1_endchannel
  551. ; sfxnote is either squarenote or noisenote depending on the channel
  552. Audio1_sfxnote:
  553. cp $20 ; is this command a sfxnote?
  554. jr nz, Audio1_pitchenvelope
  555. ld a, c
  556. cp Ch3 ; is this a noise or sfx channel?
  557. jr c, Audio1_pitchenvelope ; no
  558. ld b, 0
  559. ld hl, wChannelFlags2
  560. add hl, bc
  561. bit BIT_EXECUTE_MUSIC, [hl] ; is executemusic being used?
  562. jr nz, Audio1_pitchenvelope ; yes
  563. call Audio1_notelength
  564. ; This code seems to do the same thing as what Audio1_ApplyDutyAndSoundLength
  565. ; does below.
  566. ld d, a
  567. ld b, 0
  568. ld hl, wChannelDuties
  569. add hl, bc
  570. ld a, [hl]
  571. or d
  572. ld d, a
  573. ld b, REG_DUTY_SOUND_LEN
  574. call Audio1_GetRegisterPointer
  575. ld [hl], d
  576. call Audio1_GetNextMusicByte
  577. ld d, a
  578. ld b, REG_VOLUME_ENVELOPE
  579. call Audio1_GetRegisterPointer
  580. ld [hl], d
  581. call Audio1_GetNextMusicByte
  582. ld e, a
  583. ld a, c
  584. cp Ch7
  585. ld a, 0
  586. jr z, .skip
  587. ; Channels 1 through 3 have 2 registers that control frequency, but the noise
  588. ; channel a single register (the polynomial counter) that controls frequency,
  589. ; so this command has one less byte on the noise channel.
  590. push de
  591. call Audio1_GetNextMusicByte
  592. pop de
  593. .skip
  594. ld d, a
  595. push de
  596. call Audio1_ApplyDutyAndSoundLength
  597. call Audio1_EnableChannelOutput
  598. pop de
  599. call Audio1_ApplyWavePatternAndFrequency
  600. ret
  601. Audio1_pitchenvelope:
  602. ld a, c
  603. cp Ch4
  604. jr c, Audio1_note ; if not a sfx
  605. ld a, d
  606. cp $10 ; is this command a pitchenvelope?
  607. jr nz, Audio1_note ; no
  608. ld b, $0
  609. ld hl, wChannelFlags2
  610. add hl, bc
  611. bit BIT_EXECUTE_MUSIC, [hl]
  612. jr nz, Audio1_note ; no
  613. call Audio1_GetNextMusicByte
  614. ld [rNR10], a
  615. jp Audio1_endchannel
  616. Audio1_note:
  617. ld a, c
  618. cp Ch3
  619. jr nz, Audio1_notelength ; if not noise channel
  620. ld a, d
  621. and $f0
  622. cp $b0 ; is this command a dnote?
  623. jr z, Audio1_dnote
  624. jr nc, Audio1_notelength ; no
  625. swap a
  626. ld b, a
  627. ld a, d
  628. and $f
  629. ld d, a
  630. ld a, b
  631. push de
  632. push bc
  633. jr asm_94fd
  634. Audio1_dnote:
  635. ld a, d
  636. and $f
  637. push af
  638. push bc
  639. call Audio1_GetNextMusicByte ; get dnote instrument
  640. asm_94fd
  641. ld d, a
  642. ld a, [wDisableChannelOutputWhenSfxEnds]
  643. and a
  644. jr nz, .asm_9508
  645. ld a, d
  646. call Audio1_PlaySound
  647. .asm_9508
  648. pop bc
  649. pop de
  650. Audio1_notelength:
  651. ld a, d
  652. push af
  653. and $f
  654. inc a
  655. ld b, 0
  656. ld e, a ; store note length (in 16ths)
  657. ld d, b
  658. ld hl, wChannelNoteSpeeds
  659. add hl, bc
  660. ld a, [hl]
  661. ld l, b
  662. call Audio1_MultiplyAdd
  663. ld a, c
  664. cp Ch4
  665. jr nc, .sfxChannel
  666. ld a, [wMusicTempo]
  667. ld d, a
  668. ld a, [wMusicTempo + 1]
  669. ld e, a
  670. jr .skip
  671. .sfxChannel
  672. ld d, $1
  673. ld e, $0
  674. cp Ch7
  675. jr z, .skip ; if noise channel
  676. call Audio1_SetSfxTempo
  677. ld a, [wSfxTempo]
  678. ld d, a
  679. ld a, [wSfxTempo + 1]
  680. ld e, a
  681. .skip
  682. ld a, l ; a = note_length * note_speed
  683. ld b, 0
  684. ld hl, wChannelNoteDelayCountersFractionalPart
  685. add hl, bc
  686. ld l, [hl]
  687. call Audio1_MultiplyAdd
  688. ld e, l
  689. ld d, h ; de = note_delay_frac_part + (note_length * note_speed * tempo)
  690. ld hl, wChannelNoteDelayCountersFractionalPart
  691. add hl, bc
  692. ld [hl], e
  693. ld a, d
  694. ld hl, wChannelNoteDelayCounters
  695. add hl, bc
  696. ld [hl], a
  697. ld hl, wChannelFlags2
  698. add hl, bc
  699. bit BIT_EXECUTE_MUSIC, [hl]
  700. jr nz, Audio1_notepitch
  701. ld hl, wChannelFlags1
  702. add hl, bc
  703. bit BIT_NOISE_OR_SFX, [hl]
  704. jr z, Audio1_notepitch
  705. pop hl
  706. ret
  707. Audio1_notepitch:
  708. pop af
  709. and $f0
  710. cp $c0 ; compare to rest
  711. jr nz, .notRest
  712. ld a, c
  713. cp Ch4
  714. jr nc, .next
  715. ; If this isn't an SFX channel, try the corresponding SFX channel.
  716. ld hl, wChannelSoundIDs + Ch4
  717. add hl, bc
  718. ld a, [hl]
  719. and a
  720. jr nz, .done
  721. ; fall through
  722. .next
  723. ld a, c
  724. cp Ch2
  725. jr z, .channel3
  726. cp Ch6
  727. jr nz, .notChannel3
  728. .channel3
  729. ld b, 0
  730. ld hl, Audio1_HWChannelDisableMasks
  731. add hl, bc
  732. ld a, [rNR51]
  733. and [hl]
  734. ld [rNR51], a ; disable hardware channel 3's output
  735. jr .done
  736. .notChannel3
  737. ld b, REG_VOLUME_ENVELOPE
  738. call Audio1_GetRegisterPointer
  739. ld a, $8 ; fade in sound
  740. ld [hli], a
  741. inc hl
  742. ld a, $80 ; restart sound
  743. ld [hl], a
  744. .done
  745. ret
  746. .notRest
  747. swap a
  748. ld b, 0
  749. ld hl, wChannelOctaves
  750. add hl, bc
  751. ld b, [hl]
  752. call Audio1_CalculateFrequency
  753. ld b, 0
  754. ld hl, wChannelFlags1
  755. add hl, bc
  756. bit BIT_PITCH_BEND_ON, [hl]
  757. jr z, .skipPitchBend
  758. call Audio1_InitPitchBendVars
  759. .skipPitchBend
  760. push de
  761. ld a, c
  762. cp Ch4
  763. jr nc, .sfxChannel ; if sfx channel
  764. ; If this isn't an SFX channel, try the corresponding SFX channel.
  765. ld hl, wChannelSoundIDs + Ch4
  766. ld d, 0
  767. ld e, a
  768. add hl, de
  769. ld a, [hl]
  770. and a
  771. jr nz, .noSfx
  772. jr .sfxChannel
  773. .noSfx
  774. pop de
  775. ret
  776. .sfxChannel
  777. ld b, 0
  778. ld hl, wChannelVolumes
  779. add hl, bc
  780. ld d, [hl]
  781. ld b, REG_VOLUME_ENVELOPE
  782. call Audio1_GetRegisterPointer
  783. ld [hl], d
  784. call Audio1_ApplyDutyAndSoundLength
  785. call Audio1_EnableChannelOutput
  786. pop de
  787. ld b, $0
  788. ld hl, wChannelFlags1
  789. add hl, bc
  790. bit BIT_PERFECT_PITCH, [hl] ; has toggleperfectpitch been used?
  791. jr z, .skipFrequencyInc
  792. inc e ; if yes, increment the frequency by 1
  793. jr nc, .skipFrequencyInc
  794. inc d
  795. .skipFrequencyInc
  796. ld hl, wChannelFrequencyLowBytes
  797. add hl, bc
  798. ld [hl], e
  799. call Audio1_ApplyWavePatternAndFrequency
  800. ret
  801. Audio1_EnableChannelOutput:
  802. ld b, 0
  803. ld hl, Audio1_HWChannelEnableMasks
  804. add hl, bc
  805. ld a, [rNR51]
  806. or [hl] ; set this channel's bits
  807. ld d, a
  808. ld a, c
  809. cp Ch7
  810. jr z, .noiseChannelOrNoSfx
  811. cp Ch4
  812. jr nc, .skip ; if sfx channel
  813. ; If this isn't an SFX channel, try the corresponding SFX channel.
  814. ld hl, wChannelSoundIDs + Ch4
  815. add hl, bc
  816. ld a, [hl]
  817. and a
  818. jr nz, .skip
  819. .noiseChannelOrNoSfx
  820. ; If this is the SFX noise channel or a music channel whose corresponding
  821. ; SFX channel is off, apply stereo panning.
  822. ld a, [wStereoPanning]
  823. ld hl, Audio1_HWChannelEnableMasks
  824. add hl, bc
  825. and [hl]
  826. ld d, a
  827. ld a, [rNR51]
  828. ld hl, Audio1_HWChannelDisableMasks
  829. add hl, bc
  830. and [hl] ; reset this channel's output bits
  831. or d ; set this channel's output bits that enabled in [wStereoPanning]
  832. ld d, a
  833. .skip
  834. ld a, d
  835. ld [rNR51], a
  836. ret
  837. Audio1_ApplyDutyAndSoundLength:
  838. ld b, 0
  839. ld hl, wChannelNoteDelayCounters ; use the note delay as sound length
  840. add hl, bc
  841. ld d, [hl]
  842. ld a, c
  843. cp Ch2
  844. jr z, .skipDuty ; if music channel 3
  845. cp Ch6
  846. jr z, .skipDuty ; if sfx channel 3
  847. ; include duty (except on channel 3 which doesn't have it)
  848. ld a, d
  849. and $3f
  850. ld d, a
  851. ld hl, wChannelDuties
  852. add hl, bc
  853. ld a, [hl]
  854. or d
  855. ld d, a
  856. .skipDuty
  857. ld b, REG_DUTY_SOUND_LEN
  858. call Audio1_GetRegisterPointer
  859. ld [hl], d
  860. ret
  861. Audio1_ApplyWavePatternAndFrequency:
  862. ld a, c
  863. cp Ch2
  864. jr z, .channel3
  865. cp Ch6
  866. jr nz, .notChannel3
  867. ; fall through
  868. .channel3
  869. push de
  870. ld de, wMusicWaveInstrument
  871. cp Ch2
  872. jr z, .next
  873. ld de, wSfxWaveInstrument
  874. .next
  875. ld a, [de]
  876. add a
  877. ld d, 0
  878. ld e, a
  879. ld hl, Audio1_WavePointers
  880. add hl, de
  881. ld e, [hl]
  882. inc hl
  883. ld d, [hl]
  884. ld hl, $ff30 ; wave pattern RAM
  885. ld b, $f
  886. ld a, $0 ; stop hardware channel 3
  887. ld [rNR30], a
  888. .loop
  889. ld a, [de]
  890. inc de
  891. ld [hli], a
  892. ld a, b
  893. dec b
  894. and a
  895. jr nz, .loop
  896. ld a, $80 ; start hardware channel 3
  897. ld [rNR30], a
  898. pop de
  899. .notChannel3
  900. ld a, d
  901. or $80 ; use counter mode (i.e. disable output when the counter reaches 0)
  902. and $c7 ; zero the unused bits in the register
  903. ld d, a
  904. ld b, REG_FREQUENCY_LO
  905. call Audio1_GetRegisterPointer
  906. ld [hl], e ; store frequency low byte
  907. inc hl
  908. ld [hl], d ; store frequency high byte
  909. call Audio1_ApplyFrequencyModifier
  910. ret
  911. Audio1_SetSfxTempo:
  912. call Audio1_IsCry
  913. jr nc, .notCry
  914. ld d, 0
  915. ld a, [wTempoModifier]
  916. add $80
  917. jr nc, .next
  918. inc d
  919. .next
  920. ld [wSfxTempo + 1], a
  921. ld a, d
  922. ld [wSfxTempo], a
  923. jr .done
  924. .notCry
  925. xor a
  926. ld [wSfxTempo + 1], a
  927. ld a, $1
  928. ld [wSfxTempo], a
  929. .done
  930. ret
  931. Audio1_ApplyFrequencyModifier:
  932. call Audio1_IsCry
  933. jr nc, .done
  934. ; if playing a cry, add the cry's frequency modifier
  935. ld a, [wFrequencyModifier]
  936. add e
  937. jr nc, .noCarry
  938. inc d
  939. .noCarry
  940. dec hl
  941. ld e, a
  942. ld [hl], e
  943. inc hl
  944. ld [hl], d
  945. .done
  946. ret
  947. Audio1_GoBackOneCommandIfCry:
  948. call Audio1_IsCry
  949. jr nc, .done
  950. ld hl, wChannelCommandPointers
  951. ld e, c
  952. ld d, 0
  953. sla e
  954. rl d
  955. add hl, de
  956. ld a, [hl]
  957. sub 1
  958. ld [hl], a
  959. inc hl
  960. ld a, [hl]
  961. sbc 0
  962. ld [hl], a
  963. scf
  964. ret
  965. .done
  966. scf
  967. ccf
  968. ret
  969. Audio1_IsCry:
  970. ; Returns whether the currently playing audio is a cry in carry.
  971. ld a, [wChannelSoundIDs + Ch4]
  972. cp CRY_SFX_START
  973. jr nc, .next
  974. jr .no
  975. .next
  976. cp CRY_SFX_END
  977. jr z, .no
  978. jr c, .yes
  979. .no
  980. scf
  981. ccf
  982. ret
  983. .yes
  984. scf
  985. ret
  986. Audio1_ApplyPitchBend:
  987. ld hl, wChannelFlags1
  988. add hl, bc
  989. bit BIT_PITCH_BEND_DECREASING, [hl]
  990. jp nz, .frequencyDecreasing
  991. ; frequency increasing
  992. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  993. add hl, bc
  994. ld e, [hl]
  995. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  996. add hl, bc
  997. ld d, [hl]
  998. ld hl, wChannelPitchBendFrequencySteps
  999. add hl, bc
  1000. ld l, [hl]
  1001. ld h, b
  1002. add hl, de
  1003. ld d, h
  1004. ld e, l
  1005. ld hl, wChannelPitchBendCurrentFrequencyFractionalPart
  1006. add hl, bc
  1007. push hl
  1008. ld hl, wChannelPitchBendFrequencyStepsFractionalPart
  1009. add hl, bc
  1010. ld a, [hl]
  1011. pop hl
  1012. add [hl]
  1013. ld [hl], a
  1014. ld a, 0
  1015. adc e
  1016. ld e, a
  1017. ld a, 0
  1018. adc d
  1019. ld d, a
  1020. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  1021. add hl, bc
  1022. ld a, [hl]
  1023. cp d
  1024. jp c, .reachedTargetFrequency
  1025. jr nz, .applyUpdatedFrequency
  1026. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  1027. add hl, bc
  1028. ld a, [hl]
  1029. cp e
  1030. jp c, .reachedTargetFrequency
  1031. jr .applyUpdatedFrequency
  1032. .frequencyDecreasing
  1033. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  1034. add hl, bc
  1035. ld a, [hl]
  1036. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  1037. add hl, bc
  1038. ld d, [hl]
  1039. ld hl, wChannelPitchBendFrequencySteps
  1040. add hl, bc
  1041. ld e, [hl]
  1042. sub e
  1043. ld e, a
  1044. ld a, d
  1045. sbc b
  1046. ld d, a
  1047. ld hl, wChannelPitchBendFrequencyStepsFractionalPart
  1048. add hl, bc
  1049. ld a, [hl]
  1050. add a
  1051. ld [hl], a
  1052. ld a, e
  1053. sbc b
  1054. ld e, a
  1055. ld a, d
  1056. sbc b
  1057. ld d, a
  1058. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  1059. add hl, bc
  1060. ld a, d
  1061. cp [hl]
  1062. jr c, .reachedTargetFrequency
  1063. jr nz, .applyUpdatedFrequency
  1064. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  1065. add hl, bc
  1066. ld a, e
  1067. cp [hl]
  1068. jr c, .reachedTargetFrequency
  1069. .applyUpdatedFrequency
  1070. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  1071. add hl, bc
  1072. ld [hl], e
  1073. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  1074. add hl, bc
  1075. ld [hl], d
  1076. ld b, REG_FREQUENCY_LO
  1077. call Audio1_GetRegisterPointer
  1078. ld a, e
  1079. ld [hli], a
  1080. ld [hl], d
  1081. ret
  1082. .reachedTargetFrequency
  1083. ; Turn off pitch bend when the target frequency has been reached.
  1084. ld hl, wChannelFlags1
  1085. add hl, bc
  1086. res BIT_PITCH_BEND_ON, [hl]
  1087. res BIT_PITCH_BEND_DECREASING, [hl]
  1088. ret
  1089. Audio1_InitPitchBendVars:
  1090. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  1091. add hl, bc
  1092. ld [hl], d
  1093. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  1094. add hl, bc
  1095. ld [hl], e
  1096. ld hl, wChannelNoteDelayCounters
  1097. add hl, bc
  1098. ld a, [hl]
  1099. ld hl, wChannelPitchBendLengthModifiers
  1100. add hl, bc
  1101. sub [hl]
  1102. jr nc, .next
  1103. ld a, 1
  1104. .next
  1105. ld [hl], a
  1106. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  1107. add hl, bc
  1108. ld a, e
  1109. sub [hl]
  1110. ld e, a
  1111. ld a, d
  1112. sbc b
  1113. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  1114. add hl, bc
  1115. sub [hl]
  1116. jr c, .targetFrequencyGreater
  1117. ld d, a
  1118. ld b, 0
  1119. ld hl, wChannelFlags1
  1120. add hl, bc
  1121. set BIT_PITCH_BEND_DECREASING, [hl]
  1122. jr .next2
  1123. .targetFrequencyGreater
  1124. ; If the target frequency is greater, subtract the current frequency from
  1125. ; the target frequency to get the absolute difference.
  1126. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  1127. add hl, bc
  1128. ld d, [hl]
  1129. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  1130. add hl, bc
  1131. ld e, [hl]
  1132. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  1133. add hl, bc
  1134. ld a, [hl]
  1135. sub e
  1136. ld e, a
  1137. ; Bug. Instead of borrowing from the high byte of the target frequency as it
  1138. ; should, it borrows from the high byte of the current frequency instead.
  1139. ; This means that the result will be 0x200 greater than it should be if the
  1140. ; low byte of the current frequency is greater than the low byte of the
  1141. ; target frequency.
  1142. ld a, d
  1143. sbc b
  1144. ld d, a
  1145. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  1146. add hl, bc
  1147. ld a, [hl]
  1148. sub d
  1149. ld d, a
  1150. ld b, 0
  1151. ld hl, wChannelFlags1
  1152. add hl, bc
  1153. res BIT_PITCH_BEND_DECREASING, [hl]
  1154. .next2
  1155. ld hl, wChannelPitchBendLengthModifiers
  1156. add hl, bc
  1157. .divideLoop
  1158. inc b
  1159. ld a, e
  1160. sub [hl]
  1161. ld e, a
  1162. jr nc, .divideLoop
  1163. ld a, d
  1164. and a
  1165. jr z, .doneDividing
  1166. dec a
  1167. ld d, a
  1168. jr .divideLoop
  1169. .doneDividing
  1170. ld a, e ; a = remainder - dividend
  1171. add [hl]
  1172. ld d, b ; d = quotient + 1
  1173. ld b, 0
  1174. ld hl, wChannelPitchBendFrequencySteps
  1175. add hl, bc
  1176. ld [hl], d ; store quotient + 1
  1177. ld hl, wChannelPitchBendFrequencyStepsFractionalPart
  1178. add hl, bc
  1179. ld [hl], a ; store remainder - dividend
  1180. ld hl, wChannelPitchBendCurrentFrequencyFractionalPart
  1181. add hl, bc
  1182. ld [hl], a ; store remainder - dividend
  1183. ret
  1184. Audio1_ApplyDutyCycle:
  1185. ld b, 0
  1186. ld hl, wChannelDutyCycles
  1187. add hl, bc
  1188. ld a, [hl]
  1189. rlca
  1190. rlca
  1191. ld [hl], a
  1192. and $c0
  1193. ld d, a
  1194. ld b, REG_DUTY_SOUND_LEN
  1195. call Audio1_GetRegisterPointer
  1196. ld a, [hl]
  1197. and $3f
  1198. or d
  1199. ld [hl], a
  1200. ret
  1201. Audio1_GetNextMusicByte:
  1202. ld d, 0
  1203. ld a, c
  1204. add a
  1205. ld e, a
  1206. ld hl, wChannelCommandPointers
  1207. add hl, de
  1208. ld a, [hli]
  1209. ld e, a
  1210. ld a, [hld]
  1211. ld d, a
  1212. ld a, [de] ; get next music command
  1213. inc de
  1214. ld [hl], e ; store address of next command
  1215. inc hl
  1216. ld [hl], d
  1217. ret
  1218. Audio1_GetRegisterPointer:
  1219. ; hl = address of hardware sound register b for software channel c
  1220. ld a, c
  1221. ld hl, Audio1_HWChannelBaseAddresses
  1222. add l
  1223. jr nc, .noCarry
  1224. inc h
  1225. .noCarry
  1226. ld l, a
  1227. ld a, [hl]
  1228. add b
  1229. ld l, a
  1230. ld h, $ff
  1231. ret
  1232. Audio1_MultiplyAdd:
  1233. ; hl = l + (a * de)
  1234. ld h, 0
  1235. .loop
  1236. srl a
  1237. jr nc, .skipAdd
  1238. add hl, de
  1239. .skipAdd
  1240. sla e
  1241. rl d
  1242. and a
  1243. jr z, .done
  1244. jr .loop
  1245. .done
  1246. ret
  1247. Audio1_CalculateFrequency:
  1248. ; return the frequency for note a, octave b in de
  1249. ld h, 0
  1250. ld l, a
  1251. add hl, hl
  1252. ld d, h
  1253. ld e, l
  1254. ld hl, Audio1_Pitches
  1255. add hl, de
  1256. ld e, [hl]
  1257. inc hl
  1258. ld d, [hl]
  1259. ld a, b
  1260. .loop
  1261. cp 7
  1262. jr z, .done
  1263. sra d
  1264. rr e
  1265. inc a
  1266. jr .loop
  1267. .done
  1268. ld a, 8
  1269. add d
  1270. ld d, a
  1271. ret
  1272. Audio1_PlaySound::
  1273. ld [wSoundID], a
  1274. cp $ff
  1275. jp z, .stopAllAudio
  1276. cp MAX_SFX_ID
  1277. jp z, .playSfx
  1278. jp c, .playSfx
  1279. cp $fe
  1280. jr z, .playMusic
  1281. jp nc, .playSfx
  1282. .playMusic
  1283. xor a
  1284. ld [wUnusedC000], a
  1285. ld [wDisableChannelOutputWhenSfxEnds], a
  1286. ld [wMusicTempo + 1], a
  1287. ld [wMusicWaveInstrument], a
  1288. ld [wSfxWaveInstrument], a
  1289. ld d, $8
  1290. ld hl, wChannelReturnAddresses
  1291. call .FillMem
  1292. ld hl, wChannelCommandPointers
  1293. call .FillMem
  1294. ld d, $4
  1295. ld hl, wChannelSoundIDs
  1296. call .FillMem
  1297. ld hl, wChannelFlags1
  1298. call .FillMem
  1299. ld hl, wChannelDuties
  1300. call .FillMem
  1301. ld hl, wChannelDutyCycles
  1302. call .FillMem
  1303. ld hl, wChannelVibratoDelayCounters
  1304. call .FillMem
  1305. ld hl, wChannelVibratoExtents
  1306. call .FillMem
  1307. ld hl, wChannelVibratoRates
  1308. call .FillMem
  1309. ld hl, wChannelFrequencyLowBytes
  1310. call .FillMem
  1311. ld hl, wChannelVibratoDelayCounterReloadValues
  1312. call .FillMem
  1313. ld hl, wChannelFlags2
  1314. call .FillMem
  1315. ld hl, wChannelPitchBendLengthModifiers
  1316. call .FillMem
  1317. ld hl, wChannelPitchBendFrequencySteps
  1318. call .FillMem
  1319. ld hl, wChannelPitchBendFrequencyStepsFractionalPart
  1320. call .FillMem
  1321. ld hl, wChannelPitchBendCurrentFrequencyFractionalPart
  1322. call .FillMem
  1323. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  1324. call .FillMem
  1325. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  1326. call .FillMem
  1327. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  1328. call .FillMem
  1329. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  1330. call .FillMem
  1331. ld a, $1
  1332. ld hl, wChannelLoopCounters
  1333. call .FillMem
  1334. ld hl, wChannelNoteDelayCounters
  1335. call .FillMem
  1336. ld hl, wChannelNoteSpeeds
  1337. call .FillMem
  1338. ld [wMusicTempo], a
  1339. ld a, $ff
  1340. ld [wStereoPanning], a
  1341. xor a
  1342. ld [rNR50], a
  1343. ld a, $8
  1344. ld [rNR10], a
  1345. ld a, 0
  1346. ld [rNR51], a
  1347. xor a
  1348. ld [rNR30], a
  1349. ld a, $80
  1350. ld [rNR30], a
  1351. ld a, $77
  1352. ld [rNR50], a
  1353. jp .playSoundCommon
  1354. .playSfx
  1355. ld l, a
  1356. ld e, a
  1357. ld h, 0
  1358. ld d, h
  1359. add hl, hl
  1360. add hl, de
  1361. ld de, SFX_Headers_1
  1362. add hl, de
  1363. ld a, h
  1364. ld [wSfxHeaderPointer], a
  1365. ld a, l
  1366. ld [wSfxHeaderPointer + 1], a
  1367. ld a, [hl]
  1368. and $c0
  1369. rlca
  1370. rlca
  1371. ld c, a
  1372. .sfxChannelLoop
  1373. ld d, c
  1374. ld a, c
  1375. add a
  1376. add c
  1377. ld c, a
  1378. ld b, 0
  1379. ld a, [wSfxHeaderPointer]
  1380. ld h, a
  1381. ld a, [wSfxHeaderPointer + 1]
  1382. ld l, a
  1383. add hl, bc
  1384. ld c, d
  1385. ld a, [hl]
  1386. and $f
  1387. ld e, a ; software channel ID
  1388. ld d, 0
  1389. ld hl, wChannelSoundIDs
  1390. add hl, de
  1391. ld a, [hl]
  1392. and a
  1393. jr z, .asm_99a3
  1394. ld a, e
  1395. cp $7
  1396. jr nz, .asm_999a
  1397. ld a, [wSoundID]
  1398. cp $14
  1399. jr nc, .asm_9993
  1400. ret
  1401. .asm_9993
  1402. ld a, [hl]
  1403. cp $14
  1404. jr z, .asm_99a3
  1405. jr c, .asm_99a3
  1406. .asm_999a
  1407. ld a, [wSoundID]
  1408. cp [hl]
  1409. jr z, .asm_99a3
  1410. jr c, .asm_99a3
  1411. ret
  1412. .asm_99a3
  1413. xor a
  1414. push de
  1415. ld h, d
  1416. ld l, e
  1417. add hl, hl
  1418. ld d, h
  1419. ld e, l
  1420. ld hl, wChannelReturnAddresses
  1421. add hl, de
  1422. ld [hli], a
  1423. ld [hl], a
  1424. ld hl, wChannelCommandPointers
  1425. add hl, de
  1426. ld [hli], a
  1427. ld [hl], a
  1428. pop de
  1429. ld hl, wChannelSoundIDs
  1430. add hl, de
  1431. ld [hl], a
  1432. ld hl, wChannelFlags1
  1433. add hl, de
  1434. ld [hl], a
  1435. ld hl, wChannelDuties
  1436. add hl, de
  1437. ld [hl], a
  1438. ld hl, wChannelDutyCycles
  1439. add hl, de
  1440. ld [hl], a
  1441. ld hl, wChannelVibratoDelayCounters
  1442. add hl, de
  1443. ld [hl], a
  1444. ld hl, wChannelVibratoExtents
  1445. add hl, de
  1446. ld [hl], a
  1447. ld hl, wChannelVibratoRates
  1448. add hl, de
  1449. ld [hl], a
  1450. ld hl, wChannelFrequencyLowBytes
  1451. add hl, de
  1452. ld [hl], a
  1453. ld hl, wChannelVibratoDelayCounterReloadValues
  1454. add hl, de
  1455. ld [hl], a
  1456. ld hl, wChannelPitchBendLengthModifiers
  1457. add hl, de
  1458. ld [hl], a
  1459. ld hl, wChannelPitchBendFrequencySteps
  1460. add hl, de
  1461. ld [hl], a
  1462. ld hl, wChannelPitchBendFrequencyStepsFractionalPart
  1463. add hl, de
  1464. ld [hl], a
  1465. ld hl, wChannelPitchBendCurrentFrequencyFractionalPart
  1466. add hl, de
  1467. ld [hl], a
  1468. ld hl, wChannelPitchBendCurrentFrequencyHighBytes
  1469. add hl, de
  1470. ld [hl], a
  1471. ld hl, wChannelPitchBendCurrentFrequencyLowBytes
  1472. add hl, de
  1473. ld [hl], a
  1474. ld hl, wChannelPitchBendTargetFrequencyHighBytes
  1475. add hl, de
  1476. ld [hl], a
  1477. ld hl, wChannelPitchBendTargetFrequencyLowBytes
  1478. add hl, de
  1479. ld [hl], a
  1480. ld hl, wChannelFlags2
  1481. add hl, de
  1482. ld [hl], a
  1483. ld a, $1
  1484. ld hl, wChannelLoopCounters
  1485. add hl, de
  1486. ld [hl], a
  1487. ld hl, wChannelNoteDelayCounters
  1488. add hl, de
  1489. ld [hl], a
  1490. ld hl, wChannelNoteSpeeds
  1491. add hl, de
  1492. ld [hl], a
  1493. ld a, e
  1494. cp Ch4
  1495. jr nz, .asm_9a2b
  1496. ld a, $8
  1497. ld [rNR10], a ; sweep off
  1498. .asm_9a2b
  1499. ld a, c
  1500. and a
  1501. jp z, .playSoundCommon
  1502. dec c
  1503. jp .sfxChannelLoop
  1504. .stopAllAudio
  1505. ld a, $80
  1506. ld [rNR52], a ; sound hardware on
  1507. ld [rNR30], a ; wave playback on
  1508. xor a
  1509. ld [rNR51], a ; no sound output
  1510. ld [rNR32], a ; mute channel 3 (wave channel)
  1511. ld a, $8
  1512. ld [rNR10], a ; sweep off
  1513. ld [rNR12], a ; mute channel 1 (pulse channel 1)
  1514. ld [rNR22], a ; mute channel 2 (pulse channel 2)
  1515. ld [rNR42], a ; mute channel 4 (noise channel)
  1516. ld a, $40
  1517. ld [rNR14], a ; counter mode
  1518. ld [rNR24], a
  1519. ld [rNR44], a
  1520. ld a, $77
  1521. ld [rNR50], a ; full volume
  1522. xor a
  1523. ld [wUnusedC000], a
  1524. ld [wDisableChannelOutputWhenSfxEnds], a
  1525. ld [wMuteAudioAndPauseMusic], a
  1526. ld [wMusicTempo + 1], a
  1527. ld [wSfxTempo + 1], a
  1528. ld [wMusicWaveInstrument], a
  1529. ld [wSfxWaveInstrument], a
  1530. ld d, $a0
  1531. ld hl, wChannelCommandPointers
  1532. call .FillMem
  1533. ld a, $1
  1534. ld d, $18
  1535. ld hl, wChannelNoteDelayCounters
  1536. call .FillMem
  1537. ld [wMusicTempo], a
  1538. ld [wSfxTempo], a
  1539. ld a, $ff
  1540. ld [wStereoPanning], a
  1541. ret
  1542. ; fills d bytes at hl with a
  1543. .FillMem
  1544. ld b, d
  1545. .loop
  1546. ld [hli], a
  1547. dec b
  1548. jr nz, .loop
  1549. ret
  1550. .playSoundCommon
  1551. ld a, [wSoundID]
  1552. ld l, a
  1553. ld e, a
  1554. ld h, 0
  1555. ld d, h
  1556. add hl, hl
  1557. add hl, de
  1558. ld de, SFX_Headers_1
  1559. add hl, de
  1560. ld e, l
  1561. ld d, h
  1562. ld hl, wChannelCommandPointers
  1563. ld a, [de] ; get channel number
  1564. ld b, a
  1565. rlca
  1566. rlca
  1567. and $3
  1568. ld c, a
  1569. ld a, b
  1570. and $f
  1571. ld b, c
  1572. inc b
  1573. inc de
  1574. ld c, 0
  1575. .commandPointerLoop
  1576. cp c
  1577. jr z, .next
  1578. inc c
  1579. inc hl
  1580. inc hl
  1581. jr .commandPointerLoop
  1582. .next
  1583. push hl
  1584. push bc
  1585. push af
  1586. ld b, 0
  1587. ld c, a
  1588. ld hl, wChannelSoundIDs
  1589. add hl, bc
  1590. ld a, [wSoundID]
  1591. ld [hl], a
  1592. pop af
  1593. cp Ch3
  1594. jr c, .skipSettingFlag
  1595. ld hl, wChannelFlags1
  1596. add hl, bc
  1597. set BIT_NOISE_OR_SFX, [hl]
  1598. .skipSettingFlag
  1599. pop bc
  1600. pop hl
  1601. ld a, [de] ; get channel pointer
  1602. ld [hli], a
  1603. inc de
  1604. ld a, [de]
  1605. ld [hli], a
  1606. inc de
  1607. inc c
  1608. dec b
  1609. ld a, b
  1610. and a
  1611. ld a, [de]
  1612. inc de
  1613. jr nz, .commandPointerLoop
  1614. ld a, [wSoundID]
  1615. cp CRY_SFX_START
  1616. jr nc, .asm_9aeb
  1617. jr .done
  1618. .asm_9aeb
  1619. ld a, [wSoundID]
  1620. cp CRY_SFX_END
  1621. jr z, .done
  1622. jr c, .cry
  1623. jr .done
  1624. .cry
  1625. ld hl, wChannelSoundIDs + Ch4
  1626. ld [hli], a
  1627. ld [hli], a
  1628. ld [hli], a
  1629. ld [hl], a
  1630. ld hl, wChannelCommandPointers + Ch6 * 2 ; sfx wave channel pointer
  1631. ld de, Audio1_CryEndchannel
  1632. ld [hl], e
  1633. inc hl
  1634. ld [hl], d ; overwrite pointer to point to endchannel
  1635. ld a, [wSavedVolume]
  1636. and a
  1637. jr nz, .done
  1638. ld a, [rNR50]
  1639. ld [wSavedVolume], a
  1640. ld a, $77
  1641. ld [rNR50], a ; full volume
  1642. .done
  1643. ret
  1644. Audio1_CryEndchannel:
  1645. endchannel
  1646. Audio1_HWChannelBaseAddresses:
  1647. ; the low bytes of each HW channel's base address
  1648. db HW_CH1_BASE, HW_CH2_BASE, HW_CH3_BASE, HW_CH4_BASE ; channels 0-3
  1649. db HW_CH1_BASE, HW_CH2_BASE, HW_CH3_BASE, HW_CH4_BASE ; channels 4-7
  1650. Audio1_HWChannelDisableMasks:
  1651. db HW_CH1_DISABLE_MASK, HW_CH2_DISABLE_MASK, HW_CH3_DISABLE_MASK, HW_CH4_DISABLE_MASK ; channels 0-3
  1652. db HW_CH1_DISABLE_MASK, HW_CH2_DISABLE_MASK, HW_CH3_DISABLE_MASK, HW_CH4_DISABLE_MASK ; channels 4-7
  1653. Audio1_HWChannelEnableMasks:
  1654. db HW_CH1_ENABLE_MASK, HW_CH2_ENABLE_MASK, HW_CH3_ENABLE_MASK, HW_CH4_ENABLE_MASK ; channels 0-3
  1655. db HW_CH1_ENABLE_MASK, HW_CH2_ENABLE_MASK, HW_CH3_ENABLE_MASK, HW_CH4_ENABLE_MASK ; channels 4-7
  1656. Audio1_Pitches:
  1657. dw $F82C ; C_
  1658. dw $F89D ; C#
  1659. dw $F907 ; D_
  1660. dw $F96B ; D#
  1661. dw $F9CA ; E_
  1662. dw $FA23 ; F_
  1663. dw $FA77 ; F#
  1664. dw $FAC7 ; G_
  1665. dw $FB12 ; G#
  1666. dw $FB58 ; A_
  1667. dw $FB9B ; A#
  1668. dw $FBDA ; B_