📄 basic-52.asm
字号:
AJMP FINDCR ;GO FIND THE END
INC DPTR ;BUMP THE STORE POINTER
SJMP S_0 ;CONTINUE TO LOOP
;
E3XX: MOV DPTR,#E3X ;BAD ARG ERROR
AJMP EK
;
SLET0: ACALL SLET1
AJMP POPAS ;COPY EXPRESSION TO VARIABLE
;
SLET1: ACALL VAR_ER ;CHECK FOR A"VARIABLE"
;
SLET2: PUSH R2B0 ;SAVE THE VARIABLE ADDRESS
PUSH R0B0
MOV R7,#T_EQU ;GET EQUAL TOKEN
ACALL WE
POP R1B0 ;POP VARIABLE TO R3:R1
POP R3B0
RET ;EXIT
;
R3CK: CJNE R3,#00H,E3XX ;CHECK TO SEE IF R3 IS ZERO
RET
;
SPEOP: ACALL GCI1 ;BUMP TXA
ACALL P_E ;EVALUATE PAREN
ACALL SLET2 ;EVALUATE AFTER =
CALL TWOL ;R7:R6 GETS VALUE, R3:R1 GETS LOCATION
MOV A,R6 ;SAVE THE VALUE
;
CJNE R7,#00H,E3XX ;R2 MUST BE = 0
RET
;
$EJECT
;**************************************************************
;
; ST_CAL - Calculate string Address
;
;**************************************************************
;
IST_CAL:;
;
ACALL I_PI ;BUMP TEXT, THEN EVALUATE
ACALL R3CK ;ERROR IF R3 <> 0
INC R1 ;BUMP FOR OFFSET
MOV A,R1 ;ERROR IF R1 = 255
JZ E3XX
MOV DPTR,#VARTOP ;GET TOP OF VARIABLE STORAGE
MOV B,S_LEN ;MULTIPLY FOR LOCATION
ACALL VARD ;CALCULATE THE LOCATION
MOV DPTR,#MEMTOP ;SEE IF BLEW IT
CALL FUL1
MOV DPL,S_LEN ;GET STRING LENGTH, DPH = 00H
DEC DPH ;DPH = 0
;
DUBSUB: CLR C
MOV A,R1
SUBB A,DPL
MOV R1,A
MOV A,R3
SUBB A,DPH
MOV R3,A
ORL A,R1
RET
;
;***************************************************************
;
;VARD - Calculate the offset base
;
;***************************************************************
;
VARB: MOV B,#FPSIZ ;SET UP FOR OPERATION
;
VARD: CALL LDPTRI ;LOAD DPTR
MOV A,R1 ;MULTIPLY BASE
MUL AB
ADD A,DPL
MOV R1,A
MOV A,B
ADDC A,DPH
MOV R3,A
RET
;
$EJECT
;*************************************************************
;
CSY: ; Calculate a biased string address and put in R3:R1
;
;*************************************************************
;
ACALL IST_CAL ;CALCULATE IT
PUSH R3B0 ;SAVE IT
PUSH R1B0
MOV R7,#',' ;WASTE THE COMMA
ACALL EATC
ACALL ONE ;GET THE NEXT EXPRESSION
MOV A,R1 ;CHECK FOR BOUNDS
CJNE A,S_LEN,$+3
JNC E3XX ;MUST HAVE A CARRY
DEC R1 ;BIAS THE POINTER
POP ACC ;GET VALUE LOW
ADD A,R1 ;ADD IT TO BASE
MOV R1,A ;SAVE IT
POP R3B0 ;GET HIGH ADDRESS
JNC $+3 ;PROPAGATE THE CARRY
INC R3
AJMP ERPAR ;WASTE THE RIGHT PAREN
;
$EJECT
;***************************************************************
;
; The statement action routine FOR
;
;***************************************************************
;
SFOR: ACALL SLET1 ;SET UP CONTROL VARIABLE
PUSH R3B0 ;SAVE THE CONTROL VARIABLE LOCATION
PUSH R1B0
ACALL POPAS ;POP ARG STACK AND COPY CONTROL VAR
MOV R7,#T_TO ;GET TO TOKEN
ACALL WE
ACALL GC ;GET NEXT CHARACTER
CJNE A,#T_STEP,SF2
ACALL GCI1 ;EAT THE TOKEN
ACALL EXPRB ;EVALUATE EXPRESSION
SJMP $+5 ;JUMP OVER
;
SF2: LCALL PUSH_ONE ;PUT ONE ON THE STACK
;
MOV A,#-FSIZE ;ALLOCATE FSIZE BYTES ON THE CONTROL STACK
ACALL PUSHCS ;GET CS IN R0
ACALL CSC ;CHECK CONTROL STACK
MOV R3,#CSTKAH ;IN CONTROL STACK
MOV R1,R0B0 ;STACK ADDRESS
ACALL POPAS ;PUT STEP ON STACK
ACALL POPAS ;PUT LIMIT ON STACK
ACALL DP_T ;DPTR GETS TEXT
MOV R0,R1B0 ;GET THE POINTER
ACALL T_X_S ;SAVE THE TEXT
POP TXAL ;GET CONTROL VARIABLE
POP TXAH
MOV R4,#FTYPE ;AND THE TYPE
ACALL T_X_S ;SAVE IT
;
SF3: ACALL T_DP ;GET THE TEXT POINTER
AJMP ILOOP ;CONTINUE TO PROCESS
;
$EJECT
;**************************************************************
;
; The statement action routines - PUSH and POP
;
;**************************************************************
;
SPUSH: ACALL EXPRB ;PUT EXPRESSION ON STACK
ACALL C_TST ;SEE IF MORE TO DO
JNC SPUSH ;IF A COMMA PUSH ANOTHER
RET
;
;
SPOP: ACALL VAR_ER ;GET VARIABLE
ACALL XPOP ;FLIP THE REGISTERS FOR POPAS
ACALL C_TST ;SEE IF MORE TO DO
JNC SPOP
;
RET
;
;***************************************************************
;
; The statement action routine - IF
;
;***************************************************************
;
SIF: ACALL RTST ;EVALUATE THE EXPRESSION
MOV R1,A ;SAVE THE RESULT
ACALL GC ;GET THE CHARACTER AFTER EXPR
CJNE A,#T_THEN,$+5 ;SEE IF THEN TOKEN
ACALL GCI1 ;WASTE THEN TOKEN
CJNE R1,#0,T_F1 ;CHECK R_OP RESULT
;
E_FIND: MOV R7,#T_ELSE ;FIND ELSE TOKEN
ACALL FINDC
JZ SIF-1 ;EXIT IF A CR
ACALL GCI1 ;BUMP PAST TOKEN
CJNE A,#T_ELSE,E_FIND;WASTE IF NO ELSE
;
T_F1: ACALL INTGER ;SEE IF NUMBER
JNC D_L1 ;EXECUTE LINE NUMBER
AJMP ISTAT ;EXECUTE STATEMENT IN NOT
;
B_C: MOVX A,@DPTR
DEC A
JB ACC.7,FL3-5
RET
;
$EJECT
;***************************************************************
;
; The statement action routine - GOTO
;
;***************************************************************
;
SGOTO: ACALL RLINE ;R2:R0 AND DPTR GET INTGER
;
SGT1: ACALL T_DP ;TEXT POINTER GETS DPTR
;
JBC RETBIT,SGT2 ;SEE IF RETI EXECUTED
;
JNB LINEB,$+6 ;SEE IF A LINE WAS EDITED
LCALL RCLEAR-2 ;CLEAR THE MEMORY IF SET
AJMP ILOOP-2 ;CLEAR DIRF AND LOOP
;
SGT2: JBC OTI,$+8 ;SEE IF TIMER INTERRUPT
ANL 34,#10111101B ;CLEAR INTERRUPTS
AJMP ILOOP ;EXECUTE
MOV C,ISAV
MOV INPROG,C
AJMP ILOOP ;RESTORE INTERRUPTS AND RET
;
;
;*************************************************************
;
RTST: ; Test for ZERO
;
;*************************************************************
;
ACALL EXPRB ;EVALUATE EXPRESSION
CALL INC_ASTKA ;BUMP ARG STACK
JZ $+4 ;EXIT WITH ZERO OR 0FFH
MOV A,#0FFH
RET
;
$EJECT
;
;**************************************************************
;
; GLN - get the line number in R2:R0, return in DPTR
;
;**************************************************************
;
GLN: ACALL DP_B ;GET THE BEGINNING ADDRESS
;
FL1: MOVX A,@DPTR ;GET THE LENGTH
MOV R7,A ;SAVE THE LENGTH
DJNZ R7,FL3 ;SEE IF END OF FILE
;
MOV DPTR,#E10X ;NO LINE NUMBER
AJMP EK ;HANDLE THE ERROR
;
FL3: JB ACC.7,$-5 ;CHECK FOR BIT 7
INC DPTR ;POINT AT HIGH BYTE
MOVX A,@DPTR ;GET HIGH BYTE
CJNE A,R2B0,FL2 ;SEE IF MATCH
INC DPTR ;BUMP TO LOW BYTE
DEC R7 ;ADJUST AGAIN
MOVX A,@DPTR ;GET THE LOW BYTE
CJNE A,R0B0,FL2 ;SEE IF LOW BYTE MATCH
INC DPTR ;POINT AT FIRST CHARACTER
RET ;FOUND IT
;
FL2: MOV A,R7 ;GET THE LENGTH COUNTER
CALL ADDPTR ;ADD A TO DATA POINTER
SJMP FL1 ;LOOP
;
;
;*************************************************************
;
;RLINE - Read in ASCII string, get line, and clean it up
;
;*************************************************************
;
RLINE: ACALL INTERR ;GET THE INTEGER
;
RL1: ACALL GLN
AJMP CLN_UP
;
;
D_L1: ACALL GLN ;GET THE LINE
AJMP SGT1 ;EXECUTE THE LINE
;
$EJECT
;***************************************************************
;
; The statement action routines WHILE and UNTIL
;
;***************************************************************
;
SWHILE: ACALL RTST ;EVALUATE RELATIONAL EXPRESSION
CPL A
SJMP S_WU
;
SUNTIL: ACALL RTST ;EVALUATE RELATIONAL EXPRESSION
;
S_WU: MOV R4,#DTYPE ;DO EXPECTED
MOV R5,A ;SAVE R_OP RESULT
SJMP SR0 ;GO PROCESS
;
;
;***************************************************************
;
CNULL: ; The Command Action Routine - NULL
;
;***************************************************************
;
ACALL INTERR ;GET AN INTEGER FOLLOWING NULL
MOV NULLCT,R0 ;SAVE THE NULLCOUNT
AJMP CMNDLK ;JUMP TO COMMAND MODE
;
$EJECT
;***************************************************************
;
; The statement action routine - RETI
;
;***************************************************************
;
SRETI: SETB RETBIT ;SAYS THAT RETI HAS BEEN EXECUTED
;
;***************************************************************
;
; The statement action routine - RETURN
;
;***************************************************************
;
SRETRN: MOV R4,#GTYPE ;MAKE SURE OF GOSUB
MOV R5,#55H ;TYPE RETURN TYPE
;
SR0: ACALL CSETUP ;SET UP CONTROL STACK
MOVX A,@R0 ;GET RETURN TEXT ADDRESS
MOV DPH,A
INC R0
MOVX A,@R0
MOV DPL,A
INC R0 ;POP CONTROL STACK
MOVX A,@DPTR ;SEE IF GOSUB WAS THE LAST STATEMENT
CJNE A,#EOF,$+5
AJMP CMNDLK
MOV A,R5 ;GET TYPE
JZ SGT1 ;EXIT IF ZERO
MOV CSTKA,R0 ;POP THE STACK
CPL A ;OPTION TEST, 00H, 55H, 0FFH, NOW 55H
JNZ SGT1 ;MUST BE GOSUB
RET ;NORMAL FALL THRU EXIT FOR NO MATCH
;
$EJECT
;***************************************************************
;
; The statement action routine - GOSUB
;
;***************************************************************
;
SGOSUB: ACALL RLINE ;NEW TXA IN DPTR
;
SGS0: MOV R4,#GTYPE
ACALL SGS1 ;SET EVERYTHING UP
AJMP SF3 ;EXIT
;
SGS1: MOV A,#-3 ;ALLOCATE 3 BYTES ON CONTROL STACK
ACALL PUSHCS
;
T_X_S: MOV P2,#CSTKAH ;SET UP PORT FOR CONTROL STACK
MOV A,TXAL ;GET RETURN ADDRESS AND SAVE IT
MOVX @R0,A
DEC R0
MOV A,TXAH
MOVX @R0,A
DEC R0
MOV A,R4 ;GET TYPE
MOVX @R0,A ;SAVE TYPE
RET ;EXIT
;
;
CS1: MOV A,#3 ;POP 3 BYTES
ACALL PUSHCS
;
CSETUP: MOV R0,CSTKA ;GET CONTROL STACK
MOV P2,#CSTKAH
MOVX A,@R0 ;GET BYTE
CJNE A,R4B0,$+5 ;SEE IF TYPE MATCH
INC R0
RET
JZ E4XX ;EXIT IF STACK UNDERFLOW
CJNE A,#FTYPE,CS1 ;SEE IF FOR TYPE
ACALL PUSHCS-2 ;WASTE THE FOR TYPE
SJMP CSETUP ;LOOP
;
$EJECT
;***************************************************************
;
; The statement action routine - NEXT
;
;***************************************************************
;
SNEXT: MOV R4,#FTYPE ;FOR TYPE
ACALL CSETUP ;SETUP CONTROL STACK
MOV TEMP5,R0 ;SAVE CONTROL VARIABLE ADDRESS
MOV R1,#TEMP1 ;SAVE VAR + RETURN IN TEMP1-4
;
XXI: MOVX A,@R0 ;LOOP UNTIL DONE
MOV @R1,A
INC R1
INC R0
CJNE R1,#TEMP5,XXI
;
ACALL VAR ;SEE IF THE USER HAS A VARIABLE
JNC $+6
MOV R2,TEMP1
MOV R0,TEMP2
MOV A,R2 ;SEE IF VAR'S AGREE
CJNE A,TEMP1,E4XX
MOV A,R0
CJNE A,TEMP2,E4XX
ACALL PUSHAS ;PUT CONTROL VARIABLE ON STACK
MOV A,#FPSIZ+FPSIZ+2;COMPUTE ADDRESS TO STEP VALUE SIGN
ADD A,TEMP5 ;ADD IT TO BASE OF STACK
MOV R0,A ;SAVE IN R0
MOV R2,#CSTKAH ;SET UP TO PUSH STEP VALUE
MOV P2,R2 ;SET UP PORT
MOVX A,@R0 ;GET SIGN
INC R0 ;BACK TO EXPONENT
PUSH ACC ;SAVE SIGN OF STEP
ACALL PUSHAS ;PUT STEP VALUE ON STACK
PUSH R0B0 ;SAVE LIMIT VALUE LOCATION
CALL AADD ;ADD STEP VALUE TO VARIABLE
CALL CSTAKA ;COPY STACK
MOV R3,TEMP1 ;GET CONTROL VARIABLE
MOV R1,TEMP2
ACALL POPAS ;SAVE THE RESULT
MOV R2,#CSTKAH ;RESTORE LIMIT LOCATION
POP R0B0
ACALL PUSHAS ;PUT LIMIT ON STACK
CALL FP_BASE+4 ;DO THE COMPARE
POP ACC ;GET LIMIT SIGN BACK
JZ $+3 ;IF SIGN NEGATIVE, TEST "BACKWARDS"
CPL C
ORL C,F0 ;SEE IF EQUAL
JC N4 ;STILL SMALLER THAN LIMIT?
MOV A,#FSIZE ;REMOVE CONTROL STACK ENTRY
;
; Fall thru to PUSHCS
;
$EJECT
;***************************************************************
;
; PUSHCS - push frame onto control stack
; acc has - number of bytes, also test for overflow
;
;***************************************************************
;
PUSHCS: ADD A,CSTKA ;BUMP CONTROL STACK
CJNE A,#CONVT+17,$+3 ;SEE IF OVERFLOWED
JC E4XX ;EXIT IF STACK OVERFLOW
XCH A,CSTKA ;STORE NEW CONTROL STACK VALUE, GET OLD
DEC A ;BUMP OLD VALUE
MOV R0,A ;PUT OLD-1 IN R0
;
RET ;EXIT
;
CSC: ACALL CLN_UP ;FINISH OFF THE LINE
JNC CSC-1 ;EXIT IF NO TERMINATOR
;
E4XX: MOV DPTR,#EXC ;CONTROL STACK ERROR
AJMP EK ;STACK ERROR
;
N4: MOV TXAH,TEMP3 ;GET TEXT POINTER
MOV TXAL,TEMP4
AJMP ILOOP ;EXIT
;
;***************************************************************
;
; The statement action routine - RESTORE
;
;***************************************************************
;
SRESTR: ACALL X_TR ;SWAP POINTERS
ACALL DP_B ;GET THE STARTING ADDRESS
ACALL T_DP ;PUT STARTING ADDRESS IN TEXT POINTER
ACALL B_TXA ;BUMP TXA
;
; Fall thru
;
X_TR: ;swap txa and rtxa
;
XCH A,TXAH
XCH A,RTXAH
XCH A,TXAH
XCH A,TXAL
XCH A,RTXAL
XCH A,TXAL
RET ;EXIT
;
$EJECT
;***************************************************************
;
; The statement action routine - READ
;
;***************************************************************
;
SREAD: ACALL X_TR ;SWAP POINTERS
;
SRD0: ACALL C_TST ;CHECK FOR COMMA
JC SRD4 ;SEE WHAT IT IS
;
SRD: ACALL EXPRB ;EVALUATE THE EXPRESSION
ACALL GC ;GET THE CHARACTER AFTER EXPRESSION
CJNE A,#',',SRD1 ;SEE IF MORE DATA
SJMP SRD2 ;BYBASS CLEAN UP IF A COMMA
;
SRD1: ACALL CLN_UP ;FINISH OFF THE LINE, IF AT END
;
SRD2: ACALL X_TR ;RESTORE POINTERS
ACALL VAR_ER ;GET VARIABLE ADDRESS
ACALL XPOP ;FLIP THE REGISTERS FOR POPAS
ACALL C_TST ;SEE IF A COMMA
JNC SREAD ;READ AGAIN IF A COMMA
RET ;EXIT IF NOT
;
SRD4: CJNE A,#T_DATA,SRD5 ;SEE IF DATA
ACALL GCI1 ;BUMP POINTER
SJMP SRD
;
SRD5: CJNE A,#EOF,SRD6 ;SEE IF YOU BLEW IT
ACALL X_TR ;GET THE TEXT POINTER BACK
MOV DPTR,#E14X ;READ ERROR
;
EK: LJMP ERROR
;
SRD6: ACALL FINDCR ;WASTE THIS LINE
ACALL CLN_UP ;CLEAN IT UP
JC SRD5+3 ;ERROR IF AT END
SJMP SRD0
;
NUMC: ACALL GC ;GET A CHARACTER
CJNE A,#'#',NUMC1 ;SEE IF A #
SETB COB ;VALID LINE PRINT
AJMP IGC ;BUMP THE TEXT POINTER
;
NUMC1: CJNE A,#'@',SRD4-1 ;EXIT IF NO GOOD
SETB LPB
AJMP IGC
;
$EJECT
;***************************************************************
;
; The statement action routine - PRINT
;
;***************************************************************
;
SPH0: SETB ZSURP ;NO ZEROS
;
SPH1: SETB HMODE ;HEX MODE
;
SPRINT: ACALL NUMC ;TEST FOR A LINE PRINT
ACALL $+9 ;PROCEED
ANL 35,#11110101B ;CLEAR COB AND LPB
ANL 38,#00111111B ;NO HEX MODE
;
RET
;
ACALL DELTST ;CHECK FOR A DELIMITER
JC SP1
;
SP0: JMP CRLF ;EXIT WITH A CR IF SO
;
SP2: ACALL C_TST ;CHECK FOR A COMMA
JC SP0 ;EXIT IF NO
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -