****************** * * * ROBOTRON 22-AUGUST-83 * 24-AUGUST-83 4:00 * * RSOUNDS.S SOUND ROUTINES AND DATA * ****************** * ORIGINALLY: ALIEN;TUNES.S - SOUND DRIVER * THERE ARE 3 EXTERNAL ROUTINES IN THIS PACKAGE: * DOTUNE STARTS A TUNE, THE NUMBER OF THE TUNE IS IN THE ACCUMULATOR * KILLTUNE KILLS A TUNE, THE NUMBER OF THE TUNE IS IN THE ACCUMULATOR * CLEARTUN CLEARS OUT ALL TUNES, INCLUDING BACKED UP TUNES * NOTE THAT THESE ALL PRESERVE X AND Y REGISTERS. * IN ADDITION, THERE IS A ROUTINE CALLED 'TUNER' WHICH SHOULD BE CALLED ONCE * PER FRAME (PREFERABLY AT ABOUT THE SAME TIME EACH FRAME). NOTE THAT IT * CAN BE CALLED LESS FREQUENTLY (SAY ONCE PER TWO FRAMES) IF THE DURATION * DATA IS HALVED AND YOU ARE WILLING TO LIVE WITH THE DECREASED DURATION * RESOLUTION. * A BRIEF DESCRIPTION OF THE DRIVER. THIS IS A PRIORITY BASED TUNE DRIVER * WITH TWO BACK-UP CHANNELS. WHENEVER A DOTUNE IS EXECUTED, A CLEAR CHANNEL * IS LOOKED FOR. IF IT IS NOT AVAILABLE, PRIORITIES ARE CHECKED TO SEE IF * THE NEW TUNE SHOULD PREEMPT A LOWER PRIORITY TUNE. WHICHEVER TUNE LOSES * IS STORED IN ONE OF THE BACK-UP CHANNELS AND RESTARTED WHENEVER A CHANNEL * FREES ITSELF. IF MORE THAN ONE IS BACKED UP, THE HIGHER PRIORITY ONE IS * RESTARTED. CONCEPTUALLY THERE ARE 4 SOUND CHANNELS, OF WHICH CHANNELS 0 * AND 1 ARE ACTIVE AND CHANNELS 2 AND 3 ARE INACTIVE. THERE ARE PROVISIONS * FOR INFINITE TUNES AND TUNES WHICH INVOKE OTHER TUNES WHEN THEY ARE FINISHED. * LET'S START WITH THE DATA. NOTE THAT I HAVE LEFT A SELECTION OF TUNES * AND SOUND EFFECTS FROM MS PAC-MAN IN HERE TO SHOW HOW THE DATA IS ORGANIZED. * THERE ARE 5 TABLES WHICH CONTROL THE TUNES. THESE ARE INDEXED BY THE TUNE * TUMBER. THESE ARE: * TBASE LOW BYTE OF BASE ADDRESS OF TUNE DATA * TBASE1 HI BYTE * TCTLOFF OFFSET INTO TUNE DATA WHERE CTL DATA STARTS * TVOLOFF OFFSET INTO TUNE DATA WHERE VOLUME DATA STARTS * TPRIOR PRIORITY OF THIS TUNE (FROM 0 TO $7F, 0 IS LOWEST) * THESE TABLES TELL WHERE TO FIND AND HOW TO INTERPRET THE 'TUNE DATA' FOR * EACH TUNE. THE TUNE DATA IS ORGANIZED AS FOLLOWS: * FREQUENCY INFORMATION: THIS IS A SET OF PAIRS 'FREQ,DUR' WHERE * FREQ IS THE VALUE TO STUFF INTO AUDF0 AND DUR IS THE NUMBER * OF FRAMES TO LEAVE IT THERE. THE TUNE IS TERMINATED WHEN * A NEGATIVE FREQ IS ENCOUNTERED (THERE ARE ONLY 5 SIGNIFICANT * BITS OF FREQ, SO THIS DOES NOT LIMIT THE TUNES). THERE ARE * THE FOLLOWING WAYS TO TERMINATE A TUNE: * $FF - THE TUNE IS OVER * $FE - REPEAT THE TUNE (MAKES THE TUNE INFINITE) * $FD,TUNENUM - IMMEDIATELY START TUNENUM * CONTROL INFORMATION: THIS IS A SET OF PAIRS 'CTL,DUR' WHERE CTL IS * THE VALUE TO STUFF INTO AUDC0 AND DUR IS THE NUMBER OF FRAMES * TO LEAVE IT THERE. A DUR OF '$00' WILL MAKE THE CTL LAST THE * ENTIRE TUNE. * VOLUME INFORMATION: THIS IS A SET OF PAIRS 'VOL,DUR' WHERE VOL IS * THE VALUE TO STUFF INTO AUDV0 AND DUR IS THE NUMBER OF FRAMES * TO LEAVE IT THERE. AGAIN, A DUR OF '$00' WILL KEEP THE VOL * FOR THE ENTIRE TUNE. * NOTE THAT THE TUNE DATA FOR A SINGLE TUNE CANNOT BE LARGER THAN A PAGE. * BREAK THE TUNE INTO TWO PARTS WITH ONE STARTING THE OTHER IF YOU NEED A * LARGER TUNE. TAKE A LOOK AT THE EXAMPLES AT THE END OF THIS FILE IF THIS * DESCRIPTION DOESN'T MAKE SENSE, THERE ARE EXAMPLES OF INFINITE TUNES AND * TUNES CALLING EACH OTHER. NOTE THAT AN INFINITE TUNE CAN BE STOPPED BY * A KILLTUN OR A CLEARTUN. * AND NOW TO THE VARIABLES NEEDED. COPY OUT THESE VARIABLES (CHANGING THE * LOCATIONS AS NEEDED): * * ALL VARIABLES USED ARE IN RMAIN.S * * NOTE THAT SOUNDZP CAN PROBABLY BE PUT THE SAME PLACE AS YOUR LOADER TEMP * VARIABLES. * THE ONLY VARIABLES HERE THAT YOU MIGHT WISH TO LOOK AT FROM 'OUTSIDE' ARE * TUNON AND TUNINDEX. TUNON IS 1 IF A CHANNEL IS USED, 0 IF IT IS FREE. * TUNINDEX IS THE TUNE NUMBER OF A USED CHANNEL, 0 IF THE CHANNEL IS FREE. * NOTE THAT IF TUNON IS 0, A ZERO VOLUME IS FORCED INTO THE APPROPRIATE VOLUME * REGISTER, SO SIMPLY ZEROING THE TUNE DATA WILL SHUT THE TIA UP (OF COURSE, * CLEARTUN ALSO DOES THIS). * THE SIZE OF THIS CODE IS ABOUT $200 BYTES. NOTE THAT THE TUNE DATA WILL * PROBABLY RUN MUCH LARGER. * THIS ROUTINE ENTERS A TUNE INTO ONE OF THE SOUND CHANNELS IF IT CAN * INPUT: TUNE NUMBER IN A * X AND Y ARE PRESERVED DOTUNE STA TUNNUM ;SAVE IT TXA ;STACK REGISTERS PHA TYA PHA LDX TUNNUM ;FIND PRIORITY OF NEW TUNE LDA TPRIOR,X STA TUNTEMP0 JSR GETCHANL ;GET A CHANNEL CPX #$00 ;SEE IF WE GOT ONE BMI DTOUT LDA TUNNUM JSR BEGINTUN ;START THE TUNE DTOUT PLA ;UNSTACK REGISTERS TAY PLA TAX RTS * THIS ROUTINE TRIES TO GET A CHANNEL TO PUT A TUNE INTO. THIS IS DONE BY * GIVING AN OPEN CHANNEL IF AVAILABLE OR BUMPING SOMEONE IF NONE ARE OPEN. * IF THE PRIORITY IS TO LOW TO GET ANYTHING, FF IS RETURNED. * INPUT: PRIORITY OF REQUESTOR IN TUNTEMP0 * OUTPUT:CHANNEL IN X, $FF IF NO CHANNEL AVAILABLE * USES: X, Y GETCHANL LDX #$01 ;FIRST - SEE IF OPEN ACTIVE CHANNEL GCLOOP0 LDA TUNON,X ;SEE IF CHANNEL OPEN BNE GCNEXT0 RTS ;GOT IT - EASY GCNEXT0 DEX BPL GCLOOP0 LDX #$00 ;NOW, TRY TO BUMP ACTIVE CHANNEL LDA TUNPRIOR ;GET INDEX OF LOWER PRIORITY ACTIVE CNL CMP TUNPRIOR+1 BMI GCJMP0 INX GCJMP0 LDA TUNPRIOR,X ;SEE IF OUR PRIORITY HIGHER CMP TUNTEMP0 BPL GCNONE ;NO CHANNELS AVAILABLE JMP ENDTUNE ;HERE I DELETED STUFF TO HANDLE BACKUP CHANNELS GCNONE LDX #$FF ;NO CHANNELS AVAILABLE RTS * ROUTINE TO KILL A PARTICULAR TUNE - IF IT IS RUNNING * INPUT: TUNE NUMBER IN A * X AND Y ARE PRESERVED KILLTUNE STA TUNNUM ;SAVE IT TXA ;STACK REGISTERS PHA TYA PHA LDX #$01 ;CHECK ALL CHANNELS KTLOOP LDA TUNON,X ;SEE IF CHANNEL ON BEQ KTNEXT LDA TUNINDEX,X ;SEE IF HAS TUNE TO BE KILLED CMP TUNNUM BNE KTNEXT JSR ENDTUNE ;ERASE IT KTNEXT DEX BPL KTLOOP PLA ;UNSTACK REGISTERS TAY PLA TAX RTS * THIS ROUTINE ERASES ALL TUNES * X AND Y ARE PRESERVED CLEARTUN TXA ;STACK REGISTERS PHA TYA PHA LDX #$01 CTLOOP JSR ENDTUNE ;ERASE CURRENT TUNE DEX BPL CTLOOP PLA ;UNSTACK REGISTERS TAY PLA TAX RTS * THIS ROUTINE IS CALLED EVERY VBLANK TO TAKE CARE OF TUNES * REGISTERS ARE NOT SAVED TUNER LDX #$01 ;TWO TUNES CHANNELS, START WITH SECOND TUNLOOP LDA TUNON,X BNE TUNBODY STA AUDV0,X ;CHANNEL OFF - MAKE SURE VOLUME OFF JMP TUNNEXT TUNBODY LDA TUNBASE,X ;GET ADDRESS OF TUNE STA SOUNDZP LDA TUNBASE1,X STA SOUNDZP+1 DEC FREQTIME,X ;DO FREQUENCY BNE TUNCTL JSR TNXTFREQ ;TIME FOR NEXT FREQUENCY TUNCTL LDA CTLTIME,X ;DO CONTROL BEQ TUNVOL ;IS CTL CONSTANT? (STARTS AT 0) DEC CTLTIME,X BNE TUNVOL JSR TNXTCTL ;TIME FOR NEXT CTL TUNVOL LDA VOLTIME,X ;DO VOLUME BEQ TUNNEXT ;IS VOLUME CONSTANT? (STARTS AT 0) DEC VOLTIME,X BNE TUNNEXT JSR TNXTVOL ;TIME FOR NEXT VOLUME TUNNEXT DEX ;DONE WITH THAT TUNE, IS THERE ANOTHER? BPL TUNLOOP RTS ;ALL DONE * ROUTINES TO GET NEXT FREQUENCY, CTL, OR VOLUME * THIS ROUTINE GETS NEXT FREQUENCY TNXTFREQ LDY FREQOFF,X ;GET INDEX INTO TABLE LDA (SOUNDZP),Y ;GET FREQUENCY BMI TNFENDT ;IS THIS THE END OF THE TUNE? STA AUDF0,X INY LDA (SOUNDZP),Y ;GET DURATION STA FREQTIME,X INY TYA STA FREQOFF,X RTS TNFENDT CMP #$FF ;SEE IF TUNE OVER BEQ TNFEOVER CMP #$FE ;SEE IF TUNE REPEATS BEQ TNFEREPT INY ;ANOTHER TUNE COMING LDA (SOUNDZP),Y ;FIND OUT WHICH TUNE JSR BEGINTUN ;START TUNE JMP TNFEOUT TNFEREPT LDA TUNINDEX,X ;TUNE REPEATS - RESTART IT JSR BEGINTUN ;START TUNE JMP TNFEOUT TNFEOVER JSR ENDTUNE ;TUNE FINISHED TNFEOUT PLA ;END OF TUNE PLA ;GET RID OF WHERE WE ARE RTS'ING TO JMP TUNLOOP ;UPDATE THIS CHANNEL * THIS ROUTINE GETS NEXT CONTROL BYTE TNXTCTL LDY CTLOFF,X ;GET INDEX INTO TABLE LDA (SOUNDZP),Y ;GET FREQUENCY STA AUDC0,X INY LDA (SOUNDZP),Y ;GET DURATION STA CTLTIME,X INY TYA STA CTLOFF,X RTS * THIS ROUTINE GETS NEXT VOLUME BYTE TNXTVOL LDY VOLOFF,X ;GET INDEX INTO TABLE LDA (SOUNDZP),Y ;GET FREQUENCY STA AUDV0,X INY LDA (SOUNDZP),Y ;GET DURATION STA VOLTIME,X INY TYA STA VOLOFF,X RTS * THIS ROUTINE CLEARS OUT A TUNE CHANNEL * INPUT: X IS CHANNEL ENDTUNE LDA #$00 STA TUNON,X ;INDICATE CHANNEL CLEAR STA TUNINDEX,X ;CLEAR TUNE INDEX ;HERE WAS BACKUP CHANNEL STUFF ETOUT RTS * THIS ROUTINE STARTS A TUNE IN A CHANNEL * INPUT: X IS CHANNEL, A IS TUNE * USES: Y BEGINTUN TAY ;PUT TUNE IN Y STA TUNINDEX,X ;SET THE TUNE INDEX LDA TBASE,Y ;SET THE BASE ADDRESS FOR TUNE STA TUNBASE,X LDA TBASE1,Y STA TUNBASE1,X LDA #$00 ;FREQUENCY IS AT START OF TUNE STA FREQOFF,X LDA TCTLOFF,Y ;SET CONTROL OFFSET STA CTLOFF,X LDA TVOLOFF,Y ;SET VOLUME OFFSET STA VOLOFF,X LDA TPRIOR,Y ;SET PRIORITY STA TUNPRIOR,X LDA #$01 ;SET FREQ, CTL, AND VOL TO BE SET STA FREQTIME,X ; NEXT VBLANK (TICK DOWN TO 0 EACH) STA CTLTIME,X STA VOLTIME,X STA TUNON,X ;AND TURN THE TUNE ON! RTS * THIS ROUTINE MOVES A TUNE FROM ONE CHANNEL TO ANOTHER * INPUT: Y IS FROM CHANNEL, X IS TO CHANNEL ; THIS ROUTINE IS NO LONGER NECESSARY * DATA FOR TUNES * TUNE TABLES, BASE ADDRESSES FOR TUNES AND THE OFFSETS WITHIN THE TUNES WHERE * THE CTL AND VOL INFORMATION START TBASE DB L(TMCS),L(TFPICK),L(TCREDIE),L(TSKULL0),L(TSKULL1),L(TEXTRA) DB L(TRACKA),L(TRACKB),L(TMCDIE) TBASE1 DB H(TMCS),H(TFPICK),H(TCREDIE),H(TSKULL0),H(TSKULL1),H(TEXTRA) DB H(TRACKA),H(TRACKB),H(TMCDIE) TCTLOFF DB 021,023,015,017,017,009,078,111,009 TVOLOFF DB 023,039,019,019,019,011,206,159,011 TPRIOR DB 005,020,006,015,015,025,018,018,022 * TUNE 0 - MUTANT CLONE SHOOTING SMCS EQU 0 ;TUNE 0 TMCS DB $02,$01,$03,$01,$04,$01,$05,$01,$06,$01 ;FREQ DB $07,$01,$08,$01,$09,$01,$0A,$01,$0B,$01,$FF DB $06,$00 ;CTL DB $09,$00 ;VOL * TUNE 1 - FAMILY PICKUP SOUND SFPICK EQU 1 TFPICK DB $15,$09,$0D,$03,$15,$03,$14,$03,$0C,$03 DB $15,$03,$13,$03,$0B,$03,$15,$03,$12,$03 DB $0A,$03,$FF DB $06,$06,$0D,$06,$06,$03,$0D,$06,$06,$03 DB $0D,$06,$06,$03,$0D,$06 DB $09,$00 * TUNE 2 - GENERIC EXPLOSION SCREDIE EQU 2 TCREDIE DB $02,$03,$03,$03,$04,$03,$05,$03,$06,$03 DB $15,$03,$19,$03,$FF DB $08,$0F,$02,$06 DB $09,$03,$07,$03,$06,$03,$05,$03,$04,$03 DB $06,$03,$03,$03 * TUNE 3 - SKULL AND CROSSBONES SCREAM CHANNEL 0 SSKULL0 EQU 3 TSKULL0 DB $0C,$04,$0D,$04,$0E,$04,$0F,$04,$10,$04 DB $11,$04,$12,$04,$13,$04,$FF DB $04,$00 DB $09,$00 * TUNE 4 - SKULL AND CROSSBONES SCREAM CHANNEL 1 SSKULL1 EQU 4 TSKULL1 DB $1F,$04,$1E,$04,$1D,$04,$1C,$04,$1B,$04 DB $1A,$04,$19,$04,$18,$04,$FF DB $04,$00 DB $02,$04,$03,$04,$04,$04,$05,$04,$06,$04 DB $05,$04,$04,$04,$03,$04,$FF * TUNE 5 - EXTRA MAN SEXTRA EQU 5 TEXTRA DB $03,$02,$04,$02,$05,$02,$06,$02,$FF DB $0F,$00 DB $09,$00 * TUNE 6 - BETWEEN RACK SOUND PART A SRACKA EQU 6 TRACKA DB $1F,$04,$1D,$04,$1B,$04,$1A,$04,$18,$04 ;FREQ DB $17,$04,$16,$04,$14,$04,$13,$04,$12,$04 DB $11,$04,$10,$04,$0F,$04,$0E,$04,$0D,$04 DB $0C,$04,$0B,$04,$0A,$04,$09,$02,$1F,$02 DB $08,$02,$1D,$02,$07,$02,$1B,$02,$06,$02 DB $1A,$02,$05,$02,$18,$02,$04,$02,$17,$02 DB $15,$04,$14,$04,$13,$04,$12,$04,$11,$04 DB $10,$04,$0F,$04,$0E,$04,$FD,$07 DB $06,$02,$0D,$02,$06,$02,$0D,$02 ;CTL DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$0D,$02,$06,$02,$0D,$02 DB $06,$02,$04,$02,$06,$02,$04,$02 DB $06,$02,$04,$02,$06,$02,$04,$02 DB $06,$02,$04,$02,$06,$02,$04,$02 DB $0D,$02,$04,$02,$0D,$02,$04,$02 DB $0D,$02,$04,$02,$0D,$02,$04,$02 DB $0D,$02,$04,$02,$0D,$02,$04,$02 DB $0D,$02,$04,$02,$0D,$02,$04,$02 DB $09,$00 ;VOL * TUNE 7 - BETWEEN RACK SOUND PART B SRACKB EQU 7 TRACKB DB $0D,$04,$09,$02 ;FREQ DB $13,$02,$18,$02,$1D,$02,$0B,$02,$0F,$02 DB $10,$02,$16,$02,$0A,$02,$12,$02,$15,$02 DB $1D,$02,$0D,$02,$0E,$02,$09,$02,$13,$02 DB $18,$02,$1D,$02,$0B,$02,$0F,$02,$10,$02 DB $16,$02,$0A,$02,$12,$02,$15,$02,$1D,$02 DB $0D,$02,$0E,$02,$09,$02,$13,$02,$18,$02 DB $1D,$02,$0B,$02,$0F,$02,$10,$02,$16,$02 DB $0A,$02,$12,$02,$15,$02,$1D,$02,$0D,$02 DB $0E,$02,$09,$02,$13,$02,$18,$02,$1D,$02 DB $0B,$02,$0F,$02,$10,$02,$16,$02,$0A,$02 DB $12,$02,$15,$02,$1D,$02,$FF DB $0D,$02,$04,$04,$0D,$06,$06,$04 ;CTL DB $04,$06,$0D,$06,$06,$04,$04,$02 DB $0D,$06,$06,$04,$04,$06,$0D,$06 DB $06,$04,$04,$02,$0D,$06,$06,$04 DB $04,$06,$0D,$06,$06,$04,$04,$02 DB $0D,$06,$06,$04,$04,$06,$0D,$06 DB $09,$00 ;VOL * TUNE 8 - MC DEATH SOUND SMCDIE EQU 8 TMCDIE DB $0A,$04,$0C,$04,$0F,$04,$1F,$80,$FF DB $08,$00 DB $09,$0C,$0F,$10,$0A,$10,$09,$10,$07,$10 DB $05,$10,$04,$10,$03,$0C,$02,$0C,$01,$0C *********** * TEMPORARY EQUIVALENCES FOR ROBOTRON *********** *SSKULL EQU SPACDTH *SFPICK EQU SANIM10 *SMCS EQU SMUNCH *SCREDIE EQU SFRTBNC *SMCDIE EQU SENERGA * TUNE # - ;S EQU # ;T DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ; DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00 *********** END OF RSOUNDS.S ************* EJE