es512.asm

来自「isd voice record and playback code」· 汇编 代码 · 共 1,955 行 · 第 1/3 页

ASM
1,955
字号
	call	writebyte
	djnz	R3,write8
;	call	dostop
	clr	SDA					;to establish level for subsequent stop condition
	nop
	setb	SCL
	jnb	SCLIN,$				;wait until SCL is released to ensure operation is completed
	nop
	setb	SDA				;stop condition
;	mov	A,#200			;******change from 64
	mov	A,#65
	call	waitus
	jnb	freeform,rstbuf
	mov	command,#STOPPDN
	call	sendshort
	mov	command,#STOPDIG
	call	sendshort
	ret

readdigital:
	mov	command,#STOPDIG
	call	sendshort
	call	adjaddr
	setb	empty
	jb	freeform,nosetrd
	mov	R0,#databuf
nosetrd:
	setb	SCL		;******change; added
	nop
	jnb	SCLIN,$
	clr	SDA					;start condition
	mov	A,#080h			;address=040h, write
	call	writebyte	;wait for acknowledge
	mov	A,#DIGRD		;read digital
	call	writebyte	;wait for acknowledge
	mov	A,datah
	call	writebyte	;wait for acknowledge
	mov	A,datal
	call	writebyte	;wait for acknowledge
	nop
	nop
	nop
	nop
	setb	SCL
	nop
	jnb	SCLIN,$
	nop			;******extra
	nop
	clr	SDA
	mov	A,#081h			;address=040h, read
	call	writebyte	;wait for acknowledge
	nop
	nop
	mov	R3,#7
; R0 is already set, read and ack 7 bytes, read and no-ack last byte
read7:
	call	readbyte
	jz	was0a
	clr	empty
was0a:
	mov	@R0,A
	inc	R0
	djnz	R3,read7
	setb	noack
	call	readbyte
	jz	was0b
	clr	empty
was0b:
	mov	@R0,A
	inc	R0
	call	dostop
	jnb	freeform,rstbuf
	ret
rstbuf:
	mov	R0,#databuf		;convenience for following code
	mov	command,#STOPPDN
	call	sendshort
	mov	command,#STOPDIG
	call	sendshort
	ret

initmap:
	mov	command,#STOPDIG
	call	sendshort
	mov	datal,#DATAMAPL
	mov	datah,#DATAMAPH
	mov	command,#DIGER
	call	sendlong
if (m224)
	mov	R4,#31		;for 224 msgs
else
	mov	R4,#15		;for 96 msgs
endif
waiterase:
	jb	RAC,$
	jnb	RAC,$
	djnz	R4,waiterase
	mov	command,#STOPDIG
	call	sendshort
	mov	A,#128
	call	waitus
	mov	altmapl,#07fh
	mov	altmaph,#07fh
	mov	command,#STOPPDN
	call	sendshort
	mov	command,#STOPDIG
	call	sendshort
	ret

eraserow:
	mov	command,#STOPDIG
	call	sendshort
	mov	command,#DIGER
	call	adjaddr

	mov	A,#0e0h
	anl	A,addrl
	mov	datal,A

	call	sendlong
	mov	command,#STOPPDN
	call	sendshort
	mov	command,#STOPDIG
	call	sendshort
	mov	A,#128
	call	waitus
	ret

sendshort:
	clr	SDA					;start condition
	mov	A,#080h			;address=040h, write, or
	call	writebyte	;wait for acknowledge
	mov	A,command
	call	writebyte	;wait for acknowledge
	call	dostop
	ret	

readstatus:
	clr	SDA					;start condition
	mov	A,#081h			;read
	call	writebyte	;wait for acknowledge
	call	readbyte	;send acknowledge
	mov	status,A
	call	readbyte	;send acknowledge
	mov	datah,A
	setb	noack
	call	readbyte	;send acknowledge
	mov	datal,A
	call	dostop
	ret

writebyte:
	clr	ackerror
writebyte1:
	mov	R4,#8
	mov	temp1,A
sendloop:
	rlc	A
	clr	SCL
	mov	SDA,C
	nop
	nop
	nop
	nop
	nop
	setb	SCL
	nop
	jnb	SCLIN,$
	djnz	R4,sendloop
	nop
	clr	SCL
	nop
	setb	SDA		;release data line
	nop
	nop
	nop
	nop
	setb	SCL
	nop
; check for ack
	jnb	SCLIN,$
	nop
	nop
	jb	SDAIN,acknotok
	clr		SCL		;end of acknowledge- should return SDA line to transmitter, should go high...
	clr	ackerror
	nop
	nop
	nop		;to be sure that SDA goes high
	ret
acknotok:
	clr	SCL
	jb	ackerror,toobad
	mov	A,#1
	call	waitms
	mov	A,temp1
	setb	ackerror
	jmp	writebyte1
toobad:
	ret			;with ackerror bit set		

readbyte:
	mov	R4,#8
	clr	SCL
	nop
	nop
readloop:
	nop
	nop			;7us matches ISD scope shot...	

	nop
	nop
	setb	SCL
;	jnb	SCLIN,$			;in case receiver is holding SCL low
;	jnb	INT_,$
	nop
	nop
	nop
	nop
	mov	C,SDAIN
	rlc	A
	clr	SCL
	djnz	R4,readloop
	jb	noack,lastbyte
	clr	SDA				;send ack bit
	jmp	sendack
lastbyte:
	setb	SDA
	nop
	nop
	nop
	nop
	nop			;for possible slow SDA rise time
sendack:
	setb	SCL
	nop
	jnb	SCLIN,$		;in case receiver is holding SCL low
	nop
	nop
	nop
	clr		SCL
	clr	noack
	setb	SDA
	nop				;****** all of these
	nop
	nop
	nop
	ret

erase:
	mov	C,mapbit
	mov	bumpadd,C
	mov	addrl,#MSGMAPL
	mov	addrh,#MSGMAPH
	mov	R7,#64
erasemsgloop:
	call readdigital		;mapbit bit will adjust addresses
	mov	R5,#8
eradloop:
	mov	A,@R0
	cjne	A,msg,asis
	mov	@R0,#0
asis:	
	inc	R0
	djnz	R5,eradloop
	cpl	bumpadd
	call writedigital
	cpl	bumpadd
	call	incaddr
	djnz	R7,erasemsgloop
	mov	addrl,#MSGMAPL
	mov	addrh,#MSGMAPH
	call	eraserow
	call	incrow
	call	eraserow
	cpl	mapbit

;erase corresponding msg information
	call	msg2addr
	mov	cdh,addrh
	mov	cdl,addrl
	mov	dig3,addrl
	mov	A,#0e0h
	anl	A,addrl
	mov	addrl,A
	mov	A,#01fh
	anl	A,dig3
	mov	dig3,A
	mov	R5,#0
erasemsginfo:
	mov	A,R5
	cjne A,dig3,copythis
	call	incaddr
	inc	R5
	jmp	finemi
copythis:
	call	readdigital
; if for this message, skip to next (leaving erased)
	cpl	bumpadd
	call	writedigital
	cpl	bumpadd
	call incaddr
	inc	R5
	call	readdigital
; if for this message, skip to next (leaving erased)
	cpl	bumpadd
	call	writedigital
	cpl	bumpadd
finemi:
	call	incaddr
	inc	R5
	cjne	R5,#32,erasemsginfo
	mov	addrh,cdh
	mov	addrl,cdl
	call	eraserow
	call	togglealtbit
	ret

play:
	call	createbitmap
	jb	valid,msgok
	ret
msgok:
	mov	addrl,#0				;******
	mov	addrh,#0				;******
	mov	racs,#nrows
	clr	lastone
	setb	first
	mov	cfg,#PROMPT
	call	setcfg
	clr	P0.6
	clr	TR1
	clr	ET1
	clr	IE1
	setb	EX1
	setb	EA
playloop:
	call	getbit
	jc	pias
getnextp:
	call inccluster
	jmp	playloop
pias:
	call converta
	mov	command,#SETPLAY
	call	sendlonga
	djnz	R6,ndecp
	cjne	R7,#0,pwait
	jmp	finp
ndecp:
	cjne R6,#0ffh,pwait
	dec	R7
pwait:
	jnb	P1.3,stopplay	
	jnb	lastone,pwait
	clr	lastone
	jmp	getnextp
finp:
	jnb	P1.3,stopplay	
	jb	INT_,finp
finp1:
	clr lastone
	clr	EA
	clr	EX1
	ret
stopplay:
	mov	command,#STOP
	call	sendshort
	jnb	P1.3,$
	setb	P0.6
	jmp	finp1
	
record:
	mov	msg,#0					;msg 0 indicates empty spot, msg FF is reserved for digital locations
	call	createbitmap	;creates map and count of all empty locations
	mov	cfg,#MREC
	call	setcfg
	setb	first
	setb	recflag
	mov	cdh,R7
	mov	cdl,R6

	mov	R6,#0			;reset cluster count to 0- will increment as recording continues
	mov	R7,#0

	mov	racs,#nrows
	clr	lastone
	clr	TR1
	clr	ET1
	clr	IE1
	setb	EX1
	setb	EA
;	clr	P0.7			;to detect release of record key
	clr	P0.5
	mov	addrl,#0				;******	
	mov	addrh,#0				;******

recloop:
	call	getbit
	jc	rias
getnextr:
	call	inccluster
	djnz	cdl,ndeccd
	mov	A,cdh
	cjne	A,#0,recloop
	jmp	bailout
ndeccd:
	mov	A,cdl
	cjne A,#0ffh,recloop
	dec	cdh
	jmp	recloop
rias:
	inc	R6		;low byte cluster count
	cjne	R6,#0,riascont
	inc	R7		;high byte cluster count
riascont:
	call	converta
	mov	command,#SETREC
	call	sendlonga
	jnb	lastone,$
	jnb	RAC,$
	clr	lastone
;	jnb	P1.3,getnextr
	jnb	P1.1,getnextr
bailout:
;	setb	P0.7
	setb	P0.5
	clr	lastone
	mov	command,#STOP
	call	sendshort
	clr	EA
	clr	EX1
	clr	recflag
	mov	cfg,#IDLE
	call	setcfg
	mov	msg,rmsg
	call updatemsgmap
	ret

createbitmap:
	mov	C,mapbit
	mov	bumpadd,C
if (m224)
	mov	scans,#62			;for 224 msgs
else
	mov	scans,#63			;for 96 msgs
endif
	mov	R0,#databuf
	clr	done
	clr	valid
	mov	R1,#bitmap
	mov	bits,#8
	mov	addrl,#MSGMAPL
	mov	addrh,#MSGMAPH
	call	readdigital
;	jnb	empty,notempty
;	call	readdigital
notempty:
	mov	R6,#0
	mov	R7,#0
cbmloop:
	mov	A,@R0
	cjne	A,msg,cbm0
	setb	valid
	setb	C
	inc	R6
	mov	A,R6
	jnz	cbm1
	inc	R7
	jmp	cbm1
cbm0:
	clr	C
cbm1:
	call	setbit
	call	advmsg
	jnb	done,cbmloop
	mov	R1,#bitmap
	mov	bits,#8
	mov	addrl,#0
	mov	addrh,#0
	ret

updatemsgmap:
; don't erase map until out of space, to reduce write/erase cycles
	mov	C,mapbit
	mov	bumpadd,C
	mov	R1,#bitmap
	mov	bits,#8
	mov	addrl,#MSGMAPL
	mov	addrh,#MSGMAPH
	mov	R0,#databuf
	call	readdigital			;current map - ensures that unwritten bytes will be copied forward
;	jnb	empty,ne3
;	call	readdigital
ne3:
	setb	writeback				;causes advmsg to rewrite the buffer before reading the next
	jmp	ummloop
nothere:
	call	advmsg
ummloop:
	call	getbit
	jnc	nothere
	mov	@R0,msg
	djnz	R6,ndec
	cjne	R7,#0,nothere
	call	writedigital
	clr	writeback			;for now, just write new information
	ret
ndec:
	cjne R6,#0ffh,nothere
	dec	R7
	jmp	nothere

advmsg:
	inc	R0
	cjne	R0,#(databuf + 8),advok
	jnb	writeback,readonly
	call	writedigital
readonly:
	djnz	scans,notendyet
	setb	done
	ret
notendyet:
	call	incaddr
	call	readdigital
;	jnb	empty,againnotempty
;	call	readdigital
againnotempty:
	nop
advok:	
	ret

setbit:
	mov	A,@R1		;must protect this routine from going beyond end of bitmap
	rlc	A
	jmp	goon
getbit:
	mov	A,@R1
	mov	C,ACC.7
	rl	A
goon:
	mov	@R1,A
	djnz	bits,samebyte
	inc	R1
	mov	bits,#8
samebyte:
	ret

exit:
	pop	ACC
	pop	PSW
	setb	EA
	reti

ext0svc1:
	jmp	exit

ext1svc1:
	djnz	racs,notyet
	mov	racs,#nrows
	jmp	exit
notyet:
	mov	A,racs
	cjne	A,#1,exit
	jnb	RAC,$
	setb	lastone
	mov	A,#60
	call	waitms
	jmp	exit

tmr0svc1:
	jmp	exit

tmr1svc1:
	mov	R3,#0
	mov	R5,#0
	mov	P0,#00fh		;key drive low, 5k control default
	nop
	nop
	mov	A,P1
	anl	A,#KEYIN
	cjne	A,#KEYIN,keydown
	mov	priorkey,lastkey
	mov	lastkey,#010h
donetmr1:	
	cjne	R3,#0,somekey
	setb	keyup
somekey:
	mov	P0,#0ffh		;key drive high, 5k control default
	mov	TL1,#TMRLO20	;20ms key debounce delay
	mov	TH1,#TMRHI20
	clr	TF1
	setb	ET1
	setb	TR1
	jmp	exit
keydown:
	mov	keycount,#010h
	mov	P0,#0Efh
	call	countkeys
	mov	P0,#0Dfh
	call	countkeys
	mov	P0,#0Bfh
	call	countkeys
	mov	P0,#07fh
	call	countkeys
	cjne	R3,#1,exitkeys
	mov	A,keycount
	clr	keyup
	cjne	A,lastkey,setlastkey
	cjne	A,priorkey,setnewkey
	jmp	donetmr1
setnewkey:
	setb	newkey
setlastkey:
	mov	priorkey,lastkey
	mov	lastkey,A
	mov	DPTR,#keydecode
	movc	A,@A+DPTR
	mov	keycode,A
exitkeys:
	jmp	donetmr1

countkeys:
	mov	A,#1
	call	waitms
	mov	R2,#4
	mov	A,P1
keyloop:
	rrc	A
	jc	nopush
	inc	R3
	mov	keycount,R5
nopush:
	inc	R5
	djnz	R2,keyloop
	ret	

waitms:
	mov	timeout1,A
outerloop:
	mov	timeout0,#0
innerloop:
	nop
	nop
	djnz timeout0,innerloop
	djnz timeout1,outerloop
	ret

waitus:
	mov	timeout1,A
usloop:
	nop

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?