*
*	File:		Gems.a - Version 2.2 for MicroTec 3/5/92
*
*	Contains:	The library routines and includes for Gems data.
*
*	Written by:	Burt Sloane & Jonathan L. Miller
*
*	Copyright:	1990 by Sega of America, Inc., all rights reserved.
*
*	Change History:
*		3/5/92 JLM Update for 2.2 - new z80 mem map, plus fixed dmastart
*		11/19/91 BAS Update for 2.0, several routines didnt disable ints
*
*	To Do:
*
*
*

* N.B.  in routines in this file, a0 and d0 are freely trashed


********************************** DATA INCLUDES ********************************


BUSREQ		EQU	$A11100			; Z80 bus request control register
BUSRES		EQU	$A11200			; Z80 reset control register
Z80RAM		EQU	$A00000			; Z80 RAM in 68k addr space
Z80DMABLOCK	EQU	$A01b20			; Z80 can't read 68k space if set
Z80DMAUNSAFE	EQU	$A01b21			; Z80 might be reading 68k space if set
Z80MBOXBASE	EQU	$A01b22			; Z80 mailbox base addr

PSG_PORT	EQU	$C00011

********************************** Z80 CONTROL ROUTINES ********************************


*
* gemsdmastart - tell the z80 we want to do dma
*

gemsdmastart	move.w	sr,-(SP)
		or.w	#$0700,sr		; disable ints

dsretry		move.w	#$100,BUSREQ		; Z80 bus request on
dslp		btst.b	#0,BUSREQ		; spin on bus grant
		bne.s	dslp

		move.b	#1,Z80DMABLOCK		; set dma block semaphore
		move.b	Z80DMAUNSAFE,d0		; get unsafe flag

		move.w	#$0,BUSREQ		; Z80 bus request off

		tst.b	d0			; was it safe?
		beq.s	dsok			; yes
		moveq	#68,d0			; no, wait > 59 microsecs (ms*8[states/ms]/10[dbra])
dswait		dbra	d0,dswait		; wait
		bra.s	dsretry

dsok		move.w	(sp)+,sr
		rts
		
*
* gemsdmaend - tell the z80 we're done with dma
*

gemsdmaend	move.w	sr,-(SP)
		or.w	#$0700,sr		; disable ints

		jsr	gemsholdz80
		move.b	#0,Z80DMABLOCK
		jsr	gemsreleasez80
		
		move.w	(sp)+,sr
		rts

*
* gemsholdz80 - take the z80 bus
*

gemsholdz80	move.w	#$100,BUSREQ		; Z80 bus request on
hzlp		btst.b	#0,BUSREQ		; spin on bus grant
		bne.s	hzlp
		rts
		
*
* gemsreleasez80 - release the z80 bus
*

gemsreleasez80	move.w	#$0,BUSREQ		; Z80 bus request off
		rts

*
* gemsloadz80 - bus request the z80 and download the code between Z80CODE and Z80END
*

gemsloadz80	move.l	a1,-(sp)
		move.w	sr,-(SP)
		or.w	#$0700,sr		; disable ints

		move.w	#$100,BUSRES		; Z80 bus reset off
		jsr	gemsholdz80
	
		lea	Z80CODE+20,a0		; copy from 68k to z80 addr space
		move.l	Z80CODE,d0		;length to move
;		lea	Z80END,a1
;		move.l	a1,d0
;		sub.l	a0,d0
;		subq	#1,d0			; d0 is # of byte to copy - 1 (for dbra)
		lea	Z80RAM,a1
lzlp1		move.b	(a0)+,(a1)+
		dbra	d0,lzlp1
		
lzlp2		move.b	#0,(a1)+		; zero fill remainder of 8k block
		cmpa.l	#(Z80RAM+$2000),a1
		bne.s	lzlp2

		move.w	(sp)+,sr
		move.l	(sp)+,a1
		rts


*
* gemsstartz80 - release the z80 bus and reset the z80 (use after loadz80)
*

gemsstartz80	move.w	sr,-(SP)
		or.w	#$0700,sr		; disable ints

		move.w	#$0,BUSRES		; Z80 bus reset on (assumes buss rquest on)
		move.l	#15,d0			; a loop > 26 uS
szlp		subq.l	#1,d0
		bne.s	szlp
		move.w	#$0,BUSREQ		; Z80 bus request off
		move.w	#$100,BUSRES		; Z80 bus reset off
		
		move.w	(sp)+,sr
		rts

*
* stdsetup - setup these regs:
*  d1 - the old value of wptr
*  a0 - Z80RAM+$36(wptr)
*  a1 - Z80RAM+$1B40(fifo)
* also save the sr, turns off ints, and holds the z80
*
stdsetup	move.l	(sp)+,a0		; get the return addr
		link	a6,#0			; set up the link
		movem.l	d1/a1,-(sp)		; save some regs
		move.w	sr,-(SP)

		move.l	a0,-(sp)		; push the return addr

		lea	Z80RAM+$36,a0		; a0 points to wptr
		lea	Z80RAM+$1B40,a1		; a1 points to fifo

		or.w	#$0700,sr		; disable ints
		
		move.w	#$100,BUSREQ		; Z80 bus request on
sslp		btst.b	#0,BUSREQ		; spin on bus grant
		bne.s	sslp

xout		move.b	(a0),d1			; d1 is write index into fifo
		ext.w	d1			; extend to 16 bits
		rts

*
* stdcleanup - clean up after stdsetup - JMP here only!!!
*
stdcleanup 	move.w	#$0,BUSREQ		; Z80 bus request off
		
		move.w	(sp)+,sr
		movem.l	(sp)+,d1/a1
		unlk	a6
		rts

*
* stdcmdwrite - write a command to the z80(-1, d0), assuming:
*  d0 - the byte
*  d1 - the value of wptr
*  a0 - Z80RAM+$36(wptr)
*  a1 - Z80RAM+$1B40(fifo)
*
stdcmdwrite	move.b	#-1,(a1,d1.w)		; write into fifo

		addq.b	#1,d1			; increment write index mod 64
		andi.b	#$3F,d1
* fall through to stdwrite

*
* stdwrite - write a byte to the z80, assuming:
*  d0 - the byte
*  d1 - the value of wptr
*  a0 - Z80RAM+$36(wptr)
*  a1 - Z80RAM+$1B40(fifo)
*
stdwrite   	move.b	d0,(a1,d1.w)		; write into fifo

		addq.b	#1,d1			; increment write index mod 64
		andi.b	#$3F,d1
		move.b	d1,(a0)			; write it back
		rts

*
* gemsputcbyte - write a byte into the z80's incoming command fifo
*
* stack frame after the link:
*	+------------------+
*	+    byte(long)    +  000000bb
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsputcbyte	jsr	stdsetup

		move.l	8(a6),d0		; get command byte into d0
		jsr	stdwrite

		jmp	stdcleanup

*
* gemsputptr - utility to send a 24-bit ptr to the z80's incoming command fifo
*
* stack frame after the link:
*	+------------------+
*	+     ptr(long)    +  00pppppp
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsputptr	jsr	stdsetup

		move.l	8(a6),d0		; get ptr into d0
		jsr	stdwrite

		asr.l	#8,d0
		jsr	stdwrite

		asr.l	#8,d0
		jsr	stdwrite

		jmp	stdcleanup

*
* gemsinit - initialize the z80 and send pointers to data in 68000 space
*
* stack frame after the link:
*	+------------------+
*	+   sampbankptr    +  00pppppp
*  +20	+------------------+
*	+    seqbankptr    +  00pppppp
*  +16	+------------------+
*	+    envbankptr    +  00pppppp
*  +12	+------------------+
*	+   patchbankptr   +  00pppppp
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsinit	link	a6,#0
		jsr	gemsloadz80
		jsr	gemsstartz80

		moveq	#-1,d0
		move.l	d0,-(A7)
		jsr	gemsputcbyte
		moveq	#11,d0
		move.l	d0,-(A7)
		jsr	gemsputcbyte

		move.l	8(A6),-(A7)
		jsr	gemsputptr
		move.l	12(A6),-(A7)
		jsr	gemsputptr
		move.l	16(A6),-(A7)
		jsr	gemsputptr
		move.l	20(A6),-(A7)
		jsr	gemsputptr
		unlk	a6

		rts


BRIANS_INIT	move.l	Z80CODE+16,D0
		add.l	#Z80CODE,D0
		move.l	D0,-(SP)		;(D) #.sampbank,-(SP)
		move.l	Z80CODE+12,D0
		add.l	#Z80CODE,D0
		move.l	D0,-(SP)		;(S) #.seqbank,-(SP)
		move.l	Z80CODE+8,D0
		add.l	#Z80CODE,D0
		move.l	D0,-(SP)		;(M) #.envbank,-(SP)
		move.l	Z80CODE+4,D0
		add.l	#Z80CODE,D0
		move.l	D0,-(SP)		;(P) #.patchbank,-(SP)
		BSR	gemsinit
		add.l	#16,SP
		RTS


*
* gemsstartsong - start a song by #
*
* stack frame after the link:
*	+------------------+
*	+   song #(long)   +  000000ss
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsstartsong	jsr	stdsetup

		moveq	#16,d0

com1arg		jsr	stdcmdwrite

		move.l	8(A6),d0
		jsr	stdwrite

		jmp	stdcleanup


gemsstartsfx	jsr	stdsetup

		moveq	#16,d0

;com1arg
;		jsr	stdcmdwrite

;		move.l	8(A6),d0
;		jsr	stdwrite

		jmp	stdcleanup



*
* gemsstopsong - stop a song by #
*
* stack frame after the link:
*	+------------------+
*	+   song #(long)   +  000000ss
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsstopsong	jsr	stdsetup

		moveq	#18,d0
		bra.s	com1arg


stop_music	MOVEM.L	a6/A0/D0,-(SP)		;preserve a6/a0/d0
		BSR	GEMSStopSONG
		MOVEM.L	(SP)+,a6/A0/D0
		RTS


go_music	MOVEM.L	a6/A0/D0,-(SP)		;preserve a6/a0/d0
		BSR	GEMSSTARTSONG
		MOVEM.L	(SP)+,a6/A0/D0
.x		RTS



*
* gemssettempo - set tempo
*
* stack frame after the link:
*	+------------------+
*	+   tempo (long)   +  000000tt
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemssettempo	jsr	stdsetup

		moveq	#5,d0
		bra.s	com1arg

*
* gemspauseall - pause all songs currently running
*
* stack frame after the link:
*	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemspauseall	jsr	stdsetup

		moveq	#12,d0
		jsr	stdcmdwrite

		jmp	stdcleanup

*
* gemsresumeall - resume all songs currently paused
*
* stack frame after the link:
*	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsresumeall	jsr	stdsetup

		moveq	#13,d0
		jsr	stdcmdwrite

		jmp	stdcleanup


*
* gemsstopall - stop all songs currently playing, reset
*
* stack frame after the link:
*	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsstopall  	jsr	stdsetup

		moveq	#22,d0
		jsr	stdcmdwrite

		jmp	stdcleanup


*
* gemslockchannel - lock a sound effects channel
*
* stack frame after the link:
*	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemslockchannel	jsr	stdsetup

		moveq	#28,d0
		bra	com1arg

*
* gemsunlockchannel - unlock a sound effects channel
*
* stack frame after the link:
*	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsunlockchannel
		jsr	stdsetup
	
		moveq	#29,d0
		bra	com1arg

*
* gemsprogchange - program change
*
* stack frame after the link:
*	+------------------+
*	+    prog (long)   +  000000pp
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsprogchange	jsr	stdsetup

		moveq	#2,d0

com2arg		jsr	stdcmdwrite

		move.l	8(A6),d0
		jsr	stdwrite

		move.l	12(A6),d0
		jsr	stdwrite

		jmp	stdcleanup

*
* gemsnoteon - turn note on
*
* stack frame after the link:
*	+------------------+
*	+    note (long)   +  000000nn
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsnoteon	jsr	stdsetup

		moveq	#0,d0
		bra.s	com2arg

*
* gemsnoteoff - turn note off
*
* stack frame after the link:
*	+------------------+
*	+    note (long)   +  000000nn
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsnoteoff	jsr	stdsetup

		moveq	#1,d0
		bra.s	com2arg

*
* gemssetprio - set channel priority
*
* stack frame after the link:
*	+------------------+
*	+ priority (long)  +  000000pp
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemssetprio	jsr	stdsetup

		moveq	#20,d0
		bra.s	com2arg

*
* gemspitchbend - pitch bend
*
* stack frame after the link:
*	+------------------+
*	+  bend amt (long) +  0000bbbb  signed 8-bit frac is # semi-tones
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemspitchbend	jsr	stdsetup

		moveq	#5,d0
		jsr	stdcmdwrite

		move.l	8(A6),d0
		jsr	stdwrite

		move.l	12(A6),d0
		jsr	stdwrite

		asr.l	#8,d0
		jsr	stdwrite

		jmp	stdcleanup

*
* gemssetenv - connect channel to envelope(trigger it if not in retrig mode)
*
* stack frame after the link:
*	+------------------+
*	+    env (long)    +  000000ee
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemssetenv   	jsr	stdsetup

		moveq	#6,d0
		bra.s	com2arg

*
* gemsretrigenv - turn on retrig mode if val is 80h, off if 0h
*
* stack frame after the link:
*	+------------------+
*	+    val (long)    +  000000vv
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsretrigenv	jsr	stdsetup

		moveq	#7,d0
		bra.s	com2arg

*
* gemssustain - turn on sustain mode if val is 80h, off if 0h
*
* stack frame after the link:
*	+------------------+
*	+    val (long)    +  000000vv
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemssustain  	jsr	stdsetup

		moveq	#14,d0
		bra.s	com2arg

*
* gemsmute - mute song/channel if val is 1, enable if 0
*
* stack frame after the link:
*	+------------------+
*	+    val (long)    +  000000vv
*  +16	+------------------+
*	+  channel (long)  +  000000cc
*  +12	+------------------+
*	+    song (long)   +  000000ss
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsmute     	jsr	stdsetup

		moveq	#23,d0
com3arg
		jsr	stdcmdwrite

		move.l	8(A6),d0
		jsr	stdwrite

		move.l	12(A6),d0
		jsr	stdwrite

		move.l	16(A6),d0
		jsr	stdwrite

		jmp	stdcleanup


*
* gemsstorembox - store val(0..127) in mailbox(0..29)
*
* stack frame after the link:
*	+------------------+
*	+    val (long)    +  000000vv
*  +12	+------------------+
*	+  mailbox (long)  +  000000mm
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemsstorembox	jsr	stdsetup

		moveq	#27,d0
		bra	com2arg

*
* gemsreadmbox - read a val(0..127) from a mailbox(0..29)
*
* stack frame at the top of the proc:
*	+------------------+
*	+  mailbox (long)  +  000000mm
*  +4	+------------------+
*	+  return address  +
*  a7-> +------------------+
*
* returns value in d0

gemsreadmbox 	move.w	sr,-(SP)
		or.w	#$0700,sr		; disable ints

		jsr	gemsholdz80
		moveq	#0,d0
		move.b	11(a7),d0
		lea	Z80MBOXBASE,a0
		move.b	(A0,d0.w),d0
		jsr	gemsreleasez80

		move.w	(sp)+,sr
		rts

*
* gemssamprate - set digital playback rate for channel
*  4 = no override, get rate from sample header
*  5 = 10.4 kHz, see docs for other freqs
*
* stack frame after the link:
*	+------------------+
*	+    rate (long)   +  000000rr
*  +12	+------------------+
*	+  channel (long)  +  000000cc
*  +8	+------------------+
*	+  return address  +
*  +4	+------------------+
*	+    previous a6   +
*  a6-> +------------------+

gemssamprate 	jsr	stdsetup

		moveq	#26,d0
		bra	com2arg


		;d0=channel : d1=rate
set_samp_rate	movem.l	a0/d0/d1,-(sp)		;preserve a6/a0/d1/d0
		bsr	gemssamprate	
		movem.l	(sp)+,a0/d0/d1
		rts



* Sequence 0 "title2"
* Sequence 1 "STOP THE FIGHT"
* Sequence 2 "box "
* Sequence 3 "ko"
* Sequence 4 "punch fm"
* Sequence 5 "punch fm"
* Sequence 6 "punch fm"
* Sequence 7 "punch fm"
* Sequence 8 "punch fm"
* Sequence 9 "bodypunch1"
* Sequence 10 "bodypunch2"
* Sequence 11 "punch1 fm"
* Sequence 12 "punch2 fm"
* Sequence 13 "miss1"
* Sequence 14 "miss2"
* Sequence 15 "Bell.seq"
* Sequence 16 "CrowdWhistle.fm"
* Sequence 17 "BOOS N WHISTLE"
* Sequence 18 "Letters whoosh (title)"
* Sequence 19 "CHEER"
* Sequence 20 "PSG CHEER"
* Sequence 21 "BACKGROUND CROWD"
* Sequence 22 "break"
* Sequence 23 "DIGITIAL CHEER"
* Sequence 24 "Hitting Mat"
* Sequence 25 "Heartbeat"
* Sequence 26 "Letters explode (title)"
* Sequence 27 "Highlight acknowledge"
* Sequence 28 "sportstalkmusic"
* Sequence 29 "head grunt"
* Sequence 30 "grunt1"
* Sequence 31 "VICTORY (LONGER)"
* Sequence 32 "head grunt"
* Sequence 33 "grunt2lower"
* Sequence 34 "body grunt"
* Sequence 35 "RING GIRL"
* Sequence 36 "ON GROUND"
* Sequence 37 "WHISTLE 2"
* Sequence 38 "BEEP"
* Sequence 39 "victory short w mbs "
* Sequence 40 "wrong choise"
* Sequence 41 "psg crowdnoise medium"
* Sequence 42 "psgcrowdnoise loud"
* Sequence 43 "cmon n figt wimp"
* Sequence 44 "come on 'n fight"
* Sequence 45 "come on you wimp"
* Sequence 46 "fight you wimp"

