📄 extra.asm
字号:
acall pbit ajmp opcd10aopcd28: ;Rn,A done acall p_reg_n acall pcomma ajmp paopcd29: ;Rn,direct done acall p_reg_n acall pcomma ajmp pdirectopcd30: ;Rn,#data done acall p_reg_n ajmp pdataopcd31: ;direct,Rn done acall pdirect acall pcomma ajmp p_reg_nopcd32: ;direct,direct done mov a, r3 push acc mov a, r4 mov r3, a acall pdirect acall pcomma pop acc mov r3, a ajmp pdirectopcd33: ;direct,@Ri done acall pdirect acall pcomma ajmp p_reg_iopcd34: ;@Ri,A done acall p_reg_i acall pcomma ajmp paopcd35: ;@Ri,direct done acall p_reg_i acall pcomma ajmp pdirectopcd36: ;@Ri,#data done acall p_reg_i ajmp pdataopcd38: ;DPTR,#data16 done acall pdptr acall pcomma acall plbopcd27: mov a, r3 ;addr16 done acall phex_h mov a, r4 ajmp phex_hopcd39: ;A,@A+DPTR done acall pac acall pat acall pa mov a,#'+' acall cout_h ajmp pdptropcd40: ;A,@A+PC done acall pac acall pat acall pa mov a,#'+' acall cout_h mov a,#'P' acall cout_h ajmp prcopcd41: ;A,@DPTR done acall pac acall pat ajmp pdptropcd42: ;@DPTR,A done acall pat acall pdptr acall pcomma ajmp pasfrmnu: .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'+128sfr1: .db 0xF0,'B'+128 ;5sfr2: .db 0xD0,"PS",'W'+128 ;7sfr3: .db 0xA8,'I','E'+128sfr4: .db 0xB8,'I','P'+128sfr5: .db 0x89,"TMO",'D'+128 ;8sfr6: .db 0x88,"TCO",'N'+128 ;8sfr7: .db 0x98,"SCO",'N'+128 ;8sfr8: .db 0x87,"PCO",'N'+128 ;8 .db 0 ;just in caseopot2: .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, movbitptr: .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 timechardly:mov r1, #80 chdly2: mov a, th1 cpl a inc a mov r0, a djnz r0, * djnz r1, chdly2 retprcolon:acall phex_h mov a, #':' ajmp cout_hphexsp: acall phex_hspace_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 groundedpcstr_h: ljmp pcstrssrun2: ;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_hssrun3: ;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 ssrun5ssrun4: 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_hssrun5: 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_hssrun6: mov r6, dpl ;where we'll begin executing mov r7, dphssrun7: 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 interruptssstart:jmp @a+dptrdone: acall chardly pop acc mov r1, a pop acc mov r0, a pop dpl pop dph pop psw pop acc retistep: ;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 STEPstep1: lcall cin_filter lcall upperstep2: cjne a, #13, step7 ajmp donestep7: cjne a, #' ', step8 ;check space ajmp donestep8: cjne a,#'?',step10 ;check '?' mov dptr,#help5txt acall pcstr_h ajmp step1step10: 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 retistep11: cjne a,#'H',step12 ;check 'H'=hex dump internal ram ajmp ssdmpstep12: cjne a,#'R',step13 ;check 'R'=print out registers ajmp ssregstep13: cjne a,#'S',step14 ;check 'S'=skip next inst ajmp ssskipstep14: cjne a,#'A',step15 ;check 'A'=change acc value ajmp sschaccstep15: cjne a,#'.',step20 mov dptr, #ssnames acall pstr_h ajmp step1step20: ajmp step1 pequal: ; prints '=' mov a,#'=' ajmp cout_hssdmp: 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 ssdmp2ssdmp1: mov a, r0 acall prcolon mov r1, #16ssdmp2: acall space_h mov a, @r0 acall phex_h inc r0 djnz r1, ssdmp2 acall newline_h cjne r0, #0x80, ssdmp1 acall newline_h ajmp step1ssreg: mov dptr, #sfr2+1 acall pstr_h acall pequal mov a, sp add a, #252 mov r0, a mov a, @r0 acall phexsp ;print psw mov dptr,#sfr3+1 mov r0, 0xA8 acall psfr ;print ie mov dptr,#sfr4+1 mov r0, 0xB8 acall psfr ;print ip mov dptr,#sfr5+1 mov r0, 0x89 acall psfr ;print tmod mov dptr,#sfr6+1 mov r0, 0x88 acall psfr ;print tcon mov dptr,#sfr7+1 mov r0, 0x98 acall psfr ;print smod mov dptr,#sfr8+1 mov r0, 0x87 acall psfr ;print pcon mov a, #'T' acall cout_h mov a, #'0' acall cout_h acall pequal mov a, 8Ch acall phex_h ;print Timer 0 mov a, 8Ah acall phex_h acall space_h mov a, #'T' acall cout_h mov a, #'1' acall cout_h acall pequal mov a, 8Dh ;print Timer 1 acall phex_h mov a, 8Bh acall phex_h acall newline_h ajmp step1psfr: acall pstr_h acall pequal
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -