home *** CD-ROM | disk | FTP | other *** search
Text File | 1978-10-10 | 41.7 KB | 2,055 lines |
-
- Include "Equ.s"
- Translate equ -30
-
- ******************************************************************
- * ** * * **** **** *** ** **** *** ***
- * * * ** ** * * * * * * * * * *
- * **** * ** * * * **** **** **** **** * *
- * * * * * * * * * * * * * * *
- * * * * * **** **** **** * * **** *** ***
- ******************************************************************
- *
- * AMOS MUSICAL ROUTINES
- *
- * Version 1.1
- * By Francois Lionet
- * AMOS (c) Mandarin / Jawx 1990
- *
- * This source code is public domain
- *
- ******************************************************************
- *
- * Here is the main AMOS extension. It includes all music
- * instructions, and is a perfect example of how to create a
- * extension for AMOS.
- * It has been assembled with GENAM2.
- *
- * This code is certainely not perfect, some parts may seem to
- * you improvable, and sure are! If you make changes to it, be sure
- * keep compatibility with the previous version. Create a version for
- * each new change so that AMOS music extension don`t become a
- * jungle!
- * Some labels may look rather French to you, but sorry, it is
- * my native language!
- *
- * When you program an extension, try to program it in RELATIVE
- * code, using adress register and index. The COMPILER will only
- * accept relative code.
- *
- * Thanks to Andreas Tadic, the author of GMC for inspiration in
- * some parts of the music routine...
- *
- ******************************************************************
-
- ******************************************************************
- * AMOS INTERFACE
-
- ******* COLD START
- * This must be at the beginning of your program!
- * It is called just after loading...
- *
- * On Entry:
- * A0= Branch table
- * A1= Current intuition.library base
- * A2= Current graphic.library base
- * A3= Current diskfont.library base
- * A5= AMOS data zone address
- * You must return
- * A0= Token table
- * A1= Welcome message
- * A2= Routine called by screen reset
- * A3= Routine called on Quit
- * D0= False/true-> ERROR
- * D1= Number of extension. This number MUST be the same
- * than the extension number in the extension list
- * D2= Address of a routine called each time a memory bank
- * has been changed, zero if not to be called
- *
- * If D1<>number of extension or D0=true, AMOS does not load!
- *
- movem.l a4-a6,-(sp)
-
- * If AMOS data zone, stands 8 long words allowing you to simply
- * put a patch in the VBL interrupt. The first on is at VBLRout.
- * At each VBL, AMOS explores this list, and call all address <> 0
- * It stops at the FIRST zero. The music patch is the first routine
- * called.
- lea MusInt(pc),a1 * Interrupt routine
- move.l a1,VBLRout(a5) * Branch
- lea MusAdr(pc),a1
- move.l a0,(a1) * Store address of BRANCH TABLE
- lea MB(pc),a3 * Base of music parameters
- lea BkCheck(pc),a0 * Address of CHECK MUSIC BANK
- move.l a0,d2
- lea AdMB(pc),a1
- move.l a3,(a1)
- lea Tk(pc),a0 * Address of TOKEN TABLE
- lea MusWel(pc),a1 * Address of WELCOME MESSAGE
- lea MusDef(pc),a2 * Address of SCREEN RESET
- lea MusEnd(pc),a3 * Address of QUIT
- moveq #0,d1 * Returns NUMBER OF EXTENSION
- movem.l (sp)+,a4-a6
- moveq #0,d0 * NO ERRORS
- rts
-
- ******* SCREEN RESET
- * Each time a DEFAULT occurs, this routine is called. If you
- * do not want any effect, make it point to a RTS
- MusDef:
- lea MB(pc),a3
- * Init narrator
- bsr NarInit
- * Init musique
- bsr RazWave * Reset waves
- move.l Buffer(a5),a0 * Draw square wave
- move.l a0,a1
- moveq #127,d0
- MuDf1 move.b #-127,128(a0)
- move.b #127,(a0)+
- dbra d0,MuDf1
- moveq #0,d1 * 0-> Noise
- bsr NeWave
- moveq #1,d1 * 1-> Square wave
- bsr NeWave
- move.w #LNoise/2-1,d2 * Draw first noise
- move.w BSeed-MB(a3),d1
- move.l WaveBase-MB(a3),a0
- lea WaveDeb(a0),a0
- MuDf2 add.w Circuits+6,d1
- mulu #$3171,d1
- lsr.l #8,d1
- move.w d1,(a0)+
- dbra d2,MuDf2
- move.w d1,BSeed-MB(a3)
- moveq #56,d0 * Default settings
- moveq #%1111,d1
- bsr Vol
- bsr MVol
- move.w #5,SamBank-MB(a3) * Sample bank=5
- moveq #0,d0 * Sam loop off
- moveq #-1,d1
- bsr SL0
- bsr MuInit
- rts
-
- ******* QUIT
- * Here you should restore everything to normal, close
- * all opened libraries, give all reserved memory back to
- * the system...
- MusEnd: lea MB(pc),a3
- * Plus de routine VBL
- clr.l VBLRout(a5) * No more routine
- * End narrator (if there)
- tst.l TranBase-MB(a3)
- beq.s NarEnd
- lea WriteRep-MB(a3),a1
- move.l $4,a6
- jsr RemPort(a6)
- lea TalkIO-MB(a3),a1
- jsr CloseDev(a6)
- move.l TranBase-MB(a3),a1
- jsr CloseLib(a6)
- * End music
- NarEnd bsr MOff
- moveq #%1111,d0
- bsr EnvOff
- bsr RazWave
- lea Circuits,a0
- move.w #$000F,DmaCon(a0)
- move.w #%0000011110000000,IntReq(a0)
- move.w #%0000011110000000,IntEna(a0)
- clr.w $a8(a0)
- clr.w $b8(a0)
- clr.w $c8(a0)
- clr.w $d8(a0)
- rts
-
- ******* Now follow a tricky thing to allow AMAL to grab the address
- * of the vumeters. AMAL will get the address of the music extension
- * BkCheck routine, look 4 bytes before, and get the address of the
- * voices volume level
- AdMB dc.l 0
- ******* LOOK FOR MUSIC BANK
- * Authorised registers: D0-D7/A0-A3
- BkCheck lea MB(pc),a3
- move.l MusBank-MB(a3),d0 * Address of OLD music bank
- move.l 2*8(a0),d1 * Address of ACTUAL music bank
- beq.s BkNo * 8 bytes per bank (here bank 3)
- move.l d1,a1 * Looks for "Musi"
- move.l (a1),d2
- cmp.l BkMus-MB(a3),d2
- bne.s BkNo
- lea 8(a1),a1
- moveq #0,d1 * Performs a check sum
- add.l (a1),d1
- add.l 4(a1),d1
- add.l 8(a1),d1
- add.l 12(a1),d1
- cmp.l d0,a1
- bne.s BkNew
- cmp.l MusCheck-MB(a3),d1
- bne.s BkNew
- * Same bank! Do nothing!
- rts
- * No more bank!
- BkNo tst.l d0
- beq.s BkNo1
- bsr MuInit
- clr.l MusBank-MB(a3)
- BkNo1 rts
- * A NEW bank
- BkNew move.l a1,MusBank-MB(a3)
- move.l d1,MusCheck-MB(a3)
- bsr MuInit
- move.l MusBank-MB(a3),a0
- move.l a0,a1
- add.l (a0),a1
- move.l a1,BankInst-MB(a3)
- move.l a0,a1
- add.l 4(a0),a1
- move.l a1,BankSong-MB(a3)
- add.l 8(a0),a0
- move.l a0,BankPat-MB(a3)
- rts
-
- ******* Call normal error messages
- OOMem moveq #24,d0 * Out of mem
- bra.s IError
- IFonc: moveq #23,d0 * Function call
- IError: move.l MusAdr(pc),a0 * No need to care about SP!
- jmp 4(a0)
- ******* Call customized error messages
- WNDef moveq #0,d0
- bra.s Custom
- SNDef moveq #1,d0
- bra.s Custom
- BNSam moveq #2,d0
- bra.s Custom
- STSho moveq #3,d0
- bra.s Custom
- W0Res moveq #4,d0
- bra.s Custom
- MnRes moveq #5,d0
- bra.s Custom
- MNDef moveq #6,d0
- Custom: moveq #0,d1 * Error can be trapped
- lea MusErr(pc),a0 * Your list
- move.l MusAdr(pc),a1
- jmp 8(a1)
- ******* Debugging facility
- * If you call this routine, it restore screen, leaves
- * everything opened, and do an ILLEGAL instruction to come back
- * to MONAM2. A0 holds the current PC address, do just do a PC=A0
- * to come just after the JSR IBUG!
- * Really usefull for annoying bugs! Of course, you can't call
- * it under insterrupts, and you have to do a RESET after...
- IBug: move.l MusAdr(pc),a0
- jmp (a0)
-
- ***********************************************************
- * Now, the code!
- *
- * How to get the parameters?
- *
- * When an instruction or function is called, you get the parameters
- * pushed in A3. Remember that you unpile them in REVERSE order than
- * the instruction syntax.
- * As you have a entry point for each set of parameters, you know
- * how many are pushed...
- * - INTEGER: move.l (a3)+,d0
- * - STRING: move.l (a3)+,a0
- * move.w (a0)+,d0
- * A0---> start of the string.
- * D0---> length of the string
- * - FLOAT: move.l (a3)+,d0
- * fast floatting point format.
- * IMPORTANT POINT: you MUST unpile the EXACT number of parameters,
- * to restore A3 to its original level. If you do not, you will not
- * have a immediate error, and AMOS will certainely crash on next
- * UNTIL / WEND / ENDIF / NEXT etc... You do not have to care about it
- * when an error occurs...
- *
- * You must preserve A4 to A6. All other registers can be freely
- * modified.
- * You end a routine by a RTS.
- *
- * To send a function`s parameter back to AMOS, you load it in D3,
- * and put its type in D2:
- * moveq #0,d2 for an integer
- * moveq #1,d2 for a float
- * moveq #2,d2 for a string
- *
- * THE JUMP TABLE
- *
- * The address given to you during initialisation process
- * points to a usefull BRA table, to have quick access to some
- * important AMOS routines. Here are the offsets of this routines:
- *
- * bra JBug ;00- Debugging facility
- * bra RunErr ;04- Normal error
- * bra ERunErr ;08- Specific error
- * bra BkAd ;0C- D3.l (number of bank-1)->A0 Bank address
- * bra Tests ;10- Performs update
- * bra WaitRout ;14- Wait routine (see play)
- * bra GetEc ;18- Get screen address D0.l= screen number
- * bra AdOuBank ;1C- Address or memory bank? (D3.l)
- * bra EffBank ;20- Erases bank #D3.l
- *
-
- ***********************************************************
- * NARRATOR!
- * This part of code is certainely perfectible, as it is not
- * really "safe"...
-
- ******* Open narrator
- OpNar move.l TranBase(pc),d0
- bne.s OpNarOk
- movem.l a3-a6,-(sp)
- lea MB(pc),a3
- sub.l a1,a1 * Narrator.device
- move.l $4,a6
- jsr FindTask(a6)
- lea WriteRep-MB(a3),a1
- move.l d0,$10(a1)
- jsr AddPort(a6)
- lea TalkIo-MB(a3),a1
- moveq #0,d0
- moveq #0,d1
- lea NarDevice-MB(a3),a0
- jsr OpenDev(a6)
- tst.l d0
- bne OpNarE
- bsr NarInit
- lea TranName-MB(a3),a1 * Translator.library
- moveq #0,d0
- jsr OpenLib(a6)
- move.l d0,TranBase-MB(a3)
- beq OpNarE
- movem.l (sp)+,a3-a6
- OpNarOk rts
- OpNarE movem.l (sp)+,a3-a6
- NoNar moveq #7,d0
- bra Custom
-
- ******* Init narrator (if here)!
- NarInit lea TalkIO-MB(a3),a1
- lea WriteRep-MB(a3),a0
- move.l a0,14(a1)
- move.w #150,48(a1)
- move.w #110,50(a1)
- clr.w 52(a1)
- clr.w 54(a1)
- lea Amaps-MB(a3),a0
- move.l a0,56(a1)
- move.w #4,60(a1)
- move.w #63,62(a1)
- move.w #22200,64(a1)
- rts
-
- ******* SAY a$[,multi]
- ISay2: bsr OpNar
- move.l (a3)+,d7
- bra.s ISay
- ISay1: bsr OpNar
- moveq #0,d7
- ISay: moveq #%0000,d0
- bsr VOnOf
- lea MB(pc),a0
- clr.w EnvOn-MB(a0)
- clr.w Noise-MB(a0)
- move.l (a3)+,a0
- moveq #0,d0
- move.w (a0)+,d0
- move.l Buffer(a5),a1
- move.l #1024,d1
- movem.l a3-a6,-(sp)
- move.l TranBase(pc),a6
- jsr Translate(a6)
- tst.w d0
- bne.s SayX
- lea TalkIO(pc),a1
- move.w #3,28(a1)
- move.l #1024,36(a1)
- move.l Buffer(a5),40(a1)
- move.l ExecBase,a6
- tst.w d7
- bne.s ISayA
- jsr DoIO(a6)
- bra.s SayX
- ISayA jsr SendIO(a6)
- SayX movem.l (sp)+,a3-a6
- moveq #%1111,d0
- bsr VOnOf
- rts
- ******* SET TALK sex,mode,pitch,rate
- ITalk bsr OpNar
- move.l #EntNul,d0
- lea TalkIO(pc),a1
- move.l (a3)+,d1
- cmp.l d0,d1
- beq.s IRd1
- cmp.w #40,d1
- bcs IFonc
- cmp.w #400,d1
- bhi IFonc
- move.w d1,48(a1)
- IRd1 move.l (a3)+,d1
- cmp.l d0,d1
- beq.s IRd2
- cmp.w #65,d1
- bcs IFonc
- cmp.w #320,d1
- bhi IFonc
- move.w d1,50(a1)
- IRd2 move.l (a3)+,d1
- cmp.l d0,d1
- beq.s IRd3
- and.w #$0001,d1
- move.w d1,52(a1)
- IRd3 move.l (a3)+,d1
- cmp.l d0,d1
- beq.s IRd4
- and.w #$0001,d1
- move.w d1,54(a1)
- IRd4 rts
-
- ***********************************************************
- * MUSIC INSTRUCTION
-
- ******* BELL
- Bell0 moveq #0,d3
- moveq #70,d2
- moveq #%1111,d1
- moveq #1,d5
- lea EnvBell(pc),a0
- move.l a0,d6
- bra GoBel
- Bell1 moveq #0,d3
- move.l (a3)+,d2
- moveq #%1111,d1
- moveq #1,d5
- lea EnvBell(pc),a0
- move.l a0,d6
- bra GoBel
- ******* BOOM
- Boom moveq #0,d3
- moveq #36,d2
- moveq #0,d5
- lea EnvBoom(pc),a0
- move.l a0,d6
- bra.s Shout
- ******* SHOOT
- Shoot moveq #0,d3
- moveq #60,d2
- moveq #0,d5
- lea EnvShoot(pc),a0
- move.l a0,d6
- * Gives a stereo effect
- Shout: clr.w d0
- bsr VOnOf
- moveq #%1000,d1
- Shot movem.l d0-d7,-(sp)
- bsr GoShot
- movem.l (sp)+,d0-d7
- addq.w #1,d2
- lsr.w #1,d1
- bcc.s Shot
- rts
-
- ******* VOLUME n
- IVol1 move.l (a3)+,d0
- moveq #%1111,d1
- bsr Vol
- bsr MVol
- rts
- ******* VOLUME voice,n
- IVol2 move.l (a3)+,d0
- move.l (a3)+,d1
- * Set voices volume level
- Vol cmp.l #64,d0
- bcc IFonc
- moveq #0,d2
- lea EnvBase(pc),a0
- Vol1 btst d2,d1
- beq.s Vol2
- move.w d0,EnvDVol(a0)
- Vol2 lea EnvLong(a0),a0
- addq.w #1,d2
- cmp.w #4,d2
- bcs.s Vol1
- rts
-
- ******* PLAY note,length
- IPlay2 move.l (a3)+,d3
- bmi IFonc
- move.l (a3)+,d2
- moveq #%1111,d1
- moveq #-1,d5
- moveq #0,d6
- bra.s GoBel
- ******* Play voice,note,length
- IPlay3 move.l (a3)+,d3
- bmi IFonc
- move.l (a3)+,d2
- move.l (a3)+,d1
- moveq #-1,d5
- moveq #0,d6
- GoBel cmp.l #96,d2 * <96?
- bhi IFonc
- move.w d1,d0 * Stop voices
- eor.w #$000F,d0
- bsr VOnOf
- GoShot move.l a3,-(sp)
- lea Circuits,a2
- lea MB(pc),a3
- move.w EnvOn-MB(a3),d7
- clr.w EnvOn-MB(a3)
- * Explores all 4 voices
- moveq #0,d0
- move.w d1,d4
- moveq #3,d1
- IPl1 btst d1,d4
- beq.s IPl2
- bsr VPlay
- IPl2 dbra d1,IPl1
- ******* Start!
- IPlX move.w #$1f4,d1
- IPlX0 dbra d1,IPlX0
- bset #15,d0
- move.w d0,DmaCon(a2)
- move.w d7,EnvOn-MB(a3)
- move.l (sp)+,a3
- * Wait?
- tst.l d3
- beq.s IPlX1
- move.l MusAdr(pc),a0 * Call the AMOS wait routine
- jsr $14(a0)
- IPlX1 rts
-
- ******* Play voice D1: WAVE orSAMPLE
- * Note D2
- VPlay movem.l d0-d7/a0-a2,-(sp)
- bclr d1,Noise-MB(a3) * No more random
- tst.w d2
- beq VSil
- addq.w #3,d2
- move.w d5,d0 * Forced wave? (bell)
- bpl.s VPl0
- move.w d1,d0 * Wave or Sample?
- lsl.w #1,d0
- lea Waves(pc),a0
- move.w 0(a0,d0.w),d0
- bmi VPl2
-
- * Play WAVE!
- VPl0 beq VPl4
- moveq #0,d3
- bset d1,d3
- move.w d3,DmaCon(a2) * Stop voice
- lea $a0(a2),a2
- move.w d1,d3
- lsl.w #4,d3
- add.w d3,a2 * a2-> I/O
- movem.l d1-d3/a2,-(sp)
- move.w d0,d1
- bsr WaveAd
- beq WNDef
- move.l a2,a1
- movem.l (sp)+,d1-d3/a2
- pea WaveEnv(a1)
- lea WaveDeb(a1),a1
- subq.w #1,d2
- move.w d2,d3
- ext.l d3
- divu #12,d3
- lsl.w #2,d3
- lea TFreq-MB(a3),a0
- add.w d3,a0
- add.w (a0)+,a1
- move.l a1,(a2) * AudAd
- move.w (a0)+,d3
- move.w d3,4(a2) * AudLen
- lsl.w #1,d3
- lea TNotes-MB(a3),a1
- lsl.w #1,d2
- mulu 0(a1,d2.w),d3
- move.l MusClock-MB(a3),d2
- divu d3,d2
- cmp.w #124,d2
- bcc.s VPl1
- moveq #124,d2
- VPl1: move.w d2,6(a2) * AudPer
- * Start enveloppe
- move.l (sp)+,d5
- tst.l d6 * Fixed enveloppe? (bell / shoot)
- bne.s VPl1a
- move.l d5,d6
- VPl1a lea EnvBase-MB(a3),a0
- move.w d1,d0
- mulu #EnvLong,d0
- add.w d0,a0
- move.l d6,EnvAd(a0)
- move.l d6,EnvDeb(a0)
- clr.w EnvVol(a0)
- bsr MuIntE
- movem.l (sp)+,a0-a2/d0-d7
- bset d1,d0
- bset d1,d7
- rts
- ******* Silence!
- VSil moveq #0,d0
- bset d1,d0
- move.w d0,DmaCon(a2)
- movem.l (sp)+,a0-a2/d0-d7
- bclr d1,d7
- rts
- ******* Play SAMPLE
- VPl2 move.l a2,-(sp)
- move.w d2,-(sp)
- neg.w d0
- bsr GetSam
- move.w (sp)+,d0
- move.l (sp)+,a2
- VPl3 lea TNotes-MB(a3),a0
- lsl.w #1,d0
- mulu -2(a0,d0.w),d3
- divu #440,d3
- bra SPl0
- ******* Play NOISE
- VPl4 bset d1,Noise-MB(a3)
- move.w d2,d0
- move.l WaveBase-MB(a3),a1
- lea WaveEnv(a1),a0
- lea WaveDeb(a1),a1
- move.l #LNoise,d2
- move.l #2000,d3
- tst.l d6
- bne.s VPl3
- move.l a0,d6
- bra.s VPl3
-
- ******* PLAY OFF (voice)
- IPlOf0 moveq #%1111,d0
- bra.s PlOf
- IPlOf1 move.l (a3)+,d0
- PlOf move.l a3,-(sp)
- lea MB(pc),a3
- bsr EnvOff
- move.l (sp)+,a3
- rts
-
- ***********************************************************
- * SAMPLE INSTRUCTIONS
-
- ******* SAM BANK n
- ISBank move.l (a3)+,d0
- bls IFonc
- cmp.l #16,d0
- bhi IFonc
- lea SamBank(pc),a0
- move.w d0,(a0)
- rts
- ******* SAMLOOP ON
- ISLOn1 moveq #-1,d0
- SLoop move.l (a3)+,d1
- bra.s Sl0
- ISLOn0 moveq #-1,d0
- moveq #%1111,d1
- bra.s Sl0
- ******* SAMLOOP OFF
- ISLOf1 moveq #0,d0
- move.l (a3)+,d1
- bra.s Sl0
- ISLOf0 moveq #0,d0
- moveq #%1111,d1
- SL0 moveq #0,d2
- lea EnvSam(pc),a0
- Sl1 btst d2,d1
- beq.s Sl2
- move.w d0,8(a0)
- Sl2 lea $10(a0),a0
- addq.w #1,d2
- cmp.w #4,d2
- bcs.s Sl1
- rts
- ******* NOISE TO voice
- INoTo move.l (a3)+,d1
- moveq #0,d0
- bra.s ISmt
- ******* SAMPLE n TO voice
- ISamTo move.l 4(a3),d0
- bsr GetSam
- move.l (a3)+,d1
- move.l (a3)+,d0
- neg.w d0
- * Poke D1-> waves
- ISmt lea Waves(pc),a0
- moveq #0,d2
- ISmt1 btst d2,d1
- beq.s ISmt2
- move.w d0,(a0)
- ISmt2 addq.l #2,a0
- addq.w #1,d2
- cmp.w #4,d2
- bcs.s ISmt1
- rts
- ******* SAM PLAY number
- ISam1 move.l (a3)+,d0
- bsr GetSam
- moveq #%1111,d1
- moveq #0,d6
- bra GoSam
- ******* SAM PLAY voix,number
- ISam2 move.l (a3)+,d0
- bsr GetSam
- move.l (a3)+,d1
- moveq #0,d6
- bra GoSam
- ******* SAM PLAY voix,number,frequence
- ISam3 move.l 4(a3),d0
- bsr GetSam
- move.l (a3)+,d3
- cmp.l #500,d3
- ble IFonc
- addq.l #4,a3
- move.l (a3)+,d1
- moveq #0,d6
- bra GoSam
- ******* SAM RAW voice,ad,length,freq
- ISamR move.l (a3)+,d3
- cmp.l #500,d3
- ble IFonc
- move.l (a3)+,d2
- cmp.l #256,d2
- ble IFonc
- move.l (a3)+,a1
- move.l (a3)+,d1
- moveq #0,d6
- GoSam: move.l a3,-(sp)
- lea MB(pc),a3
- move.w d1,d0 * Stops music
- eor.w #$000F,d0
- bsr VOnOf
- lea Circuits,a2
- move.w EnvOn-MB(a3),d7
- clr.w EnvOn-MB(a3)
- * Do all voices
- moveq #0,d0
- move.w d1,d4
- moveq #3,d1
- ISp2b btst d1,d4
- beq.s ISp2c
- bsr SPlay
- ISp2c dbra d1,ISp2b
- * Start!
- ISpX move.w #$1f4,d1
- ISpX1 dbra d1,ISpX1
- bset #15,d0
- move.w d0,DmaCon(a2)
- move.w d7,EnvOn-MB(a3)
- move.l (sp)+,a3
- rts
-
- ******* Find a sample -> A0
- GetSam move.l d0,-(sp)
- move.w SamBank(pc),d3
- ext.l d3
- beq IFonc
- move.l MusAdr(pc),a0
- jsr $0C(a0)
- move.l -8(a0),d0
- cmp.l BkSam(pc),d0
- bne BNSam
- * Get sample characteristics1
- move.l (sp)+,d0
- bls IFonc
- cmp.w (a0),d0
- bhi SNDef
- lsl.w #2,d0
- move.l 2-4(a0,d0.w),d0
- beq SNDef
- add.l d0,a0
- move.w 8(a0),d3
- ext.l d3
- move.l 10(a0),d2
- lea 14(a0),a1
- rts
-
- ******* SAMPLAY routine
- * A1= Sample
- * D3= Freq
- * D2= Long
- * D1= Voice
- SPlay: movem.l d0-d7/a0-a2,-(sp)
- bclr d1,Noise-MB(a3)
- SPl0 moveq #0,d0
- bset d1,d0 * Stop voice
- move.w d0,DmaCon(a2)
-
- lea $a0(a2),a2
- move.w d1,d4
- lsl.w #4,d4
- add.w d4,a2 * a2-> I/O
- move.l a1,(a2) * AudAd
- move.w d2,d4
- lsr.w #1,d4
- move.w d4,4(a2) * AudLen
- move.l MusClock-MB(a3),d4
- divu d3,d4
- bvc.s SPl1
- moveq #124,d4
- SPl1 cmp.w #124,d4
- bcc.s SPl2
- moveq #124,d4
- SPl2: move.w d4,6(a2) * AudPer
- * Starts enveloppe
- move.l d6,a1
- tst.l d6
- bne SPl4
- lea EnvSam-MB(a3),a1
- move.w d1,d0
- lsl.w #4,d0
- add.w d0,a1
- mulu #50,d2
- divu d3,d2
- subq.w #1,d2
- bhi.s SPl3
- moveq #1,d2
- SPl3 move.w d2,4(a1)
- SPl4 lea EnvBase-MB(a3),a0
- move.w d1,d0
- mulu #EnvLong,d0
- add.w d0,a0
- move.l a1,EnvAd(a0)
- move.l a1,EnvDeb(a0)
- clr.w EnvVol(a0)
- bsr MuIntE
- * Fini!
- movem.l (sp)+,d0-d7/a0-a2
- bset d1,d0
- bset d1,d7
- rts
-
- ***********************************************************
- * WAVE INSTRUCTION SET
-
- ******* WAVE n TO n
- IWave: move.l 4(a3),d1
- bmi IFonc
- bsr WaveAd
- beq WNDef
- move.l (a3)+,d1
- move.l (a3)+,d0
- bra ISmt
- ******* SET WAVE n,a$
- ISWave: move.l (a3)+,a1
- move.w (a1)+,d1
- cmp.w #256,d1
- bcs STSho
- move.l (a3)+,d1
- bls IFonc
- move.l a3,-(sp)
- lea MB(pc),a3
- bsr NeWave
- bne OOMem
- move.l (sp)+,a3
- rts
- ******* DEL WAVE
- IDWave1 move.l (a3)+,d1
- bmi IFonc
- beq W0Res
- cmp.l #1,d1
- beq W0Res
- move.l a3,-(sp)
- lea MB(pc),a3
- moveq #%1111,d0
- bsr EnvOff
- bsr WaveAd
- beq WNDef
- bsr WaveDel
- bsr NoWave
- move.l (sp)+,a3
- rts
- ******* SET ENVEL n,n TO n,v
- ISEnv move.l (a3)+,d4
- cmp.l #64,d4
- bcc IFonc
- move.l (a3)+,d3
- move.l (a3)+,d5
- bmi IFonc
- cmp.l #7,d5
- bcc IFonc
- move.l (a3)+,d1
- bmi IFonc
- tst.w d5
- bne.s ISe1
- tst.w d3
- bls IFonc
- ISe1 move.l a3,-(sp)
- lea MB(pc),a3
- bsr WaveAd
- beq WNDef
- lsl.w #2,d5
- lea WaveEnv(a2,d5.w),a2
- move.w d3,(a2)+
- move.w d4,(a2)+
- clr.w (a2)
- move.l (sp)+,a3
- rts
- ******* RAZ WAVES
- RazWave movem.l a2/d0-d2,-(sp)
- moveq #%1111,d0
- bsr EnvOff * Stop all voices
- lea WaveBase-MB(a3),a2 * Erase all instruments
- move.l a2,d2
- RzW1 move.l d2,a2
- move.l (a2),d0
- beq.s RzW2
- move.l d0,a2
- bsr WaveDel
- bra.s RzW1
- RzW2 bsr NoWave
- movem.l (sp)+,a2/d0-d2
- rts
- * Plus de Waves speciales
- NoWave lea Waves(pc),a0 * Default waves
- move.w #1,(a0)+
- move.w #1,(a0)+
- move.w #1,(a0)+
- move.w #1,(a0)+
- rts
-
- ******* NEW WAVES
- * A1= Array address
- * D1= # to create
- NeWave: movem.l d1-d7/a1-a2,-(sp)
- NeW0 bsr WaveAd
- beq.s NeW1
- moveq #%1111,d0
- bsr EnvOff
- bsr WaveDel
- bra.s NeW0
- NeW1 move.l #WaveLong,d0
- SyCall SyChip
- beq.s NeWE
- move.l d0,(a2)
- move.l d0,a2
- move.w d1,WaveNb(a2)
- * Copy default ADSR
- move.l a1,-(sp)
- lea EnvDef-MB(a3),a0
- lea WaveEnv(a2),a1
- NeW3 move.l (a0)+,(a1)+
- bne.s NeW3
- move.l (sp)+,a1
- * Full wave: 256 bytes
- lea WaveDeb(a2),a2
- move.l a2,a0
- moveq #256/4-1,d0
- NeW2 move.l (a1)+,(a0)+
- dbra d0,NeW2
- * 1/2
- move.l a2,a1
- move.l a0,a2
- moveq #127,d0
- bsr NewRout
- * 1/4
- move.l a2,a1
- move.l a0,a2
- moveq #63,d0
- bsr NewRout
- * 1/8
- move.l a2,a1
- move.l a0,a2
- moveq #31,d0
- bsr NewRout
- * 1/16
- move.l a2,a1
- move.l a0,a2
- moveq #15,d0
- bsr NewRout
- * 1/32
- move.l a2,a1
- move.l a0,a2
- moveq #7,d0
- bsr NewRout
- * 1/64
- move.l a2,a1
- move.l a0,a2
- moveq #3,d0
- bsr NewRout
- ******* No error
- moveq #0,d0
- NeWx movem.l (sp)+,d1-d7/a1-a2
- rts
- ******* Out of mem
- NeWE moveq #-1,d0
- bra.s NeWx
-
- ******* Divide a sample by 2
- NewRout move.b (a1)+,d1
- ext.w d1
- move.b (a1)+,d2
- ext.w d2
- add.w d2,d1
- asr.w #1,d1
- move.b d1,(a0)+
- dbra d0,NewRout
- rts
-
- ******* Get a wave address
- WaveAd: moveq #0,d2
- lea WaveBase(pc),a2
- move.l (a2),d0
- beq.s WAd2
- WAd1 move.l a2,d2
- move.l d0,a2
- cmp.w WaveNb(a2),d1
- beq.s WAd3
- move.l (a2),d0
- bne.s WAd1
- WAd2 moveq #0,d0
- rts
- WAd3 moveq #-1,d0
- rts
-
- ******* Deletion of a WAVE (A2)-D2
- WaveDel movem.l a0-a2/d0-d2,-(sp)
- move.w WaveNb(a2),d1
- move.l d2,a0
- move.l (a2),(a0)
- move.l #WaveLong,d0
- move.l a2,a1
- SyCall SyFree
- movem.l (sp)+,a0-a2/d0-d2
- rts
-
- ***********************************************************
- * ENVELOPPES
-
- ***********************************************************
- * STOP ENVELOPPE D0
- EnvOff movem.l d0-d3/a0,-(sp)
- move.w EnvOn-MB(a3),d1
- clr.w EnvOn-MB(a3)
- moveq #0,d3
- lea Circuits,a0
- moveq #0,d2
- EOf1 btst d2,d0
- beq.s EOf2
- bclr d2,d1
- beq.s EOf2
- bset d2,d3
- move.w #2,$a4(a0)
- clr.w $a8(a0)
- EOf2 lea $10(a0),a0
- addq.w #1,d2
- cmp.w #4,d2
- bcs.s EOf1
- move.w d1,EnvOn-MB(a3)
- move.w d3,MuReStart-MB(a3)
- movem.l (sp)+,d0-d3/a0
- rts
-
- ******* Next enveloppe
- MuIntE move.l EnvAd(a0),a1
- MuIe0 move.w (a1)+,d3
- beq.s MuIntS
- bmi.s MuIe1
- move.w d3,EnvNb(a0)
- move.w EnvDVol(a0),d4
- mulu (a1)+,d4
- lsr.w #6,d4
- sub.w EnvVol(a0),d4
- ext.l d4
- lsl.w #8,d4
- divs d3,d4
- ext.l d4
- lsl.l #8,d4
- move.l d4,EnvDelta(a0)
- clr.w EnvVol+2(a0)
- move.l a1,EnvAd(a0)
- rts
- * Loop
- MuIe1 move.l EnvDeb(a0),a1
- bra.s MuIe0
- * End of a voice
- MuIntS bset d1,d5
- bclr d1,d0
- bclr d1,Noise-MB(a3)
- * Restarts the music
- bset d1,MuReStart+1-MB(a3)
- rts
-
- ******************************************************************
- * MUSIC
-
- ******* Music initialisation
- MuInit: clr.l MuBase-MB(a3)
- clr.w MuNumber-MB(a3)
- move.l #$DFF0A0,MuChip0-MB(a3)
- move.l #$DFF0B0,MuChip1-MB(a3)
- move.l #$DFF0C0,MuChip2-MB(a3)
- move.l #$DFF0D0,MuChip3-MB(a3)
- move.w #$000F,MuDMAsk-MB(a3)
- clr.w MuReStart-MB(a3)
- bsr MOff
- rts
-
- ******* MUSIC OFF-> Stops all musics
- IMuSOff movem.l a0-a3/d0-d1,-(sp)
- lea MB(pc),a3
- clr.l MuBase-MB(a3)
- clr.w MuNumber-MB(a3)
- bsr MOff
- movem.l (sp)+,a0-a3/d0-d1
- rts
-
- ******* MUSIC STOP-> Stops current music
- IMuStop movem.l a0-a3/d0-d1,-(sp)
- lea MB(pc),a3
- move.l MuBase-MB(a3),d0
- beq.s IStp
- clr.w MuBase-MB(a3)
- move.l d0,a0
- clr.w VoiCpt0(a0)
- clr.w VoiCpt1(a0)
- clr.w VoiCpt2(a0)
- clr.w VoiCpt3(a0)
- move.l d0,MuBase-MB(a3)
- IStp movem.l (sp)+,a0-a3/d0-d1
- rts
-
- ******* MUSIC VOLUME
- IMVol move.l (a3)+,d0
- cmp.l #64,d0
- bcc IFonc
- * Set volume
- MVol and.w #63,d0
- lea MB(pc),a0
- move.w d0,MuVolume-MB(a0)
- move.l MuBase-MB(a0),d4
- beq.s MVol3
- clr.l MuBase-MB(a0)
- lea MuBuffer-MB(a0),a1
- move.w MuNumber-MB(a0),d1
- MVol0 move.l a1,a2
- moveq #3,d2
- MVol1 move.w VoiDVol(a2),d3
- mulu d0,d3
- lsr.w #6,d3
- move.w d3,VoiVol(a2)
- lea VoiLong(a2),a2
- dbra d2,MVol1
- MVol2 lea MuLong(a1),a1
- subq.w #1,d1
- bne.s MVol0
- move.l d4,MuBase-MB(a0)
- MVol3 rts
-
- ******* VOICE ON/OFF Voices
- IVoice move.l (a3)+,d0
- and.w #$000F,d0
- move.l a3,-(sp)
- lea MB(pc),a3
- bsr VOnOf
- movem.l (sp)+,a3
- rts
-
- ******* Start / Stop voices D0
- VOnOf movem.l d0-d5/a0-a3,-(sp)
- lea MB(pc),a3
- move.l MuBase-MB(a3),d1
- beq.s VooX
- clr.l MuBase-MB(a3)
- move.l d1,a1
- move.l d1,a2
- move.w MuDMAsk-MB(a3),d1
- move.w d0,MuDMAsk-MB(a3)
- move.l WaveBase-MB(a3),a0
- lea WaveDeb(a0),a0
- move.l a0,d3
- lea MuChip0-MB(a3),a0
- moveq #0,d2
- moveq #0,d4
- * Exploration loop
- Voo1 btst d2,d0
- bne.s Voo2
- * Stop a voice!
- btst d2,d1 * Already stopped?
- beq.s VooN
- bset d2,d4
- move.l d3,(a0)
- bclr d2,MuStart+1(a2)
- bclr d2,MuStop+1(a2)
- bra.s VooN
- * Re start a voice
- Voo2 btst d2,d1 * Already on?
- bne.s VooN
- bset d2,MuReStart+1-MB(a3)
- * Next
- VooN addq.l #4,a0
- lea VoiLong(a1),a1
- addq.w #1,d2
- cmp.w #4,d2
- bcs.s Voo1
- * Stop them!
- move.w d4,Circuits+DmaCon
- move.w #$200,d0
- VooW dbra d0,VooW
- move.l a2,MuBase-MB(a3)
- VooX movem.l (sp)+,d0-d5/a0-a3
- rts
-
- ******* MUSIC n
- IMusic move.l (a3)+,d3
- bls IFonc
- * Points to the SONG
- move.l a3,-(sp)
- lea MB(pc),a3
- tst.l MusBank-MB(a3)
- beq MnRes
- move.l BankSong-MB(a3),a1
- cmp.w (a1),d3
- bhi MNDef
- lsl.w #2,d3
- add.l 2-4(a1,d3.w),a1
- * Still room?
- cmp.w #3,MuNumber-MB(a3)
- bcc IMusX
- clr.l MuBase-MB(a3)
- * Buffer address
- move.w MuNumber-MB(a3),d0
- move.w d0,d1
- addq.w #1,MuNumber-MB(a3)
- mulu #MuLong,d0
- lea MuBuffer-MB(a3),a2
- add.w d0,a2
- * Init datas
- moveq #(VoiLong*4)/2-1,d0
- move.l a2,a0
- IMus1 clr.w (a0)+
- dbra d0,IMus1
- clr.w MuStop(a2)
- clr.w MuStart(a2)
- * Init parameters
- move.l a2,d2
- move.w #100,MuCpt(a2)
- move.w #14,MuTempo(a2)
- moveq #0,d0
- IMus2 move.w #1,VoiCpt(a2)
- lea FoEnd-MB(a3),a0
- move.l a0,VoiAdr(a2)
- move.l a1,a0
- add.w 0(a0,d0.w),a0
- move.l a0,VoiPat(a2)
- move.l a0,VoiDPat(a2)
- lea VoiLong(a2),a2
- addq.w #2,d0
- cmp.w #8,d0
- bne.s IMus2
- * Starts music
- move.l d2,MuBase-MB(a3)
- IMusX move.l (sp)+,a3
- rts
-
- ******* Tempo T
- ITempo move.l (a3)+,d0
- cmp.l #100,d0
- bhi IFonc
- move.l MuBase(pc),d1
- beq.s ITemp
- move.l d1,a0
- move.w d0,MuTempo(a0)
- ITemp rts
-
- ***********************************************************
- * =VU METRE(v)
- FVu move.l (a3)+,d0
- cmp.l #4,d0
- bcc IFonc
- lea MB(pc),a0
- moveq #0,d3
- move.b 0(a0,d0.w),d3
- clr.b 0(a0,d0.w)
- moveq #0,d2
- rts
-
- ***********************************************************
- * =MU BASE
- FMB lea MB(pc),a0
- move.l a0,d3
- moveq #0,d2
- rts
-
- ***********************************************************
- *
- * INTERRUPT ROUTINES
- *
- * Here is the main point! Happy SoundTracker users, forget
- * everything! This music routine does not use the same system!
- * Music is not coded in parallel (all note for all voices
- * in 16 bytes), but in a more efficient but a little more complex
- * "track" system.
- * Each voice has its own track. More than that, the delays between
- * each note is not fixed as in SoundTracker (to have important
- * delays you just leave a few empty notes after), but coded in the
- * note itself. The delay is acheived by counting this value to
- * zero.
- * LABEL are not coded within the note, but stands before it, in
- * two bytes. The main advantage is that you can have up to 128
- * different labels, and the parameter of this label is a full
- * byte. More than one label can be put after each other, and will
- * only have effect for the next note.
- *
- * This structure makes AMOS music player very versatile: it can play
- * (after appropriate conversion) SoundTracker-like musics or IFF
- * music files.
- *
- * I also realised when the music routine was finished, that it
- * would not be really difficult to implement the music priority
- * system, which I think is really useful to do games!
- *
- * If you carefully look to the code, I am sure you will be able
- * to grab a few clock cycle here or there. I prefer to write readable
- * code, a little slower (very little) than more efficient tricky
- * code!!!
- *
- * For version 2 I want to implement synthetic instruments which saves
- * A LOT of memory. Anyway, almost everything is ready to do so, with
- * all the WAVE interrupt routines...
- *
- ***********************************************************
-
- ******* VBL Entry
- MusInt lea MB(pc),a3
- move.w EnvOn-MB(a3),d0
- beq Music
- lea EnvBase-MB(a3),a0
- lea $a0(a6),a2
- moveq #0,d1
- moveq #3,d2
- moveq #0,d5
- MuInt1 btst d1,d0
- beq.s MuIntN
- move.l EnvDelta(a0),d3
- add.l EnvVol(a0),d3
- move.l d3,EnvVol(a0)
- swap d3
- move.w d3,8(a2)
- MuInt2 subq.w #1,EnvNb(a0)
- bne.s MuIntN
- bsr MuIntE
- MuIntN lea EnvLong(a0),a0
- lea $10(a2),a2
- addq.w #1,d1
- dbra d2,MuInt1
- move.w d0,EnvOn-MB(a3)
- move.w d5,DmaCon(a6)
- ******* Make noise?
- tst.w Noise-MB(a3)
- beq.s Music
- move.w PNoise-MB(a3),d0
- moveq #7,d2
- move.w BSeed-MB(a3),d1
- move.l WaveBase-MB(a3),a0
- INoi1 add.w 6(a6),d1
- mulu #$3171,d1
- lsr.l #8,d1
- move.w d1,WaveDeb(a0,d0.w)
- subq.w #2,d0
- bpl.s INoi2
- move.w #LNoise-2,d0
- INoi2 dbra d2,INoi1
- move.w d0,PNoise-MB(a3)
- move.w d1,BSeed-MB(a3)
-
- ******* Music routine
- Music: move.l MuBase-MB(a3),d0
- beq MuEnd1
- movem.l a4-a6,-(sp)
- move.l d0,a5
- bsr MuEvery
- * Here is a smart counter, which gives progressive results
- * from zero to 100...
- move.w MuCpt(a5),d0
- add.w MuTempo(a5),d0
- move.w d0,MuCpt(a5)
- cmp.w #100,d0
- bcs MuEnd
- sub.w #100,MuCpt(a5)
- * Lets go for one step of music!
- moveq #0,d5
- moveq #0,d7
- move.l a5,a4
- tst.b VoiCpt+1(a4)
- beq.s Mus0
- addq.w #1,d5
- subq.b #1,VoiCpt+1(a4)
- bne.s Mus0
- moveq #0,d6
- move.l MuChip0-MB(a3),a6
- bsr MuStep
- Mus0 lea MuVoix1(a5),a4
- tst.b VoiCpt+1(a4)
- beq.s Mus1
- addq.w #1,d5
- subq.b #1,VoiCpt+1(a4)
- bne.s Mus1
- moveq #1,d6
- move.l MuChip1-MB(a3),a6
- bsr MuStep
- Mus1 lea MuVoix2(a5),a4
- tst.b VoiCpt+1(a4)
- beq.s Mus2
- addq.w #1,d5
- subq.b #1,VoiCpt+1(a4)
- bne.s Mus2
- moveq #2,d6
- move.l MuChip2-MB(a3),a6
- bsr MuStep
- Mus2 lea MuVoix3(a5),a4
- tst.b VoiCpt+1(a4)
- beq.s Mus3
- addq.w #1,d5
- subq.b #1,VoiCpt+1(a4)
- bne.s Mus3
- moveq #3,d6
- move.l MuChip3-MB(a3),a6
- bsr MuStep
- Mus3 and.w MuDMAsk-MB(a3),d7
- move.w d7,$DFF096
- tst.w d5
- beq.s MuFin
- MuEnd movem.l (sp)+,a4-a6
- MuEnd1 rts
- * Finished?
- MuFin subq.w #1,MuNumber-MB(a3)
- beq MuFini
- * Restarts previous music
- move.w MuNumber-MB(a3),d0
- subq.w #1,d0
- mulu #MuLong,d0
- lea MuBuffer-MB(a3),a0
- add.w d0,a0
- move.l a0,MuBase-MB(a3)
- move.w MuDMAsk-MB(a3),MuReStart-MB(a3)
- clr.w MuStart(a0)
- clr.w MuStop(a0)
- bra.s MuEnd
- * Really finished!
- MuFini clr.l MuBase-MB(a3)
- bsr.s MOff
- bra.s MuEnd
- * Stop sound routine
- MOff lea Circuits,a0
- move.w MuDMAsk-MB(a3),d0
- beq.s MOf3
- move.w d0,DmaCon(a0)
- moveq #3,d1
- MOf1 btst d1,d0
- beq.s MOf2
- move.w #2,$a4(a0)
- clr.w $a8(a0)
- MOf2 lea $10(a0),a0
- dbra d1,MOf1
- MOf3 rts
-
- ******* One step of music for one voice
- MuStep move.l VoiAdr(a4),a2
- MuSt0 move.w (a2)+,d0
- bmi.s MuEtiq
- * Play a normal note
- move.w d0,VoiCpt(a4)
- move.w (a2)+,d0
- beq.s MuSt1
- move.w d0,VoiNote(a4)
- move.w d0,$06(a6)
- move.l BankInst-MB(a3),d0
- move.l VoiInst(a4),a0
- add.l (a0),d0
- move.l d0,(a6)
- move.w 8(a0),$04(a6)
- bset d6,d7
- bclr d6,MuStop+1(a5)
- bset d6,MuStart+1(a5)
- move.w VoiSlB(a4),VoiSlide(a4)
- move.w VoiSlC(a4),VoiSlB(a4)
- move.b VoiVol+1(a4),0(a3,d6.w)
- MuSt1 move.l a2,VoiAdr(a4)
- rts
- * Label entry
- MuEtiq move.w d0,d1
- and.w #$7F00,d0
- lsr.w #6,d0
- lea MuJumps(pc),a0
- jmp 0(a0,d0.w)
-
- ******* Jmup table to labels
- MuJumps bra EtEnd * 00-> Fin pattern
- bra EtSlUp * 01-> Slide up
- bra EtSlDo * 02-> Slide down
- bra EtSVol * 03-> Set volume
- bra MuStep * 04->
- bra EtRep * 05-> Repeat
- bra EtLOn * 06-> Led On
- bra EtLOff * 07-> Led Off
- bra EtTemp * 08-> Set Tempo
- bra EtInst * 09-> Set Instrument
- ******* End of a pattern
- EtEnd clr.w VoiCpt(a4)
- clr.w VoiRep(a4)
- clr.l VoiDeb(a4)
- move.l VoiPat(a4),a0
- RePat move.w (a0)+,d0
- bmi.s EtEnd1
- move.l a0,VoiPat(a4)
- move.l BankPat-MB(a3),a0
- cmp.w (a0),d0
- bhi.s EtEndX
- lsl.w #2,d0
- add.w d6,d0
- lsl.w #1,d0
- move.w 2(a0,d0.w),d0
- beq.s EtEndX
- lea 0(a0,d0.w),a2
- bra MuSt0
- EtEndX rts
- EtEnd1 cmp.w #-1,d0
- beq.s EtEndX
- move.l VoiDPat(a4),a0
- bra.s RePat
- ******* Change instrument
- EtInst and.w #$00FF,d1
- move.l BankInst-MB(a3),a1
- lsl.w #5,d1
- lea 2(a1,d1.w),a1
- move.l a1,VoiInst(a4)
- move.w 12(a1),d0
- cmp.w #64,d0
- bcs.s EtInst1
- moveq #63,d0
- EtInst1 move.w d0,VoiDVol(a4)
- mulu MuVolume-MB(a3),d0
- lsr.w #6,d0
- move.w d0,VoiVol(a4)
- bra MuSt0
- ******* Slide up
- EtSlUp and.w #$00FF,d1
- neg.w d1
- move.w d1,VoiSlide(a4)
- move.w d1,VoiSlB(a4)
- clr.w VoiSlC(a4)
- bra MuSt0
- ******* Slide down
- EtSlDo and.w #$00FF,d1
- move.w d1,VoiSlide(a4)
- move.w d1,VoiSlB(a4)
- clr.w VoiSlC(a4)
- bra MuSt0
- ******* Set Volume
- EtSVol and.w #$00FF,d1
- cmp.w #64,d1
- bcs.s EtSVol1
- moveq #63,d1
- EtSVol1 move.w d1,VoiDVol(a4)
- mulu MuVolume-MB(a3),d1
- lsr.w #6,d1
- move.w d1,VoiVol(a4)
- bra MuSt0
- ******* Set Tempo
- EtTemp and.w #$00FF,d1
- move.w d1,MuTempo(a5)
- bra MuSt0
- ******* Led On
- EtLOn bclr #1,$bfe001
- bra MuSt0
- ******* Led Off
- EtLOff bset #1,$bfe001
- bra MuSt0
- ******* Repeat
- EtRep and.w #$00FF,d1
- bne.s EtRep1
- move.l a2,VoiDeb(a4)
- bra MuSt0
- EtRep1 tst.w VoiRep(a4)
- bne.s EtRep2
- move.w d1,VoiRep(a4)
- bra MuSt0
- EtRep2 subq.w #1,VoiRep(a4)
- beq MuSt0
- move.l VoiDeb(a4),d0
- beq MuSt0
- move.l d0,a2
- bra MuSt0
-
- ******* Routine call every VBL
- MuEvery
- * Update VOLUME and FREQUENCE
- move.l MuChip0-MB(a3),a6 * Voix 0
- move.w VoiSlide0(a5),d0
- add.w d0,VoiNote0(a5)
- move.w VoiNote0(a5),$06(a6)
- move.w VoiVol0(a5),$08(a6)
- move.l MuChip1-MB(a3),a6 * Voix 1
- move.w VoiSlide1(a5),d0
- add.w d0,VoiNote1(a5)
- move.w VoiNote1(a5),$06(a6)
- move.w VoiVol1(a5),$08(a6)
- move.l MuChip2-MB(a3),a6 * Voix 2
- move.w VoiSlide2(a5),d0
- add.w d0,VoiNote2(a5)
- move.w VoiNote2(a5),$06(a6)
- move.w VoiVol2(a5),$08(a6)
- move.l MuChip3-MB(a3),a6 * Voix 3
- move.w VoiSlide3(a5),d0
- add.w d0,VoiNote3(a5)
- move.w VoiNote3(a5),$06(a6)
- move.w VoiVol3(a5),$08(a6)
-
- * Second step of sample?
- MuRsXX move.w MuStop(a5),d0
- beq MuEvX
- move.l BankInst-MB(a3),d1
- btst #0,d0 * Voix 0
- beq.s MuEv0
- move.l MuChip0-MB(a3),a6
- move.l VoiInst0(a5),a0
- move.l d1,d2
- add.l 4(a0),d2
- move.l d2,(a6)
- move.w 10(a0),$04(a6)
- MuEv0 btst #1,d0 * Voix 1
- beq.s MuEv1
- move.l MuChip1-MB(a3),a6
- move.l VoiInst1(a5),a0
- move.l d1,d2
- add.l 4(a0),d2
- move.l d2,(a6)
- move.w 10(a0),$04(a6)
- MuEv1 btst #2,d0 * Voix 2
- beq.s MuEv2
- move.l MuChip2-MB(a3),a6
- move.l VoiInst2(a5),a0
- move.l d1,d2
- add.l 4(a0),d2
- move.l d2,(a6)
- move.w 10(a0),$04(a6)
- MuEv2 btst #3,d0 * Voix 3
- beq.s MuEv3
- move.l MuChip3-MB(a3),a6
- move.l VoiInst3(a5),a0
- move.l d1,d2
- add.l 4(a0),d2
- move.l d2,(a6)
- move.w 10(a0),$04(a6)
- MuEv3
-
- * Start a voice
- MuEvX move.w MuStart(a5),d1
- move.w d1,MuStop(a5)
- clr.w MuStart(a5)
- or.w d1,d0
- and.w MuDMAsk-MB(a3),d0
- bset #15,d0
- move.w d0,$DFF096
-
- * Restart voices?
- move.w MuReStart-MB(a3),d0
- beq MuRsX
- moveq #0,d3
- btst #0,d0 * Voix 0
- beq.s MuRs0
- lea $DFF0A0,a6
- move.l a6,MuChip0-MB(a3)
- move.w #2,$04(a6)
- tst.l VoiInst0(a5)
- beq.s MuRs0
- bset #0,d3
- MuRs0 btst #1,d0 * Voix 1
- beq.s MuRs1
- lea $DFF0B0,a6
- move.l a6,MuChip1-MB(a3)
- move.w #2,$04(a6)
- tst.l VoiInst1(a5)
- beq.s MuRs1
- bset #1,d3
- MuRs1 btst #2,d0 * Voix 2
- beq.s MuRs2
- lea $DFF0C0,a6
- move.l a6,MuChip2-MB(a3)
- move.w #2,$04(a6)
- tst.l VoiInst2(a5)
- beq.s MuRs2
- bset #2,d3
- MuRs2 btst #3,d0 * Voix 3
- beq.s MuRs3
- lea $DFF0D0,a6
- move.l a6,MuChip3-MB(a3)
- move.w #2,$04(a6)
- tst.l VoiInst3(a5)
- beq.s MuRs3
- bset #3,d3
- MuRs3 clr.w MuReStart-MB(a3)
- or.w d0,MuDMAsk-MB(a3)
- or.w d3,MuStop(a5)
- MuRsX
- rts
-
-
- ***********************************************************
- * LED INSTRUCTION
- LedOn:
- *******
- bclr #1,$BFE001
- rts
- LedOf:
- *******
- bset #1,$BFE001
- rts
-
-
- ***********************************************************
- * MUSIC TOKEN TABLE
- *
- * This table is the crucial point of the extension! It tells
- * everything the tokenisatioin process needs to know. You have to
- * be carefull when writing it!
- *
- * The format is simple:
- * dc.w Address of instruction-Tk,Address of function-Tk
- * dc.b "instruction nam","e"+$80,"Param list",-1[or -2]
- *
- * 1- Address of instr/function
- * You must state the one that is needed. Just put
- * a 1 in the function field for an instruction, and in the
- * instruction field for a function. Reserved variables need
- * TWO address!
- *
- * 2- Instruction name
- * It must be finished by the letter plus $80. Be carefull
- * ARGASM assembler produces bad code if you do "a"+$80, he wants
- * $80+"a"!!!
- * -You can SET A MARK in the token table with a "!" before
- * the name. See later
- * -Using a $80 ALONE as a name definition, will force AMOS
- * to point to the previous "!" mark...
- *
- * 3- Param list
- * This list tells AMOS everything about the instruction.
- *
- * - First character:
- * The first character defines the TYPE on instruction:
- * I--> instruction
- * 0--> function that returns a integer
- * 1--> function that returns a float
- * 2--> function that returns a string
- * V--> reserved variable. In that case, you must
- * state the type int-float-string
- * - If your instruction does not need parameters, then you stop
- * - Your instruction needs parameters, now comes the param list
- * Type,TypetType,Type...
- * Type of the parameter (0 1 2)
- * Comma or "t" for TO
- *
- * 4- End of instruction
- * "-1" states the end of the instruction
- * "-2" tells AMOS that another parameter list
- * can be accepted. if so, MUST follow the
- * complete instruction definition as explained
- * but with another param list.
- * If so, you can use the "!" and $80 facility not to rewrite the
- * full name of the instruction...See SAM LOOP ON instruction for an
- * example...
- *
- * Remember that AMOS token list comes first, so names like:
- * PRINTHELLO will never work: AMOS will tokenise PRINT first!
- * Extension token list are explored in order of number...
-
- * The next two lines NEED to be there...
- Tk: dc.w 1,0
- dc.b $80,-1
-
- dc.w 1,FMB-Tk
- dc.b "mubas","e"+$80,"0",-1
- dc.w 1,FVu-Tk
- dc.b "vumete","r"+$80,"00",-1
- dc.w IVoice-Tk,1
- dc.b "voic","e"+$80,"I0",-1
- dc.w IMusOff-Tk,1
- dc.b "music of","f"+$80,"I",-1
- dc.w IMuStop-Tk,1
- dc.b "music sto","p"+$80,"I",-1
- dc.w ITempo-Tk,1
- dc.b "temp","o"+$80,"I0",-1
- dc.w IMusic-Tk,1
- dc.b "musi","c"+$80,"I0",-1
- dc.w INoTo-Tk,1
- dc.b "noise t","o"+$80,"I0",-1
- dc.w Boom-Tk,1
- dc.b "boo","m"+$80,"I",-1
- dc.w Shoot-Tk,1
- dc.b "shoo","t"+$80,"I",-1
- dc.w ISBank-Tk,1
- dc.b "sam ban","k"+$80,"I0",-1
- dc.w ISLOn0-Tk,1
- dc.b "!sam loop o","n"+$80,"I",-2
- dc.w ISLOn1-Tk,1
- dc.b $80,"I",-1
- dc.w ISLOf0-Tk,1
- dc.b "sam loop of","f"+$80,"I",-2
- dc.w ISLOf1-Tk,1
- dc.b $80,"I0",-1
- dc.w ISamTo-Tk,1
- dc.b "sampl","e"+$80,"I0t0",-1
- dc.w ISam1-Tk,1
- dc.b "!sam pla","y"+$80,"I0",-2
- dc.w ISam2-Tk,1
- dc.b $80,"I0,0",-2
- dc.w ISam3-Tk,1
- dc.b $80,"I0,0,0",-1
- dc.w ISamR-Tk,1
- dc.b "sam ra","w"+$80,"I0,0,0,0",-1
- dc.w Bell0-Tk,1
- dc.b "!bel","l"+$80,"I",-2
- dc.w Bell1-Tk,1
- dc.b $80,"I0",-1
- dc.w IPlOf0-Tk,1
- dc.b "!play of","f"+$80,"I",-2
- dc.w IPlOf1-Tk,1
- dc.b $80,"I0",-1
- dc.w IPlay2-Tk,1
- dc.b "!pla","y"+$80,"I0,0",-2
- dc.w IPlay3-Tk,1
- dc.b $80,"I0,0,0",-1
- dc.w ISWave-Tk,1
- dc.b "set wav","e"+$80,"I0,2",-1
- dc.w IDWave1-Tk,1
- dc.b "del wav","e"+$80,"I0",-1
- dc.w ISEnv-Tk,1
- dc.b "set enve","l"+$80,"I0,0t0,0",-1
- dc.w IMVol-Tk,1
- dc.b "mvolum","e"+$80,"I0",-1
- dc.w IVol1-Tk,1
- dc.b "!volum","e"+$80,"I0",-2
- dc.w IVol2-Tk,1
- dc.b $80,"I0,0",-1
- dc.w IWave-Tk,1
- dc.b "wav","e"+$80,"I0t0",-1
- dc.w LedOn-Tk,1
- dc.b "led o","n"+$80,"I",-1
- dc.w LedOf-Tk,1
- dc.b "led of","f"+$80,"I",-1
- dc.w ISay1-Tk,1
- dc.b "!sa","y"+$80,"I2",-2
- dc.w ISay2-Tk,1
- dc.b $80,"I2,0",-1
- dc.w ITalk-Tk,1
- dc.b "set tal","k"+$80,"I0,0,0,0",-1
- * You MUST finish the table by a ZERO
- dc.w 0
-
- *************** Enveloppes definitions
- * Be carefull, ARGASM is bugged with __Rs!!!
- RsReset
- EnvNb: rs.w 1
- EnvDVol: rs.w 1
- EnvVol: rs.l 1
- EnvDelta: rs.l 1
- EnvAd: rs.l 1
- EnvDeb: rs.l 1
- EnvLong: equ __Rs
-
- *************** Wave definition
- LWave: equ 256+128+64+32+16+8+4+2
- LNoise: equ LWave
- RsReset
- WaveNext: rs.l 1
- WaveNb: rs.w 1
- WaveEnv: rs.w 16*2
- WaveDeb: rs.b LWave
- WaveLong: equ __Rs
-
- *************** Music voice data
- RsReset
- VoiAdr rs.l 1
- VoiDeb rs.l 1
- VoiInst rs.l 1
- VoiDPat rs.l 1
- VoiPat rs.l 1
- VoiCpt rs.w 1
- VoiRep rs.w 1
- VoiNote rs.w 1
- VoiDVol rs.w 1
- VoiVol rs.w 1
- VoiSlide rs.w 1
- VoiSlB rs.w 1
- VoiSlC rs.w 1
- VoiLong equ __Rs
-
- *************** MUBASE table
- RsReset
- * Voix 0
- MuVoix0 equ __Rs
- VoiAdr0 rs.l 1
- VoiDeb0 rs.l 1
- VoiInst0 rs.l 1
- VoiDPat0 rs.l 1
- VoiPat0 rs.l 1
- VoiCpt0 rs.w 1
- VoiRep0 rs.w 1
- VoiNote0 rs.w 1
- VoiDVol0 rs.w 1
- VoiVol0 rs.w 1
- VoiSlide0 rs.w 1
- VoiSlB0 rs.w 1
- VoiSlC0 rs.w 1
- * Voix 1
- MuVoix1 equ __Rs
- VoiAdr1 rs.l 1
- VoiDeb1 rs.l 1
- VoiInst1 rs.l 1
- VoiDPat1 rs.l 1
- VoiPat1 rs.l 1
- VoiCpt1 rs.w 1
- VoiRep1 rs.w 1
- VoiNote1 rs.w 1
- VoiDVol1 rs.w 1
- VoiVol1 rs.w 1
- VoiSlide1 rs.w 1
- VoiSlB1 rs.w 1
- VoiSlC1 rs.w 1
- * Voix 2
- MuVoix2 equ __Rs
- VoiAdr2 rs.l 1
- VoiDeb2 rs.l 1
- VoiInst2 rs.l 1
- VoiDPat2 rs.l 1
- VoiPat2 rs.l 1
- VoiCpt2 rs.w 1
- VoiRep2 rs.w 1
- VoiNote2 rs.w 1
- VoiDVol2 rs.w 1
- VoiVol2 rs.w 1
- VoiSlide2 rs.w 1
- VoiSlB2 rs.w 1
- VoiSlC2 rs.w 1
- * Voix 3
- MuVoix3 equ __Rs
- VoiAdr3 rs.l 1
- VoiDeb3 rs.l 1
- VoiInst3 rs.l 1
- VoiDPat3 rs.l 1
- VoiPat3 rs.l 1
- VoiCpt3 rs.w 1
- VoiRep3 rs.w 1
- VoiNote3 rs.w 1
- VoiDVol3 rs.w 1
- VoiVol3 rs.w 1
- VoiSlide3 rs.w 1
- VoiSlB3 rs.w 1
- VoiSlC3 rs.w 1
- * Other data
- MuCpt rs.w 1
- MuTempo rs.w 1
- MuStart rs.w 1
- MuStop rs.w 1
- * Total length
- MuLong equ __Rs
-
- *************** MUSIC extension data zone
- even
- MB:
- MuVu dc.l 0 * Vu Meters
- MuBase dc.l 0 * Curretn music address
- MusAdr dc.l 0 * Branch table address
- MusClock dc.l 3546895 * Clock speed
- WaveBase dc.l 0 * Wave tree
- Waves dc.w 0,0,0,0
- EnvOn: dc.w 0 * ADSR running?
- EnvBase: ds.b EnvLong*4 * ADSR table
- SamBank: dc.w 0 * Sample bank
- BSeed: dc.w 0 * Random seed
- Noise: dc.w 0 * Noise on?
- PNoise: dc.w 0 * Pointer to noise buffer
- * Musique
- MusBank dc.l 0 * Music bank
- MusCheck dc.l 0 * Check sum
- BankInst dc.l 0 * Instruments
- BankSong dc.l 0 * Songs
- BankPat dc.l 0 * Patterns
- MuNumber dc.w 0 * Music priority
- MuVolume dc.w 0 * Music volume
- MuDMAsk dc.w 0 * Voice mask
- MuReStart dc.w 0 * Restart the voice
- MuChip0 dc.l 0 * Circuits 0
- MuChip1 dc.l 0 * 1
- MuChip2 dc.l 0 * 2
- MuChip3 dc.l 0 * 3
- FoEnd dc.w $8000 * Fake empty pattern
- MuBuffer ds.b MuLong*3 * Music tables
-
- *************** Default enveloppes
- EnvDef: dc.w 1,64,4,55,5,50,25,0,0,0
- EnvShoot dc.w 1,64,10,0,0,0
- EnvBoom dc.w 1,64,10,50,50,0,0,0
- EnvBell dc.w 1,64,4,40,25,0,0,0
-
- *************** Sample enveloppes
- EnvSam dc.w 1,64,1,64,0,0,0,0
- dc.w 1,64,1,64,0,0,0,0
- dc.w 1,64,1,64,0,0,0,0
- dc.w 1,64,1,64,0,0,0,0
-
- *************** Bank headers
- BkSam: dc.b "Samples "
- BkMus: dc.b "Music "
-
- *************** Frequency / notes
- TFreq: dc.w 000,256/2
- dc.w 000,256/2
- dc.w 256,128/2
- dc.w 384,64/2
- dc.w 448,32/2
- dc.w 480,16/2
- dc.w 496,8/2
- dc.w 504,4/2
- dc.w 504,4/2
- TNotes: dc.w 00,00,00,33,35,37,39,41,44,46,49,52
- dc.w 55,58,62,65,69,73,78,82,87,92,98,104
- dc.w 110,117,123,131,139,147,156,165,175,185,196,208
- dc.w 220,233,247,262,277,294,311,330,349,370,392,415
- dc.w 440,466,494,523,554,587,622,659,698,740,784,830
- dc.w 880,932,988,1046,1109,1175,1245,1319,1397,1480,1568,1661
- dc.w 1760,1865,1986,2093,2217,2349,2489,2637,2794,2960,3136,3322
- dc.w 3520,3729,3952,4186,4435,4699,4978,5274,5588,5920,6272,6645
- dc.w 7040,7459,7902,8372
-
- *************** NARRATOR
- Amaps: dc.b 3,5,10,12
- TranBase dc.l 0
- TalkIO: ds.l 20
- WriteRep: ds.l 8
- TranName dc.b "translator.library",0
- NarDevice dc.b "narrator.device",0
-
- *************** Welcome message
- * 27 Y,position is like locate ,position...
- MusWel: dc.b 27,"Y8Music player V 1.1",0
-
- *************** ERROR MESSAGES
- MusErr: dc.b "Wave not defined",0 *0
- dc.b "Sample not defined",0 *1
- dc.b "Sample bank not found",0 *2
- dc.b "256 characters for a wave",0 *3
- dc.b "Wave 0 and 1 are reserved",0 *4
- dc.b "Music bank not found",0 *5
- dc.b "Music not defined",0 *6
- dc.b "Can't open narrator",0 *7
-
- *************** That's it!
- dc.l 0
-
-
-