📄 myextra.asm
字号:
opcd11a:acall pcomma
acall plb
mov a, r3
acall phex_h
ajmp opcd10a
opcd12: ;Rn,#data,rel done
acall p_reg_n
ajmp opcd11a
opcd13: ;@Ri,#data,rel done
acall p_reg_i
ajmp opcd11a
opcd19: ;AB done
acall pa
mov a, #'B'
ajmp cout_h
opcd20: ;Rn,rel done
acall p_reg_n
acall pcomma
ajmp prel
opcd21: ;direct,rel done
acall pdirect
ajmp opcd10a
opcd24: ;bit,rel done
acall pbit
ajmp opcd10a
opcd28: ;Rn,A done
acall p_reg_n
acall pcomma
ajmp pa
opcd29: ;Rn,direct done
acall p_reg_n
acall pcomma
ajmp pdirect
opcd30: ;Rn,#data done
acall p_reg_n
ajmp pdata
opcd31: ;direct,Rn done
acall pdirect
acall pcomma
ajmp p_reg_n
opcd32: ;direct,direct done
mov a, r3
push acc
mov a, r4
mov r3, a
acall pdirect
acall pcomma
pop acc
mov r3, a
ajmp pdirect
opcd33: ;direct,@Ri done
acall pdirect
acall pcomma
ajmp p_reg_i
opcd34: ;@Ri,A done
acall p_reg_i
acall pcomma
ajmp pa
opcd35: ;@Ri,direct done
acall p_reg_i
acall pcomma
ajmp pdirect
opcd36: ;@Ri,#data done
acall p_reg_i
ajmp pdata
opcd38: ;DPTR,#data16 done
acall pdptr
acall pcomma
acall plb
opcd27: mov a, r3 ;addr16 done
acall phex_h
mov a, r4
ajmp phex_h
opcd39: ;A,@A+DPTR done
acall pac
acall pat
acall pa
mov a,#'+'
acall cout_h
ajmp pdptr
opcd40: ;A,@A+PC done
acall pac
acall pat
acall pa
mov a,#'+'
acall cout_h
mov a,#'P'
acall cout_h
ajmp prc
opcd41: ;A,@DPTR done
acall pac
acall pat
ajmp pdptr
opcd42: ;@DPTR,A done
acall pat
acall pdptr
acall pcomma
ajmp pa
sfrmnu: .db 0xE0,"AC",'C'+128
.db 0x81,'S','P'+128
.db 0x82,"DP",'L'+128
.db 0x83,"DP",'H'+128
.db 0x80,'P','0'+128
.db 0x90,'P','1'+128
.db 0xA0,'P','2'+128
.db 0xB0,'P','3'+128
.db 0x99,"SBU",'F'+128
.db 0xCD,"TH",'2'+128
.db 0xC8,"T2CO",'N'+128
.db 0xCC,"TL",'2'+128
.db 0xCB,"RCAP2",'H'+128
.db 0xCA,"RCAP2",'L'+128
.db 0x8C,"TH",'0'+128
.db 0x8A,"TL",'0'+128
.db 0x8D,"TH",'1'+128
.db 0x8B,"TL",'1'+128
sfr1: .db 0xF0,'B'+128 ;5
sfr2: .db 0xD0,"PS",'W'+128 ;7
sfr3: .db 0xA8,'I','E'+128
sfr4: .db 0xB8,'I','P'+128
sfr5: .db 0x89,"TMO",'D'+128 ;8
sfr6: .db 0x88,"TCO",'N'+128 ;8
sfr7: .db 0x98,"SCO",'N'+128 ;8
sfr8: .db 0x87,"PCO",'N'+128 ;8
.db 0 ;just in case
opot2: .db 0x59, 0x59, 0x09, 0x09 ;inc, dec, add, addc
.db 0x09, 0x09, 0x09, 0x7A ;orl, anl, xrl, mov
.db 0x7E, 0x09, 0x76, 0x33 ;mov, subb, mov, cjne
.db 0x09, 0x52, 0x09, 0x71 ;xch, djnz, mov, mov
bitptr: .db 0x00, 0x02, 0x06, 0x08, 0x0C, 0x0E, 0x10, 0x12
.db 0x14, 0x16, 0x1B, 0x1E, 0x20, 0x23, 0x24, 0x25
;some stuff used by single step... it's here to fill up some of
;the unused space from the end of the disassembler code and the
;beginning of the single-step header (which must begin on a 256
;byte page boundry)
wr_check: ;write to memory and check that it worked.
;acc=0 if it worked, nonzero if it didn't write
mov r0, a ;keep a copy of the data in r0
movx @dptr, a
clr a
movc a, @a+dptr
clr c
subb a, r0
ret
;delay for approx 1 character transmit time
chardly:mov r1, #80
chdly2: mov a, th1
cpl a
inc a
mov r0, a
djnz r0, *
djnz r1, chdly2
ret
prcolon:acall phex_h
mov a, #':'
ajmp cout_h
phexsp: acall phex_h
space_h:
mov a, #' '
ajmp cout_h
;SINGLE
;---------------------------------------------------------;
; ;
; single step command ;
; ;
;---------------------------------------------------------;
.org locat+0x400
.db 0xA5,0xE5,0xE0,0xA5 ;signiture
.db 254,step_key,0,0 ;id (254=user installed command)
.db 0,0,0,0 ;prompt code vector
.dB 0,0,0,0 ;reserved
.db 0,0,0,0 ;reserved
.db 0,0,0,0 ;reserved
.db 0,0,0,0 ;user defined
.db 255,255,255,255 ;length and checksum (255=unused)
.db "Single-Step",0
.org locat+0x440 ;executable code begins here
ssrun:
;first check to make sure they connect int1 low
jnb p3.3, ssrun2
mov dptr, #sserr1 ;give error msg if int1 not grounded
pcstr_h:
ljmp pcstr
ssrun2: ;make sure there's a ljmp at the int1 vector location
mov dptr, #0x0013
clr a
movc a, @a+dptr
add a, #254
jz ssrun3
mov dptr, #sserr2 ;give error that paulmon2 was not found.
ajmp pcstr_h
ssrun3: ;now write an ljmp to "step" in the ram and check it.
inc dptr
movc a, @a+dptr
mov r0, a
clr a
inc dptr
movc a, @a+dptr
mov dpl, a
mov dph, r0 ;now data pointer points to int1 target
mov a, #2
acall wr_check
jnz ssrun4
inc dptr
mov a, #(step >> 8)
acall wr_check
jnz ssrun4
inc dptr
mov a, #(step & 255)
acall wr_check
jz ssrun5
ssrun4: mov r0, dpl
mov r1, dph
mov dptr, #sserr3 ;error: couldn't write to memory @xxxx
acall pcstr_h
mov a, r1
acall phex_h
mov a, r0
acall phex_h
ajmp newline_h
ssrun5: mov a, ip ;set to high priority interrupt
anl a, #00000100b
mov ip, a
;let's not beat around the bush (like paulmon1), all
;we need to know is where to jump into memory.
mov dptr, #prompt8
acall pcstr_h
mov a, r7
acall phex_h
mov a, r6
acall phex_h
mov dptr,#prompt4
acall pcstr_h
lcall ghex16 ;ask for the jump location
jb psw.5, ssrun7
jnc ssrun6
mov dptr,#abort
acall pstr_h
ajmp newline_h
ssrun6: mov r6, dpl ;where we'll begin executing
mov r7, dph
ssrun7: clr tcon.2 ;need low-level triggered int1
mov dptr,#ssmsg ;tell 'em we're starting
acall pcstr_h
mov dptr,#ssnames
acall pstr_h
clr a
mov sp, #8 ;just like after a reset
push acc ;unlike a 8051 start-up, push return addr
push acc ;of 0000, just in case they end w/ ret
mov dpl, r6 ;load the program's address into dptr
mov dph, r7
mov psw, a ;and clear everything to zero
mov r0, a
mov r1, a
mov r2, a
mov r3, a
mov r4, a
mov r5, a
mov r6, a
mov r7, a
mov b, a
mov lastpc, #ssstart & 255
mov (lastpc+1), #ssstart >> 8
setb ie.2
setb ea ;turn on the interrupt
ssstart:jmp @a+dptr
done: acall chardly
pop acc
mov r1, a
pop acc
mov r0, a
pop dpl
pop dph
pop psw
pop acc
reti
step: ;this is the single step interrupt service code...
push acc
push psw ;Stack Contents: (in this order)
push dph ;PC_L PC_H ACC PSW DPH DPL R0 R1
push dpl
mov a, r0
push acc
mov a, r1
push acc
;in case the previous instruction was "clr ti", we
;must wait for a character transmit time "in case it
;was a move to SBUF) and then set ti so that our cout
;doesn't hang when we transmit the first character!
acall chardly
setb ti
;now print out a line that looks like this:
;ACC B C DPTR R0 R1 R2 R3 R4 R5 R6 R7 SP PC Instruction
;00 00 0 3F00 00:00:00:00:00:00:00:00 00 - 0000: LJMP 0825
acall space_h
acall space_h
mov a, sp
add a, #251
mov r0, a ;r0 points to user's acc on stack
mov a, @r0
acall phexsp ;print acc
mov a, b
acall phexsp ;print b register
inc r0
mov a, @r0
rl a
anl a, #1
acall phex1_h ;print carry bit
acall space_h
inc r0
mov a, @r0
acall phex_h ;print dptr (msb)
inc r0
mov a, @r0
acall phexsp ;print dptr (lsb)
acall space_h
inc r0
mov a, @r0
acall prcolon ;print r0
inc r0
mov a, @r0
acall prcolon ;print r1
mov a, r2
acall prcolon ;print r2
mov a, r3
acall prcolon ;print r3
mov a, r4
acall prcolon ;print r4
mov a, r5
acall prcolon ;print r5
mov a, r6
acall prcolon ;print r6
mov a, r7
acall phexsp ;print r7
acall space_h
mov a, r0
add a, #248
acall phexsp ;print stack pointer
acall space_h
acall space_h
;now the trick is to disassemble the instruction... this isn't
;easy, since the user wants to see the last instruction that
;just executed, but program counter on the stack points to the
;next instruction to be executed. The dirty trick is to grab
;the program counter from last time where we stashed it in some
;memory that hopefully the user's program hasn't overwritten.
mov a, lastpc
mov lastpc, r6
mov r6, a
mov a, (lastpc+1)
mov (lastpc+1), r7
mov r7, a
mov a, r2
push acc
mov a, r3
push acc
mov a, r4
push acc
setb psw.1 ;tell it to use a compact format
;the disassembler uses quite a bit of stack space... if the
;user didn't leave enough room for the stack to grow with
;all this overhead, it will likely crash somewhere in the
;disassembler... oh well, not much I can do about it. The
;worst case stack usage for disasm is 9 bytes. We just
;pushed 5 and 6 at the beginning of step. With the two
;bytes for the interrupt, a total of 22 bytes of free stack
;space must be available to use the single-step feature.
acall disasm
pop acc
mov r4, a
pop acc
mov r3, a
pop acc
mov r2, a
mov r7, (lastpc+1)
mov r6, lastpc
;now grab the user's PC value to keep it for next time
mov a, sp
add a, #249
mov r0, a ;r0 points to user's acc on stack
mov a, @r0
mov lastpc, a
inc r0
mov a, @r0
mov (lastpc+1), a
;SINGLE STEP
step1: lcall cin_filter
lcall upper
step2: cjne a, #13, step7
ajmp done
step7: cjne a, #' ', step8 ;check space
ajmp done
step8: cjne a,#'?',step10 ;check '?'
mov dptr,#help5txt
acall pcstr_h
ajmp step1
step10: cjne a,#'Q',step11 ;check 'Q'=quit and run normal
mov dptr, #squit
acall pstr_h
clr ie.2
acall chardly
mov 8, #0 ;force return to 0000
mov 9, #0
mov sp, #9
reti
step11:
cjne a,#'H',step12 ;check 'H'=hex dump internal ram
ajmp ssdmp
step12: cjne a,#'R',step13 ;check 'R'=print out registers
ajmp ssreg
step13: cjne a,#'S',step14 ;check 'S'=skip next inst
ajmp ssskip
step14: cjne a,#'A',step15 ;check 'A'=change acc value
ajmp sschacc
step15: cjne a,#'.',step20
mov dptr, #ssnames
acall pstr_h
ajmp step1
step20: ajmp step1
pequal: ; prints '='
mov a,#'='
ajmp cout_h
ssdmp:
mov dptr, #ssdmps1
acall pstr_h
clr a
acall prcolon
acall space_h
mov r0, sp
dec r0
mov a, @r0
acall phexsp
inc r0
mov a, @r0
acall phex_h
mov r0, #2
mov r1, #14
ajmp ssdmp2
ssdmp1: mov a, r0
acall prcolon
mov r1, #16
ssdmp2: acall space_h
mov a, @r0
acall phex_h
inc r0
djnz r1, ssdmp2
acall newline_h
cjne r0, #0x00, ssdmp1 ; modified for 256 bytes RAM
acall newline_h
ajmp step1
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -