;---------------------------------------------------------------------------- ; This is a simple sample program to play a tune on the synth code. ; ; MODULE: MUSIC DRIVER - DOES NOT HAVE TO BE EDITED! ; ; COPYRIGHT 1992,1993,1994 Atari U.S. Corporation ; ; UNAUTHORIZED REPRODUCTION, ADAPTATION, DISTRIBUTION, ; PERFORMANCE OR DISPLAY OF THIS COMPUTER PROGRAM OR ; THE ASSOCIATED AUDIOVISUAL WORK IS STRICTLY PROHIBITED. ; ALL RIGHTS RESERVED. ;---------------------------------------------------------------------------- ;---------------------------------------------------------------------------- ; INCLUDE FILES ;---------------------------------------------------------------------------- .include 'd:/jaguar/inc/jaguar.inc' .include 'fulsyn.inc' .include 'synth.cnf' ;---------------------------------------------------------------------------- ; EXTERNALS ;---------------------------------------------------------------------------- .extern SYN_COPY ; start of the synth .extern TABS_COPY ; start of tables .extern DSPORG ; start oF DSP RAM .extern VOLUME ; MIDI volume .extern UEBERVOLUME ; global volume .extern patches ; Patch Data .extern SCORE_ADD ; ptr to the music data .extern PATCHLOC ; ptr to the patches .extern scoretab ; Here's the music data .extern SHUTDOWN .extern TMR1_ISR ;---------------------------------------------------------------------------- ; CODE SECTION ;---------------------------------------------------------------------------- .text ; Init the DSP code move.l #$00070007,D_END ; Set GOOD mode move.l #0,D_CTRL ; Turn DSP off move.l #0,D_FLAGS ; Set known state ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; First we copy the Jerry code into Jerry move.l #SYN_COPY,a0 move.l (a0)+,a1 ; Get load address move.l (a0)+,d1 ; and length asr.l #2,d1 subq.l #1,d1 .1: move.l (a0)+,(a1)+ dbra d1,.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now we copy the tables into Jerry break1: move.l #TABS_COPY,a0 move.l (a0)+,a1 ; Get load address move.l (a0)+,d1 ; and length asr.l #2,d1 subq.l #1,d1 .2: move.l (a0)+,(a1)+ ; initialize voice table dbra d1,.2 break2: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Turn off score timer move.w #0,JPIT1 move.w #0,JPIT1+2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; The next several lines may seem weird, so let's explain... ; ; This is MAGIC to make the DSP turn itself off at the next sample interrupt. ; We are going to change the 'movei' instruction at the start of the DSP's ; IS2 interrupt handler so that it points to a routine that will shut down ; the DSP (this routine is part of the SYNTH source in this particular ; example). This 'movei' instruction has the format: ; ; 0x98d1 ; ; Because all DSP RAM address have the same high word, we only have to change ; the low word. However, since we can only reliably access LONG's in DSP RAM, ; we have to create the instruction itself also. Here are the steps involved: ; ; 1) Save current address of interrupt handler so we can restore it later. ; ; 2) Get address of the DSP's "turn myself off" routine. ; ; 3) Clear the high word of the address to make room for the 'MOVEI' code. ; ; 4) 'OR' in the 'movei' code. ; ; 5) Store the new 'movei' instruction into the DSP interrupt handler area. ; Now the the DSP will jump to the SHUTDOWN routine on the next sample ; interrupt it gets. ; ; 6) Try to turn off the DSP ourselves... just to be safe. ; ; 7) Restore the original 'movei' instruction and interrupt handler address ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; move.l $f1b010, orglong ; Step 1 move.l #SHUTDOWN,d0 ; Step 2 and.l #$ffff,d0 ; Step 3 or.l #$981d0000,d0 ; Step 4 move.l d0,$f1b010 ; Step 5 move.l #0,D_CTRL ; Step 6a move.l #0,D_FLAGS ; Step 6b move.l orglong,$f1b010 ; Step 7 (theoretically we should wait for a semaphore...) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Setup S clock move.l #SCLKVALUE,SCLK move.l #$15,SMODE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set the volume move.l #MIDIVOLUME,VOLUME ; set global volume move.l #GLOBALVOLUME,UEBERVOLUME ; set global volume ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now it should be safe to turn on the DSP move.l #DSPORG,D_PC ; Set up D_PC move.l #$1,D_CTRL ; LET 'R RIP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now we copy the score to the score location move.l #scoretab,a0 move.l #$50000,a1 ; here's where we put the music data scorelop: move.l (a0)+,d0 ; copy it move.l d0,(a1)+ cmp.l #$7fffffff,d0 bne scorelop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Tell the music driver where the music score is located. move.l #$50000,SCORE_ADD ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now let's set up a patch table move.l #patches,a0 ; First word is the number of patch tables move.w (a0)+,d0 mulu.w #20,d0 ; a table contains 20 longs move.l #PATCHTAB,a1 patchlop: move.l (a0)+,(a1)+ ; now we copy the patches dbra d0,patchlop ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Tell the synth where the patches are located move.l #PATCHTAB, PATCHLOC ; set the ptr to the patches ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Set up JPIT1 (timer) move.w #$56,JPIT1+2 move.w #$114,JPIT1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Enable sound (mute bit) move.w #$100,JOYSTICK ;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Now our music should be playing... illegal ; We have nothing else to do, so DIE! ; ************************ END OF MAIN CODE *********************** ;--------------------------------------------------------------------------- ; B S S ;--------------------------------------------------------------------------- .bss orglong: ds.l 1 ;____________________________________EOF____________________________________