SoundProcessing:
9825: A5 E0 LDA <??SND_E0?? ;
9827: F0 0C BEQ $9835 ;
9829: A9 00 LDA #$00 ; Disable all ...
982B: 8D 15 40 STA S_Status ; ... channels
982E: A9 0F LDA #$0F ; Enable Square1, Square2, ...
9830: 8D 15 40 STA S_Status ; ... Triangle, and Noise (everything but DMC).
9833: D0 11 BNE $9846 ; Has to be NE so this is a jump to process sound effects
;
9835: A9 FF LDA #$FF ; Set bit 1 (and others)
9837: 8D 17 40 STA S_FrameCntr ; ?? Sync frame-count to sound procesor ??
983A: 20 D5 9A JSR MusEffect ; Process any music effect or music request on square-2
983D: 20 A0 99 JSR $99A0 ; ?? Process any noise effect or noise request
9840: 20 85 9B JSR DModEffect ; Process any delta-modulation effect or delta-modulation request
9843: 20 6B 9C JSR PlayMusic ; Process any music
;
9846: 20 CC 98 JSR SndEffect ; Process any sound effect or sound-effect request on square-1
;
9849: A9 00 LDA #$00 ; Clear ...
984B: 8D 04 06 STA SND_Request ; ... the sound-effect request
984E: 8D 03 06 STA ??SND_603?? ;
9851: 8D 02 06 STA SND_ReqMusEff ; Clear the music-effect request
9854: 8D 01 06 STA ??SND_601?? ; Clear the delta-modulation request
9857: 8D 00 06 STA SND_ReqMusic ;
985A: 60 RTS ;
Misc Sounds
MiscSounds:
; Various sound effects played on the square-1 channel. The table of offsets gives the
; priority if multiple effects are requested. Thus 1) bouncing-off-shield is higher
; priority than the lowest 7) near-death-beeping.
;
; The near-death beeping is prioritized in hard-code. If any sound effect is playing
; then the near-death-beep will NOT preempt it.
;
; These "scripts" are read one byte at a time. These bytes are note numbers whose tones
; are written to the square-1 channel every music pass. Thus these effects are really,
; really short and one-shot fire-and-forget effects not intended to be stopped.
;
; Bytes with the upper-bit set are control values written to square-1 followed immediately
; by a note number. A 00 ends the script.
;
; See the note-table at 9F00.
;
985B: 1C 4C 27 5C 46 67 07
;
9862: 95 50 08 08 08 08 08 90 ; 7 Near-death beeping
986A: 08 08 08 08 08 08 08 08
9872: 08 08 08 08 00
9877: 82 4A 48 4A 08 08 08 08 ; 1 Bouncing off shield
987F: 08 08 00
9882: 9F 1E 22 24 26 9F 28 2A ; 3 Wizzrobe magic attack (thanks James Vanderhyde)
988A: 2C 2E 9A 28 2A 2C 2E 9C
9892: 28 2A 2C 2E 96 28 2A 2C
989A: 2E 98 28 2A 2C 2E 00
98A1: 99 42 4A 50 54 00 ; 5 Letters popping up
98A7: 99 70 0A 70 0E 70 10 9F ; 2 Enemy death
98AF: 70 2A 12 1E 2A 70 1E 00
98B7: 9A 42 08 08 56 08 08 00 ; 4 Picking up a heart (thanks James Vanderhyde)
98BF: 08 08 00
98C2: 9F 40 30 40 3A 28 00 ; 6 Picking a letter when entering name
; Request a sound effect. If the upper bit of 604 is set, sound effect processing is
; suspended. If 604 is 0, current sound effect (in 605) continues. The near-death-beeping
; can't interrupt any playing effect (this beeping is a continual effect that will play
; in the background).
;
98C9: 4C 46 9D JMP $9D46 ; Jump over large data area (area too big for a relative jump)
Sound Effect
SndEffect:
98CC: AD 04 06 LDA SND_Request ; Sound request
98CF: 30 F8 BMI $98C9 ; Sounds suspended .... out
98D1: F0 09 BEQ $98DC ; No request ... keep playing the current
98D3: C9 40 CMP #$40 ; Near death beeping?
98D5: D0 0B BNE $98E2 ; No ... start this effect
98D7: AE 05 06 LDX SND_CurEffect ; Is there any effect playing?
98DA: F0 06 BEQ $98E2 ; No ... heart sound can play
98DC: AD 05 06 LDA SND_CurEffect ; Is there a sound effect playing?
98DF: D0 10 BNE $98F1 ; Yes ... go process the tones
98E1: 60 RTS ; Done
98E2: 8D 05 06 STA SND_CurEffect ; Current sound effect
98E5: A0 00 LDY #$00 ; Bit number ...
98E7: C8 INY ; ... in A ...
98E8: 4A LSR A ; ... to ...
98E9: 90 FC BCC $98E7 ; ... Y (sound priority from left to right if multiple are given)
98EB: B9 5A 98 LDA $985A,Y ; Lookup sound effect script
98EE: 8D 0E 06 STA 060E ; Save script for sound effect
;
98F1: AC 0E 06 LDY 060E ; Script pointer to Y
98F4: EE 0E 06 INC 060E ; Bump script pointer
98F7: B9 5B 98 LDA MiscSounds,Y ; Get command
98FA: 30 15 BMI $9911 ; Upper bit set ... this is control and next is note
98FC: D0 1F BNE $991D ; If it is just a note, go play it (0 ends script)
;
98FE: A2 90 LDX #$90 ; Disable decay, no looping, duty cycle to 8+/8-
9900: 8E 00 40 STX S_SQR1_A ; Reset square 1 [NES] Audio -> Square 1 Control
9903: A2 18 LDX #$18 ; Wavelength = 0, length counter = 6
9905: 8E 03 40 STX S_SQR1_D ; Reset square 1 [NES] Audio -> Square 1 Coarse tune
9908: A2 00 LDX #$00 ; Clear fine ...
990A: 8E 02 40 STX S_SQR1_C ; ... tune [NES] Audio -> Square 1 Fine tune
990D: 8E 05 06 STX SND_CurEffect ; Clear the sound-effect-playing flag
9910: 60 RTS ; Done
9911: 8D 00 40 STA S_SQR1_A ; Store sq1 control value [NES] Audio -> Square 1 Control
9914: AC 0E 06 LDY 060E ; Get script pointer
9917: EE 0E 06 INC 060E ; Bump pointer
991A: B9 5B 98 LDA MiscSounds,Y ; Get note value
;
991D: 20 0D 9C JSR $9C0D ; Play the note on square 1
9920: A9 7F LDA #$7F ; Bit 7=0 ...
9922: 8D 01 40 STA S_SQR1_B ; ... disable sweep [NES] Audio -> Square 1 Ramp control
9925: 60 RTS ; Done
9926: A9 0F LDA #$0F ; Enable Pulse1, Pulse2, ...
9928: 8D 15 40 STA S_Status ; ... Triangle, and Noise. [NES] IRQ status / Sound enable
992B: A9 00 LDA #$00 ;
992D: 8D 08 06 STA SND_DMod1 ;
9930: 8D 07 06 STA SND_CurMusEff ;
9933: 8D 1A 06 STA 061A ;
9936: 8D F6 05 STA 05F6 ;
9939: 60 RTS ;
993A: 8C 06 06 STY 0606 ;
993D: A9 05 LDA #$05 ;
993F: 85 69 STA <0069 ;
9941: AD 04 06 LDA SND_Request ; If anything is requested alongside ...
9944: 29 EF AND #$EF ; ... "letters popping up" then ...
9946: D0 03 BNE $994B ; ... drop request for ...
9948: 8D 04 06 STA SND_Request ; ... "letters popping up"
994B: A4 69 LDY <0069 ;
994D: B9 BB 9F LDA $9FBB,Y ;
9950: D0 1C BNE $996E ;
9952: 8C 06 06 STY 0606 ;
9955: A9 38 LDA #$38 ;
9957: 85 69 STA <0069 ;
9959: A9 0D LDA #$0D ; Initialize ...
995B: 85 68 STA <0068 ; ... count
995D: C6 68 DEC <0068 ; Drop the count
995F: A4 68 LDY <0068 ; End of sample table?
9961: F0 F6 BEQ $9959 ; Yes ... go reset
9963: C0 07 CPY #$07 ;
9965: 90 04 BCC $996B ;
9967: A9 10 LDA #$10 ;
9969: D0 10 BNE $997B ;
996B: B9 F8 9E LDA $9EF8,Y ;
996E: AA TAX ; Hold value
996F: 29 0F AND #$0F ; Lower 4 bits ...
9971: 8D 0E 40 STA S_NOI_C ; ... to sample rate [NES] Audio -> Noise Frequency reg #1
9974: 8A TXA ; Restore value
9975: 4A LSR A ; Get ...
9976: 4A LSR A ; ... upper ...
9977: 4A LSR A ; ... four ...
9978: 4A LSR A ; ... bits
9979: 09 10 ORA #$10 ; Disable envelope decay
997B: 8D 0C 40 STA S_NOI_A ; Set noise volume [NES] Audio -> Noise control reg
997E: A9 08 LDA #$08 ; Set length counter reload ...
9980: 8D 0F 40 STA S_NOI_D ; ... to 00001 [NES] Audio -> Noise Frequency reg #2
9983: C6 69 DEC <0069 ;
9985: D0 0A BNE $9991 ;
9987: A9 F0 LDA #$F0 ; Volume ...
9989: 8D 0C 40 STA S_NOI_A ; ... zero [NES] Audio -> Noise control reg
998C: A9 00 LDA #$00 ;
998E: 8D 06 06 STA 0606 ;
9991: 60 RTS ;
9992: 8C 06 06 STY 0606 ;
9995: A9 0A LDA #$0A ;
9997: 85 69 STA <0069 ;
9999: A4 69 LDY <0069 ;
999B: B9 B1 9F LDA $9FB1,Y ;
999E: D0 CE BNE $996E ;
;
99A0: AC 03 06 LDY ??SND_603?? ;
99A3: 30 81 BMI $9926 ;
99A5: AD 06 06 LDA 0606 ;
99A8: 4E 03 06 LSR ??SND_603?? ;
99AB: B0 E5 BCS $9992 ;
99AD: 4A LSR A ;
99AE: B0 E9 BCS $9999 ;
99B0: 4E 03 06 LSR ??SND_603?? ;
99B3: B0 85 BCS $993A ;
99B5: 4A LSR A ;
99B6: B0 93 BCS $994B ;
99B8: 4E 03 06 LSR ??SND_603?? ;
99BB: B0 2A BCS $99E7 ;
99BD: 4A LSR A ;
99BE: B0 2E BCS $99EE ;
99C0: 4E 03 06 LSR ??SND_603?? ;
99C3: B0 8D BCS $9952 ;
99C5: 4A LSR A ;
99C6: B0 95 BCS $995D ;
99C8: 4E 03 06 LSR ??SND_603?? ;
99CB: B0 0C BCS $99D9 ;
99CD: 4A LSR A ;
99CE: B0 10 BCS $99E0 ;
99D0: 4A LSR A ;
99D1: B0 36 BCS $9A09 ;
99D3: 4E 03 06 LSR ??SND_603?? ;
99D6: B0 25 BCS $99FD ;
99D8: 60 RTS ;
99D9: 8C 06 06 STY 0606 ;
99DC: A9 18 LDA #$18 ;
99DE: 85 69 STA <0069 ;
99E0: A4 69 LDY <0069 ;
99E2: B9 3C 9A LDA $9A3C,Y ;
99E5: D0 87 BNE $996E ;
99E7: 8C 06 06 STY 0606 ;
99EA: A9 20 LDA #$20 ;
99EC: 85 69 STA <0069 ;
99EE: A5 69 LDA <0069 ;
99F0: 4A LSR A ;
99F1: A8 TAY ;
99F2: A2 0E LDX #$0E ; Coversion to 11 bits as ...
99F4: 8E 0E 40 STX S_NOI_C ; ... note E6 [NES] Audio -> Noise Frequency reg #1
99F7: B9 C0 9F LDA $9FC0,Y ;
99FA: 4C 7B 99 JMP $997B ;
99FD: 8C 06 06 STY 0606 ;
9A00: A9 D0 LDA #$D0 ;
9A02: 8D F3 05 STA 05F3 ;
9A05: A9 10 LDA #$10 ; Volume all ...
9A07: 85 68 STA <0068 ; ... the way down
9A09: AD F3 05 LDA 05F3 ;
9A0C: C9 BF CMP #$BF ;
9A0E: 90 04 BCC $9A14 ;
9A10: E6 68 INC <0068 ; Increase the volume
9A12: D0 14 BNE $9A28 ; Didn't overflow ... use it
9A14: AD F3 05 LDA 05F3 ;
9A17: 4A LSR A ;
9A18: 90 0E BCC $9A28 ;
9A1A: 4A LSR A ;
9A1B: 90 0B BCC $9A28 ;
9A1D: 4A LSR A ;
9A1E: 90 08 BCC $9A28 ;
9A20: A5 68 LDA <0068 ; Current noise volume
9A22: C9 10 CMP #$10 ; At its lowest?
9A24: F0 02 BEQ $9A28 ; Yes ... leave it there
9A26: C6 68 DEC <0068 ; Drop the volume
9A28: A5 68 LDA <0068 ; New volume value
9A2A: 8D 0C 40 STA S_NOI_A ; Set new volume [NES] Audio -> Noise control reg
9A2D: A2 03 LDX #$03 ; 4 bit conversion ...
9A2F: 8E 0E 40 STX S_NOI_C ; ... to note A12 [NES] Audio -> Noise Frequency reg #1
9A32: A9 08 LDA #$08 ; Length counter load ...
9A34: 8D 0F 40 STA S_NOI_D ; ... to 00001 [NES] Audio -> Noise Frequency reg #2
9A37: CE F3 05 DEC 05F3 ;
9A3A: 4C 85 99 JMP $9985 ;
9A3D: 1F 2F 2E 3F 3F 4C 4E 5F 6F 6F 7E 8F 9E AF BE CF DE EF FE FD FE FF FF FE
Misc Music
MiscMusic:
;
; Note number ... upper bit set for set delay
;
9A55: 0C 08 11 1C 28 33 40 62
;
9A5D: 8A 4E 58 60 ; 2 ??
9A61: 8A 5E 94 60 00 ; 1 ?? Change selection
9A66: 8A 42 06 3C 30 2E 3E 44 CC 02 00 ; 3 Discover secret
9A71: 83 40 42 48 4A 02 50 4C 54 94 56 00 ; 4 Picked up something
9A7D: 94 3A 3E A8 50 8A 4E 02 CC 4A 00 ; 5 ?? Short music
9A88: 81 28 3E 24 82 3A 81 16 30 1A 82 34 00 ; 6 Enemy death
9A95: 94 56 42 02 4C 52 42 5C 4A 5A 02 4C 5A ; 7 ?? Long music ?
9AA2: 56 02 50 4C 5A 02 54 5A 58 02 50 54 4C ;
9AAF: 42 02 4C 50 48 4A 50 00 ;
9AB7: 8A 08 08 08 85 3C 3A 38 36 3A 38 36 34 ; 8 ?? Spiraling down ?
9AC4: 38 36 34 32 36 34 32 30 34 32 30 2E 2A ;
9AD1: 28 A8 26 00 ;
Music Effect
MusEffect:
9AD5: AD 02 06 LDA SND_ReqMusEff ; Get music effect request
9AD8: 30 08 BMI $9AE2 ;
9ADA: D0 0B BNE $9AE7 ; Requested sound ... do it
9ADC: AD 07 06 LDA SND_CurMusEff ; Is any sound playing?
9ADF: D0 19 BNE $9AFA ; Yes ... process it
9AE1: 60 RTS ; Out
9AE2: 20 46 9D JSR $9D46 ;
9AE5: A9 80 LDA #$80 ; Effect #8 ?? spiraling down
9AE7: 8D 07 06 STA SND_CurMusEff ; Store effect
9AEA: A0 00 LDY #$00 ; Count 1st ...
9AEC: C8 INY ; ... bit ...
9AED: 4A LSR A ; ... number ...
9AEE: 90 FC BCC $9AEC ; ... from right
9AF0: B9 54 9A LDA $9A54,Y ; Get offset to script
9AF3: 8D 18 06 STA SND_MusEffDel ; Store new script offset
9AF6: A9 01 LDA #$01 ; Script starts ...
9AF8: 85 6F STA <SND_MusEffCnt ; ... now (no delay)
;
9AFA: C6 6F DEC <SND_MusEffCnt ; Decrement delay
9AFC: D0 49 BNE $9B47 ; Not time ... warble or hold note
9AFE: AC 18 06 LDY SND_MusEffDel ; Get script pointer
9B01: EE 18 06 INC SND_MusEffDel ; Bump script pointer
9B04: B9 55 9A LDA MiscMusic,Y ; Get command
9B07: 30 1C BMI $9B25 ; Delay+note ... go store delay first
9B09: D0 27 BNE $9B32 ; Not end of script ... go do note
;
9B0B: AD 07 06 LDA SND_CurMusEff ; Ending ...
9B0E: C9 40 CMP #$40 ; ... the long music ?
9B10: F0 D5 BEQ $9AE7 ; Yes ... start it over
;
9B12: A2 90 LDX #$90 ; Volume all ...
9B14: 8E 04 40 STX S_SQR2_A ; ... the way down [NES] Audio -> Square 2 Control
9B17: A2 18 LDX #$18 ; Wavelength = 0, length counter = 6
9B19: 8E 07 40 STX S_SQR2_D ; Reset square 2 [NES] Audio -> Square 2 Coarse tune
9B1C: A2 00 LDX #$00 ; Clear ...
9B1E: 8E 07 06 STX SND_CurMusEff ; ... current playing music effect
9B21: 8E 06 40 STX S_SQR2_C ; Clear wavelength [NES] Audio -> Square 2 Fine tune
9B24: 60 RTS ; Done
;
9B25: 29 7F AND #$7F ; Mask off upper bit
9B27: 85 6E STA <SND_MusEffRel ; Store new delay reload
9B29: AC 18 06 LDY SND_MusEffDel ; Get pointer to next in script
9B2C: EE 18 06 INC SND_MusEffDel ; Bump script pointer
9B2F: B9 55 9A LDA MiscMusic,Y ; Get note value
;
9B32: 20 2B 9C JSR $9C2B ; Note on square 2 (fine value goes to 6B)
9B35: A9 7F LDA #$7F ; Bit 7=0 ...
9B37: 8D 05 40 STA S_SQR2_B ; ... disable [NES] Audio -> Square 2 Ramp control
9B3A: A9 86 LDA #$86 ; Set envelope decay rate ...
9B3C: 8D 04 40 STA S_SQR2_A ; ... to 6 [NES] Audio -> Square 2 Control
9B3F: A5 6E LDA <SND_MusEffRel ; Get last delay reload
9B41: 85 6F STA <SND_MusEffCnt ; Reset reload
9B43: A9 1F LDA #$1F ; Reset ...
9B45: 85 6D STA <SND_MusEffBell ; ... bell-curve envelope
;
9B47: AD 07 06 LDA SND_CurMusEff ; Current music effect
9B4A: 29 90 AND #$90 ; Is this effect 1 or 8?
9B4C: F0 16 BEQ $9B64 ; No ... just let the note play as is
9B4E: A4 6D LDY <SND_MusEffBell ; Bell curve envelope counter
9B50: F0 02 BEQ $9B54 ; Reached the bottom ... hold that value
9B52: C6 6D DEC <SND_MusEffBell ; Decrement the envelope counter
9B54: B9 65 9B LDA $9B65,Y ; Get the volume value
9B57: 8D 04 40 STA S_SQR2_A ; Set volume as per the bell curve [NES] Audio -> Square 2 Control
9B5A: A5 6F LDA <SND_MusEffCnt ; Warble count (use current delay count)
9B5C: A6 6B LDX <SND_Sq2Fine ; Current frequency
9B5E: 20 54 9C JSR Warble ; Do the warble
9B61: 8E 06 40 STX S_SQR2_C ; Play the note on square 2 [NES] Audio -> Square 2 Fine tune
9B64: 60 RTS ; Done
; This table contains volumes for notes played on sq2 over 32 consecutive intervals.
; These basically form a bell curve that rises quickly, holds, then decays quickly.
;
9B65: 95 96 97 98 99 9A 9B 9C 9D 9E 9F 9F 9F 9F 9F 9F
9B75: 9F 9F 9F 9F 9F 9F 9F 9E 9D 9C 9B 9A 99 98 97 96
Modulation Effect
DModEffect:
; The request value in 0601 is used as data in the effect getting stored in 608. If the upper bit
; of the request is 1 then the D/A is initialized with 7F. Otherwise it is initialized with 00.
;
; If either 05F6 or 0608 holds a non-zero value then an effect is in progress and continues. The 05F6
; only gets cleared at 9926.
;
9B85: AD 01 06 LDA ??SND_601?? ; Delta-modulation effect request
9B88: 30 29 BMI $9BB3 ; Upper bit set ... initialize with D/A = 7F
9B8A: D0 23 BNE $9BAF ; Anything else ... initialize with D/A = 00
;
9B8C: AD 08 06 LDA SND_DMod1 ;
9B8F: F0 18 BEQ $9BA9 ;
9B91: CE F2 05 DEC 05F2 ;
9B94: D0 18 BNE $9BAE ;
9B96: AD 08 06 LDA SND_DMod1 ;
9B99: 30 18 BMI $9BB3 ;
9B9B: 29 70 AND #$70 ;
9B9D: D0 10 BNE $9BAF ;
9B9F: A9 00 LDA #$00 ;
9BA1: 8D 08 06 STA SND_DMod1 ;
9BA4: A9 0F LDA #$0F ; Enable Pulse1, Pulse2, (NOTE NO DeltaMod) ...
9BA6: 8D 15 40 STA S_Status ; ... Triangle, and Noise. [NES] IRQ status / Sound enable
9BA9: AD F6 05 LDA 05F6 ;
9BAC: D0 09 BNE $9BB7 ;
9BAE: 60 RTS ; Done
;
9BAF: A2 00 LDX #$00 ; D/A to ...
9BB1: F0 04 BEQ $9BB7 ; ... (BRA) full-off
;
9BB3: A2 7F LDX #$7F ; D/A to full-on
9BB5: 29 F0 AND #$F0 ;
;
9BB7: 8E 11 40 STX S_DMC_B ; [NES] Audio -> DPCM D/A data
9BBA: 8D 08 06 STA SND_DMod1 ;
9BBD: AA TAX ;
9BBE: 29 F0 AND #$F0 ;
9BC0: F0 03 BEQ $9BC5 ;
9BC2: 8D F6 05 STA 05F6 ;
9BC5: 8A TXA ;
9BC6: A0 00 LDY #$00 ; Count ...
9BC8: C8 INY ; ... first bit ...
9BC9: 4A LSR A ; ... from ...
9BCA: 90 FC BCC $9BC8 ; ... right (must be 1 to 7)
9BCC: B9 FB 9B LDA $9BFB,Y ; Lookup ...
9BCF: 8D 10 40 STA S_DMC_A ; ... control value [NES] Audio -> DPCM control
9BD2: B9 ED 9B LDA $9BED,Y ; Lookup ...
9BD5: 8D 12 40 STA S_DMC_C ; ... address value [NES] Audio -> DPCM address
9BD8: B9 F4 9B LDA $9BF4,Y ; Lookup ...
9BDB: 8D 13 40 STA S_DMC_D ; ... data length value [NES] Audio -> DPCM data length
9BDE: A9 A0 LDA #$A0 ; Reset a timer ...
9BE0: 8D F2 05 STA 05F2 ; ... in the effect
9BE3: A9 0F LDA #$0F ; Enable Pulse1, Pulse2, ...
9BE5: 8D 15 40 STA S_Status ; ... Triangle, and Noise. [NES] IRQ status / Sound enable
9BE8: A9 1F LDA #$1F ; Enable DeltaModulation, Pulse1, Pulse2, ...
9BEA: 8D 15 40 STA S_Status ; ... Triangle, and Noise. [NES] IRQ status / Sound enable
9BED: 60 RTS ; Done
;
; Table of DPCM addresses
9BEE: 00 4C 80 1D 20 28 4C
;
; Table of DPCM data lengths
9BF5: 75 C0 40 0A B0 90 D0
;
; Table of DPCM controls
9BFC: 0F 0F 0D 0F 0E 0F 0E
9C03: 8C 01 40 STY S_SQR1_B ; Set control [NES] Audio -> Square 1 Ramp control
9C06: 8E 00 40 STX S_SQR1_A ; Set ramp [NES] Audio -> Square 1 Control
9C09: 60 RTS ; Done
;
NoteOnSq1:
9C0A: 20 03 9C JSR $9C03 ; Store X and Y to Square 1 Control/Ramp
9C0D: A8 TAY ; Note number to Y
9C0E: B9 01 9F LDA $9F01,Y ; Fine note frequency
9C11: F0 0D BEQ $9C20 ; Fine is 0 for silence
9C13: 85 6A STA <SND_Sq1Fine ; Remember fine value (for warbling)
9C15: 8D 02 40 STA S_SQR1_C ; Set fine value [NES] Audio -> Square 1 Fine tune
9C18: B9 00 9F LDA NoteTable,Y ; Coarse note frequency
9C1B: 09 08 ORA #$08 ; Base value
9C1D: 8D 03 40 STA S_SQR1_D ; Set coarse value [NES] Audio -> Square 1 Coarse tune
9C20: 60 RTS ; Done
9C21: 8E 04 40 STX S_SQR2_A ; Set control [NES] Audio -> Square 2 Control
9C24: 8C 05 40 STY S_SQR2_B ; Set ramp [NES] Audio -> Square 2 Ramp control
9C27: 60 RTS ; Done
;
NoteOnSq2:
9C28: 20 21 9C JSR $9C21 ; Store X and Y to Square 2 Control/Ramp
9C2B: A8 TAY ; Note number to Y
9C2C: B9 01 9F LDA $9F01,Y ; Fine note frequency
9C2F: F0 EF BEQ $9C20 ; Fine is 0 for silence
9C31: 85 6B STA <SND_Sq2Fine ; Remember fine value (for warbling)
9C33: 8D 06 40 STA S_SQR2_C ; Set fine value [NES] Audio -> Square 2 Fine tune
9C36: B9 00 9F LDA NoteTable,Y ; Coarse note frequency
9C39: 09 08 ORA #$08 ; Length counter load = 00001
9C3B: 8D 07 40 STA S_SQR2_D ; Set coarse value [NES] Audio -> Square 2 Coarse tune
9C3E: 60 RTS ; Done
NoteOnTri:
9C3F: A8 TAY ; Note number to Y
9C40: B9 01 9F LDA $9F01,Y ; Fine note frequency
9C43: F0 DB BEQ $9C20 ; Fine is 0 for silence
9C45: 8D F0 05 STA SND_TriFine ; Remember fine value (for warbling)
9C48: 8D 0A 40 STA S_TRI_C ; Set fine value [NES] Audio -> Triangle Frequency reg1
9C4B: B9 00 9F LDA NoteTable,Y ; Coarse note frequency
9C4E: 09 08 ORA #$08 ; Length counter load = 00001
9C50: 8D 0B 40 STA S_TRI_D ; Set coarse value [NES] Audio -> Triangle Frequency reg2
9C53: 60 RTS ; Done
Warble
Warble:
; Modify X (A<10 do nothing, A:3==1 then --X, A:3==0 then ++X without wrapping)
; Warbling counts from 0 up and back around.
; 1st 16 leave frequency alone. Then 4 increments (no wrapping) followed by 4 decrements, 4 inc,
; 4 dec, and so on. Notice how wrapping is only checked on the increment. The decrement doesn't
; need it since we either did increment 4 (and can come back down 4) or we topped out in which
; case there is plenty of room to come down.
;
; If A<10 then X is left alone
; If A bit 3 is 1 OR X=FF
; X=X-1 then A=X
; ELSE
; X=X+1 then A=X
;
9C54: C9 10 CMP #$10 ; If warble count is less than 10 ...
9C56: 90 0F BCC $9C67 ; ... keep the original frequency
9C58: 4A LSR A ; Check ...
9C59: 4A LSR A ; ... bit ...
9C5A: 4A LSR A ; ... 3
9C5B: B0 05 BCS $9C62 ; Bit is set ...
9C5D: 8A TXA ; ... go decrement
9C5E: 69 01 ADC #$01 ; Bit is clear ... increment
9C60: D0 04 BNE $9C66 ; No overflow ... use result
9C62: 8A TXA ; Decrement ...
9C63: 18 CLC ; ... by ...
9C64: 69 FF ADC #$FF ; ... adding -1
9C66: AA TAX ; Result back to X
9C67: 60 RTS ; Done
9C68: 4C 2C 9D JMP $9D2C ; Jump to processing music
Play Music
PlayMusic:
9C6B: AD 00 06 LDA SND_ReqMusic ; Get any music request
9C6E: D0 06 BNE $9C76 ; There is one ... go start it
9C70: AD 09 06 LDA SND_CurSong ; Currently playing music
9C73: D0 F3 BNE $9C68 ; There is a song playing ... keep it going
9C75: 60 RTS ; Done
; Initialize a new song
9C76: 8D 09 06 STA SND_CurSong ; Newly requested music
9C79: 30 18 BMI $9C93 ;
9C7B: C9 06 CMP #$06 ;
9C7D: D0 04 BNE $9C83 ;
9C7F: A0 24 LDY #$24 ;
9C81: D0 62 BNE $9CE5 ;
9C83: C9 01 CMP #$01 ;
9C85: F0 14 BEQ $9C9B ;
9C87: C9 40 CMP #$40 ;
9C89: F0 0C BEQ $9C97 ;
9C8B: C9 10 CMP #$10 ;
9C8D: D0 10 BNE $9C9F ;
9C8F: A0 11 LDY #$11 ;
9C91: D0 0A BNE $9C9D ;
;
9C93: A0 19 LDY #$19 ;
9C95: D0 06 BNE $9C9D ;
9C97: A0 0F LDY #$0F ;
9C99: D0 02 BNE $9C9D ;
9C9B: A0 08 LDY #$08 ;
9C9D: 84 6C STY <006C ;
;
9C9F: AA TAX ;
9CA0: 30 30 BMI $9CD2 ;
9CA2: C9 01 CMP #$01 ;
9CA4: F0 20 BEQ $9CC6 ;
9CA6: C9 40 CMP #$40 ;
9CA8: F0 10 BEQ $9CBA ;
9CAA: C9 10 CMP #$10 ;
9CAC: D0 30 BNE $9CDE ;
; Song fragments 14..19 (loop)
9CAE: E6 6C INC <006C ;
9CB0: A4 6C LDY <006C ;
9CB2: C0 1A CPY #$1A ;
9CB4: D0 2F BNE $9CE5 ;
9CB6: A0 14 LDY #$14 ;
9CB8: D0 E3 BNE $9C9D ;
; Song fragments 0F..11 (loop)
9CBA: E6 6C INC <006C ;
9CBC: A4 6C LDY <006C ;
9CBE: C0 12 CPY #$12 ;
9CC0: D0 23 BNE $9CE5 ;
9CC2: A0 0F LDY #$0F ;
9CC4: D0 D7 BNE $9C9D ;
; Song fragments 09..0F (loop) Main background music
9CC6: E6 6C INC <006C ;
9CC8: A4 6C LDY <006C ;
9CCA: C0 10 CPY #$10 ;
9CCC: D0 17 BNE $9CE5 ;
9CCE: A0 09 LDY #$09 ;
9CD0: D0 CB BNE $9C9D ;
;
; Song fragments 19..23 (loop) Splash screen music
9CD2: E6 6C INC <006C ; Next song number
9CD4: A4 6C LDY <006C ; Have we reached ...
9CD6: C0 24 CPY #$24 ; ... the end?
9CD8: D0 0B BNE $9CE5 ; No ... use it
9CDA: A0 19 LDY #$19 ; Restart ...
9CDC: D0 BF BNE $9C9D ; ... at 19
;
9CDE: 8A TXA ; Song number
9CDF: A0 00 LDY #$00 ; Find ...
9CE1: C8 INY ; .. first ...
9CE2: 4A LSR A ; ... bit from ...
9CE3: 90 FC BCC $9CE1 ; ... right
9CE5: B9 5F 8D LDA $8D5F,Y ; Set ...
9CE8: A8 TAY ; ... note ...
9CE9: B9 60 8D LDA $8D60,Y ; ... duration ...
9CEC: 8D F4 05 STA 05F4 ; ... list
9CEF: B9 61 8D LDA $8D61,Y ; Set ...
9CF2: 85 66 STA <SND_PtrA ; ... pointer ...
9CF4: B9 62 8D LDA $8D62,Y ; ... to ...
9CF7: 85 67 STA <SND_PtrB ; ... music
9CF9: B9 63 8D LDA $8D63,Y ; Set offset for ...
9CFC: 8D 0C 06 STA SND_SongPC_C ; ... voice C
9CFF: B9 64 8D LDA $8D64,Y ; Set offset for ...
9D02: 8D 0B 06 STA SND_SongPC_B ; ... voice B
9D05: B9 65 8D LDA $8D65,Y ; Set offset for ...
9D08: 8D 0D 06 STA SND_SongPC_D ; ... voice D
9D0B: 8D F5 05 STA SND_DrumRep ; ?? Copy of D for reload
9D0E: B9 66 8D LDA $8D66,Y ;
9D11: 8D 19 06 STA 0619 ;
9D14: B9 67 8D LDA $8D67,Y ;
9D17: 8D F1 05 STA 05F1 ;
9D1A: A9 01 LDA #$01 ; Music begins on ...
9D1C: 8D 11 06 STA SND_Timer ; ... next tick
9D1F: 8D 13 06 STA 0613 ;
9D22: 8D 16 06 STA 0616 ;
9D25: 8D 17 06 STA 0617 ;
9D28: 4A LSR A ; Music program counter for voice A ...
9D29: 8D 0A 06 STA SND_SongPC_A ; ... to zero (start of song)
9D2C: CE 11 06 DEC SND_Timer ; Decrement event timer
9D2F: D0 52 BNE $9D83 ; Not time for a new event ... skip on
9D31: AC 0A 06 LDY SND_SongPC_A ; Get music program counter
9D34: EE 0A 06 INC SND_SongPC_A ; Bump counter
9D37: B1 66 LDA (SND_PtrA),Y ; Get next music byte
9D39: F0 04 BEQ $9D3F ; 0 means end of song
9D3B: 10 28 BPL $9D65 ; Upper bit clear ... regular note event
9D3D: D0 18 BNE $9D57 ; (BRA) Upper bit set ... set duration
;
9D3F: AD 09 06 LDA SND_CurSong ; Current song playing
9D42: 29 F1 AND #$F1 ; 1111_0001 Part of a sequence of song fragments?
9D44: D0 0E BNE $9D54 ; Yes ... go back and play next fragment (9C9F)
;
9D46: A9 00 LDA #$00 ; Stop ...
9D48: 8D 09 06 STA SND_CurSong ; ... current song
9D4B: 8D 15 40 STA S_Status ; all sounds. [NES] IRQ status / Sound enable
9D4E: A9 0F LDA #$0F ; Enable Pulse1, Pulse2, ...
9D50: 8D 15 40 STA S_Status ; ... Triangle, and Noise. [NES] IRQ status / Sound enable
9D53: 60 RTS ; Done
9D54: 4C 9F 9C JMP $9C9F ; Long BNE from 9D44
;
9D57: 20 E6 9E JSR GetNoteLen ; Look up note duration based on song's note set
9D5A: 8D 10 06 STA SND_LenReload ; New event timer reload
9D5D: AC 0A 06 LDY SND_SongPC_A ; Get music program counter
9D60: EE 0A 06 INC SND_SongPC_A ; Bump counter
9D63: B1 66 LDA (SND_PtrA),Y ; S Get next music byte
;
9D65: AE 07 06 LDX SND_CurMusEff ; Is there a music effect playing?
9D68: D0 13 BNE $9D7D ; Yes ... let it have this voice
9D6A: 20 2B 9C JSR $9C2B ; Note on square 2
9D6D: F0 03 BEQ $9D72 ; If it was silence, skip next
9D6F: 20 72 9F JSR $9F72 ;
9D72: 8D 12 06 STA 0612 ;
9D75: 20 21 9C JSR $9C21 ; Set sq2 ramp
9D78: A9 00 LDA #$00 ;
9D7A: 8D 1B 06 STA 061B ;
;
9D7D: AD 10 06 LDA SND_LenReload ; Reset event timer ...
9D80: 8D 11 06 STA SND_Timer ; ... to current default
9D83: AC 07 06 LDY SND_CurMusEff ; Is there a music effect playing?
9D86: D0 26 BNE $9DAE ; Yes ... let it have this voice
9D88: EE 1B 06 INC 061B ;
9D8B: AC 12 06 LDY 0612 ;
9D8E: F0 03 BEQ $9D93 ;
9D90: CE 12 06 DEC 0612 ;
9D93: 20 7C 9F JSR $9F7C ;
9D96: 8D 04 40 STA S_SQR2_A ; [NES] Audio -> Square 2 Control
9D99: A2 7F LDX #$7F ;
9D9B: 8E 05 40 STX S_SQR2_B ; [NES] Audio -> Square 2 Ramp control
9D9E: AD 09 06 LDA SND_CurSong ;
9DA1: 10 0B BPL $9DAE ;
9DA3: AD 1B 06 LDA 061B ;
9DA6: A6 6B LDX <SND_Sq2Fine ;
9DA8: 20 54 9C JSR Warble ;
9DAB: 8E 06 40 STX S_SQR2_C ; [NES] Audio -> Square 2 Fine tune
9DAE: AC 0B 06 LDY SND_SongPC_B ;
9DB1: F0 66 BEQ $9E19 ;
9DB3: CE 13 06 DEC 0613 ;
9DB6: D0 36 BNE $9DEE ;
9DB8: AC 0B 06 LDY SND_SongPC_B ; S
9DBB: EE 0B 06 INC SND_SongPC_B ;
9DBE: B1 66 LDA (SND_PtrA),Y ;
9DC0: 10 0E BPL $9DD0 ;
9DC2: 20 E6 9E JSR GetNoteLen ;
9DC5: 8D 0F 06 STA 060F ;
9DC8: AC 0B 06 LDY SND_SongPC_B ;
9DCB: EE 0B 06 INC SND_SongPC_B ;
9DCE: B1 66 LDA (SND_PtrA),Y ;
9DD0: AE 05 06 LDX SND_CurEffect ; Is there a sound effect playing?
9DD3: D0 13 BNE $9DE8 ; Yes ... skip this
9DD5: 20 0D 9C JSR $9C0D ; Note on square 2
9DD8: F0 03 BEQ $9DDD ;
9DDA: 20 72 9F JSR $9F72 ;
9DDD: 8D 14 06 STA 0614 ;
9DE0: 20 03 9C JSR $9C03 ;
9DE3: A9 00 LDA #$00 ;
9DE5: 8D 1C 06 STA 061C ;
;
9DE8: AD 0F 06 LDA 060F ;
9DEB: 8D 13 06 STA 0613 ;
9DEE: AE 05 06 LDX SND_CurEffect ; Is there a sound effect playing?
9DF1: D0 26 BNE $9E19 ;
9DF3: EE 1C 06 INC 061C ;
9DF6: AC 14 06 LDY 0614 ;
9DF9: F0 03 BEQ $9DFE ;
9DFB: CE 14 06 DEC 0614 ;
9DFE: 20 7C 9F JSR $9F7C ;
9E01: 8D 00 40 STA S_SQR1_A ; [NES] Audio -> Square 1 Control
9E04: AD 09 06 LDA SND_CurSong ;
9E07: 10 0B BPL $9E14 ;
9E09: AD 1C 06 LDA 061C ;
9E0C: A6 6A LDX <SND_Sq1Fine ;
9E0E: 20 54 9C JSR Warble ;
9E11: 8E 02 40 STX S_SQR1_C ; [NES] Audio -> Square 1 Fine tune
9E14: A9 7F LDA #$7F ;
9E16: 8D 01 40 STA S_SQR1_B ; [NES] Audio -> Square 1 Ramp control
9E19: AD 0C 06 LDA SND_SongPC_C ;
9E1C: D0 03 BNE $9E21 ;
9E1E: 4C 95 9E JMP $9E95 ;
9E21: CE 16 06 DEC 0616 ;
9E24: D0 52 BNE $9E78 ;
9E26: AC 0C 06 LDY SND_SongPC_C ;
9E29: EE 0C 06 INC SND_SongPC_C ;
9E2C: B1 66 LDA (SND_PtrA),Y ;
9E2E: F0 62 BEQ $9E92 ;
9E30: 10 38 BPL $9E6A ;
9E32: C9 F0 CMP #$F0 ;
9E34: F0 11 BEQ $9E47 ;
9E36: 90 1D BCC $9E55 ;
9E38: 38 SEC ;
9E39: E9 F0 SBC #$F0 ;
9E3B: 8D 1E 06 STA 061E ;
9E3E: AD 0C 06 LDA SND_SongPC_C ;
9E41: 8D 1F 06 STA 061F ;
9E44: 4C 26 9E JMP $9E26 ;
9E47: CE 1E 06 DEC 061E ;
9E4A: F0 06 BEQ $9E52 ;
9E4C: AD 1F 06 LDA 061F ;
9E4F: 8D 0C 06 STA SND_SongPC_C ;
9E52: 4C 26 9E JMP $9E26 ;
9E55: 20 E6 9E JSR GetNoteLen ;
9E58: 8D 15 06 STA 0615 ;
9E5B: A9 1F LDA #$1F ;
9E5D: 8D 08 40 STA S_TRI_A ; [NES] Audio -> Triangle Control
9E60: AC 0C 06 LDY SND_SongPC_C ;
9E63: EE 0C 06 INC SND_SongPC_C ;
9E66: B1 66 LDA (SND_PtrA),Y ;
9E68: F0 28 BEQ $9E92 ;
9E6A: 20 3F 9C JSR NoteOnTri ;
9E6D: A9 00 LDA #$00 ;
9E6F: 8D 1D 06 STA 061D ;
9E72: AE 15 06 LDX 0615 ;
9E75: 8E 16 06 STX 0616 ;
;
9E78: EE 1D 06 INC 061D ; Bump warble
9E7B: AD 1D 06 LDA 061D ; Get the warble count ...
9E7E: AE F0 05 LDX SND_TriFine ; .. and the current note frequency
9E81: 20 54 9C JSR Warble ; Warble the note frequency in X
9E84: 8E 0A 40 STX S_TRI_C ; Play the note on triangle voice [NES] Audio -> Triangle Frequence reg1
9E87: AD F1 05 LDA 05F1 ;
9E8A: 10 04 BPL $9E90 ;
9E8C: A9 1F LDA #$1F ;
9E8E: D0 02 BNE $9E92 ;
9E90: A9 FF LDA #$FF ;
9E92: 8D 08 40 STA S_TRI_A ; ?? intro music voice [NES] Audio -> Triangle Control
;
9E95: AD 09 06 LDA SND_CurSong ; Current song number
9E98: 29 91 AND #$91 ; 1001_0001 Does song have drums in it?
9E9A: F0 37 BEQ $9ED3 ; No ... skip drums
9E9C: CE 17 06 DEC 0617 ;
9E9F: D0 32 BNE $9ED3 ;
9EA1: AC 0D 06 LDY SND_SongPC_D ;
9EA4: EE 0D 06 INC SND_SongPC_D ;
9EA7: B1 66 LDA (SND_PtrA),Y ;
9EA9: D0 08 BNE $9EB3 ;
9EAB: AD F5 05 LDA SND_DrumRep ;
9EAE: 8D 0D 06 STA SND_SongPC_D ;
9EB1: D0 EE BNE $9EA1 ;
; Music drums
9EB3: 20 E0 9E JSR $9EE0 ;
9EB6: 8D 17 06 STA 0617 ;
9EB9: 8A TXA ;
9EBA: 29 3E AND #$3E ; 00111110
9EBC: 4A LSR A ; 00000011
9EBD: 4A LSR A ;
9EBE: 4A LSR A ;
9EBF: 4A LSR A ;
9EC0: A8 TAY ;
9EC1: B9 D4 9E LDA $9ED4,Y ;
9EC4: 8D 0C 40 STA S_NOI_A ;
9EC7: B9 D8 9E LDA $9ED8,Y ;
9ECA: 8D 0E 40 STA S_NOI_C ;
9ECD: B9 DC 9E LDA $9EDC,Y ;
9ED0: 8D 0F 40 STA S_NOI_D ;
9ED3: 60 RTS ;
; Four different drum notes. ?? seems to be the durration of the noise
; all at the same frequency. ?? First note is "off"
9ED4: 10 1C 1C 1C
9ED8: 00 03 0A 03
9EDC: 00 18 18 58
; abcdefg
; g->CAR
; bcdefgg
; cdefgga
; defggab
9EE0: AA TAX ;
9EE1: 6A ROR A ;
9EE2: 8A TXA ;
9EE3: 2A ROL A ;
9EE4: 2A ROL A ;
9EE5: 2A ROL A ;
;
GetNoteLen:
; Get the note duration indexed within the current song's
; set of durations.
9EE6: 29 07 AND #$07 ; Each duration-set has 8 entries
9EE8: 18 CLC ; Index into ...
9EE9: 6D F4 05 ADC 05F4 ; ... set defined for song
9EEC: A8 TAY ; Get ...
9EED: B9 D1 9F LDA NoteDelaySet,Y ; ... note duration
9EF0: 60 RTS ; Done
Get0NoteLen:
; Get the note duration indexed within the first
; set of durations.
9EF1: 29 07 AND #$07 ; Within set 0
9EF3: A8 TAY ; Get ...
9EF4: B9 D1 9F LDA NoteDelaySet,Y ; ... note duration
9EF7: 60 RTS ; Done
9EF8: CB 0E 0E 4C 6D 8C CD FF
Note Table
NoteTable:
; Note table (coarse/fine). Frequencies to the duty cycle are 1.79MHz/(N+1).
; Frequencies are divided down by 16. There may be some other small factor
; in the formula since large frequencies begin to show errors with expected
; frequencies. The notes in the table are mostly in order with a few notes
; left out and moved to the beginning or end.
;
9F00: 00 23 ; 3107.6 G7
9F02: 00 6A ; 1045.5 C6
9F04: 03 27 ; 138.4 C#3
9F06: 00 97 ; 736.0 F#5
9F08: 00 00 ; 0.0 R
9F0A: 02 F9 ; 146.8 D3
9F0C: 02 CF ; 155.3 D#3
9F0E: 02 A6 ; 164.7 E3
9F10: 02 80 ; 174.5 F3
9F12: 02 5C ; 184.9 F#3
9F14: 02 3A ; 195.9 G3
9F16: 02 1A ; 207.5 G#3
9F18: 01 FC ; 219.7 A3
9F1A: 01 DF ; 233.0 B-3
9F1C: 01 C4 ; 246.9 B3
9F1E: 01 AB ; 261.3 C4
9F20: 01 93 ; 276.9 C#4
9F22: 01 7C ; 293.6 D4
9F24: 01 67 ; 310.7 E-4
9F26: 01 53 ; 329.0 E4
9F28: 01 40 ; 348.5 F4
9F2A: 01 2E ; 369.2 F#4
9F2C: 01 1D ; 391.1 G4
9F2E: 01 0D ; 414.3 G#4
9F30: 00 FE ; 438.7 A4
9F32: 00 EF ; 466.1 B-4
9F34: 00 E2 ; 492.8 B4
9F36: 00 D5 ; 522.7 C5
9F38: 00 C9 ; 553.8 C#5
9F3A: 00 BE ; 585.7 D5
9F3C: 00 B3 ; 621.5 E-5
9F3E: 00 A9 ; 658.0 E5
9F40: 00 A0 ; 694.8 F5
9F42: 00 8E ; 782.3 G5
9F44: 00 86 ; 828.7 G#5
9F46: 00 77 ; 932.2 B-5
9F48: 00 7E ; 880.9 A5
9F4A: 00 71 ; 981.3 B5
9F4C: 00 54 ; 1316.1 E6
9F4E: 00 64 ; 1107.6 C#6
9F50: 00 5F ; 1165.3 D6
9F52: 00 59 ; 1243.0 E-6
9F54: 00 50 ; 1381.1 F6
9F56: 00 47 ; 1553.8 G6
9F58: 00 43 ; 1645.2 G#6
9F5A: 00 3F ; 1748.0 A6
9F5C: 00 38 ; 1962.7 B6
9F5E: 00 32 ; 2193.6 C7
9F60: 00 21 ; 3290.4 G#7
9F62: 05 4D ; 82.3 E2
9F64: 05 01 ; 87.2 F2
9F66: 04 B9 ; 92.4 F#2
9F68: 04 35 ; 103.7 G#2
9F6A: 03 F8 ; 110.0 A2
9F6C: 03 BF ; 116.5 B-2
9F6E: 03 89 ; 123.4 B2
9F70: 03 57 ; 130.6 C3
9F72: AD 19 06 LDA 0619 ;
9F75: A9 20 LDA #$20 ;
9F77: A2 82 LDX #$82 ;
9F79: A0 7F LDY #$7F ;
9F7B: 60 RTS ;
9F7C: AD 19 06 LDA 0619 ;
9F7F: 10 07 BPL $9F88 ;
9F81: B9 92 9F LDA $9F92,Y ;
9F84: 29 0F AND #$0F ;
9F86: D0 07 BNE $9F8F ;
9F88: B9 92 9F LDA $9F92,Y ;
9F8B: 4A LSR A ;
9F8C: 4A LSR A ;
9F8D: 4A LSR A ;
9F8E: 4A LSR A ;
9F8F: 09 90 ORA #$90 ;
9F91: 60 RTS ;
; ?? Control values for square-voice (controlls durration -- short values create short notes)
9F92: 04 24 24 34 34 35 35 35 45 45 46 46 46 46 46 46
9FA2: 46 46 57 57 57 57 68 68 68 68 79 79 79 68 68
9FB1: 57 47 67 87 A8 B9 9A 8A 5A 9B
9FBB: 8B FB F9 9D 6E 3F
9FC1: 1A 1A 1C 1D 1D 1E 1E 1F 1F 1E 1A 19 16 13 11 11
RESET:
;
; Configure the MMC1 and jump to E440 (Bank 7) for startup.
;
BF50: 78 SEI ; Disable interrupts
BF51: D8 CLD ; Clear decimal flag
BF52: A9 00 LDA #$00 ; Clear the PPU control register ...
BF54: 8D 00 20 STA P_CNTRL_1 ; ... truns off NMIs
BF57: A2 FF LDX #$FF ; Stack to ...
BF59: 9A TXS ; ... 01FF
BF5A: AD 02 20 LDA P_STATUS ; Wait ...
BF5D: 29 80 AND #$80 ; ... for ...
BF5F: F0 F9 BEQ $BF5A ; ... VBLANK
BF61: AD 02 20 LDA P_STATUS ; Wait ...
BF64: 29 80 AND #$80 ; ... for another ...
BF66: F0 F9 BEQ $BF61 ; ... VBLANK (1st might have been a leftover flag)
BF68: 09 FF ORA #$FF ; Reset ...
BF6A: 8D 00 80 STA $8000 ; ... ...
BF6D: 8D 00 A0 STA $A000 ; ... all ...
BF70: 8D 00 C0 STA $C000 ; ... four ...
BF73: 8D 00 E0 STA $E000 ; ... MMC1 registers
BF76: A9 0F LDA #$0F ; Set MMC control to 8K CHR ROM, fixed/bank 16K PRG pages, ...
BF78: 20 98 BF JSR MMC_Control ; ... and horizontal mirroring (vertical scrolling)
BF7B: A9 00 LDA #$00 ; Set MMC reg1 VROM bank
BF7D: 8D 00 A0 STA $A000 ; The cartridge doesn't ...
BF80: 4A LSR A ; ... swap VROM pages. ...
BF81: 8D 00 A0 STA $A000 ; ... Just ...
BF84: 4A LSR A ; ... set ...
BF85: 8D 00 A0 STA $A000 ; ... to ...
BF88: 4A LSR A ; ...
BF89: 8D 00 A0 STA $A000 ; ...
BF8C: 4A LSR A ; ...
BF8D: 8D 00 A0 STA $A000 ; ... --00000
BF90: A9 07 LDA #$07 ; Interesting! Put bank 7 ...
BF92: 20 AC BF JSR MMC_Bank ; ... in the low ROM bank
BF95: 4C 40 E4 JMP $E440 ; Start of game
; MMC1 Info
; R0 - Control ***CPPMM
; C CHR ROM bank mode. Zelda uses 0: 8KB at a time
; PP Program ROM switch mode. Zelda uses 3: 16K fixed, 16K switched banks
; MM Name table mirroring. Zelda uses 2 or 3: vertical or horizontal
; R1 - CHR bank size ***CCCCC
; Ignored in Zelda since R0.C is 0
; R2 - CHR bank select ***CCCCC
; Ignored in Zelda since R0.C is 0
; R3 - PRG bank select ***RPPPP
; R PRG RAM enabled. Zelda sends 0, but battery-backed RAM is always enabled.
; PPPP bank select. Zelda switches banks 0-6.
MMC Control
MMC_Control:
; Set the MMC Control register (0) to value in A
BF98: 8D 00 80 STA $8000 ; MMC Register 0 (control): --edcba ...
BF9B: 4A LSR A ; ... mirroring
BF9C: 8D 00 80 STA $8000 ; ... mirroring
BF9F: 4A LSR A ; ... switch: c=0 high ROM, C=1 low ROM
BFA0: 8D 00 80 STA $8000 ; ... size: d=0 32K (full), D=1 16K (half)
BFA3: 4A LSR A ; ... chrrom mode: e=0 8K banks, B=1 4K banks
BFA4: 8D 00 80 STA $8000 ; The MMC is write-trigger (write to ROM ...
BFA7: 4A LSR A ; .. has no affect anyway).
BFA8: 8D 00 80 STA $8000 ; Bits are written from LSB to MSB ...
BFAB: 60 RTS ; ... only 5 bits
MMC Bank
MMC_Bank:
; Set the MMC Bank register (3) to value in A
BFAC: 8D 00 E0 STA $E000 ; MMC Register 3 (ROM page switching): --edcba ...
BFAF: 4A LSR A ; ...
BFB0: 8D 00 E0 STA $E000 ; ... Write the ...
BFB3: 4A LSR A ; ... switching ...
BFB4: 8D 00 E0 STA $E000 ; ... page ...
BFB7: 4A LSR A ; ... number
BFB8: 8D 00 E0 STA $E000 ; The MMC is write-trigger (write to ROM ...
BFBB: 4A LSR A ; .. has no affect anyway).
BFBC: 8D 00 E0 STA $E000 ; Bits are written from LSB to MSB ...
BFBF: 60 RTS ; ... only 5 bits
BFC0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
BFD0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
BFE0: FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
BFF0: FF FF FF FF FF FF FF FF FF FF
Vectors
BFFA: 84 E4 ; NMI to E484
BFFC: 50 BF ; RESET to BF50
BFFE: F0 BF ; IRQ to BFF0 (this bank should never be at end)