;----------------------------------------------------------------------------; ; V1.4 Compact(ish) Version.... OK, so it's a little verbose, HUMBUG ! ; ; ; ; LOADING MUSIC IV ,THE REMIX! ; ; ; ; Orchestration, blood, sweat & tears by Jonathan Dunn ; ; ; ; Oh wow (paroxism!) programming by Paul Hughes ; ; ; ; (c) Copyright Ocean Software / Imagine Software / Paul Hughes 1988 ; ;----------------------------------------------------------------------------; ORG $B43E DRIVER.START EQU . ; ; TUNE - Initialises a tune, entered with tune number in X ; TUNE LDY #0 LDA #0 CLR_VAR STA VAR_START,Y ; Reset all variables to zero INY CPY #VAR_END-VAR_START BNE CLR_VAR LDY #$16 CLRSID LDA #8 ; Set SID test bit so there's no STA SID,Y LDA #0 ; grotty clicking STA SID,Y DEY BPL CLRSID STY MODEBYTE_A ; Reset any non-zero variables ($FF) STY MODEBYTE_B STY MODEBYTE_C LDY #1 STY DURCOUNT.A ; $01 STY DURCOUNT.B STY DURCOUNT.C STY DURATIONON_A STY DURATIONON_B STY DURATIONON_C STY MFL_A STY MFL_B STY MFL_C LDA TUNETABLE.A.L,X ; Initialise the addresses STA PC.A LDA TUNETABLE.A.H,X ; of the tunes into each STA PC.A+1 LDA TUNETABLE.B.L,X ; individual program counter STA PC.B LDA TUNETABLE.B.H,X STA PC.B+1 LDA TUNETABLE.C.L,X STA PC.C LDA TUNETABLE.C.H,X STA PC.C+1 LDA #$0F ; Volume on STA $D418 RTS ; Finito ; ; REFRESH - Called by interrupt, plays the music ; REFRESH LDA MFL_A ; Check if channel A is playing BEQ NOMUSIC_A JSR MUSICA ; Play it NOMUSIC_A LDA MFL_B ; Check if channel B is playing BEQ NOMUSIC_B JSR MUSICB ; Play it NOMUSIC_B LDA MFL_C ; Check if channel C is playing BEQ NOMUSIC_C JSR MUSICC ; Play it NOMUSIC_C LDA #READ_C ; Set up the channel C indirect STA MOD_1+1 ; address for the arpeggio LDA #2 ; Start modulation from channel C STA VOICE_NUM LDX VOICE_NUM NEXT_VOICE LDA drumFLAG,X ; If a drum is playing don't do any BNE NOPUL_A ; modulators LDA ARPFLAG_A,X ; Is the arpeggio active on this BEQ NOAR_A ; Voice JSR DO_ARP_A ; Yes, process the arpeggio NOAR_A LDA PULSEFLAG_A,X ; Is the pulse width active on this BEQ NOPUL_A ; voice JSR DOPULSE_A ; Yes, process the pulse width NOPUL_A DEC MOD_1+1 ; Modify the indirect arpeggio address DEC MOD_1+1 DEX STX VOICE_NUM ; Do the next voice BPL NEXT_VOICE NOPUL_C JMP DRUMMER ; Process DunnyDrums (tm) ; ; MUSICTEST - Tests to see if music is playing ; MUSICTEST LDA MFL_A ; ORA all the flags together ORA MFL_B ; if zero is the result then the ORA MFL_C ; tune is complete RTS ; ; MUSICA - Handles all music to channel A ; MUSICA DEC DURCOUNT.A ; Note duration over ? BEQ READBYTE.A ; Yup, get a new byte DEC RELEASE_A ; Has the note release finished BNE NO_RELEASE_A ; No, modulate channel A LDA EFFECTFLAG_A ; Effect mode active ? BEQ NOEFFECT_A ; No LDX REAL_NOTE_A ; Get the real unmauled note LDA LOWFREQ,X STA FREQ.LOW.A ; expand out into a frequency LDA HIFREQ,X STA FREQ.HI.A NOEFFECT_A LDA MODEBYTE_A ; Should the gate get set AND #1 BEQ NO_RELEASE_A ; No way jose LDA GATEOFF.A ; Set the gate bit STA $D404 NO_RELEASE_A LDX #0 JMP MODULATE ; Modulate channel A READBYTE.A LDA SUSTAIN_A ; Reset the note's release period STA RELEASE_A LDY #0 ; Shut down any drum on this channel STY drumFLAG+0 LDA (PC.A),Y ; Get next byte from the data BPL NOCONTROL_A TAX LDA JUMPVECL.A-128,X ; the control code vectors STA JUMPVEC.A+1 LDA JUMPVECH.A-128,X STA JUMPVEC.A+2 INY JUMPVEC.A JMP $FFFF ; Self modified jump address NOCONTROL_A CMP #REST ; Is it a rest BNE NOREST_A JMP REST_A ; Yes process a rest NOREST_A ADD TRANSVAL_A ; Add any transpose value to the base STA NOTE_A ; note, and store it STA REAL_NOTE_A LDX EFFECTFLAG_A ; Is effect mode enabled BEQ NOFX_A ; No, thank God ! LDA MODEBYTE_A ; Is it an emulated plucked note (!) AND #8 BNE PLUCK ; Yessum boss LDA EFFECT_NOTE_A ; Use the effect note for the freq JMP NOFX_A PLUCK LDA REAL_NOTE_A ; Otherwise get the base note and ADD EFFECT_NOTE_A ; add the effect note on NOFX_A TAX ; Expand the note into a frequency LDA LOWFREQ,X STA FREQ.LOW.A ; Maulable frequencys LDA HIFREQ,X STA FREQ.HI.A DOREST_A LDA PULSEFLAG_A ; Pulse mode enabled ? BEQ NOPULSE_A ; No LDA MODEBYTE_A ; Should the pulse be retriggered AND #2 BEQ NOPULSE_A ; No LDA PWL2_A ; Reset all pulse width variables STA PWL_A LDA PWH2_A STA PWH_A LDA #0 STA PULSEDIR_A ; Pulse direction LDA CUP2_A ; Counts up STA CUP_A LDA CDOWN2_A ; Counts down STA CDOWN_A NOPULSE_A LDA VIBFLAG_A ; Is the vibrato active BEQ NOV_A ; No LDA VIBDELAY2_A ; Reset the vibrato delay STA VIBDELAY_A LDA VIBDEPTH_A ; Get the vibrato depth LSR STA VIBDEPTH2_A ; Divide it by 2 for other direction LDA #0 ; Reset the Vib direction variable STA VIB_DIR_A NOV_A LDA MODEBYTE_A ; Should the gate get set AND #1 BEQ REST_A ; No LDA GATE.A ; Set the gate bit STA $D404 REST_A LDA DURATIONON_A ; Automatic duration mode ? BNE PICK_UP_A ; No LDA DURATION_A ; Reset the note duration STA DURCOUNT.A LDX GAPFLAG_A ; Gap mode active BEQ NOGAP2_A ; no SUB SUSTAIN_A ; Subtact the sustain from the STA RELEASE_A ; duration to give a release value NOGAP2_A INC PC.A ; Increment the music PC BNE COMEOUT.A INC PC.A+1 COMEOUT.A JMP NO_RELEASE_A ; Do the modulators for channel A PICK_UP_A INY ; Manual duration mode LDA (PC.A),Y STA DURCOUNT.A ; Get the duration of the note LDX GAPFLAG_A ; Gap mode active BEQ NOGAP_A ; No SUB SUSTAIN_A ; Subtact the sustain from the STA RELEASE_A ; duration to give a release value NOGAP_A LDA PC.A ; Add 2 to the music PC ADD #2 STA PC.A BCC SKIPIT_A INC PC.A+1 SKIPIT_A JMP NO_RELEASE_A ; Do the modulators for channel A ; ; MODULATE - Handles all modulation requirements for Channels A,B & C ; MODULATE LDA ARPFLAG_A,X ; Is arpeggio processing BEQ NOARP_A RTS ; Yes, don't bother with other stuff NOARP_A LDA PORTFLAG.A,X ; Pitch bender on ? BEQ NOBEND.A ; No JSR DO.BEND.A ; Set up a pitch bend JMP NOVIB_A NOBEND.A LDA VIBFLAG_A,X ; Is the vibrato active ? BEQ NOVIB_A ; No JSR DOVIB_A ; Process the vibrato NOVIB_A JMP DUMP ; Dump the final frequency to SID ; ; DO.BEND.A - Processes all pitchbending to all channels ; DO.BEND.A BMI SET.BEND.A ; Bendflag minus = init bend DEC BENDLENGTH.A,X ; See if bend complete BEQ BEND.DONE.A ; Exit if so PROC.BEND.A LDA BEND.DIR.A,X ; Otherwise get bend direction BMI BEND.DOWN.A ; Minus = downwards bend LDA FREQ.LOW.A,X ; Get frequency and add the bend ADD BENDSTEP.A,X STA FREQ.LOW.A,X ; additive BCC NOCHANGE1.A INC FREQ.HI.A,X NOCHANGE1.A RTS ; Exit BEND.DOWN.A LDA FREQ.LOW.A,X ; Get frequency and subtract the bend SUB BENDSTEP.A,X STA FREQ.LOW.A,X ; subtractive BCS NOCHANGE2.A DEC FREQ.HI.A,X NOCHANGE2.A RTS ; Exit BEND.DONE.A LDA #0 ; Terminate the pitchbend STA PORTFLAG.A,X RTS ; Exit SET.BEND.A LDA #1 ; Do bend but don't re-initialise STA PORTFLAG.A,X LDY WORD_OFFSET,X LDA BEND.DIR.A,X ; Get the bend direction BMI SET.DOWN.A LDA FREQ.LOW.A,X ; Subract the offset from the base SUB OFFSET.A,Y STA FREQ.LOW.A,X ; frequency (bend up to a note) LDA FREQ.HI.A,X SBC OFFSET.A+1,Y STA FREQ.HI.A,X JMP PROC.BEND.A ; Process the bend SET.DOWN.A LDA FREQ.LOW.A,X ; Add the offset from the base ADD OFFSET.A,Y STA FREQ.LOW.A,X ; frequency (bend down to a note) LDA FREQ.HI.A,X ADC OFFSET.A+1,Y STA FREQ.HI.A,X JMP PROC.BEND.A ; Process the bend ; ; DOVIB_A - Suprisingly enuf this handles the vibrato ; DOVIB_A LDA VIBDELAY_A,X ; Time to activate the vibrato BEQ DELAYOFF_A DEC VIBDELAY_A,X ; No, not yet RTS DELAYOFF_A DEC VIBDEPTH2_A,X ; Decrement the vib direction counter BEQ CHANGEDIR_A ; Zero = change the direction LDA VIB_DIR_A,X ; Get the vibrato direction BNE VIB_DOWN_A LDA FREQ.LOW.A,X ; Get the base frequency ADD VIBRATE_A,X ; Add the vibrato add rate STA FREQ.LOW.A,X BCC NOADD_A INC FREQ.HI.A,X NOADD_A RTS ; Exit VIB_DOWN_A LDA FREQ.LOW.A,X ; Get the base frequency SUB VIBRATE_A,X ; Subtract the vibrato subtract rate STA FREQ.LOW.A,X BCS NOADD2_A DEC FREQ.HI.A,X NOADD2_A RTS ; Exit CHANGEDIR_A LDA VIB_DIR_A,X ; Flip the vibrato direction EOR #1 STA VIB_DIR_A,X LDA VIBDEPTH_A,X ; Reset the depth counter STA VIBDEPTH2_A,X JMP DELAYOFF_A ; Back to processing the vibrato ; ; TRANS_A - Constant transpose value initialise ; TRANS_A LDA (PC.A),Y ; Pull in the transpose value STA TRANSVAL_A ; Store it LDA #2 JMP ADD_PC_A ; Bump the PC ; ; TRANS_B - Constant transpose value initialise ; TRANS_B ; Ditto LDA (PC.B),Y STA TRANSVAL_B LDA #2 JMP ADD_PC_B ; ; TRANS_C - Constant transpose value initialise ; TRANS_C ; Ditto LDA (PC.C),Y STA TRANSVAL_C LDA #2 JMP ADD_PC_C ; ; CT_A - Call a routine transposed ; CT_A LDA (PC.A),Y ; Pull in the transpose value STA TRANSVAL_A ; Store INC PC.A ; Bump the PC BNE SKPCT_A INC PC.A+1 SKPCT_A JMP CALL.A ; Cheap n nasty go to the CALL routine ; ; CT_B - Call a routine transposed ; CT_B ; Ditto LDA (PC.B),Y STA TRANSVAL_B INC PC.B BNE SKPCT_B INC PC.B+1 SKPCT_B JMP CALL.B ; ; CT_C - Call a routine transposed ; CT_C ; Ditto LDA (PC.C),Y STA TRANSVAL_C INC PC.C BNE SKPCT_C INC PC.C+1 SKPCT_C JMP CALL.C ; ; LENGTH_A - Determines the duration of the notes ; LENGTH_A LDA (PC.A),Y ; Pull in the constant duration value STA DURATION_A LDA #0 STA DURATIONON_A ; Signal this mode LDA #2 JMP ADD_PC_A ; Bump the PC ; ; DO_ARP_A - Processes the arpeggiator on A,B & C ; DO_ARP_A DEC NEXTDELAY_A,X ; Time to read the next byte yet ? BEQ GO_ARP_A RTS ; No GO_ARP_A LDA NEXTDELAY2_A,X ; Reset the read period STA NEXTDELAY_A,X LDY ARPEGIND_A,X ; Get the index within the table MOD_1 LDA (READ_A),Y ; plus the indirect address LDY SID_OFFSETS,X ADD NOTE_A,X ; add this value to the base note TAX LDA LOWFREQ,X ; Expand out into a frequency STA $D400,Y LDA HIFREQ,X STA $D401,Y LDX VOICE_NUM INC ARPEGIND_A,X ; Increment the index within the table LDA ARPEGIND_A,X CMP ARPEGLEN_A,X ; Reached the end of the table yet ? BNE RESETARP_A LDA #2 ; Yes reset the index to 2 STA ARPEGIND_A,X RESETARP_A RTS ; Exit ; ; DOPULSE_A - Process pwm on A,B & C ; DOPULSE_A LDA PULSEDIR_A,X ; Get the pulse direction BNE PULSEDOWN_A PULSEUP_A DEC CUP_A,X ; Decrement the pulse up counter BEQ NEWDIR_A ; zero, do the other direction LDY SID_OFFSETS,X LDA PWL_A,X ; Add the rate up to the ADD RATEUP_A,X STA PWL_A,X ; pulse width STA $D402,Y LDA PWH_A,X ADC #0 STA PWH_A,X STA $D403,Y RTS ; Exit PULSEDOWN_A DEC CDOWN_A,X ; Decrement the pulse down counter BEQ NEWDIR2_A ; Zero, do the other direction LDY SID_OFFSETS,X LDA PWL_A,X ; Subtract the pulse down counter SUB RATEUP_A,X STA PWL_A,X ; to the pulse width STA $D402,Y LDA PWH_A,X SBC #0 STA PWH_A,X STA $D403,Y RTS ; Exit NEWDIR_A LDA CUP2_A,X ; Reset the count up STA CUP_A,X LDA #1 ; Set the new direction STA PULSEDIR_A,X JMP PULSEDOWN_A ; Process it NEWDIR2_A LDA CDOWN2_A,X ; Reset the count down STA CDOWN_A,X LDA #0 ; Set the new direction STA PULSEDIR_A,X JMP PULSEUP_A ; Process it ; ; DUMP - Dumps frequencies to SID channel A,B & C ; DUMP LDY SID_OFFSETS,X LDA FREQ.LOW.A,X ; Get the final mauled frequency STA $D400,Y LDA FREQ.HI.A,X ; and send it to SID STA $D401,Y RTS ; ; ADD_PC_A - Adds a value in A to PC.A ; ADD_PC_A ADD PC.A ; Add PC to the value in the STA PC.A BCC SKP_A ; accumulator INC PC.A+1 SKP_A JMP READBYTE.A ; and back to the sequencer ; ; DUR_ON_A - Acctivates manual duration mode ; DUR_ON_A LDA #1 ; Set the manual duration flag STA DURATIONON_A INC PC.A ; Bump PC BNE SKIP_A INC PC.A+1 SKIP_A JMP READBYTE.A ; Back to the sequencer ; ; PULSEON_A - Switches pulse width modulation on ! ; PULSEON_A LDA #0 STA FROM+1 ; Zero FROM+1 LDA (PC.A),Y ; Get the pulse patch number ASL:ASL ADD (PC.A),Y ; *5 ADC #PWM_START STA FROM LDA FROM+1 ADC ^PWM_START ; plus PWM table base address STA FROM+1 DEY ; Y=0 LDA (FROM),Y STA RATEUP_A ; Get the rate on the upward sweep INY ; Y=1 STY PULSEFLAG_A ; Pulse enabled STY PULSEDIR_A ; Set the initial direction LDA (FROM),Y STA CUP_A ; Get the additive count STA CUP2_A INY LDA (FROM),Y STA CDOWN_A ; Get the subtractive count STA CDOWN2_A INY ; Y=2 LDA (FROM),Y ; Initial pulse width LOW STA PWL2_A INY ; Y=3 LDA (FROM),Y STA PWH2_A ; Initial pulse width HIGH LDA #2 ; Bump PC JMP ADD_PC_A ; ; MUSICB - Handles all music to channel B ; MUSICB DEC DURCOUNT.B BEQ READBYTE.B DEC RELEASE_B BNE NO_RELEASE_B LDA EFFECTFLAG_B BEQ NOEFFECT_B LDX REAL_NOTE_B LDA LOWFREQ,X STA FREQ.LOW.B LDA HIFREQ,X STA FREQ.HI.B NOEFFECT_B LDA MODEBYTE_B AND #1 BEQ NO_RELEASE_B LDA GATEOFF.B STA $D404+7 NO_RELEASE_B LDX #1 JMP MODULATE ; Modulate channel B READBYTE.B LDA SUSTAIN_B STA RELEASE_B LDY #0 STY drumFLAG+1 LDA (PC.B),Y BPL NOCONTROL_B TAX LDA JUMPVECL.B-128,X STA JUMPVEC.B+1 LDA JUMPVECH.B-128,X STA JUMPVEC.B+2 INY JUMPVEC.B JMP $FFFF NOCONTROL_B CMP #REST BNE NOREST_B JMP REST_B NOREST_B ADD TRANSVAL_B STA NOTE_B STA REAL_NOTE_B LDX EFFECTFLAG_B BEQ NOFX_B LDA MODEBYTE_B AND #8 BNE PLUCK_B LDA EFFECT_NOTE_A JMP NOFX_B PLUCK_B LDA REAL_NOTE_B ADD EFFECT_NOTE_B NOFX_B TAX LDA LOWFREQ,X STA FREQ.LOW.B ; Maulable frequencys LDA HIFREQ,X STA FREQ.HI.B LDA PULSEFLAG_B BEQ NOPULSE_B LDA MODEBYTE_B AND #2 BEQ NOPULSE_B LDA PWL2_B STA PWL_B LDA PWH2_B STA PWH_B LDA #0 STA PULSEDIR_B LDA CUP2_B STA CUP_B LDA CDOWN2_B STA CDOWN_B NOPULSE_B LDA VIBFLAG_B BEQ NOV_B LDA VIBDELAY2_B STA VIBDELAY_B LDA VIBDEPTH_B LSR STA VIBDEPTH2_B LDA #0 STA VIB_DIR_B NOV_B LDA MODEBYTE_B AND #1 BEQ REST_B LDA GATE.B STA $D404+7 REST_B LDA DURATIONON_B BNE PICK_UP_B LDA DURATION_B STA DURCOUNT.B LDX GAPFLAG_B BEQ NOGAP2_B SUB SUSTAIN_B STA RELEASE_B NOGAP2_B INC PC.B BNE COMEOUT.B INC PC.B+1 COMEOUT.B JMP NO_RELEASE_B PICK_UP_B INY LDA (PC.B),Y STA DURCOUNT.B LDX GAPFLAG_B BEQ NOGAP_B SUB SUSTAIN_B STA RELEASE_B NOGAP_B LDA PC.B ADD #2 STA PC.B BCC SKIPIT_B INC PC.B+1 SKIPIT_B JMP NO_RELEASE_B ; ; ADD_PC_B - Adds a value in A to PC.B ; ADD_PC_B ADD PC.B STA PC.B BCC SKP_B INC PC.B+1 SKP_B JMP READBYTE.B ; ; LENGTH_B - Determines the duration of the notes ; LENGTH_B LDA (PC.B),Y STA DURATION_B LDA #0 STA DURATIONON_B LDA #2 JMP ADD_PC_B ; ; DUR_ON_B - Acctivates manual duration mode ; DUR_ON_B LDA #1 STA DURATIONON_B INC PC.B BNE SKIP_B INC PC.B+1 SKIP_B JMP READBYTE.B ; ; PULSEON_B - Switches pulse width modulation on ! ; PULSEON_B LDA #0 STA FROM+1 LDA (PC.B),Y ASL:ASL ADD (PC.B),Y ADC #PWM_START STA FROM LDA FROM+1 ADC ^PWM_START STA FROM+1 DEY LDA (FROM),Y STA RATEUP_B INY STY PULSEFLAG_B STY PULSEDIR_B LDA (FROM),Y STA CUP_B STA CUP2_B INY LDA (FROM),Y STA CDOWN_B STA CDOWN2_B INY LDA (FROM),Y STA PWL2_B INY LDA (FROM),Y STA PWH2_B LDA #2 JMP ADD_PC_B ; ; MUSICC - Handles all music to channel C ; MUSICC DEC DURCOUNT.C BEQ READBYTE.C DEC RELEASE_C BNE NO_RELEASE_C LDA EFFECTFLAG_C BEQ NOEFFECT_C LDX REAL_NOTE_C LDA LOWFREQ,X STA FREQ.LOW.C LDA HIFREQ,X STA FREQ.HI.C NOEFFECT_C LDA MODEBYTE_C AND #1 BEQ NO_RELEASE_C LDA GATEOFF.C STA $D404+14 NO_RELEASE_C LDA drumFLAG+2 ; No modulation during drums BEQ DO_MODULATE RTS DO_MODULATE LDX #2 JMP MODULATE ; Modulate channel C READBYTE.C LDA SUSTAIN_C STA RELEASE_C LDA drumFLAG+2 BEQ DONTOFF_C LDA #0 STA drumFLAG+2 STA DRUMx+2 STA $D404+14 LDA SUSTEMP+2 STA $D406+14 LDA ADTEMP+2 STA $D405+14 DONTOFF_C LDY #0 LDA (PC.C),Y BPL NOCONTROL_C ; Found a control byte TAX LDA JUMPVECL.C-128,X STA JUMPVEC.C+1 LDA JUMPVECH.C-128,X STA JUMPVEC.C+2 INY JUMPVEC.C JMP $FFFF NOCONTROL_C CMP #REST BNE NOREST_C JMP REST_C NOREST_C ADD TRANSVAL_C STA NOTE_C STA REAL_NOTE_C LDX EFFECTFLAG_C BEQ NOFX_C LDA MODEBYTE_C AND #8 BNE PLUCK_C LDA EFFECT_NOTE_C JMP NOFX_C PLUCK_C LDA REAL_NOTE_C ADD EFFECT_NOTE_C NOFX_C TAX LDA LOWFREQ,X STA FREQ.LOW.C ; Maulable frequencys LDA HIFREQ,X STA FREQ.HI.C DOREST_C LDA PULSEFLAG_C BEQ NOPULSE_C LDA MODEBYTE_C AND #2 BEQ NOPULSE_C LDA PWL2_C STA PWL_C LDA PWH2_C STA PWH_C LDA #0 STA PULSEDIR_C LDA CUP2_C STA CUP_C LDA CDOWN2_C STA CDOWN_C NOPULSE_C LDA VIBFLAG_C BEQ NOV_C LDA VIBDELAY2_C STA VIBDELAY_C LDA VIBDEPTH_C LSR STA VIBDEPTH2_C LDA #0 STA VIB_DIR_C NOV_C LDA MODEBYTE_C AND #1 BEQ REST_C LDA GATE.C STA $D404+14 REST_C LDA DURATIONON_C BNE PICK_UP_C LDA DURATION_C STA DURCOUNT.C LDX GAPFLAG_C BEQ NOGAP2_C SUB SUSTAIN_C STA RELEASE_C NOGAP2_C INC PC.C BNE COMEOUT.C INC PC.C+1 COMEOUT.C JMP NO_RELEASE_C PICK_UP_C INY LDA (PC.C),Y STA DURCOUNT.C LDX GAPFLAG_C BEQ NOGAP_C SUB SUSTAIN_C STA RELEASE_C NOGAP_C LDA PC.C ADD #2 STA PC.C BCC SKIPIT_C INC PC.C+1 SKIPIT_C JMP NO_RELEASE_C ; ; LENGTH_C - Determines the duration of the notes ; LENGTH_C LDA (PC.C),Y STA DURATION_C LDA #0 STA DURATIONON_C LDA #2 JMP ADD_PC_C ; ; DUR_ON_C - Acctivates manual duration mode ; DUR_ON_C LDA #1 STA DURATIONON_C INC PC.C BNE SKIP_C INC PC.C+1 SKIP_C JMP READBYTE.C ; ; ADD_PC_C - Adds a value in A to PC.C ; ADD_PC_C ADD PC.C STA PC.C BCC SKP_C INC PC.C+1 SKP_C JMP READBYTE.C ; ; PULSEON_C - Switches pulse width modulation on ! ; PULSEON_C LDA #0 STA FROM+1 LDA (PC.C),Y ASL:ASL ADD (PC.C),Y ADC #PWM_START STA FROM LDA FROM+1 ADC ^PWM_START STA FROM+1 DEY LDA (FROM),Y STA RATEUP_C INY STY PULSEFLAG_C STY PULSEDIR_C LDA (FROM),Y STA CUP_C STA CUP2_C INY LDA (FROM),Y STA CDOWN_C STA CDOWN2_C INY LDA (FROM),Y STA PWL2_C INY LDA (FROM),Y STA PWH2_C LDA #2 JMP ADD_PC_C ; ; Music control routines follow ...... ; ; ; JUMP.A - Jumps to a new sequence of notes ; JUMP.A LDA (PC.A),Y STA TEMP.PC ; Preserve the LOW byte new address INY LDA (PC.A),Y STA PC.A+1 ; New high byte into PC+1 LDA TEMP.PC STA PC.A ; Low byte in PC JMP READBYTE.A ; Back to sequencer ; ; CALL.A - Same as JSR, goes to a new sequence and returns on finding a RET ; CALL.A LDX SP.A ; Stack pointer, channel A LDA (PC.A),Y STA TEMP.PC ; TEMP.PC contains CALL address INY LDA (PC.A),Y STA TEMP.PC+1 LDA PC.A ADD #3 STA STACK.A.L,X ; Preserve current PC low byte LDA PC.A+1 ADC #0 STA STACK.A.H,X ; Preserve current PC high byte LDA TEMP.PC ; Set PC to CALL address STA PC.A LDA TEMP.PC+1 STA PC.A+1 INC SP.A ; Increment channel A stack pointer JMP READBYTE.A ; ; RET.A - Returns the last stacked PC value ; RET.A DEC SP.A ; Decrement channel A stack pointer LDX SP.A LDA STACK.A.L,X ; Retrieve Program counter low byte STA PC.A LDA STACK.A.H,X ; Retrieve Program counter high byte STA PC.A+1 LDA #0 STA TRANSVAL_A ; Reset the transpose value JMP READBYTE.A ; ; FOR.HANDLE.A - Handles the stacking of FOR instructions ; FOR.HANDLE.A LDX SP.A LDA (PC.A),Y STA FOR.COUNTS.A,X ; Store number of channel A FOR loops LDA PC.A ; Bump PC, and stack it's new value ADD #2 STA PC.A STA STACK.A.L,X BCC NOCARRY.A INC PC.A+1 NOCARRY.A LDA PC.A+1 STA STACK.A.H,X INC SP.A ; Bump channel A stack pointer JMP READBYTE.A ; ; NEXT.HANDLE.A - Handles unstacking PC and decrementing the FOR counters ; NEXT.HANDLE.A LDX SP.A ; SP.A only gets stored in LAST.NEXT DEX ; to preserve the FOR address DEC FOR.COUNTS.A,X BEQ LAST.NEXT.A LDA STACK.A.L,X ; Get back old for address STA PC.A LDA STACK.A.H,X STA PC.A+1 JMP READBYTE.A LAST.NEXT.A STX SP.A ; Decremented SP.A is now stored INC PC.A BNE NOCARRY2.A INC PC.A+1 NOCARRY2.A JMP READBYTE.A ; Back to sequencer ; ; JUMP.B - Jumps to a new sequence of notes ; JUMP.B ; Ditto LDA (PC.B),Y STA TEMP.PC INY LDA (PC.B),Y STA PC.B+1 LDA TEMP.PC STA PC.B JMP READBYTE.B ; ; CALL.B - Same as JSR, goes to a new sequence and returns on finding a RET ; CALL.B LDX SP.B ; Ditto LDA (PC.B),Y STA TEMP.PC INY LDA (PC.B),Y STA TEMP.PC+1 LDA PC.B ADD #3 STA STACK.B.L,X LDA PC.B+1 ADC #0 STA STACK.B.H,X LDA TEMP.PC STA PC.B LDA TEMP.PC+1 STA PC.B+1 INC SP.B JMP READBYTE.B ; ; RET.B - Returns the last stacked PC value ; RET.B DEC SP.B ; Ditto LDX SP.B LDA STACK.B.L,X STA PC.B LDA STACK.B.H,X STA PC.B+1 LDA #0 STA TRANSVAL_B JMP READBYTE.B ; ; FOR.HANDLE.B - Handles the stacking of FOR instructions ; FOR.HANDLE.B LDX SP.B ; Ditto LDA (PC.B),Y STA FOR.COUNTS.B,X LDA PC.B ADD #2 STA PC.B STA STACK.B.L,X BCC NOCARRY.B INC PC.B+1 NOCARRY.B LDA PC.B+1 STA STACK.B.H,X INC SP.B JMP READBYTE.B ; ; NEXT.HANDLE.B - Handles unstacking PC and decrementing the FOR counters ; NEXT.HANDLE.B LDX SP.B ; Ditto DEX DEC FOR.COUNTS.B,X BEQ LAST.NEXT.B LDA STACK.B.L,X STA PC.B LDA STACK.B.H,X STA PC.B+1 JMP READBYTE.B LAST.NEXT.B STX SP.B INC PC.B BNE NOCARRY2.B INC PC.B+1 NOCARRY2.B JMP READBYTE.B ; ; JUMP.C - Jumps to a new sequence of notes ; JUMP.C ; Ditto LDA (PC.C),Y STA TEMP.PC INY LDA (PC.C),Y STA PC.C+1 LDA TEMP.PC STA PC.C JMP READBYTE.C ; ; CALL.C - Same as JSR, goes to a new sequence and returns on finding a RET ; CALL.C LDX SP.C ; Ditto LDA (PC.C),Y STA TEMP.PC INY LDA (PC.C),Y STA TEMP.PC+1 LDA PC.C ADD #3 STA STACK.C.L,X LDA PC.C+1 ADC #0 STA STACK.C.H,X LDA TEMP.PC STA PC.C LDA TEMP.PC+1 STA PC.C+1 INC SP.C JMP READBYTE.C ; ; RET.C - Returns the last stacked PC value ; RET.C DEC SP.C ; Ditto LDX SP.C LDA STACK.C.L,X STA PC.C LDA STACK.C.H,X STA PC.C+1 LDA #0 STA TRANSVAL_C JMP READBYTE.C ; ; FOR.HANDLE.C - Handles the stacking of FOR instructions ; FOR.HANDLE.C LDX SP.C ; Ditto LDA (PC.C),Y STA FOR.COUNTS.C,X LDA PC.C ADD #2 STA PC.C STA STACK.C.L,X BCC NOCARRY.C INC PC.C+1 NOCARRY.C LDA PC.C+1 STA STACK.C.H,X INC SP.C JMP READBYTE.C ; ; NEXT.HANDLE.C - Handles unstacking PC and decrementing the FOR counters ; NEXT.HANDLE.C LDX SP.C ; Ditto DEX DEC FOR.COUNTS.C,X BEQ LAST.NEXT.C LDA STACK.C.L,X STA PC.C LDA STACK.C.H,X STA PC.C+1 JMP READBYTE.C LAST.NEXT.C STX SP.C INC PC.C BNE NOCARRY2.C INC PC.C+1 NOCARRY2.C JMP READBYTE.C ; ; VIBON_A - Acctivates the vibrato ; VIBON_A LDA (PC.A),Y STA VIBDELAY2_A ; Permenant vib delay INY LDA (PC.A),Y STA VIBRATE_A ; additive/subtractive rate INY LDA (PC.A),Y STA VIBDEPTH_A ; Variable vib depth LSR STA VIBDEPTH2_A ; Permenant vib depth LDX #1 STX VIBFLAG_A ; Signal vibrato is on DEX STX VIB_DIR_A ; Set the initial vibrato direction STX ARPFLAG_A ; Cancel arpeggio (if it is running) LDA #4 ; Bump the PC JMP ADD_PC_A ; ; VIBOFF_A - Guess moron ! ; VIBOFF_A LDA #0 ; Shut down the vibrato STA VIBFLAG_A INC PC.A ; Bump PC BNE SKIP2_A INC PC.A+1 SKIP2_A JMP READBYTE.A ; Back to the sequencer ; ; VIBON_B - Acctivates the vibrato ; VIBON_B ; Ditto LDA (PC.B),Y STA VIBDELAY2_B ; Permenant vib delay INY LDA (PC.B),Y STA VIBRATE_B INY LDA (PC.B),Y STA VIBDEPTH_B LSR STA VIBDEPTH2_B ; " " " " " depth LDX #1 STX VIBFLAG_B DEX STX VIB_DIR_B STX ARPFLAG_B LDA #4 JMP ADD_PC_B ; ; VIBOFF_B - Guess moron ! ; VIBOFF_B LDA #0 ; Ditto STA VIBFLAG_B INC PC.B BNE SKIP2_B INC PC.B+1 SKIP2_B JMP READBYTE.B ; ; VIBON_C - Acctivates the vibrato ; VIBON_C ; Ditto LDA (PC.C),Y STA VIBDELAY2_C ; Permenant vib delay INY LDA (PC.C),Y STA VIBRATE_C INY LDA (PC.C),Y STA VIBDEPTH_C LSR STA VIBDEPTH2_C ; " " " " " depth LDX #1 STX VIBFLAG_C DEX STX VIB_DIR_C STX ARPFLAG_C LDA #4 JMP ADD_PC_C ; ; VIBOFF_C - Guess moron ! ; VIBOFF_C LDA #0 ; Ditto STA VIBFLAG_C INC PC.C BNE SKIP2_C INC PC.C+1 SKIP2_C JMP READBYTE.C ; ; ARPON_A - Acctivates the arpeggiator ; ARPON_A LDA (PC.A),Y STA READ_A ; Get the address of the arpeggio INY LDA (PC.A),Y ; table STA READ_A+1 LDY #0 ; STY VIBFLAG_A LDA (READ_A),Y STA NEXTDELAY2_A ; Get the delay between reading bytes INY STY ARPFLAG_A ; Trigger the arpeggiator STY NEXTDELAY_A LDA (READ_A),Y ADD #2 STA ARPEGLEN_A ; Set the length of the arpeggio table INY STY ARPEGIND_A ; Set the index into the table LDA #3 ; Bump the PC JMP ADD_PC_A ; ; ARPOFF_A - No prizes dickhead ! ; ARPOFF_A LDA #0 ; Shut down the arpeggiator STA ARPFLAG_A INC PC.A ; Bump the PC BNE SKIP4_A INC PC.A+1 SKIP4_A JMP READBYTE.A ; Back to the sequencer ; ; ARPON_B - Acctivates the arpeggiator ; ARPON_B ; Ditto LDA (PC.B),Y STA READ_B INY LDA (PC.B),Y STA READ_B+1 LDY #0 ; STY VIBFLAG_B LDA (READ_B),Y STA NEXTDELAY2_B INY STY ARPFLAG_B STY NEXTDELAY_B LDA (READ_B),Y ADD #2 STA ARPEGLEN_B INY STY ARPEGIND_B LDA #3 JMP ADD_PC_B ; ; ARPOFF_B - No prizes dickhead ! ; ARPOFF_B LDA #0 ; Ditto STA ARPFLAG_B INC PC.B BNE SKIP4_B INC PC.B+1 SKIP4_B JMP READBYTE.B ; ; ARPON_C - Acctivates the arpeggiator ; ARPON_C ; Ditto LDA (PC.C),Y STA READ_C INY LDA (PC.C),Y STA READ_C+1 LDY #0 ; STY VIBFLAG_C LDA (READ_C),Y STA NEXTDELAY2_C INY STY ARPFLAG_C STY NEXTDELAY_C LDA (READ_C),Y ADD #2 STA ARPEGLEN_C INY STY ARPEGIND_C LDA #3 JMP ADD_PC_C ; ; ARPOFF_C - No prizes dickhead ! ; ARPOFF_C LDA #0 ; Ditto STA ARPFLAG_C INC PC.C BNE SKIP4_C INC PC.C+1 SKIP4_C JMP READBYTE.C ; ; MODE_A - Sets triggering mode, i'll be buggered if i know what this does ! ; MODE_A LDA (PC.A),Y BMI SETEM_A EOR #$FF AND MODEBYTE_A STA MODEBYTE_A LDA #2 JMP ADD_PC_A SETEM_A ORA MODEBYTE_A STA MODEBYTE_A LDA #2 JMP ADD_PC_A ; ; MODE_B - Sets triggering mode ; MODE_B LDA (PC.B),Y BMI SETEM_B EOR #$FF AND MODEBYTE_B STA MODEBYTE_B LDA #2 JMP ADD_PC_B SETEM_B ORA MODEBYTE_B STA MODEBYTE_B LDA #2 JMP ADD_PC_B ; ; MODE_C - Sets triggering mode ; MODE_C LDA (PC.C),Y BMI SETEM_C EOR #$FF AND MODEBYTE_C STA MODEBYTE_C LDA #2 JMP ADD_PC_C SETEM_C ORA MODEBYTE_C STA MODEBYTE_C LDA #2 JMP ADD_PC_C ; ; PORT_A - Sends 1 byte of data to an offset of the SID chip ; PORT_A LDA (PC.A),Y STA TEMP_VAL ; Store byte to be send to SID INY LDA (PC.A),Y ; Get sid offset TAX LDA TEMP_VAL ; Send value to SID STA $D400,X LDA #3 ; Bump the PC JMP ADD_PC_A PORT_B ; Ditto LDA (PC.B),Y STA TEMP_VAL INY LDA (PC.B),Y TAX LDA TEMP_VAL STA $D400,X LDA #3 JMP ADD_PC_B PORT_C ; Ditto LDA (PC.C),Y STA TEMP_VAL INY LDA (PC.C),Y TAX LDA TEMP_VAL STA $D400,X LDA #3 JMP ADD_PC_C ; ; CODE_A - Jumps to a machine code segment ; CODE_A LDA (PC.A),Y STA JUMP_MOD_A+1 ; Get the address of the code INY LDA (PC.A),Y ; to be JSR'd to STA JUMP_MOD_A+2 JUMP_MOD_A JSR $AAAA ; Self modified LDA #3 ; Bump the PC JMP ADD_PC_A CODE_B ; Ditto LDA (PC.B),Y STA JUMP_MOD_B+1 INY LDA (PC.B),Y STA JUMP_MOD_B+2 JUMP_MOD_B JSR $AAAA ; Self modified LDA #3 JMP ADD_PC_B CODE_C ; Ditto LDA (PC.C),Y STA JUMP_MOD_C+1 INY LDA (PC.C),Y STA JUMP_MOD_C+2 JUMP_MOD_C JSR $AAAA ; Self modified LDA #3 JMP ADD_PC_C ; ; EFFECT_A - Sets up effect mode ; EFFECT_A LDA (PC.A),Y STA EFFECT_NOTE_A STY EFFECTFLAG_A LDA #2 JMP ADD_PC_A EFFECT_B LDA (PC.B),Y STA EFFECT_NOTE_B STY EFFECTFLAG_B LDA #2 JMP ADD_PC_B EFFECT_C LDA (PC.C),Y STA EFFECT_NOTE_C STY EFFECTFLAG_C LDA #2 JMP ADD_PC_C ; ; BEND.ON.A - Acctivates the Pitchbender & sets up the pitchbend data ; BEND.ON.A LDA #$81 ; Bend on+minus = initialise bend STA PORTFLAG.A LDA (PC.A),Y STA BEND.DIR.A ; Get the bend direction INY LDA (PC.A),Y STA BENDSTEP.A ; Get the steps INY LDA (PC.A),Y STA BENDLENGTH.A ; and the length INY LDA (PC.A),Y ; Bend offset (Rate x Duration) STA OFFSET.A INY LDA (PC.A),Y STA OFFSET.A+1 LDA #6 ; Bump the PC JMP ADD_PC_A ; ; BEND.ON.B - Acctivates the Pitchbender & sets up the pitchbend data ; BEND.ON.B LDA #$81 ; Bend on. Minus = init benda STA PORTFLAG.B LDA (PC.B),Y STA BEND.DIR.B ; Pitchbend direction INY LDA (PC.B),Y STA BENDSTEP.B ; Bend steps INY LDA (PC.B),Y STA BENDLENGTH.B INY LDA (PC.B),Y ; Bend offset (Rate x Duration) STA OFFSET.B INY LDA (PC.B),Y STA OFFSET.B+1 LDA #6 JMP ADD_PC_B ; ; BEND.ON.C - Acctivates the Pitchbender & sets up the pitchbend data ; ;BEND.ON.C LDA #$81 ; Bend on. Minus = init bend ; STA PORTFLAG.C ; LDA (PC.C),Y ; STA BEND.DIR.C ; Pitchbend direction ; INY ; LDA (PC.C),Y ; STA BENDSTEP.C ; Bend steps ; INY ; LDA (PC.C),Y ; STA BENDLENGTH.C ; INY ; LDA (PC.C),Y ; Bend offset (Rate x Duration) ; STA OFFSET.C ; INY ; LDA (PC.C),Y ; STA OFFSET.C+1 ; ; LDA #6 ; JMP ADD_PC_C ; ; PATCH.A - Pokes sound patch into SID chip Channel A ; PATCH.A LDA #0 STA FROM+1 ; Zeroise FROM+1 LDA (PC.A),Y ; Get patch number ASL ASL ADD (PC.A),Y ; *5 ADC #PATCH_START STA FROM LDA FROM+1 ; Plus patch base address ADC ^PATCH_START STA FROM+1 LDY #4 LDA (FROM),Y STA GATEOFF.A ; Get the gateoff value DEY LDX #0 LDA (FROM),Y ; Minus = gap mode BPL NO_GAP_A INX NO_GAP_A AND #$7F ; Get rid of bit 7 STA SUSTAIN_A STX GAPFLAG_A ; Set the gap flag (nonzero) DEY LDA (FROM),Y ; Get SR period STA $D406 STA SUSTEMP+0 ; Preserve this DEY LDA (FROM),Y STA $D405 ; Get the AD period STA ADTEMP+0 ; Preserve this DEY LDA (FROM),Y STA GATE.A ; Get the gateon value LDA #2 ; Bump the PC JMP ADD_PC_A ; ; PATCH.B - Pokes sound patch into SID chip Channel B ; PATCH.B LDA #0 ; Ditto STA FROM+1 LDA (PC.B),Y ASL ASL ADD (PC.B),Y ADC #PATCH_START STA FROM LDA FROM+1 ADC ^PATCH_START STA FROM+1 LDY #4 LDA (FROM),Y STA GATEOFF.B DEY LDX #0 LDA (FROM),Y BPL NO_GAP_B INX NO_GAP_B AND #$7F STA SUSTAIN_B STX GAPFLAG_B DEY LDA (FROM),Y STA $D406+7 STA SUSTEMP+1 DEY LDA (FROM),Y STA $D405+7 STA ADTEMP+1 DEY LDA (FROM),Y STA GATE.B LDA #2 JMP ADD_PC_B ; ; PATCH.C - Pokes sound patch into SID chip Channel C ; PATCH.C LDA #0 STA FROM+1 LDA (PC.C),Y ASL ASL ADD (PC.C),Y ADC #PATCH_START STA FROM LDA FROM+1 ADC ^PATCH_START STA FROM+1 LDY #4 LDA (FROM),Y STA GATEOFF.C DEY LDX #0 LDA (FROM),Y BPL NO_GAP_C INX NO_GAP_C AND #$7F STA SUSTAIN_C STX GAPFLAG_C DEY LDA (FROM),Y STA $D406+14 STA SUSTEMP+2 DEY LDA (FROM),Y STA $D405+14 STA ADTEMP+2 DEY LDA (FROM),Y STA GATE.C LDA #2 JMP ADD_PC_C ; ; DRUM_C - Gets new drum table pointers (DunnyDrums tm) ; DRUM_C LDA (PC.C),Y STA DRUMadd ASL ADD DRUMadd ASL ADC DRUMadd TAX LDA DRUMTABLE,X ;GET LO & HI BYTE OF WVFORM TABLE STA WAVES_L+2 ; LDA DRUMTABLE+1,X ; STA WAVES_H+2 ; LDA DRUMTABLE+2,X ;" "" " "" " FREQUENCY TABLE STA FREQS_L+2 ; LDA DRUMTABLE+3,X ; STA FREQS_H+2 ; LDA DRUMTABLE+4,X ;GET LENGTH OF DRUM TABLE STA DRUMlength+2 ; LDA DRUMTABLE+5,X ;GET VOLUME (SUTAIAN/RELEASE) STA drumFLAG+2 ; STA $D406+14 ; LDA DRUMTABLE+6,X ;GET PULSE WIDTH STA $D403+14 LDA #$00 ;ATTACK/DECAY STA $D405+14 ;FOR DRUMSOUND INY LDA (PC.C),Y STA DRUMtr+2 LDA DURATIONON_C BNE GRAB_DUR_C LDA DURATION_C STA DURCOUNT.C LDA #3 ADD_N_FALL_C ADD PC.C STA PC.C BCC NOLOW_C INC PC.C+1 NOLOW_C RTS GRAB_DUR_C INY LDA (PC.C),Y STA DURCOUNT.C LDA #4 JMP ADD_N_FALL_C ;----------DRUM PROGRAM-------------------- DRUMMER LDX #2 NEXT_DRUM LDA drumFLAG,X BEQ QUITDRUM LDA DRUMx,X CMP DRUMlength,X BNE DRUMcont LDA #0 STA $D417 STA DRUMx,X STA drumFLAG,X LDY SID_OFFSETS,X LDA SUSTEMP,X STA $D406,Y LDA ADTEMP,X STA $D405,Y LDA #0 STA $D404,Y QUITDRUM DEX BPL NEXT_DRUM RTS DRUMcont STX TEMPX ; TEMPX+0 = Drum Number STA TEMPX+1 ; TEMPX+1 = Drum's position in table LDA FREQS_L,X STA DRUMFQ+1 LDA FREQS_H,X STA DRUMFQ+2 LDA WAVES_L,X STA DRUMWV+1 LDA WAVES_H,X STA DRUMWV+2 LDY SID_OFFSETS,X LDX TEMPX+1 ;GET CURRENT VOICE DRUMFQ LDA $DDDD,X ; LOAD FREQUENCY FROM TABLE (S/M/C) LDX TEMPX ADD DRUMtr,X ; ADD TRANSPOSE BYTE LDX TEMPX+1 STA $D401,Y ; STORE IN SID FRQ HI DRUMWV LDA $DDDD,X ; LOAD WAVEFORM FROM TABLE (S/M/C) STA $D404,Y ; STORE IN SID WAVEFORM LDX TEMPX INC DRUMx,X DEX BMI DRUMS_DONE JMP NEXT_DRUM DRUMS_DONE RTS BITABLE DFB 1,2,4 ; ; END_A - Terminates the tune on that voice ; END_A LDA #0 STA MFL_A STA PORTFLAG.A STA VIBFLAG_A STA ARPFLAG_A STA PULSEFLAG_A RTS END_B LDA #0 STA MFL_B STA PORTFLAG.B STA VIBFLAG_B STA ARPFLAG_B STA PULSEFLAG_B RTS END_C LDA #0 STA MFL_C STA PORTFLAG.C STA VIBFLAG_C STA ARPFLAG_C STA PULSEFLAG_C RTS DRUM_A DRUM_B ;BEND.ON.B BEND.ON.C ;EFFECT_A ;EFFECT_B NOTHING RTS ; FINITO ; ; Control tables... ; JUMPVECL.A DFL JUMP.A,CALL.A,RET.A,FOR.HANDLE.A,NEXT.HANDLE.A DFL BEND.ON.A,PATCH.A,LENGTH_A,VIBON_A,VIBOFF_A DFL ARPON_A,ARPOFF_A,DUR_ON_A,PULSEON_A,NOTHING DFL END_A,TRANS_A,CT_A,NOTHING,MODE_A,DRUM_A DFL PORT_A,CODE_A,EFFECT_A JUMPVECH.A DFH JUMP.A,CALL.A,RET.A,FOR.HANDLE.A,NEXT.HANDLE.A DFH BEND.ON.A,PATCH.A,LENGTH_A,VIBON_A,VIBOFF_A DFH ARPON_A,ARPOFF_A,DUR_ON_A,PULSEON_A,NOTHING DFH END_A,TRANS_A,CT_A,NOTHING,MODE_A,DRUM_A DFH PORT_A,CODE_A,EFFECT_A JUMPVECL.B DFL JUMP.B,CALL.B,RET.B,FOR.HANDLE.B,NEXT.HANDLE.B DFL BEND.ON.B,PATCH.B,LENGTH_B,VIBON_B,VIBOFF_B DFL ARPON_B,ARPOFF_B,DUR_ON_B,PULSEON_B,NOTHING DFL END_B,TRANS_B,CT_B,NOTHING,MODE_B,DRUM_B DFL PORT_B,CODE_B,EFFECT_B JUMPVECH.B DFH JUMP.B,CALL.B,RET.B,FOR.HANDLE.B,NEXT.HANDLE.B DFH BEND.ON.B,PATCH.B,LENGTH_B,VIBON_B,VIBOFF_B DFH ARPON_B,ARPOFF_B,DUR_ON_B,PULSEON_B,NOTHING DFH END_B,TRANS_B,CT_B,NOTHING,MODE_B,DRUM_B DFH PORT_B,CODE_B,EFFECT_B JUMPVECL.C DFL JUMP.C,CALL.C,RET.C,FOR.HANDLE.C,NEXT.HANDLE.C DFL BEND.ON.C,PATCH.C,LENGTH_C,VIBON_C,VIBOFF_C DFL ARPON_C,ARPOFF_C,DUR_ON_C,PULSEON_C,NOTHING DFL END_C,TRANS_C,CT_C,NOTHING,MODE_C,DRUM_C DFL PORT_C,CODE_C,EFFECT_C JUMPVECH.C DFH JUMP.C,CALL.C,RET.C,FOR.HANDLE.C,NEXT.HANDLE.C DFH BEND.ON.C,PATCH.C,LENGTH_C,VIBON_C,VIBOFF_C DFH ARPON_C,ARPOFF_C,DUR_ON_C,PULSEON_C,NOTHING DFH END_C,TRANS_C,CT_C,NOTHING,MODE_C,DRUM_C DFH PORT_C,CODE_C,EFFECT_C STACKDEPTH EQU 5 STACK.A.L DFS STACKDEPTH,0 STACK.B.L DFS STACKDEPTH,0 STACK.C.L DFS STACKDEPTH,0 STACK.A.H DFS STACKDEPTH,0 STACK.B.H DFS STACKDEPTH,0 STACK.C.H DFS STACKDEPTH,0 FOR.COUNTS.A DFS STACKDEPTH,0 FOR.COUNTS.B DFS STACKDEPTH,0 FOR.COUNTS.C DFS STACKDEPTH,0 SID_OFFSETS DFB 0,7,14 WORD_OFFSET DFB 0,2,4 SILLYMESS DFM "LOADER4 THE REMIX! BY JONATHAN DUNN DRIVER BY PAUL HUGHES" LOWFREQ DFL N00,N01,N02,N03,N04,N05,N06,N07,N08,N09 DFL N10,N11,N12,N13,N14,N15,N16,N17,N18,N19 DFL N20,N21,N22,N23,N24,N25,N26,N27,N28,N29 DFL N30,N31,N32,N33,N34,N35,N36,N37,N38,N39 DFL N40,N41,N42,N43,N44,N45,N46,N47,N48,N49 DFL N50,N51,N52,N53,N54,N55,N56,N57,N58,N59 DFL N60,N61,N62,N63,N64,N65,N66,N67,N68,N69 DFL N70,N71,N72,N73,N74,N75,N76,N77,N78,N79 DFL N80,N81,N82,N83,N84,N85,N86,N87,N88,N89 DFL N90,N91,N92,N93,000 HIFREQ DFH N00,N01,N02,N03,N04,N05,N06,N07,N08,N09 DFH N10,N11,N12,N13,N14,N15,N16,N17,N18,N19 DFH N20,N21,N22,N23,N24,N25,N26,N27,N28,N29 DFH N30,N31,N32,N33,N34,N35,N36,N37,N38,N39 DFH N40,N41,N42,N43,N44,N45,N46,N47,N48,N49 DFH N50,N51,N52,N53,N54,N55,N56,N57,N58,N59 DFH N60,N61,N62,N63,N64,N65,N66,N67,N68,N69 DFH N70,N71,N72,N73,N74,N75,N76,N77,N78,N79 DFH N80,N81,N82,N83,N84,N85,N86,N87,N88,N89 DFH N90,N91,N92,N93,000 DRIVER.END EQU . ;------------------------------------------------------------------------------ DATA.START EQU . TUNETABLE.A.L DFL LOADER1 TUNETABLE.A.H DFH LOADER1 TUNETABLE.B.L DFL LOADER2 TUNETABLE.B.H DFH LOADER2 TUNETABLE.C.L DFL LOADER3 TUNETABLE.C.H DFH LOADER3 ;----------------------------------------------------------------------------- LOADER1 DFL MANUAL DFL PATCH,1,PWM,1 DFL VIBON,0,9,6 DFL EFFECT,12 DFL BEND,UP,$10,48:DFW $10*48 DFL C2,192 DFL BEND,UP,$10,48:DFW $10*48 DFL A#1,192 DFL BEND,UP,$10,48:DFW $10*48 DFL G#1,192 DFL LOOP,3,REST,192,NEXT DFL PATCH,2,PWM,2,VIBON,4,10,6 DFL LOOP,2 DFL CT,0:DFW BASSSEQ1 DFL CT,-2:DFW BASSSEQ1 DFL CT,-4:DFW BASSSEQ1 DFL NEXT DFL LOOP,2,CT,0:DFW BASSSEQ1:DFL NEXT DFL LOOP,2 DFL CT,0:DFW BASSSEQ1 DFL CT,-2:DFW BASSSEQ1 DFL CT,-4:DFW BASSSEQ1 DFL NEXT DFL LOOP,2,CT,0:DFW BASSSEQ1:DFL NEXT DFL CT,+3:DFW BASSSEQ1 DFL CT,0:DFW BASSSEQ1 DFL CT,0:DFW BASSSEQ1 DFL CT,-2:DFW BASSSEQ1 DFL CT,-4:DFW BASSSEQ1 ;$35 DFL LOOP,4,CT,0:DFW BASSSEQ1:DFL NEXT DFL LOOP,2 DFL CT,0:DFW BASSSEQ1 DFL CT,-2:DFW BASSSEQ1 DFL CT,-4:DFW BASSSEQ1 DFL NEXT DFL LOOP,2,CT,0:DFW BASSSEQ1:DFL NEXT DFL CT,0:DFW BASSSEQ1 DFL CT,-2:DFW BASSSEQ1 DFL CT,-4:DFW BASSSEQ1 ;-----FADE HERE DFL CODE:DFW RESETVOLUME DFL LOOP,15 FADEBIT DFL PORT,15,$18 DFL C2,18,C2,6,C3,12,C2,12,C2,6,C2,6,C3,6,C2,12 DFL A#1,6,A#1,6,A#1,6 DFL CODE:DFW FADEROUTINE DFL NEXT DFB END FADEROUTINE DEC FADEBIT+1 RTS RESETVOLUME LDA #15 STA FADEBIT+1 RTS ;----------------------------------------------------------------------------- LOADER2 DFB MANUAL DFL PATCH,0,PWM,0 DFL VIBON,0,$FF,4 DFL LOOP,6 DFL BEND,UP,$30,36:DFW $30*36 DFL C5,192,NEXT ;MELODY#1 DFL PATCH,4,PWM,4 DFL VIBON,4,$20,6 DFL LOOP,2 DFL LENGTH,12 DFL REST,C4,D#4,F4 DFL BEND,UP,$FF,6:DFW $FF*6 DFL G4,F4,MANUAL,D#4,24 DFL D4,12,D#4,24,D4,36,A#3,24 DFL D4,36,D#4,36,D4,24 DFL D4,6,D#4,6,D4,60,A#3,24 DFL C4,36,A#3,36,G#3,24 DFL C4,36,C#4,36,D#4,24 DFL NEXT DFL LOOP,2,REST,192,NEXT ;MELODY#2 DFL LOOP,2 DFL C4,96 DFL D#4,24,F4,24 DFL BEND,UP,$FF,6:DFW $FF*6 DFL D#4,12,D4,12,C4,12,G3,24 DFL F3,24,F3,60+72 DFL BEND,UP,$FF,9:DFW $FF*9 DFL G3,24 DFL G#3,36,D#4,36,C#4,12,C4,12 DFL C#4,48,C4,48 DFL NEXT DFL LOOP,4,REST,192,NEXT ;MELODY#3 DFL PATCH,5,PWM,5 DFL VIBON,0,$70,6 DFL LENGTH,6 DFL LOOP,6 DFL C5,C6,C7,C6,C6,C7,C6,C6 DFL C5,C7,C7,C6,C6,C7,C6,C6 DFL NEXT DFL MANUAL DFL C3,96,REST,96 DFL LOOP,3,REST,192,NEXT ;MELODY#4 DFL PATCH,7,PWM,7 DFL VIBON,12,$20,6 DFL LOOP,2 DFL D#4,48,D4,48 DFL C4,48,A#3,48 DFL D#4,12,D4,24,F4,60+72 DFL G3,24 DFL BEND,UP,$FF,7:DFW $FF*7 DFL F4,12,D#4,36,D4,36,C4,12 DFL F4,48,G4,48 DFL NEXT DFL LOOP,2,REST,192,NEXT DFL PATCH,0,PWM,0 DFL VIBON,0,$FF,4 DFL LOOP,3 DFL BEND,UP,$30,36:DFW $30*36 DFL C5,192,NEXT ;FADED BIT DFL PATCH,8,PWM,8 DFL VIBON,0,$20,6 DFL LOOP,15 DFL C4,36,D#4,24,D4,12,C4,24 DFL NEXT DFB END ;----------------------------------------------------------------------------- LOADER3 DFB MANUAL DFL LOOP,3,REST,192,NEXT DFL LOOP,5,CALL:DFW DRUMSEQ1:DFL NEXT DFL REST,24 DFL DRUM,1,0,24 DFL DRUM,0,0,12 DFL DRUM,0,0,12 DFL DRUM,1,0,12 DFL DRUM,1,0,6 DFL DRUM,1,0,6 ;BACK BIT#1 DFL PATCH,3,PWM,3 DFL ARPON:DFW ARP8 DFL LOOP,2 DFL CALL:DFW BACK1 DFL CT,-2:DFW BACK1 DFL CT,-4:DFW BACK1 DFL NEXT DFL LOOP,2,CALL:DFW BACK1:DFL NEXT DFL LOOP,2 DFL CALL:DFW BACK1 DFL CT,-2:DFW BACK1 DFL CT,-4:DFW BACK1 DFL NEXT DFL LOOP,2,CALL:DFW BACK1:DFL NEXT DFL PATCH,6,PWM,6 DFL LOOP,2,CALL:DFW BACK1:DFL NEXT ;BACK BIT#2 DFL ARPON:DFW ARP18 DFL CALL:DFW BACK2 DFL CT,-2:DFW BACK2 DFL CT,-4:DFW BACK2 DFL CALL:DFW BACK2 DFL REST,192 ;BACK BIT#1 AGAIN DFL PATCH,3,PWM,4 DFL ARPON:DFW ARP8 DFL LOOP,2,CALL:DFW BACK1:DFL NEXT DFL LOOP,2 DFL CALL:DFW BACK1 DFL CT,-2:DFW BACK1 DFL CT,-4:DFW BACK1 DFL NEXT DFL LOOP,2,CALL:DFW BACK1:DFL NEXT DFL LOOP,6,CALL:DFW DRUMSEQ1:DFL NEXT ;FADE BIT STARTS HERE DFL LOOP,15 DFL C4,6,C4,6,C4,6,C4,6 DFL DRUM,1,0,12 DFL C4,6,C4,6 DFL C4,6,C4,6 DFL C4,6,C4,6 DFL DRUM,1,0,12 DFL C4,6,C4,6 DFL NEXT DFB END ;-------SEQUENCES------------------------------------------------------------- BASSSEQ1 DFL LOOP,2 DFL C2,18,C2,6,C3,12,C2,12,C2,6,C2,6,C3,6,C2,12 DFL A#1,6,A#1,6,A#1,6 DFL NEXT DFL RET DRUMSEQ1 DFL LOOP,2 DFL REST,24 DFL DRUM,1,0,24 DFL NEXT DFL RET BACK1 DFL LOOP,3 DFL C3,6 DFL DRUM,2,0,6 DFL C4,6,C5,6 DFL DRUM,1,0,12 DFL C4,6,C5,6 DFL NEXT DFL C3,6 DFL DRUM,2,0,6 DFL C4,6,C5,6 DFL DRUM,1,0,12 DFL C4,6 DFL DRUM,1,0,6 DFL RET BACK2 DFL PATCH,6 DFL PWM,6 DFL C4,12,C4,12 DFL DRUM,1,0,12 DFL C4,12 DFL PATCH,4 DFL PWM,4 DFL C4,12,C4,12 DFL DRUM,1,0,12 DFL PATCH,6 DFL PWM,6 DFL C4,12 DFL C4,12,C4,12 DFL DRUM,1,0,12 DFL C4,12 DFL PATCH,4 DFL PWM,4 DFL C4,12,C4,12 DFL DRUM,1,0,12 DFL PATCH,6 DFL PWM,6 DFL C4,12,RET ;-------PATCHES--------------------------------------------------------------- PATCH_START DFB $43,$00,$7B,96+GAP,$22;0 DFB $41,$00,$AD,3,$40 ;1 DFB $21,$00,$E9,2,$40 ;2 DFB $13,$00,$98,2,$40 ;3 DFB $41,$00,$8E,4+GAP,$42;4 DFB $43,$00,$48,3,$14 ;5 DFB $11,$00,$89,2,$40 ;6 DFB $41,$00,$7D,3+GAP,$54;7 DFB $15,$00,$99,2,$42 ;8 ;-------PWMS------------------------------------------------------------------ PWM_START DFB $40,48,42:DFW $0000 ;0 DFB $40,16,16:DFW $0800 ;1 DFB $40,00,02:DFW $0000 ;2 DFB $80,00,03:DFW $0000 ;3 DFB $30,10,08:DFW $0000 ;4 DFB $FF,00,02:DFW $0800 ;5 DFB $10,05,05:DFW $0200 ;6 DFB $20,10,05:DFW $0000 ;7 DFB $40,16,16:DFW $0200 ;8 ARP8 DFB 1,3,24,12,0 ARP20 DFB 1,2,0,24 ARP18 DFB 1,4,0,3,7,12 ARP22 DFL 1,2,12,0 ;-----DRUM TABLE & DATA--------------------- DRUMTABLE DFW DRUM1V,DRUM1F:DFL 6,$B8,$08 DFW DRUM2V,DRUM2F:DFL 13,$D8,$08 DFW DRUM3V,DRUM3F:DFL 5,$75,$00 DFW DRUM1V,DRUM1F:DFL 6,$88,$08 ;-----BASS DRUM------ DRUM1V DFB $41,$41,$15,$80,$12,$80 DRUM1F DFB $0D,$0C,$13,$22,$12,$20 ;-----SNARE---------- DRUM2V DFB $41,$41,$41,$81,$81,$80,$14,$80,$12,$80,$14,$80,$12,$80 DRUM2F DFB $11,$10,$0C,$4F,$4F,$4E,$12,$4D,$11,$4C,$10,$4B,$0F,$4A ;-----HI-HAT--------- DRUM3V DFB $15,$15,$80,$12,$80 DRUM3F DFB $10,$0F,$80,$10,$70 TURNOFF LDA #8 STA $D404 STA $D404+7 STA $D404+14 LDA #0 STA $D404 STA $D404+7 STA $D404+14 RTS DATA.END EQU . ;------------------------------------------------------------------------------ UP EQU 1 DOWN EQU $80 GAP EQU $80 NO EQU 0 FILTIT EQU 1 REST EQU 94 JUMP EQU $80 CALL EQU $81 RET EQU $82 LOOP EQU $83 NEXT EQU $84 BEND EQU $85 PATCH EQU $86 LENGTH EQU $87 VIBON EQU $88 VIBOFF EQU $89 ARPON EQU $8A ARPOFF EQU $8B MANUAL EQU $8C PWM EQU $8D FILTER EQU $8E END EQU $8F TRANSPOSE EQU $90 CT EQU $91 FILTOFF EQU $92 MODE EQU $93 DRUM EQU $94 PORT EQU $95 CODE EQU $96 EFFECT EQU $97 VAR_START FILT_TOGGLE DFB 0 FILT_TOGFLAG DFB 0 DURCOUNT.A DFB 0 DURCOUNT.B DFB 0 DURCOUNT.C DFB 0 TEMP.PC DFB 0,0 ; 2 bytes GATE.A DFB 0 GATE.B DFB 0 GATE.C DFB 0 SP.A DFB 0 SP.B DFB 0 SP.C DFB 0 PORTFLAG.A DFB 0 PORTFLAG.B DFB 0 PORTFLAG.C DFB 0 BEND.DIR.A DFB 0 BEND.DIR.B DFB 0 BEND.DIR.C DFB 0 BENDSTEP.A DFB 0 BENDSTEP.B DFB 0 BENDSTEP.C DFB 0 FREQ.LOW.A DFB 0 FREQ.LOW.B DFB 0 FREQ.LOW.C DFB 0 FREQ.HI.A DFB 0 FREQ.HI.B DFB 0 FREQ.HI.C DFB 0 OFFSET.A DFB 0,0 ; 2 bytes OFFSET.B DFB 0,0 ; 2 bytes OFFSET.C DFB 0,0 ; 2 bytes BENDLENGTH.A DFB 0 BENDLENGTH.B DFB 0 BENDLENGTH.C DFB 0 RELEASE_A DFB 0 RELEASE_B DFB 0 RELEASE_C DFB 0 SUSTAIN_A DFB 0 SUSTAIN_B DFB 0 SUSTAIN_C DFB 0 DURATION_A DFB 0 DURATION_B DFB 0 DURATION_C DFB 0 VIBFLAG_A DFB 0 VIBFLAG_B DFB 0 VIBFLAG_C DFB 0 VIBDELAY_A DFB 0 VIBDELAY_B DFB 0 VIBDELAY_C DFB 0 VIBDELAY2_A DFB 0 VIBDELAY2_B DFB 0 VIBDELAY2_C DFB 0 VIBDEPTH_A DFB 0 VIBDEPTH_B DFB 0 VIBDEPTH_C DFB 0 VIBDEPTH2_A DFB 0 VIBDEPTH2_B DFB 0 VIBDEPTH2_C DFB 0 VIBRATE_A DFB 0 VIBRATE_B DFB 0 VIBRATE_C DFB 0 VIB_DIR_A DFB 0 VIB_DIR_B DFB 0 VIB_DIR_C DFB 0 NEXTDELAY_A DFB 0 NEXTDELAY_B DFB 0 NEXTDELAY_C DFB 0 NEXTDELAY2_A DFB 0 NEXTDELAY2_B DFB 0 NEXTDELAY2_C DFB 0 ARPEGLEN_A DFB 0 ARPEGLEN_B DFB 0 ARPEGLEN_C DFB 0 ARPEGIND_A DFB 0 ARPEGIND_B DFB 0 ARPEGIND_C DFB 0 ARPFLAG_A DFB 0 ARPFLAG_B DFB 0 ARPFLAG_C DFB 0 GATEOFF.A DFB 0 GATEOFF.B DFB 0 GATEOFF.C DFB 0 NOTE_A DFB 0 NOTE_B DFB 0 NOTE_C DFB 0 DURATIONON_A DFB 0 DURATIONON_B DFB 0 DURATIONON_C DFB 0 PULSEDIR_A DFB 0 PULSEDIR_B DFB 0 PULSEDIR_C DFB 0 RATEUP_A DFB 0 RATEUP_B DFB 0 RATEUP_C DFB 0 RATEDOWN_A DFB 0 RATEDOWN_B DFB 0 RATEDOWN_C DFB 0 CUP_A DFB 0 CUP_B DFB 0 CUP_C DFB 0 CUP2_A DFB 0 CUP2_B DFB 0 CUP2_C DFB 0 CDOWN_A DFB 0 CDOWN_B DFB 0 CDOWN_C DFB 0 CDOWN2_A DFB 0 CDOWN2_B DFB 0 CDOWN2_C DFB 0 PWL_A DFB 0 PWL_B DFB 0 PWL_C DFB 0 PWL2_A DFB 0 PWL2_B DFB 0 PWL2_C DFB 0 PWH_A DFB 0 PWH_B DFB 0 PWH_C DFB 0 PWH2_A DFB 0 PWH2_B DFB 0 PWH2_C DFB 0 PULSEFLAG_A DFB 0 PULSEFLAG_B DFB 0 PULSEFLAG_C DFB 0 GAPFLAG_A DFB 0 GAPFLAG_B DFB 0 GAPFLAG_C DFB 0 MFL_A DFB 0 MFL_B DFB 0 MFL_C DFB 0 TRANSVAL_A DFB 0 TRANSVAL_B DFB 0 TRANSVAL_C DFB 0 MODEBYTE_A DFB 0 MODEBYTE_B DFB 0 MODEBYTE_C DFB 0 VOICE_NUM DFB 0 DRUMadd DFB 0 DRUMx DFS 3,0 drumFLAG DFS 3,0 DRUMtr DFS 3,0 DRUMlength DFS 3,0 WAVES_L DFS 3,0 WAVES_H DFS 3,0 FREQS_L DFS 3,0 FREQS_H DFS 3,0 VOLUMES DFS 3,0 RELEASE.TEMP DFB 0 ATTACK.TEMP DFB 0 TEMP_VAL DFB 0 EFFECTFLAG_A DFB 0 EFFECTFLAG_B DFB 0 EFFECTFLAG_C DFB 0 EFFECT_NOTE_A DFB 0 EFFECT_NOTE_B DFB 0 EFFECT_NOTE_C DFB 0 REAL_NOTE_A DFB 0 REAL_NOTE_B DFB 0 REAL_NOTE_C DFB 0 TEMPX DFB 0,0 ; 2 Bytes SUSTEMP DFS 3,0 ADTEMP DFS 3,0 VAR_END EQU . PROG.END EQU . ;------------------------------------------------------------------------------ SID EQU $D400 ; ; ZP - All zero page usage for speed, although only the PC's require ZP ; ZP EQU $20 IA EQU ZP IX EQU ZP+1 IY EQU ZP+2 PC.A EQU ZP+4 PC.B EQU ZP+6 PC.C EQU ZP+8 READ_A EQU ZP+10 READ_B EQU ZP+12 READ_C EQU ZP+14 FROM EQU ZP+16 FRM EQU ZP+18 ; USED BY TESTER TO EQU ZP+20 TO2 EQU ZP+22 SA EQU ZP+24 SX EQU ZP+25 SY EQU ZP+26 ; PAL Note frequency table N00 EQU 279 N01 EQU 296 N02 EQU 314 N03 EQU 332 N04 EQU 352 N05 EQU 373 N06 EQU 395 N07 EQU 419 N08 EQU 444 N09 EQU 470 N10 EQU 498 N11 EQU 528 N12 EQU 559 N13 EQU 592 N14 EQU 627 N15 EQU 665 N16 EQU 704 N17 EQU 746 N18 EQU 790 N19 EQU 837 N20 EQU 887 N21 EQU 940 N22 EQU 996 N23 EQU 1055 N24 EQU 1118 N25 EQU 1184 N26 EQU 1255 N27 EQU 1330 N28 EQU 1408 N29 EQU 1492 N30 EQU 1581 N31 EQU 1675 N32 EQU 1774 N33 EQU 1880 N34 EQU 1992 N35 EQU 2110 N36 EQU 2236 N37 EQU 2369 N38 EQU 2509 N39 EQU 2659 N40 EQU 2817 N41 EQU 2984 N42 EQU 3162 N43 EQU 3350 N44 EQU 3549 N45 EQU 3760 N46 EQU 3984 N47 EQU 4220 N48 EQU 4471 N49 EQU 4737 N50 EQU 5019 N51 EQU 5317 N52 EQU 5634 N53 EQU 5969 N54 EQU 6324 N55 EQU 6700 N56 EQU 7098 N57 EQU 7520 N58 EQU 7967 N59 EQU 8441 N60 EQU 8943 N61 EQU 9475 N62 EQU 10038 N63 EQU 10635 N64 EQU 11267 N65 EQU 11937 N66 EQU 12647 N67 EQU 13399 N68 EQU 14195 N69 EQU 15040 N70 EQU 15934 N71 EQU 16881 N72 EQU 17886 N73 EQU 18949 N74 EQU 20076 N75 EQU 21270 N76 EQU 22534 N77 EQU 23875 N78 EQU 25294 N79 EQU 26798 N80 EQU 28391 N81 EQU 30080 N82 EQU 31869 N83 EQU 33764 N84 EQU 35771 N85 EQU 37898 N86 EQU 40151 N87 EQU 42540 N88 EQU 45069 N89 EQU 47749 N90 EQU 50588 N91 EQU 53596 N92 EQU 56783 N93 EQU 60160 C0 EQU 0 C#0 EQU 1 D0 EQU 2 D#0 EQU 3 E0 EQU 4 F0 EQU 5 F#0 EQU 6 G0 EQU 7 G#0 EQU 8 A0 EQU 9 A#0 EQU 10 B0 EQU 11 C1 EQU 12 C#1 EQU 13 D1 EQU 14 D#1 EQU 15 E1 EQU 16 F1 EQU 17 F#1 EQU 18 G1 EQU 19 G#1 EQU 20 A1 EQU 21 A#1 EQU 22 B1 EQU 23 C2 EQU 24 C#2 EQU 25 D2 EQU 26 D#2 EQU 27 E2 EQU 28 F2 EQU 29 F#2 EQU 30 G2 EQU 31 G#2 EQU 32 A2 EQU 33 A#2 EQU 34 B2 EQU 35 C3 EQU 36 C#3 EQU 37 D3 EQU 38 D#3 EQU 39 E3 EQU 40 F3 EQU 41 F#3 EQU 42 G3 EQU 43 G#3 EQU 44 A3 EQU 45 A#3 EQU 46 B3 EQU 47 C4 EQU 48 C#4 EQU 49 D4 EQU 50 D#4 EQU 51 E4 EQU 52 F4 EQU 53 F#4 EQU 54 G4 EQU 55 G#4 EQU 56 A4 EQU 57 A#4 EQU 58 B4 EQU 59 C5 EQU 60 C#5 EQU 61 D5 EQU 62 D#5 EQU 63 E5 EQU 64 F5 EQU 65 F#5 EQU 66 G5 EQU 67 G#5 EQU 68 A5 EQU 69 A#5 EQU 70 B5 EQU 71 C6 EQU 72 C#6 EQU 73 D6 EQU 74 D#6 EQU 75 E6 EQU 76 F6 EQU 77 F#6 EQU 78 G6 EQU 79 G#6 EQU 80 A6 EQU 81 A#6 EQU 82 B6 EQU 83 C7 EQU 84 C#7 EQU 85 D7 EQU 86 D#7 EQU 87 E7 EQU 88 F7 EQU 89 F#7 EQU 90 G7 EQU 91 G#7 EQU 92 A7 EQU 93 A#7 EQU 94 B7 EQU 95