;
; EXPLOSION SOUND EFFECT FOR COP820.
; TIMER INTERRUPT IS USED.
; SI MUST BE TIED TO SO.  OUTPUT ON SO.
; USE 20MHz XTAL, 1us INSTR CYCLE FOR THIS DEMO.
; 
; WRITTEN BY:  JERRY LEVENTER
; DATE:        OCTOBER 4, 1989
;
; EDITTED MAY 11, 1994 - REVISED FOR NEW ASSEMBLER (ASMCOP v4.2) 
;
	.TITLE XPLOD8
	.CHIP	820
        .SECT   MAIN,ROM,ABS=0
;
	PORTGC	=   0D5 	; PORT G CONFIGURATION
	SIOR	=   0E9 	; SIO SHIFT REGISTER
	TMRLO	=   0EA 	; TIMER LOW BYTE
	TMRHI	=   0EB 	; TIMER HIGH BYTE
	TAULO	=   0EC 	; TIMER REGISTER LOW BYTE
	TAUHI	=   0ED 	; TIMER REGISTER HIGH BYTE
	CNTRL	=   0EE 	; CONTROL REGISTER
	PSW	=   0EF 	; PSW REGISTER
	TRUN	=   4
	TPND	=   5
	BUSY	=   2
;
; ****  SPECIAL REGISTERS AND CONSTANTS  ****
;
;       ANY REGISTER USED FOR THE DRSZ TEST MUST
; 	BE INITIALIZED TO AT LEAST "1" .
;
	FIRSTR	=	0F5	; FIRST TONE CONTROL REGISTER
	  FIRST	= 	002	;   FIRST TONE CONSTANT 
	LASTR	=	0F6	; LAST TONE CONTROL REGISTER
	  LAST	=	002	;   LAST TONE CONSTANT 
	EXITR	= 	0F7	; ROUTINE DURATION REGISTER
	  EXIT	=	010	;   EXIT CONSTANT
	RNGVAL	=	002	; HOLDS CURRENT RANDOM #
	TCNTR	=	0F8	; TONE DURATION REGISTER
	  TCNT	=	0A	;   TONE CONSTANT 
	  TCNT1	=	020	;   "FIRST" TONE CONSTANT
	LUPREG	=	0F9	; EXTRACTION RATE REGISTER
	  XTRCT	=	004	;   EXTRACT CONSTANT
	LUPCNT	=	0FA	; EXTRACTION VARIABLE REGISTER
	TEMP	= 	000	; LAST TONE FLAG 
	TVALO	=   0FF		; TIMER VALUES
	TVALHI  =   010	
;
; ******************************
; ****	BEGIN PROGRAM HERE  ****
; ******************************
;
MAIN:	LD	SP,#02F 	 ; DEFAULT INITIALIZATION OF SP
	JSR	XPLOD		; **** XPLOD CALLING ROUTINE ****
	JP	.		; **** SELF LOOP FOR DEMO ****
XPLOD:	LD	PORTGC,#030
	LD	CNTRL,#08A	; SK = DIV BY 8, PWM ON 
	LD 	PSW,#011	; ENABLE TIMER INTERRUPT
	LD	TMRLO,#TVALO	; INITIALIZE TIMER
	LD	TMRHI,#TVALHI
	LD	TAULO,#TVALO
	LD	TAUHI,#TVALHI
	LD	FIRSTR,#FIRST	; LENGTHEN FIRST TONE
	LD	LASTR,#LAST	; LENGTHEN LAST TONE	
 	LD	EXITR,#EXIT 	; INITIALIZE EXIT COUNT
	LD	TCNTR,#TCNT	; INITIALIZE TONE COUNT
	LD	LUPCNT,#XTRCT	; INITIALIZE EXTRACTION RATE
	RBIT	0,TEMP		; RESET LAST TONE FLAG
	SBIT	TRUN,CNTRL	; START TIMER
NOISE:	SC			; INIT. STAGE 1
	LD	B,#RNGVAL	; POINT TO RANDOM NUMBER
	LD	[B+],#0FF	; INIT TO ALL ONE'S
	LD	[B],#0FF
START:	X	A,SIOR		; LOAD AND START SIOR
	SBIT	BUSY,PSW
	LD	A,LUPCNT	; RESTORE EXTRACTION COUNT
	X	A,LUPREG
;    
;    ----------------------------------------------------------
;    RING COUNTER (17 STAGE)
;
;    THIS IS A SEVENTEEN STAGE RING COUNTER (LINEAR
;    FEEDBACK SHIFT REGISTER) WITH THE RRC COMMAND.
;    THE COUNTER'S 14th AND 17th STAGES THROUGH AN             
;    EXCLUSIVE-OR SERVE AS THE FEEDBACK FUNCTION. 
;    THIS 14,17 RING COUNTER BREAKS DOWN INTO         
;    1 CYCLE OF [(2 ** 17) - 1] COUNTS.  SINCE THE EXCLUSIVE OR
;    OCCURS AFTER THE ROTATE, IT IS THE 15th AND CARRY
;    STAGES THAT ARE XOR'D (BIT 2 AND CARRY).
;
;			  STAGE
;			-----------	
;    BEFORE ROTATE:	14   	17
;    AFTER ROTATE:	15	CARRY   
;
;	CARRY BIT = STAGE 1
;	LOW ORDER BIT OF 16 BIT REGISTER = STAGE 17 
;    ----------------------------------------------------------
;
RING:	LD	A,[B]		; GET RANDOM #
	RRC	A		; ROTATE UPPER BYTE	
	X	A,[B-]		;
	LD	A,[B]
	RRC	A		; ROTATE LOWER BYTE
	X	A,[B]
	LD	A,#004		; PERFORM XOR	
	AND	A,[B]
	IFEQ	A,#000
	JP	TSTLUP
	IFC
	JP	RC
	SC
	JP	TSTLUP
RC:	RC
TSTLUP:	LD	A,[B+]		; POINT TO UPPER BYTE
	DRSZ	LUPREG		; EXTRACT THIS # ?
	JP	RING		; NO, KEEP ROTATING
	LD     A,[B]   		; YES
	JMP	START
;
; *****	TIMER INTERRUPT ROUTINE ******
;
	.=	0FF
	IFBIT	TPND,PSW	; TEST TIMER PND FLAG
	JP	TMOUT
	JMP	XPLOD
TMOUT:	RBIT	TRUN,CNTRL	; STOP TIMER
	LD	B,#LUPCNT
	DRSZ	FIRSTR		; TEST FOR FIRST TONE 
	JMP	NXT1		; AND ADJUST 
	DRSZ	TCNTR		; TEST FOR NEW TONE 
	JP	NXT		; NO
	JP	NEWF
NXT:	LD	FIRSTR,#1	; DISABLE FIRST TONE REG
NXT2:	SBIT	4,PSW		; ENABLE TIMER INTERRUPT
	RBIT	5,PSW		; RESET TPND FLAG
	LD	B,#RNGVAL	; POINT TO RANDOM #
	SBIT	TRUN,CNTRL	; RESTART TIMER
	RETI			; RETURN 
NEWF:	DRSZ	EXITR		; TEST EXIT COUNT
	JP	NF		; NO
	DRSZ	LASTR		; ENABLE LAST TONE
	JP	LST
	JP	NLST
LST:	LD	EXITR,#09	; SET LAST TONE LENGTH
	SBIT 	0,TEMP		; SET LAST TONE FLAG
	JP	NF2	
NLST:	LD	A,SP		; *** RESTORE STACK POINTER ***
	ADD	A,#002		; *** FROM TIMER INTERRUPT  ***
	X	A,SP		; *** AND RETURN TO MAIN    ***
	RET
NF:	IFBIT	0,TEMP		; LAST TONE ?
	JP	NF2		; YES
	LD	A,[B]		; NEW TONE
NF4:	ADD	A,#04		; INCR EXTRACTION VALUE
	X	A,[B]
NF2:	LD	TCNTR,#TCNT	; REINITIALIZE TONE TIME
	JMP 	NXT
NXT1:	LD	TCNTR,#TCNT1	; ADJUST FIRST TONE LENGTH
	JMP	NXT2
	.END
