
EXPORT STe_segment, STe_module, STe_end
EXPORT SetFilter, SetPlayFreq

EXPORT DMAinterupt
EXPORT PlayRoutine

include "nt_const.s"


******************* ROUINE TO STOP THE SOUND DMA ********************
STe_end:        pea     Stop_DMA(PC)
                tst.w   d0
                beq.b   hard_stop
                move.l  #Stop_DMA_soft,(a7)
hard_stop:      move.w  #Supexec,-(SP)
                trap    #Xbios
                addq.w  #6,SP        ;remove params to 'super'
                rts

                
Stop_DMA:       lea     MFP,A0
                move.b  (A0)+,MFP_EnblA
                move.b  (A0)+,MFP_MaskA
                move.w  #0,PCM_CONTROL ;Stop DMA sound chip
                move.l  #PCM_VECTOR,D0
                lea     DMAinterupt-12(PC),A0
                bra     XB_kill


Stop_DMA_soft:  lea     MFP,A0
                move.b  (A0)+,MFP_EnblA
                move.b  (A0)+,MFP_MaskA
                bsr     no_reload
                move.l  #PCM_VECTOR,D0
                lea     DMAinterupt-12(PC),A0
                bra     XB_kill

******************* ROUINE TO START THE SOUND DMA *******************
**************************** PLAY SEGMENT ***************************
STe_segment:    move.l  A0,tablePointer ; char **samples
                ext.l   D0
                addq.l  #1,D0           ; int repeat
                beq.b   dontrepeat
                subq.l  #1,D0
                lsl.l   #2,D0
                add.l   A0,D0
dontrepeat:     move.l  D0,inittable    ; zero if no rep., else addr.                DATA
                pea     Start_DMA
                move.w  #Supexec,-(SP)
                trap    #Xbios
                addq.w  #6,SP        ;remove params to 'super'
                rts


           
Start_DMA:      lea     MFP,A0
                move.b  MFP_EnblA,(A0)+
                move.b  MFP_MaskA,(A0)+

                clr.w  PCM_CONTROL ;Stop DMA sound chip

                move.b  MFP_Data,D0   ;Read monitor-type (mono/color)
                eor.b   D0,MFP_Edge   ;Enable IRQ on Sound _not_ Active!
                andi.b  #%1111111,MFP_Edge ; Sound not Active.
                eor.b   D0,MFP_Edge   ; IRQ when sound becomes not active.

                lea     DMAinterupt-4(PC),A0
                move.l  PCM_VECTOR,(A0)+
                move.l  A0,PCM_VECTOR

                bclr    #7,MFP_PendA
                bset    #7,MFP_MaskA  ;Mask 'Sound Active' interupt.
                bset    #7,MFP_EnblA  ;Enable 'Sound Active' interupt

                bsr     DMAmusic
                moveq   #3,D0
                and.w   PCM_CONTROL,D0
                bne.b   last_segment
                
                move.w  #3,PCM_CONTROL ;start DMA chip in LOOP mode
                bsr     DMAmusic
                
last_segment:   rts


************** ROUINE TO SET THE FILTER BEFORE PLAYING **************
****************************     oOo     ****************************
MIX_GI_12dB     EQU %10_000_0000_00
SetFilter:      pea    StuffInMW
                move.w  #Supexec,-(SP)
                trap    #Xbios
                addq.w  #6,SP        ;remove params to 'super'
                rts
StuffInMW:      move.w #MIX_GI_12dB,MW_DATA
                move.w #%111_1111_1111,MW_MASK
                rts
                
                
**************** ROUINE TO SET THE PLAYING FREQUENCY ****************
****************************     oOo     ****************************
SetPlayFreq:    move.w d0,PlayFreq ; move argument to global var.
                pea    setfreq
                move.w  #Supexec,-(SP)
                trap    #Xbios
                addq.w  #6,SP        ;remove params to 'super'
                rts
setfreq:        move.w  PlayFreq,PCM_MODE
                rts
                
                
****************************************************************
* Routine to play the music, called when sound buffer is empty *
****************************************************************
                SUPER
                
***************** RUTINES FOR THE STE DMA SOUND *****************
                DC.L    'XBRA','zexc'
                DS.L    1                ; Old Vector
DMAinterupt:    movem.l D0/A0-A1,-(SP)
                
                bclr    #7,MFP_ISRA
                move.w  #$2300,SR
                
                bsr.b   DMAmusic
                
                movem.l (SP)+,D0/A0-A1
                rte


DMAmusic:       bsr.b Segment
                
                ; This Routine returns D0: DMA_START, A0: DMA_END
                
                beq.b   no_reloadDMA
                lea     PCM_START,A1  ;Insert Secondary-buffer in the queue.
                movep.w D0,3(A1)
                swap    D0
                move.w  D0,(A1)

                move.l  A0,D0
                movep.w D0,3+PCM_END-PCM_START(A1)
                swap    D0
                move.w  D0,PCM_END-PCM_START(A1)
no_reloadDMA:   rts


******************** ROUTINE TO PLAY SEGM FILES ********************
*** Uses : D0,A0,A1
Segment:        movea.l tablePointer,A0
                cmpi.l  #-1,(A0)
                bne.b   no_repeat
                move.l  inittable,D0
                movea.l D0,A0
                beq.b   no_reload 
no_repeat:      movea.l (A0)+,A1
                move.l  (A0)+,D0
                move.l  A0,tablePointer
                lea     0(A1,D0.l),A0 ;end of DMA
                move.l  A1,D0; start of DMA
                rts

no_reload:      ; If the DMA chip isn't in LOOP mode, don't do anything
                moveq   #3,D0
                and.w   PCM_CONTROL,D0
                subq.w  #3,D0
                bne.b   dont_set
                ; At this point is the last segment playing - therefor
                ; set the DMA chip into SINGLE, rather than LOOP
                ; playback mode... The DMA chip will then stop after
                ; the sample have been played!
                move.w  #1,PCM_CONTROL ; DMA chip in SINGLE mode
dont_set:       moveq   #0,D0
                rts


**************** XB_SEARCH *********************
** entry: A0:Pointer to 'Magic', D0:vector.    *
** returns : if found -> ZERO
xb_search:                  
	MOVE.L D0, A1           ;A1 now points to 'vector'
	MOVE.L A0, D2           ;D2 contains copy of pointer to 'magic' 
xb_next:
	MOVE.L A1, D1           ;At end D1 points to old 'next' pointer
	MOVE.L (A1), A1         ;Find next XBRA struct.
	LEA    -12(A1), A1
	MOVE.L D2, A0           ;Copy pointer to magic into A0 
	CMP.L (A0)+, (A1)+      ;Is 'XBRA' ok ?
	BNE.B not_xbra
	CMP.L (A0)+, (A1)+      ;Is ID ok ?
	BNE.B xb_next           ;Try next in chain...
not_xbra:
	RTS



********************************************************************
* Routine 'XB_kill'  (the -9 option!)
* Note !
*   This routine depends on the fact that 'Magic' contains the 
*   'Oldvec' field. It uses this to unchain all the routines after
*   the last XBRA routine til your routine.
*
* entry: (vector, Pointer to 'Magic').
*
* exit  : 
*	D0 : Retval (1=was in chain - OK [-but removed, not killed]).
* uses:
*   D0-D2/A0-A1 ; D2 is only used by xb_search
********************************************************************
XB_kill:
	BSR.B xb_search			;Get last XBRA routine in chain.            
	BZE.B xb_rem				;If the routine was found - dispose normally
									;A0+4 is our pointer to next in chain. 
	MOVE.L D1, A1				;D1 is the Last XBRA pointer to next routine
	MOVE.L 4(A0), (A1)		;Make previous XBRA point on later routine.
	RTS
xb_rem:							;(A1)->XBRA.xb_oldvec of later routine.
	MOVE.L D1, A0				;D1->XBRA.xb_oldvec of routine before our.
	MOVE.L (A1), (A0)			;Make previous routine point on later one.
	RTS
	
	
                .BSS
                .EVEN
_vars:                
tablePointer:   DS.L 1
inittable:      DS.L 1
PlayBuff:       DS.L 1
PlayRoutine:    DS.L 1

PlayFreq:       DS.W 1

MFP:            DS.B 2

                
                END