⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 paulmon2.asm

📁 MCS51系列单片机的汇编器
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;by 8 for one bit and by 16 since the built-in UART takes 16 timer
;overflows for each bit.  We need to be careful about roundoff during
;division and the result has to be inverted since timer #1 counts up.  Of
;course, timer #1 gets used in 8-bit auto reload mode for generating the
;built-in UART's baud rate once we know what the reload value should be.


autobaud:
	mov	a, #baud_const	;skip if user supplied baud rate constant
	jnz	autoend_jmp
	mov	a, baud_save+3	;is there a value from a previous boot?
	xrl	baud_save+2, #01010101b
	xrl	baud_save+1, #11001100b
	xrl	baud_save+0, #00011101b
	cjne	a, baud_save+2, autob1
	cjne	a, baud_save+1, autob1
	cjne	a, baud_save+0, autob1
autoend_jmp:
	ajmp	autoend

autob1: ;wait for inactivity

	mov	pcon, #0x80	;configure uart, fast baud
	mov	scon, #0x42	;configure uart, but receive disabled
	mov	tmod, #0x11	;get timers ready for action (16 bit mode)
	clr	a
	mov	tcon, a
	mov	tl0, a
	mov	th0, a
	mov	tl1, a
	mov	th1, a

	;make sure there is no activity on the line
	;before we actually begin looking for the carriage return
	mov	r0, #200
autob1b:mov	r1, #30
autob1c:jnb	p3.0, autob1
	djnz	r1, autob1c
	djnz	r0, autob1b

autob2: ;look for the bits of the carriage return
	jb	p3.0, autob2	;wait for start bit
	jb	p3.0, autob2
	jb	p3.0, autob2	;  check it a few more times to make
	jb	p3.0, autob2	;  sure we don't trigger on some noise
	jb	p3.0, autob2
autob2b:jnb	p3.0, autob2b	;wait for bit #0 to begin
	setb	tr1		;and now we're timing it
autob2c:jb	tf1, autob1	;check for timeout while waiting
	jb	p3.0, autob2c	;wait for bit #1 to begin
autob2d:jb	tf1, autob1	;check for timeout while waiting
	jnb	p3.0, autob2d	;wait for bit #2 to begin
autob2e:jb	tf1, autob1	;check for timeout while waiting
	jb	p3.0, autob2e	;wait for bit #4 to begin
	setb	tr0		;start timing last 4 bits
autob2f:jb	tf1, autob1	;check for timeout while waiting
	jnb	p3.0, autob2f	;wait for stop bit to begin
	clr	tr1		;stop timing (both timers)
	clr	tr0

	jb	tf1, autob1	;check for timeout one last time

	;compute the baud rate based on timer1
	mov	a, tl1
	rlc	a
	mov	b, a
	mov	a, th1
	rlc	a
	jc	autob1		;error if timer0 > 32767
	mov	c, b.7
	addc	a, #0
	cpl	a
	inc	a		;now a has the value to load into th1
	jz	autob1		;error if baud rate too fast

	;after we get the carriage return, we need to make sure there
	;isn't any "crap" on the serial line, as there is in the case
	;were we get the letter E (and conclude the wrong baud rate).
	;unfortunately the simple approach of just looking at the line
	;for silence doesn't work, because we have to accept the case
	;where the user's terminal emulation is configured to send a
	;line feed after the carriage return.  The best thing to do is
	;use the uart and look see if it receives anything

autob3: mov	th1, a		;config timer1
	mov	tl1, #255	;start asap!
	mov	tmod, #0x21	;autoreload mode
	setb	ren		;turn on the uart
	setb	tr1		;turn on timer1 for its clock

	mov	a, th1
	cpl	a
	inc	a
	mov	r1, a
autob3b:mov	r0, #255
autob3c:djnz	r0, autob3c
	djnz	r1, autob3b

	jnb	ri, autob4
	;if we got here, there was some stuff after the carriage
	;return, so we'll read it and see if it was the line feed
	clr	ri
	mov	a, sbuf
	anl	a, #01111111b
	add	a, #246
	jz	autob4		;ok if 0A, the line feed character
	add	a, #5
	jz	autob4		;of if 05, since we may have missed start bit
autob1_jmp:
	ljmp	autob1
autob4:
	;compute the baud rate based on timer0, check against timer1 value
	mov	a, tl0
	rlc	a
	mov	r0, a
	mov	a, th0
	rlc	a
	mov	r1, a
	jc	autob1_jmp	;error if timer0 > 32767
	mov	a, r0
	rlc	a
	mov	b, a
	mov	a, r1
	rlc	a
	mov	c, b.7
	addc	a, #0
	jz	autob1_jmp	;error if baud too fast!
	cpl	a
	inc	a
	cjne	a, th1, autob1_jmp
	;acc has th1 value at this point

autoend:mov	baud_save+3, a
	mov	baud_save+2, a	;store the baud rate for next warm boot.
	mov	baud_save+1, a
	mov	baud_save+0, a
	xrl	baud_save+2, #01010101b
	xrl	baud_save+1, #11001100b 
	xrl	baud_save+0, #00011101b 
	mov	th1, a
	mov	tl1, a
	mov	tmod, #0x21	;set timer #1 for 8 bit auto-reload
	mov	pcon, #0x80	;configure built-in uart
	mov	scon, #0x52
	setb	tr1		;start the baud rate timer
	ret



;---------------------------------------------------------;
;							  ;
;     More subroutines, but less frequent used, so	  ;
;     they're down here in the second 2k page.		  ;
;							  ;
;---------------------------------------------------------;



;this twisted bit of code looks for escape sequences for
;up, down, left, right, pageup, and pagedown, as well
;as ordinary escape and ordinary characters.  Escape
;sequences are required to arrive with each character
;nearly back-to-back to the others, otherwise the characters
;are treated as ordinary user keystroaks.  cin_filter
;returns a single byte when it sees the multi-byte escape
;sequence, as shown here.

; return value	 key	      escape sequence
;   11 (^K)	 up	      1B 5B 41
;   10 (^J)	 down	      1B 5B 42
;   21 (^U)	 right	      1B 5B 43
;    8 (^H)	 left	      1B 5B 44
;   25 (^Y)	 page up      1B 5B 35 7E
;   26 (^Z)	 page down    1B 5B 36 7E

.equ	esc_char, 27

cin_filter:
	jnb	ri, cinf1
	lcall	cin
	cjne	a, #esc_char, cinf_end
	;if esc was already in sbuf, just ignore it
cinf1:	lcall	cin
	cjne	a, #esc_char, cinf_end
cinf2:	acall	cinf_wait
	jb	ri, cinf4
	mov	a, #esc_char
	ret			;an ordinary ESC

cinf4:	;if we get here, it's a control code, since a character
	;was received shortly after receiving an ESC character
	lcall	cin
	cjne	a, #'[', cinf_consume
	acall	cinf_wait
	jnb	ri, cin_filter
	lcall	cin
cinf5a: cjne	a, #'A', cinf5b
	mov	a, #11
	ret
cinf5b: cjne	a, #'B', cinf5c
	mov	a, #10
	ret
cinf5c: cjne	a, #'C', cinf5d
	mov	a, #21
	ret
cinf5d: cjne	a, #'D', cinf5e
	mov	a, #8
	ret
cinf5e: cjne	a, #0x35, cinf5f
	sjmp	cinf8
cinf5f: cjne	a, #0x36, cinf5g
	sjmp	cinf8
cinf5g: sjmp	cinf_consume		;unknown escape sequence

cinf8:	;when we get here, we've got the sequence for pageup/pagedown
	;but there's one more incoming byte to check...
	push	acc
	acall	cinf_wait
	jnb	ri, cinf_restart
	lcall	cin
	cjne	a, #0x7E, cinf_notpg
	pop	acc
	add	a, #228
cinf_end: ret
cinf_restart:
	pop	acc
	sjmp	cin_filter
cinf_notpg:
	pop	acc
;unrecognized escape... eat up everything that's left coming in
;quickly, then begin looking again
cinf_consume:
	acall	cinf_wait
	jnb	ri, cin_filter
	lcall	cin
	cjne	a, #esc_char, cinf_consume
	sjmp	cinf2

;this thing waits for a character to be received for approx
;4 character transmit time periods.  It returns immedately
;or after the entire wait time.	 It does not remove the character
;from the buffer, so ri should be checked to see if something
;actually did show up while it was waiting
	.equ	char_delay, 4		;number of char xmit times to wait
cinf_wait:
	mov	a, r2
	push	acc
	mov	r2, #char_delay*5
cinfw2: mov	a, th0
cinfw3: jb	ri, cinfw4
	inc	a
	jnz	cinfw3
	djnz	r2, cinfw2
cinfw4: pop	acc
	mov	r2, a
	ret




pint8u: ;prints the unsigned 8 bit value in Acc in base 10
	push	b
	push	acc
	sjmp	pint8b

pint8:	;prints the signed 8 bit value in Acc in base 10
	push	b
	push	acc
	jnb	acc.7, pint8b
	mov	a, #'-'
	lcall	cout
	pop	acc
	push	acc
	cpl	a
	add	a, #1
pint8b: mov	b, #100
	div	ab
	setb	f0
	jz	pint8c
	clr	f0
	add	a, #'0'
	lcall	cout
pint8c: mov	a, b
	mov	b, #10
	div	ab
	jnb	f0, pint8d
	jz	pint8e
pint8d: add	a, #'0'
	lcall	cout
pint8e: mov	a, b
	add	a, #'0'
	lcall	cout
	pop	acc
	pop	b
	ret



	;print 16 bit unsigned integer in DPTR, using base 10.
pint16u:	;warning, destroys r2, r3, r4, r5, psw.5
	push	acc
	mov	a, r0
	push	acc
	clr	psw.5
	mov	r2, dpl
	mov	r3, dph

pint16a:mov	r4, #16		;ten-thousands digit
	mov	r5, #39
	acall	pint16x
	jz	pint16b
	add	a, #'0'
	lcall	cout
	setb	psw.5

pint16b:mov	r4, #232	;thousands digit
	mov	r5, #3
	acall	pint16x
	jnz	pint16c
	jnb	psw.5, pint16d
pint16c:add	a, #'0'
	lcall	cout
	setb	psw.5

pint16d:mov	r4, #100	;hundreds digit
	mov	r5, #0
	acall	pint16x
	jnz	pint16e
	jnb	psw.5, pint16f
pint16e:add	a, #'0'
	lcall	cout
	setb	psw.5

pint16f:mov	a, r2		;tens digit
	mov	r3, b
	mov	b, #10
	div	ab
	jnz	pint16g
	jnb	psw.5, pint16h
pint16g:add	a, #'0'
	lcall	cout

pint16h:mov	a, b		;and finally the ones digit
	mov	b, r3
	add	a, #'0'
	lcall	cout

	pop	acc
	mov	r0, a
	pop	acc
	ret

;ok, it's a cpu hog and a nasty way to divide, but this code
;requires only 21 bytes!  Divides r2-r3 by r4-r5 and leaves
;quotient in r2-r3 and returns remainder in acc.  If Intel
;had made a proper divide, then this would be much easier.

pint16x:mov	r0, #0
pint16y:inc	r0
	clr	c
	mov	a, r2
	subb	a, r4
	mov	r2, a
	mov	a, r3
	subb	a, r5
	mov	r3, a
	jnc	pint16y
	dec	r0
	mov	a, r2
	add	a, r4
	mov	r2, a
	mov	a, r3
	addc	a, r5
	mov	r3, a
	mov	a, r0
	ret



;pcstr prints the compressed strings.  A dictionary of 128 words is
;stored in 4 bit packed binary format.	When pcstr finds a byte in
;a string with the high bit set, it prints the word from the dictionary.
;A few bytes have special functions and everything else prints as if
;it were an ordinary string.

; special codes for pcstr:
;    0 = end of string
;   13 = CR/LF
;   14 = CR/LF and end of string
;   31 = next word code should be capitalized

pcstr:	push	acc
	mov	a, r0
	push	acc
	mov	a, r1
	push	acc
	mov	a, r4
	push	acc
	setb	psw.1
	setb	psw.5
pcstr1: clr	a
	movc	a, @a+dptr
	inc	dptr
	jz	pcstr2
	jb	acc.7, decomp
	anl	a, #0x7F
pcstrs1:cjne	a, #13, pcstrs2
	lcall	newline
	setb	psw.1
	sjmp	pcstr1
pcstrs2:cjne	a, #31, pcstrs3
	clr	psw.5
	sjmp	pcstr1
pcstrs3:cjne	a, #14, pcstrs4
	lcall	newline
	sjmp	pcstr2
pcstrs4:
	clr	psw.1
	lcall	cout
	sjmp	pcstr1
pcstr2: pop	acc
	mov	r4, a
	pop	acc
	mov	r1, a
	pop	acc
	mov	r0, a
	pop	acc
	ret

;dcomp actually takes care of printing a word from the dictionary

; dptr = position in packed words table
; r4=0 if next nibble is low, r4=255 if next nibble is high

decomp: anl	a, #0x7F
	mov	r0, a		;r0 counts which word
	jb	psw.1, decomp1	;avoid leading space if first word
	lcall	space
decomp1:clr	psw.1
	push	dpl
	push	dph
	mov	dptr, #words
	mov	r4, #0
	mov	a, r0
	jz	dcomp3
	;here we must seek past all the words in the table
	;that come before the one we're supposed to print
	mov	r1, a
dcomp2: acall	get_next_nibble
	jnz	dcomp2
	;when we get here, a word has been skipped... keep doing
	;this until we're pointing to the correct one
	djnz	r1, dcomp2
dcomp3: ;now we're pointing to the correct word, so all we have
	;to do is print it out
	acall	get_next_nibble
	jz	dcomp_end
	cjne	a, #15, dcomp4
	;the character is one of the 12 least commonly used
	acall	get_next_nibble
	inc	a
	movc	a, @a+pc
	sjmp	dcomp5
	.db	"hfwgybxvkqjz"
dcomp4: ;the character is one of the 14 most commonly used
	inc	a
	movc	a, @a+pc
	sjmp	dcomp5
	.db	"etarnisolumpdc"
dcomp5: ;decide if it should be uppercase or lowercase
	mov	c, psw.5
	mov	acc.5, c
	setb	psw.5
	cjne	r0, #20, dcomp6
	clr	acc.5
dcomp6: cjne	r0, #12, dcomp7
	clr	acc.5
dcomp7: lcall	cout
	sjmp	dcomp3
dcomp_end:
	pop	dph
	pop	dpl
	ajmp	pcstr1

get_next_nibble:	;...and update dptr and r4, of course
	clr	a
	movc	a, @a+dptr
	cjne	r4, #0, gnn2
	mov	r4, #255
	anl	a, #00001111b
	ret
gnn2:	mov	r4, #0
	inc	dptr
	swap	a
	anl	a, #00001111b
	ret


;---------------------------------------------------------;
;							  ;
;	 Here begins the data tables and strings	  ;
;							  ;
;---------------------------------------------------------;

;this is the dictionary of 128 words used by pcstr.

words:
	.db	0x82, 0x90, 0xE8, 0x23, 0x86, 0x05, 0x4C, 0xF8
	.db	0x44, 0xB3, 0xB0, 0xB1, 0x48, 0x5F, 0xF0, 0x11
	.db	0x7F, 0xA0, 0x15, 0x7F, 0x1C, 0x2E, 0xD1, 0x40
	.db	0x5A, 0x50, 0xF1, 0x03, 0xBF, 0xBA, 0x0C, 0x2F
	.db	0x96, 0x01, 0x8D, 0x3F, 0x95, 0x38, 0x0D, 0x6F
	.db	0x5F, 0x12, 0x07, 0x71, 0x0E, 0x56, 0x2F, 0x48
	.db	0x3B, 0x62, 0x58, 0x20, 0x1F, 0x76, 0x70, 0x32
	.db	0x24, 0x40, 0xB8, 0x40, 0xE1, 0x61, 0x8F, 0x01
	.db	0x34, 0x0B, 0xCA, 0x89, 0xD3, 0xC0, 0xA3, 0xB9
	.db	0x58, 0x80, 0x04, 0xF8, 0x02, 0x85, 0x60, 0x25
	.db	0x91, 0xF0, 0x92, 0x73, 0x1F, 0x10, 0x7F, 0x12
	.db	0x54, 0x93, 0x10, 0x44, 0x48, 0x07, 0xD1, 0x26
	.db	0x56, 0x4F, 0xD0, 0xF6, 0x64, 0x72, 0xE0, 0xB8
	.db	0x3B, 0xD5, 0xF0, 0x16, 0x4F, 0x56, 0x30, 0x6F
	.db	0x48, 0x02, 0x5F, 0xA8, 0x20, 0x1F, 0x01, 0x76
	.db	0x30, 0xD5, 0x60, 0x25, 0x41, 0xA4, 0x2C, 0x60
	.db	0x05, 0x6F, 0x01, 0x3F, 0x26, 0x1F, 0x30, 0x07
	.db	0x8E, 0x1D, 0xF0, 0x63, 0x99, 0xF0, 0x42, 0xB8
	.db	0x20, 0x1F, 0x23, 0x30, 0x02, 0x7A, 0xD1, 0x60
	.db	0x2F, 0xF0, 0xF6, 0x05, 0x8F, 0x93, 0x1A, 0x50
	.db	0x28, 0xF0, 0x82, 0x04, 0x6F, 0xA3, 0x0D, 0x3F
	.db	0x1F, 0x51, 0x40, 0x23, 0x01, 0x3E, 0x05, 0x43
	.db	0x01, 0x7A, 0x01, 0x17, 0x64, 0x93, 0x30, 0x2A
	.db	0x08, 0x8C, 0x24, 0x30, 0x99, 0xB0, 0xF3, 0x19
	.db	0x60, 0x25, 0x41, 0x35, 0x09, 0x8E, 0xCB, 0x19
	.db	0x12, 0x30, 0x05, 0x1F, 0x31, 0x1D, 0x04, 0x14
	.db	0x4F, 0x76, 0x12, 0x04, 0xAB, 0x27, 0x90, 0x56
	.db	0x01, 0x2F, 0xA8, 0xD5, 0xF0, 0xAA, 0x26, 0x20
	.db	0x5F, 0x1C, 0xF0, 0xF3, 0x61, 0xFE, 0x01, 0x41
	.db	0x73, 0x01, 0x27, 0xC1, 0xC0, 0x84, 0x8F, 0xD6
	.db	0x01, 0x87, 0x70, 0x56, 0x4F, 0x19, 0x70, 0x1F
	.db	0xA8, 0xD9, 0x90, 0x76, 0x02, 0x17, 0x43, 0xFE
	.db	0x01, 0xC1, 0x84, 0x0B, 0x15, 0x7F, 0x02, 0x8B
	.db	0x14, 0x30, 0x8F, 0x63, 0x39, 0x6F, 0x19, 0xF0
	.db	0x11, 0xC9, 0x10, 0x6D, 0x02, 0x3F, 0x91, 0x09
	.db	0x7A, 0x41, 0xD0, 0xBA, 0x0C, 0x1D, 0x39, 0x5F
	.db	0x07, 0xF2, 0x11, 0x17, 0x20, 0x41, 0x6B, 0x35
	.db	0x09, 0xF7, 0x75, 0x12, 0x0B, 0xA7, 0xCC, 0x48
	.db	0x02, 0x3F, 0x64, 0x12, 0xA0, 0x0C, 0x27, 0xE3
	.db	0x9F, 0xC0, 0x14, 0x77, 0x70, 0x11, 0x40, 0x71
	.db	0x21, 0xC0, 0x68, 0x25, 0x41, 0xF0, 0x62, 0x7F
	.db	0xD1, 0xD0, 0x21, 0xE1, 0x62, 0x58, 0xB0, 0xF3
	.db	0x05, 0x1F, 0x73, 0x30, 0x77, 0xB1, 0x6F, 0x19
	.db	0xE0, 0x19, 0x43, 0xE0, 0x58, 0x2F, 0xF6, 0xA4
	.db	0x14, 0xD0, 0x23, 0x03, 0xFE, 0x31, 0xF5, 0x14
	.db	0x30, 0x99, 0xF8, 0x03, 0x3F, 0x64, 0x22, 0x51
	.db	0x60, 0x25, 0x41, 0x2F, 0xE3, 0x01, 0x56, 0x27
	.db	0x93, 0x09, 0xFE, 0x11, 0xFE, 0x79, 0xBA, 0x60
	.db	0x75, 0x42, 0xEA, 0x62, 0x58, 0xA0, 0xE5, 0x1F
	.db	0x53, 0x4F, 0xD1, 0xC0, 0xA3, 0x09, 0x42, 0x53
	.db	0xF7, 0x12, 0x04, 0x62, 0x1B, 0x30, 0xF5, 0x05
	.db	0xF7, 0x69, 0x0C, 0x35, 0x1B, 0x70, 0x82, 0x2F
	.db	0x2F, 0x14, 0x4F, 0x51, 0xC0, 0x64, 0x25, 0x00

;STR

logon1: .db	"Welcome",128,148,"2, by",31,248,31,254,13,14
logon2: .db	32,32,"See",148,"2.DOC,",148,"2.EQU",164
	.db	148,"2.HDR",180,213,141,".",14
abort:	.db	" ",31,158,31,160,"!",13,14
prompt1:.db	148,"2 Loc:",0
prompt2:.db	" >", 160	;must follow after prompt1
prompt3:.db	134,202,130,'(',0
prompt4:.db	"),",149,140,128,200,": ",0
prompt5:.db	31,151,130,195,"s",199,166,131,","
	.db	186," JUMP",128,134,161,"r",130,13,14
prompt6:.db	13,13,31,135,131,129,": ",0
prompt7:.db	31,228,251," key: ",0
prompt8:.db	13,13,31,136,128,131,129," (",0
prompt9:.db	13,13,31,130,31,253,0
prompt9b:.db	 31,129,32,32,32,32,32,31,201,14	;must follow prompt9
prompt10:.db	") ",31,135,31,178,": ",0
beg_str:.db	"First",31,129,": ",0
end_str:.db	"Last",31,129,":",32,32,0
sure:	.db	31,185,161," sure?",0
edits1: .db	13,13,31,156,154,146,",",140,128,200,14
edits2: .db	"  ",31,156,193,",",142,129,247,13,14
dnlds1: .db	13,13,31,159," ascii",249,150,31,152,132,137
	.db	",",149,140,128,160,13,14
dnlds2: .db	13,31,138,160,"ed",13,14
dnlds3: .db	13,31,138,193,"d",13,14
dnlds4: .db	"Summary:",14
dnlds5: .db	" ",198,"s",145,"d",14
dnlds6a:.db	" ",139,145,"d",14
dnlds6b:.db	" ",139," written",14
dnlds7: .db	31,155,":",14
dnlds8: .db	" ",139," unable",128," write",14
dnlds9: .db	32,32,"bad",245,"s",14
dnlds10:.db	" ",133,159,150,198,14
dnlds11:.db	" ",133,132,157,14
dnlds12:.db	" ",133," non",132,157,14
dnlds13:.db	31,151,155," detected",13,14
runs1:	.db	13,134,"ning",130,":",13,14
uplds3: .db	13,13,"Sending",31,152,132,137,172,32,32,0
uplds4: .db	" ",128,32,32,0		;must follow uplds3
help1txt:.db	13,13,"Standard",31,158,"s",14
help2txt:.db	31,218,31,244,"ed",31,158,"s",14
type1:	.db	31,154,158,0
type2:	.db	31,130,0
type4:	.db	31,143,31,226,31,170,0
type5:	.db	"???",0
help_cmd2:.db	31,215,0
help_cmd: .db	31,142,215,209,0	;these 11 _cmd string must be in order
dir_cmd:  .db	31,209,130,"s",0
run_cmd:  .db	31,134,130,0
dnld_cmd: .db	31,138,0
upld_cmd: .db	31,147,0
nloc_cmd: .db	31,135,129,0
jump_cmd: .db	31,136,128,131,129,0
dump_cmd: .db	31,132,219,154,131,0
intm_cmd: .db	31,132,219,192,131,0
edit_cmd: .db	31,156,154,146,0
clrm_cmd: .db	31,237,131,0
erfr_cmd: .db	31,203,153,144,0
erfr_ok:  .db	31,153,144,203,'d',13,14
erfr_err: .db	31,133,155,13,14


⌨️ 快捷键说明

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