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

📄 mypaulm2.asm

📁 8051 monitor programm: - use external ram to run user program - use eeprom to save user program
💻 ASM
📖 第 1 页 / 共 4 页
字号:
;;we'll start timer #1 in 16 bit mode at the transition between the;start bit and the LSB and stop it between the MBS and stop bit.;That will give approx the number of cpu cycles for 8 bits.  Divide;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, autob1autoend_jmp:	ajmp	autoendautob1: ;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, #200autob1b:mov	r1, #30autob1c:jnb	p3.0, autob1	djnz	r1, autob1c	djnz	r0, autob1bautob2: ;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, autob2autob2b:jnb	p3.0, autob2b	;wait for bit #0 to begin	setb	tr1		;and now we're timing itautob2c:jb	tf1, autob1	;check for timeout while waiting	jb	p3.0, autob2c	;wait for bit #1 to beginautob2d:jb	tf1, autob1	;check for timeout while waiting	jnb	p3.0, autob2d	;wait for bit #2 to beginautob2e:jb	tf1, autob1	;check for timeout while waiting	jb	p3.0, autob2e	;wait for bit #4 to begin	setb	tr0		;start timing last 4 bitsautob2f: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 anythingautob3: 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, aautob3b:mov	r0, #255autob3c: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 bitautob1_jmp:	ljmp	autob1autob4:	;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 pointautoend: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, 27cin_filter:	jnb	ri, cinf1	lcall	cin	cjne	a, #esc_char, cinf_end	;if esc was already in sbuf, just ignore itcinf1:	lcall	cin	cjne	a, #esc_char, cinf_endcinf2:	acall	cinf_wait	jb	ri, cinf4	mov	a, #esc_char	ret			;an ordinary ESCcinf4:	;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	cincinf5a: cjne	a, #'A', cinf5b	mov	a, #11	retcinf5b: cjne	a, #'B', cinf5c	mov	a, #10	retcinf5c: cjne	a, #'C', cinf5d	mov	a, #21	retcinf5d: cjne	a, #'D', cinf5e	mov	a, #8	retcinf5e: cjne	a, #0x35, cinf5f	sjmp	cinf8cinf5f: cjne	a, #0x36, cinf5g	sjmp	cinf8cinf5g: sjmp	cinf_consume		;unknown escape sequencecinf8:	;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, #228cinf_end: retcinf_restart:	pop	acc	sjmp	cin_filtercinf_notpg:	pop	acc;unrecognized escape... eat up everything that's left coming in;quickly, then begin looking againcinf_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 waitcinf_wait:	mov	a, r2	push	acc	mov	r2, #char_delay*5cinfw2: mov	a, th0cinfw3: jb	ri, cinfw4	inc	a	jnz	cinfw3	djnz	r2, cinfw2cinfw4: pop	acc	mov	r2, a	retpint8u: ;prints the unsigned 8 bit value in Acc in base 10	push	b	push	acc	sjmp	pint8bpint8:	;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, #1pint8b: mov	b, #100	div	ab	setb	f0	jz	pint8c	clr	f0	add	a, #'0'	lcall	coutpint8c: mov	a, b	mov	b, #10	div	ab	jnb	f0, pint8d	jz	pint8epint8d: add	a, #'0'	lcall	coutpint8e: 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, dphpint16a:mov	r4, #16		;ten-thousands digit	mov	r5, #39	acall	pint16x	jz	pint16b	add	a, #'0'	lcall	cout	setb	psw.5pint16b:mov	r4, #232	;thousands digit	mov	r5, #3	acall	pint16x	jnz	pint16c	jnb	psw.5, pint16dpint16c:add	a, #'0'	lcall	cout	setb	psw.5pint16d:mov	r4, #100	;hundreds digit	mov	r5, #0	acall	pint16x	jnz	pint16e	jnb	psw.5, pint16fpint16e:add	a, #'0'	lcall	cout	setb	psw.5pint16f:mov	a, r2		;tens digit	mov	r3, b	mov	b, #10	div	ab	jnz	pint16g	jnb	psw.5, pint16hpint16g:add	a, #'0'	lcall	coutpint16h: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, #0pint16y: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 capitalizedpcstr:	push	acc	mov	a, r0	push	acc	mov	a, r1	push	acc	mov	a, r4	push	acc	setb	psw.1	setb	psw.5pcstr1: clr	a	movc	a, @a+dptr	inc	dptr	jz	pcstr2	jb	acc.7, decomp	anl	a, #0x7Fpcstrs1:cjne	a, #13, pcstrs2	lcall	newline	setb	psw.1	sjmp	pcstr1pcstrs2:cjne	a, #31, pcstrs3	clr	psw.5	sjmp	pcstr1pcstrs3:cjne	a, #14, pcstrs4	lcall	newline	sjmp	pcstr2pcstrs4:	clr	psw.1	lcall	cout	sjmp	pcstr1pcstr2: 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 highdecomp: anl	a, #0x7F	mov	r0, a		;r0 counts which word	jb	psw.1, decomp1	;avoid leading space if first word	lcall	spacedecomp1: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, adcomp2: 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, dcomp2dcomp3: ;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.5dcomp6: cjne	r0, #12, dcomp7	clr	acc.5dcomp7: lcall	cout	sjmp	dcomp3dcomp_end:	pop	dph	pop	dpl	ajmp	pcstr1get_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	retgnn2:	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;STRlogon1: .db	"Welcome",128,148,"2, by",31,248,31,254,13,14logon2: .db	32,32,"See",148,"2.DOC,",148,"2.EQU",164	.db	148,"2.HDR",180,213,141,".",14abort:	.db	" ",31,158,31,160,"!",13,14prompt1:.db	148,"2 Loc:",0prompt2:.db	" >", 160	;must follow after prompt1prompt3:.db	134,202,130,'(',0prompt4:.db	"),",149,140,128,200,": ",0prompt5:.db	31,151,130,195,"s",199,166,131,","	.db	186," JUMP",128,134,161,"r",130,13,14prompt6:.db	13,13,31,135,131,129,": ",0prompt7:.db	31,228,251," key: ",0prompt8:.db	13,13,31,136,128,131,129," (",0prompt9:.db	13,13,31,130,31,253,0prompt9b:.db	 31,129,32,32,32,32,32,31,201,14	;must follow prompt9prompt10:.db	") ",31,135,31,178,": ",0beg_str:.db	"First",31,129,": ",0end_str:.db	"Last",31,129,":",32,32,0sure:	.db	31,185,161," sure?",0edits1: .db     13,13,"Address> ",0 ;31,156,154,146,",",140,128,200,14edits2: .db	"  ",31,156,193,",",142,129,247,13,14dnlds1: .db	13,13,31,159," ascii",249,150,31,152,132,137	.db	",",149,140,128,160,13,14dnlds2: .db	13,31,138,160,"ed",13,14dnlds3: .db	13,31,138,193,"d",13,14dnlds4: .db	"Summary:",14dnlds5: .db	" ",198,"s",145,"d",14dnlds6a:.db	" ",139,145,"d",14dnlds6b:.db	" ",139," written",14dnlds7: .db	31,155,":",14dnlds8: .db	" ",139," unable",128," write",14dnlds9: .db	32,32,"bad",245,"s",14dnlds10:.db	" ",133,159,150,198,14dnlds11:.db	" ",133,132,157,14dnlds12:.db	" ",133," non",132,157,14dnlds13:.db	31,151,155," detected",13,14runs1:	.db	13,134,"ning",130,":",13,14uplds3: .db	13,13,"Sending",31,152,132,137,172,32,32,0uplds4: .db	" ",128,32,32,0		;must follow uplds3help1txt:.db	13,13,"Standard",31,158,"s",14help2txt:.db	31,218,31,244,"ed",31,158,"s",14type1:	.db	31,154,158,0type2:	.db	31,130,0type4:	.db	31,143,31,226,31,170,0type5:	.db	"???",0help_cmd2:.db	31,215,0help_cmd: .db	31,142,215,209,0	;these 11 _cmd string must be in orderdir_cmd:  .db	31,209,130,"s",0run_cmd:  .db	31,134,130,0dnld_cmd: .db	31,138,0upld_cmd: .db	31,147,0nloc_cmd: .db	31,135,129,0jump_cmd: .db	31,136,128,131,129,0dump_cmd: .db	31,132,219,154,131,0intm_cmd: .db	31,132,219,192,131,0edit_cmd: .db	31,156,154,146,0clrm_cmd: .db	31,237,131,0erfr_cmd: .db	31,203,153,144,0erfr_ok:  .db	31,153,144,203,'d',13,14erfr_err: .db	31,133,155,13,14

⌨️ 快捷键说明

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