www.pudn.com > EPG3231adpcm.rar > SPEECHSR.ASM


;************************************************************************ 
;*  Name:     SpeechSR.ASM to EPG3231 body 
;*  Company:  ELAN MICROELECTRONICS CORP. 
;*  Crystal:  32768 Hz 
;*  Designer: Knight kuo    Date:2006/03/09 
;************************************************************************ 
INCLUDE	"EPG3231.H" 
INCLUDE	"Constant.H" 
INCLUDE	"ADPCM0509.H" 
; 
;  ---  come from EPG3231-em202.obj 
EXTERN	PFS_Stable, ENTER_SLEEP, ExFSecErase, ExFWrite 
;  ---  come from Adpcm.obj 
EXTERN	DecodeStart, AdpcmDecode, EncodeStart, AdpcmEncode 
; 
ResetSEG	CSEG	0x10000 
	LJMP	MSTART	;(0x10000) Initialize 
	SJMP	IPAINT	;(0x10002) Input Port And Touch Panel Interrupt 
	NOP 
	LJMP	CAPINT	;(0x10004) Capture Input Interrupt 
	SJMP	SPHINT	;(0x10006) Speech Timer Interrupt 
	NOP 
	SJMP	TMRINT	;(0x10008) Timer-0,1,2 Interrupt 
	NOP 
	SJMP	PERIPH	;(0x1000A) Peripheral Interrupt 
	NOP 
SphTabSeg	CSEG	0x10020 
;  ***  Read speech code subroutine 
Read_Speech_Code: 
	TBRD	1,ACC 
	JBC	TABPTRH,cEndAddr+1,QReadSphcode 
	MOV	A,#0x7F 
QReadSphcode: 
	RET	 
; 
SphSEG	CSEG	0x10100 
; 
;  ***  Interrupt routine 
;  ===  Port A input interrupt routine 
IPAINT: 
	PUSH 
	MOV	A,PAINTSTA 
	JE	A,#0,QIPAINT 
	CLR	PAINTSTA 
	JBS	F_STOP/16,F_STOP%16,QIPAINT 
	CLR	TIMCNT 
	BS	TR01CON,T1EN	;En. Timer1 
QIPAINT: 
	POP 
	RETI 
;  ===  Capture Input Interrupt 
CAPINT: 
	BC	INTSTA,CPIF 
	RETI 
;  ===  Speech Timer Interrupt 
SPHINT: 
	BC	SPHTCON,SPHTI 
	MOVPR	SPHDR,INDF1 
	BC	BSR1,0		;Limit bank0 
	RETI 
;  ===  Timer-0,1,2 Interrupt 
TMRINT: 
	JBS	INTSTA,TMR2I,JTim2Int	;To timer2 int. routine. 
	JBS	INTSTA,TMR1I,JTim1Int	;To timer1 int. routine. 
	BC	INTSTA,TMR0I 
; 
;  ***  Timer 2 interrupt routine 
JTim2Int: 
	BC	INTSTA,TMR2I 
	BS	ADCON,ADEN		;AD enable 
	RETI 
; 
;  ***  Timer 1 interrupt routine 
JTim1Int: 
	BC	INTSTA,TMR1I 
	PUSH 
	INC	TIMCNT 
	JBS	TIMCNT,0,TI32ms 
	JBS	TIMCNT,1,TI64ms 
	JBS	TIMCNT,2,TI128ms 
	JBS	TIMCNT,3,TI256ms 
	JBS	TIMCNT,4,TI512ms 
	JBS	TIMCNT,5,TI1024ms 
;	SJMP	QTim1Int 
;  ---  no function reture 
TI1024ms: 
TI256ms: 
	SJMP	QTim1Int 
; 
;  ===  Check sleep mode debounce 
TI32ms: 
	JBC	FSLPON/16,FSLPON%16,QTim1Int 
	JINZ	SLPCNT,QTim1Int 
	BS	FSLEEP/16,FSLEEP%16 
	SJMP	QTim1Int 
; 
;  ===  Check Record & Playback stop key 
TI64ms: 
	JBS	F_STOP/16,F_STOP%16,QTim1Int 
	BC	TR01CON,T1EN	;Dis. Timer1 
	COMA	xKEY1/16 
	AND	A,#0xF0 
	JBS	STATUS,F_Z,QTim1Int 
	CLR	PAINTEN 
	BS	F_STOP/16,F_STOP%16 
	SJMP	QTim1Int 
; 
;  ===  512ms for cursor control	 
TI512ms: 
	INC	T05SEC 
	JBC	FERASE/16,FERASE%16,QTim1Int 
	BTG	FSHLED/16,FSHLED%16 
	JBC	FSHLED/16,FSHLED%16,TILEDoff 
;  ---  LED turn-on 
	BC	xLED1/16,xLED1%16 
	BC	xLED4/16,xLED4%16 
	SJMP	QTim1Int 
; 
;  ---  LED turn-off 
TILEDoff: 
	MOV	A,#0xFF 
	MOV	xLED1/16,A 
	SJMP	QTim1Int 
; 
;  ===  128ms Key scan 
TI128ms: 
	COMA	PORTA 
	AND	A,#0xF0 
	JBS	STATUS,F_Z,QIKScan		;No key 
	XOR	A,KEY_NO 
	AND	A,#0xF0 
	JBS	STATUS,F_Z,IKScan1 
;	MOV	A,#0x0F 
;	AND	KEY_NO,A 
	COMA	PORTA 
;	AND	A,#0xF0 
	MOV	KEY_NO,A 
	SJMP	QTim1Int 
IKScan1: 
	MOV	A,#0xF0 
	AND	KEY_NO,A 
	MOV	A,#1 
	JBS	KEY_NO,4,IKScan2 
	INC	ACC 
	JBS	KEY_NO,5,IKScan3 
	INC	ACC 
	JBS	KEY_NO,6,IKScan3 
	INC	ACC 
	SJMP	IKScan3 
IKScan2: 
	JBC	KEY_NO,7,IKScan3 
	MOV	A,#5 
IKScan3: 
	OR	KEY_NO,A 
	SJMP	QTim1Int 
QIKScan: 
	CLR	KEY_NO	 
;	SJMP	QTim1Int 
QTim1Int: 
	POP 
	RETI 
; 
;  ===  Peripheral Interrupt 
PERIPH: 
;	JBC	INTSTA,ADIF,QPERIPH 
	BC	INTSTA,ADIF 
	MOVRP	PRODH,ADOTH 
	BS	FAD_OK/16,FAD_OK%16 
;  ---  Write data to flash 
	JBC	FWD_OK/16,FWD_OK%16,QPERIPH 
	BC	FWD_OK/16,FWD_OK%16 
	PUSH 
	LCALL	ExFWrite		;41usec 
	INC	ADD_L 
	JBC	STATUS,F_C,IWrD2Flash 
	INC	ADD_M 
	JBC	STATUS,F_C,IWrD2Flash 
	INC	ADD_H 
IWrD2Flash: 
	POP 
QPERIPH: 
;	BC	SPISTA,SRBFI 
;	BC	INTSTA,URXI 
;	BC	INTSTA,UTXI 
;	BC	INTSTA,UERRI 
	RETI 
; 
;  ***  Subroutine 
;  ===  Key hold release 
KeyHold: 
	MOV	A,KEY_NO 
	AND	A,#0x0F 
	JBC	STATUS,F_Z,KeyHold 
	RET 
; 
;  ===  Clear Bank 16 RAM 0x80 ~ 0x8F 
ClrRAM: 
	MOV	A,#16 
	MOV	BSR1,A 
	CLR	FSR1 
	MOV	A,#16 
	RPT	ACC 
	CLR	INDF1 
	RET 
; 
;  ===  Speech initial routine 
;  ---  Check DAC or PWM code option 
SpeechIni: 
	TBPTH	#0x00 
	TBPTM	#0x00 
	TBPTL	#0x0E*2+1		;word 2 bit 9 & 8 
	BC	FDAOUT/16,FDAOUT%16 
	TBRD	0,ACC		;01: DAC output 
	JBC	ACC,1,QSpeechIni 
	BS	FDAOUT/16,FDAOUT%16 
QSpeechIni: 
	RET 
;	 
;  ***  Address bus + 1 
IWrData: 
	BC	CPUCON,GLINT	;En. all un-mask interrupt. 
	LCALL	ExFWrite		;41usec 
	BS	CPUCON,GLINT	;En. all un-mask interrupt. 
	INC	ADD_L 
	JBC	STATUS,F_C,QIncAddr 
	INC	ADD_M 
	JBC	STATUS,F_C,QIncAddr 
	INC	ADD_H 
QIncAddr: 
	RET 
; 
;********************************************* 
;*  Main program start 
;********************************************* 
MSTART: 
	BC	CPUCON,GLINT	;En. all un-mask interrupt. 
	CLR	STKPTR		;Stack reset 00 
;  ---  EPG3231 I/O setting 
	BC	STBCON,REN	;PA pull-up 
	MOV	A,#00001000b 
	AND	DCRB,A		;PB output 
	MOV	A,#11110111b 
	OR	PORTB,A 
	MOV	A,#0xFF 
	MOV	DCRC,A		;PC input 
	MOV	PCCON,A 
;  ---  Port H & G input for EPG3231-em202 setting 
;  ---  Port D, E & F output for EPG3231-em202 setting 
	MOV	A,#00001111B 
	AND	DCRHI,A		;PI output 
	MOV	A,#0xFF 
	MOV	PORTI,A 
	CLR	DCRJK		;PJ & PK output 
	MOV	PORTJ,A 
	MOV	PORTK,A 
;  ---  Change Fast mode frequency 
	MOV	A,#cPFS 
	LCALL	PFS_Stable 
;  ---  Speech initial 
	BC	FSLEEP/16,FSLEEP%16 
	CLR	KEY_NO 
	CLR	FSHCTRL		;FWRFUL, FERASE 
	CLR	MRCTRL 
	SCALL	SpeechIni 
	In_CS	#11111110b	;/CS is PortB.3 
;  ---  RAM point 
	MOV	A,#00110011b 
	MOV	POST_ID,A 
	BANK	#0 
	MOV	A,#16 
	MOV	BSR1,A 
	CLR	FSR1 
	MOVPR	FSR0,FSR1 
	TBPTH	#0x80 
	TBPTM	#0x40 
	TBPTL	#0x00 
	MOV	A,#16 
	MOV	TIMCNT,A 
ReLoadAddrLp: 
	TBRD	1,ACC 
	JNEA	#0xFF,ReloadAddr 
	COM	ACC 
ReLoadAddr: 
	MOV	INDF1,A 
	JDNZ	TIMCNT,ReloadAddrLp 
	BS	FWRFUL/16,FWRFUL%16 
;  ---  Initial A/D setting 
	MOV	A,#cADCF		;FA/D==999K 
	MOV	ADCF,A          	 
	MOV	A,#01000111b	;VRS:Ext. & Diff. 
	MOV	ADCON,A		;ADIN8 
	BS	ADOTL,FSS		;A/D clock source is from Fpll/2 
	BS	INTCON,ADIE	;A/D int. enable 
;  ---  Timer 2 & Speech Timer setting 
	MOV	A,#cTR2CON 
	MOV	TR2CON,A 
	BS	SFCR,SPHSB	;Speech channel 
	CLR	SPHTCON		;Speech Timer=1/4Mz x (DIPSW) 
	MOV	A,#00000111b	;D/A output control by speeech timer 
	MOV	VOCON,A 
;  ---  Timer 1 setting 
	MOV	A,#cTR01CON 
	MOV	TR01CON,A 
	MOV	A,#cTimer1 
	MOV	TRL1,A 
	MOV	A,#00000110b    	 
	OR	INTCON,A        	 
	CLR	INTSTA          	 
	BS	CPUCON,GLINT	;En. all un-mask interrupt. 
; 
;********************************************* 
;*  Speech playback & record main loop routine 
;*  Key1: Speech sample rate 8K 
;*  Key2: Speech sample rate 9.6K 
;*  Key3: Speech sample rate 12K 
;*  Key4: Speech sample rate 16K 
;*  One touch key is record / playback 
;*  Key1 & Key4 key hold 2 sec is Flash erase 
;********************************************* 
SphMainLp: 
	BS	TR01CON,T1EN	;En. Timer1 
	BS	F_STOP/16,F_STOP%16 
	CLR	PAINTEN 
	MOV	A,#0xFF 
	MOV	xLED1/16,A 
	BS	FSLPON/16,FSLPON%16 
	CLR	SLPCNT 
	SCALL	KeyHold 
SphMainLp1: 
	JBS	FSLEEP/16,FSLEEP%16,Sph2Sleep 
	MOV	A,KEY_NO 
	AND	A,#0x0F 
	ADD	PCL,A 
	SJMP	SphMainLp1 
	SJMP	ToSpeech8K 
	SJMP	ToSpeech9K6 
	SJMP	ToSpeech12K 
	SJMP	ToSpeech16K 
;	SJMP	ToFSHErase 
;  ===  Flash chip erase 
ToFSHErase: 
	CLR	T05SEC 
Key0s5Lp: 
	MOV	A,KEY_NO 
	AND	A,#0x0F 
	JLE	A,#4,SphMainLp 
	JBC	T05SEC,2,Key0s5Lp 
	JNEA	#5,SphMainLp 
	BC	TR01CON,T1EN	;Dis. Timer1 
	BC	FSLPON/16,FSLPON%16 
	BS	FERASE/16,FERASE%16 
	BC	xLED1/16,xLED1%16 
	BC	xLED4/16,xLED4%16 
	SCALL	ClrRAM 
	InAddr	#0x00,#0x20,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x00,#0x30,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x00,#0x40,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x00,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x01,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x01,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x02,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x02,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x03,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x03,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x04,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x04,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x05,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x05,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x06,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x06,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x07,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x07,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x08,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x08,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x09,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x09,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0A,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0A,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0B,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0B,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0C,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0C,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0D,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0D,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0E,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0E,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0F,#0x00,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x0F,#0x80,#0x00 
	LCALL	ExFSecErase 
	InAddr	#0x00,#0x20,#0x08		;ADPCM start address 
	CLR	FSHCTRL			;FWRFUL, FERASE 
	SJMP	SphMainLp 
;  ===  Speech 16K sample rate 
ToSpeech16K: 
;  ---  Speech timer 32K 
	MOV	A,#cSPT32K%0x100 
	MOV	SPHTRL,A 
	MOV	A,#cSPT32K/0x100 
	MOV	SPHTCON,A 
;  ---  Timer2 16K 
	MOV	A,#cADT16K 
	MOV	TRL2,A 
;  ---  RAM 0x80 - 0x83 
	MOV	A,#0x10 
	MOV	BSR1,A 
	MOV	A,#0x80 
	MOV	FSR1,A 
	BC	xLED4/16,xLED4%16 
	SJMP	ChkRecord 
; 
;  ===  Speech 12K sample rate 
ToSpeech12K: 
;  ---  Speech timer 24K 
	MOV	A,#cSPT24K%0x100 
	MOV	SPHTRL,A 
	MOV	A,#cSPT24K/0x100 
	MOV	SPHTCON,A 
;  ---  Timer2 12K 
	MOV	A,#cADT12K 
	MOV	TRL2,A 
;  ---  RAM 0x84 - 0x87 
	MOV	A,#0x10 
	MOV	BSR1,A 
	MOV	A,#0x84 
	MOV	FSR1,A 
	BC	xLED3/16,xLED3%16 
	SJMP	ChkRecord 
; 
;  ===  Speech 9K6 sample rate 
ToSpeech9K6: 
;  ---  Speech timer 19.2K 
	MOV	A,#cSPT19K%0x100 
	MOV	SPHTRL,A 
	MOV	A,#cSPT19K/0x100 
	MOV	SPHTCON,A 
;  ---  Timer2 9.6K 
	MOV	A,#cADT9K 
	MOV	TRL2,A 
;  ---  RAM 0x88 - 0x8B 
	MOV	A,#0x10 
	MOV	BSR1,A 
	MOV	A,#0x88 
	MOV	FSR1,A 
	BC	xLED2/16,xLED2%16 
	SJMP	ChkRecord 
; 
;  ===  Speech 8K sample rate 
ToSpeech8K: 
;  ---  Speech timer 16K 
	MOV	A,#cSPT16K%0x100 
	MOV	SPHTRL,A 
	MOV	A,#cSPT16K/0x100 
	MOV	SPHTCON,A 
;  ---  Timer2 8K 
	MOV	A,#cADT8K 
	MOV	TRL2,A 
;  ---  RAM 0x8C - 0x8F 
	MOV	A,#0x10 
	MOV	BSR1,A 
	MOV	A,#0x8C 
	MOV	FSR1,A 
	BC	xLED1/16,xLED1%16 
;	SJMP	ChkRecord 
; 
;  ===  Check Record or playback 
ChkRecord: 
	BC	FSLPON/16,FSLPON%16 
	MOV	A,INDF1 
	JBS	ACC,0,ToPlayback 
	JBS	FWRFUL/16,FWRFUL%16,SphMainLp 
	SCALL	KeyHold 
	CLR	PAINTSTA 
	BC	TR01CON,T1EN	;Dis. Timer1 
	MOV	A,#0xF0 
	MOV	PAINTEN,A		;En. PA.7~4 int. 
	BC	F_STOP/16,F_STOP%16 
;  ---  Writing Push address 
	MOVRP	TABPTRL,ADD_L 
	MOVRP	TABPTRM,ADD_M 
	MOVRP	TABPTRH,ADD_H 
;  ---  Record start address : word change to byte 
	BC	STATUS,F_C 
	RLCA	ADD_L 
	MOV	INDF1,A 
	RLCA	ADD_M 
	MOV	INDF1,A 
	RLCA	ADD_H 
	BS	ACC,7		;External data ROM 
	MOV	INDF1,A 
;  ---  Setting Flash backup address 
	DEC	FSR1 
	RRCA	FSR1 
	AND	A,#00000110b 
	MOV	ADD_L,A 
	MOV	A,#0x20 
	MOV	ADD_M,A 
	CLR	ADD_H 
;  ---  Writing record address to flash 
	MOV	A,#10001100b 
	AND	FSR1,A 
	MOV	A,#1 
	MOV	INDF1,A 
	MOV	I_DATA_L,A 
	MOVPR	I_DATA_H,INDF1 
	SCALL	IWrData 
	MOVPR	I_DATA_L,INDF1 
	MOVPR	I_DATA_H,INDF1 
	SCALL	IWrData 
;  ---  Writing Pop address 
	MOVPR	ADD_L,TABPTRL 
	MOVPR	ADD_M,TABPTRM 
	MOVPR	ADD_H,TABPTRH 
;  ---  Record speech data to flash 
	BANK	#0 
	CLR	BSR1 
	CLR	FSR1 
	MOVRP	FSR0,FSR1	 
	BC	FAD_OK/16,FAD_OK%16 
	BS	ADCON,ADEN	;AD enable 
WaitFastAD: 
	JBC	FAD_OK/16,FAD_OK%16,WaitFastAD 
	BC	FAD_OK/16,FAD_OK%16 
	MOVPR	ADCODE,PRODH 
	MOVPR	I_DATA_L,PRODH 
	LCALL	EncodeStart 
	CLR	FWRCNT 
	BS	TR2CON,T2EN	;En. Timer2 
RecordLoop: 
	JBS	FAD_OK/16,FAD_OK%16,Wr2Flash 
	JBS	ADD_H,cEndAddr,RecordEnd 
	JBC	F_STOP/16,F_STOP%16,RecordLoop 
;  ---  Stop record flash data => 0x7F 
RecordStop: 
	BC	TR2CON,T2EN	;Dis. Timer2 
	MOV	A,FWRCNT 
	AND	A,#00000011b 
	ADD	PCL,A 
	SJMP	SWr2FlashL 
	SJMP	SWr2FlashL 
	SJMP	SWr2FlashH 
;	SJMP	SWr2FlashH 
SWr2FlashH: 
	MOV	A,#0x7F 
	MOV	I_DATA_H,A 
	SJMP	RecordStop1 
SWr2FlashL:        
	MOV	A,#0x7F 
	MOV	I_DATA_L,A 
	CLR	I_DATA_H 
RecordStop1: 
	SCALL	IWrData 
	SJMP	ChkKeyHold 
; 
;  ===  Writer to flash 
Wr2Flash: 
	BC	FAD_OK/16,FAD_OK%16 
	MOV	A,FWRCNT 
	INC	FWRCNT 
	AND	A,#00000011b 
	ADD	PCL,A 
	SJMP	Wr2Flash5 
	SJMP	Wr2Flash7 
	SJMP	Wr2Flash1 
	SJMP	Wr2Flash3 
;  ---  Write flash High byte & high nibble 
Wr2Flash7: 
	MOVPR	ADCODE,PRODH 
	LCALL	AdpcmEncode	;16usec 
	SWAPA	S1Code		;2:Hn 
	OR	I_DATA_H,A 
	BS	FWD_OK/16,FWD_OK%16 
	SJMP	RecordLoop 
;  ---  Write flash High byte & low nibble 
Wr2Flash5: 
	MOVPR	ADCODE,PRODH 
	LCALL	AdpcmEncode	;16usec 
	MOV	A,S1Code		;2:Ln 
	MOV	I_DATA_H,A 
	SJMP	RecordLoop 
;  ---  Write flash low byte & high nibble 
Wr2Flash3: 
	MOVPR	ADCODE,PRODH 
	LCALL	AdpcmEncode	;16usec 
	SWAPA	S1Code		;1:Hn 
	OR	I_DATA_L,A 
	SJMP	RecordLoop 
;  ---  Write flash low byte & low nibble 
Wr2Flash1: 
	MOVPR	ADCODE,PRODH 
	LCALL	AdpcmEncode	;16usec 
	MOV	A,S1Code		;1:Ln 
	MOV	I_DATA_L,A 
	SJMP	RecordLoop 
; 
;  ===  Record full to the end 
RecordEnd: 
	BC	TR2CON,T2EN	;Dis. Timer2 
	BS	FWRFUL/16,FWRFUL%16 
	SJMP	ChkKeyHold 
; 
;  ===  Playback routine 
ToPlayback: 
	SCALL	KeyHold 
	BC	TR01CON,T1EN	;Dis. Timer1 
	MOV	A,#0xF0 
	MOV	PAINTEN,A		;En. PA.7~4 int. 
	BC	F_STOP/16,F_STOP%16 
	MOVRP	TABPTRL,INDF1 
	MOVRP	TABPTRM,INDF1 
	MOVRP	TABPTRH,INDF1 
;  ---  Playback speech data 
	BANK	#0 
	CLR	BSR1 
	CLR	FSR1 
	MOVRP	FSR0,FSR1 
;  ---  Voice turn-on 
	TBRD	1,ADCODE 
	SCALL	VO_OnSR 
	LCALL	DecodeStart 
	MOV	A,FSR0 
PlaybackLoop: 
	JBS	F_STOP/16,F_STOP%16,PlaybackOff 
	JE	A,FSR1,PlaybackLoop 
; 
;  ===  Playback data to RAM buffer 
Playback: 
	LCALL	AdpcmDecode 
	JNEA	#0x7F,Playback1 
;  ---  Playback stop 
PlaybackOff: 
	SCALL	VO_OffSR 
ChkKeyHold: 
	COMA	xKEY1/16 
	AND	A,#0xF0 
	JBC	STATUS,F_Z,ChkKeyHold 
	SJMP	SphMainLp 
;  ---  Playback data 
Playback1: 
	MOV	A,S1Xn 
	XOR	ADCODE,A		;Swap ADCODE & ACC 
	XOR	A,ADCODE 
	XOR	ADCODE,A 
	ADD	A,ADCODE 
	RRCA	ACC 
	BTG	ACC,7		;unsign change to sign for  
	MOV	INDF0,A 
	BS	FSR0,7		;Limit 0x80 ~ 0xFF 
	MOV	A,FSR0 
Playback2: 
	JE	A,FSR1,Playback2 
	MOV	A,ADCODE 
	BTG	ACC,7		;unsign change to sign for  
	MOV	INDF0,A 
	BS	FSR0,7		;Limit 0x80 ~ 0xFF 
	MOV	A,FSR0 
	SJMP	PlaybackLoop 
; 
;  ===  Sleep mode 
Sph2Sleep: 
	BC	CPUCON,GLINT	;Dis. all un-mask interrupt. 
	BC	TR01CON,T1EN	;Dis. Timer1 
;  ---  Sleep mode 
	MOV	A,#11110000b 
	MOV	PAWAKE,A 
Go2Sleep: 
	LCALL	ENTER_SLEEP 
;  ---  Change Fast mode frequency 
	MOV	A,#cPFS 
	LCALL	PFS_Stable 
	COMA	PORTA 
	AND	A,#0xF0 
	JBS	STATUS,F_Z,Go2Sleep 
	MOV	KEY_NO,A 
;  ---  Wakeup to speech run	 
	CLR	PAWAKE 
	BC	FSLEEP/16,FSLEEP%16 
	CLR	INTSTA          	 
	BS	FSLPON/16,FSLPON%16 
	CLR	SLPCNT 
	BS	TR01CON,T1EN	;En. Timer1 
	BS	CPUCON,GLINT	;En. all un-mask interrupt. 
	SJMP	SphMainLp1 
; 
;***************************************************** 
;Function : Voice turn-on 
;Input parameter :  ADCODE 
;Output parameter : SPHDR 
;***************************************************** 
VO_OnSR: 
	BS	SPHTCON,SPHTIE		;En. speech timer int. 
	BS	SPHTCON,SPHTEN		;En. speech timer 
	BS	VOCON,VOEN		;En. Voice output 
	JBS	FDAOUT/16,FDAOUT%16,QVO_On 
VO_On1: 
	MOV	A,#0x80 
	MOV	SPHDR,A 
	CLR	S1Xn 
	MOV	A,S1Xn 
VO_On2: 
	JE	A,ADCODE,QVO_On 
	INC	ACC 
	MOV	S1Xn,A 
	BTG	ACC,7 
	MOV	INDF0,A 
	BS	FSR0,7 
	MOV	A,FSR0 
VO_OnLp: 
	JE	A,FSR1,VO_OnLp 
	MOV	A,S1Xn 
	SJMP	VO_On2 
QVO_On: 
	MOV	A,ADCODE 
	BTG	ACC,7 
	MOV	INDF0,A 
	BS	FSR0,7 
	RET 
; 
;***************************************************** 
;Function : Voice turn-off 
;Input parameter :  ADCODE 
;Output parameter : SPHDR 
;***************************************************** 
VO_OffSR: 
	JBS	FDAOUT/16,FDAOUT%16,QVO_Off 
	BC	FPBKEND/16,FPBKEND%16 
	BC	TR01CON,T1EN		;Dis. Timer1 
	JBC	F_STOP/16,F_STOP%16,VO_OffLp 
	MOVRP	FSR0,FSR1 
	MOVRP	BSR,BSR1 
	MOV	A,INDF0 
	BS	FSR0,7	;Limit 0x80 ~ 0xFF 
	BTG	ACC,7 
	MOV	ADCODE,A 
VO_OffLp: 
	MOV	A,FSR0 
VO_OffLp1: 
	JE	A,FSR1,VO_OffLp2 
	JBS	FPBKEND/16,FPBKEND%16,VO_OffLp1 
	SJMP	VO_Off1 
VO_OffLp2: 
	JBC	FPBKEND/16,FPBKEND%16,VO_Off1 
QVO_Off: 
	BC	VOCON,VOEN		;Disable Voice output 
	BC	SPHTCON,SPHTEN		;Dis. speech timer 
	BC	SPHTCON,SPHTIE		;Dis. speech timer int. 
	RET 
; 
VO_Off1: 
	MOV	A,ADCODE 
	JBC	STATUS,F_Z,VO_Off2 
	BS	FPBKEND/16,FPBKEND%16 
	SJMP	VO_OffLp 
VO_Off2: 
	DEC	ACC 
	MOV	ADCODE,A 
	BTG	ACC,7 
	MOV	INDF0,A 
	BS	FSR0,7 
	SJMP	VO_OffLp 
;