📄 paulmon2.asm
字号:
;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 + -