home *** CD-ROM | disk | FTP | other *** search
-
- TITLE '8080 FIG-FORTH 1.1 VERSION A0 17SEP79'
- ;
- ; FIG-FORTH RELEASE 1.1 FOR THE 8080 PROCESSOR
- ;
- ; ALL PUBLICATIONS OF THE FORTH INTEREST GROUP
- ; ARE PUBLIC DOMAIN. THEY MAY BE FURTHER
- ; DISTRIBUTED BY THE INCLUSION OF THIS CREDIT
- ; NOTICE:
- ;
- ; THIS PUBLICATION HAS BEEN MADE AVAILABLE BY THE
- ; FORTH INTEREST GROUP
- ; P. O. BOX 1105
- ; SAN CARLOS, CA 94070
- ;
- ; IMPLEMENTATION BY:
- ; JOHN CASSADY
- ; FOR THE FORTH IMPLEMENTATION TEAM (FIT) MARCH 1979
- ; MODIFIED for CP/M by:
- ; KIM HARRIS
- ; FIT LIBRARIAN SEPT 1979
- ; ACKNOWLEDGEMENTS:
- ; GEORGE FLAMMER
- ; ROBT. D. VILLWOCK
- ; Microsystems inc. Pasadena Ca.
- ;
- ; DISTRIBUTED BY FORTH POWER
- ; P.O. BOX 2455 SAN RAFAEL CA
- ; 94902 415-471-1762
- ; SUPPORT, SYSTEMS PROGRAMMING,
- ; APPLICATIONS PROGRAMMING
- ;
- ; UNLESS OTHERWISE INDICATED, THIS DISTRIBUTION IS SUPPORTED
- ; SOLELY BY THE FORTH INTEREST GROUP (LISTINGS) AND BY
- ; FORTH POWER (MACHINE READABLE COPIES AND EXTENSIONS).
- ;
- ; COPYRIGHT AND TRADEMARK NOTICES:
- ; FORTH (C) 1974,1975,1976,1977,1978,1979 FORTH INC.
- ; FIST (C) 1979 FORTH INTERNATIONAL STANDARDS TEAM
- ; FIG, FORTH DIMENSIONS, FIT, (C) 1978, 1979 FORTH INTEREST GROUP
- ; FORTH POWER (C) 1978, 1979 MARIN SERVICES, INC.
- ; FORTH 77, FORTH 78, FORTH 79, STANDARD FORTH, FORTH INTERNATIONAL
- ; STANDARD, (C) 1976, 1977, 1978, 1979, FIST
- ; MULTI-FORTH (C) 1978, 1979 CREATIVE SOLUTIONS
- ; CP/M (C) 1979 DIGITAL RESEARCH INC.
- ; MOST ANYTHING WITH AN 11 IN IT (C) DIGITAL EQUIPMENT CORP
- ; THERE MAY BE OTHERS ! !
- ; MINIFORTH, MICROFORTH, POLYFORTH, FORTH TM FORTH INC.
- ; FIG-FORTH (C) 1978 1979 FORTH INTEREST GROUP
- ; ALL RIGHTS RESERVED EXCEPT AS EXPRESSLY INDICATED !
- ;
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;
- ; UPDATES, PATCHES, BUG REPORTS, EXTENSIONS
- ; FOR THIS SOFTWARE IN FORTH DIMENSIONS
- ; NEWSLETTER OF FORTH INTEREST GROUP (FIG)
- ; 6 issues $5.00 includes fig membership
- ;
- ; DOCUMENTATION FROM FIG or FORTH POWER
- ;
- ; FORTH PRIMER (240pp) Richard Stevens
- ; KITT PEAK NATIONAL OBSERVATORY $20.00
- ;
- ; FORTH IMPLEMENTATION TEAM LANGUAGE MODEL, EDITOR SOURCE,
- ; LANGUAGE GLOSSARY, AND IMPLEMENTATION GUIDE $10.00
- ;
- ; FORTH FOR MICROCOMPUTERS by JOHN S JAMES
- ; reprint from DDJ #25 $2.00
- ;
- ; FORTH POCKET PROGRAMMERS CARD FREE W/ S.A.S.E.
- ;
- ; SOURCE CODE FOR TI990, 6502, 6800, PDP11, PACE,
- ; 8080 (included here) $10.00/ LISTING
- ;
- ; DOCUMENTATION FROM FIG
- ;
- ; USING FORTH by ELIZABETH RATHER (200pp)
- ; FORTH INC. 1979 $20.00
- ;
- ; DOCUMENTATION FROM FORTH POWER
- ;
- ;
- ; CP/M MULTI-FORTH USERS MANUAL $20.00
- ; FORTH 79 INTERNATIONAL STANDARD
- ;
- ; CP/M 8080 FORTH BY FIG 8" DISKETT IBM STD.
- ; WITH EDITOR AND ASSEMBLER, COPY AND PRINT,
- ; AND USERS GUIDE $65.00
- ;
- ; also on 5" CP/M, 5 & 8 Northstar DOS
- ;
- ; CP/M Multi-Forth, Full 79 International
- ; Standard with extensions, Strings, Prom burner,
- ; Real time clock, VIDEO EDITOR, UTILITIES
- ; A PROFESSIONAL LEVEL PRODUCT $150.00
- ; includes manual
- ;
- ; PDP 11 FORTH by JOHN S. JAMES
- ; 8" RX01 diskett or 9 track 800 bpi DOS tape
- ; runs under OS or stand alone
- ; WITH USERS GUIDE $150.00
- ;
- ; FIG TRS 80 FORTH cassette or diskette
- ; WRITE FOR PRICES
- ;
- ; APPLE FORTH BY CapN' SOFTWARE $40.00
- ; EASYWRITER (word processor for APPLE
- ; by CapN' SOFTWARE) $100.00
- ;
- ; APPLE FORTH BY UNIVERSITY OF UTRECHT,
- ; includes floating pt and many extensions
- ; A PROFESSIONAL LEVEL PRODUCT $100.00
- ;
- ; FORTH FOR MICROPROSSOR DEVELOPMENT SYSTEMS,
- ; FORTH FOR D.G., VAX 11, INTERDATA, Series 1,
- ; C.A., HONEYWELL LEVEL 6, and others, Write for prices
- ;
- ; DOCUMENTATION FROM CALTECH
- ; CALTECH FORTH MANUAL $6.00
- ; CAL TECH BOOKSTORE PASADENA CA
- ; by MARTIN S. EWING 100pp postpaid
- ;
- ; CALL FOR PAPERS, ARTICLES, SPEAKERS: FOR FORTH DIMENSIONS
- ; AND TRADE PUBLICATIONS SEND TO FIG. FOR SPEAKERS, WORKSHOPS,
- ; SHOWS AND CONVENTIONS CONTACT FIG. FIG SOLICITES FORTH SOFTWARE
- ; FOR INCLUSION IN THIS EFFORT.
- ; FORTH INTERNATIONAL STANDARDS TEAM (FIT)
- ; FORTH 79 INTERNATIONAL STANDARD, REQUIRED AND
- ; RESERVED WORD GLOSSARY, AND STANDARDS ACTIVITY
- ; DISTRIBUTION. $30.00 TO FIT c/o FIG or to
- ;
- ; CAROLYN ROSENBERG, FIT SECRETARY
- ; c/o FORTH INC. MANHATTAN BEACH CA.
- ;
- ;
- ;-----------------------------------------------------
- ; LABELS USED WHICH DIFFER FROM FIG-FORTH PUBLISHED
- ; 8080 LISTING 1.0:
- ;
- ; REL 1.1 REL 1.0
- ; ------- -------
- ; ANDD AND
- ; CSPP CSP
- ; ELSEE ELSE
- ; ENDD END
- ; ENDIFF ENDIF
- ; ERASEE ERASE
- ; IDO I
- ; IFF IF
- ; INN IN
- ; MODD MOD
- ; ORR OR
- ; OUTT OUT
- ; RR R
- ; RPP RP
- ; SUBB SUB
- ; XORR XOR
- ;
- ; SEE ALSO:
- ; RELEASE & VERSION NUMBERS
- ; ASCII CHARACTER EQUATES
- ; MEMORY ALLOCATION
- ; DISK INTERFACE
- ; CONSOLE & PRINTER INTERFACE
- ;
- PAGE
- ;
- ;----------------------------------------------------------
- ;
- ; RELEASE & VERSION NUMBERS
- ;
- FIGREL EQU 1 ; FIG RELEASE #
- FIGREV EQU 1 ; FIG REVISION #
- USRVER EQU 0 ; USER VERSION #
- ;
- ; ASCII CHARACTERS USED
- ;
- ABL EQU 20H ; SPACE
- ACR EQU 0DH ; CARRIAGE RETURN
- ADOT EQU 02EH ; PERIOD
- BELL EQU 07H ; (^G)
- BSIN EQU 7FH ; INPUT BACKSPACE CHR = RUBOUT
- BSOUT EQU 08H ; OUTPUT BACKSPACE (^H)
- DLE EQU 10H ; (^P)
- LF EQU 0AH ; LINE FEED
- FF EQU 0CH ; FORM FEED (^L)
- ;
- ; MEMORY ALLOCATION
- ;
- EM EQU 4000H ; TOP OF MEMORY + 1 = LIMIT
- NSCR EQU 1 ; NUMBER OF 1024 BYTE SCREENS
- KBBUF EQU 128 ; DATA BYTES PER DISK BUFFER
- US EQU 40H ; USER VARIABLES SPACE
- RTS EQU 0A0H ; RETURN STACK & TERM BUFF SPACE
- ;
- CO EQU KBBUF+4 ; DISK BUFFER + 2 HEADER + 2 TAIL
- NBUF EQU NSCR*400H/KBBUF ; NUMBER OF BUFFERS
- BUF1 EQU EM-CO*NBUF ; ADDR FIRST DISK BUFFER
- INITR0 EQU BUF1-US ; (R0)
- INITS0 EQU INITR0-RTS ; (S0)
- ;
- PAGE
- ;
- ;-------------------------------------------------------
- ;
- ORG 100H
- ORIG NOP
- JMP CLD ; VECTOR TO COLD START
- NOP
- JMP WRM ; VECTOR TO WARM START
- DB FIGREL ; FIG RELEASE #
- DB FIGREV ; FIG REVISION #
- DB USRVER ; USER VERSION #
- DB 0EH ; IMPLEMENTATION ATTRIBUTES
- DW TASK-7 ; TOPMOST WORD IN FORTH VOCABULARY
- DW BSIN ; BKSPACE CHARACTER
- DW INITR0 ; INIT (UP)
- ;<<<<<< FOLLOWING USED BY COLD;
- ; MUST BE IN SAME ORDER AS USER VARIABLES
- DW INITS0 ; INIT (S0)
- DW INITR0 ; INIT (R0)
- DW INITS0 ; INIT (TIB)
- DW 20H ; INIT (WIDTH)
- DW 0 ; INIT (WARNING)
- DW INITDP ; INIT (FENCE)
- DW INITDP ; INIT (DP)
- DW FORTH+6 ; INIT (VOC-LINK)
- ;<<<<<< END DATA USED BY COLD
- DW 5H,0B320H ; CPU NAME ( HW,LW )
- ; ( 32 BIT, BASE 36 INTEGER )
- ;
- ;
- ; +---------------+
- ; B +ORIGIN | . . .W:I.E.B.A| IMPLEMENTATION
- ; +---------------+ ATTRIBUTES
- ; ^ ^ ^ ^ ^
- ; | | | | +-- PROCESSOR ADDR =
- ; | | | | { 0 BYTE | 1 WORD }
- ; | | | +---- HIGH BYTE AT
- ; | | | { 0 LOW ADDR |
- ; | | | 1 HIGH ADDR }
- ; | | +------ ADDR MUST BE EVEN
- ; | | { 0 YES | 1 NO }
- ; | +-------- INTERPRETER IS
- ; | { 0 PRE | 1 POST }
- ; | INCREMENTING
- ; +---------- { 0 ABOVE SUFFICIENT
- ; | 1 OTHER DIFFER-
- ; ENCES EXIST }
- ;
- PAGE
- ;
- ;------------------------------------------------------
- ;
- ; FORTH REGISTERS
- ;
- ; FORTH 8080 FORTH PRESERVATION RULES
- ; ----- ---- ------------------------------------------------------------------------HH+ ; IP BC SHOULD BE PRESERVED ACROSS
- ; FORTH WORDS
- ; W DE SOMETIMES OUTPUT FROM NEXT
- ; MAY BE ALTERED BEFORE JMP'ING TO NEXT
- ; INPUT ONLY WHEN 'DPUSH' CALLED
- ; SP SP SHOULD BE USED ONLY AS DATA STACK
- ; ACROSS FORTH WORDS
- ; MAY BE USED WITHIN FORTH WORDS
- ; IF RESTORED BEFORE 'NEXT'
- ; HL NEVER OUTPUT FROM NEXT
- ; INPUT ONLY WHEN 'HPUSH' CALLED
- ;
- UP DW INITR0 ; USER AREA POINTER
- RPP DW INITR0 ; RETURN STACK POINTER
- ;
- ;------------------------------------------------------
- ;
- ; COMMENT CONVENTIONS:
- ;
- ; = MEANS "IS EQUAL TO"
- ; <- MEANS ASSIGNMENT
- ;
- ; NAME = ADDRESS OF NAME
- ; (NAME) = CONTENTS AT NAME
- ; ((NAME))= INDIRECT CONTENTS
- ;
- ; CFA = ADDRESS OF CODE FIELD
- ; LFA = ADDRESS OF LINK FIELD
- ; NFA = ADDR OF START OF NAME FIELD
- ; PFA = ADDR OF START OF PARAMETER FIELD
- ;
- ; S1 = ADDR OF 1ST WORD OF PARAMETER STACK
- ; S2 = ADDR OF 2ND WORD OF PARAMETER STACK
- ; R1 = ADDR OF 1ST WORD OF RETURN STACK
- ; R2 = ADDR OF 2ND WORD OF RETURN STACK
- ; ( ABOVE STACK POSITIONS VALID BEFORE & AFTER EXECUTION
- ; OF ANY WORD, NOT DURING. )
- ;
- ; LSB = LEAST SIGNIFICANT BIT
- ; MSB = MOST SIGNIFICANT BIT
- ; LB = LOW BYTE
- ; HB = HIGH BYTE
- ; LW = LOW WORD
- ; HW = HIGH WORD
- ; ( MAY BE USED AS SUFFIX TO ABOVE NAMES )
- ;
- PAGE
- ;
- ;---------------------------------------------------
- ; DEBUG SUPPORT
- ;
- ; TO USE:
- ; (1) SET 'BIP' TO IP VALUE TO HALT, CANNOT BE CFA
- ; (2) SET MONITOR'S BREAKPOINT PC TO 'BREAK'
- ; OR PATCH 'HLT' INSTR. THERE
- ; (3) PATCH A 'JMP TNEXT' AT 'NEXT'
- ; WHEN (IP) = (BIP) CPU WILL HALT
- ;
- BIP DW 0 ; BREAKPOINT ON IP VALUE
- ;
- TNEXT LXI H,BIP
- MOV A,M ; LB
- CMP C
- JNZ TNEXT1
- INX H
- MOV A,M ; HB
- CMP B
- JNZ TNEXT1
- BREAK NOP ; PLACE BREAKPOINT HERE
- NOP
- NOP
- TNEXT1 LDAX B
- INX B
- MOV L,A
- JMP NEXT+3
- ;
- ;--------------------------------------------------
- ;
- ; NEXT, THE FORTH ADDRESS INTERPRETER
- ; ( POST INCREMENTING VERSION )
- ;
- DPUSH PUSH D
- HPUSH PUSH H
- NEXT LDAX B ;(W) <- ((IP))
- INX B ;(IP) <- (IP)+2
- MOV L,A
- LDAX B
- INX B
- MOV H,A ; (HL) <- CFA
- NEXT1: MOV E,M ;(PC) <- ((W))
- INX H
- MOV D,M
- XCHG
- PCHL ; NOTE: (DE) = CFA+1
- ;
- PAGE
- ;
- ; FORTH DICTIONARY
- ;
- ;
- ; DICTIONARY FORMAT:
- ;
- ; BYTE
- ; ADDRESS NAME CONTENTS
- ; ------- ---- --------
- ; ( MSB=1
- ; ( P=PRECEDENCE BIT
- ; ( S=SMUDGE BIT
- ; NFA NAME FIELD 1PS<LEN> < NAME LENGTH
- ; 0<1CHAR> MSB=0, NAME'S 1ST CHAR
- ; 0<2CHAR>
- ; ...
- ; 1<LCHAR> MSB=1, NAME'S LAST CHR
- ; LFA LINK FIELD <LINKLB> = PREVIOUS WORD'S NFA
- ; <LINKHB>
- ;LABEL: CFA CODE FIELD <CODELB> = ADDR CPU CODE
- ; <CODEHB>
- ; PFA PARAMETER <1PARAM> 1ST PARAMETER BYTE
- ; FIELD <2PARAM>
- ; ...
- ;
- ;
- DP0: DB 83H ; LIT
- DB 'LI'
- DB 'T'+80H
- DW 0 ; (LFA)=0 MARKS END OF DICTIONARY
- LIT DW $+2 ;(S1) <- ((IP))
- LDAX B ; (HL) <- ((IP)) = LITERAL
- INX B ; (IP) <- (IP) + 2
- MOV L,A ; LB
- LDAX B ; HB
- INX B
- MOV H,A
- JMP HPUSH ; (S1) <- (HL)
- ;
- DB 87H ; EXECUTE
- DB 'EXECUT'
- DB 'E'+80H
- DW LIT-6
- EXEC DW $+2
- POP H ; (HL) <- (S1) = CFA
- JMP NEXT1
- ;
- DB 86H ; BRANCH
- DB 'BRANC'
- DB 'H'+80H
- DW EXEC-0AH
- BRAN DW $+2 ;(IP) <- (IP) + ((IP))
- BRAN1 MOV H,B ; (HL) <- (IP)
- MOV L,C
- MOV E,M ; (DE) <- ((IP)) = BRANCH OFFSET
- INX H
- MOV D,M
- DCX H
- DAD D ; (HL) <- (HL) + ((IP))
- MOV C,L ; (IP) <- (HL)
- MOV B,H
- JMP NEXT
- ;
- DB 87H ; 0BRANCH
- DB '0BRANC'
- DB 'H'+80H
- DW BRAN-9
- ZBRAN DW $+2
- POP H
- MOV A,L
- ORA H
- JZ BRAN1 ; IF (S1)=0 THEN BRANCH
- INX B ; ELSE SKIP BRANCH OFFSET
- INX B
- JMP NEXT
- ;
- DB 86H ; (LOOP)
- DB '(LOOP'
- DB ')'+80H
- DW ZBRAN-0AH
- XLOOP DW $+2
- LXI D,1 ; (DE) <- INCREMENT
- XLOO1 LHLD RPP ; ((HL)) = INDEX
- MOV A,M ; INDEX <- INDEX + INCR
- ADD E
- MOV M,A
- MOV E,A
- INX H
- MOV A,M
- ADC D
- MOV M,A
- INX H ; ((HL)) = LIMIT
- INR D
- DCR D
- MOV D,A ; (DE) <- NEW INDEX
- JM XLOO2 ; IF INCR > 0
- MOV A,E
- SUB M ; THEN (A) <- INDEX - LIMIT
- MOV A,D
- INX H
- SBB M
- JMP XLOO3
- XLOO2 MOV A,M ; ELSE (A) <- LIMIT - INDEX
- SUB E
- INX H
- MOV A,M
- SBB D
- ; ; IF (A) < 0
- XLOO3 JM BRAN1 ; THEN LOOP AGAIN
- INX H ; ELSE DONE
- SHLD RPP ; DISCARD R1 & R2
- INX B ; SKIP BRANCH OFFSET
- INX B
- JMP NEXT
- ;
- DB 87H ; (+LOOP)
- DB '(+LOOP'
- DB ')'+80H
- DW XLOOP-9
- XPLOO DW $+2
- POP D ; (DE) <- INCR
- JMP XLOO1
- ;
- DB 84H ; (DO)
- DB '(DO'
- DB ')'+80H
- DW XPLOO-0AH
- XDO DW $+2
- LHLD RPP ; (RP) <- (RP) - 4
- DCX H
- DCX H
- DCX H
- DCX H
- SHLD RPP
- POP D ; (R1) <- (S1) = INIT INDEX
- MOV M,E
- INX H
- MOV M,D
- POP D ; (R2) <- (S2) = LIMIT
- INX H
- MOV M,E
- INX H
- MOV M,D
- JMP NEXT
- ;
- DB 81H ; I
- DB 'I'+80H
- DW XDO-7
- IDO DW $+2 ;(S1) <- (R1) , (R1) UNCHANGED
- LHLD RPP
- MOV E,M ; (DE) <- (R1)
- INX H
- MOV D,M
- PUSH D ; (S1) <- (DE)
- JMP NEXT
- ;
- DB 85H ; DIGIT
- DB 'DIGI'
- DB 'T'+80H
- DW IDO-4
- DIGIT DW $+2
- POP H ; (L) <- (S1)LB = ASCII CHR TO BE
- ; CONVERTED
- POP D ; (DE) <- (S2) = BASE VALUE
- MOV A,E
- SUI 30H ; IF CHR > "0"
- JM DIGI2
- CPI 0AH ; AND IF CHR > "9"
- JM DIGI1
- SUI 7
- CPI 0AH ; AND IF CHR >= "A"
- JM DIGI2
- ; ; THEN VALID NUMERIC OR ALPHA CHR
- DIGI1 CMP L ; IF < BASE VALUE
- JP DIGI2
- ; ; THEN VALID DIGIT CHR
- MOV E,A ; (S2) <- (DE) = CONVERTED DIGIT
- LXI H,1 ; (S1) <- TRUE
- JMP DPUSH
- ; ; ELSE INVALID DIGIT CHR
- DIGI2 MOV L,H ; (HL) <- FALSE
- JMP HPUSH ; (S1) <- FALSE
- ;
- DB 86H ; (FIND) (2-1)FAILURE
- DB '(FIND' ; (2-3)SUCCESS
- DB ')'+80H
- DW DIGIT-8
- PFIND DW $+2
- POP D ; (DE) <- NFA
- PFIN1 POP H ; (HL) <- STRING ADDR
- PUSH H ; SAVE STRING ADDR FOR NEXT ITERATION
- LDAX D
- XRA M ; CHECK LENGTHS & SMUDGE BIT
- ANI 3FH
- JNZ PFIN4 ; LENGTHS DIFFERENT
- ; ; LENGTHS MATCH, CHECK EACH CHR
- PFIN2 INX H ; (HL) <- ADDR NEXT CHR IN STRING
- INX D ; (DE) <- ADDR NEXT CHR IN NF
- LDAX D
- XRA M ; IGNORE MSB
- ADD A
- JNZ PFIN3 ; NO MATCH
- JNC PFIN2 ; MATCH SO FAR, LOOP AGAIN
- LXI H,5 ; STRING MATCHES
- DAD D ; ((SP)) <- PFA
- XTHL
- ; ; BACK UP TO LENGTH BYTE OF NF = NFA
- PFIN6 DCX D
- LDAX D
- ORA A
- JP PFIN6 ; IF MSB = 1 THEN (DE) = NFA
- MOV E,A ; (DE) <- LENGTH BYTE
- MVI D,0
- LXI H,1 ; (HL) <- TRUE
- JMP DPUSH ; RETURN, NF FOUND
- ; ABOVE NF NOT A MATCH, TRY ANOTHER
- PFIN3 JC PFIN5 ; IF NOT END OF NF
- PFIN4 INX D ; THEN FIND END OF NF
- LDAX D
- ORA A
- JP PFIN4
- PFIN5 INX D ; (DE) <- LFA
- XCHG
- MOV E,M ; (DE) <- (LFA)
- INX H
- MOV D,M
- MOV A,D
- ORA E ; IF (LFA) <> 0
- JNZ PFIN1 ; THEN TRY PREVIOUS DICT. DEF.
- ; ; ELSE END OF DICTIONARY
- POP H ; DISCARD STRING ADDR
- LXI H,0 ; (HL) <- FALSE
- JMP HPUSH ; RETURN, NO MATCH FOUND
- ;
- DB 87H ; ENCLOSE
- DB 'ENCLOS'
- DB 'E'+80H
- DW PFIND-9
- ENCL DW $+2
- POP D ; (DE) <- (S1) = DELIMITER CHAR
- POP H ; (HL) <- (S2) = ADDR TEXT TO SCAN
- PUSH H ; (S4) <- ADDR
- MOV A,E
- MOV D,A ; (D) <- DELIM CHR
- MVI E,-1 ; INITIALIZE CHR OFFSET COUNTER
- DCX H ; (HL) <- ADDR-1
- ; ; SKIP OVER LEADING DELIMITER CHRS
- ENCL1 INX H
- INR E
- CMP M ; IF TEXT CHR = DELIM CHR
- JZ ENCL1 ; THEN LOOP AGAIN
- ; ; ELSE NON-DELIM CHR FOUND
- MVI D,0 ; (S3) <- (E) = OFFSET TO 1ST NON-DELIM
- PUSH D
- MOV D,A ; (D) <- DELIM CHR
- MOV A,M ; IF 1ST NON-DELIM = NULL
- ANA A
- JNZ ENCL2
- MVI D,0 ; THEN (S2) <- OFFSET TO BYTE
- INR E ; FOLLOWING NULL
- PUSH D
- DCR E ; (S1) <- OFFSET TO NULL
- PUSH D
- JMP NEXT
- ; ; ELSE TEXT CONTAINS NON-DELIM &
- ; NON-NULL CHR
- ENCL2 MOV A,D ; (A) <- DELIM CHR
- INX H ; (HL) <- ADDR NEXT CHR
- INR E ; (E) <- OFFSET TO NEXT CHR
- CMP M ; IF NEXT CHR <> DELIM CHR
- JZ ENCL4
- MOV A,M ; AND IF NEXT CHR <> NULL
- ANA A
- JNZ ENCL2 ; THEN CONTINUE SCAN
- ; ; ELSE CHR = NULL
- ENCL3 MVI D,0 ; (S2) <- OFFSET TO NULL
- PUSH D
- PUSH D ; (S1) <- OFFSET TO NULL
- JMP NEXT
- ; ; ELSE CHR = DELIM CHR
- ENCL4 MVI D,0 ; (S2) <- OFFSET TO BYTE
- ; FOLLOWING TEXT
- PUSH D
- INR E ; (S1) <- OFFSET TO 2 BYTES AFTER
- ; END OF WORD
- PUSH D
- JMP NEXT
- ;
- DB 84H ; EMIT
- DB 'EMI'
- DB 'T'+80H
- DW ENCL-0AH
- EMIT DW DOCOL
- DW PEMIT
- DW ONE,OUTT
- DW PSTOR,SEMIS
- ;
- DB 83H ; KEY
- DB 'KE'
- DB 'Y'+80H
- DW EMIT-7
- KEY DW $+2
- JMP PKEY
- ;
- DB 89H ; ?TERMINAL
- DB '?TERMINA'
- DB 'L'+80H
- DW KEY-6
- QTERM DW $+2
- LXI H,0
- JMP PQTER
- ;
- DB 82H ; CR
- DB 'C'
- DB 'R'+80H
- DW QTERM-0CH
- CR DW $+2
- JMP PCR
- ;
- DB 85H ; CMOVE
- DB 'CMOV'
- DB 'E'+80H
- DW CR-5
- CMOVE DW $+2
- MOV L,C ; (HL) <- (IP)
- MOV H,B
- POP B ; (BC) <- (S1) = #CHRS
- POP D ; (DE) <- (S2) = DEST ADDR
- XTHL ; (HL) <- (S3) = SOURCE ADDR
- ; ; (S1) <- (IP)
- JMP CMOV2 ; RETURN IF #CHRS = 0
- CMOV1 MOV A,M ; ((DE)) <- ((HL))
- INX H ; INC SOURCE ADDR
- STAX D
- INX D ; INC DEST ADDR
- DCX B ; DEC #CHRS
- CMOV2 MOV A,B
- ORA C
- JNZ CMOV1 ; REPEAT IF #CHRS <> 0
- POP B ; RESTORE (IP) FROM (S1)
- JMP NEXT
- ;
- DB 82H ; U* 16X16 UNSIGNED MULTIPLY
- DB 'U' ; AVG EXECUUION TIME = 994 CYCLES
- DB '*'+80H
- DW CMOVE-8
- USTAR DW $+2
- POP D ; (DE) <- MPLIER
- POP H ; (HL) <- MPCAND
- PUSH B ; SAVE IP
- MOV B,H
- MOV A,L ; (BA) <- MPCAND
- CALL MPYX ; (AHL)1 <- MPCAND.LB * MPLIER
- ; 1ST PARTIAL PRODUCT
- PUSH H ; SAVE (HL)1
- MOV H,A
- MOV A,B
- MOV B,H ; SAVE (A)1
- CALL MPYX ; (AHL)2 <- MPCAND.HB * MPLIER
- ; 2ND PARTIAL PRODUCT
- POP D ; (DE) <- (HL)1
- MOV C,D ; (BC) <- (AH)1
- ; FORM SUM OF PARTIALS:
- ; (AHL) 1
- ; + (AHL) 2
- ; --------
- ; (AHLE)
- DAD B ; (HL) <- (HL)2 + (AH)1
- ACI 0 ; (AHLE) <- (BA) * (DE)
- MOV D,L
- MOV L,H
- MOV H,A ; (HLDE) <- MPLIER * MPCAND
- POP B ; RESTORE IP
- PUSH D ; (S2) <- PRODUCT.LW
- JMP HPUSH ; (S1) <- PRODUCT.HW
- ;
- ; MULTIPLY PRIMITIVE
- ; (AHL) <- (A) * (DE)
- ; #BITS = 24 8 16
- MPYX LXI H,0 ; (HL) <- 0 = PARTIAL PRODUCT.LW
- MVI C,8 ; LOOP COUNTER
- MPYX1 DAD H ; LEFT SHIFT (AHL) 24 BITS
- RAL
- JNC MPYX2 ; IF NEXT MPLIER BIT = 1
- DAD D ; THEN ADD MPCAND
- ACI 0
- MPYX2 DCR C ; IF NOT LAST MPLIER BIT
- JNZ MPYX1 ; THEN LOOP AGAIN
- RET ; ELSE DONE
- ;
- DB 82H ; U/
- DB 'U'
- DB '/'+80H
- DW USTAR-5
- USLAS DW $+2
- LXI H,4
- DAD SP ; ((HL)) <- NUMERATOR.LW
- MOV E,M ; (DE) <- NUMER.LW
- MOV M,C ; SAVE IP ON STACK
- INX H
- MOV D,M
- MOV M,B
- POP B ; (BC) <- DENOMINATOR
- POP H ; (HL) <- NUMER.HW
- MOV A,L
- SUB C ; IF NUMER >= DENOM
- MOV A,H
- SBB B
- JC USLA1
- LXI H,0FFFFH ; THEN OVERFLOW
- LXI D,0FFFFH ; SET REM & QUOT TO MAX
- JMP USLA7
- USLA1 MVI A,16 ; LOOP COUNTER
- USLA2 DAD H ; LEFT SHIFT (HLDE) THRU CARRY
- RAL
- XCHG
- DAD H
- JNC USLA3
- INX D
- ANA A
- USLA3 XCHG ; SHIFT DONE
- RAR ; RESTORE 1ST CARRY
- PUSH PSW ; SAVE COUNTER
- JNC USLA4 ; IF CARRY = 1
- MOV A,L ; THEN (HL) <- (HL) - (BC)
- SUB C
- MOV L,A
- MOV A,H
- SBB B
- MOV H,A
- JMP USLA5
- USLA4 MOV A,L ; ELSE TRY (HL) <- (HL) - (BC)
- SUB C
- MOV L,A
- MOV A,H
- SBB B ; (HL) <- PARTIAL REMAINDER
- MOV H,A
- JNC USLA5
- DAD B ; UNDERFLOW, RESTORE
- DCX D
- USLA5 INX D ; INC QUOT
- USLA6 POP PSW ; RESTORE COUNTER
- DCR A ; IF COUNTER > 0
- JNZ USLA2 ; THEN LOOP AGAIN
- USLA7 POP B ; ELSE DONE, RESTORE IP
- PUSH H ; (S2) <- REMAINDER
- PUSH D ; (S1) <- QUOTIENT
- JMP NEXT
- ;
- DB 83H ; AND
- DB 'AN'
- DB 'D'+80H
- DW USLAS-5
- ANDD DW $+2 ; (S1) <- (S1) AND (S2)
- POP D
- POP H
- MOV A,E
- ANA L
- MOV L,A
- MOV A,D
- ANA H
- MOV H,A
- JMP HPUSH
- ;
- DB 82H ; OR
- DB 'O'
- DB 'V'+80H
- DW ANDD-6
- ORR DW $+2 ; (S1) <- (S1) OR (S2)
- POP D
- POP H
- MOV A,E
- ORA L
- MOV L,A
- MOV A,D
- ORA H
- MOV H,A
- JMP HPUSH
- ;
- DB 83H ; XOR
- DB 'XO'
- DB 'R'+80H
- DW ORR-5
- XORR DW $+2 ; (S1) <- (S1) XOR (S2)
- POP D
- POP H
- MOV A,E
- XRA L
- MOV L,A
- MOV A,D
- XRA H
- MOV H,A
- JMP HPUSH
- ;
- DB 83H ; SP@
- DB 'SP'
- DB '@'+80H
- DW XORR-6
- SPAT DW $+2 ;(S1) <- (SP)
- LXI H,0
- DAD SP ; (HL) <- (SP)
- JMP HPUSH ; (S1) <- (HL)
- ;
- DB 83H ; STACK POINTER STORE
- DB 'SP'
- DB '!'+80H
- DW SPAT-6
- SPSTO DW $+2 ;(SP) <- (S0) ( USER VARIABLE )
- LHLD UP ; (HL) <- USER VAR BASE ADDR
- LXI D,6
- DAD D ; (HL) <- S0
- MOV E,M ; (DE) <- (S0)
- INX H
- MOV D,M
- XCHG
- SPHL ; (SP) <- (S0)
- JMP NEXT
- ;
- DB 83H ; RP@
- DB 'RP'
- DB '@'+80H
- DW SPSTO-6
- RPAT DW $+2 ;(S1) <- (RP)
- LHLD RPP
- JMP HPUSH
- ;
- DB 83H ; RETURN STACK POINTER STORE
- DB 'RP'
- DB '!'+80H
- DW RPAT-6
- RPSTO DW $+2 ;(RP) <- (R0) ( USER VARIABLE )
- LHLD UP ; (HL) <- USER VARIABLE BASE ADDR
- LXI D,8
- DAD D ; (HL) <- R0
- MOV E,M ; (DE) <- (R0)
- INX H
- MOV D,M
- XCHG
- SHLD RPP ; (RP) <- (R0)
- JMP NEXT
- ;
- DB 82H ; ;S
- DB ';'
- DB 'S'+80H
- DW RPSTO-6
- SEMIS DW $+2 ;(IP) <- (R1)
- LHLD RPP
- MOV C,M ; (BC) <- (R1)
- INX H
- MOV B,M
- INX H
- SHLD RPP ; (RP) <- (RP) + 2
- JMP NEXT
- ;
- DB 85H ; LEAVE
- DB 'LEAV'
- DB 'E'+80H
- DW SEMIS-5
- LEAVE DW $+2 ;LIMIT <- INDEX
- LHLD RPP
- MOV E,M ; (DE) <- (R1) = INDEX
- INX H
- MOV D,M
- INX H
- MOV M,E ; (R2) <- (DE) = LIMIT
- INX H
- MOV M,D
- JMP NEXT
- ;
- DB 82H ; >R
- DB '>'
- DB 'R'+80H
- DW LEAVE-8
- TOR DW $+2 ;(R1) <- (S1)
- POP D ; (DE) <- (S1)
- LHLD RPP
- DCX H ; (RP) <- (RP) - 2
- DCX H
- SHLD RPP
- MOV M,E ; ((HL)) <- (DE)
- INX H
- MOV M,D
- JMP NEXT
- ;
- DB 82H ; R>
- DB 'R'
- DB '>'+80H
- DW TOR-5
- FROMR DW $+2 ;(S1) <- (R1)
- LHLD RPP
- MOV E,M ; (DE) <- (R1)
- INX H
- MOV D,M
- INX H
- SHLD RPP ; (RP) <- (RP) + 2
- PUSH D ; (S1) <- (DE)
- JMP NEXT
- ;
- DB 81H ; R
- DB 'R'+80H
- DW FROMR-5
- RR DW IDO+2
- ;
- DB 82H ; 0=
- DB '0'
- DB '='+80H
- DW RR-4
- ZEQU DW $+2
- POP H ; (HL) <- (S1)
- MOV A,L
- ORA H ; IF (HL) = 0
- LXI H,0 ; THEN (HL) <- FALSE
- JNZ ZEQU1
- INX H ; ELSE (HL) <- TRUE
- ZEQU1 JMP HPUSH ; (S1) <- (HL)
- ;
- DB 82H ; 0<
- DB '0'
- DB '<'+80H
- DW ZEQU-5
- ZLESS DW $+2
- POP H ; (HL) <- (S1)
- DAD H ; IF (HL) >= 0
- LXI H,0 ; THEN (HL) <- FALSE
- JNC ZLES1
- INX H ; ELSE (HL) <- TRUE
- ZLES1 JMP HPUSH ; (S1) <- (HL)
- ;
- DB 81H ; +
- DB '+'+80H
- DW ZLESS-5
- PLUS DW $+2 ;(S1) <- (S1) + (S2)
- POP D
- POP H
- DAD D
- JMP HPUSH
- ;
- DB 82H ; D+ (4-2)
- DB 'D' ; XLW XHW YLW YHW --- SLW SHW
- DB '+'+80H ; S4 S3 S2 S1 S2 S1
- DW PLUS-4
- DPLUS DW $+2
- LXI H,6
- DAD SP ; ((HL)) = XLW
- MOV E,M ; (DE) = XLW
- MOV M,C ; SAVE IP ON STACK
- INX H
- MOV D,M
- MOV M,B
- POP B ; (BC) <- YHW
- POP H ; (HL) <- YLW
- DAD D
- XCHG ; (DE) <- YLW + XLW = SUM.LW
- POP H ; (HL) <- XHW
- MOV A,L
- ADC C
- MOV L,A ; (HL) <- YHW + XHW + CARRY
- MOV A,H
- ADC B
- MOV H,A
- POP B ; RESTORE IP
- PUSH D ; (S2) <- SUM.LW
- JMP HPUSH ; (S1) <- SUM.HW
- ;
- DB 85H ; MINUS
- DB 'MINU'
- DB 'S'+80H
- DW DPLUS-5
- MINUS DW $+2 ;(S1) <- -(S1) ( 2'S COMPLEMENT )
- POP H
- MOV A,L
- CMA
- MOV L,A
- MOV A,H
- CMA
- MOV H,A
- INX H
- JMP HPUSH
- ;
- DB 86H ; DMINUS
- DB 'DMINU'
- DB 'S'+80H
- DW MINUS-8
- DMINU DW $+2
- POP H ; (HL) <- HW
- POP D ; (DE) <- LW
- SUB A
- SUB E ; (DE) <- 0 - (DE)
- MOV E,A
- MVI A,0
- SBB D
- MOV D,A
- MVI A,0
- SBB L ; (HL) <- 0 - (HL)
- MOV L,A
- MVI A,0
- SBB H
- MOV H,A
- PUSH D ; (S2) <- LW
- JMP HPUSH ; (S1) <- HW
- ;
- DB 84H ; OVER
- DB 'OVE'
- DB 'R'+80H
- DW DMINU-9
- OVER DW $+2
- POP D
- POP H
- PUSH H
- JMP DPUSH
- ;
- DB 84H ; DROP
- DB 'DRO'
- DB 'P'+80H
- DW OVER-7
- DROP DW $+2
- POP H
- JMP NEXT
- ;
- DB 84H ; SWAP
- DB 'SWA'
- DB 'P'+80H
- DW DROP-7
- SWAP DW $+2
- POP H
- XTHL
- JMP HPUSH
- ;
- DB 83H ; DUP
- DB 'DU'
- DB 'P'+80H
- DW SWAP-7
- DUP DW $+2
- POP H
- PUSH H
- JMP HPUSH
- ;
- DB 84H ; 2DUP
- DB '2DU'
- DB 'P'+80H
- DW DUP-6
- TDUP DW $+2
- POP H
- POP D
- PUSH D
- PUSH H
- JMP DPUSH
- ;
- DB 82H ; PLUS STORE
- DB '+'
- DB '!'+80H
- DW TDUP-7
- PSTOR DW $+2 ;((S1)) <- ((S1)) + (S2)
- POP H ; (HL) <- (S1) = ADDR
- POP D ; (DE) <- (S2) = INCR
- MOV A,M ; ((HL)) <- ((HL)) + (DE)
- ADD E
- MOV M,A
- INX H
- MOV A,M
- ADC D
- MOV M,A
- JMP NEXT
- ;
- DB 86H ; TOGGLE
- DB 'TOGGL'
- DB 'E'+80H
- DW PSTOR-5
- TOGGL DW $+2 ;((S2)) <- ((S2)) XOR (S1)LB
- POP D ; (E) <- BYTE MASK
- POP H ; (HL) <- ADDR
- MOV A,M
- XRA E
- MOV M,A ; (ADDR) <- (ADDR) XOR (E)
- JMP NEXT
- ;
- DB 81H ; @
- DB '@'+80H
- DW TOGGL-9
- AT DW $+2 ;(S1) <- ((S1))
- POP H ; (HL) <- ADDR
- MOV E,M ; (DE) <- (ADDR)
- INX H
- MOV D,M
- PUSH D ; (S1) <- (DE)
- JMP NEXT
- ;
- DB 82H ; C@
- DB 'C'
- DB '@'+80H
- DW AT-4
- CAT DW $+2 ;(S1) <- ((S1))LB
- POP H ; (HL) <- ADDR
- MOV L,M ; (HL) <- (ADDR)LB
- MVI H,0
- JMP HPUSH
- ;
- DB 82H ; 2@
- DB '2'
- DB '@'+80H
- DW CAT-5
- TAT DW $+2
- POP H ; (HL) <- ADDR HW
- LXI D,2
- DAD D ; (HL) <- ADDR LW
- MOV E,M ; (DE) <- LW
- INX H
- MOV D,M
- PUSH D ; (S2) <- LW
- LXI D,-3 ; (HL) <- ADDR HW
- DAD D
- MOV E,M ; (DE) <- HW
- INX H
- MOV D,M
- PUSH D ; (S1) <- HW
- JMP NEXT
- ;
- DB 81H ; STORE
- DB '!'+80H
- DW TAT-5
- STORE DW $+2 ;((S1)) <- (S2)
- POP H ; (HL) <- (S1) = ADDR
- POP D ; (DE) <- (S2) = VALUE
- MOV M,E ; ((HL)) <- (DE)
- INX H
- MOV M,D
- JMP NEXT
- ;
- DB 82H ; C STORE
- DB 'C'
- DB '!'+80H
- DW STORE-4
- CSTOR DW $+2 ;((S1))LB <- (S2)LB
- POP H ; (HL) <- (S1) = ADDR
- POP D ; (DE) <- (S2) = BYTE
- MOV M,E ; ((HL))LB <- (E)
- JMP NEXT
- ;
- DB 82H ; 2 STORE
- DB '2'
- DB '!'+80H
- DW CSTOR-5
- TSTOR DW $+2
- POP H ; (HL) <- ADDR
- POP D ; (DE) <- HW
- MOV M,E ; (ADDR) <- HW
- INX H
- MOV M,D
- INX H ; (HL) <- ADDR LW
- POP D ; (DE) <- LW
- MOV M,E ; (ADDR+2) <- LW
- INX H
- MOV M,D
- JMP NEXT
- ;
- DB 0C1H ; :
- DB ':'+80H
- DW TSTOR-5
- COLON DW DOCOL
- DW QEXEC
- DW SCSP
- DW CURR
- DW AT
- DW CONT
- DW STORE
- DW CREAT
- DW RBRAC
- DW PSCOD
- DOCOL LHLD RPP
- DCX H ; (R1) <- (IP)
- MOV M,B
- DCX H ; (RP) <- (RP) - 2
- MOV M,C
- SHLD RPP
- INX D ; (DE) <- CFA+2 = (W)
- MOV C,E ; (IP) <- (DE) = (W)
- MOV B,D
- JMP NEXT
- ;
- DB 0C1H ; ;
- DB ';'+80H
- DW COLON-4
- SEMI DW DOCOL
- DW QCSP
- DW COMP
- DW SEMIS
- DW SMUDG
- DW LBRAC
- DW SEMIS
- ;
- DB 84H ; NOOP
- DB 'NOO'
- DB 'P'+80H
- DW SEMI-4
- NOOP DW DOCOL
- DW SEMIS
- ;
- DB 88H ; CONSTANT
- DB 'CONSTAN'
- DB 'T'+80H
- DW NOOP-7
- CON DW DOCOL
- DW CREAT
- DW SMUDG
- DW COMMA
- DW PSCOD
- DOCON INX D ; (DE) <- PFA
- XCHG
- MOV E,M ; (DE) <- (PFA)
- INX H
- MOV D,M
- PUSH D ; (S1) <- (PFA)
- JMP NEXT
- ;
- DB 88H ; VARIABLE
- DB 'VARIABL'
- DB 'E'+80H
- DW CON-0BH
- VAR DW DOCOL
- DW CON
- DW PSCOD
- DOVAR INX D ; (DE) <- PFA
- PUSH D ; (S1) <- PFA
- JMP NEXT
- ;
- DB 84H ; USER
- DB 'USE'
- DB 'R'+80H
- DW VAR-0BH
- USER DW DOCOL
- DW CON
- DW PSCOD
- DOUSE INX D ; (DE) <- PFA
- XCHG
- MOV E,M ; (DE) <- USER VARIABLE OFFSET
- MVI D,0
- LHLD UP ; (HL) <- USER VARIABLE BASE ADDR
- DAD D ; (HL) <- (HL) + (DE)
- JMP HPUSH ; (S1) <- BASE + OFFSET
- ;
- DB 81H ; 0
- DB '0'+80H
- DW USER-7
- ZERO DW DOCON
- DW 0
- ;
- DB 81H ; 1
- DB '1'+80H
- DW ZERO-4
- ONE DW DOCON
- DW 1
- ;
- DB 81H ; 2
- DB '2'+80H
- DW ONE-4
- TWO DW DOCON
- DW 2
- ;
- DB 81H ; 3
- DB '3'+80H
- DW TWO-4
- THREE DW DOCON
- DW 3
- ;
- DB 82H ; BL
- DB 'B'
- DB 'L'+80H
- DW THREE-4
- BL DW DOCON
- DW 20H
- ;
- DB 83H ; C/L ( CHARACTERS/LINE )
- DB 'C/'
- DB 'L'+80H
- DW BL-5
- CSLL DW DOCON
- DW 64
- ;
- DB 85H ; FIRST
- DB 'FIRS'
- DB 'T'+80H
- DW CSLL-6
- FIRST DW DOCON
- DW BUF1
- ;
- DB 85H ; LIMIT
- DB 'LIMI'
- DB 'T'+80H
- DW FIRST-8
- LIMIT DW DOCON
- DW EM
- ;
- DB 85H ; B/BUF ( BYTES/BUFFER )
- DB 'B/BU'
- DB 'F'+80H
- DW LIMIT-8
- BBUF DW DOCON
- DW KBBUF
- ;
- DB 85H ; B/SCR ( BUFFERS/SCREEN )
- DB 'B/SC'
- DB 'R'+80H
- DW BBUF-8
- BSCR DW DOCON
- DW 400H/KBBUF
- ;
- DB 87H ; +ORIGIN
- DB '+ORIGI'
- DB 'N'+80H
- DW BSCR-8
- PORIG DW DOCOL
- DW LIT
- DW ORIG
- DW PLUS
- DW SEMIS
- ;
- ; USER VARIABLES
- ;
- DB 82H ; S0
- DB 'S'
- DB '0'+80H
- DW PORIG-0AH
- SZERO DW DOUSE
- DW 6
- ;
- DB 82H ; R0
- DB 'R'
- DB '0'+80H
- DW SZERO-5
- RZERO DW DOUSE
- DW 8
- ;
- DB 83H ; TIB
- DB 'TI'
- DB 'B'+80H
- DW RZERO-5
- TIB DW DOUSE
- DB 0AH
- ;
- DB 85H ; WIDTH
- DB 'WIDT'
- DB 'H'+80H
- DW TIB-6
- WIDTH DW DOUSE
- DB 0CH
- ;
- DB 87H ; WARNING
- DB 'WARNIN'
- DB 'G'+80H
- DW WIDTH-8
- WARN DW DOUSE
- DB 0EH
- ;
- DB 85H ; FENCE
- DB 'FENC'
- DB 'E'+80H
- DW WARN-0AH
- FENCE DW DOUSE
- DB 10H
- ;
- DB 82H ; DP
- DB 'D'
- DB 'P'+80H
- DW FENCE-8
- DP DW DOUSE
- DB 12H
- ;
- DB 88H ; VOC-LINK
- DB 'VOC-LIN'
- DB 'K'+80H
- DW DP-5
- VOCL DW DOUSE
- DW 14H
- ;
- DB 83H ; BLK
- DB 'BL'
- DB 'K'+80H
- DW VOCL-0BH
- BLK DW DOUSE
- DB 16H
- ;
- DB 82H ; IN
- DB 'I'
- DB 'N'+80H
- DW BLK-6
- INN DW DOUSE
- DB 18H
- ;
- DB 83H ; OUT
- DB 'OU'
- DB 'T'+80H
- DW INN-5
- OUTT DW DOUSE
- DB 1AH
- ;
- DB 83H ; SCR
- DB 'SC'
- DB 'R'+80H
- DW OUTT-6
- SCR DW DOUSE
- DB 1CH
- ;
- DB 86H ; OFFSET
- DB 'OFFSE'
- DB 'T'+80H
- DW SCR-6
- OFSET DW DOUSE
- DB 1EH
- ;
- DB 87H ; CONTEXT
- DB 'CONTEX'
- DB 'T'+80H
- DW OFSET-9
- CONT DW DOUSE
- DB 20H
- ;
- DB 87H ; CURRENT
- DB 'CURREN'
- DB 'T'+80H
- DW CONT-0AH
- CURR DW DOUSE
- DB 22H
- ;
- DB 85H ; STATE
- DB 'STAT'
- DB 'E'+80H
- DW CURR-0AH
- STATE DW DOUSE
- DB 24H
- ;
- DB 84H ; BASE
- DB 'BAS'
- DB 'E'+80H
- DW STATE-8
- BASE DW DOUSE
- DB 26H
- ;
- DB 83H ; DPL
- DB 'DP'
- DB 'L'+80H
- DW BASE-7
- DPL DW DOUSE
- DB 28H
- ;
- DB 83H ; FLD
- DB 'FL'
- DB 'D'+80H
- DW DPL-6
- FLD DW DOUSE
- DB 2AH
- ;
- DB 83H ; CSP
- DB 'CS'
- DB 'P'+80H
- DW FLD-6
- CSPP DW DOUSE
- DB 2CH
- ;
- DB 82H ; R#
- DB 'R'
- DB '#'+80H
- DW CSPP-6
- RNUM DW DOUSE
- DB 2EH
- ;
- DB 83H ; HLD
- DB 'HL'
- DB 'D'+80H
- DW RNUM-5
- HLD DW DOUSE
- DW 30H
- ;
- ; END OF USER VARIABLES
- ;
- DB 82H ; 1+
- DB '1'
- DB '+'+80H
- DW HLD-6
- ONEP DW DOCOL
- DW ONE
- DW PLUS
- DW SEMIS
- ;
- DB 82H ; 2+
- DB '2'
- DB '+'+80H
- DW ONEP-5
- TWOP DW DOCOL
- DW TWO
- DW PLUS
- DW SEMIS
- ;
- DB 84H ; HERE
- DB 'HER'
- DB 'E'+80H
- DW TWOP-5
- HERE DW DOCOL
- DW DP
- DW AT
- DW SEMIS
- ;
- DB 85H ; ALLOT
- DB 'ALLO'
- DB 'T'+80H
- DW HERE-7
- ALLOT DW DOCOL
- DW DP
- DW PSTOR
- DW SEMIS
- ;
- DB 81H ; ,
- DB ','+80H
- DW ALLOT-8
- COMMA DW DOCOL
- DW HERE
- DW STORE
- DW TWO
- DW ALLOT
- DW SEMIS
- ;
- DB 82H ; C,
- DB 'C'
- DB ','+80H
- DW COMMA-4
- CCOMM DW DOCOL
- DW HERE
- DW CSTOR
- DW ONE
- DW ALLOT
- DW SEMIS
- ;
- ; SUBROUTINE USED BY - AND <
- ; ; (HL) <- (HL) - (DE)
- SSUB MOV A,L ; LB
- SUB E
- MOV L,A
- MOV A,H ; HB
- SBB D
- MOV H,A
- RET
- ;
- DB 81H ; -
- DB '-'+80H
- DW CCOMM-5
- SUBB DW $+2
- POP D ; (DE) <- (S1) = Y
- POP H ; (HL) <- (S2) = X
- CALL SSUB
- JMP HPUSH ; (S1) <- X - Y
- ;
- DB 81H ; =
- DB '='+80H
- DW SUBB-4
- EQUAL DW DOCOL
- DW SUBB
- DW ZEQU
- DW SEMIS
- ;
- DB 81H ; <
- DB '<'+80H ; X < Y
- DW EQUAL-4 ; S2 S1
- LESS DW $+2
- POP D ; (DE) <- (S1) = Y
- POP H ; (HL) <- (S2) = X
- MOV A,D ; IF X & Y HAVE SAME SIGNS
- XRA H
- JM LES1
- CALL SSUB ; (HL) <- X - Y
- LES1 INR H ; IF (HL) >= 0
- DCR H
- JM LES2
- LXI H,0 ; THEN X >= Y
- JMP HPUSH ; (S1) <- FALSE
- LES2 LXI H,1 ; ELSE X < Y
- JMP HPUSH ; (S1) <- TRUE
- ;
- DB 82H ; U< ( UNSIGNED < )
- DB 'U'
- DB '<'+80H
- DW LESS-4
- ULESS DW DOCOL,TDUP
- DW XORR,ZLESS
- DW ZBRAN,ULES1-$ ; IF
- DW DROP,ZLESS
- DW ZEQU
- DW BRAN,ULES2-$
- ULES1 DW SUBB,ZLESS ; ELSE
- ULES2 DW SEMIS ; ENDIF
- ;
- DB 81H ; >
- DB '>'+80H
- DW ULESS-5
- GREAT DW DOCOL
- DW SWAP
- DW LESS
- DW SEMIS
- ;
- DB 83H ; ROT
- DB 'RO'
- DB 'T'+80H
- DW GREAT-4
- ROT DW $+2
- POP D
- POP H
- XTHL
- JMP DPUSH
- ;
- DB 85H ; SPACE
- DB 'SPAC'
- DB 'E'+80H
- DW ROT-6
- SPACE DW DOCOL
- DW BL
- DW EMIT
- DW SEMIS
- ;
- DB 84H ; -DUP
- DB '-DU'
- DB 'P'+80H
- DW SPACE-8
- DDUP DW DOCOL
- DW DUP
- DW ZBRAN ; IF
- DW DDUP1-$
- DW DUP ; ENDIF
- DDUP1 DW SEMIS
- ;
- DB 88H ; TRAVERSE
- DB 'TRAVERS'
- DB 'E'+80H
- DW DDUP-7
- TRAV DW DOCOL
- DW SWAP
- TRAV1 DW OVER ; BEGIN
- DW PLUS
- DW LIT
- DW 7FH
- DW OVER
- DW CAT
- DW LESS
- DW ZBRAN ; UNTIL
- DW TRAV1-$
- DW SWAP
- DW DROP
- DW SEMIS
- ;
- DB 86H ; LATEST
- DB 'LATES'
- DB 'T'+80H
- DW TRAV-0BH
- LATES DW DOCOL
- DW CURR
- DW AT
- DW AT
- DW SEMIS
- ;
- DB 83H ; LFA
- DB 'LF'
- DB 'A'+80H
- DW LATES-9
- LFA DW DOCOL
- DW LIT
- DW 4
- DW SUBB
- DW SEMIS
- ;
- DB 83H ; CFA
- DB 'CF'
- DB 'A'+80H
- DW LFA-6
- CFA DW DOCOL
- DW TWO
- DW SUBB
- DW SEMIS
- ;
- DB 83H ; NFA
- DB 'NF'
- DB 'A'+80H
- DW CFA-6
- NFA DW DOCOL
- DW LIT
- DW 5
- DW SUBB
- DW LIT
- DW -1
- DW TRAV
- DW SEMIS
- ;
- DB 83H ; PFA
- DB 'PF'
- DB 'A'+80H
- DW NFA-6
- PFA DW DOCOL
- DW ONE
- DW TRAV
- DW LIT
- DW 5
- DW PLUS
- DW SEMIS
- ;
- DB 84H ; STORE CSP
- DB '!CS'
- DB 'P'+80H
- DW PFA-6
- SCSP DW DOCOL
- DW SPAT
- DW CSPP
- DW STORE
- DW SEMIS
- ;
- DB 86H ; ?ERROR
- DB '?ERRO'
- DB 'R'+80H
- DW SCSP-7
- QERR DW DOCOL
- DW SWAP
- DW ZBRAN ; IF
- DW QERR1-$
- DW ERROR
- DW BRAN ; ELSE
- DW QERR2-$
- QERR1 DW DROP ; ENDIF
- QERR2 DW SEMIS
- ;
- DB 85H ; ?COMP
- DB '?COM'
- DB 'P'+80H
- DW QERR-9
- QCOMP DW DOCOL
- DW STATE
- DW AT
- DW ZEQU
- DW LIT
- DW 11H
- DW QERR
- DW SEMIS
- ;
- DB 85H ; ?EXEC
- DB '?EXE'
- DB 'C'+80H
- DW QCOMP-8
- QEXEC DW DOCOL
- DW STATE
- DW AT
- DW LIT
- DW 12H
- DW QERR
- DW SEMIS
- ;
- DB 86H ; ?PAIRS
- DB '?PAIR'
- DB 'S'+80H
- DW QEXEC-8
- QPAIR DW DOCOL
- DW SUBB
- DW LIT
- DW 13H
- DW QERR
- DW SEMIS
- ;
- DB 84H ; ?CSP
- DB '?CS'
- DB 'P'+80H
- DW QPAIR-9
- QCSP DW DOCOL
- DW SPAT
- DW CSPP
- DW AT
- DW SUBB
- DW LIT
- DW 14H
- DW QERR
- DW SEMIS
- ;
- DB 88H ; ?LOADING
- DB '?LOADIN'
- DB 'G'+80H
- DW QCSP-7
- QLOAD DW DOCOL
- DW BLK
- DW AT
- DW ZEQU
- DW LIT
- DW 16H
- DW QERR
- DW SEMIS
- ;
- DB 87H ; COMPILE
- DB 'COMPIL'
- DB 'E'+80H
- DW QLOAD-0BH
- COMP DW DOCOL
- DW QCOMP
- DW FROMR
- DW DUP
- DW TWOP
- DW TOR
- DW AT
- DW COMMA
- DW SEMIS
- ;
- DB 0C1H ; [
- DB '['+80H
- DW COMP-0AH
- LBRAC DW DOCOL
- DW ZERO
- DW STATE
- DW STORE
- DW SEMIS
- ;
- DB 81H ; ]
- DB ']'+80H
- DW LBRAC-4
- RBRAC DW DOCOL
- DW LIT,0C0H
- DW STATE,STORE
- DW SEMIS
- ;
- DB 86H ; SMUDGE
- DB 'SMUDG'
- DB 'E'+80H
- DW RBRAC-4
- SMUDG DW DOCOL
- DW LATES
- DW LIT
- DW 20H
- DW TOGGL
- DW SEMIS
- ;
- DB 83H ; HEX
- DB 'HE'
- DB 'X'+80H
- DW SMUDG-9
- HEX DW DOCOL
- DW LIT
- DW 10H
- DW BASE
- DW STORE
- DW SEMIS
- ;
- DB 87H ; DECIMAL
- DB 'DECIMA'
- DB 'L'+80H
- DW HEX-6
- DEC DW DOCOL
- DW LIT
- DW 0AH
- DW BASE
- DW STORE
- DW SEMIS
- ;
- DB 87H ; (;CODE)
- DB '(;CODE'
- DB ')'+80H
- DW DEC-0AH
- PSCOD DW DOCOL
- DW FROMR
- DW LATES
- DW PFA
- DW CFA
- DW STORE
- DW SEMIS
- ;
- DB 0C5H ; ;CODE
- DB ';COD'
- DB 'E'+80H
- DW PSCOD-0AH
- SEMIC DW DOCOL
- DW QCSP
- DW COMP
- DW PSCOD
- DW LBRAC
- SEMI1 DW NOOP ; ( ASSEMBLER )
- DW SEMIS
- ;
- DB 87H ; <BUILDS
- DB '<BUILD'
- DB 'S'+80H
- DW SEMIC-8
- BUILD DW DOCOL
- DW ZERO
- DW CON
- DW SEMIS
- ;
- DB 85H ; DOES>
- DB 'DOES'
- DB '>'+80H
- DW BUILD-0AH
- DOES DW DOCOL
- DW FROMR
- DW LATES
- DW PFA
- DW STORE
- DW PSCOD
- DODOE LHLD RPP ; (HL) <- (RP)
- DCX H
- MOV M,B ; (R1) <- (IP) = PFA = (SUBSTITUTE CFA)
- DCX H
- MOV M,C
- SHLD RPP ; (RP) <- (RP) - 2
- INX D ; (DE) <- PFA = (SUBSTITUTE CFA)
- XCHG
- MOV C,M ; (IP) <- (SUBSTITUTE CFA)
- INX H
- MOV B,M
- INX H
- JMP HPUSH ; (S1) <- PFA+2 = SUBSTITUTE PFA
- ;
- DB 85H ; COUNT
- DB 'COUN'
- DB 'T'+80H
- DW DOES-8
- COUNT DW DOCOL
- DW DUP
- DW ONEP
- DW SWAP
- DW CAT
- DW SEMIS
- ;
- DB 84H ; TYPE
- DB 'TYP'
- DB 'E'+80H
- DW COUNT-8
- TYPE DW DOCOL
- DW DDUP
- DW ZBRAN ; IF
- DW TYPE1-$
- DW OVER
- DW PLUS
- DW SWAP
- DW XDO ; DO
- TYPE2 DW IDO
- DW CAT
- DW EMIT
- DW XLOOP ; LOOP
- DW TYPE2-$
- DW BRAN ; ELSE
- DW TYPE3-$
- TYPE1 DW DROP ; ENDIF
- TYPE3 DW SEMIS
- ;
- DB 89H ; -TRAILING
- DB '-TRAILIN'
- DB 'G'+80H
- DW TYPE-7
- DTRAI DW DOCOL
- DW DUP
- DW ZERO
- DW XDO ; DO
- DTRA1 DW OVER
- DW OVER
- DW PLUS
- DW ONE
- DW SUBB
- DW CAT
- DW BL
- DW SUBB
- DW ZBRAN ; IF
- DW DTRA2-$
- DW LEAVE
- DW BRAN ; ELSE
- DW DTRA3-$
- DTRA2 DW ONE
- DW SUBB ; ENDIF
- DTRA3 DW XLOOP ; LOOP
- DW DTRA1-$
- DW SEMIS
- ;
- DB 84H ; (.")
- DB '(."'
- DB ')'+80H
- DW DTRAI-0CH
- PDOTQ DW DOCOL
- DW RR
- DW COUNT
- DW DUP
- DW ONEP
- DW FROMR
- DW PLUS
- DW TOR
- DW TYPE
- DW SEMIS
- ;
- DB 0C2H ; ."
- DB '.'
- DB '"'+80H
- DW PDOTQ-7
- DOTQ DW DOCOL
- DW LIT
- DW 22H
- DW STATE
- DW AT
- DW ZBRAN ; IF
- DW DOTQ1-$
- DW COMP
- DW PDOTQ
- DW WORD
- DW HERE
- DW CAT
- DW ONEP
- DW ALLOT
- DW BRAN ; ELSE
- DW DOTQ2-$
- DOTQ1 DW WORD
- DW HERE
- DW COUNT
- DW TYPE ; ENDIF
- DOTQ2 DW SEMIS
- ;
- DB 86H ; EXPECT
- DB 'EXPEC'
- DB 'T'+80H
- DW DOTQ-5
- EXPEC DW DOCOL
- DW OVER
- DW PLUS
- DW OVER
- DW XDO ; DO
- EXPE1 DW KEY
- DW DUP
- DW LIT
- DW 0EH
- DW PORIG
- DW AT
- DW EQUAL
- DW ZBRAN ; IF
- DW EXPE2-$
- DW DROP
- DW DUP
- DW IDO
- DW EQUAL
- DW DUP
- DW FROMR
- DW TWO
- DW SUBB
- DW PLUS
- DW TOR
- DW ZBRAN ; IF
- DW EXPE6-$
- DW LIT
- DW BELL
- DW BRAN ; ELSE
- DW EXPE7-$
- EXPE6 DW LIT
- DW BSOUT ; ENDIF
- EXPE7 DW BRAN ; ELSE
- DW EXPE3-$
- EXPE2 DW DUP
- DW LIT
- DW 0DH
- DW EQUAL
- DW ZBRAN ; IF
- DW EXPE4-$
- DW LEAVE
- DW DROP
- DW BL
- DW ZERO
- DW BRAN ; ELSE
- DW EXPE5-$
- EXPE4 DW DUP ; ENDIF
- EXPE5 DW IDO
- DW CSTOR
- DW ZERO
- DW IDO
- DW ONEP
- DW STORE ; ENDIF
- EXPE3 DW EMIT
- DW XLOOP ; LOOP
- DW EXPE1-$
- DW DROP
- DW SEMIS
- ;
- DB 85H ; QUERY
- DB 'QUER'
- DB 'Y'+80H
- DW EXPEC-9
- QUERY DW DOCOL
- DW TIB
- DW AT
- DW LIT
- DW 50H
- DW EXPEC
- DW ZERO
- DW INN
- DW STORE
- DW SEMIS
- ;
- DB 0C1H ; 0 (NULL)
- DB 80H
- DW QUERY-8
- NULL DW DOCOL
- DW BLK
- DW AT
- DW ZBRAN ; IF
- DW NULL1-$
- DW ONE
- DW BLK
- DW PSTOR
- DW ZERO
- DW INN
- DW STORE
- DW BLK
- DW AT
- DW BSCR
- DW ONE
- DW SUBB
- DW ANDD
- DW ZEQU
- DW ZBRAN ; IF
- DW NULL2-$
- DW QEXEC
- DW FROMR
- DW DROP ; ENDIF
- NULL2 DW BRAN ; ELSE
- DW NULL3-$
- NULL1 DW FROMR
- DW DROP ; ENDIF
- NULL3 DW SEMIS
- ;
- DB 84H ; FILL
- DB 'FIL'
- DB 'L'+80H
- DW NULL-4
- FILL DW $+2
- MOV L,C
- MOV H,B
- POP D
- POP B
- XTHL
- XCHG
- FILL1 MOV A,B ; BEGIN
- ORA C
- JZ FILL2 ; WHILE
- MOV A,L
- STAX D
- INX D
- DCX B
- JMP FILL1 ; REPEAT
- FILL2 POP B
- JMP NEXT
- ;
- DB 85H ; ERASE
- DB 'ERAS'
- DB 'E'+80H
- DW FILL-7
- ERASEE DW DOCOL
- DW ZERO
- DW FILL
- DW SEMIS
- ;
- DB 86H ; BLANKS
- DB 'BLANK'
- DB 'S'+80H
- DW ERASEE-8
- BLANK DW DOCOL
- DW BL
- DW FILL
- DW SEMIS
- ;
- DB 84H ; HOLD
- DB 'HOL'
- DB 'D'+80H
- DW BLANK-9
- HOLD DW DOCOL
- DW LIT
- DW -1
- DW HLD
- DW PSTOR
- DW HLD
- DW AT
- DW CSTOR
- DW SEMIS
- ;
- DB 83H ; PAD
- DB 'PA'
- DB 'D'+80H
- DW HOLD-7
- PAD DW DOCOL
- DW HERE
- DW LIT
- DW 44H
- DW PLUS
- DW SEMIS
- ;
- DB 84H ; WORD
- DB 'WOR'
- DB 'D'+80H
- DW PAD-6
- WORD DW DOCOL
- DW BLK
- DW AT
- DW ZBRAN ; IF
- DW WORD1-$
- DW BLK
- DW AT
- DW BLOCK
- DW BRAN ; ELSE
- DW WORD2-$
- WORD1 DW TIB
- DW AT ; ENDIF
- WORD2 DW INN
- DW AT
- DW PLUS
- DW SWAP
- DW ENCL
- DW HERE
- DW LIT
- DW 22H
- DW BLANK
- DW INN
- DW PSTOR
- DW OVER
- DW SUBB
- DW TOR
- DW RR
- DW HERE
- DW CSTOR
- DW PLUS
- DW HERE
- DW ONEP
- DW FROMR
- DW CMOVE
- DW SEMIS
- ;
- DB 88H ; (NUMBER)
- DB '(NUMBER'
- DB ')'+80H
- DW WORD-7
- PNUMB DW DOCOL
- PNUM1 DW ONEP ; BEGIN
- DW DUP
- DW TOR
- DW CAT
- DW BASE
- DW AT
- DW DIGIT
- DW ZBRAN ; WHILE
- DW PNUM2-$
- DW SWAP
- DW BASE
- DW AT
- DW USTAR
- DW DROP
- DW ROT
- DW BASE
- DW AT
- DW USTAR
- DW DPLUS
- DW DPL
- DW AT
- DW ONEP
- DW ZBRAN ; IF
- DW PNUM3-$
- DW ONE
- DW DPL
- DW PSTOR ; ENDIF
- PNUM3 DW FROMR
- DW BRAN ; REPEAT
- DW PNUM1-$
- PNUM2 DW FROMR
- DW SEMIS
- ;
- DB 86H ; NUMBER
- DB 'NUMBE'
- DB 'R'+80H
- DW PNUMB-0BH
- NUMB DW DOCOL
- DW ZERO
- DW ZERO
- DW ROT
- DW DUP
- DW ONEP
- DW CAT
- DW LIT
- DW 2DH
- DW EQUAL
- DW DUP
- DW TOR
- DW PLUS
- DW LIT
- DW -1
- NUMB1 DW DPL ; BEGIN
- DW STORE
- DW PNUMB
- DW DUP
- DW CAT
- DW BL
- DW SUBB
- DW ZBRAN ; WHILE
- DW NUMB2-$
- DW DUP
- DW CAT
- DW LIT
- DW 2EH
- DW SUBB
- DW ZERO
- DW QERR
- DW ZERO
- DW BRAN ; REPEAT
- DW NUMB1-$
- NUMB2 DW DROP
- DW FROMR
- DW ZBRAN ; IF
- DW NUMB3-$
- DW DMINU ; ENDIF
- NUMB3 DW SEMIS
- ;
- DB 85H ; -FIND (0-3) SUCCESS
- DB '-FIN' ; (0-1) FAILURE
- DB 'D'+80H
- DW NUMB-9
- DFIND DW DOCOL
- DW BL
- DW WORD
- DW HERE
- DW CONT
- DW AT
- DW AT
- DW PFIND
- DW DUP
- DW ZEQU
- DW ZBRAN ; IF
- DW DFIN1-$
- DW DROP
- DW HERE
- DW LATES
- DW PFIND ; ENDIF
- DFIN1 DW SEMIS
- ;
- DB 87H ; (ABORT)
- DB '(ABORT'
- DB ')'+80H
- DW DFIND-8
- PABOR DW DOCOL
- DW ABORT
- DW SEMIS
- ;
- DB 85H ; ERROR
- DB 'ERRO'
- DB 'R'+80H
- DW PABOR-0AH
- ERROR DW DOCOL
- DW WARN
- DW AT
- DW ZLESS
- DW ZBRAN ; IF
- DW ERRO1-$
- DW PABOR ; ENDIF
- ERRO1 DW HERE
- DW COUNT
- DW TYPE
- DW PDOTQ
- DB 2
- DB '? '
- DW MESS
- DW SPSTO
- ; CHANGE FROM FIG MODEL
- ; DW INN,AT,BLK,AT
- DW BLK,AT
- DW DDUP
- DW ZBRAN,ERRO2-$ ; IF
- DW INN,AT
- DW SWAP ; ENDIF
- ERRO2 DW QUIT
- ;
- DB 83H ; ID.
- DB 'ID'
- DB '.'+80H
- DW ERROR-8
- IDDOT DW DOCOL
- DW PAD
- DW LIT
- DW 20H
- DW LIT
- DW 5FH
- DW FILL
- DW DUP
- DW PFA
- DW LFA
- DW OVER
- DW SUBB
- DW PAD
- DW SWAP
- DW CMOVE
- DW PAD
- DW COUNT
- DW LIT
- DW 1FH
- DW ANDD
- DW TYPE
- DW SPACE
- DW SEMIS
- ;
- DB 86H ; CREATE
- DB 'CREAT'
- DB 'E'+80H
- DW IDDOT-6
- CREAT DW DOCOL
- DW DFIND
- DW ZBRAN ; IF
- DW CREA1-$
- DW DROP
- DW NFA
- DW IDDOT
- DW LIT
- DW 4
- DW MESS
- DW SPACE ; ENDIF
- CREA1 DW HERE
- DW DUP
- DW CAT
- DW WIDTH
- DW AT
- DW MIN
- DW ONEP
- DW ALLOT
- DW DUP
- DW LIT
- DW 0A0H
- DW TOGGL
- DW HERE
- DW ONE
- DW SUBB
- DW LIT
- DW 80H
- DW TOGGL
- DW LATES
- DW COMMA
- DW CURR
- DW AT
- DW STORE
- DW HERE
- DW TWOP
- DW COMMA
- DW SEMIS
- ;
- DB 0C9H ; [COMPILE]
- DB '[COMPILE'
- DB ']'+80H
- DW CREAT-9
- BCOMP DW DOCOL
- DW DFIND
- DW ZEQU
- DW ZERO
- DW QERR
- DW DROP
- DW CFA
- DW COMMA
- DW SEMIS
- ;
- DB 0C7H ; LITERAL
- DB 'LITERA'
- DB 'L'+80H
- DW BCOMP-0CH
- LITER DW DOCOL
- DW STATE
- DW AT
- DW ZBRAN ; IF
- DW LITE1-$
- DW COMP
- DW LIT
- DW COMMA ; ENDIF
- LITE1 DW SEMIS
- ;
- DB 0C8H ; DLITERAL
- DB 'DLITERA'
- DB 'L'+80H
- DW LITER-0AH
- DLITE DW DOCOL
- DW STATE
- DW AT
- DW ZBRAN ; IF
- DW DLIT1-$
- DW SWAP
- DW LITER
- DW LITER ; ENDIF
- DLIT1 DW SEMIS
- ;
- DB 86H ; ?STACK
- DB '?STAC'
- DB 'K'+80H
- DW DLITE-0BH
- QSTAC DW DOCOL
- DW SPAT
- DW SZERO
- DW AT
- DW SWAP
- DW ULESS
- DW ONE
- DW QERR
- DW SPAT
- DW HERE
- DW LIT
- DW 80H
- DW PLUS
- DW ULESS
- DW LIT
- DW 7
- DW QERR
- DW SEMIS
- ;
- DB 89H ; INTERPRET
- DB 'INTERPRE'
- DB 'T'+80H
- DW QSTAC-9
- INTER DW DOCOL
- INTE1 DW DFIND ; BEGIN
- DW ZBRAN ; IF
- DW INTE2-$
- DW STATE
- DW AT
- DW LESS
- DW ZBRAN ; IF
- DW INTE3-$
- DW CFA
- DW COMMA
- DW BRAN ; ELSE
- DW INTE4-$
- INTE3 DW CFA
- DW EXEC ; ENDIF
- INTE4 DW QSTAC
- DW BRAN ; ELSE
- DW INTE5-$
- INTE2 DW HERE
- DW NUMB
- DW DPL
- DW AT
- DW ONEP
- DW ZBRAN ; IF
- DW INTE6-$
- DW DLITE
- DW BRAN ; ELSE
- DW INTE7-$
- INTE6 DW DROP
- DW LITER ; ENDIF
- INTE7 DW QSTAC ; ENDIF
- INTE5 DW BRAN ; AGAIN
- DW INTE1-$
- ;
- DB 89H ; IMMEDIATE
- DB 'IMMEDIAT'
- DB 'E'+80H
- DW INTER-0CH
- IMMED DW DOCOL
- DW LATES
- DW LIT
- DW 40H
- DW TOGGL
- DW SEMIS
- ;
- DB 8AH ; VOCABULARY
- DB 'VOCABULAR'
- DB 'Y'+80H
- DW IMMED-0CH
- VOCAB DW DOCOL
- DW BUILD
- DW LIT
- DW 0A081H
- DW COMMA
- DW CURR
- DW AT
- DW CFA
- DW COMMA
- DW HERE
- DW VOCL
- DW AT
- DW COMMA
- DW VOCL
- DW STORE
- DW DOES
- DOVOC DW TWOP
- DW CONT
- DW STORE
- DW SEMIS
- ;
- DB 0C5H ; FORTH
- DB 'FORT'
- DB 'H'+80H
- DW VOCAB-0DH
- FORTH DW DODOE
- DW DOVOC
- DW 0A081H
- DW TASK-7 ; COLD START VALUE ONLY
- ; CHANGED EACH TIME A DEF IS APPENDED
- ; TO THE FORTH VOCABULARY
- DW 0 ; END OF VOCABULARY LIST
- ;
- DB 8BH ; DEFINITIONS
- DB 'DEFINITION'
- DB 'S'+80H
- DW FORTH-8
- DEFIN DW DOCOL
- DW CONT
- DW AT
- DW CURR
- DW STORE
- DW SEMIS
- ;
- DB 0C1H ; (
- DB '('+80H
- DW DEFIN-0EH
- PAREN DW DOCOL
- DW LIT
- DW 29H
- DW WORD
- DW SEMIS
- ;
- DB 84H ; QUIT
- DB 'QUI'
- DB 'T'+80H
- DW PAREN-4
- QUIT DW DOCOL
- DW ZERO
- DW BLK
- DW STORE
- DW LBRAC
- QUIT1 DW RPSTO ; BEGIN
- DW CR
- DW QUERY
- DW INTER
- DW STATE
- DW AT
- DW ZEQU
- DW ZBRAN ; IF
- DW QUIT2-$
- DW PDOTQ
- DB 2
- DB 'OK' ; ENDIF
- QUIT2 DW BRAN ; AGAIN
- DW QUIT1-$
- ;
- DB 85H ; ABORT
- DB 'ABOR'
- DB 'T'+80H
- DW QUIT-7
- ABORT DW DOCOL
- DW SPSTO
- DW DEC
- DW QSTAC
- DW CR
- DW DOTCPU
- DW PDOTQ
- DB 0DH
- DB 'fig-FORTH '
- DB FIGREL+30H,ADOT,FIGREV+30H
- DW FORTH
- DW DEFIN
- DW QUIT
- ;
- WRM LXI B,WRM1
- JMP NEXT
- WRM1 DW WARM
- ;
- DB 84H ; WARM
- DB 'WAR'
- DB 'M'+80H
- DW ABORT-8
- WARM DW DOCOL
- DW MTBUF
- DW ABORT
- ;
- CLD LXI B,CLD1
- LHLD ORIG+12H
- SPHL
- JMP NEXT
- CLD1 DW COLD
- ;
- DB 84H ; COLD
- DB 'COL'
- DB 'D'+80H
- DW WARM-7
- COLD DW DOCOL
- DW MTBUF
- DW ZERO,DENSTY
- DW STORE
- DW LIT,BUF1
- DW USE,STORE
- DW LIT,BUF1
- DW PREV,STORE
- DW DRZER
- DW LIT,0
- DW LIT,EPRINT
- DW STORE
- ;
- DW LIT
- DW ORIG+12H
- DW LIT
- DW UP
- DW AT
- DW LIT
- DW 6
- DW PLUS
- DW LIT
- DW 10H
- DW CMOVE
- DW LIT
- DW ORIG+0CH
- DW AT
- DW LIT
- DW FORTH+6
- DW STORE
- DW ABORT
- ;
- DB 84H ; S->D
- DB 'S->'
- DB 'D'+80H
- DW COLD-7
- STOD DW $+2
- POP D
- LXI H,0
- MOV A,D
- ANI 80H
- JZ STOD1
- DCX H
- STOD1 JMP DPUSH
- ;
- DB 82H ; +-
- DB '+'
- DB '-'+80H
- DW STOD-7
- PM DW DOCOL
- DW ZLESS
- DW ZBRAN ; IF
- DW PM1-$
- DW MINUS ; ENDIF
- PM1 DW SEMIS
- ;
- DB 83H ; D+-
- DB 'D+'
- DB '-'+80H
- DW PM-5
- DPM DW DOCOL
- DW ZLESS
- DW ZBRAN ; IF
- DW DPM1-$
- DW DMINU ; ENDIF
- DPM1 DW SEMIS
- ;
- DB 83H ; ABS
- DB 'AB'
- DB 'S'+80H
- DW DPM-6
- ABS DW DOCOL
- DW DUP
- DW PM
- DW SEMIS
- ;
- DB 84H ; DABS
- DB 'DAB'
- DB 'S'+80H
- DW ABS-6
- DABS DW DOCOL
- DW DUP
- DW DPM
- DW SEMIS
- ;
- DB 83H ; MIN
- DB 'MI'
- DB 'N'+80H
- DW DABS-7
- MIN DW DOCOL,TDUP
- DW GREAT
- DW ZBRAN ; IF
- DW MIN1-$
- DW SWAP ; ENDIF
- MIN1 DW DROP
- DW SEMIS
- ;
- DB 83H ; MAX
- DB 'MA'
- DB 'X'+80H
- DW MIN-6
- MAX DW DOCOL,TDUP
- DW LESS
- DW ZBRAN ; IF
- DW MAX1-$
- DW SWAP ; ENDIF
- MAX1 DW DROP
- DW SEMIS
- ;
- DB 82H ; M*
- DB 'M'
- DB '*'+80H
- DW MAX-6
- MSTAR DW DOCOL,TDUP
- DW XORR
- DW TOR
- DW ABS
- DW SWAP
- DW ABS
- DW USTAR
- DW FROMR
- DW DPM
- DW SEMIS
- ;
- DB 82H ; M/
- DB 'M'
- DB '/'+80H
- DW MSTAR-5
- MSLAS DW DOCOL
- DW OVER
- DW TOR
- DW TOR
- DW DABS
- DW RR
- DW ABS
- DW USLAS
- DW FROMR
- DW RR
- DW XORR
- DW PM
- DW SWAP
- DW FROMR
- DW PM
- DW SWAP
- DW SEMIS
- ;
- DB 81H ; *
- DB '*'+80H
- DW MSLAS-5
- STAR DW DOCOL
- DW MSTAR
- DW DROP
- DW SEMIS
- ;
- DB 84H ; /MOD
- DB '/MO'
- DB 'D'+80H
- DW STAR-4
- SLMOD DW DOCOL
- DW TOR
- DW STOD
- DW FROMR
- DW MSLAS
- DW SEMIS
- ;
- DB 81H ; /
- DB '/'+80H
- DW SLMOD-7
- SLASH DW DOCOL
- DW SLMOD
- DW SWAP
- DW DROP
- DW SEMIS
- ;
- DB 83H ; MOD
- DB 'MO'
- DB 'D'+80H
- DW SLASH-4
- MODD DW DOCOL
- DW SLMOD
- DW DROP
- DW SEMIS
- ;
- DB 85H ; */MOD
- DB '*/MO'
- DB 'D'+80H
- DW MODD-6
- SSMOD DW DOCOL
- DW TOR
- DW MSTAR
- DW FROMR
- DW MSLAS
- DW SEMIS
- ;
- DB 82H ; */
- DB '*'
- DB '/'+80H
- DW SSMOD-8
- SSLA DW DOCOL
- DW SSMOD
- DW SWAP
- DW DROP
- DW SEMIS
- ;
- DB 85H ; M/MOD
- DB 'M/MO'
- DB 'D'+80H
- DW SSLA-5
- MSMOD DW DOCOL
- DW TOR
- DW ZERO
- DW RR
- DW USLAS
- DW FROMR
- DW SWAP
- DW TOR
- DW USLAS
- DW FROMR
- DW SEMIS
- ;
- ; BLOCK MOVED DOWN 2 PAGES
- ;
- ;
- DB 86H ; (LINE)
- DB '(LINE'
- DB ')'+80H
- DW MSMOD-8
- PLINE DW DOCOL
- DW TOR
- DW LIT
- DW 40H
- DW BBUF
- DW SSMOD
- DW FROMR
- DW BSCR
- DW STAR
- DW PLUS
- DW BLOCK
- DW PLUS
- DW LIT
- DW 40H
- DW SEMIS
- ;
- DB 85H ; .LINE
- DB '.LIN'
- DB 'E'+80H
- DW PLINE-9
- DLINE DW DOCOL
- DW PLINE
- DW DTRAI
- DW TYPE
- DW SEMIS
- ;
- DB 87H ; MESSAGE
- DB 'MESSAG'
- DB 'E'+80H
- DW DLINE-8
- MESS DW DOCOL
- DW WARN
- DW AT
- DW ZBRAN ; IF
- DW MESS1-$
- DW DDUP
- DW ZBRAN ; IF
- DW MESS2-$
- DW LIT
- DW 4
- DW OFSET
- DW AT
- DW BSCR
- DW SLASH
- DW SUBB
- DW DLINE
- DW SPACE ; ENDIF
- MESS2 DW BRAN ; ELSE
- DW MESS3-$
- MESS1 DW PDOTQ
- DB 6
- DB 'MSG # '
- DW DOT ; ENDIF
- MESS3 DW SEMIS
- PAGE
- ;------------------------------------------
- ;
- ; 8080 PORT FETCH AND STORE
- ; ( SELF MODIFYING CODE, NOT REENTRANT )
- ;
- DB 82H ; P@ "PORT @"
- DB 'P'
- DB '@'+80H
- DW MESS-0AH
- PTAT: DW $+2
- POP D ;E <- PORT#
- LXI H,$+5
- MOV M,E
- IN 0 ;( PORT# MODIFIED )
- MOV L,A ;L <- (PORT#)
- MVI H,0
- JMP HPUSH
- ;
- DB 82H ; "PORT STORE"
- DB 'P'
- DB '!'+80H
- DW PTAT-5
- PTSTO: DW $+2
- POP D ;E <- PORT#
- LXI H,$+7
- MOV M,E
- POP H ;H <- CDATA
- MOV A,L
- OUT 0 ;( PORT# MODIFIED )
- JMP NEXT
- PAGE
- ;--------------------------------------------------
- ; CP/M DISK INTERFACE
- ;
- ; CP/M BIOS CALLS USED
- ; ( NOTE EQU'S ARE 3 LOWER THAN DOCUMENTED OFFSETS
- ; BECAUSE BASE ADDR IS BIOS+3 )
- ;
- RITSEC EQU 39
- RDSEC EQU 36
- SETDMA EQU 33
- SETSEC EQU 30
- SETTRK EQU 27
- SETDSK EQU 24
- ;
- ; DOUBLE DENSITY 8" FLOPPY CAPACITIES
- SPT2 EQU 52 ; SECTORS PER TRACK
- TRKS2 EQU 77 ; NUMBER OF TRACKS
- SPDRV2 EQU SPT2*TRKS2 ; SECTORS/DRIVE
- ; SINGLE DENSITY 8" FLOPPY CAPACITIES
- SPT1 EQU 26 ; SECTORS/TRACK
- TRKS1 EQU 77 ; # TRACKS
- SPDRV1 EQU SPT1*TRKS1 ; SECTORS/DRIVE
- ;
- BPS EQU 128 ; BYTES PER SECTOR
- MXDRV EQU 2 ; MAX # DRIVES
- ;
- ; FORTH VARIABLES AND CONSTANTS USED IN DISK INTERFACE
- ;
- DB 85H ; DRIVE ( CURRENT DRIVE # )
- DB 'DRIV'
- DB 'E'+80H
- DW PTSTO-5
- DRIVE DW DOVAR,0
- ;
- DB 83H ; SEC ( SECTOR # )
- DB 'SE'
- DB 'C'+80H
- DW DRIVE-8
- SEC: DW DOVAR
- DW 0
- ;
- DB 85H ; TRACK ( TRACK # )
- DB 'TRAC'
- DB 'K'+80H
- DW SEC-6
- TRACK: DW DOVAR,0
- ;
- DB 83H ; USE ( ADDR OF NEXT BUFFER TO USE )
- DB 'US'
- DB 'E'+80H
- DW TRACK-8
- USE: DW DOVAR
- DW BUF1
- ;
- DB 84H ; PREV
- ; ( ADDR OF PREVIOUSLY USED BUFFER )
- DB 'PRE'
- DB 'V'+80H
- DW USE-6
- PREV DW DOVAR
- DW BUF1
- ;
- DB 87H ; SEC/BLK ( # SECTORS/BLOCK )
- DB 'SEC/BL'
- DB 'K'+80H
- DW PREV-7
- SPBLK DW DOCON
- DW KBBUF/BPS
- ;
- DB 85H ; #BUFF ( NUMBER OF BUFFERS )
- DB '#BUF'
- DB 'F'+80H
- DW SPBLK-10
- NOBUF DW DOCON,NBUF
- ;
- DB 87H ; DENSITY ( 0 = SINGLE , 1 = DOUBLE )
- DB 'DENSIT'
- DB 'Y'+80H
- DW NOBUF-8
- DENSTY DW DOVAR
- DW 0
- ;
- DB 8AH ; DISK-ERROR ( DISK ERROR STATUS )
- DB 'DISK-ERRO'
- DB 'R'+80H
- DW DENSTY-10
- DSKERR DW DOVAR,0
- ;
- ; DISK INTERFACE HIGH-LEVEL ROUTINES
- ;
- DB 84H ; +BUF ( ADVANCE BUFFER )
- DB '+BU'
- DB 'F'+80H
- DW DSKERR-13
- PBUF DW DOCOL
- DW LIT,CO
- DW PLUS,DUP
- DW LIMIT,EQUAL
- DW ZBRAN,PBUF1-$
- DW DROP,FIRST
- PBUF1: DW DUP,PREV
- DW AT,SUBB
- DW SEMIS
- ;
- DB 86H ; UPDATE
- DB 'UPDAT'
- DB 'E'+80H
- DW PBUF-7
- UPDAT DW DOCOL,PREV
- DW AT,AT
- DW LIT,8000H
- DW ORR
- DW PREV,AT
- DW STORE,SEMIS
- ;
- DB 8DH ; EMPTY-BUFFERS
- DB 'EMPTY-BUFFER'
- DB 'S'+80H
- DW UPDAT-9
- MTBUF DW DOCOL,FIRST
- DW LIMIT,OVER
- DW SUBB,ERASEE
- DW SEMIS
- ;
- DB 83H ; DR0
- DB 'DR'
- DB '0'+80H
- DW MTBUF-16
- DRZER DW DOCOL,ZERO
- DW OFSET,STORE
- DW SEMIS
- ;
- DB 83H ; DR1
- DB 'DR'
- DB '1'+80H
- DW ERZER-6
- DRONE DW DOCOL
- DW DENSTY,AT
- DW ZBRAN,DRON1-$
- DW LIT,SPDRV2
- DW BRAN,DRON2-$
- DRON1 DW LIT,SPDRV1
- DRON2 DW OFSET,STORE
- DW SEMIS
- ;
- DB 86H ; BUFFER
- DB 'BUFFE'
- DB 'R'+80H
- DW DRONE-6
- BUFFE: DW DOCOL,USE
- DW AT,DUP
- DW TOR
- BUFF1 DW PBUF ; WON'T WORK IF SINGLE BUFFER
- DW ZBRAN,BUFF1-$
- DW USE,STORE
- DW RR,AT
- DW ZLESS
- DW ZBRAN,BUFF2-$
- DW RR,TWOP
- DW RR,AT
- DW LIT,7FFFH
- DW ANDD,ZERO
- DW RSLW
- BUFF2 DW RR,STORE
- DW RR,PREV
- DW STORE,FROMR
- DW TWOP,SEMIS
- ;
- DB 85H ; BLOCK
- DB 'BLOC'
- DB 'K'+80H
- DW BUFFE-9
- BLOCK DW DOCOL,OFSET
- DW AT,PLUS
- DW TOR,PREV
- DW AT,DUP
- DW AT,RR
- DW SUBB
- DW DUP,PLUS
- DW ZBRAN,BLOC1-$
- BLOC2 DW PBUF,ZEQU
- DW ZBRAN,BLOC3-$
- DW DROP,RR
- DW BUFFE,DUP
- DW RR,ONE
- DW RSLW
- DW TWO,SUBB
- BLOC3 DW DUP,AT
- DW RR,SUBB
- DW DUP,PLUS
- DW ZEQU
- DW ZBRAN,BLOC2-$
- DW DUP,PREV
- DW STORE
- BLOC1 DW FROMR,DROP
- DW TWOP,SEMIS
- ;
- ;
- ; CP/M INTERFACE ROUTINES
- ;
- ; SERVICE REQUEST
- ;
- IOS LHLD 1 ; (HL) <- BIOS TABLE ADDR+3
- DAD D ; + SERVICE REQUEST OFFSET
- PCHL ; EXECUTE REQUEST
- ; RET FUNCTION PROVIDED BY CP/M
- ;
- DB 86H ; SET-IO
- ; ( ASSIGN SECTOR, TRACK FOR BDOS )
- DB 'SET-I'
- DB 'O'+80H
- DW BLOCK-8
- SETIO: DW $+2
- PUSH B ; SAVE (IP)
- LHLD USE+2 ; (BC) <- ADDR BUFFER
- MOV B,H
- MOV C,L
- LXI D,SETDMA ; SEND BUFFER ADDR TO CP/M
- CALL IOS
- ;
- LHLD SEC+2 ; (BC) <- (SEC) = SECTOR #
- MOV C,L
- LXI D,SETSEC ; SEND SECTOR # TO CP/M
- CALL IOS
- ;
- LHLD TRACK+2 ; (BC) <- (TRACK) = TRACK #
- MOV B,H
- MOV C,L
- LXI D,SETTRK
- CALL IOS
- ;
- POP B ; RESTORE (IP)
- JMP NEXT
- ;
- DB 89H ; SET-DRIVE
- DB 'SET-DRIV'
- DB 'E'+80H
- DW SETIO-9
- SETDRV: DW $+2
- PUSH B ; SAVE (IP)
- LDA DRIVE+2 ; (C) <- (DRIVE) = DRIVE #
- MOV C,A
- LXI D,SETDSK ; SEND DRIVE # TO CP/M
- CALL IOS
- POP B ; RESTORE (IP)
- JMP NEXT
- ;
- ; T&SCALC ( CALCULATES DRIVE#, TRACK#, & SECTOR# )
- ; STACK INPUT: SECTOR-DISPLACEMENT = BLK# * SEC/BLK
- ; OUTPUT: VARIABLES DRIVE, TRACK, & SEC
- ;
- DB 87H ; T&SCALC
- DB 'T&SCAL'
- DB 'C'+80H
- DW SETDRV-12
- TSCALC: DW DOCOL,DENSTY
- DW AT
- DW ZBRAN,TSCALS-$
- DW LIT,SPDRV2
- DW SLMOD
- DW LIT,MXDRV
- DW MIN
- DW DUP,DRIVE
- DW AT,EQUAL
- DW ZBRAN,TSCAL1-$
- DW DROP
- DW BRAN,TSCAL2-$
- TSCAL1 DW DRIVE,STORE
- DW SETDRV
- TSCAL2 DW LIT,SPT2
- DW SLMOD,TRACK
- DW STORE,ONEP
- DW SEC,STORE
- DW SEMIS
- ; SINGLE DENSITY
- TSCALS DW LIT,SPDRV1
- DW SLMOD
- DW LIT,MXDRV
- DW MIN
- DW DUP,DRIVE
- DW AT,EQUAL
- DW ZBRAN,TSCAL3-$
- DW DROP
- DW BRAN,TSCAL4-$
- TSCAL3 DW DRIVE,STORE
- DW SETDRV
- TSCAL4 DW LIT,SPT1
- DW SLMOD,TRACK
- DW STORE,ONEP
- DW SEC,STORE
- DW SEMIS
- ;
- ; SEC-READ
- ; ( READ A SECTOR SETUP BY 'SET-DRIVE' & 'SETIO' )
- ;
- DB 88H ; SEC-READ
- DB 'SEC-REA'
- DB 'D'+80H
- DW TSCALC-10
- SECRD DW $+2
- PUSH B ; SAVE (IP)
- LXI D,RDSEC ; ASK CP/M TO READ SECTOR
- CALL IOS
- STA DSKERR+2 ; (DSKERR) <- ERROR STATUS
- POP B ; RESTORE (IP)
- JMP NEXT
- ;
- ; SEC-WRITE
- ; ( WRITE A SECTOR SETUP BY 'SET-DRIVE' & 'SETIO' )
- ;
- DB 89H ; SEC-WRITE
- DB 'SEC-WRIT'
- DB 'E'+80H
- DW SECRD-11
- SECWT DW $+2
- PUSH B ; SAVE (IP)
- LXI D,RITSEC ; ASK CP/M TO WRITE SECTOR
- CALL IOS
- STA DSKERR+2 ; (DSKERR) <- ERROR STATUS
- POP B ; RESTORE (IP)
- JMP NEXT
- ;
- DB 83H ; R/W ( FORTH DISK PRIMATIVE )
- DB 'R/'
- DB 'W'+80H
- DW SECWT-12
- RSLW DW DOCOL
- DW USE,AT
- DW TOR
- DW SWAP,SPBLK
- DW STAR,ROT
- DW USE,STORE
- DW SPBLK,ZERO
- DW XDO
- RSLW1 DW OVER,OVER
- DW TSCALC,SETIO
- DW ZBRAN,RSLW2-$
- DW SECRD
- DW BRAN,RSLW3-$
- RSLW2 DW SECWT
- RSLW3 DW ONEP
- DW LIT,80H
- DW USE,PSTOR
- DW XLOOP,RSLW1-$
- DW DROP,DROP
- DW FROMR,USE
- DW STORE,SEMIS
- ;
- ;--------------------------------------------------------
- ;
- ; ALTERNATIVE R/W FOR NO DISK INTERFACE
- ;
- ;RSLW DW DOCOL,DROP,DROP,DROP,SEMIS
- ;
- ;--------------------------------------------------------
- ;
- DB 85H ; FLUSH
- DB 'FLUS'
- DB 'H'+80H
- DW RSLW-6
- FLUSH DW DOCOL
- DW NOBUF,ONEP
- DW ZERO,XDO
- FLUS1 DW ZERO,BUFFE
- DW DROP
- DW XLOOP,FLUS1-$
- DW SEMIS
- ;
- DB 84H ; LOAD
- DB 'LOA'
- DB 'D'+80H
- DW FLUSH-8
- LOAD DW DOCOL,BLK
- DW AT,TOR
- DW INN,AT
- DW TOR,ZERO
- DW INN,STORE
- DW BSCR,STAR
- DW BLK,STORE ; BLK <- SCR * B/SCR
- DW INTER ; INTERPRET FROM OTHER SCREEN
- DW FROMR,INN
- DW STORE
- DW FROMR,BLK
- DW STORE
- DW SEMIS
- ;
- DB 0C3H ; -->
- DB '--'
- DB '>'+80H
- DW LOAD-7
- ARROW DW DOCOL
- DW QLOAD
- DW ZERO
- DW INN
- DW STORE
- DW BSCR
- DW BLK
- DW AT
- DW OVER
- DW MODD
- DW SUBB
- DW BLK
- DW PSTOR
- DW SEMIS
- ;
- PAGE
- ;-------------------------------------------------
- ;
- ; CP/M CONSOLE & PRINTER INTERFACE
- ;
- ; CP/M BIOS CALLS USED
- ; ( NOTE: BELOW OFFSETS ARE 3 LOWER THAN CP/M
- ; DOCUMENTATION SINCE BASE ADDR = BIOS+3 )
- ;
- KCSTAT EQU 3 ; CONSOLE STATUS
- KCIN EQU 6 ; CONSOLE INPUT
- KCOUT EQU 9 ; CONSOLE OUTPUT
- KPOUT EQU 0CH ; PRINTER OUTPUT
- ;
- EPRINT DW 0 ; ENABLE PRINTER VARIABLE
- ; ; 0 = DISABLED, 1 = ENABLED
- ;
- ; BELOW BIOS CALLS USE 'IOS' IN DISK INTERFACE
- ;
- CSTAT PUSH B ; CONSOLE STATUS
- LXI D,KCSTAT ; CHECK IF ANY CHR HAS BEEN TYPED
- CALL IOS
- POP B ; IF CHR TYPED THEN (A) <- 0FFH
- RET ; ELSE (A) <- 0
- ; ; CHR IGNORED
- ;
- CIN PUSH B ; CONSOLE INPUT
- LXI D,KCIN ; WAIT FOR CHR TO BE TYPED
- CALL IOS ; (A) <- CHR, (MSB) <- 0
- POP B
- RET
- ;
- COUT PUSH H ; CONSOLE OUTPUT
- LXI D,KCOUT ; WAIT UNTIL READY
- CALL IOS ; THEN OUTPUT (C)
- POP H
- RET
- ;
- POUT LXI D,KPOUT ; PRINTER OUTPUT
- CALL IOS ; WAIT UNTIL READY
- RET ; THEN OUTPUT (C)
- ;
- CPOUT CALL COUT ; OUTPUT (C) TO CONSOLE
- XCHG
- LXI H,EPRINT
- MOV A,M ; IF (EPRINT) <> 0
- ORA A
- JZ CPOU1
- MOV C,E ; THEN OUTPUT (C) TO PRINTER
- CALL POUT
- CPOU1 RET
- ;
- ; FORTH TO CP/M SERIAL IO INTERFACE
- ;
- PQTER CALL CSTAT ; IF CHR TYPED
- LXI H,0
- ORA A
- JZ PQTE1
- INR L ; THEN (S1) <- TRUE
- PQTE1 JMP HPUSH ; ELSE (S1) <- FALSE
- ;
- PKEY CALL CIN ; READ CHR FROM CONSOLE
- CPI DLE ; IF CHR = (^P)
- MOV E,A
- JNZ PKEY1
- LXI H,EPRINT ; THEN TOGGLE (EPRINT)LSB
- MVI E,ABL ; CHR <- BLANK
- MOV A,M
- XRI 1
- MOV M,A
- PKEY1 MOV L,E
- MVI H,0
- JMP HPUSH ; (S1)LB <- CHR
- ;
- PEMIT DW $+2 ; (EMIT) ORPHAN
- POP H ; (L) <- (S1)LB = CHR
- PUSH B ; SAVE (IP)
- MOV C,L
- CALL CPOUT ; OUTPUT CHR TO CONSOLE
- ; ; & MAYBE PRINTER
- POP B ; RESTORE (IP)
- JMP NEXT
- ;
- PCR PUSH B ; SAVE (IP)
- MVI C,ACR ; OUTPUT (CR) TO CONSOLE
- MOV L,C
- CALL CPOUT ; & MAYBE TO PRINTER
- MVI C,LF ; OUTPUT (LF) TO CONSOLE
- MOV L,C
- CALL CPOUT ; & MAYBE TO PRINTER
- POP B ; RESTORE (IP)
- JMP NEXT
- ;
- ;----------------------------------------------------
- PAGE
- ;
- DB 0C1H ; ' ( TICK )
- DB 0A7H
- DW ARROW-6
- TICK DW DOCOL
- DW DFIND
- DW ZEQU
- DW ZERO
- DW QERR
- DW DROP
- DW LITER
- DW SEMIS
- ;
- DB 86H ; FORGET
- DB 'FORGE'
- DB 'T'+80H
- DW TICK-4
- FORG DW DOCOL
- DW CURR
- DW AT
- DW CONT
- DW AT
- DW SUBB
- DW LIT
- DW 18H
- DW QERR
- DW TICK
- DW DUP
- DW FENCE
- DW AT
- DW LESS
- DW LIT
- DW 15H
- DW QERR
- DW DUP
- DW NFA
- DW DP
- DW STORE
- DW LFA
- DW AT
- DW CONT
- DW AT
- DW STORE
- DW SEMIS
- ;
- DB 84H ; BACK
- DB 'BAC'
- DB 'K'+80H
- DW FORG-9
- BACK DW DOCOL
- DW HERE
- DW SUBB
- DW COMMA
- DW SEMIS
- ;
- DB 0C5H ; BEGIN
- DB 'BEGI'
- DB 'N'+80H
- DW BACK-7
- BEGIN DW DOCOL
- DW QCOMP
- DW HERE
- DW ONE
- DW SEMIS
- ;
- DB 0C5H ; ENDIF
- DB 'ENDI'
- DB 'F'+80H
- DW BEGIN-8
- ENDIFF DW DOCOL
- DW QCOMP
- DW TWO
- DW QPAIR
- DW HERE
- DW OVER
- DW SUBB
- DW SWAP
- DW STORE
- DW SEMIS
- ;
- DB 0C4H ; THEN
- DB 'THE'
- DB 'N'+80H
- DW ENDIFF-8
- THEN DW DOCOL
- DW ENDIFF
- DW SEMIS
- ;
- DB 0C2H ; DO
- DB 'D'
- DB 'O'+80H
- DW THEN-7
- DO DW DOCOL
- DW COMP
- DW XDO
- DW HERE
- DW THREE
- DW SEMIS
- ;
- DB 0C4H ; LOOP
- DB 'LOO'
- DB 'P'+80H
- DW DO-5
- LOOP DW DOCOL
- DW THREE
- DW QPAIR
- DW COMP
- DW XLOOP
- DW BACK
- DW SEMIS
- ;
- DB 0C5H ; +LOOP
- DB '+LOO'
- DB 'P'+80H
- DW LOOP-7
- PLOOP DW DOCOL
- DW THREE
- DW QPAIR
- DW COMP
- DW XPLOO
- DW BACK
- DW SEMIS
- ;
- DB 0C5H ; UNTIL
- DB 'UNTI'
- DB 'L'+80H
- DW PLOOP-8
- UNTIL DW DOCOL
- DW ONE
- DW QPAIR
- DW COMP
- DW ZBRAN
- DW BACK
- DW SEMIS
- ;
- DB 0C3H ; END
- DB 'EN'
- DB 'D'+80H
- DW UNTIL-8
- ENDD DW DOCOL
- DW UNTIL
- DW SEMIS
- ;
- DB 0C5H ; AGAIN
- DB 'AGAI'
- DB 'N'+80H
- DW ENDD-6
- AGAIN DW DOCOL
- DW ONE
- DW QPAIR
- DW COMP
- DW BRAN
- DW BACK
- DW SEMIS
- ;
- DB 0C6H ; REPEAT
- DB 'REPEA'
- DB 'T'+80H
- DW AGAIN-8
- REPEA DW DOCOL
- DW TOR
- DW TOR
- DW AGAIN
- DW FROMR
- DW FROMR
- DW TWO
- DW SUBB
- DW ENDIFF
- DW SEMIS
- ;
- DB 0C2H ; IF
- DB 'I'
- DB 'F'+80H
- DW REPEA-9
- IFF DW DOCOL
- DW COMP
- DW ZBRAN
- DW HERE
- DW ZERO
- DW COMMA
- DW TWO
- DW SEMIS
- ;
- DB 0C4H ; ELSE
- DB 'ELS'
- DB 'E'+80H
- DW IFF-5
- ELSEE DW DOCOL
- DW TWO
- DW QPAIR
- DW COMP
- DW BRAN
- DW HERE
- DW ZERO
- DW COMMA
- DW SWAP
- DW TWO
- DW ENDIFF
- DW TWO
- DW SEMIS
- ;
- DB 0C5H ; WHILE
- DB 'WHIL'
- DB 'E'+80H
- DW ELSEE-7
- WHILE DW DOCOL
- DW IFF
- DW TWOP
- DW SEMIS
- ;
- DB 86H ; SPACES
- DB 'SPACE'
- DB 'S'+80H
- DW WHILE-8
- SPACS DW DOCOL
- DW ZERO
- DW MAX
- DW DDUP
- DW ZBRAN ; IF
- DW SPAX1-$
- DW ZERO
- DW XDO ; DO
- SPAX2 DW SPACE
- DW XLOOP ; LOOP ENDIF
- DW SPAX2-$
- SPAX1 DW SEMIS
- ;
- DB 82H ; <#
- DB '<'
- DB '#'+80H
- DW SPACS-9
- BDIGS DW DOCOL
- DW PAD
- DW HLD
- DW STORE
- DW SEMIS
- ;
- DB 82H ; #>
- DB '#'
- DB '>'+80H
- DW BDIGS-5
- EDIGS DW DOCOL
- DW DROP
- DW DROP
- DW HLD
- DW AT
- DW PAD
- DW OVER
- DW SUBB
- DW SEMIS
- ;
- DB 84H ; SIGN
- DB 'SIG'
- DB 'N'+80H
- DW EDIGS-5
- SIGN DW DOCOL
- DW ROT
- DW ZLESS
- DW ZBRAN ; IF
- DW SIGN1-$
- DW LIT
- DW 2DH
- DW HOLD ; ENDIF
- SIGN1 DW SEMIS
- ;
- DB 81H ; #
- DB '#'+80H
- DW SIGN-7
- DIG DW DOCOL
- DW BASE
- DW AT
- DW MSMOD
- DW ROT
- DW LIT
- DW 9
- DW OVER
- DW LESS
- DW ZBRAN ; IF
- DW DIG1-$
- DW LIT
- DW 7
- DW PLUS ; ENDIF
- DIG1 DW LIT
- DW 30H
- DW PLUS
- DW HOLD
- DW SEMIS
- ;
- DB 82H ; #S
- DB '#'
- DB 'S'+80H
- DW DIG-4
- DIGS DW DOCOL
- DIGS1 DW DIG ; BEGIN
- DW OVER
- DW OVER
- DW ORR
- DW ZEQU
- DW ZBRAN ; UNTIL
- DW DIGS1-$
- DW SEMIS
- ;
- DB 83H ; D.R
- DB 'D.'
- DB 'R'+80H
- DW DIGS-5
- DDOTR DW DOCOL
- DW TOR
- DW SWAP
- DW OVER
- DW DABS
- DW BDIGS
- DW DIGS
- DW SIGN
- DW EDIGS
- DW FROMR
- DW OVER
- DW SUBB
- DW SPACS
- DW TYPE
- DW SEMIS
- ;
- DB 82H ; .R
- DB '.'
- DB 'R'+80H
- DW DDOTR-6
- DOTR DW DOCOL
- DW TOR
- DW STOD
- DW FROMR
- DW DDOTR
- DW SEMIS
- ;
- DB 82H ; D.
- DB 'D'
- DB '.'+80H
- DW DOTR-5
- DDOT DW DOCOL
- DW ZERO
- DW DDOTR
- DW SPACE
- DW SEMIS
- ;
- DB 81H ; .
- DB '.'+80H
- DW DDOT-5
- DOT DW DOCOL
- DW STOD
- DW DDOT
- DW SEMIS
- ;
- DB 81H ; ?
- DB '?'+80H
- DW DOT-4
- QUES DW DOCOL
- DW AT
- DW DOT
- DW SEMIS
- ;
- DB 82H ; U.
- DB 'U'
- DB '.'+80H
- DW QUES-4
- UDOT DW DOCOL
- DW ZERO
- DW DDOT
- DW SEMIS
- ;
- DB 85H ; VLIST
- DB 'VLIS'
- DB 'T'+80H
- DW UDOT-5
- VLIST DW DOCOL
- DW LIT
- DW 80H
- DW OUTT
- DW STORE
- DW CONT
- DW AT
- DW AT
- VLIS1 DW OUTT ; BEGIN
- DW AT
- DW CSLL
- DW GREAT
- DW ZBRAN ; IF
- DW VLIS2-$
- DW CR
- DW ZERO
- DW OUTT
- DW STORE ; ENDIF
- VLIS2 DW DUP
- DW IDDOT
- DW SPACE
- DW SPACE
- DW PFA
- DW LFA
- DW AT
- DW DUP
- DW ZEQU
- DW QTERM
- DW ORR
- DW ZBRAN ; UNTIL
- DW VLIS1-$
- DW DROP
- DW SEMIS
- ;
- ;------ EXIT CP/M -----------------------
- ;
- DB 83H ; BYE
- DB 'BY'
- DB 'E'+80H
- DW VLIST-8
- BYE DW $+2
- JMP 0
- ;-----------------------------------------------
- ;
- DB 84H ; LIST
- DB 'LIS'
- DB 'T'+80H
- DW BYE-6
- LIST DW DOCOL,DEC
- DW CR,DUP
- DW SCR,STORE
- DW PDOTQ
- DB 6,'SCR # '
- DW DOT
- DW LIT,10H
- DW ZERO,XDO
- LIST1 DW CR,IDO
- DW LIT,3
- DW DOTR,SPACE
- DW IDO,SCR
- DW AT,DLINE
- DW QTERM ; ?TERMINAL
- DW ZBRAN,LIST2-$ ; IF
- DW LEAVE ; LEAVE
- LIST2 DW XLOOP,LIST1-$ ; ENDIF
- DW CR,SEMIS
- ;
- DB 85H ; INDEX
- DB 'INDE'
- DB 'X'+80H
- DW LIST-7
- INDEX DW DOCOL
- DW LIT,FF
- DW EMIT,CR
- DW ONEP,SWAP
- DW XDO
- INDE1 DW CR,IDO
- DW LIT,3
- DW DOTR,SPACE
- DW ZERO,IDO
- DW DLINE,QTERM
- DW ZBRAN,INDE2-$
- DW LEAVE
- INDE2 DW XLOOP,INDE1-$
- DW SEMIS
- ;
- DB 85H ; TRIAD
- DB 'TRIA'
- DB 'D'+80H
- DW INDEX-8
- TRIAD DW DOCOL
- DW LIT,FF
- DW EMIT
- DW LIT,3
- DW SLASH
- DW LIT,3
- DW STAR
- DW LIT,3
- DW OVER,PLUS
- DW SWAP,XDO
- TRIA1 DW CR,IDO
- DW LIST
- DW QTERM ; ?TERMINAL
- DW ZBRAN,TRIA2-$ ; IF
- DW LEAVE ; LEAVE
- TRIA2 DW XLOOP,TRIA1-$ ; ENDIF
- DW CR
- DW LIT,15
- DW MESS,CR
- DW SEMIS
- ;
- DB 84H ; .CPU
- DB '.CP'
- DB 'U'+80H
- DW TRIAD-8
- DOTCPU DW DOCOL
- DW BASE,AT
- DW LIT,36
- DW BASE,STORE
- DW LIT,22H
- DW PORIG,TAT
- DW DDOT
- DW BASE,STORE
- DW SEMIS
- ;
- DB 84H ; TASK
- DB 'TAS'
- DB 'K'+80H
- DW DOTCPU-7
- TASK DW DOCOL
- DW SEMIS
- ;
- INITDP: DS EM-$ ;CONSUME MEMORY TO LIMIT
- ;
- PAGE
- ;
- ; MEMORY MAP
- ; ( THE FOLLOWING EQUATES ARE NOT REFERENCED ELSEWHERE )
- ;
- ; LOCATION CONTENTS
- ; -------- --------
- MCOLD EQU ORIG ;JMP TO COLD START
- MWARM EQU ORIG+4 ;JMP TO WARM START
- MA2 EQU ORIG+8 ;COLD START PARAMETERS
- MUP EQU UP ;USER VARIABLES' BASE 'REG'
- MRP EQU RPP ;RETURN STACK 'REGISTER'
- ;
- MBIP EQU BIP ;DEBUG SUPPORT
- MDPUSH EQU DPUSH ;ADDRESS INTERPRETER
- MHPUSH EQU HPUSH
- MNEXT EQU NEXT
- ;
- MDP0 EQU DP0 ;START FORTH DICTIONARY
- MDIO EQU DRIVE ;CP/M DISK INTERFACE
- MCIO EQU EPRINT ;CONSOLE & PRINTER INTERFACE
- MIDP EQU INITDP ;END INITIAL FORTH DICTIONARY
- ; = COLD (DP) VALUE
- ; = COLD (FENCE) VALUE
- ; | NEW
- ; | DEFINITIONS
- ; V
- ;
- ; ^
- ; | DATA
- ; | STACK
- MIS0 EQU INITS0 ; = COLD (SP) VALUE = (S0)
- ; = (TIB)
- ; | TERMINAL INPUT
- ; | BUFFER
- ; V
- ;
- ; ^
- ; | RETURN
- ; | STACK
- MIR0 EQU INITR0 ;START USER VARIABLES
- ; = COLD (RP) VALUE = (R0)
- ; = (UP)
- ; ;END USER VARIABLES
- MFIRST EQU BUF1 ;START DISK BUFFERS
- ; = FIRST
- MEND EQU EM-1 ;END DISK BUFFERS
- MLIMIT EQU EM ;LAST MEMORY LOC USED + 1
- ; = LIMIT
- ;
- ;
- END ORIG
- HHHHDT=0 LEAVE ; LEAVE
- TRIA2 DW XLOOP,TRIA1-$ ; ENDIF
- DW CR
- DW LIT,15
- DW MESS,CR
- DW SEMIS
- ;
- DB 84H ; .CPU
- DB '.CP'
- DB 'U'+80H
- DW TRIAD-8
- DOTCPUPPORT
- MDPUSH EQU DPUSH ;ADDRESS INTERPR