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

📄 paulmon2.asm

📁 MCS51系列单片机的汇编器
💻 ASM
📖 第 1 页 / 共 4 页
字号:
	;mov	 dptr, #edit_cmd
	acall	help2
	mov	r4, #clrm_key
	;mov	 dptr, #clrm_cmd
	acall	help2
	mov	a, #has_flash
	jz	help_skerfm
	mov	r4, #erfr_key
	;mov	 dptr, #erfr_cmd
	acall	help2
help_skerfm:
	mov	dptr, #help2txt
	acall	pcstr_h
	mov	dptr, #bmem
help3:	acall	find
	jnc	help4
	mov	dpl, #4
	clr	a
	movc	a,@a+dptr
	cjne	a, #254, help3a	   ;only FE is an ext command
	acall	dspace
	inc	dpl
	clr	a
	movc	a,@a+dptr
	acall	cout
	acall	dash_sp
	mov	dpl, #32
	acall	pstr
	acall	newline
help3a: inc	dph
	mov	a, dph
	cjne	a, #((emem+1) >> 8) & 255, help3
help4:	
	ajmp	newline

help2:				;print 11 standard lines
	acall	dspace		;given key in R4 and name in dptr
	mov	a, r4
	acall	cout
	acall	dash_sp
	acall	pcstr_h
	ajmp	newline

;---------------------------------------------------------;

upld:

	acall	get_mem
	;assume we've got the beginning address in r3/r2
	;and the final address in r5/r4 (r4=lsb)...

	;print out what we'll be doing
	mov	dptr, #uplds3
	acall	pcstr_h
	mov	a, r3
	acall	phex
	mov	a, r2
	acall	phex
	;mov	 dptr, #uplds4
	acall	pcstr_h
	mov	a, r5
	acall	phex
	mov	a, r4
	acall	phex
	acall	newline

	;need to adjust end location by 1...
	mov	dph, r5
	mov	dpl, r4
	inc	dptr
	mov	r4, dpl
	mov	r5, dph

	mov	dptr, #prompt7
	acall	pcstr_h
	acall	cin
	cjne	a, #27, upld2e
	ajmp	abort_it
upld2e: acall	newline
	mov	dpl, r2
	mov	dph, r3

upld3:	mov	a, r4		;how many more bytes to output??
	clr	c
	subb	a, dpl
	mov	r2, a
	mov	a, r5
	subb	a, dph
	jnz	upld4		;if >256 left, then do next 16
	mov	a, r2
	jz	upld7		;if we're all done
	anl	a, #11110000b
	jnz	upld4		;if >= 16 left, then do next 16
	sjmp	upld5		;otherwise just finish it off
upld4:	mov	r2, #16
upld5:	mov	a, #':'		;begin the line
	acall	cout
	mov	a, r2
	acall	phex		;output # of data bytes
	acall	phex16		;output memory location
	mov	a, dph
	add	a, dpl
	add	a, r2
	mov	r3, a		;r3 will become checksum
	clr	a
	acall	phex		;output 00 code for data
upld6:	clr	a
	movc	a, @a+dptr
	acall	phex		;output each byte
	add	a, r3
	mov	r3, a
	inc	dptr
	djnz	r2, upld6	;do however many bytes we need
	mov	a, r3
	cpl	a
	inc	a
	acall	phex		;and finally the checksum
	acall	newline
	acall	line_dly
	acall	esc
	jnc	upld3		;keep working if no esc pressed
	sjmp	abort_it
upld7:	mov	a, #':'
	acall	cout
	clr	a
	acall	phex
	acall	phex
	acall	phex
	inc	a
	acall	phex
	mov	a, #255
	acall	phex
upld8:	ajmp	newline2


line_dly: ;a brief delay between line while uploading, so the
	;receiving host can be slow (i.e. most windows software)
	mov	a, r0
	push	acc
	mov	r0, #line_delay*2
line_d2:mov	a, th0		;get baud rate const
line_d3:inc	a
	nop
	nop
	jnz	line_d3
	djnz	r0, line_d2
	pop	acc
	mov	r0, a
	ret

;---------------------------------------------------------;

get_mem:     ;this thing gets the begin and end locations for
	     ;a few commands.  If an esc or enter w/ no input,
	     ;it pops it's own return and returns to the menu
	     ;(nasty programming, but we need tight code for 4k rom)
	acall	newline2
	mov	dptr, #beg_str
	acall	pcstr_h
	acall	ghex16
	jc	pop_it
	jb	psw.5, pop_it
	push	dph
	push	dpl
	acall	newline
	mov	dptr, #end_str
	acall	pcstr_h
	acall	ghex16
	mov	r5, dph
	mov	r4, dpl
	pop	acc
	mov	r2, a
	pop	acc
	mov	r3, a
	jc	pop_it
	jb	psw.5, pop_it
	ajmp	newline

pop_it: pop	acc
	pop	acc
abort_it:
	acall	newline
abort2: mov	dptr, #abort
	ajmp	pcstr_h


clrm:
	acall	get_mem
	mov	dptr, #sure
	acall	pcstr_h
	acall	cin_filter_h
	acall	upper
	cjne	a, #'Y', abort_it
	acall	newline2
     ;now we actually do it

clrm2:	mov	dph, r3
	mov	dpl, r2
clrm3:	clr	a
	lcall	smart_wr
	mov	a, r5
	cjne	a, dph, clrm4
	mov	a, r4
	cjne	a, dpl, clrm4
	ret
clrm4:	inc	dptr
	sjmp	clrm3

;---------------------------------------------------------;

nloc:
	mov	dptr, #prompt6
	acall	pcstr_h
	acall	ghex16
	jc	abort2
	jb	psw.5, abort2
	acall	dptrtor6r7
	ajmp	newline2

;---------------------------------------------------------;

erfr:
	acall	newline2
	mov	dptr, #erfr_cmd
	acall	pcstr_h
	mov	a, #','
	acall	cout_sp
	mov	dptr, #sure
	acall	pcstr_h
	acall	cin_filter_h
	acall	upper
	cjne	a, #'Y', abort_it
	acall	newline2
	lcall	erall
	mov	dptr, #erfr_ok
	jnc	erfr_end
	mov	dptr, #erfr_err
erfr_end:
	ajmp	pcstr_h



;---------------------------------------------------------;

intm:	acall	newline
	mov	r0, #0
intm2:	acall	newline
	cjne	r0, #0x80, intm3 
	ajmp	newline
intm3:	mov	a, r0
	acall	phex
	mov	a, #':'
	acall	cout
intm4:	acall	space
	mov	a, @r0
	acall	phex
	inc	r0
	mov	a, r0
	anl	a, #00001111b
	jnz	intm4
	sjmp	intm2





;**************************************************************
;**************************************************************
;*****							  *****
;*****	     2k page boundry is somewhere near here	  *****
;*****	       (no ajmp or acall past this point)	  *****
;*****							  *****
;**************************************************************
;**************************************************************



;---------------------------------------------------------;
;							  ;
;   Subroutines for memory managment and non-serial I/O	  ;
;							  ;
;---------------------------------------------------------;


;finds the next header in the external memory.
;  Input DPTR=point to start search (only MSB used)
;  Output DPTR=location of next module
;    C=set if a header found, C=clear if no more headers
find:	mov	dpl, #0
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xA5, find3
	inc	dptr
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xE5, find3
	inc	dptr
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xE0, find3
	inc	dptr
	clr	a
	movc	a, @a+dptr
	cjne	a, #0xA5, find3
	mov	dpl, #0			;found one here!
	setb	c
	ret
find3:	mov	a, #(emem >> 8)
	cjne	a, dph, find4		;did we just check the end
	clr	c
	ret
find4:	inc	dph			;keep on searching
	sjmp	find



;routine that erases the whole flash rom!  C=1 if failure, C=0 if ok

erall:	mov	a, #has_flash
	jz	erallno
	mov	dptr, #bflash		;is it already erased ??
erall0: clr	a
	movc	a, @a+dptr
	cpl	a
	jnz	erall_b			;do actual erase if any byte not 255
	inc	dptr
	mov	a, #((eflash+1) & 255)
	cjne	a, dpl, erall0
	mov	a, #(((eflash+1) >> 8) & 255)
	cjne	a, dph, erall0
	;if we get here, the entire chip was already erased,
	;so there is no need to do anything
	clr	c
	ret
erall_b:
	mov	dptr, #bflash		;first program to all 00's
erall1: clr	a
	movc	a, @a+dptr
	jz	erall2			;don't waste time!
	clr	a
	lcall	prgm			;ok, program this byte
	;if the program operation failed... we should abort because
	;they are all likely to fail and it will take a long time...
	;which give the appearance that the program has crashed,
	;when it's really following the flash rom algorithm
	;correctly and getting timeouts.
	jc	erallno
	;mov	a, #'.'
	;lcall	cout
erall2: inc	dptr
	mov	a, #((eflash+1) & 255)
	cjne	a, dpl, erall1
	mov	a, #(((eflash+1) >> 8) & 255)
	cjne	a, dph, erall1		;after this it's all 00's
	mov	dptr, #bflash		;beginning address
	mov	r4, #232		;max # of trials, lsb
	mov	r5, #4			;max # of trials, msb-1
erall3: 
	;mov	a, #'#'
	;lcall	cout
	djnz	r4, erall3a
	djnz	r5, erall3a
erallno:setb	c
	ret				;if it didn't work!
erall3a:mov	a, #0x20
	mov	c, ea		 ;-	;turn off all interrupts!!
	mov	psw.1, c
	clr	ea
	movx	@dptr, a		;send the erase setup
	movx	@dptr, a		;and begin the erase
	mov	r3, #erwait1
erwt:	mov	r2, #erwait2		;now wait 10ms...
	djnz	r2, *
	djnz	r3, erwt
erall4: mov	a, #0xA0
	movx	@dptr, a		;send erase verify
	mov	r2, #verwait		;wait for 6us
	djnz	r2, *
	clr	a
	movc	a, @a+dptr
	mov	c, psw.1
	mov	ea, c		;-     ;turn interrupts back on
	cpl	a
	jnz	erall3			;erase again if not FF
	inc	dptr
	mov	a, #(((eflash+1) >> 8) & 255)  ;verify whole array
	cjne	a, dph, erall4
	mov	a, #((eflash+1) & 255)
	cjne	a, dpl, erall4
	mov	a, #255
	mov	dptr, #bflash
	movx	@dptr, a		;reset the flash rom
	clr	a
	movx	@dptr, a		;and go back to read mode
	clr	c
	ret




;a routine that writes ACC to into flash memory at DPTR
; assumes that Vpp is active and stable already.
; C is set if error occurs, C is clear if it worked

prgm:	mov	b, a
	mov	a, r2
	push	acc
	mov	a, r3
	push	acc
	mov	r2, #25	       ;try to program 25 times if needed
prgm2:	mov	a, #40h
	mov	c, ea		 ;-	;turn off all interrupts!!
	mov	psw.1, c
	clr	ea
	movx	@dptr, a	;send setup programming command
	mov	a, b
	movx	@dptr, a	;write to the cell
	mov	r3, #pgmwait	;now wait for 10us
	djnz	r3, *
	mov	a, #0xC0
	movx	@dptr, a	;send program verify command
	mov	r3, #verwait	;wait 6us while it adds margin
	djnz	r3, *
	clr	a
	movc	a, @a+dptr
	mov	c, psw.1
	mov	ea, c		;-     ;turn interrupts back on
	clr	c
	subb	a, b
	jz	prgmok		;note, C is still clear is ACC=0
	djnz	r2, prgm2
prgmbad:setb	c		;it gets here if programming failure
prgmok: clr	a
	movx	@dptr, a	;and go back into read mode
	pop	acc
	mov	r3, a
	pop	acc
	mov	r2, a
	mov	a, b		;restore ACC to original value
	ret



;************************************
;To make PAULMON2 able to write to other
;types of memory than RAM and flash rom,
;modify this "smart_wr" routine.  This
;code doesn't accept any inputs other
;that the address (dptr) and value (acc),
;so this routine must know which types
;of memory are in what address ranges
;************************************


;Write to Flash ROM or ordinary RAM.  Carry bit will indicate
;if the value was successfully written, C=1 if not written.


smart_wr:
	push	acc
	push	b
	mov	b, a
	;do we even have a flash rom?
	mov	a, #has_flash
	jz	wr_ram
	;there is a flash rom, but is this address in it?
	mov	a, dph
	cjne	a, #(eflash >> 8), isfl3
	sjmp	wr_flash
isfl3:	jnc	wr_ram
	cjne	a, #(bflash >> 8), isfl4
	sjmp	wr_flash
isfl4:	jnc	wr_flash
	sjmp	wr_ram

wr_flash:
	mov	a, b
	acall	prgm
	pop	b
	pop	acc
	ret

wr_ram: mov	a, b
	movx	@dptr, a	;write the value to memory
	clr	a
	movc	a, @a+dptr	;read it back from code memory
	clr	c
	subb	a, b
	jz	smwrok
	movx	a, @dptr	;read it back from data memory
	clr	c
	subb	a, b
	jz	smwrok
smwrbad:setb	c
	sjmp	smwrxit
smwrok: clr	c
smwrxit:pop	b
	pop	acc
	ret




;---------------------------------------------------------;
;							  ;
;	Power-On initialization code and such...	  ;
;							  ;
;---------------------------------------------------------;

;first the hardware has to get initialized.

intr_return:
	reti

poweron:
	clr	a
	mov	ie, a		;all interrupts off
	mov	ip, a
	mov	psw, #psw_init
	;clear any interrupt status, just in case the user put
	;"ljmp 0" inside their interrupt service code.
	acall	intr_return
	acall	intr_return
	cpl	a
	mov	p0, a
	mov	p1, a
	mov	p2, a
	mov	p3, a
	mov	sp, #stack

;Before we start doing any I/O, a short delay is required so
;that any external hardware which may be in "reset mode" can
;initialize.  This is typically a problem when a 82C55 chip
;is used and its reset line is driven from the R-C reset
;circuit used for the 8051.  Because the 82C55 reset pin
;switches from zero to one at a higher voltage than the 8051,
;any 82C55 chips would still be in reset mode right now...

rst_dly:
	mov	r1, #200	;approx 100000 cycles
rdly2:	mov	r2, #249	;500 cycles
	djnz	r2, *
	djnz	r1, rdly2

;Check for the Erase-on-startup signal and erase Flash ROM 
;if it's there.

	mov	a, #has_flash
	jz	skip_erase
	mov	a, #erase_pin
	jz	skip_erase
	mov	r0, #250	;check it 250 times, just to be sure
chk_erase:
	mov	c, erase_pin
	mov	r1, #200
	djnz	r1, *		;short delay
	jc	skip_erase	;skip erase if this bit is not low
	djnz	r0, chk_erase
	lcall	erall		;and this'll delete the flash rom
skip_erase:

;run any user initialization programs in external memory
	mov	b, #249
	acall	stcode

;initialize the serial port, auto baud detect if necessary
	acall	autobaud	;set up the serial port
	;mov	a, th1
	;lcall	phex

;run the start-up programs in external memory.
	mov	b, #253
	acall	stcode

;now print out the nice welcome message

welcome:
	mov	r0, #24
welcm2: lcall	newline
	djnz	r0, welcm2
	mov	r0, #15
	mov	a, #' '
welcm4: lcall	cout
	djnz	r0, welcm4
	mov	dptr, #logon1
	lcall	pcstr
	mov	dptr, #logon2
	lcall	pcstr
	lcall	dir
	mov	r6, #(pgm & 255)
	mov	r7, #(pgm >> 8)
	ljmp	menu


stcode: mov	dptr, #bmem	 ;search for startup routines
stcode2:lcall	find
	jnc	stcode5
	mov	dpl, #4
	clr	a
	movc	a, @a+dptr
	cjne	a, b, stcode4	;only startup code if matches B
	push	b
	push	dph
	mov	a, #(stcode3 & 255)
	push	acc
	mov	a, #(stcode3 >> 8)
	push	acc
	mov	dpl, #64
	clr	a
	jmp	@a+dptr		;jump to the startup code
stcode3:pop	dph		;hopefully it'll return to here
	pop	b
stcode4:inc	dph
	mov	a, dph
	cjne	a, #((emem+1) >> 8) & 255, stcode2
stcode5:ret			;now we've executed all of 'em


;to do automatic baud rate detection, we assume the user will
;press the carriage return, which will cause this bit pattern
;to appear on port 3 pin 0 (CR = ascii code 13, assume 8N1 format)
;
;	       0 1 0 1 1 0 0 0 0 1
;	       | |	       | |
; start bit----+ +--lsb	  msb--+ +----stop bit
;
;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

⌨️ 快捷键说明

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