; **************************************************************
; *                    JAZ Developer Library
; *                           8/29/95
; *                       Andreas Binner
; *                    (c) 1995 Atari Corp.
; *			   Version 1.2
; *	     Last updated: 12/21/95 by H.M. Krober
; **************************************************************

		.include "jaguar.inc"
		.include "modules/external.dat"
		
TIMER   	 EQU   $F10000

PLIST_SIZE	 EQU	21
NUM_VOICES       EQU    10
SFX_BIT		 EQU	23

		.extern	SCOREP1
		.extern	SCOREP2
		.extern	MTIMEP1
		.extern	MTIMEP2
		.extern PLISTP1
		.extern SHUTDOWN
		.extern DSP_START
		.extern SYNTH_COPY	
		.extern PRIORITY_TABLE
		.extern VOICE_TABLE
		.extern VT_RET_VALUE
		.extern EFFECT_MODE
		.extern MIDI_VOLUME
		.extern MDTAB_START
		.extern ENVELOPE_START


		XDEF	ATTN			; required by JAZ
		XDEF	DELAY			; required by JAZ
		XDEF	MIXER			; required by JAZ
		XDEF	REVERB			; required by JAZ
		XDEF	EFFECT_MODE		; required by JAZ

		XDEF	DIST			; required by JAZ

		XDEF	OSC_SAMPLER		; required by JAZ
		XDEF	OSC_SAMPLER_LOOP	; required by JAZ
		XDEF	OSC_NISAMPLER		; required by JAZ
		XDEF	OSC_FIXEDWAVE		; required by JAZ
		XDEF	OSC_FIXEDWAVE_LOOP	; required by JAZ
		XDEF	OSC_FM			; required by JAZ
		XDEF	OSC_FM_LOOP		; required by JAZ
		XDEF	OSC_POLYWAVE		; required by JAZ
		XDEF	OSC_NOISE		; required by JAZ

		XDEF	OSC_FX_PW		; required by JAZ
		XDEF	OSC_FX_PAN		; required by JAZ
		XDEF	OSC_FX_PITCH		; required by JAZ
		XDEF	OSC_FX_DIST		; required by JAZ
		XDEF	ENV_FX_PW		; required by JAZ
		XDEF	ENV_FX_PAN		; required by JAZ
		XDEF	ENV_FX_PITCH		; required by JAZ
		XDEF	OSC_FX_DIST		; required by JAZ
		XDEF	OSC_FX_VALUE		; required by JAZ

		XDEF	ENV_SLOT1		; required by JAZ
		XDEF	ENV_SLOT2		; required by JAZ
		XDEF	ENV_SLOT3		; required by JAZ

		XDEF	LOOPENV_SLOT1		; required by JAZ
		XDEF	LOOPENV_SLOT2		; required by JAZ
		XDEF	LOOPENV_SLOT3		; required by JAZ
		XDEF	LOOPENV_SKIP		; required by JAZ
	

		XDEF	LFO_1			; required by JAZ
		XDEF	LFO_2			; required by JAZ

		XDEF	DFT_FILTER		; required by JAZ
		XDEF	FILTER_2
		XDEF	FILTER_DEF_1		; required by JAZ
		XDEF	FILTER_DEF_2		; required by JAZ
		XDEF	VT_RETURN_LOC
				
		.GLOBL	_SFireEffect
		.GLOBL	_SFireEffectwPan
		.GLOBL	_SVoiceOn
		.GLOBL	_SVoiceOff
		.GLOBL	_SVoiceStatus
		.GLOBL	_SSync
		.GLOBL	_SSetScore1
		.GLOBL	_SSetScore2
		.GLOBL	_SSetPerf
		.GLOBL	_SSetVolAbs
		.GLOBL	_SSetVolRel
		.GLOBL	_SSetPitch
		.GLOBL	_SSetPan
		.GLOBL	_SSetRear
		.GLOBL	_STurnOn
		.GLOBL	_STurnOff
		.GLOBL	_SInit
		.GLOBL	_SSurround
		.GLOBL	_SMainVolume
		.GLOBL	_SSFXVolume
		.GLOBL	_patches
		.GLOBL	patches
		.GLOBL	_samples
		.GLOBL	samples
		.GLOBL	_midi_score
		.GLOBL	midi_score
				
;                .text
                 .data
		
_SFireEffectwPan:
		movem.l	d0-d3/a0,-(sp)

		clr.l	d1
		move.w	20+4(sp),d1		;patch
		move.l	d1, d2
		bset.l	#31,d1

		clr.l	d0
		move.w	20+12(sp),d0		;pan
		move.w	d0,d3
		swap	d0
		move.w	d3,d0			; pan now in upper and lower word
		mulu	#21*4,d2		; calculate patch (patchsize in longs)
		
		add.l	#19*4,d2		; add pan location

		move.l	PLISTP1,a0		; get pointer to patches
		add.l	d2,a0			; right patch, pan loc
		move.l	d0, (a0)		; write pan

		clr.l	d0
		move.w	20+6(sp),d0		;volume
		move	#24,d2
		lsl.l	d2,d0
		or.l	d0,d1


		clr.l	d0
		move.l	#freq_table,a0
		move.w	20+8(sp),d0		;pitch
		lsl.w	#2,d0
		move.l	(a0,d0.l),d0
		lsl.l	#7,d0
		or.l	d0,d1
		bset	#SFX_BIT, d1			; set sound fx bit !!!


		clr.l	d0
		move.w	20+10(sp),d0	;prior
		move	#29,d2
		lsl.l	d2,d0
		
		move.l	d0,effect_score
		move.l	d1,effect_score+4
		and.l	#$00ffffff,d1

		move.l	#0,effect_score+8
		move.l	d1,effect_score+12
		move.l	#$7fffffff,effect_score+16

		move.l	#0,MTIMEP2
		move.l	#effect_score,SCOREP2
		movem.l	(sp)+,d0-d3/a0
		rts




_SFireEffect:
		movem.l	d0-d2/a0,-(sp)

		clr.l	d1
		move.w	16+4(sp),d1		;patch
		bset.l	#31,d1
		
		clr.l	d0
		move.w	16+6(sp),d0		;volume
		move	#24,d2
		lsl.l	d2,d0
		or.l	d0,d1

		clr.l	d0
		move.l	#freq_table,a0
		move.w	16+8(sp),d0		;pitch
		lsl.w	#2,d0
		move.l	(a0,d0.l),d0
		lsl.l	#7,d0
		or.l	d0,d1
		bset	#SFX_BIT, d1			; set sound fx bit !!!

		clr.l	d0
		move.w	16+10(sp),d0	;prior
		move	#29,d2
		lsl.l	d2,d0
		
		move.l	d0,effect_score
		move.l	d1,effect_score+4
		and.l	#$00ffffff,d1
		move.l	#0,effect_score+8
		move.l	d1,effect_score+12
		move.l	#$7fffffff,effect_score+16

		
		move.l	#0,MTIMEP2
		move.l	#effect_score,SCOREP2
		movem.l	(sp)+,d0-d2/a0
		rts



_SVoiceOn:
		movem.l	d1-d3/a0,-(sp)

		clr.l	d1
		move.w	16+4(sp),d1		;patch
		bset.l	#31,d1
		
		clr.l	d2
		move.w	16+6(sp),d2		;volume
		move	#24,d3
		lsl.l	d3,d2
		or.l	d2,d1

		move.l	#freq_table,a0
		move.w	16+8(sp),d2		;pitch
		lsl.w	#2,d2
		move.l	(a0,d2.l),d2
		lsl.l	#7,d2
		or.l	d2,d1
		bset	#SFX_BIT, d1			; set sound fx bit !!!
	
		clr.l	d2
		move.w	16+10(sp),d2	;prior
		move	#29,d3
		lsl.l	d3,d2
		move.l	d2,effect_score		
		
		move.l	d1,effect_score+4
		move.l	#$7fffffff,effect_score+8

		move.l	#0,MTIMEP2
		move.l	#effect_score,SCOREP2
		
		and.l	#$00ffffff,d1
  		jsr		Sfind_voice		
		
		movem.l	(sp)+,d1-d3/a0
		rts

Sfind_voice:
		movem.l	a0,-(sp)
		move.l	#PRIORITY_TABLE+4,a0
floop1:
		move.l	#0,d0		
floop2:
		cmp.l	(a0,d0),d1
		beq		found
		addq.l	#8,d0
		cmp.l	#96,d0
		bne		floop2
		bra		floop1
found:
		lsr.l	#3,d0
		movem.l	(sp)+,a0
		rts
		
		
_SVoiceOff:
		movem.l	d1/a1,-(sp)
		clr.l	d1
		move.w	8+4(sp),d1
		lsl.l	#3,d1
		move.l	#PRIORITY_TABLE+4,a1
		move.l	(a1,d1),d0
		move.l	#0,effect_score
		move.l	d0,effect_score+4
		move.l	#$7fffffff,effect_score+8
		move.l	#0,MTIMEP2
		move.l	#effect_score,SCOREP2
		movem.l	(sp)+,d1/a1
		rts
		
_SVoiceStatus:
		movem.l	d1/a1,-(sp)
		clr.l	d1
		move.w	8+4(sp),d1
		lsl.l	#3,d1
		move.l	#PRIORITY_TABLE,a1
		move.l	(a1,d1),d0
		and.l	#$f,d0
		movem.l	(sp)+,d1/a1
		rts

_SSync:
		movem.l	d0,-(sp)
		move.l	MTIMEP1,d0
		add.l	4+4(sp),d0
Swait:
		cmp.l	MTIMEP1,d0
		bhi	Swait		
		movem.l	(sp)+,d0
		rts
		
_SSetScore1:
		movem.l	 d1-d2/a0,-(sp)
		move.w   #0, TIMER
		move.w   #0, TIMER+2		; stop music

		move.l	#0,MTIMEP1
		move.l	12+4(sp),SCOREP1
		cmp.l	#-1,SCOREP1
		bne	.1
		move.l	#endless_score,SCOREP1  ; set score 1 to endless loop
		move.w   #$69,TIMER+2   	; score timer
		move.w   #$100,TIMER		

		move.l	#NUM_VOICES-1, d1	; turn off all Music voices
.soff:
		move.l	#PRIORITY_TABLE, a0	; get voice bits from priority table
		move.l	d1, d2
		lsl.l	#3, d2
		add.l	d2, a0
		move.l	(a0),d2
		btst	#3,d2			; voice used?
		beq	.sso
		addq.l	#4, a0			; yes,
		move.l	(a0),d2			; get also note on event bits

		btst	#SFX_BIT-7, d2		; was it a sound effect (bits got shifted right by 7)
		beq	.sso			; yes, we are out of here

		move.w	d1, -(a7)		; no, it's a music voice	
		jsr	_SVoiceOff		; turn it off
		addq.l	#2, a7
.ssc:
		nop
		nop
		move.l	SCOREP2, d0		
		cmp.l	#effect_score+8,d0	; score done ?
		bne	.ssc
		
.sso:
		dbra	d1, .soff		; do all voices

		move.w   #0, TIMER
		move.w   #0, TIMER+2		; turn timer off and then on again

.1:
		move.w   #$69,TIMER+2   ; score timer
		move.w   #$100,TIMER	
		movem.l	 (a7)+,d1-d2/a0
		rts	

_SSetScore2:
		move.w   #0, TIMER
		move.w   #0, TIMER+2

		move.l	#0,MTIMEP2
		move.l	4(sp),SCOREP2
		cmp.l	#-1,SCOREP2
		bne		.2
		move.l	#endless_score,SCOREP2
.2:
		move.w   #$69,TIMER+2   ; score timer
		move.w   #$100,TIMER	
		rts	

_SSetPerf:
		movem.l	d0-d1/a0-a2,-(sp)

		move.w   #0, TIMER
		move.w   #0, TIMER+2

 		move.l	#endless_score,SCOREP1
		move.l	#endless_score,SCOREP2

		move.w   #$69,TIMER+2   ; score timer
		move.w   #$100,TIMER	

		move.l	#13, d1		; turn off all voices
.soff:
		move.w	d1, -(a7)
		jsr	_SVoiceOff
		addq.l	#2, a7
.ssc:
		move.l	SCOREP2, d0
		cmp.l	#effect_score+8,d0
		bne	.ssc

		dbra	d1, .soff

		move.w   #0, TIMER
		move.w   #0, TIMER+2

		clr.l	d0
		move.w	5*4+4(sp), d0
		move.l	#_SYNTH_TABLE, a0
		moveq.l	#4, d1
		lsl.l	d1,d0
		add.l	d0,a0

; mdtabs	
		move.l	(a0),a1
		move.l	(a1)+,a2
		move.l	(a1)+,d1
		lsr.l	#2,d1
;		subq.l	#1,d1
.pf_copy_mdtab:
		move.l	(a1)+,(a2)+
		dbra	d1, .pf_copy_mdtab


; envelopes	
		move.l	4(a0),a1
		move.l	(a1)+,a2
		move.l	(a1)+,d1
		lsr.l	#2,d1
;		subq.l	#1,d1
.pf_copy_envelope:
		move.l	(a1)+,(a2)+
		dbra	d1, .pf_copy_envelope

		move.l	8(a0), PLISTP1

		clr.l	d0
		move.w	5*4+6(sp),d0
		lsl.l	#2,d0
		move.l	12(a0), a1
		add.l	d0,a1
		move.l	(a1), SCOREP1
		
		move.l   #effect_score,SCOREP2
		move.l	 #0, MTIMEP1
		move.l   #0, MTIMEP2
		move.l   #0,R_DAC
		move.l   #0,L_DAC
		
		move.w   #$69,TIMER+2   ; score timer
		move.w   #$100,TIMER	
		
		movem.l	(sp)+,d0-d1/a0-a2
		rts



_SSetVolRel:
		movem.l	d1-d2,-(sp)

		move.l	#$50400000,d1
StandardControl:
		clr.l	d2
		move.w	8+4(sp),d2		;voice
		or.l	d2,d1
		
		clr.l	d2
		move.w	8+6(sp),d2		;volume
		lsl.l	#7,d2
		or.l	d2,d1

		move.l	#$e0000000,effect_score		
		
		move.l	d1,effect_score+4
		move.l	#$7fffffff,effect_score+8

		move.l	#0,MTIMEP2
		move.l	#effect_score,SCOREP2
				
		movem.l	(sp)+,d1-d2
		rts






_SSetPitch:
		movem.l	d1-d2,-(sp)

		move.l	#$50000000,d1
		jmp	StandardControl
		
_SSetPan:
		movem.l	d1-d2,-(sp)

		move.l	#$50200000,d1
		jmp	StandardControl

_SSetVolAbs:
		movem.l	d1-d2,-(sp)

		move.l	#$50600000,d1
		jmp	StandardControl				

_STurnOff:
 		move.l 	#SHUTDOWN,d0
		and.l	#$ffff,d0
		or.l 	#$981e0000,d0
		move.l 	d0,$f1b010
		rts
		
_STurnOn:
		movem.l	d0-d1/a0-a2,-(sp)
		clr.l	d0
		move.w	5*4+4(sp), d0
		move.l	#_SYNTH_TABLE, a0
		moveq.l	#4, d1
		lsl.l	d1,d0
		add.l	d0,a0

; mdtabs	
		move.l	(a0),a1
		move.l	(a1)+,a2
		move.l	(a1)+,d1
		lsr.l	#2,d1
;		subq.l	#1,d1
.copy_mdtab:
		move.l	(a1)+,(a2)+
		dbra	d1, .copy_mdtab


; envelopes	
		move.l	4(a0),a1
		move.l	(a1)+,a2
		move.l	(a1)+,d1
		lsr.l	#2,d1
;		subq.l	#1,d1
.copy_envelope:
		move.l	(a1)+,(a2)+
		dbra	d1, .copy_envelope



		move.l	8(a0), PLISTP1

		clr.l	d0
		move.w	5*4+6(sp),d0
		lsl.l	#2,d0
		move.l	12(a0), a1
		add.l	d0,a1
		move.l	(a1), SCOREP1
		
		move.l   #effect_score,SCOREP2
		move.l	 #0, MTIMEP1
		move.l   #0, MTIMEP2
		move.l   #0,R_DAC
		move.l   #0,L_DAC
		
		
		move.l   #0,D_FLAGS     ; Set known state
		
		move.w   #0, TIMER
		move.w   #0, TIMER+2
		
		move.l   #$13,SCLK		;i2s interrupt
		move.l   #$15,SMODE     ; start interrupt

		move.w   #$69,TIMER+2   ; score timer
		move.w   #$100,TIMER	
		
		move.w	#$100,JOYSTICK
		
		move.l	save_adr,$f1b010	;restore i2s

		move.l   #DSP_START,D_PC   ; Set up D_PC
		move.l   #$1,D_CTRL        ; LET 'R RIP

		move.w   5*4+8(sp),d0
		beq	 internal_clock
		move.l   #$14,SMODE     ; set external clock
internal_clock:
		movem.l	(sp)+,d0-d1/a0-a2
		rts
		
_SInit:
		movem.l	d1/a0-a1,-(sp)

		move.l	#$7fffffff,effect_score
		move.l	#$00070007,D_END	; Set GOOD mode
		move.l	#0,D_FLAGS			; Set known state
		move.l	#SYNTH_COPY,a0
		move.l	(a0)+,a1
		move.l	(a0)+,d1
		asr.l	#2,d1
translop:
		move.l	(a0)+,(a1)+
		dbra	d1,translop
		move.l	$f1b010,save_adr	; save i2s
		movem.l	(sp)+,d1/a0-a1
		rts

_SSurround:
		movem.l	d0,-(sp)
		move.l	4+4(sp),d0
		lsl.l	#1,d0
		or.l	#$ffff0000,d0
		move.l	d0,EFFECT_MODE	
		movem.l	(sp)+,d0
		rts
				
_SMainVolume:
		movem.l	d1,-(sp)
		move.l	4+4(sp),d0
		move.l	MIDI_VOLUME,d1
		move.w	d0, d1
		move.l	d1, MIDI_VOLUME
		movem.l	(sp)+,d1
		rts



_SSFXVolume:
		movem.l	d1,-(sp)
		move.l	4+4(sp),d0
		move.l	MIDI_VOLUME,d1
		swap 	d1
		move.w	d0, d1
		swap	d1
		move.l	d1, MIDI_VOLUME
		movem.l	(sp)+,d1
		rts

		
		.data
	.long
_SYNTH_TABLE::
	.include "modules/table.dat"
_SCORE_TABLE::
	.include "modules/stable.dat"


	.include "syncore.das"
	.68000
    .data
	.long
_patches:		
patches:
	.include "modules/patches.dat"
_mdtab:
	.include "modules/mdtab.dat"

_envelopes:
	.include "modules/envelope.dat"

	.68000
    .data
_samples:
	.include "modules/samples.dat"	
	.long
_midi_score:
midi_score:
	.include "modules/score.dat"
 ;	frequency table for note on events in 6.10
;	
;		Decimal Value		Note #
; ---------------------------------------------------

freq_table:
	dc.l	52 		;	0
	dc.l	55 		;	1
	dc.l	58 		;	2
	dc.l	61 		;	3
	dc.l	65 		;	4
	dc.l	69 		;	5
	dc.l	73 		;	6
	dc.l	77 		;	7
	dc.l	82 		;	8
	dc.l	87 		;	9
	dc.l	92 		;	10
	dc.l	97 		;	11
	dc.l	103		;	12
	dc.l	109 		;	13
	dc.l	116 		;	14
	dc.l	123 		;	15
	dc.l	130 		;	16
	dc.l	138 		;	17
	dc.l	146 		;	18
	dc.l	155 		;	19
	dc.l	164 		;	20
	dc.l	173 		;	21
	dc.l	184 		;	22
	dc.l	195 		;	23
	dc.l	206 		;	24
	dc.l	219 		;	25
	dc.l	232 		;	26
	dc.l	245 		;	27
	dc.l	260 		;	28
	dc.l	275 		;	29
	dc.l	292 		;	30
	dc.l	309 		;	31
	dc.l	328 		;	32
	dc.l	347 		;	33
	dc.l	368 		;	34
	dc.l	389 		;	35
	dc.l	413 		;	36
	dc.l	437 		;	37
	dc.l	463 		;	38
	dc.l	491 		;	39
	dc.l	520 		;	40
	dc.l	551 		;	41
	dc.l	584 		;	42
	dc.l	618 		;	43
	dc.l	655  		;	44
	dc.l	694 		;	45
	dc.l	735 		;	46
	dc.l	779 		;	47
	dc.l	825 		;	48
	dc.l	874 		;	49
	dc.l	926 		;	50
	dc.l	981 		;	51
	dc.l	1040		;	52
	dc.l	1102 		;	53
	dc.l	1167  		;	54
	dc.l	1237 		;	55
	dc.l	1310  		;	56
	dc.l	1388 		;	57
	dc.l	1470 		;	58
	dc.l	1558 		;	59
	dc.l	1651 		;	60
	dc.l	1749 		;	61
	dc.l	1853 		;	62
	dc.l	1963 		;	63
	dc.l	2080 		;	64
	dc.l	2203 		;	65
	dc.l	2334  		;	66
	dc.l	2473 		;	67
	dc.l	2620  		;	68
	dc.l	2776  		;	69
	dc.l	2941 		;	70
	dc.l	3116 		;	71
	dc.l	3301 		;	72
	dc.l	3497 		;	73
	dc.l	3705 		;	74
	dc.l	3926 		;	75
	dc.l	4159 		;	76
	dc.l	4406 		;	77
	dc.l	4668 		;	78
	dc.l	4946 		;	79
	dc.l	5240 		;	80
	dc.l	5552 		;	81
	dc.l	5882 		;	82
	dc.l	6232 		;	83
	dc.l	6602 		;	84
	dc.l	6995 		;	85
	dc.l	7411 		;	86
	dc.l	7851 		;	87
	dc.l	8318 		;	88
	dc.l	8813 		;	89
	dc.l	9337 		;	90
	dc.l	9892 		;	91
	dc.l	10480 		;	92
	dc.l	11104 		;	93
	dc.l	11764  		;	94
	dc.l	12463 		;	95
	dc.l	13204 		;	96
	dc.l	13990 		;	97
	dc.l	14821 		;	98
	dc.l	15703 		;	99
	dc.l	16636 		;	100
	dc.l	17626  		;	101
	dc.l	18674 		;	102
	dc.l	19784 		;	103
	dc.l	20961 		;	104
	dc.l	22207 		;	105
	dc.l	23528 		;	106
	dc.l	24927 		;	107
	dc.l	26409 		;	108
	dc.l	27979 		;	109
	dc.l	29643 		;	110
	dc.l	31405 		;	111
	dc.l	33273 		;	112
	dc.l	35251 		;	113
	dc.l	37348 		;	114
	dc.l	39568 		;	115
	dc.l	41921 		;	116
	dc.l	44414 		;	117
	dc.l	47055 		;	118
	dc.l	49853 		;	119
	dc.l	52818 		;	120
	dc.l	55958 		;	121
	dc.l	59286 		;	122
	dc.l	62811 		;	123
	dc.l	4096 		;	124
	dc.l	2048 		;	125
	dc.l	1024		;	126
	dc.l	512 		;	127




		.Long		
endless_score:
		.dc.l	$7ffffff0
		.dc.l	$3fffffff



		.68000
		.bss
		.long
save_adr:
		.ds.l	1
effect_score:
		.ds.l	10



