📄 monplus.asm
字号:
ACALL GETC ;GET THE NEXT CHARACTER
CJNE A,#' ',GO1 ;NOT A SPACE SO KEEP CHECKING
SJMP GO ;SPACE DOESN'T MEAN ANYTHING SO LOOP
GO1: CJNE A,#CR,GO2 ;NOT A RETURN SO PRESUME A NEW ADDRESS
SJMP GO3 ;RETURN, SO GO FROM OLD ADDRESS
GO2: ACALL RDHX1 ;PRESUME A NEW ADDRESS
MOV DPH,A
ACALL RDHEX
MOV DPL,A
GO3: PUSH DPL ;PC IS NOW OK SO RESTORE IT
PUSH DPH
ACALL RESTORE ;RESTORE EVERYTHING ELSE
ACALL SETALL ;SET ALL ACTIVE BREAKPOINTS
RET ;RETURN IS ACTUALLY A GO!!
STEP: POP DPH ;GET THE OLD PROGRAM COUNTER
POP DPL ;USE DPTR SINCE IT WILL BE RESTORED
ACALL GETC ;GET THE NEXT CHARACTER
CJNE A,#' ',STEP1 ;NOT A SPACE SO KEEP CHECKING
SJMP STEP ;SPACE DOESN'T MEAN ANYTHING SO LOOP
STEP1: CJNE A,#CR,STEP2 ;NOT A RETURN SO PRESUME A NEW ADDRESS
SJMP STEP3 ;RETURN, SO STEP FROM OLD ADDRESS
STEP2: ACALL RDHX1 ;PRESUME A NEW ADDRESS
MOV DPH,A
ACALL RDHEX
MOV DPL,A
STEP3: ACALL CRLF ;GO TO A NEW LINE TO MAKE IT PRETTY
PUSH DPL ;PC IS NOW OK SO RESTORE
PUSH DPH
ACALL RESTORE ;RESTORE EVERYTHING ELSE
PUSH ACC ;SAVE THE ACCUMULATOR
SETB P3.2 ;MAKE SURE INT0 IS OFF
MOV A,#10 ;SHORT DELAY TO MAKE SURE IT GOT DONE
DJNZ ACC,*
ORL IE,#0x81 ;ENABLE INT0
ORL IP,#0x01 ;AND MAKE IT HIGH PRIORITY
MOV A,#10 ;SHORT DELAY TO MAKE SURE IT GOT DONE
DJNZ ACC,*
POP ACC ;RESTORE THE ACCUMULATOR
ACALL SETALL ;SET ALL BREAKPOINTS
CLR P3.2 ;CAUSE INT0 AFTER THE NEXT INSTRUCTION
RETI ;RETURN IS ACTUALLY A GO!!
.eject
UCALL: POP ADHI ;GET THE OLD PROGRAM COUNTER
POP ADLO
ACALL GETC ;GET THE NEXT CHARACTER
CJNE A,#' ',CALL1 ;NOT A SPACE SO KEEP CHECKING
SJMP UCALL ;SPACE DOESN'T MEAN ANYTHING SO LOOP
CALL1: CJNE A,#CR,CALL2 ;NOT A RETURN SO PRESUME A NEW ADDRESS
SJMP CALL3 ;RETURN, SO GO FROM OLD ADDRESS
CALL2: ACALL RDHX1 ;PRESUME A NEW ADDRESS
MOV ADHI,A
ACALL RDHEX
MOV ADLO,A
CALL3: MOV DPTR,#CALLRET ;PUSH THE ADDRESS OF CALLRET SO THAT
PUSH DPL ;THE RETURN OF THE CALLED ROUTINE
PUSH DPH ;WILL GO THERE
ACALL RESTORE ;RESTORE EVERYTHING EXCEPT PC
PUSH ADLO ;PC IS NOW OK SO RESTORE
PUSH ADHI
ACALL SETALL ;SET ALL BREAKPOINTS
RET ;RETURN IS ACTUALLY A GO!!
.eject
DUMP: PUSH ACC ;SAVE THE ACCUMULATOR
PUSH DPH ;AND THE DPTR
PUSH DPL
PUSH TEMP1 ;AND THE WORK AREAS
PUSH CNTHI
PUSH CNTLO
ACALL RDHEX ;GET THE UPPER BYTE OF THE START ADDRESS
MOV DPH,A
ACALL RDHEX ;GET THE LOWER BYTE OF THE START ADDRESS
ANL A,#0xF0 ;START ON 16-BYTE BOUNDARY
MOV DPL,A
ACALL RDHEX ;GET THE HIGH BYTE OF THE COUNT
MOV CNTHI,A
ACALL RDHEX ;AND THE LOW BYTE OF THE COUNT
MOV CNTLO,A
ACALL CRLF ;START ON A NEW LINE
LOUTLP: MOV TEMP1,#0x10 ;SET UP BYTE COUNTER
MOV A,DPH ;AT START OF LINE OUTPUT ADDR
ACALL WRBYTE
MOV A,DPL
ACALL WRBYTE
ACALL SPACE ;AND SPACE TO MAKE IT TIDY
PUSH DPH ;SAVE DPTR FOR LATER
PUSH DPL
BOUTLP: MOVX A,@DPTR ;OUTPUT HEX ONE BYTE AT A TIME
ACALL WRBYTE
ACALL SPACE ;A SPACE TO MAKE IT NEAT
INC DPTR
DJNZ TEMP1,BOUTLP ;IF NOT DONE, LOOP
ACALL SPACE ;A SPACE TO MAKE IT NEAT
POP DPL ;RESTORE THE DPTR
POP DPH
MOV TEMP1,#0x10 ;SET UP BYTE COUNTER
AOUTLP: MOVX A,@DPTR ;OUTPUT ASCII ONE BYTE AT A TIME
CJNE A,#127,AOUT1 ;SEE IF ITS >127
AOUT1: JNC AOUT3 ;YES, SO OUTPUT '.'
CJNE A,#' ',AOUT2 ;SEE IF ITS <32
AOUT2: JC AOUT3 ;YES, SO OUTPUT '.'
SJMP AOUT4 ;ITS PRINTABLE, SO PRINT IT
AOUT3: MOV A,#'.' ;NOT PRINTABLE, SO MAKE IT '.'
AOUT4: ACALL PUTC ;PRINT IT
INC DPTR
DJNZ TEMP1,AOUTLP ;IF NOT DONE, LOOP
ACALL CRLF ;GO TO NEXT LINE
CLR C ;SET UP FOR SUBTRACT
MOV A,CNTLO ;SUBTRACT 16 FROM THE COUNT
SUBB A,#0x10
MOV CNTLO,A
MOV A,CNTHI
SUBB A,#0
MOV CNTHI,A
ORL A,CNTLO ;SEE IF WE'VE REACHED ZERO YET
JZ DMPSKP ;IF SO, WE'RE DONE
JNC LOUTLP ;NO CARRY, SO NOT DONE YET
DMPSKP: POP CNTLO ;RESTORE THE WORK AREAS
POP CNTHI
POP TEMP1
POP DPL ;AND THE DPTR
POP DPH
POP ACC ;AND THE ACCUMULATOR
RET ;BACK FOR NEXT COMMAND
.eject
PRMLD: MOV BKFLAG,#0 ;CLEAR ALL BREAKPOINTS
MOV A,R0 ;SAVE R0
PUSH ACC
PUSH DPH ;SAVE DPTR
PUSH DPL
PUSH ADHI ;SAVE ADHI AND ADLO
PUSH ADLO
PUSH TEMP1 ;SAVE TEMP1 THRU TEMP3
PUSH TEMP2
PUSH TEMP3
MOV TEMP2,#0 ;SET UP ZERO OFFSET
MOV TEMP3,#0
PRM: ACALL GETC ;GET THE NEXT CHARACTER
CJNE A,#' ',PRM1 ;NOT A SPACE SO KEEP CHECKING
SJMP PRM ;SPACE DOESN'T MEAN ANYTHING SO LOOP
PRM1: CJNE A,#CR,PRM2 ;NOT A RETURN SO PRESUME A NEW ADDRESS
SJMP PRMWAIT ;RETURN, SO GO FROM ZERO
PRM2: ACALL RDHX1 ;PRESUME AN OFFSET
MOV TEMP3,A
ACALL RDHEX
MOV TEMP2,A
ACALL CRLF
PRMLIN: ACALL CRLF
PRMWAIT: ACALL GETC ;WAIT UNTIL ':' IS RECEIVED (START OF LINE)
CJNE A,#':',PRMWAIT
MOV CKSUM,#0 ;INITIALIZE THE CHECKSUM
MOV R0,#BUFFER ;POINT R0 TO THE BUFFER AREA
ACALL RDHEX ;GET THE BYTE COUNT
MOV CNTLO,A ;INITIALIZE THE COUNT
ADD A,CKSUM ;UPDATE THE CHECKSUM
MOV CKSUM,A
JZ PRMDONE ;LAST RECORD HAS 0 BYTE COUNT
MOV TEMP1,CNTLO ;LOAD BYTE COUNT FOR LINE INTO TEMP1
ACALL RDHEX ;READ HIGH BYTE OF START ADDRESS
MOV ADHI,A
ADD A,CKSUM ;UPDATE THE CHECKSUM
MOV CKSUM,A
ACALL RDHEX ;READ LOW BYTE OF START ADDRESS
MOV ADLO,A
ADD A,CKSUM ;UPDATE THE CHECKSUM
MOV CKSUM,A
ACALL RDHEX ;READ RECORD TYPE 00 = DATA, 01 = END
ADD A,CKSUM ;UPDATE THE CHECKSUM
MOV CKSUM,A
.eject
PRMRDLP: ACALL RDHEX ;GET DATA BYTE
MOV @R0,A ;STORE IT IN THE BUFFER
INC R0 ;BUMP THE POINTER
ADD A,CKSUM ;UPDATE THE CHECKSUM
MOV CKSUM,A
DJNZ TEMP1,PRMRDLP ;DECR BYTE COUNTER, LOOP IF NOT FINISHED
ACALL RDHEX ;GET THE CHECKSUM
ADD A,CKSUM ;ADD IT IN
JZ PRMPRG ;IF CKSUM = 0, THEN EVERYTHING'S OK
PRMER1: MOV A,#'?' ;ELSE SEND ERROR CODE
ACALL PUTC
SJMP PRMLIN ;GO BACK TO TRY AGAIN
PRMPRG: MOV TEMP1,CNTLO ;LOAD BYTE COUNT FOR LINE INTO TEMP1
MOV DPH,ADHI ;GET HIGH BYTE OF START ADDRESS
MOV DPL,ADLO ;GET LOW BYTE OF START ADDRESS
MOV A,DPL ;ADD IN THE OFFSET
ADD A,TEMP2
MOV DPL,A
MOV A,DPH
ADDC A,TEMP3
MOV DPH,A
MOV R0,#BUFFER ;POINT TO THE BEGINNING OF THE BUFFER
PRGLP: MOV A,@R0 ;GET THE DATA BYTE
MOV DATA,A ;SAVE IT
MOVX @DPTR,A ;LOAD IT INTO THE PROM
MOV A,#10 ;WAIT 10 MILLISECONDS FOR THE PROM
ACALL DELAY
MOVX A,@DPTR ;READ THE BYTE BACK FROM THE PROM
CJNE A,DATA,PRMER2 ;IF IT DIDN'T PROGRAM RIGHT, GIVE ERROR MESSAGE
SJMP PRGCONT ;ELSE CONTINUE
PRMER2: MOV A,#'!' ;SEND ERROR MESSAGE
ACALL PUTC
AJMP PRMLIN ;GO BACK TO TRY AGAIN
PRGCONT: INC R0 ;POINT TO NEXT BYTE
INC DPTR ;POINT TO NEXT PROM ADDRESS
DJNZ TEMP1,PRGLP ;DECR BYTE COUNTER, LOOP IF NOT FINISHED
MOV A,#'$' ;SEND OK MESSAGE
ACALL PUTC
AJMP PRMLIN ;GO BACK FOR MORE
.eject
PRMDONE: ACALL RDHEX ;READ HIGH ADDRESS
ACALL RDHEX ;READ LOW ADDRESS
ACALL RDHEX ;READ RECORD TYPE
ACALL RDHEX ;READ LAST CHECKSUM
MOV A,#'$' ;SEND OK CODE
ACALL PUTC
PRMEX: ACALL GETC ;READ LAST CR
POP TEMP3 ;RESTORE TEMP1 THRU TEMP3
POP TEMP2
POP TEMP1
POP ADLO ;RESTORE ADLO AND ADHI
POP ADHI
POP DPL ;RESTORE DPTR
POP DPH
POP ACC ;RESTORE R0
MOV R0,A
RET ;DONE, BACK FOR NEXT COMMAND
.eject
FILL: PUSH ADLO ;SAVE ALL USED REGISTERS
PUSH ADHI
PUSH CNTLO
PUSH CNTHI
PUSH DPH
PUSH DPL
PUSH ACC
ACALL RDHEX ;GET HIGH BYTE OF ADDRESS
MOV ADHI,A ;SAVE IT
ACALL RDHEX ;GET LOW BYTE OF ADDRESS
MOV ADLO,A ;SAVE IT
ACALL RDHEX ;GET HIGH BYTE OF COUNT
INC A ;FIX DJNZ WIERDITY
MOV CNTHI,A ;SAVE IT
ACALL RDHEX ;GET LOW BYTE OF COUNT
INC A ;FIX DJNZ WIERDITY
MOV CNTLO,A ;SAVE IT
ACALL RDHEX ;BYTE TO FILL WITH
MOV DPH,ADHI ;HIGH BYTE OF ADDRESS
MOV DPL,ADLO ;LOW BYTE OF ADDRESS
FLP: MOVX @DPTR,A ;STORE THE BYTE
INC DPTR ;POINT TO THE NEXT LOCATION
DJNZ CNTLO,FLP ;LOOP IF NOT DONE
DJNZ CNTHI,FLP ;LOOP IF NOT DONE
POP ACC ;RESTORE ALL USED REGISTERS
POP DPL
POP DPH
POP CNTHI
POP CNTLO
POP ADHI
POP ADLO
RET ;BACK FOR MORE
.eject
MOVE: PUSH ADLO ;SAVE ALL USED REGISTERS
PUSH ADHI
PUSH TEMP1
PUSH TEMP2
PUSH CNTLO
PUSH CNTHI
PUSH DPH
PUSH DPL
PUSH ACC
ACALL RDHEX ;GET HIGH BYTE OF SOURCE ADDRESS
MOV ADHI,A ;SAVE IT
ACALL RDHEX ;GET LOW BYTE OF SOURCE ADDRESS
MOV ADLO,A ;SAVE IT
ACALL RDHEX ;GET HIGH BYTE OF DEST ADDRESS
MOV TEMP2,A ;SAVE IT
ACALL RDHEX ;GET LOW BYTE OF DEST ADDRESS
MOV TEMP1,A ;SAVE IT
ACALL RDHEX ;GET HIGH BYTE OF COUNT
INC A ;FIX DJNZ WIERDITY
MOV CNTHI,A ;SAVE IT
ACALL RDHEX ;GET LOW BYTE OF COUNT
INC A ;FIX DJNZ WIERDITY
MOV CNTLO,A ;SAVE IT
MVLP: MOV DPH,ADHI ;HIGH BYTE OF SOURCE ADDRESS
MOV DPL,ADLO ;LOW BYTE OF SOURCE ADDRESS
MOVX A,@DPTR ;FETCH THE DATA BYTE
INC DPTR ;POINT TO THE NEXT LOCATION
MOV ADHI,DPH ;SAVE THE HIGH BYTE
MOV ADLO,DPL ;SAVE THE LOW BYTE
MOV DPH,TEMP2 ;HIGH BYTE OF DEST ADDRESS
MOV DPL,TEMP1 ;LOW BYTE OF DEST ADDRESS
MOVX @DPTR,A ;STORE THE BYTE
INC DPTR ;POINT TO THE NEXT LOCATION
MOV TEMP2,DPH ;SAVE THE HIGH BYTE
MOV TEMP1,DPL ;SAVE THE LOW BYTE
DJNZ CNTLO,MVLP ;LOOP IF NOT DONE
DJNZ CNTHI,MVLP ;LOOP IF NOT DONE
POP ACC ;RESTORE ALL USED REGISTERS
POP DPL
POP DPH
POP CNTHI
POP CNTLO
POP TEMP2
POP TEMP1
POP ADHI
POP ADLO
RET ;BACK FOR MORE
.eject
RSTBP: MOV A,@R0 ;RESTORE A BRKPT
MOV DPH,A ;R0 POINTS TO BP DATA
INC R0
MOV A,@R0
MOV DPL,A
INC R0
MOV A,@R0 ;RESTORE THE CODE
MOVX @DPTR,A
INC DPTR
INC R0
MOV A,@R0
MOVX @DPTR,A
INC DPTR
INC R0
MOV A,@R0
MOVX @DPTR,A
RET
RSTALL: PUSH DPH ;SAVE THE REGISTERS
PUSH DPL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -