📄 basic-52.asm
字号:
;
CRLF: MOV R5,#CR ;LOAD THE CR
ACALL TEROT ;CALL TERMINAL OUT
MOV R5,#LF ;LOAD THE LF
AJMP TEROT ;OUTPUT IT AND RETURN
;
;PRINT THE MESSAGE ADDRESSED IN ROM OR RAM BY THE DPTR
;ENDS WITH THE CHARACTER IN R4
;DPTR HAS THE ADDRESS OF THE TERMINATOR
;
CRP: ACALL CRLF ;DO A CR THEN PRINT ROM
;
ROM_P: CLR A ;CLEAR A FOR LOOKUP
MOVC A,@A+DPTR ;GET THE CHARACTER
CLR ACC.7 ;CLEAR MS BIT
CJNE A,#'"',$+4 ;EXIT IF TERMINATOR
RET
SETB C0ORX1
;
PN1: MOV R5,A ;OUTPUT THE CHARACTER
ACALL TEROT
INC DPTR ;BUMP THE POINTER
SJMP PN0
;
UPRNT: ACALL X31DP
;
PRNTCR: MOV R4,#CR ;OUTPUT UNTIL A CR
;
PN0: JBC C0ORX1,ROM_P
MOVX A,@DPTR ;GET THE RAM BYTE
JZ $+5
CJNE A,R4B0,$+4 ;SEE IF THE SAME AS TERMINATOR
RET ;EXIT IF THE SAME
CJNE A,#CR,PN1 ;NEVER PRINT A CR IN THIS ROUTINE
LJMP E1XX ;BAD SYNTAX
;
$EJECT
;***************************************************************
;
; INLINE - Input a line to IBUF, exit when a CR is received
;
;***************************************************************
;
INL2: CJNE A,#CNTRLD,INL2B ;SEE IF A CONTROL D
;
INL0: ACALL CRLF ;DO A CR
;
INLINE: MOV P2,#HIGH IBUF ;IBUF IS IN THE ZERO PAGE
MOV R0,#LOW IBUF ;POINT AT THE INPUT BUFFER
;
INL1: ACALL INCHAR ;GET A CHARACTER
MOV R5,A ;SAVE IN R5 FOR OUTPUT
CJNE A,#BS,INL2 ;SEE IF A DELETE CHARACTER
CJNE R0,#LOW IBUF,INL6
MOV R5,#BELL ;OUTPUT A BELL
;
INLX: ACALL TEROT ;OUTPUT CHARACTER
SJMP INL1 ;DO IT AGAIN
;
INL2B: MOVX @R0,A ;SAVE THE CHARACTER
CJNE A,#CR,$+5 ;IS IT A CR
AJMP CRLF ;OUTPUT A CRLF AND EXIT
CJNE A,#20H,$+3
JC INLX ;ONLY ECHO CONTROL CHARACTERS
INC R0 ;BUMP THE POINTER
CJNE R0,#IBUF+79,INLX
DEC R0 ;FORCE 79
SJMP INLX-2 ;OUTPUT A BELL
;
INL6: DEC R0 ;DEC THE RAM POINTER
MOV R5,#BS ;OUTPUT A BACK SPACE
ACALL TEROT
ACALL STEROT ;OUTPUT A SPACE
MOV R5,#BS ;ANOTHER BACK SPACE
SJMP INLX ;OUTPUT IT
;
PTIME: DB 128-2 ; PROM PROGRAMMER TIMER
DB 00H
DB 00H
DB 50H
DB 67H
DB 41H
;
$EJECT
;$INCLUDE(:F2:BAS52.OUT)
;BEGINNING
;***************************************************************
;
; TEROT - Output a character to the system console
; update PHEAD position.
;
;***************************************************************
;
STEROT: MOV R5,#' ' ;OUTPUT A SPACE
;
TEROT: PUSH ACC ;SAVE THE ACCUMULATOR
PUSH DPH ;SAVE THE DPTR
PUSH DPL
JNB CNT_S,$+7 ;WAIT FOR A CONTROL Q
ACALL BCK ;GET SERIAL STATUS
SJMP $-5
MOV A,R5 ;PUT OUTPUT BYTE IN A
JNB BO,$+8 ;CHECK FOR MONITOR
LCALL 2040H ;DO THE MONITOR
AJMP TEROT1 ;CLEAN UP
JNB COUB,$+8 ;SEE IF USER WANTS OUTPUT
LCALL 4030H
AJMP TEROT1
JNB UPB,T_1 ;NO AT IF NO XBIT
JNB LPB,T_1 ;AT PRINT
LCALL 403CH ;CALL AT LOCATION
AJMP TEROT1 ;FINISH OFF OUTPUT
;
T_1: JNB COB,TXX ;SEE IF LIST SET
MOV DPTR,#SPV ;LOAD BAUD RATE
ACALL LD_T
CLR LP ;OUTPUT START BIT
ACALL TIMER_LOAD ;LOAD AND START THE TIMER
MOV A,R5 ;GET THE OUTPUT BYTE
SETB C ;SET CARRY FOR LAST OUTPUT
MOV R5,#9 ;LOAD TIMER COUNTDOWN
;
LTOUT1: RRC A ;ROTATE A
JNB TF1,$ ;WAIT TILL TIMER READY
MOV LP,C ;OUTPUT THE BIT
ACALL TIMER_LOAD ;DO THE NEXT BIT
DJNZ R5,LTOUT1 ;LOOP UNTIL DONE
JNB TF1,$ ;FIRST STOP BIT
ACALL TIMER_LOAD
JNB TF1,$ ;SECOND STOP BIT
MOV R5,A ;RESTORE R5
SJMP TEROT1 ;BACK TO TEROT
;
$EJECT
TXX: JNB TI,$ ;WAIT FOR TRANSMIT READY
CLR TI
MOV SBUF,R5 ;SEND OUT THE CHARACTER
;
TEROT1: CJNE R5,#CR,$+6 ;SEE IF A CR
MOV PHEAD,#00H ;IF A CR, RESET PHEAD AND
;
CJNE R5,#LF,NLC ;SEE IF A LF
MOV A,NULLCT ;GET THE NULL COUNT
JZ NLC ;NO NULLS IF ZERO
;
TEROT2: MOV R5,#NULL ;PUT THE NULL IN THE OUTPUT REGISTER
ACALL TEROT ;OUTPUT THE NULL
DEC A ;DECREMENT NULL COUNT
JNZ TEROT2 ;LOOP UNTIL DONE
;
NLC: CJNE R5,#BS,$+5 ;DEC PHEAD IF A BACKSPACE
DEC PHEAD
CJNE R5,#20H,$+3 ;IS IT A PRINTABLE CHARACTER?
JC $+4 ;DON'T INCREMENT PHEAD IF NOT PRINTABLE
INC PHEAD ;BUMP PRINT HEAD
POP DPL ;RESTORE DPTR
POP DPH
POP ACC ;RESTORE ACC
RET ;EXIT
;
;END
;$INCLUDE(:F2:BAS52.OUT)
;
BCK: ACALL CSTS ;CHECK STATUS
JNC CI_RET+1 ;EXIT IF NO CHARACTER
;
$EJECT
;***************************************************************
;
;INPUTS A CHARACTER FROM THE SYSTEM CONSOLE.
;
;***************************************************************
;
INCHAR: JNB BI,$+8 ;CHECK FOR MONITOR (BUBBLE)
LCALL 2060H
SJMP INCH1
JNB CIUB,$+8 ;CHECK FOR USER
LCALL 4033H
SJMP INCH1
JNB RI,$ ;WAIT FOR RECEIVER READY.
MOV A,SBUF
CLR RI ;RESET READY
CLR ACC.7 ;NO BIT 7
;
INCH1: CJNE A,#13H,$+5
SETB CNT_S
CJNE A,#11H,$+5
CLR CNT_S
CJNE A,#CNTRLC,$+7
JNB NO_C,C_EX ;TRAP NO CONTROL C
RET
;
CLR JKBIT
CJNE A,#17H,CI_RET ;CONTROL W
SETB JKBIT
;
CI_RET: SETB C ;CARRY SET IF A CHARACTER
RET ;EXIT
;
;*************************************************************
;
;RROM - The Statement Action Routine RROM
;
;*************************************************************
;
RROM: SETB INBIT ;SO NO ERRORS
ACALL RO1 ;FIND THE LINE NUMBER
JBC INBIT,CRUN
RET ;EXIT
;
$EJECT
;***************************************************************
;
CSTS: ; RETURNS CARRY = 1 IF THERE IS A CHARACTER WAITING FROM
; THE SYSTEM CONSOLE. IF NO CHARACTER THE READY CHARACTER
; WILL BE CLEARED
;
;***************************************************************
;
JNB BI,$+6 ;BUBBLE STATUS
LJMP 2068H
JNB CIUB,$+6 ;SEE IF EXTERNAL CONSOLE
LJMP 4036H
MOV C,RI
RET
;
MOV DPTR,#WB ;EGO MESSAGE
ACALL ROM_P
;
C_EX: CLR CNT_S ;NO OUTPUT STOP
LCALL SPRINT+4 ;ASSURE CONSOLE
ACALL CRLF
JBC JKBIT,C_EX-5
;
JNB DIRF,SSTOP0
AJMP C_K ;CLEAR COB AND EXIT
;
T_CMP: MOV A,TVH ;COMPARE TIMER TO SP_H AND SP_L
MOV R1,TVL
CJNE A,TVH,T_CMP
XCH A,R1
SUBB A,SP_L
MOV A,R1
SUBB A,SP_H
RET
;
;*************************************************************
;
BR0: ; Trap the timer interrupt
;
;*************************************************************
;
CALL T_CMP ;COMPARE TIMER
JC BCHR+6 ;EXIT IF TEST FAILS
SETB OTI ;DOING THE TIMER INTERRUPT
CLR OTS ;CLEAR TIMER BIT
MOV C,INPROG ;SAVE IN PROGRESS
MOV ISAV,C
MOV DPTR,#TIV
SJMP BR2
;
$EJECT
;***************************************************************
;
; The command action routine - RUN
;
;***************************************************************
;
CRUN: LCALL RCLEAR-2 ;CLEAR THE STORAGE ARRAYS
ACALL SRESTR+2 ;GET THE STARTING ADDRESS
ACALL B_C
JZ CMNDLK ;IF NULL GO TO COMMAND MODE
;
ACALL T_DP
ACALL B_TXA ;BUMP TO STARTING LINE
;
CILOOP: ACALL SP0 ;DO A CR AND A LF
CLR DIRF ;NOT IN DIRECT MODE
;
;INTERPERTER DRIVER
;
ILOOP: MOV SP,SPSAV ;RESTORE THE STACK EACH TIME
JB DIRF,$+9 ;NO INTERRUPTS IF IN DIRECT MODE
MOV INTXAH,TXAH ;SAVE THE TEXT POINTER
MOV INTXAL,TXAL
LCALL BCK ;GET CONSOLE STATUS
JB DIRF,I_L ;DIRECT MODE
ANL C,/GTRD ;SEE IF CHARACTER READY
JNC BCHR ;NO CHARACTER = NO CARRY
;
; DO TRAP OPERATION
;
MOV DPTR,#GTB ;SAVE TRAP CHARACTER
MOVX @DPTR,A
SETB GTRD ;SAYS READ A BYTE
;
BCHR: JB OTI,I_L ;EXIT IF TIMER INTERRUPT IN PROGRESS
JB OTS,BR0 ;TEST TIMER VALUE IF SET
JNB INTPEN,I_L ;SEE IF INTERRUPT PENDING
JB INPROG,I_L ;DON'T DO IT AGAIN IF IN PROGRESS
MOV DPTR,#INTLOC ;POINT AT INTERRUPT LOCATION
;
BR2: MOV R4,#GTYPE ;SETUP FOR A FORCED GOSUB
ACALL SGS1 ;PUT TXA ON STACK
SETB INPROG ;INTERRUPT IN PROGRESS
;
ERL4: CALL L20DPI
AJMP D_L1 ;GET THE LINE NUMBER
;
I_L: ACALL ISTAT ;LOOP
ACALL CLN_UP ;FINISH IT OFF
JNC ILOOP ;LOOP ON THE DRIVER
JNB DIRF,CMNDLK ;CMND1 IF IN RUN MODE
LJMP CMNDR ;DON'T PRINT READY
;
CMNDLK: JMP CMND1 ;DONE
$EJECT
;**************************************************************
;
; The Statement Action Routine - STOP
;
;**************************************************************
;
SSTOP: ACALL CLN_UP ;FINISH OFF THIS LINE
MOV INTXAH,TXAH ;SAVE TEXT POINTER FOR CONT
MOV INTXAL,TXAL
;
SSTOP0: SETB CONB ;CONTINUE WILL WORK
MOV DPTR,#STP ;PRINT THE STOP MESSAGE
SETB STOPBIT ;SET FOR ERROR ROUTINE
JMP ERRS ;JUMP TO ERROR ROUTINE
;
$EJECT
;**************************************************************
;
; ITRAP - Trap special function register operators
;
;**************************************************************
;
ITRAP: CJNE A,#TMR0,$+8 ;TIMER 0
MOV TH0,R3
MOV TL0,R1
RET
;
CJNE A,#TMR1,$+8 ;TIMER 1
MOV TH1,R3
MOV TL1,R1
RET
;
CJNE A,#TMR2,$+8 ;TIMER 2
DB 8BH ;MOV R3 DIRECT OP CODE
DB 0CDH ;T2H LOCATION
DB 89H ;MOV R1 DIRECT OP CODE
DB 0CCH ;T2L LOCATION
RET
;
CJNE A,#TRC2,$+8 ;RCAP2 TOKEN
RCL: CJNE R3,#0FFh,RCL1 ;JKJ: Don't allow to load FF
CJNE R1,#0FFh,RCL1
RET
RCL1: DB 8BH ;MOV R3 DIRECT OP CODE
DB 0CBH ;RCAP2H LOCATION
DB 89H ;MOV R1 DIRECT OP CODE
DB 0CAH ;RCAP2L LOCATION
RET
;
ACALL R3CK ;MAKE SURE THAT R3 IS ZERO
CJNE A,#TT2C,$+6
DB 89H ;MOV R1 DIRECT OP CODE
DB 0C8H ;T2CON LOCATION
RET
;
CJNE A,#T_IE,$+6 ;IE TOKEN
MOV IE,R1
RET
;
CJNE A,#T_IP,$+6 ;IP TOKEN
MOV IP,R1
RET
;
CJNE A,#TTC,$+6 ;TCON TOKEN
MOV TCON,R1
RET
;
CJNE A,#TTM,$+6 ;TMOD TOKEN
MOV TMOD,R1
RET
;
CJNE A,#T_P1,T_T2 ;P1 TOKEN
MOV P1,R1
RET
;
;***************************************************************
;
; T_TRAP - Trap special operators
;
;***************************************************************
;
T_T: MOV TEMP5,A ;SAVE THE TOKEN
ACALL GCI1 ;BUMP POINTER
ACALL SLET2 ;EVALUATE AFTER =
MOV A,TEMP5 ;GET THE TOKEN BACK
CJNE A,#T_XTAL,$+6
LJMP AXTAL1 ;SET UP CRYSTAL
;
ACALL IFIXL ;R3:R1 HAS THE TOS
MOV A,TEMP5 ;GET THE TOKEN AGAIN
CJNE A,#T_MTOP,T_T1 ;SEE IF MTOP TOKEN
MOV DPTR,#MEMTOP
CALL S31DP
JMP RCLEAR ;CLEAR THE MEMORY
;
T_T1: CJNE A,#T_TIME,ITRAP ;SEE IF A TIME TOKEN
MOV C,EA ;SAVE INTERRUPTS
CLR EA ;NO TIMER 0 INTERRUPTS DURING LOAD
MOV TVH,R3 ;SAVE THE TIME
MOV TVL,R1
MOV EA,C ;RESTORE INTERRUPTS
RET ;EXIT
;
T_T2: CJNE A,#T_PC,INTERX ;PCON TOKEN
DB 89H ;MOV DIRECT, R1 OP CODE
DB 87H ;ADDRESS OF PCON
RET ;EXIT
;
T_TRAP: CJNE A,#T_ASC,T_T ;SEE IF ASC TOKEN
ACALL IGC ;EAT IT AND GET THE NEXT CHARACTER
CJNE A,#'$',INTERX ;ERROR IF NOT A STRING
ACALL CSY ;CALCULATE ADDRESS
ACALL X3120
CALL TWO_EY
ACALL SPEOP+4 ;EVALUATE AFTER EQUALS
AJMP ISTAX1 ;SAVE THE CHARACTER
;
$EJECT
;**************************************************************
;
;INTERPERT THE STATEMENT POINTED TO BY TXAL AND TXAH
;
;**************************************************************
;
ISTAT: ACALL GC ;GET THR FIRST CHARACTER
JNB XBIT,IAT ;TRAP TO EXTERNAL RUN PACKAGE
CJNE A,#20H,$+3
JNC IAT
LCALL 2070H ;LET THE USER SET UP THE DPTR
ACALL GCI1
ANL A,#0FH ;STRIP OFF BIAS
SJMP ISTA1
;
IAT: CJNE A,#T_XTAL,$+3
JNC T_TRAP
JNB ACC.7,SLET ;IMPLIED LET IF BIT 7 NOT SET
CJNE A,#T_UOP+12,ISTAX ;DBYTE TOKEN
ACALL SPEOP ;EVALUATE SPECIAL OPERATOR
ACALL R3CK ;CHECK LOCATION
MOV @R1,A ;SAVE IT
RET
;
ISTAX: CJNE A,#T_UOP+13,ISTAY ;XBYTE TOKEN
ACALL SPEOP
;
ISTAX1: MOV P2,R3
MOVX @R1,A
RET
;
ISTAY: CJNE A,#T_CR+1,$+3 ;TRAP NEW OPERATORS
JC I_S
CJNE A,#0B0H,$+3 ;SEE IF TOO BIG
JNC INTERX
ADD A,#0F9H ;BIAS FOR LOOKUP TABLE
SJMP ISTA0 ;DO THE OPERATION
;
I_S: CJNE A,#T_LAST,$+3 ;MAKE SURE AN INITIAL RESERVED WORD
JC $+5 ;ERROR IF NOT
;
INTERX: LJMP E1XX ;SYNTAX ERROR
;
JNB DIRF,ISTA0 ;EXECUTE ALL STATEMENTS IF IN RUN MODE
CJNE A,#T_DIR,$+3 ;SEE IF ON TOKEN
JC ISTA0 ;OK IF DIRECT
CJNE A,#T_GOSB+1,$+5 ;SEE IF FOR
SJMP ISTA0 ;FOR IS OK
CJNE A,#T_REM+1,$+5 ;NEXT IS OK
SJMP ISTA0
CJNE A,#T_STOP+6,INTERX ;SO IS REM
;
$EJECT
ISTA0: ACALL GCI1 ;ADVANCE THE TEXT POINTER
MOV DPTR,#STATD ;POINT DPTR TO LOOKUP TABLE
CJNE A,#T_GOTO-3,$+5 ;SEE IF LET TOKEN
SJMP ISTAT ;WASTE LET TOKEN
ANL A,#3FH ;STRIP OFF THE GARBAGE
;
ISTA1: RL A ;ROTATE FOR OFFSET
ADD A,DPL ;BUMP
MOV DPL,A ;SAVE IT
CLR A
MOVC A,@A+DPTR ;GET HIGH BYTE
PUSH ACC ;SAVE IT
INC DPTR
CLR A
MOVC A,@A+DPTR ;GET LOW BYTE
POP DPH
MOV DPL,A
;
AC1: CLR A
JMP @A+DPTR ;GO DO IT
;
$EJECT
;***************************************************************
;
; The statement action routine - LET
;
;***************************************************************
;
SLET: ACALL S_C ;CHECK FOR POSSIBLE STRING
JC SLET0 ;NO STRING
CLR LINEB ;USED STRINGS
;
CALL X31DP ;PUT ADDRESS IN DPTR
MOV R7,#T_EQU ;WASTE =
ACALL EATC
ACALL GC ;GET THE NEXT CHARACTER
CJNE A,#'"',S_3 ;CHECK FOR A "
MOV R7,S_LEN ;GET THE STRING LENGTH
;
S_0: ACALL GCI1 ;BUMP PAST "
ACALL DELTST ;CHECK FOR DELIMITER
JZ INTERX ;EXIT IF CARRIAGE RETURN
MOVX @DPTR,A ;SAVE THE CHARACTER
CJNE A,#'"',S_1 ;SEE IF DONE
;
S_E: MOV A,#CR ;PUT A CR IN A
MOVX @DPTR,A ;SAVE CR
AJMP GCI1
;
S_3: PUSH DPH
PUSH DPL ;SAVE DESTINATION
ACALL S_C ;CALCULATE SOURCE
JC INTERX ;ERROR IF CARRY
POP R0B0 ;GET DESTINATION BACK
POP R2B0
;
SSOOP: MOV R7,S_LEN ;SET UP COUNTER
;
S_4: CALL TBYTE ;TRANSFER THE BYTE
CJNE A,#CR,$+4 ;EXIT IF A CR
RET
DJNZ R7,S_5 ;BUMP COUNTER
MOV A,#CR ;SAVE A CR
MOVX @R0,A
AJMP EIGP ;PRINT EXTRA IGNORED
;
$EJECT
;
S_5: CALL INC3210 ;BUMP POINTERS
SJMP S_4 ;LOOP
;
S_1: DJNZ R7,$+8 ;SEE IF DONE
ACALL S_E
ACALL EIGP ;PRINT EXTRA IGNORED
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -