		;START A NEW SONG PLAYING

		;X REGISTER SELECTS CHANNEL
		;Y REGISTER SELECTS NOTE FROM TABLE

NEWSND: LDA	X,NOTE0_INDEX		;GET CURRENT NOTE OFFSET IN SONG
	ASL				;SONG TABLE ENTRIES 2 BYTES LONG
	TAY				; LENGTH:ENVELOPE, FREQUENCY:CONTROL
	STY 	TEMP0			
	LDA	@SONG_PTR(Y)		;SONG TERMINATED WITH NULL BYTE
	BEQ	.SENDS			; low nybble : envelope number
	STA	X,ENVL0			; high nybble : note length

	LSR				; SHIFT NOTE LENGTH TO
	LSR				; LOW NYBBLE TO USE AS
	LSR				; INDEX INTO NOTE LENGTH TABLE
	LSR
	TAY				;GET NOTE DURATION
	LDA	DUR_TABLE,Y		;16 POSSIBLE NOTE LENGTHS
	STA	X,NOTE0_DUR		;

	LDY	TEMP0			;RESTORE Y
	INY				;GET NEXT BYTE : NOTE TABLE         
	LDA	@SONG_PTR(Y)		

	ASL				;OFFSET INTO NOTE_TABLE
	TAY				;2 BYTES / ENTRY
	LDA	NOTE_TABLE,Y
	STA	X,AUDF0			;FREQ
	INY
	LDA	NOTE_TABLE,Y		;CTL
	STA	X,AUDC0
	
	INC	X,NOTE0_INDEX		;GET READY FOR NEXT NOTE
	RTS

.SENDS:	LDA	#0
	STA	X,AUDV0			;TURN OFF SOUND
	STA	X,NOTE0_INDEX		;reset note counter 
	STA	X,NOTE0_DUR
	RTS



		;ENVELOPE GENERATION ROUTINE

ENVELOP:LDA	X,ENVL0		;LOW ORDER NYBBLE IS ENVELOPE NUMBER	
	AND	#$0F		; IF ENVELOPE # IS 0, IS NOT NOTE,
	BEQ	.REST		; IS REST. SET VOLUME TO 0

	SEC	
	SBC	#01		; DETERMINE WHICH ENVELOPE IS ACTIVE, 0 - 14
	ASL			; EACH ENTRY IS 2 BYTES
	TAY	

	STY	ENVELOPE_NUMBER	;SAVE ACTIVE ENVELOPE NUMBER 

	LDA	X,ENV_INDEX_L	;ENV_INDEX SET TO 0 WHEN NOT ACTIVE
	BNE	.CALC		;ALWAYS NONZERO OTHERWISE

	LDA	Y,ENV_RTBL	;GET ADDRESS OF ENVELOPE RATE TABLE
	STA	ENV_PTR		;FOR CURRENT ACTIVE ENVELOPE
	LDA	Y,ENV_RTBL+1	;2 BYTES PER ENTRY
	STA	ENV_PTR+1	

	LDA	X,ENVL0		; ENVELOPE RATE DEPENDS ON NOTE LENGTH
	AND 	#$F0		; GET NOTE LENGTH
	LSR			; SHIFT IT INTO LOW NYBBLE
	LSR
	LSR

	TAY			; GET ENVELOPE RATE INDEX
	LDA	@ENV_PTR(Y)
	STA	X,ENV_IND_L	;FRACTIONAL PART
	STA	X,ENV_INDEX_L	;MUST BE NONZERO - USED AS FLAG ABOVE

	INY
	LDA	@ENV_PTR(Y)	;INDEX PART
	STA	X,ENV_IND_H
	STA	X,ENV_INDEX_H

.CALC:	LDY	ENVELOPE_NUMBER	; CURRENT ACTIVE ENVELOPE
	LDA	Y,ENV_TBL	;GET ADDRESS OF ACTUAL ENVELOPE TABLE
	STA	ENV_PTR
	LDA	Y,ENV_TBL+1
	STA	ENV_PTR+1	;ENV_PTR FINALLY POINTS TO START OF ENVELOPE

	LDY	X,ENV_IND_H	;GET ENVELOPE INDEX VALUE
	LDA	@ENV_PTR(Y)	;GET ACTUAL ENVELOPE VOLUME
	STA	X,AUDV0		

	CLC
	LDA	X,ENV_IND_L	;CALCULATE NEXT ENVELOPE INDEX VALUE
	ADC	X,ENV_INDEX_L	;AND UPDATE INDEX H & L COUNTERS
	STA	X,ENV_IND_L

	LDA	X,ENV_IND_H
	ADC	X,ENV_INDEX_H
	STA	X,ENV_IND_H

.EXIT:	RTS

.REST:	LDA	#0
	STA	X,AUDV0
	RTS
	

