; December 18, 1986
; MS-DOS compatible Source code for MCS BASIC-52 (tm)
; Assembles with ASM51 Macro Assembler Version 2.2
;
; The following source code does not include the floating point math
; routines. These are seperately compiled using FP52.SRC.
;
; Both the BASIC.SRC and FP52.SRC programs assemble into ABSOLUTE
; object files, and do not need to be relocated or linked. The FP52
; object code and the BASIC object code, when compiled without modification
; of the source listings, create the same object code that is found on
; the MCS BASIC-52 Version 1.1 microcontrollers.
;
; The original source code had 7 "include" files that have been incorporated
; into this file for ease of assembly.
; These 7 files are: LOOK52.SRC, BAS52.RST, BAS52.PGM, BAS52.TL, BAS52.OUT,
; BAS52.PWM, and BAS52.CLK.
;
;
; Intel Corporation, Embedded Controller Operations
cpu 8052
page 0
newpage
include stddef51.inc
include bitfuncs.inc
bigendian on
segment code
;**************************************************************
;
; TRAP VECTORS TO MONITOR
;
; RESET TAG (0AAH) ---------2001H
;
; TAG LOCATION (5AH) ------ 2002H
;
; EXTERNAL INTERRUPT 0 ---- 2040H
;
; COMMAND MODE ENTRY ------ 2048H
;
; SERIAL PORT ------------- 2050H
;
; MONITOR (BUBBLE) OUTPUT - 2058H
;
; MONITOR (BUBBLE) INPUT -- 2060H
;
; MONITOR (BUBBLE) CSTS --- 2068H
;
; GET USER JUMP VECTOR ---- 2070H
;
; GET USER LOOKUP VECTOR -- 2078H
;
; PRINT AT VECTOR --------- 2080H
;
; INTERRUPT PWM ----------- 2088H
;
; EXTERNAL RESET ---------- 2090H
;
; USER OUTPUT-------------- 4030H
;
; USER INPUT -------------- 4033H
;
; USER CSTS --------------- 4036H
;
; USER RESET -------------- 4039H
;
; USER DEFINED PRINT @ --- 403CH
;
;***************************************************************
;
newpage
;***************************************************************
;
; MCS - 51 - 8K BASIC VERSION 1.1
;
;***************************************************************
;
AJMP CRST ;START THE PROGRAM
db 037h ; ******AA inserted
;
ORG 3H
;
;***************************************************************
;
;EXTERNAL INTERRUPT 0
;
;***************************************************************
;
JB DRQ,STQ ;SEE IF DMA IS SET
PUSH PSW ;SAVE THE STATUS
LJMP 4003H ;JUMP TO USER IF NOT SET
;
ORG 0BH
;
;***************************************************************
;
;TIMER 0 OVERFLOW INTERRUPT
;
;***************************************************************
;
PUSH PSW ;SAVE THE STATUS
JB C_BIT,STJ ;SEE IF USER WANTS INTERRUPT
LJMP 400BH ;EXIT IF USER WANTS INTERRUPTS
;
ORG 13H
;
;***************************************************************
;
;EXTERNAL INTERRUPT 1
;
;***************************************************************
;
JB INTBIT,STK
PUSH PSW
LJMP 4013H
;
newpage
;
ORG 1BH
;
;***************************************************************
;
;TIMER 1 OVERFLOW INTERRUPT
;
;***************************************************************
;
PUSH PSW
LJMP CKS_I
;
STJ: LJMP I_DR ;DO THE INTERRUPT
;
;***************************************************************
;
;SERIAL PORT INTERRUPT
;
;***************************************************************
;
ORG 23H
;
PUSH PSW
JB SPINT,STU ;SEE IF MONITOR EANTS INTERRUPT
LJMP 4023H
;
ORG 2BH
;
;**************************************************************
;
;TIMER 2 OVERFLOW INTERRUPT
;
;**************************************************************
;
PUSH PSW
LJMP 402BH
;
newpage
;**************************************************************
;
;USER ENTRY
;
;**************************************************************
;
ORG 30H
;
LJMP IBLK ;LINK TO USER BLOCK
;
STQ: JB I_T0,STS ;SEE IF MONITOR WANTS IT
CLR DACK
JNB P3.2,$ ;WAIT FOR DMA TO END
SETB DACK
RETI
;
STS: LJMP 2040H ;GO TO THE MONITOR
;
STK: SETB INTPEN ;TELL BASIC AN INTERRUPT WAS RECEIVED
RETI
;
STU: LJMP 2050H ;SERIAL PORT INTERRUPT
;
newpage
include look52.inc ; ******AA
EIG: DB "EXTRA IGNORED",'"'
;
EXA: DB "A-STACK",'"'
;
EXC: DB "C-STACK",'"'
;
newpage
include bas52.rst ; ******AA
newpage
;***************************************************************
;
; CIPROG AND CPROG - Program a prom
;
;***************************************************************
;
include bas52.pgm ; ******AA
newpage
;**************************************************************
;
PGU: ;PROGRAM A PROM FOR THE USER
;
;**************************************************************
;
CLR PROMV ;TURN ON THE VOLTAGE
MOV PSW,#00011000B ;SELECT RB3
ACALL PG1 ;DO IT
SETB PROMV ;TURN IT OFF
RET
;
;
;*************************************************************
;
CCAL: ; Set up for prom moves
; R3:R1 gets source
; R7:R6 gets # of bytes
;
;*************************************************************
;
ACALL GETEND ;GET THE LAST LOCATION
INC DPTR ;BUMP TO LOAD EOF
MOV R3,BOFAH
MOV R1,BOFAL ;RESTORE START
CLR C ;PREPARE FOR SUBB
MOV A,DPL ;SUB DPTR - BOFA > R7:R6
SUBB A,R1
MOV R6,A
MOV A,DPH
SUBB A,R3
MOV R7,A
RET
;
;
include bas52.tl ; ******AA
newpage
;***************************************************************
;
CROM: ; The command action routine - ROM - Run out of rom
;
;***************************************************************
;
CLR CONB ;CAN'T CONTINUE IF MODE CHANGE
ACALL RO1 ;DO IT
;
C_K: LJMP CL3 ;EXIT
;
RO1: LCALL DELTST ;SEE IF INTGER PRESENT ******AA CALL-->LCALL, INTGER-->DELTST
MOV R4,#R1B0 ;SAVE THE NUMBER ******AA ABS-->IMM, R0B0-->R0B1 ?!?
JNC $+6 ; ******AA $+4-->$+6 ???
;MOV R4,#01H ;ONE IF NO INTEGER PRESENT ******AA repl. by next two
LCALL ONE ; ******AA
MOV R4,A ; ******AA
ACALL ROMFD ;FIND THE PROGRAM
CJNE R4,#0,RFX ;EXIT IF R4 <> 0
INC DPTR ;BUMP PAST TAG
MOV BOFAH,DPH ;SAVE THE ADDRESS
MOV BOFAL,DPL
RET
;
ROMFD: MOV DPTR,#ROMADR+16 ;START OF USER PROGRAM
;
RF1: MOVX A,@DPTR ;GET THE BYTE
CJNE A,#55H,RF3 ;SEE IF PROPER TAG
DJNZ R4,RF2 ;BUMP COUNTER
;
RFX: RET ;DPTR HAS THE START ADDRESS
;
RF2: INC DPTR ;BUMP PAST TAG
ACALL G5
INC DPTR ;BUMP TO NEXT PROGRAM
SJMP RF1 ;DO IT AGAIN
;
RF3: JBC INBIT,RFX ;EXIT IF SET
;
NOGO: MOV DPTR,#NOROM
AJMP ERRLK
;
newpage
;***************************************************************
;
L20DPI: ; load R2:R0 with the location the DPTR is pointing to
;
;***************************************************************
;
MOVX A,@DPTR
MOV R2,A
INC DPTR
MOVX A,@DPTR
MOV R0,A
RET ;DON'T BUMP DPTR
;
;***************************************************************
;
X31DP: ; swap R3:R1 with DPTR
;
;***************************************************************
;
XCH A,R3
XCH A,DPH
XCH A,R3
XCH A,R1
XCH A,DPL
XCH A,R1
RET
;
;***************************************************************
;
LD_T: ; Load the timer save location with the value the DPTR is
; pointing to.
;
;****************************************************************
;
MOVX A,@DPTR
MOV T_HH,A
INC DPTR
MOVX A,@DPTR
MOV T_LL,A
RET
;
newpage
;
;***************************************************************
;
;GETLIN - FIND THE LOCATION OF THE LINE NUMBER IN R3:R1
; IF ACC = 0 THE LINE WAS NOT FOUND I.E. R3:R1
; WAS TOO BIG, ELSE ACC <> 0 AND THE DPTR POINTS
; AT THE LINE THAT IS GREATER THAN OR EQUAL TO THE
; VALUE IN R3:R1.
;
;***************************************************************
;
GETEND: SETB ENDBIT ;GET THE END OF THE PROGRAM
;
GETLIN: LCALL DP_B ;GET BEGINNING ADDRESS ******AA CALL-->LCALL
;
G1: LCALL B_C ; ******AA CALL-->LCALL
JZ G3 ;EXIT WITH A ZERO IN A IF AT END
INC DPTR ;POINT AT THE LINE NUMBER
JB ENDBIT,G2 ;SEE IF WE WANT TO FIND THE END
ACALL DCMPX ;SEE IF (DPTR) = R3:R1
ACALL DECDP ;POINT AT LINE COUNT
MOVX A,@DPTR ;PUT LINE LENGTH INTO ACC
JB UBIT,G3 ;EXIT IF EQUAL
JC G3 ;SEE IF LESS THAN OR ZERO
;
G2: ACALL ADDPTR ;ADD IT TO DPTR
SJMP G1 ;LOOP
;
G3: CLR ENDBIT ;RESET ENDBIT
RET ;EXIT
;
G4: MOV DPTR,#PSTART ;DO RAM
;
G5: SETB ENDBIT
SJMP G1 ;NOW DO TEST
;
newpage
;***************************************************************
;
; LDPTRI - Load the DATA POINTER with the value it is pointing
; to - DPH = (DPTR) , DPL = (DPTR+1)
;
; acc gets wasted
;
;***************************************************************
;
LDPTRI: MOVX A,@DPTR ;GET THE HIGH BYTE
PUSH ACC ;SAVE IT
INC DPTR ;BUMP THE POINTER
MOVX A,@DPTR ;GET THE LOW BYTE
MOV DPL,A ;PUT IT IN DPL
POP DPH ;GET THE HIGH BYTE
RET ;GO BACK
;
;***************************************************************
;
;L31DPI - LOAD R3 WITH (DPTR) AND R1 WITH (DPTR+1)
;
;ACC GETS CLOBBERED
;
;***************************************************************
;
L31DPI: MOVX A,@DPTR ;GET THE HIGH BYTE
MOV R3,A ;PUT IT IN THE REG
INC DPTR ;BUMP THE POINTER
MOVX A,@DPTR ;GET THE NEXT BYTE
MOV R1,A ;SAVE IT
RET
;
;***************************************************************
;
;DECDP - DECREMENT THE DATA POINTER - USED TO SAVE SPACE
;
;***************************************************************
;
DECDP2: ACALL DECDP
;
DECDP: XCH A,DPL ;GET DPL
JNZ $+4 ;BUMP IF ZERO
DEC DPH
DEC A ;DECREMENT IT
XCH A,DPL ;GET A BACK
RET ;EXIT
;
newpage
;***************************************************************
;
;DCMPX - DOUBLE COMPARE - COMPARE (DPTR) TO R3:R1
;R3:R1 - (DPTR) = SET CARRY FLAG
;
;IF R3:R1 > (DPTR) THEN C = 0
;IF R3:R1 < (DPTR) THEN C = 1
;IF R3:R1 = (DPTR) THEN C = 0
;
;***************************************************************
;
DCMPX: CLR UBIT ;ASSUME NOT EQUAL
MOVX A,@DPTR ;GET THE BYTE
CJNE A,R3B0,D1 ;IF A IS GREATER THAN R3 THEN NO CARRY
;WHICH IS R3<@DPTR = NO CARRY AND
;R3>@DPTR CARRY IS SET
INC DPTR ;BUMP THE DATA POINTER
MOVX A,@DPTR ;GET THE BYTE
ACALL DECDP ;PUT DPTR BACK
CJNE A,R1B0,D1 ;DO THE COMPARE
CPL C ;FLIP CARRY
;
CPL UBIT ;SET IT
D1: CPL C ;GET THE CARRY RIGHT
RET ;EXIT
;
;***************************************************************
;
; ADDPTR - Add acc to the dptr
;
; acc gets wasted
;
;***************************************************************
;
ADDPTR: ADD A,DPL ;ADD THE ACC TO DPL
MOV DPL,A ;PUT IT IN DPL
JNC $+4 ;JUMP IF NO CARRY
INC DPH ;BUMP DPH
RET ;EXIT
;
newpage
;*************************************************************
;
LCLR: ; Set up the storage allocation
;
;*************************************************************
;
ACALL ICLR ;CLEAR THE INTERRUPTS
ACALL G4 ;PUT END ADDRESS INTO DPTR
MOV A,#6 ;ADJUST MATRIX SPACE
ACALL ADDPTR ;ADD FOR PROPER BOUNDS
ACALL X31DP ;PUT MATRIX BOUNDS IN R3:R1
MOV DPTR,#MT_ALL ;SAVE R3:R1 IN MATRIX FREE SPACE
ACALL S31DP ;DPTR POINTS TO MEMTOP
ACALL L31DPI ;LOAD MEMTOP INTO R3:R1
MOV DPTR,#STR_AL ;GET MEMORY ALLOCATED FOR STRINGS
ACALL LDPTRI
LCALL DUBSUB ;R3:R1 = MEMTOP - STRING ALLOCATION ******AA CALL-->LCALL
MOV DPTR,#VARTOP ;SAVE R3:R1 IN VARTOP
;
; FALL THRU TO S31DP2
;
;***************************************************************
;
;S31DP - STORE R3 INTO (DPTR) AND R1 INTO (DPTR+1)
;
;ACC GETS CLOBBERED
;
;***************************************************************
;
S31DP2: ACALL S31DP ;DO IT TWICE
;
S31DP: MOV A,R3 ;GET R3 INTO ACC
MOVX @DPTR,A ;STORE IT
INC DPTR ;BUMP DPTR
MOV A,R1 ;GET R1
MOVX @DPTR,A ;STORE IT
INC DPTR ;BUMP IT AGAIN TO SAVE PROGRAM SPACE
RET ;GO BACK
;
;
;***************************************************************
;
STRING: ; Allocate memory for strings
;
;***************************************************************
;
LCALL TWO ;R3:R1 = NUMBER, R2:R0 = LEN
MOV DPTR,#STR_AL ;SAVE STRING ALLOCATION
ACALL S31DP
INC R6 ;BUMP
MOV S_LEN,R6 ;SAVE STRING LENGTH
AJMP RCLEAR ;CLEAR AND SET IT UP
;
newpage
;***************************************************************
;
; F_VAR - Find the variable in symbol table
; R7:R6 contain the variable name
; If not found create a zero entry and set the carry
; R2:R0 has the address of variable on return
;
;***************************************************************
;
F_VAR: MOV DPTR,#VARTOP ;PUT VARTOP IN DPTR
ACALL LDPTRI
ACALL DECDP2 ;ADJUST DPTR FOR LOOKUP
;
F_VAR0: MOVX A,@DPTR ;LOAD THE VARIABLE
JZ F_VAR2 ;TEST IF AT THE END OF THE TABLE
INC DPTR ;BUMP FOR NEXT BYTE
CJNE A,R7B0,F_VAR1 ;SEE IF MATCH
MOVX A,@DPTR ;LOAD THE NAME
CJNE A,R6B0,F_VAR1
;
; Found the variable now adjust and put in R2:R0
;
DLD: MOV A,DPL ;R2:R0 = DPTR-2
SUBB A,#2
MOV R0,A
MOV A,DPH
SUBB A,#0 ;CARRY IS CLEARED
MOV R2,A
RET
;
F_VAR1: MOV A,DPL ;SUBTRACT THE STACK SIZE+ADJUST
CLR C
SUBB A,#STESIZ
MOV DPL,A ;RESTORE DPL
JNC F_VAR0
DEC DPH
SJMP F_VAR0 ;CONTINUE COMPARE
;
newpage
;
; Add the entry to the symbol table
;
F_VAR2: LCALL R76S ;SAVE R7 AND R6
CLR C
ACALL DLD ;BUMP THE POINTER TO GET ENTRY ADDRESS
;
; Adjust pointer and save storage allocation
; and make sure we aren't wiping anything out
; First calculate new storage allocation
;
MOV A,R0
SUBB A,#STESIZ-3 ;NEED THIS MUCH RAM
MOV R1,A
MOV A,R2
SUBB A,#0
MOV R3,A
;
; Now save the new storage allocation
;
MOV DPTR,#ST_ALL
CALL S31DP ;SAVE STORAGE ALLOCATION
;
; Now make sure we didn't blow it, by wiping out MT_ALL
;
ACALL DCMPX ;COMPARE STORAGE ALLOCATION
JC CCLR3 ;ERROR IF CARRY
SETB C ;DID NOT FIND ENTRY
RET ;EXIT IF TEST IS OK
;
newpage
;***************************************************************
;
; Command action routine - NEW
;
;***************************************************************
;
CNEW: MOV DPTR,#PSTART ;SAVE THE START OF PROGRAM
MOV A,#EOF ;END OF FILE
MOVX @DPTR,A ;PUT IT IN MEMORY
;
; falls thru
;
;*****************************************************************
;
; The statement action routine - CLEAR
;
;*****************************************************************
;
CLR LINEB ;SET UP FOR RUN AND GOTO
;
RCLEAR: ACALL LCLR ;CLEAR THE INTERRUPTS, SET UP MATRICES
MOV DPTR,#MEMTOP ;PUT MEMTOP IN R3:R1
ACALL L31DPI
ACALL G4 ;DPTR GETS END ADDRESS
ACALL CL_1 ;CLEAR THE MEMORY
;
RC1: MOV DPTR,#STACKTP ;POINT AT CONTROL STACK TOP
CLR A ;CONTROL UNDERFLOW
;
RC2: MOVX @DPTR,A ;SAVE IN MEMORY
MOV CSTKA,#STACKTP
MOV ASTKA,#STACKTP
CLR CONB ;CAN'T CONTINUE
RET
;
newpage
;***************************************************************
;
; Loop until the memory is cleared
;
;***************************************************************
;
CL_1: INC DPTR ;BUMP MEMORY POINTER
CLR A ;CLEAR THE MEMORY
MOVX @DPTR,A ;CLEAR THE RAM
MOVX A,@DPTR ;READ IT
JNZ CCLR3 ;MAKE SURE IT IS CLEARED
MOV A,R3 ;GET POINTER FOR COMPARE
CJNE A,DPH,CL_1 ;SEE TO LOOP
MOV A,R1 ;NOW TEST LOW BYTE
CJNE A,DPL,CL_1
;
CL_2: RET
;
CCLR3: LJMP TB ;ALLOCATED MEMORY DOESN'T EXSIST ******AA JMP-->LJMP
;
;**************************************************************
;
SCLR: ;Entry point for clear return
;
;**************************************************************
;
LCALL DELTST ;TEST FOR A CR ******AA CALL-->LCALL
JNC RCLEAR
LCALL GCI1 ;BUMP THE TEST POINTER ******AA CALL-->LCALL
CJNE A,#'I',RC1 ;SEE IF I, ELSE RESET THE STACK
;
;**************************************************************
;
ICLR: ; Clear interrupts and system garbage
;
;**************************************************************
;
JNB INTBIT,$+5 ;SEE IF BASIC HAS INTERRUPTS
CLR EX1 ;IF SO, CLEAR INTERRUPTS
ANL 34,#00100000B ;SET INTERRUPTS + CONTINUE
RETI
;
newpage
;***************************************************************
;
;OUTPUT ROUTINES
;
;***************************************************************
;
CRLF2: ACALL CRLF ;DO TWO CRLF'S
;
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
;
newpage
;***************************************************************
;
; 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,#HI(IBUF) ;IBUF IS IN THE ZERO PAGE
MOV R0,#LO(IBUF) ;POINT AT THE INPUT BUFFER
;
INL1: ACALL INCHAR ;GET A CHARACTER
MOV R5,A ;SAVE IN R5 FOR OUTPUT
CJNE A,#7FH,INL2 ;SEE IF A DELETE CHARACTER
CJNE R0,#LO(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
;
newpage
include bas52.out ; ******AA
;
BCK: ACALL CSTS ;CHECK STATUS
JNC CI_RET+1 ;EXIT IF NO CHARACTER
;
newpage
;***************************************************************
;
;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
;
newpage
;***************************************************************
;
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
;
newpage
;***************************************************************
;
; 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: LJMP CMND1 ;DONE ******AA JMP-->LJMP
newpage
;**************************************************************
;
; 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
LJMP ERRS ;JUMP TO ERROR ROUTINE ******AA JMP-->LJMP
;
newpage
;**************************************************************
;
; 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: 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
LCALL TWO_EY ; ******AA CALL-->LCALL
ACALL SPEOP+4 ;EVALUATE AFTER EQUALS
AJMP ISTAX1 ;SAVE THE CHARACTER
;
newpage
;**************************************************************
;
;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
;
newpage
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
;
newpage
;***************************************************************
;
; 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: LCALL TBYTE ;TRANSFER THE BYTE ******AA CALL-->LCALL
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
;
newpage
;
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
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
;
newpage
;**************************************************************
;
; 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
;
newpage
;*************************************************************
;
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
;
newpage
;***************************************************************
;
; 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
;
newpage
;**************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;
;**************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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
;
newpage
;***************************************************************
;
; 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 COMMA
;
SP1: ACALL CPS ;SEE IF A STRING TO PRINT
JNC SP2 ;IF A STRING, CHECK FOR A COMMA
;
SP4: CJNE A,#T_TAB,SP6
ACALL I_PI ;ALWAYS CLEARS CARRY
SUBB A,PHEAD ;TAKE DELTA BETWEEN TAB AND PHEAD
JC SP2 ;EXIT IF PHEAD > TAB
SJMP SP7 ;OUTPUT SPACES
;
SP6: CJNE A,#T_SPC,SM
ACALL I_PI ;SET UP PAREN VALUE
;
SP7: JZ SP2
LCALL STEROT ;OUTPUT A SPACE
DEC A ;DECREMENT COUNTER
SJMP SP7 ;LOOP
;
newpage
SM: CJNE A,#T_CHR,SP8
ACALL IGC
CJNE A,#'$',$+9
ACALL CNX ;PUT THE CHARACTER ON THE STACK
ACALL IFIXL ;PUT THE CHARACTER IN R1
SJMP $+6
ACALL ONE ;EVALUATE THE EXPRESSION, PUT IN R3:R1
ACALL ERPAR
MOV R5,R1B0 ;BYTE TO OUTPUT
SJMP SQ
;
SP8: CJNE A,#T_CR,SX
ACALL GCI1 ;EAT THE TOKEN
MOV R5,#CR
;
SQ: CALL TEROT
SJMP SP2 ;OUTPUT A CR AND DO IT AGAIN
;
SX: CJNE A,#T_USE,SP9 ;USING TOKEN
ACALL IGC ;GE THE CHARACTER AFTER THE USING TOKEN
CJNE A,#'F',U4 ;SEE IF FLOATING
MOV FORMAT,#0F0H ;SET FLOATING
ACALL IGC ;BUMP THE POINTER AND GET THE CHARACTER
ACALL GCI1 ;BUMP IT AGAIN
ANL A,#0FH ;STRIP OFF ASCII BIAS
JZ U3 ;EXIT IF ZERO
CJNE A,#3,$+3 ;SEE IF AT LEAST A THREE
JNC U3 ;FORCE A THREE IF NOT A THREE
MOV A,#3
;
U3: ORL FORMAT,A ;PUT DIGIT IN FORMAT
SJMP U8 ;CLEAN UP END
;
U4: CJNE A,#'0',U5
MOV FORMAT,#0 ;FREE FORMAT
ACALL GCI1 ;BUMP THE POINTER
SJMP U8
;
U5: CJNE A,#'#',U8 ;SEE IF INTGER FORMAT
ACALL U6
MOV FORMAT,R7 ;SAVE THE FORMAT
CJNE A,#'.',U8A ;SEE IF TERMINATOR WAS RADIX
ACALL IGC ;BUMP PAST .
ACALL U6 ;LOOP AGAIN
MOV A,R7 ;GET COUNT
ADD A,FORMAT ;SEE IF TOO BIG
ADD A,#0F7H
JNC U5A
;
newpage
SE0: AJMP INTERX ;ERROR, BAD SYNTAX
;
U5A: MOV A,R7 ;GET THE COUNT BACK
SWAP A ;ADJUST
ORL FORMAT,A ;GET THE COUNT
;
U8A: MOV A,FORMAT
;
U8B: SWAP A ;GET THE FORMAT RIGHT
MOV FORMAT,A
;
U8: ACALL ERPAR
AJMP SP2 ;DONE
;
U6: MOV R7,#0 ;SET COUNTER
;
U7: CJNE A,#'#',SP9A ;EXIT IF NOT A #
INC R7 ;BUMP COUNTER
ACALL IGC ;GET THE NEXT CHARACTER
SJMP U7 ;LOOP
;
SP9: ACALL DELTST+2 ;CHECK FOR DELIMITER
JNC SP9A ;EXIT IF A DELIMITER
;
CJNE A,#T_ELSE,SS
;
SP9A: RET ;EXIT IF ELSE TOKEN
;
;**************************************************************
;
; P_E - Evaluate an expression in parens ( )
;
;**************************************************************
;
P_E: MOV R7,#T_LPAR
ACALL WE
;
ERPAR: MOV R7,#')' ;EAT A RIGHT PAREN
;
EATC: ACALL GCI ;GET THE CHARACTER
CJNE A,R7B0,SE0 ;ERROR IF NOT THE SAME
RET
;
newpage
;***************************************************************
;
S_ON: ; ON Statement
;
;***************************************************************
;
ACALL ONE ;GET THE EXPRESSION
ACALL GCI ;GET THE NEXT CHARACTER
CJNE A,#T_GOTO,C0
ACALL C1 ;EAT THE COMMAS
AJMP SF3 ;DO GOTO
;
C0: CJNE A,#T_GOSB,SE0
ACALL C1
AJMP SGS0 ;DO GOSUB
;
C1: CJNE R1,#0,C2
ACALL INTERR ;GET THE LINE NUMBER
ACALL FINDCR
AJMP RL1 ;FINISH UP THIS LINE
;
C2: MOV R7,#','
ACALL FINDC
CJNE A,#',',SE0 ;ERROR IF NOT A COMMA
DEC R1
ACALL GCI1 ;BUMP PAST COMMA
SJMP C1
;
newpage
;
SS: ACALL S_C ;SEE IF A STRING
JC SA ;NO STRING IF CARRY IS SET
LCALL UPRNT ;PUT POINTER IN DPTR
AJMP SP2 ;SEE IF MORE
;
SA: ACALL EXPRB ;MUST BE AN EXPRESSION
MOV A,#72
CJNE A,PHEAD,$+3 ;CHECK PHEAD POSITION
JNC $+4
ACALL SP0 ;FORCE A CRLF
JNB HMODE,S13 ;HEX MODE?
CALL FCMP ;SEE IF TOS IS < 0FFFH
JC S13 ;EXIT IF GREATER
CALL AABS ;GET THE SIGN
JNZ OOPS ;WASTE IF NEGATIVE
ACALL IFIXL
CALL FP_BASE+22 ;PRINT HEXMODE
AJMP SP2
OOPS: CALL ANEG ;MAKE IT NEGATIVE
;
S13: CALL FP_BASE+14 ;DO FP OUTPUT
MOV A,#1 ;OUTPUT A SPACE
AJMP SP7
;
newpage
;***************************************************************
;
; ANU - Get variable name from text - set carry if not found
; if succeeds returns variable in R7:R6
; R6 = 0 if no digit in name
;
;***************************************************************
;
ANU: ACALL IGC ;INCREMENT AND GET CHARACTER
LCALL 1FEDH ;CHECK FOR DIGIT
JC $+14 ;EXIT IF VALID DIGIT
CJNE A,#'_',$+4 ;SEE IF A _
RET
;
AL: CJNE A,#'A',$+3 ;IS IT AN ASCII A?
JC $+6 ;EXIT IF CARRY IS SET
CJNE A,#'Z'+1,$+3 ;IS IT LESS THAN AN ASCII Z
CPL C ;FLIP CARRY
RET
;
JNB F0,VAR2
;
SD0: MOV DPTR,#E6X
AJMP EK
;
SDIMX: SETB F0 ;SAYS DOING A DIMENSION
SJMP VAR1
;
VAR: CLR F0 ;SAYS DOING A VARIABLE
;
VAR1: ACALL GC ;GET THE CHARACTER
ACALL AL ;CHECK FOR ALPHA
JNC $+6 ;ERROR IF IN DIM
JB F0,SD0
RET
MOV R7,A ;SAVE ALPHA CHARACTER
CLR A ;ZERO IN CASE OF FAILURE
MOV R5,A ;SAVE IT
;
VY: MOV R6,A
ACALL ANU ;CHECK FOR ALPHA OR NUMBER
JC VX ;EXIT IF NO ALPHA OR NUM
;
XCH A,R7
ADD A,R5 ;NUMBER OF CHARACTERS IN ALPHABET
XCH A,R7 ;PUT IT BACK
MOV R5,#26 ;FOR THE SECOND TIME AROUND
SJMP VY
;
VX: CLR LINEB ;TELL EDITOR A VARIABLE IS DECLARED
CJNE A,#T_LPAR,V4 ;SEE IF A LEFT PAREN
;
ORL R6B0,#80H ;SET BIT 7 TO SIGINIFY MATRIX
CALL F_VAR ;FIND THE VARIABLE
PUSH R2B0 ;SAVE THE LOCATION
PUSH R0B0
JNC SD0-3 ;DEFAULT IF NOT IN TABLE
JB F0,SDI ;NO DEFAULT FOR DIMENSION
MOV R1,#10
MOV R3,#0
ACALL D_CHK
;
VAR2: ACALL PAREN_INT ;EVALUATE INTEGER IN PARENS
CJNE R3,#0,SD0 ;ERROR IF R3<>0
POP DPL ;GET VAR FOR LOOKUP
POP DPH
MOVX A,@DPTR ;GET DIMENSION
DEC A ;BUMP OFFSET
SUBB A,R1 ;A MUST BE > R1
JC SD0
LCALL DECDP2 ;BUMP POINTER TWICE
ACALL VARB ;CALCULATE THE BASE
;
X3120: XCH A,R1 ;SWAP R2:R0, R3:R1
XCH A,R0
XCH A,R1
XCH A,R3
XCH A,R2
XCH A,R3
RET
;
V4: JB F0,SD0 ;ERROR IF NO LPAR FOR DIM
LCALL F_VAR ;GET SCALAR VARIABLE
CLR C
RET
;
newpage
;
SDI: ACALL PAREN_INT ;EVALUATE PAREN EXPRESSION
CJNE R3,#0,SD0 ;ERROR IF NOT ZERO
POP R0B0 ;SET UP R2:R0
POP R2B0
ACALL D_CHK ;DO DIM
ACALL C_TST ;CHECK FOR COMMA
JNC SDIMX ;LOOP IF COMMA
RET ;RETURN IF NO COMMA
;
D_CHK: INC R1 ;BUMP FOR TABLE LOOKUP
MOV A,R1
JZ SD0 ;ERROR IF 0FFFFH
MOV R4,A ;SAVE FOR LATER
MOV DPTR,#MT_ALL ;GET MATRIX ALLOCATION
ACALL VARB ;DO THE CALCULATION
MOV R7,DPH ;SAVE MATRIX ALLOCATION
MOV R6,DPL
MOV DPTR,#ST_ALL ;SEE IF TOO MUCH MEMORY TAKEN
CALL FUL1 ;ST_ALL SHOULD BE > R3:R1
MOV DPTR,#MT_ALL ;SAVE THE NEW MATRIX POINTER
CALL S31DP
MOV DPL,R0 ;GET VARIABLE ADDRESS
MOV DPH,R2
MOV A,R4 ;DIMENSION SIZE
MOVX @DPTR,A ;SAVE IT
CALL DECDP2 ;SAVE TARGET ADDRESS
;
R76S: MOV A,R7
MOVX @DPTR,A
INC DPTR
MOV A,R6 ;ELEMENT SIZE
MOVX @DPTR,A
RET ;R2:R0 STILL HAS SYMBOL TABLE ADDRESS
;
newpage
;***************************************************************
;
; The statement action routine - INPUT
;
;***************************************************************
;
SINPUT: ACALL CPS ;PRINT STRING IF THERE
;
ACALL C_TST ;CHECK FOR A COMMA
JNC IN2A ;NO CRLF
ACALL SP0 ;DO A CRLF
;
IN2: MOV R5,#'?' ;OUTPUT A ?
CALL TEROT
;
IN2A: SETB INP_B ;DOING INPUT
CALL INLINE ;INPUT THE LINE
CLR INP_B
MOV TEMP5,#HI(IBUF)
MOV TEMP4,#LO(IBUF)
;
IN3: ACALL S_C ;SEE IF A STRING
JC IN3A ;IF CARRY IS SET, NO STRING
ACALL X3120 ;FLIP THE ADDRESSES
MOV R3,TEMP5
MOV R1,TEMP4
ACALL SSOOP
ACALL C_TST ;SEE IF MORE TO DO
JNC IN2
RET
;
IN3A: CALL DTEMP ;GET THE USER LOCATION
CALL GET_NUM ;GET THE USER SUPPLIED NUMBER
JNZ IN5 ;ERROR IF NOT ZERO
CALL TEMPD ;SAVE THE DATA POINTER
ACALL VAR_ER ;GET THE VARIABLE
ACALL XPOP ;SAVE THE VARIABLE
CALL DTEMP ;GET DPTR BACK FROM VAR_ER
ACALL C_TST ;SEE IF MORE TO DO
JC IN6 ;EXIT IF NO COMMA
MOVX A,@DPTR ;GET INPUT TERMINATOR
CJNE A,#',',IN5 ;IF NOT A COMMA DO A CR AND TRY AGAIN
INC DPTR ;BUMP PAST COMMA AND READ NEXT VALUE
CALL TEMPD
SJMP IN3
;
newpage
;
IN5: MOV DPTR,#IAN ;PRINT INPUT A NUMBER
CALL CRP ;DO A CR, THEN, PRINT FROM ROM
LJMP CC1 ;TRY IT AGAIN
;
IN6: MOVX A,@DPTR
CJNE A,#CR,EIGP
RET
;
EIGP: MOV DPTR,#EIG
CALL CRP ;PRINT THE MESSAGE AND EXIT
AJMP SP0 ;EXIT WITH A CRLF
;
;***************************************************************
;
SOT: ; On timer interrupt
;
;***************************************************************
;
ACALL TWO ;GET THE NUMBERS
MOV SP_H,R3
MOV SP_L,R1
MOV DPTR,#TIV ;SAVE THE NUMBER
SETB OTS
AJMP R76S ;EXIT
;
;
;***************************************************************
;
SCALL: ; Call a user rountine
;
;***************************************************************
;
ACALL INTERR ;CONVERT INTEGER
CJNE R2,#0,S_C_1 ;SEE IF TRAP
MOV A,R0
JB ACC.7,S_C_1
ADD A,R0
MOV DPTR,#4100H
MOV DPL,A
;
S_C_1: ACALL AC1 ;JUMP TO USER PROGRAM
ANL PSW,#11100111B ;BACK TO BANK 0
RET ;EXIT
;
newpage
;**************************************************************
;
THREE: ; Save value for timer function
;
;**************************************************************
;
ACALL ONE ;GET THE FIRST INTEGER
CALL CBIAS ;BIAS FOR TIMER LOAD
MOV T_HH,R3
MOV T_LL,R1
MOV R7,#',' ;WASTE A COMMA
ACALL EATC ;FALL THRU TO TWO
;
;**************************************************************
;
TWO: ; Get two values seperated by a comma off the stack
;
;**************************************************************
;
ACALL EXPRB
MOV R7,#',' ;WASTE THE COMMA
ACALL WE
JMP TWOL ;EXIT
;
;*************************************************************
;
ONE: ; Evaluate an expression and get an integer
;
;*************************************************************
;
ACALL EXPRB ;EVALUATE EXPERSSION
;
IFIXL: CALL IFIX ;INTEGERS IN R3:R1
MOV A,R1
RET
;
;
;*************************************************************
;
I_PI: ; Increment text pointer then get an integer
;
;*************************************************************
;
ACALL GCI1 ;BUMP TEXT, THEN GET INTEGER
;
PAREN_INT:; Get an integer in parens ( )
;
ACALL P_E
SJMP IFIXL
;
newpage
;
DP_B: MOV DPH,BOFAH
MOV DPL,BOFAL
RET
;
DP_T: MOV DPH,TXAH
MOV DPL,TXAL
RET
;
CPS: ACALL GC ;GET THE CHARACTER
CJNE A,#'"',NOPASS ;EXIT IF NO STRING
ACALL DP_T ;GET TEXT POINTER
INC DPTR ;BUMP PAST "
MOV R4,#'"'
CALL PN0 ;DO THE PRINT
INC DPTR ;GO PAST QUOTE
CLR C ;PASSED TEST
;
T_DP: MOV TXAH,DPH ;TEXT POINTER GETS DPTR
MOV TXAL,DPL
RET
;
;*************************************************************
;
S_C: ; Check for a string
;
;*************************************************************
;
ACALL GC ;GET THE CHARACTER
CJNE A,#'$',NOPASS ;SET CARRY IF NOT A STRING
AJMP IST_CAL ;CLEAR CARRY, CALCULATE OFFSET
;
;
;
;**************************************************************
;
C_TST: ACALL GC ;GET A CHARACTER
CJNE A,#',',NOPASS ;SEE IF A COMMA
;
newpage
;***************************************************************
;
;GC AND GCI - GET A CHARACTER FROM TEXT (NO BLANKS)
; PUT CHARACTER IN THE ACC
;
;***************************************************************
;
IGC: ACALL GCI1 ;BUMP POINTER, THEN GET CHARACTER
;
GC: SETB RS0 ;USE BANK 1
MOV P2,R2 ;SET UP PORT 2
MOVX A,@R0 ;GET EXTERNAL BYTE
CLR RS0 ;BACK TO BANK 0
RET ;EXIT
;
GCI: ACALL GC
;
; This routine bumps txa by one and always clears the carry
;
GCI1: SETB RS0 ;BANK 1
INC R0 ;BUMP TXA
CJNE R0,#0,$+4
INC R2
CLR RS0
RET ;EXIT
;
newpage
;**************************************************************
;
; Check delimiters
;
;**************************************************************
;
DELTST: ACALL GC ;GET A CHARACTER
CJNE A,#CR,DT1 ;SEE IF A CR
CLR A
RET
;
DT1: CJNE A,#':',NOPASS ;SET CARRY IF NO MATCH
;
L_RET: RET
;
;
;***************************************************************
;
; FINDC - Find the character in R7, update TXA
;
;***************************************************************
;
FINDCR: MOV R7,#CR ;KILL A STATEMENT LINE
;
FINDC: ACALL DELTST
JNC L_RET
;
CJNE A,R7B0,FNDCL2 ;MATCH?
RET
;
FNDCL2: ACALL GCI1
SJMP FINDC ;LOOP
;
ACALL GCI1
;
WCR: ACALL DELTST ;WASTE UNTIL A "REAL" CR
JNZ WCR-2
RET
;
newpage
;***************************************************************
;
; VAR_ER - Check for a variable, exit if error
;
;***************************************************************
;
VAR_ER: ACALL VAR
SJMP INTERR+2
;
;
;***************************************************************
;
; S_D0 - The Statement Action Routine DO
;
;***************************************************************
;
S_DO: ACALL CSC ;FINISH UP THE LINE
MOV R4,#DTYPE ;TYPE FOR STACK
ACALL SGS1 ;SAVE ON STACK
AJMP ILOOP ;EXIT
;
newpage
;***************************************************************
;
; CLN_UP - Clean up the end of a statement, see if at end of
; file, eat character and line count after CR
;
;***************************************************************
;
C_2: CJNE A,#':',C_1 ;SEE IF A TERMINATOR
AJMP GCI1 ;BUMP POINTER AND EXIT, IF SO
;
C_1: CJNE A,#T_ELSE,EP5
ACALL WCR ;WASTE UNTIL A CR
;
CLN_UP: ACALL GC ;GET THE CHARACTER
CJNE A,#CR,C_2 ;SEE IF A CR
ACALL IGC ;GET THE NEXT CHARACTER
CJNE A,#EOF,B_TXA ;SEE IF TERMINATOR
;
NOPASS: SETB C
RET
;
B_TXA: XCH A,TXAL ;BUMP TXA BY THREE
ADD A,#3
XCH A,TXAL
JBC CY,$+4
RET
INC TXAH
RET
;
newpage
;***************************************************************
;
; Get an INTEGER from the text
; sets CARRY if not found
; returns the INTGER value in DPTR and R2:R0
; returns the terminator in ACC
;
;***************************************************************
;
INTERR: ACALL INTGER ;GET THE INTEGER
JC EP5 ;ERROR IF NOT FOUND
RET ;EXIT IF FOUND
;
INTGER: ACALL DP_T
CALL FP_BASE+18 ;CONVERT THE INTEGER
ACALL T_DP
MOV DPH,R2 ;PUT THE RETURNED VALUE IN THE DPTR
MOV DPL,R0
;
ITRET: RET ;EXIT
;
;
WE: ACALL EATC ;WASTE THE CHARACTER
;
; Fall thru to evaluate the expression
;
newpage
;***************************************************************
;
; EXPRB - Evaluate an expression
;
;***************************************************************
;
EXPRB: MOV R2,#LO(OPBOL) ;BASE PRECEDENCE
;
EP1: PUSH R2B0 ;SAVE OPERATOR PRECEDENCE
CLR ARGF ;RESET STACK DESIGNATOR
;
EP2: MOV A,SP ;GET THE STACK POINTER
ADD A,#12 ;NEED AT LEAST 12 BYTES
JNC $+5
LJMP ERROR-3
MOV A,ASTKA ;GET THE ARG STACK
SUBB A,#LO(TM_TOP+12);NEED 12 BYTES ALSO
JNC $+5
LJMP E4YY
JB ARGF,EP4 ;MUST BE AN OPERATOR, IF SET
ACALL VAR ;IS THE VALUE A VARIABLE?
JNC EP3 ;PUT VARIABLE ON STACK
;
ACALL CONST ;IS THE VALUE A NUMERIC CONSTANT?
JNC EP4 ;IF SO, CONTINUE, IF NOT, SEE WHAT
CALL GC ;GET THE CHARACTER
CJNE A,#T_LPAR,EP4 ;SEE IF A LEFT PAREN
MOV A,#(LO(OPBOL+1))
SJMP XLPAR ;PROCESS THE LEFT PAREN
;
EP3: ACALL PUSHAS ;SAVE VAR ON STACK
;
EP4: ACALL GC ;GET THE OPERATOR
;
CJNE A,#T_LPAR,$+3 ;IS IT AN OPERATOR
JNC XOP ;PROCESS OPERATOR
CJNE A,#T_UOP,$+3 ;IS IT A UNARY OPERATOR
JNC XBILT ;PROCESS UNARY (BUILT IN) OPERATOR
POP R2B0 ;GET BACK PREVIOUS OPERATOR PRECEDENCE
JB ARGF,ITRET ;OK IF ARG FLAG IS SET
;
EP5: CLR C ;NO RECOVERY
LJMP E1XX+2
;
; Process the operator
;
XOP: ANL A,#1FH ;STRIP OFF THE TOKE BITS
JB ARGF,XOP1 ;IF ARG FLAG IS SET, PROCESS
CJNE A,#T_SUB-T_LPAR,XOP3
MOV A,#T_NEG-T_LPAR
;
newpage
XOP1: ADD A,#LO(OPBOL+1) ;BIAS THE TABLE
MOV R2,A
MOV DPTR,#00H
MOVC A,@A+DPTR ;GET THE CURRENT PRECEDENCE
MOV R4,A
POP ACC ;GET THE PREVIOUS PRECEDENCE
MOV R5,A ;SAVE THE PREVIOUS PRECEDENCE
MOVC A,@A+DPTR ;GET IT
CJNE A,R4B0,$+7 ;SEE WHICH HAS HIGHER PRECEDENCE
CJNE A,#12,ITRET ;SEE IF ANEG
SETB C
JNC ITRET ;PROCESS NON-INCREASING PRECEDENCE
;
; Save increasing precedence
;
PUSH R5B0 ;SAVE OLD PRECEDENCE ADDRESS
PUSH R2B0 ;SAVE NEW PRECEDENCE ADDRESS
ACALL GCI1 ;EAT THE OPERATOR
ACALL EP1 ;EVALUATE REMAINING EXPRESSION
POP ACC
;
; R2 has the action address, now setup and perform operation
;
XOP2: MOV DPTR,#OPTAB
ADD A,#LO(~OPBOL)
CALL ISTA1 ;SET UP TO RETURN TO EP2
AJMP EP2 ;JUMP TO EVALUATE EXPRESSION
;
; Built-in operator processing
;
XBILT: ACALL GCI1 ;EAT THE TOKEN
ADD A,#LO(50H+LO(UOPBOL))
JB ARGF,EP5 ;XBILT MUST COME AFTER AN OPERATOR
CJNE A,#STP,$+3
JNC XOP2
;
XLPAR: PUSH ACC ;PUT ADDRESS ON THE STACK
ACALL P_E
SJMP XOP2-2 ;PERFORM OPERATION
;
XOP3: CJNE A,#T_ADD-T_LPAR,EP5
ACALL GCI1
AJMP EP2 ;WASTE + SIGN
;
newpage
XPOP: ACALL X3120 ;FLIP ARGS THEN POP
;
;***************************************************************
;
; POPAS - Pop arg stack and copy variable to R3:R1
;
;***************************************************************
;
POPAS: LCALL INC_ASTKA
JMP VARCOP ;COPY THE VARIABLE
;
AXTAL: MOV R2,#HI(CXTAL)
MOV R0,#LO(CXTAL)
;
; fall thru
;
;***************************************************************
;
PUSHAS: ; Push the Value addressed by R2:R0 onto the arg stack
;
;***************************************************************
;
CALL DEC_ASTKA
SETB ARGF ;SAYS THAT SOMTHING IS ON THE STACK
LJMP VARCOP
;
;
;***************************************************************
;
ST_A: ; Store at expression
;
;***************************************************************
;
ACALL ONE ;GET THE EXPRESSION
SJMP POPAS ;SAVE IT
;
;
;***************************************************************
;
LD_A: ; Load at expression
;
;***************************************************************
;
ACALL ONE ;GET THE EXPRESSION
ACALL X3120 ;FLIP ARGS
SJMP PUSHAS
;
newpage
;***************************************************************
;
CONST: ; Get a constant fron the text
;
;***************************************************************
;
CALL GC ;FIRST SEE IF LITERAL
CJNE A,#T_ASC,C0C ;SEE IF ASCII TOKEN
CALL IGC ;GET THE CHARACTER AFTER TOKEN
CJNE A,#'$',CN0 ;SEE IF A STRING
;
CNX: CALL CSY ;CALCULATE IT
LJMP AXBYTE+2 ;SAVE IT ON THE STACK ******AA JMP-->LJMP
;
CN0: LCALL TWO_R2 ;PUT IT ON THE STACK ******AA CALL-->LCALL
CALL GCI1 ;BUMP THE POINTER
LJMP ERPAR ;WASTE THE RIGHT PAREN ******AA JMP-->LJMP
;
;
C0C: CALL DP_T ;GET THE TEXT POINTER
CALL GET_NUM ;GET THE NUMBER
CJNE A,#0FFH,C1C ;SEE IF NO NUMBER
SETB C
C2C: RET
;
C1C: JNZ FPTST
CLR C
SETB ARGF
;
C3C: JMP T_DP
;
FPTST: ANL A,#00001011B ;CHECK FOR ERROR
JZ C2C ;EXIT IF ZERO
;
; Handle the error condition
;
MOV DPTR,#E2X ;DIVIDE BY ZERO
JNB ACC.0,$+6 ;UNDERFLOW
MOV DPTR,#E7X
JNB ACC.1,$+6 ;OVERFLOW
MOV DPTR,#E11X
;
FPTS: JMP ERROR
;
newpage
;***************************************************************
;
; The Command action routine - LIST
;
;***************************************************************
;
CLIST: CALL NUMC ;SEE IF TO LINE PORT
ACALL FSTK ;PUT 0FFFFH ON THE STACK
CALL INTGER ;SEE IF USER SUPPLIES LN
CLR A ;LN = 0 TO START
MOV R3,A
MOV R1,A
JC CL1 ;START FROM ZERO
;
CALL TEMPD ;SAVE THE START ADDTESS
CALL GCI ;GET THE CHARACTER AFTER LIST
CJNE A,#T_SUB,$+10 ;CHECK FOR TERMINATION ADDRESS '-'
ACALL INC_ASTKA ;WASTE 0FFFFH
LCALL INTERR ;GET TERMINATION ADDRESS
ACALL TWO_EY ;PUT TERMINATION ON THE ARG STACK
MOV R3,TEMP5 ;GET THE START ADDTESS
MOV R1,TEMP4
;
CL1: CALL GETLIN ;GET THE LINE NO IN R3:R1
JZ CL3 ;RET IF AT END
;
CL2: ACALL C3C ;SAVE THE ADDRESS
INC DPTR ;POINT TO LINE NUMBER
ACALL PMTOP+3 ;PUT LINE NUMBER ON THE STACK
ACALL CMPLK ;COMPARE LN TO END ADDRESS
JC CL3 ;EXIT IF GREATER
CALL BCK ;CHECK FOR A CONTROL C
ACALL DEC_ASTKA ;SAVE THE COMPARE ADDRESS
CALL DP_T ;RESTORE ADDRESS
ACALL UPPL ;UN-PROCESS THE LINE
ACALL C3C ;SAVE THE CR ADDRESS
ACALL CL6 ;PRINT IT
INC DPTR ;BUMP POINTER TO NEXT LINE
MOVX A,@DPTR ;GET LIN LENGTH
DJNZ ACC,CL2 ;LOOP
ACALL INC_ASTKA ;WASTE THE COMPARE BYTE
;
CL3: AJMP CMND1 ;BACK TO COMMAND PROCESSOR
;
CL6: MOV DPTR,#IBUF ;PRINT IBUF
CALL PRNTCR ;PRINT IT
CALL DP_T
;
CL7: JMP CRLF
;
LCALL X31DP
newpage
;***************************************************************
;
;UPPL - UN PREPROCESS A LINE ADDRESSED BY DPTR INTO IBUF
; RETURN SOURCE ADDRESS OF CR IN DPTR ON RETURN
;
;***************************************************************
;
UPPL: MOV R3,#HI(IBUF) ;POINT R3 AT HIGH IBUF
MOV R1,#LO(IBUF) ;POINT R1 AT IBUF
INC DPTR ;SKIP OVER LINE LENGTH
ACALL C3C ;SAVE THE DPTR (DP_T)
CALL L20DPI ;PUT LINE NUMBER IN R2:R0
CALL FP_BASE+16 ;CONVERT R2:R0 TO INTEGER
CALL DP_T
INC DPTR ;BUMP DPTR PAST THE LINE NUMBER
;
UPP0: CJNE R1,#LO(IBUF+6),$+3
JC UPP1A-4 ;PUT SPACES IN TEXT
INC DPTR ;BUMP PAST LN HIGH
MOVX A,@DPTR ;GET USER TEXT
MOV R6,A ;SAVE A IN R6 FOR TOKE COMPARE
JB ACC.7,UPP1 ;IF TOKEN, PROCESS
CJNE A,#20H,$+3 ;TRAP THE USER TOKENS
JNC $+5
CJNE A,#CR,UPP1 ;DO IT IF NOT A CR
CJNE A,#'"',UPP9 ;SEE IF STRING
ACALL UPP7 ;SAVE IT
ACALL UPP8 ;GET THE NEXT CHARACTER AND SAVE IT
CJNE A,#'"',$-2 ;LOOP ON QUOTES
SJMP UPP0
;
UPP9: CJNE A,#':',UPP1A ;PUT A SPACE IN DELIMITER
ACALL UPP7A
MOV A,R6
ACALL UPP7
ACALL UPP7A
SJMP UPP0
;
UPP1A: ACALL UPP8+2 ;SAVE THE CHARACTER, UPDATE POINTER
SJMP UPP0 ;EXIT IF A CR, ELSE LOOP
;
UPP1: ACALL C3C ;SAVE THE TEXT POINTER
MOV C,XBIT
MOV F0,C ;SAVE XBIT IN F0
MOV DPTR,#TOKTAB ;POINT AT TOKEN TABLE
JNB F0,UPP2
LCALL 2078H ;SET UP DPTR FOR LOOKUP
;
UPP2: CLR A ;ZERO A FOR LOOKUP
MOVC A,@A+DPTR ;GET TOKEN
INC DPTR ;ADVANCE THE TOKEN POINTER
CJNE A,#0FFH,UP_2 ;SEE IF DONE
JBC F0,UPP2-9 ;NOW DO NORMAL TABLE
AJMP CMND1 ;EXIT IF NOT FOUND
;
UP_2: CJNE A,R6B0,UPP2 ;LOOP UNTIL THE SAME
;
UP_3: CJNE A,#T_UOP,$+3
JNC UPP3
ACALL UPP7A ;PRINT THE SPACE IF OK
;
UPP3: CLR A ;DO LOOKUP
MOVC A,@A+DPTR
JB ACC.7,UPP4 ;EXIT IF DONE, ELSE SAVE
JZ UPP4 ;DONE IF ZERO
ACALL UPP7 ;SAVE THE CHARACTER
INC DPTR
SJMP UPP3 ;LOOP
;
UPP4: CALL DP_T ;GET IT BACK
MOV A,R6 ;SEE IF A REM TOKEN
XRL A,#T_REM
JNZ $+6
ACALL UPP8
SJMP $-2
JNC UPP0 ;START OVER AGAIN IF NO TOKEN
ACALL UPP7A ;PRINT THE SPACE IF OK
SJMP UPP0 ;DONE
;
UPP7A: MOV A,#' ' ;OUTPUT A SPACE
;
UPP7: AJMP PPL9+1 ;SAVE A
;
UPP8: INC DPTR
MOVX A,@DPTR
CJNE A,#CR,UPP7
AJMP PPL7+1
;
newpage
;**************************************************************
;
; This table contains all of the floating point constants
;
; The constants in ROM are stored "backwards" from the way
; basic normally treats floating point numbers. Instead of
; loading from the exponent and decrementing the pointer,
; ROM constants pointers load from the most significant
; digits and increment the pointers. This is done to 1) make
; arg stack loading faster and 2) compensate for the fact that
; no decrement data pointer instruction exsist.
;
; The numbers are stored as follows:
;
; BYTE X+5 = MOST SIGNIFICANT DIGITS IN BCD
; BYTE X+4 = NEXT MOST SIGNIFICANT DIGITS IN BCD
; BYTE X+3 = NEXT LEAST SIGNIFICANT DIGITS IN BCD
; BYTE X+2 = LEAST SIGNIFICANT DIGITS IN BCD
; BYTE X+1 = SIGN OF THE ABOVE MANTISSA 0 = +, 1 = -
; BYTE X = EXPONENT IN TWO'S COMPLEMENT BINARY
; ZERO EXPONENT = THE NUMBER ZERO
;
;**************************************************************
;
ATTAB: DB 128-2 ; ARCTAN LOOKUP
DB 00H
DB 57H
DB 22H
DB 66H
DB 28H
;
DB 128-1
DB 01H
DB 37H
DB 57H
DB 16H
DB 16H
;
DB 128-1
DB 00H
DB 14H
DB 96H
DB 90H
DB 42H
;
DB 128-1
DB 01H
DB 40H
DB 96H
DB 28H
DB 75H
;
DB 128
DB 00H
DB 64H
DB 62H
DB 65H
DB 10H
;
DB 128
DB 01H
DB 99H
DB 88H
DB 20H
DB 14H
;
DB 128
DB 00H
DB 51H
DB 35H
DB 99H
DB 19H
;
DB 128
DB 01H
DB 45H
DB 31H
DB 33H
DB 33H
;
DB 129
DB 00H
DB 00H
DB 00H
DB 00H
DB 10H
;
DB 0FFH ;END OF TABLE
;
NTWO: DB 129
DB 0
DB 0
DB 0
DB 0
DB 20H
;
TTIME: DB 128-4 ; CLOCK CALCULATION
DB 00H
DB 00H
DB 00H
DB 04H
DB 13H
;
newpage
;***************************************************************
;
; COSINE - Add pi/2 to stack, then fall thru to SIN
;
;***************************************************************
;
ACOS: ACALL POTWO ;PUT PI/2 ON THE STACK
ACALL AADD ;TOS = TOS+PI/2
;
;***************************************************************
;
; SINE - use taylor series to calculate sin function
;
;***************************************************************
;
ASIN: ACALL PIPI ;PUT PI ON THE STACK
ACALL RV ;REDUCE THE VALUE
MOV A,MT2 ;CALCULATE THE SIGN
ANL A,#01H ;SAVE LSB
XRL MT1,A ;SAVE SIGN IN MT1
ACALL CSTAKA ;NOW CONVERT TO ONE QUADRANT
ACALL POTWO
ACALL CMPLK ;DO COMPARE
JC $+6
ACALL PIPI
ACALL ASUB
ACALL AABS
MOV DPTR,#SINTAB ;SET UP LOOKUP TABLE
ACALL POLYC ;CALCULATE THE POLY
ACALL STRIP
AJMP SIN0
;
; Put PI/2 on the stack
;
POTWO: ACALL PIPI ;PUT PI ON THE STACK, NOW DIVIDE
;
DBTWO: MOV DPTR,#NTWO
ACALL PUSHC
;MOV A,#2 ;BY TWO
;ACALL TWO_R2
AJMP ADIV
;
newpage
;*************************************************************
;
POLYC: ; Expand a power series to calculate a polynomial
;
;*************************************************************
;
ACALL CSTAKA2 ;COPY THE STACK
ACALL AMUL ;SQUARE THE STACK
ACALL POP_T1 ;SAVE X*X
ACALL PUSHC ;PUT CONSTANT ON STACK
;
POLY1: ACALL PUSH_T1 ;PUT COMPUTED VALUE ON STACK
ACALL AMUL ;MULTIPLY CONSTANT AND COMPUTED VALUE
ACALL PUSHC ;PUT NEXT CONSTANT ON STACK
ACALL AADD ;ADD IT TO THE OLD VALUE
CLR A ;CHECK TO SEE IF DONE
MOVC A,@A+DPTR
CJNE A,#0FFH,POLY1 ;LOOP UNTIL DONE
;
AMUL: LCALL FP_BASE+6
AJMP FPTST
;
;*************************************************************
;
RV: ; Reduce a value for Trig and A**X functions
;
; value = (value/x - INT(value/x)) * x
;
;*************************************************************
;
ACALL C_T2 ;COPY TOS TO T2
ACALL ADIV ;TOS = TOS/TEMP2
ACALL AABS ;MAKE THE TOS A POSITIVE NUMBER
MOV MT1,A ;SAVE THE SIGN
ACALL CSTAKA2 ;COPY THE STACK TWICE
ACALL IFIX ;PUT THE NUMBER IN R3:R1
PUSH R3B0 ;SAVE R3
MOV MT2,R1 ;SAVE THE LS BYTE IN MT2
ACALL AINT ;MAKE THE TOS AN INTEGER
ACALL ASUB ;TOS = TOS/T2 - INT(TOS/T2)
ACALL P_T2 ;TOS = T2
ACALL AMUL ;TOS = T2*(TOS/T2 - INT(TOS/T2)
POP R3B0 ;RESTORE R3
RET ;EXIT
;
newpage
;**************************************************************
;
; TAN
;
;**************************************************************
;
ATAN: ACALL CSTAKA ;DUPLACATE STACK
ACALL ASIN ;TOS = SIN(X)
ACALL SWAP_ASTKA ;TOS = X
ACALL ACOS ;TOS = COS(X)
AJMP ADIV ;TOS = SIN(X)/COS(X)
;
STRIP: ACALL SETREG ;SETUP R0
MOV R3,#1 ;LOOP COUNT
AJMP AI2-1 ;WASTE THE LSB
;
;************************************************************
;
; ARC TAN
;
;************************************************************
;
AATAN: ACALL AABS
MOV MT1,A ;SAVE THE SIGN
ACALL SETREG ;GET THE EXPONENT
ADD A,#7FH ;BIAS THE EXPONENT
MOV UBIT,C ;SAVE CARRY STATUS
JNC $+4 ;SEE IF > 1
ACALL RECIP ;IF > 1, TAKE RECIP
MOV DPTR,#ATTAB ;SET UP TO CALCULATE THE POLY
ACALL POLYC ;CALCULATE THE POLY
JNB UBIT,SIN0 ;JUMP IF NOT SET
ACALL ANEG ;MAKE X POLY NEGATIVE
ACALL POTWO ;SUBTRACT PI/2
ACALL AADD
;
SIN0: MOV A,MT1 ;GET THE SIGN
JZ SRT
AJMP ANEG
;
newpage
;*************************************************************
;
; FCOMP - COMPARE 0FFFFH TO TOS
;
;*************************************************************
;
FCMP: ACALL CSTAKA ;COPY THE STACK
ACALL FSTK ;MAKE THE TOS = 0FFFFH
ACALL SWAP_ASTKA ;NOW COMPARE IS 0FFFFH - X
;
CMPLK: JMP FP_BASE+4 ;DO THE COMPARE
;
;*************************************************************
;
DEC_ASTKA: ;Push ARG STACK and check for underflow
;
;*************************************************************
;
MOV A,#-FPSIZ
ADD A,ASTKA
CJNE A,#LO(TM_TOP+6),$+3
JC E4YY
MOV ASTKA,A
MOV R1,A
MOV R3,#ASTKAH
;
SRT: RET
;
E4YY: MOV DPTR,#EXA
AJMP FPTS ;ARG STACK ERROR
;
;
AXTAL3: ACALL PUSHC ;PUSH CONSTANT, THEN MULTIPLY
ACALL AMUL
;
; Fall thru to IFIX
;
newpage
;***************************************************************
;
IFIX: ; Convert a floating point number to an integer, put in R3:R1
;
;***************************************************************
;
CLR A ;RESET THE START
MOV R3,A
MOV R1,A
MOV R0,ASTKA ;GET THE ARG STACK
MOV P2,#ASTKAH
MOVX A,@R0 ;READ EXPONENT
CLR C
SUBB A,#81H ;BASE EXPONENT
MOV R4,A ;SAVE IT
DEC R0 ;POINT AT SIGN
MOVX A,@R0 ;GET THE SIGN
JNZ SQ_ERR ;ERROR IF NEGATIVE
JC INC_ASTKA ;EXIT IF EXPONENT IS < 81H
INC R4 ;ADJUST LOOP COUNTER
MOV A,R0 ;BUMP THE POINTER REGISTER
SUBB A,#FPSIZ-1
MOV R0,A
;
I2: INC R0 ;POINT AT DIGIT
MOVX A,@R0 ;GET DIGIT
SWAP A ;FLIP
CALL FP_BASE+20 ;ACCUMULATE
JC SQ_ERR
DJNZ R4,$+4
SJMP INC_ASTKA
MOVX A,@R0 ;GET DIGIT
CALL FP_BASE+20
JC SQ_ERR
DJNZ R4,I2
;
newpage
;************************************************************
;
INC_ASTKA: ; Pop the ARG STACK and check for overflow
;
;************************************************************
;
MOV A,#FPSIZ ;NUMBER TO POP
SJMP SETREG+1
;
SETREG: CLR A ;DON'T POP ANYTHING
MOV R0,ASTKA
MOV R2,#ASTKAH
MOV P2,R2
ADD A,R0
JC E4YY
MOV ASTKA,A
MOVX A,@R0
A_D: RET
;
;************************************************************
;
; EBIAS - Bias a number for E to the X calculations
;
;************************************************************
;
EBIAS: ACALL PUSH_ONE
ACALL RV
CJNE R3,#00H,SQ_ERR ;ERROR IF R3 <> 0
ACALL C_T2 ;TEMP 2 GETS FRACTIONS
ACALL INC_ASTKA
ACALL POP_T1
ACALL PUSH_ONE
;
AELP: MOV A,MT2
JNZ AEL1
;
MOV A,MT1
JZ A_D
MOV DPTR,#FPT2-1
MOVX @DPTR,A ;MAKE THE FRACTIONS NEGATIVE
;
RECIP: ACALL PUSH_ONE
ACALL SWAP_ASTKA
AJMP ADIV
;
AEL1: DEC MT2
ACALL PUSH_T1
ACALL AMUL
SJMP AELP
;
SQ_ERR: LJMP E3XX ;LINK TO BAD ARG
;
newpage
;************************************************************
;
; SQUARE ROOT
;
;************************************************************
;
ASQR: ACALL AABS ;GET THE SIGN
JNZ SQ_ERR ;ERROR IF NEGATIVE
ACALL C_T2 ;COPY VARIABLE TO T2
ACALL POP_T1 ;SAVE IT IN T1
MOV R0,#LO(FPT1)
MOVX A,@R0 ;GET EXPONENT
JZ ALN-2 ;EXIT IF ZERO
ADD A,#128 ;BIAS THE EXPONENT
JNC SQR1 ;SEE IF < 80H
RR A
ANL A,#127
SJMP SQR2
;
SQR1: CPL A ;FLIP BITS
INC A
RR A
ANL A,#127 ;STRIP MSB
CPL A
INC A
;
SQR2: ADD A,#128 ;BIAS EXPONENT
MOVX @R0,A ;SAVE IT
;
; NEWGUESS = ( X/OLDGUESS + OLDGUESS) / 2
;
SQR4: ACALL P_T2 ;TOS = X
ACALL PUSH_T1 ;PUT NUMBER ON STACK
ACALL ADIV ;TOS = X/GUESS
ACALL PUSH_T1 ;PUT ON AGAIN
ACALL AADD ;TOS = X/GUESS + GUESS
ACALL DBTWO ;TOS = ( X/GUESS + GUESS ) / 2
ACALL TEMP_COMP ;SEE IF DONE
JNB F0,SQR4
;
AJMP PUSH_T1 ;PUT THE ANSWER ON THE STACK
;
newpage
;*************************************************************
;
; NATURAL LOG
;
;*************************************************************
;
ALN: ACALL AABS ;MAKE SURE THAT NUM IS POSITIVE
JNZ SQ_ERR ;ERROR IF NOT
MOV MT2,A ;CLEAR FOR LOOP
INC R0 ;POINT AT EXPONENT
MOVX A,@R0 ;READ THE EXPONENT
JZ SQ_ERR ;ERROR IF EXPONENT IS ZERO
CJNE A,#81H,$+3 ;SEE IF NUM >= 1
MOV UBIT,C ;SAVE CARRY STATUS
JC $+4 ;TAKE RECIP IF >= 1
ACALL RECIP
;
; Loop to reduce
;
ALNL: ACALL CSTAKA ;COPY THE STACK FOR COMPARE
ACALL PUSH_ONE ;COMPARE NUM TO ONE
ACALL CMPLK
JNC ALNO ;EXIT IF DONE
ACALL SETREG ;GET THE EXPONENT
ADD A,#85H ;SEE HOW BIG IT IS
JNC ALN11 ;BUMP BY EXP(11) IF TOO SMALL
ACALL PLNEXP ;PUT EXP(1) ON STACK
MOV A,#1 ;BUMP COUNT
;
ALNE: ADD A,MT2
JC SQ_ERR
MOV MT2,A
ACALL AMUL ;BIAS THE NUMBER
SJMP ALNL
;
ALN11: MOV DPTR,#EXP11 ;PUT EXP(11) ON STACK
ACALL PUSHC
MOV A,#11
SJMP ALNE
;
newpage
ALNO: ACALL C_T2 ;PUT NUM IN TEMP 2
ACALL PUSH_ONE ;TOS = 1
ACALL ASUB ;TOS = X - 1
ACALL P_T2 ;TOS = X
ACALL PUSH_ONE ;TOS = 1
ACALL AADD ;TOS = X + 1
ACALL ADIV ;TOS = (X-1)/(X+1)
MOV DPTR,#LNTAB ;LOG TABLE
ACALL POLYC
INC DPTR ;POINT AT LN(10)
ACALL PUSHC
ACALL AMUL
MOV A,MT2 ;GET THE COUNT
ACALL TWO_R2 ;PUT IT ON THE STACK
ACALL ASUB ;INT - POLY
ACALL STRIP
JNB UBIT,AABS
;
LN_D: RET
;
;*************************************************************
;
TEMP_COMP: ; Compare FPTEMP1 to TOS, FPTEMP1 gets TOS
;
;*************************************************************
;
ACALL PUSH_T1 ;SAVE THE TEMP
ACALL SWAP_ASTKA ;TRADE WITH THE NEXT NUMBER
ACALL CSTAKA ;COPY THE STACK
ACALL POP_T1 ;SAVE THE NEW NUMBER
JMP FP_BASE+4 ;DO THE COMPARE
;
newpage
AETOX: ACALL PLNEXP ;EXP(1) ON TOS
ACALL SWAP_ASTKA ;X ON TOS
;
AEXP: ;EXPONENTIATION
;
ACALL EBIAS ;T1=BASE,T2=FRACTIONS,TOS=INT MULTIPLIED
MOV DPTR,#FPT2 ;POINT AT FRACTIONS
MOVX A,@DPTR ;READ THE EXP OF THE FRACTIONS
JZ LN_D ;EXIT IF ZERO
ACALL P_T2 ;TOS = FRACTIONS
ACALL PUSH_T1 ;TOS = BASE
ACALL SETREG ;SEE IF BASE IS ZERO
JZ $+4
ACALL ALN ;TOS = LN(BASE)
ACALL AMUL ;TOS = FRACTIONS * LN(BASE)
ACALL PLNEXP ;TOS = EXP(1)
ACALL SWAP_ASTKA ;TOS = FRACTIONS * LN(BASE)
ACALL EBIAS ;T2 = FRACTIONS, TOS = INT MULTIPLIED
MOV MT2,#00H ;NOW CALCULATE E**X
ACALL PUSH_ONE
ACALL CSTAKA
ACALL POP_T1 ;T1 = 1
;
AEXL: ACALL P_T2 ;TOS = FRACTIONS
ACALL AMUL ;TOS = FRACTIONS * ACCUMLATION
INC MT2 ;DO THE DEMONIATOR
MOV A,MT2
ACALL TWO_R2
ACALL ADIV
ACALL CSTAKA ;SAVE THE ITERATION
ACALL PUSH_T1 ;NOW ACCUMLATE
ACALL AADD ;ADD ACCUMLATION
ACALL TEMP_COMP
JNB F0,AEXL ;LOOP UNTIL DONE
;
ACALL INC_ASTKA
ACALL PUSH_T1
ACALL AMUL ;LAST INT MULTIPLIED
;
MU1: AJMP AMUL ;FIRST INT MULTIPLIED
;
newpage
;***************************************************************
;
; integer operator - INT
;
;***************************************************************
;
AINT: ACALL SETREG ;SET UP THE REGISTERS, CLEAR CARRY
SUBB A,#129 ;SUBTRACT EXPONENT BIAS
JNC AI1 ;JUMP IF ACC > 81H
;
; Force the number to be a zero
;
ACALL INC_ASTKA ;BUMP THE STACK
;
P_Z: MOV DPTR,#ZRO ;PUT ZERO ON THE STACK
AJMP PUSHC
;
AI1: SUBB A,#7
JNC AI3
CPL A
INC A
MOV R3,A
DEC R0 ;POINT AT SIGN
;
AI2: DEC R0 ;NOW AT LSB'S
MOVX A,@R0 ;READ BYTE
ANL A,#0F0H ;STRIP NIBBLE
MOVX @R0,A ;WRITE BYTE
DJNZ R3,$+3
RET
CLR A
MOVX @R0,A ;CLEAR THE LOCATION
DJNZ R3,AI2
;
AI3: RET ;EXIT
;
newpage
;***************************************************************
;
AABS: ; Absolute value - Make sign of number positive
; return sign in ACC
;
;***************************************************************
;
ACALL ANEG ;CHECK TO SEE IF + OR -
JNZ ALPAR ;EXIT IF NON ZERO, BECAUSE THE NUM IS
MOVX @R0,A ;MAKE A POSITIVE SIGN
RET
;
;***************************************************************
;
ASGN: ; Returns the sign of the number 1 = +, -1 = -
;
;***************************************************************
;
ACALL INC_ASTKA ;POP STACK, GET EXPONENT
JZ P_Z ;EXIT IF ZERO
DEC R0 ;BUMP TO SIGN
MOVX A,@R0 ;GET THE SIGN
MOV R7,A ;SAVE THE SIGN
ACALL PUSH_ONE ;PUT A ONE ON THE STACK
MOV A,R7 ;GET THE SIGN
JZ ALPAR ;EXIT IF ZERO
;
; Fall thru to ANEG
;
;***************************************************************
;
ANEG: ; Flip the sign of the number on the tos
;
;***************************************************************
;
ACALL SETREG
DEC R0 ;POINT AT THE SIGN OF THE NUMBER
JZ ALPAR ;EXIT IF ZERO
MOVX A,@R0
XRL A,#01H ;FLIP THE SIGN
MOVX @R0,A
XRL A,#01H ;RESTORE THE SIGN
;
ALPAR: RET
;
newpage
;***************************************************************
;
ACBYTE: ; Read the ROM
;
;***************************************************************
;
ACALL IFIX ;GET EXPRESSION
CALL X31DP ;PUT R3:R1 INTO THE DP
CLR A
MOVC A,@A+DPTR
AJMP TWO_R2
;
;***************************************************************
;
ADBYTE: ; Read internal memory
;
;***************************************************************
;
ACALL IFIX ;GET THE EXPRESSION
CALL R3CK ;MAKE SURE R3 = 0
MOV A,@R1
AJMP TWO_R2
;
;***************************************************************
;
AXBYTE: ; Read external memory
;
;***************************************************************
;
ACALL IFIX ;GET THE EXPRESSION
MOV P2,R3
MOVX A,@R1
AJMP TWO_R2
;
newpage
;***************************************************************
;
; The relational operators - EQUAL (=)
; GREATER THAN (>)
; LESS THAN (<)
; GREATER THAN OR EQUAL (>=)
; LESS THAN OR EQUAL (<=)
; NOT EQUAL (<>)
;
;***************************************************************
;
AGT: ACALL CMPLK
ORL C,F0 ;SEE IF EITHER IS A ONE
JC P_Z
;
FSTK: MOV DPTR,#FS
AJMP PUSHC
;
FS: DB 85H
DB 00H
DB 00H
DB 50H
DB 53H
DB 65H
;
ALT: ACALL CMPLK
CPL C
SJMP AGT+4
;
AEQ: ACALL CMPLK
MOV C,F0
SJMP ALT+2
;
ANE: ACALL CMPLK
CPL F0
SJMP AEQ+2
;
AGE: ACALL CMPLK
SJMP AGT+4
;
ALE: ACALL CMPLK
ORL C,F0
SJMP ALT+2
;
newpage
;***************************************************************
;
ARND: ; Generate a random number
;
;***************************************************************
;
MOV DPTR,#RCELL ;GET THE BINARY SEED
CALL L31DPI
MOV A,R1
CLR C
RRC A
MOV R0,A
MOV A,#6
RRC A
ADD A,R1
XCH A,R0
ADDC A,R3
MOV R2,A
DEC DPL ;SAVE THE NEW SEED
ACALL S20DP
ACALL TWO_EY
ACALL FSTK
;
ADIV: LCALL FP_BASE+8
AJMP FPTST
;
newpage
;***************************************************************
;
SONERR: ; ON ERROR Statement
;
;***************************************************************
;
LCALL INTERR ;GET THE LINE NUMBER
SETB ON_ERR
MOV DPTR,#ERRNUM ;POINT AT THR ERROR LOCATION
SJMP S20DP
;
;
;**************************************************************
;
SONEXT: ; ON EXT1 Statement
;
;**************************************************************
;
LCALL INTERR
SETB INTBIT
ORL IE,#10000100B ;ENABLE INTERRUPTS
MOV DPTR,#INTLOC
;
S20DP: MOV A,R2 ;SAVE R2:R0 @DPTR
MOVX @DPTR,A
INC DPTR
MOV A,R0
MOVX @DPTR,A
RET
;
newpage
;***************************************************************
;
; CASTAK - Copy and push another top of arg stack
;
;***************************************************************
;
CSTAKA2:ACALL CSTAKA ;COPY STACK TWICE
;
CSTAKA: ACALL SETREG ;SET UP R2:R0
SJMP PUSH_T1+4
;
PLNEXP: MOV DPTR,#EXP1
;
;***************************************************************
;
; PUSHC - Push constant on to the arg stack
;
;***************************************************************
;
PUSHC: ACALL DEC_ASTKA
MOV P2,R3
MOV R3,#FPSIZ ;LOOP COUNTER
;
PCL: CLR A ;SET UP A
MOVC A,@A+DPTR ;LOAD IT
MOVX @R1,A ;SAVE IT
INC DPTR ;BUMP POINTERS
DEC R1
DJNZ R3,PCL ;LOOP
;
SETB ARGF
RET ;EXIT
;
PUSH_ONE:;
;
MOV DPTR,#FPONE
AJMP PUSHC
;
newpage
;
POP_T1:
;
MOV R3,#HI(FPT1)
MOV R1,#LO(FPT1)
JMP POPAS
;
PUSH_T1:
;
MOV R0,#LO(FPT1)
MOV R2,#HI(FPT1)
LJMP PUSHAS
;
P_T2: MOV R0,#LO(FPT2)
SJMP $-7 ;JUMP TO PUSHAS
;
;****************************************************************
;
SWAP_ASTKA: ; SWAP TOS<>TOS-1
;
;****************************************************************
;
ACALL SETREG ;SET UP R2:R0 AND P2
MOV A,#FPSIZ ;PUT TOS+1 IN R1
MOV R2,A
ADD A,R0
MOV R1,A
;
S_L: MOVX A,@R0
MOV R3,A
MOVX A,@R1
MOVX @R0,A
MOV A,R3
MOVX @R1,A
DEC R1
DEC R0
DJNZ R2,S_L
RET
;
newpage
;
C_T2: ACALL SETREG ;SET UP R2:R0
MOV R3,#HI(FPT2)
MOV R1,#LO(FPT2) ;TEMP VALUE
;
; Fall thru
;
;***************************************************************
;
; VARCOP - Copy a variable from R2:R0 to R3:R1
;
;***************************************************************
;
VARCOP: MOV R4,#FPSIZ ;LOAD THE LOOP COUNTER
;
V_C: MOV P2,R2 ;SET UP THE PORTS
MOVX A,@R0 ;READ THE VALUE
MOV P2,R3 ;PORT TIME AGAIN
MOVX @R1,A ;SAVE IT
ACALL DEC3210 ;BUMP POINTERS
DJNZ R4,V_C ;LOOP
RET ;EXIT
;
PIPI: MOV DPTR,#PIE
AJMP PUSHC
;
newpage
;***************************************************************
;
; The logical operators ANL, ORL, XRL, NOT
;
;***************************************************************
;
AANL: ACALL TWOL ;GET THE EXPRESSIONS
MOV A,R3 ;DO THE AND
ANL A,R7
MOV R2,A
MOV A,R1
ANL A,R6
SJMP TWO_EX
;
AORL: ACALL TWOL ;SAME THING FOR OR
MOV A,R3
ORL A,R7
MOV R2,A
MOV A,R1
ORL A,R6
SJMP TWO_EX
;
ANOT: ACALL FSTK ;PUT 0FFFFH ON THE STACK
;
AXRL: ACALL TWOL
MOV A,R3
XRL A,R7
MOV R2,A
MOV A,R1
XRL A,R6
SJMP TWO_EX
;
TWOL: ACALL IFIX
MOV R7,R3B0
MOV R6,R1B0
AJMP IFIX
;
newpage
;*************************************************************
;
AGET: ; READ THE BREAK BYTE AND PUT IT ON THE ARG STACK
;
;*************************************************************
;
MOV DPTR,#GTB ;GET THE BREAK BYTE
MOVX A,@DPTR
JBC GTRD,TWO_R2
CLR A
;
TWO_R2: MOV R2,#00H ;ACC GOES TO STACK
;
;
TWO_EX: MOV R0,A ;R2:ACC GOES TO STACK
;
;
TWO_EY: SETB ARGF ;R2:R0 GETS PUT ON THE STACK
JMP FP_BASE+24 ;DO IT
;
newpage
;*************************************************************
;
; Put directs onto the stack
;
;**************************************************************
;
A_IE: MOV A,IE ;IE
SJMP TWO_R2
;
A_IP: MOV A,IP ;IP
SJMP TWO_R2
;
ATIM0: MOV R2,TH0 ;TIMER 0
MOV R0,TL0
SJMP TWO_EY
;
ATIM1: MOV R2,TH1 ;TIMER 1
MOV R0,TL1
SJMP TWO_EY
;
ATIM2: DB 0AAH ;MOV R2 DIRECT OP CODE
DB 0CDH ;T2 HIGH
DB 0A8H ;MOV R0 DIRECT OP CODE
DB 0CCH ;T2 LOW
SJMP TWO_EY ;TIMER 2
;
AT2CON: DB 0E5H ;MOV A,DIRECT OPCODE
DB 0C8H ;T2CON LOCATION
SJMP TWO_R2
;
ATCON: MOV A,TCON ;TCON
SJMP TWO_R2
;
ATMOD: MOV A,TMOD ;TMOD
SJMP TWO_R2
;
ARCAP2: DB 0AAH ;MOV R2, DIRECT OP CODE
DB 0CBH ;RCAP2H LOCATION
DB 0A8H ;MOV R0, DIRECT OP CODE
DB 0CAH ;R2CAPL LOCATION
SJMP TWO_EY
;
AP1: MOV A,P1 ;GET P1
SJMP TWO_R2 ;PUT IT ON THE STACK
;
APCON: DB 0E5H ;MOV A, DIRECT OP CODE
DB 87H ;ADDRESS OF PCON
SJMP TWO_R2 ;PUT PCON ON THE STACK
;
newpage
;***************************************************************
;
;THIS IS THE LINE EDITOR
;
;TAKE THE PROCESSED LINE IN IBUF AND INSERT IT INTO THE
;BASIC TEXT FILE.
;
;***************************************************************
;
LJMP NOGO ;CAN'T EDIT A ROM
;
LINE: MOV A,BOFAH
CJNE A,#HI(PSTART),LINE-3
CALL G4 ;GET END ADDRESS FOR EDITING
MOV R4,DPL
MOV R5,DPH
MOV R3,TEMP5 ;GET HIGH ORDER IBLN
MOV R1,TEMP4 ;LOW ORDER IBLN
;
CALL GETLIN ;FIND THE LINE
JNZ INSR ;INSERT IF NOT ZERO, ELSE APPEND
;
;APPEND THE LINE AT THE END
;
MOV A,TEMP3 ;PUT IBCNT IN THE ACC
CJNE A,#4H,$+4 ;SEE IF NO ENTRY
RET ;RET IF NO ENTRY
;
ACALL FULL ;SEE IF ENOUGH SPACE LEFT
MOV R2,R5B0 ;PUT END ADDRESS A INTO TRANSFER
MOV R0,R4B0 ;REGISTERS
ACALL IMOV ;DO THE BLOCK MOVE
;
UE: MOV A,#EOF ;SAVE EOF CHARACTER
AJMP TBR
;
;INSERT A LINE INTO THE FILE
;
INSR: MOV R7,A ;SAVE IT IN R7
CALL TEMPD ;SAVE INSERATION ADDRESS
MOV A,TEMP3 ;PUT THE COUNT LENGTH IN THE ACC
JC LTX ;JUMP IF NEW LINE # NOT = OLD LINE #
CJNE A,#04H,$+4 ;SEE IF NULL
CLR A
;
SUBB A,R7 ;SUBTRACT LINE COUNT FROM ACC
JZ LIN1 ;LINE LENGTHS EQUAL
JC GTX ;SMALLER LINE
;
newpage
;
;EXPAND FOR A NEW LINE OR A LARGER LINE
;
LTX: MOV R7,A ;SAVE A IN R7
MOV A,TEMP3 ;GET THE COUNT IN THE ACC
CJNE A,#04H,$+4 ;DO NO INSERTATION IF NULL LINE
RET ;EXIT IF IT IS
;
MOV A,R7 ;GET THE COUNT BACK - DELTA IN A
ACALL FULL ;SEE IF ENOUGH MEMORY NEW EOFA IN R3:R1
CALL DTEMP ;GET INSERATION ADDRESS
ACALL NMOV ;R7:R6 GETS (EOFA)-DPTR
CALL X3120
MOV R1,R4B0 ;EOFA LOW
MOV R3,R5B0 ;EOFA HIGH
INC R6 ;INCREMENT BYTE COUNT
CJNE R6,#00,$+4 ;NEED TO BUMP HIGH BYTE?
INC R7
;
ACALL RMOV ;GO DO THE INSERTION
SJMP LIN1 ;INSERT THE CURRENT LINE
;
GTX: CPL A ;FLIP ACC
INC A ;TWOS COMPLEMENT
CALL ADDPTR ;DO THE ADDITION
ACALL NMOV ;R7:R6 GETS (EOFA)-DPTR
MOV R1,DPL ;SET UP THE REGISTERS
MOV R3,DPH
MOV R2,TEMP5 ;PUT INSERTATION ADDRESS IN THE RIGHT REG
MOV R0,TEMP4
JZ $+4 ;IF ACC WAS ZERO FROM NMOV, JUMP
ACALL LMOV ;IF NO ZERO DO A LMOV
;
ACALL UE ;SAVE NEW END ADDRESS
;
LIN1: MOV R2,TEMP5 ;GET THE INSERTATION ADDRESS
MOV R0,TEMP4
MOV A,TEMP3 ;PUT THE COUNT LENGTH IN ACC
CJNE A,#04H,IMOV ;SEE IF NULL
RET ;EXIT IF NULL
newpage
;***************************************************************
;
;INSERT A LINE AT ADDRESS R2:R0
;
;***************************************************************
;
IMOV: CLR A ;TO SET UP
MOV R1,#LO(IBCNT) ;INITIALIZE THE REGISTERS
MOV R3,A
MOV R6,TEMP3 ;PUT THE BYTE COUNT IN R6 FOR LMOV
MOV R7,A ;PUT A 0 IN R7 FOR LMOV
;
;***************************************************************
;
;COPY A BLOCK FROM THE BEGINNING
;
;R2:R0 IS THE DESTINATION ADDRESS
;R3:R1 IS THE SOURCE ADDRESS
;R7:R6 IS THE COUNT REGISTER
;
;***************************************************************
;
LMOV: ACALL TBYTE ;TRANSFER THE BYTE
ACALL INC3210 ;BUMP THE POINTER
ACALL DEC76 ;BUMP R7:R6
JNZ LMOV ;LOOP
RET ;GO BACK TO CALLING ROUTINE
;
INC3210:INC R0
CJNE R0,#00H,$+4
INC R2
;
INC R1
CJNE R1,#00H,$+4
INC R3
RET
;
newpage
;***************************************************************
;
;COPY A BLOCK STARTING AT THE END
;
;R2:R0 IS THE DESTINATION ADDRESS
;R3:R1 IS THE SOURCE ADDRESS
;R6:R7 IS THE COUNT REGISTER
;
;***************************************************************
;
RMOV: ACALL TBYTE ;TRANSFER THE BYTE
ACALL DEC3210 ;DEC THE LOCATIONS
ACALL DEC76 ;BUMP THE COUNTER
JNZ RMOV ;LOOP
;
DEC_R: NOP ;CREATE EQUAL TIMING
RET ;EXIT
;
DEC3210:DEC R0 ;BUMP THE POINTER
CJNE R0,#0FFH,$+4 ;SEE IF OVERFLOWED
DEC R2 ;BUMP THE HIGH BYTE
DEC R1 ;BUMP THE POINTER
CJNE R1,#0FFH,DEC_R ;SEE IF OVERFLOWED
DEC R3 ;CHANGE THE HIGH BYTE
RET ;EXIT
;
;***************************************************************
;
;TBYTE - TRANSFER A BYTE
;
;***************************************************************
;
TBYTE: MOV P2,R3 ;OUTPUT SOURCE REGISTER TO PORT
MOVX A,@R1 ;PUT BYTE IN ACC
;
TBR: MOV P2,R2 ;OUTPUT DESTINATION TO PORT
MOVX @R0,A ;SAVE THE BYTE
RET ;EXIT
;
newpage
;***************************************************************
;
;NMOV - R7:R6 = END ADDRESS - DPTR
;
;ACC GETS CLOBBERED
;
;***************************************************************
;
NMOV: MOV A,R4 ;THE LOW BYTE OF EOFA
CLR C ;CLEAR THE CARRY FOR SUBB
SUBB A,DPL ;SUBTRACT DATA POINTER LOW
MOV R6,A ;PUT RESULT IN R6
MOV A,R5 ;HIGH BYTE OF EOFA
SUBB A,DPH ;SUBTRACT DATA POINTER HIGH
MOV R7,A ;PUT RESULT IN R7
ORL A,R6 ;SEE IF ZERO
RET ;EXIT
;
;***************************************************************
;
;CHECK FOR A FILE OVERFLOW
;LEAVES THE NEW END ADDRESS IN R3:R1
;A HAS THE INCREASE IN SIZE
;
;***************************************************************
;
FULL: ADD A,R4 ;ADD A TO END ADDRESS
MOV R1,A ;SAVE IT
CLR A
ADDC A,R5 ;ADD THE CARRY
MOV R3,A
MOV DPTR,#VARTOP ;POINT AT VARTOP
;
FUL1: CALL DCMPX ;COMPARE THE TWO
JC FULL-1 ;OUT OF ROOM
;
TB: MOV DPTR,#E5X ;OUT OF MEMORY
AJMP FPTS
;
newpage
;***************************************************************
;
; PP - Preprocesses the line in IBUF back into IBUF
; sets F0 if no line number
; leaves the correct length of processed line in IBCNT
; puts the line number in IBLN
; wastes the text address TXAL and TXAH
;
;***************************************************************
;
PP: ACALL T_BUF ;TXA GETS IBUF
CALL INTGER ;SEE IF A NUMBER PRESENT
CALL TEMPD ;SAVE THE INTEGER IN TEMP5:TEMP4
MOV F0,C ;SAVE INTEGER IF PRESENT
MOV DPTR,#IBLN ;SAVE THE LINE NUMBER, EVEN IF NONE
ACALL S20DP
MOV R0,TXAL ;TEXT POINTER
MOV R1,#LO(IBUF) ;STORE POINTER
;
; Now process the line back into IBUF
;
PPL: CLR ARGF ;FIRST PASS DESIGNATOR
MOV DPTR,#TOKTAB ;POINT DPTR AT LOOK UP TABLE
;
PPL1: MOV R5B0,R0 ;SAVE THE READ POINTER
CLR A ;ZERO A FOR LOOKUP
MOVC A,@A+DPTR ;GET THE TOKEN
MOV R7,A ;SAVE TOKEN IN CASE OF MATCH
;
PPL2: MOVX A,@R0 ;GET THE USER CHARACTER
MOV R3,A ;SAVE FOR REM
CJNE A,#'a',$+3
JC PPX ;CONVERT LOWER TO UPPER CASE
CJNE A,#('z'+1),$+3
JNC PPX
CLR ACC.5
;
PPX: MOV R2,A
MOVX @R0,A ;SAVE UPPER CASE
INC DPTR ;BUMP THE LOOKUP POINTER
CLR A
MOVC A,@A+DPTR
CJNE A,R2B0,PPL3 ;LEAVE IF NOT THE SAME
INC R0 ;BUMP THE USER POINTER
SJMP PPL2 ;CONTINUE TO LOOP
;
PPL3: JB ACC.7,PPL6 ;JUMP IF FOUND MATCH
JZ PPL6 ;USER MATCH
;
;
; Scan to the next TOKTAB entry
;
PPL4: INC DPTR ;ADVANCE THE POINTER
CLR A ;ZERO A FOR LOOKUP
MOVC A,@A+DPTR ;LOAD A WITH TABLE
JB ACC.7,$+6 ;KEEP SCANNING IF NOT A RESERVED WORD
JNZ PPL4
INC DPTR
;
; See if at the end of TOKTAB
;
MOV R0,R5B0 ;RESTORE THE POINTER
CJNE A,#0FFH,PPL1 ;SEE IF END OF TABLE
;
; Character not in TOKTAB, so see what it is
;
CJNE R2,#' ',PPLX ;SEE IF A SPACE
INC R0 ;BUMP USER POINTER
SJMP PPL ;TRY AGAIN
;
PPLX: JNB XBIT,PPLY ;EXTERNAL TRAP
JB ARGF,PPLY
SETB ARGF ;SAYS THAT THE USER HAS TABLE
LCALL 2078H ;SET UP POINTER
AJMP PPL1
;
PPLY: ACALL PPL7 ;SAVE CHARACTER, EXIT IF A CR
CJNE A,#'"',PPL ;SEE IF QUOTED STRING, START AGAIN IF NOT
;
; Just copy a quoted string
;
ACALL PPL7 ;SAVE THE CHARACTER, TEST FOR CR
CJNE A,#'"',$-2 ;IS THERE AN ENDQUOTE, IF NOT LOOP
SJMP PPL ;DO IT AGAIN IF ENDQUOTE
;
PPL6: MOV A,R7 ;GET THE TOKEN
ACALL PPL9+1 ;SAVE THE TOKEN
CJNE A,#T_REM,PPL ;SEE IF A REM TOKEN
MOV A,R3
ACALL PPL7+1 ;WASTE THE REM STATEMENT
ACALL PPL7 ;LOOP UNTIL A CR
SJMP $-2
;
PPL7: MOVX A,@R0 ;GET THE CHARACTER
CJNE A,#CR,PPL9 ;FINISH IF A CR
POP R0B0 ;WASTE THE CALLING STACK
POP R0B0
MOVX @R1,A ;SAVE CR IN MEMORY
INC R1 ;SAVE A TERMINATOR
MOV A,#EOF
MOVX @R1,A
MOV A,R1 ;SUBTRACT FOR LENGTH
SUBB A,#4
MOV TEMP3,A ;SAVE LENGTH
MOV R1,#LO(IBCNT) ;POINT AT BUFFER COUNT
;
PPL9: INC R0
MOVX @R1,A ;SAVE THE CHARACTER
INC R1 ;BUMP THE POINTERS
RET ;EXIT TO CALLING ROUTINE
;
;
;***************************************************************
;
;DEC76 - DECREMENT THE REGISTER PAIR R7:R6
;
;ACC = ZERO IF R7:R6 = ZERO ; ELSE ACC DOES NOT
;
;***************************************************************
;
DEC76: DEC R6 ;BUMP R6
CJNE R6,#0FFH,$+4 ;SEE IF RAPPED AROUND
DEC R7
MOV A,R7 ;SEE IF ZERO
ORL A,R6
RET ;EXIT
;
;***************************************************************
;
; MTOP - Get or Put the top of assigned memory
;
;***************************************************************
;
PMTOP: MOV DPTR,#MEMTOP
CALL L20DPI
AJMP TWO_EY ;PUT R2:R0 ON THE STACK
;
newpage
;*************************************************************
;
; AXTAL - Crystal value calculations
;
;*************************************************************
;
AXTAL0: MOV DPTR,#XTALV ;CRYSTAL VALUE
ACALL PUSHC
;
AXTAL1: ACALL CSTAKA2 ;COPY CRYSTAL VALUE TWICE
ACALL CSTAKA
MOV DPTR,#PTIME ;PROM TIMER
ACALL AXTAL2
MOV DPTR,#PROGS
ACALL S31L
MOV DPTR,#IPTIME ;IPROM TIMER
ACALL AXTAL2
MOV DPTR,#IPROGS
ACALL S31L
MOV DPTR,#TTIME ;CLOCK CALCULATION
ACALL AXTAL3
MOV A,R1
CPL A
INC A
MOV SAVE_T,A
MOV R3,#HI(CXTAL)
MOV R1,#LO(CXTAL)
JMP POPAS
;
AXTAL2: ACALL AXTAL3
;
CBIAS: ;Bias the crystal calculations
;
MOV A,R1 ;GET THE LOW COUNT
CPL A ;FLIP IT FOR TIMER LOAD
ADD A,#15 ;BIAS FOR CALL AND LOAD TIMES
MOV R1,A ;RESTORE IT
MOV A,R3 ;GET THE HIGH COUNT
CPL A ;FLIP IT
ADDC A,#00H ;ADD THE CARRY
MOV R3,A ;RESTORE IT
RET
;
newpage
include bas52.pwm ; ******AA
newpage
;LNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLN
;
LNTAB: ; Natural log lookup table
;
;LNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLNLN
;
DB 80H
DB 00H
DB 71H
DB 37H
DB 13H
DB 19H
;
DB 7FH
DB 00H
DB 76H
DB 64H
DB 37H
DB 94H
;
DB 80H
DB 00H
DB 07H
DB 22H
DB 75H
DB 17H
;
DB 80H
DB 00H
DB 52H
DB 35H
DB 93H
DB 28H
;
DB 80H
DB 00H
DB 71H
DB 91H
DB 85H
DB 86H
;
DB 0FFH
;
DB 81H
DB 00H
DB 51H
DB 58H
DB 02H
DB 23H
;
newpage
;SINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSIN
;
SINTAB: ; Sin lookup table
;
;SINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSINSIN
;
DB 128-9
DB 00H
DB 44H
DB 90H
DB 05H
DB 16H
;
DB 128-7
DB 01H
DB 08H
DB 21H
DB 05H
DB 25H
;
DB 128-5
DB 00H
DB 19H
DB 73H
DB 55H
DB 27H
;
newpage
;
DB 128-3
DB 01H
DB 70H
DB 12H
DB 84H
DB 19H
;
DB 128-2
DB 00H
DB 33H
DB 33H
DB 33H
DB 83H
;
DB 128
DB 01H
DB 67H
DB 66H
DB 66H
DB 16H
;
FPONE: DB 128+1
DB 00H
DB 00H
DB 00H
DB 00H
DB 10H
;
DB 0FFH ;END OF TABLE
;
newpage
;
SBAUD: CALL AXTAL ;PUT CRYSTAL ON THE STACK
CALL EXPRB ;PUT THE NUMBER AFTER BAUD ON STACK
MOV A,#12
ACALL TWO_R2 ;TOS = 12
ACALL AMUL ;TOS = 12*BAUD
ACALL ADIV ;TOS = XTAL/(12*BAUD)
ACALL IFIX
ACALL CBIAS
MOV DPTR,#SPV
;
S31L: JMP S31DP
;
AFREE: CALL PMTOP ;PUT MTOP ON STACK
CALL G4 ;GET END ADDRESS
MOV R0,DPL
MOV R2,DPH
ACALL TWO_EY
;
ASUB: LCALL FP_BASE+2 ;DO FP SUB
AJMP FPTST
;
ALEN: CALL CCAL ;CALCULATE THE LEN OF THE SELECTED PROGRAM
MOV R2,R7B0 ;SAVE THE HIGH BYTE
MOV A,R6 ;SAVE THE LOW BYTE
AJMP TWO_EX ;PUT IT ON THE STACK
;
ATIME: MOV C,EA ;SAVE INTERRUTS
CLR EA
PUSH MILLIV ;SAVE MILLI VALUE
MOV R2,TVH ;GET THE TIMER
MOV A,TVL
MOV EA,C ;SAVE INTERRUPTS
ACALL TWO_EX ;PUT TIMER ON THE STACK
POP ACC ;GET MILLI
ACALL TWO_R2 ;PUT MILLI ON STACK
MOV A,#200
ACALL TWO_R2 ;DIVIDE MILLI BY 200
ACALL ADIV
;
AADD: LCALL FP_BASE ;DO FP ADDITION
AJMP FPTST ;CHECK FOR ERRORS
;
newpage
;**************************************************************
;
; Here are some error messages that were moved
;
;**************************************************************
;
;
E1X: DB "BAD SYNTAX",'"'
E2X: DB 128+10
DB "DIVIDE BY ZERO",'"'
;
E6X: DB "ARRAY SIZE",'"'
;
newpage
;**************************************************************
;
T_BUF: ; TXA gets IBUF
;
;**************************************************************
;
MOV TXAH,#HI(IBUF)
MOV TXAL,#LO(IBUF)
RET
;
;
;***************************************************************
;
CXFER: ; Transfer a program from rom to ram
;
;***************************************************************
;
CALL CCAL ;GET EVERYTHING SET UP
MOV R2,#HI(PSTART)
MOV R0,#LO(PSTART)
ACALL LMOV ;DO THE TRANSFER
CALL RCLEAR ;CLEAR THE MEMORY
;
; Fall thru to CRAM
;
;***************************************************************
;
CRAM: ; The command action routine - RAM - Run out of ram
;
;***************************************************************
;
CLR CONB ;CAN'T CONTINUE IF MODE CHANGE
MOV BOFAH,#HI(PSTART)
MOV BOFAL,#LO(PSTART)
;
; Fall thru to Command Processor
;
newpage
;***************************************************************
;
CMND1: ; The entry point for the command processor
;
;***************************************************************
;
LCALL SPRINT+4 ;WASTE AT AND HEX
CLR XBIT ;TO RESET IF NEEDED
CLR A
MOV DPTR,#2002H ;CHECK FOR EXTERNAL TRAP PACKAGE
MOVC A,@A+DPTR
CJNE A,#5AH,$+6
LCALL 2048H ;IF PRESENT JUMP TO LOCATION 200BH
MOV DPTR,#RDYS ;PRINT THE READY MESSAGE
CALL CRP ;DO A CR, THEN, PRINT FROM THE ROM
;
CMNDR: SETB DIRF ;SET THE DIRECT INPUT BIT
MOV SP,SPSAV ;LOAD THE STACK
ACALL CL7 ;DO A CRLF
;
CMNX: CLR GTRD ;CLEAR BREAK
MOV DPTR,#5EH ;DO RUN TRAP
MOVX A,@DPTR
XRL A,#52
JNZ $+5
LJMP CRUN
MOV R5,#'>' ;OUTPUT A PROMPT
LCALL TEROT
CALL INLINE ;INPUT A LINE INTO IBUF
CALL PP ;PRE-PROCESS THE LINE
JB F0,CMND3 ;NO LINE NUMBER
CALL LINE ;PROCESS THE LINE
LCALL LCLR
JB LINEB,CMNX ;DON'T CLEAR MEMORY IF NO NEED
SETB LINEB
LCALL RCLEAR ;CLEAR THE MEMORY
SJMP CMNX ;LOOP BACK
;
CMND3: CALL T_BUF ;SET UP THE TEXT POINTER
CALL DELTST ;GET THE CHARACTER
JZ CMNDR ;IF CR, EXIT
MOV DPTR,#CMNDD ;POINT AT THE COMMAND LOOKUP
CJNE A,#T_CMND,$+3 ;PROCESS STATEMENT IF NOT A COMMAND
JC CMND5
CALL GCI1 ;BUMP TXA
ANL A,#0FH ;STRIP MSB'S FOR LOOKUP
LCALL ISTA1 ;PROCESS COMMAND
SJMP CMNDR
;
CMND5: LJMP ILOOP ;CHECK FOR A POSSIBLE BREAK
;
;
;
;CONSTANTS
;
XTALV: DB 128+8 ; DEFAULT CRYSTAL VALUE
DB 00H
DB 00H
DB 92H
DB 05H
DB 11H
;
EXP11: DB 85H
DB 00H
DB 42H
DB 41H
DB 87H
DB 59H
;
EXP1: DB 128+1 ; EXP(1)
DB 00H
DB 18H
DB 28H
DB 18H
DB 27H
;
IPTIME: DB 128-4 ;FPROG TIMING
DB 00H
DB 00H
DB 00H
DB 75H
DB 83H
;
PIE: DB 128+1 ;PI
DB 00H
DB 26H
DB 59H
DB 41H
DB 31H ; 3.1415926
;
newpage
;***************************************************************
;
; The error messages, some have been moved
;
;***************************************************************
;
E7X: DB 128+30
DB "ARITH. UNDERFLOW",'"'
;
E5X: DB "MEMORY ALLOCATION",'"'
;
E3X: DB 128+40
DB "BAD ARGUMENT",'"'
;
EXI: DB "I-STACK",'"'
;
newpage
;***************************************************************
;
; The command action routine - CONTINUE
;
;***************************************************************
;
CCONT: MOV DPTR,#E15X
JNB CONB,ERROR ;ERROR IF CONTINUE IS NOT SET
;
CC1: ;used for input statement entry
;
MOV TXAH,INTXAH ;RESTORE TXA
MOV TXAL,INTXAL
JMP CILOOP ;EXECUTE
;
DTEMP: MOV DPH,TEMP5 ;RESTORE DPTR
MOV DPL,TEMP4
RET
;
TEMPD: MOV TEMP5,DPH
MOV TEMP4,DPL
RET
;
newpage
;**************************************************************
;
I_DL: ; IDLE
;
;**************************************************************
;
JB DIRF,E1XX ;SYNTAX ERROR IN DIRECT INPUT
CLR DACK ;ACK IDLE
;
U_ID1: DB 01000011B ;ORL DIRECT OP CODE
DB 87H ;PCON ADDRESS
DB 01H ;SET IDLE BIT
JB INTPEN,I_RET ;EXIT IF EXTERNAL INTERRUPT
JBC U_IDL,I_RET ;EXIT IF USER WANTS TO
JNB OTS,U_ID1 ;LOOP IF TIMER NOT ENABLED
LCALL T_CMP ;CHECK THE TIMER
JC U_ID1 ;LOOP IF TIME NOT BIG ENOUGH
;
I_RET: SETB DACK ;RESTORE EXECUTION
RET ;EXIT IF IT IS
;
;
;
ER0: INC DPTR ;BUMP TO TEXT
JB DIRF,ERROR0 ;CAN'T GET OUT OF DIRECT MODE
JNB ON_ERR,ERROR0 ;IF ON ERROR ISN'T SET, GO BACK
MOV DPTR,#ERRLOC ;SAVE THE ERROR CODE
CALL RC2 ;SAVE ERROR AND SET UP THE STACKS
INC DPTR ;POINT AT ERRNUM
JMP ERL4 ;LOAD ERR NUM AND EXIT
;
newpage
;
; Syntax error
;
E1XX: MOV C,DIRF ;SEE IF IN DIRECT MODE
MOV DPTR,#E1X ;ERROR MESSAGE
SJMP ERROR+1 ;TRAP ON SET DIRF
;
MOV DPTR,#EXI ;STACK ERROR
;
; Falls through
;
;***************************************************************
;
;ERROR PROCESSOR - PRINT OUT THE ERROR TYPE, CHECK TO SEE IF IN
; RUN OR COMMAND MODE, FIND AND PRINT OUT THE
; LINE NUMBER IF IN RUN MODE
;
;***************************************************************
;
ERROR: CLR C ;RESET STACK
MOV SP,SPSAV ;RESET THE STACK
LCALL SPRINT+4 ;CLEAR LINE AND AT MODE
CLR A ;SET UP TO GET ERROR CODE
MOVC A,@A+DPTR
JBC ACC.7,ER0 ;PROCESS ERROR
;
ERROR0: ACALL TEMPD ;SAVE THE DATA POINTER
JC $+5 ;NO RESET IF CARRY IS SET
LCALL RC1 ;RESET THE STACKS
CALL CRLF2 ;DO TWO CARRIAGE RET - LINE FEED
MOV DPTR,#ERS ;OUTPUT ERROR MESSAGE
CALL ROM_P
CALL DTEMP ;GET THE ERROR MESSAGE BACK
;
ERRS: CALL ROM_P ;PRINT ERROR TYPE
JNB DIRF,ER1 ;DO NOT PRINT IN LINE IF DIRF=1
;
SERR1: CLR STOPBIT ;PRINT STOP THEN EXIT, FOR LIST
JMP CMND1
;
ER1: MOV DPTR,#INS ;OUTPUT IN LINE
CALL ROM_P
;
;NOW, FIND THE LINE NUMBER
;
;
newpage
;
;
CALL DP_B ;GET THE FIRST ADDRESS OF THE PROGRAM
CLR A ;FOR INITIALIZATION
;
ER2: ACALL TEMPD ;SAVE THE DPTR
CALL ADDPTR ;ADD ACC TO DPTR
ACALL ER4 ;R3:R1 = TXA-DPTR
JC ER3 ;EXIT IF DPTR>TXA
JZ ER3 ;EXIT IF DPTR=TXA
MOVX A,@DPTR ;GET LENGTH
CJNE A,#EOF,ER2 ;SEE IF AT THE END
;
ER3: ACALL DTEMP ;PUT THE LINE IN THE DPTR
ACALL ER4 ;R3:R1 = TXA - BEGINNING OF LINE
MOV A,R1 ;GET LENGTH
ADD A,#10 ;ADD 10 TO LENGTH, DPTR STILL HAS ADR
MOV MT1,A ;SAVE THE COUNT
INC DPTR ;POINT AT LINE NUMBER HIGH BYTE
CALL PMTOP+3 ;LOAD R2:R0, PUT IT ON THE STACK
ACALL FP_BASE+14 ;OUTPUT IT
JB STOPBIT,SERR1 ;EXIT IF STOP BIT SET
CALL CRLF2 ;DO SOME CRLF'S
CALL DTEMP
CALL UPPL ;UNPROCESS THE LINE
CALL CL6 ;PRINT IT
MOV R5,#'-' ;OUTPUT DASHES, THEN AN X
ACALL T_L ;PRINT AN X IF ERROR CHARACTER FOUND
DJNZ MT1,$-4 ;LOOP UNTIL DONE
MOV R5,#'X'
ACALL T_L
AJMP SERR1
;
ER4: MOV R3,TXAH ;GET TEXT POINTER AND PERFORM SUBTRACTION
MOV R1,TXAL
JMP DUBSUB
;
newpage
;**************************************************************
;
; Interrupt driven timer
;
;**************************************************************
;
I_DR: MOV TH0,SAVE_T ;LOAD THE TIMER
XCH A,MILLIV ;SAVE A, GET MILLI COUNTER
INC A ;BUMP COUNTER
CJNE A,#200,TR ;CHECK OUT TIMER VALUE
CLR A ;FORCE ACC TO BE ZERO
INC TVL ;INCREMENT LOW TIMER
CJNE A,TVL,TR ;CHECK LOW VALUE
INC TVH ;BUMP TIMER HIGH
;
TR: XCH A,MILLIV
POP PSW
RETI
;
newpage
include bas52.clk
;***************************************************************
;
SUI: ; Statement USER IN action routine
;
;***************************************************************
;
ACALL OTST
MOV CIUB,C ;SET OR CLEAR CIUB
RET
;
;***************************************************************
;
SUO: ; Statement USER OUT action routine
;
;***************************************************************
;
ACALL OTST
MOV COUB,C
RET
;
OTST: ; Check for a one
;
LCALL GCI ;GET THE CHARACTER, CLEARS CARRY
SUBB A,#'1' ;SEE IF A ONE
CPL C ;SETS CARRY IF ONE, CLEARS IT IF ZERO
RET
;
newpage
;**************************************************************
;
; IBLK - EXECUTE USER SUPPLIED TOKEN
;
;**************************************************************
;
IBLK: JB PSW.4,IBLK-1 ;EXIT IF REGISTER BANK <> 0
JB PSW.3,IBLK-1
JBC ACC.7,$+9 ;SEE IF BIT SEVEN IS SET
MOV DPTR,#USENT ;USER ENTRY LOCATION
LJMP ISTA1
;
JB ACC.0,199FH ;FLOATING POINT INPUT
JZ T_L ;DO OUTPUT ON 80H
MOV DPTR,#FP_BASE-2
JMP @A+DPTR
;
;
;**************************************************************
;
; GET_NUM - GET A NUMBER, EITHER HEX OR FLOAT
;
;**************************************************************
;
GET_NUM:ACALL FP_BASE+10 ;SCAN FOR HEX
JNC FP_BASE+12 ;DO FP INPUT
;
ACALL FP_BASE+18 ;ASCII STRING TO R2:R0
JNZ H_RET
PUSH DPH ;SAVE THE DATA_POINTER
PUSH DPL
ACALL FP_BASE+24 ;PUT R2:R0 ON THE STACK
POP DPL ;RESTORE THE DATA_POINTER
POP DPH
CLR A ;NO ERRORS
RET ;EXIT
;
newpage
;**************************************************************
;
; WB - THE EGO MESSAGE
;
;**************************************************************
;
WB: DB 'W'+80H,'R'+80H
DB 'I'+80H,'T'+80H,'T','E'+80H,'N'+80H
DB ' ','B'+80H,'Y'+80H,' '
DB 'J'+80H,'O'+80H,'H'+80H,'N'+80H,' '+80H
DB 'K','A'+80H,'T'+80H,'A'+80H,'U'+80H
DB 'S','K'+80H,'Y'+80H
DB ", I",'N'+80H,'T'+80H,'E'+80H,'L'+80H
DB ' '+80H,'C'+80H,'O'+80H,'R'+80H,'P'+80H
DB ". 1",'9'+80H,"85"
H_RET: RET
;
newpage
ORG 1990H
;
T_L: LJMP TEROT
;
ORG 1F78H
;
CKS_I: JB CKS_B,CS_I
LJMP 401BH
;
CS_I: LJMP 2088H
;
E14X: DB "NO DATA",'"'
;
E11X: DB 128+20
DB "ARITH. OVERFLOW",'"'
;
E16X: DB "PROGRAMMING",'"'
;
E15X: DB "CAN"
DB 27H
DB "T CONTINUE",'"'
;
E10X: DB "INVALID LINE NUMBER",'"'
;
NOROM: DB "PROM MODE",'"'
;
S_N: DB "*MCS-51(tm) BASIC V1.1*",'"'
;
ORG 1FF8H
;
ERS: DB "ERROR: ",'"'
;
newpage
;***************************************************************
;
segment xdata ;External Ram
;
;***************************************************************
;
DS 4
IBCNT: DS 1 ;LENGTH OF A LINE
IBLN: DS 2 ;THE LINE NUMBER
IBUF: DS LINLEN ;THE INPUT BUFFER
CONVT: DS 15 ;CONVERSION LOCATION FOR FPIN
;
ORG 100H
;
GTB: DS 1 ;GET LOCATION
ERRLOC: DS 1 ;ERROR TYPE
ERRNUM: DS 2 ;WHERE TO GO ON AN ERROR
VARTOP: DS 2 ;TOP OF VARIABLE STORAGE
ST_ALL: DS 2 ;STORAGE ALLOCATION
MT_ALL: DS 2 ;MATRIX ALLOCATION
MEMTOP: DS 2 ;TOP OF MEMORY
RCELL: DS 2 ;RANDOM NUMBER CELL
DS FPSIZ-1
CXTAL: DS 1 ;CRYSTAL
DS FPSIZ-1
FPT1: DS 1 ;FLOATINP POINT TEMP 1
DS FPSIZ-1
FPT2: DS 1 ;FLOATING POINT TEMP 2
INTLOC: DS 2 ;LOCATION TO GO TO ON INTERRUPT
STR_AL: DS 2 ;STRING ALLOCATION
SPV: DS 2 ;SERIAL PORT BAUD RATE
TIV: DS 2 ;TIMER INTERRUPT NUM AND LOC
PROGS: DS 2 ;PROGRAM A PROM TIME OUT
IPROGS: DS 2 ;INTELLIGENT PROM PROGRAMMER TIMEOUT
TM_TOP: DS 1
include bas52.fp
END