4 * ASSEMBLY SOURCE LISTING
8 * WITH COMPILER SECURITY
9 * AND VARIABLE LENGTH NAMES
11 * This public domain publication is provided
12 * through the courtesy of:
18 * P.O. Box 8231 - San Jose, CA 95155 - (408) 277-0668
19 * Further distribution must include this notice.
21 NAM Copyright:FORTH Interest Group
24 * === FORTH-6800 06-06-79 21:OO
27 * This listing is in the PUBLIC DOMAIN and
28 * may be freely copied or published with the
29 * restriction that a credit line is printed
30 * with the material, crediting the
31 * authors and the FORTH INTEREST GROUP.
37 * === The Forth Interest Group
39 * === San Carlos, CA 94070
41 * === Unbounded Computing
42 * === 1134-K Aster Ave.
43 * === Sunnyvale, CA 94086
45 * This version was developed on an AMI EVK 300 PROTO
46 * system using an ACIA for the I/O. All terminal 1/0
47 * is done in three subroutines:
48 * PEMIT ( word # 182 )
52 * The FORTH words for disc related I/O follow the model
53 * of the FORTH Interest Group, but have not been
54 * tested using a real disc.
56 * Addresses in this implementation reflect the fact that,
57 * on the development system, it was convenient to
58 * write-protect memory at hex 1000, and leave the first
59 * 4K bytes write-enabled. As a consequence, code from
60 * location $1000 to lable ZZZZ could be put in ROM.
61 * Minor deviations from the model were made in the
62 * initialization and words ?STACK and FORGET
63 * in order to do this.
68 NBLK EQU 4 # of disc buffer blocks for virtual memory
69 MEMEND EQU 132*NBLK+$3000 end of ram
70 * each block is 132 bytes in size,
71 * holding 128 characters
73 MEMTOP EQU $3FFF absolute end of all ram
74 ACIAC EQU $FBCE the ACIA control address and
75 ACIAD EQU ACIAC+1 data address for PROTO
77 * MEMORY MAP for this 16K system:
78 * ( positioned so that systems with 4k byte write-
79 * protected segments can write protect FORTH )
81 * addr. contents pointer init by
82 * **** ******************************* ******* ******
84 * substitute for disc mass memory
87 * 4 buffer sectors of VIRTUAL MEMORY
89 * >>>>>> memory from here up must be RAM <<<<<<
92 * 6k of romable "FORTH" <== IP ABORT
94 * the VIRTUAL FORTH MACHINE
96 * 1004 <<< WARM START ENTRY >>>
97 * 1000 <<< COLD START ENTRY >>>
99 * >>>>>> memory from here down must be RAM <<<<<<
100 * FFE RETURN STACK base <== RP RINIT
104 * holds up to 132 characters
105 * and is scanned upward by IN
108 * F2F DATA STACK <== SP SP0,SINIT
109 * | grows downward from F2F
113 * I DICTIONARY grows upward
115 * 183 end of ram-dictionary. <== DP DPINIT
118 * 150 "FORTH" ( a word ) <=, <== CONTEXT
120 * 148 start of ram-dictionary.
122 * 100 user #l table of variables <= UP DPINIT
123 * F0 registers & pointers for the virtual machine
124 * scratch area used by various words
125 * E0 lowest address used by FORTH
131 * CONVENTIONS USED IN THIS PROGRAM ARE AS FOLLOWS :
133 * IP points to the current instruction ( pre-increment mode )
134 * RP points to second free byte (first free word) in return stack
135 * SP (hardware SP) points to first free byte in data stack
137 * when A and B hold one 16 bit FORTH data word,
138 * A contains the high byte, B, the low byte.
147 N RMB 10 used as scratch by (FIND),ENCLOSE,CMOVE,EMIT,KEY,
148 * SP@,SWAP,DOES>,COLD
151 * These locations are used by the TRACE routine :
153 TRLIM RMB 1 the count for tracing without user intervention
154 TRACEM RMB 1 non-zero = trace mode
155 BRKPT RMB 2 the breakpoint address at which
156 * the program will go into trace mode
157 VECT RMB 2 vector to machine code
158 * (only needed if the TRACE routine is resident)
161 * Registers used by the FORTH virtual machine:
165 W RMB 2 the instruction register points to 6800 code
166 IP RMB 2 the instruction pointer points to pointer to 6800 code
167 RP RMB 2 the return stack pointer
168 UP RMB 2 the pointer to base of current user's 'USER' table
169 * ( altered during multi-tasking )
172 * This system is shown with one user, but additional users
173 * may be added by allocating additional user tables:
174 * UORIG2 RMB 64 data table for user #2
177 * Some of this stuff gets initialized during
178 * COLD start and WARM start:
179 * [ names correspond to FORTH words of similar (no X) name ]
182 UORIG RMB 6 3 reserved variables
183 XSPZER RMB 2 initial top of data stack for this user
184 XRZERO RMB 2 initial top of return stack
185 XTIB RMB 2 start of terminal input buffer
186 XWIDTH RMB 2 name field width
187 XWARN RMB 2 warning message mode (0 = no disc)
188 XFENCE RMB 2 fence for FORGET
189 XDP RMB 2 dictionary pointer
190 XVOCL RMB 2 vocabulary linking
191 XBLK RMB 2 disc block being accessed
192 XIN RMB 2 scan pointer into the block
193 XOUT RMB 2 cursor position
194 XSCR RMB 2 disc screen being accessed ( O=terminal )
195 XOFSET RMB 2 disc sector offset for multi-disc
196 XCONT RMB 2 last word in primary search vocabulary
197 XCURR RMB 2 last word in extensible vocabulary
198 XSTATE RMB 2 flag for 'interpret' or 'compile' modes
199 XBASE RMB 2 number base for I/O numeric conversion
200 XDPL RMB 2 decimal point place
202 XCSP RMB 2 current stack position, for compile checks
205 XDELAY RMB 2 carriage return delay count
206 XCOLUM RMB 2 carriage width
207 IOSTAT RMB 2 last acia status from write/read
218 * end of user table, start of common system variables
227 * These things, up through the lable 'REND', are overwritten
228 * at time of cold load and should have the same contents
235 FORTH FDB DODOES,DOVOC,$81A0,TASK-7
238 FCC "(C) Forth Interest Group, 1979"
246 REND EQU * ( first empty location in dictionary )
249 * The FORTH program ( address $1000 to $27FF ) is written
250 * so that it can be in a ROM, or write-protected if desired
253 * ######>> screen 3 <<
255 ***************************
256 ** C O L D E N T R Y **
257 ***************************
260 ***************************
261 ** W A R M E N T R Y **
262 ***************************
264 JMP WENT warm-start code, keeps current dictionary intact
267 ******* startup parmeters **************************
269 FDB $6800,0000 cpu & revision
270 FDB 0 topmost word in FORTH vocabulary
271 BACKSP FDB $7F backspace character for editing
272 UPINIT FDB UORIG initial user area
273 SINIT FDB ORIG-$D0 initial top of data stack
274 RINIT FDB ORIG-2 initial top of return stack
275 FDB ORIG-$D0 terminal input buffer
276 FDB 31 initial name field width
277 FDB 0 initial warning mode (0 = no disc)
278 FENCIN FDB REND initial fence
279 DPINIT FDB REND cold start value for DP
281 COLINT FDB 132 initial terminal carriage width
282 DELINT FDB 4 initial carriage return delay
283 ****************************************************
287 * ######>> screen 13 <<
288 PULABX PULS A ; 24 cycles until 'NEXT'
290 STABX STA 0,X 16 cycles until 'NEXT'
293 GETX LDA 0,X 18 cycles until 'NEXT'
295 PUSHBA PSHS B ; 8 cycles until 'NEXT'
301 * "NEXT" takes 38 cycles if TRACE is removed,
303 * and 95 cycles if NOT tracing.
305 * = = = = = = = t h e v i r t u a l m a c h i n e = = = = =
308 LEAX 1,X ; pre-increment mode
311 NEXT2 LDX 0,X get W which points to CFA of word to be done
313 LDX 0,X get VECT which points to executable code
315 * The next instruction could be patched to JMP TRACE =
316 * if a TRACE routine is available: =
320 * JMP TRACE ( an alternate for the above )
322 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
329 FCC 'LI' ; 'LIT' : NOTE: this is different from LITERAL
331 FDB 0 link of zero to terminate dictionary scan
341 * ######>> screen 14 <<
343 CLITER FDB *+2 (this is an invisible word, with no header)
353 FCC 'EXECUT' ; 'EXECUTE'
358 LDX 0,X get code field address (CFA)
363 * ######>> screen 15 <<
366 FCC 'BRANC' ; 'BRANCH'
369 BRAN FDB ZBYES Go steal code in ZBRANCH
373 FCC '0BRANC' ; '0BRANCH'
379 PSHS B ; ** emulating ABA:
383 ZBYES LDX IP Note: code is shared with BRANCH, (+LOOP), (LOOP)
391 ZBNO LDX IP no branch. This code is shared with (+LOOP), (LOOP).
392 LEAX 1,X ; jump over branch delta
397 * ######>> screen 16 <<
400 FCC '(LOOP' ; '(LOOP)'
405 LDB #1 get set to increment counter by 1
406 BRA XPLOP2 go steal other guy's code!
410 FCC '(+LOOP' ; '(+LOOP)'
413 XPLOOP FDB *+2 Note: +LOOP has an un-signed loop counter
414 PULS A ; get increment
417 BPL XPLOF forward looping
423 BRA XPLONO fall through
427 ADDB 3,X add it to counter
429 STB 3,X store new counter value
438 XPLONO LEAX 1,X ; done, don't branch back
443 BRA ZBNO use ZBRAN to skip over unused delta
445 * ######>> screen 17 <<
451 XDO FDB *+2 This is the RUNTIME DO, not the COMPILING DO
478 * ######>> screen 18 <<
484 DIGIT FDB *+2 NOTE: legal input range is 0-9, A-Z
488 BMI DIGIT2 IF LESS THAN '0', ILLEGAL
490 BMI DIGIT0 IF '9' OR LESS
492 BMI DIGIT2 if less than 'A'
494 BPL DIGIT2 if greater than 'Z'
495 SUBA #7 translate 'A' thru 'F'
497 BPL DIGIT2 if not less than the base
500 DIGIT1 STB 1,X store the flag
504 LEAS 1,S ; pop bottom number
506 STB 0,X make sure both bytes are 00
509 * ######>> screen 19 <<
511 * The word format in the dictionary is:
513 * char-count + $80 lowest address
518 * link high byte \___point to previous word
520 * CFA high byte \___pnt to 6800 code
529 FCC '(FIND' ; '(FIND)'
535 PD EQU N ptr to dict word being checked
541 PFIND0 PULS A ; loop to get arguments
548 PFIND1 LDB 0,X get count dict count
554 LDA 0,X get count from arg
557 PSHS B ; ** emulating CBA:
558 CMPA ,S+ ; compare lengths
568 TSTB ; is dict entry neg. ?
571 PSHS B ; ** emulating CBA:
574 PFIND3 LDX 0,X get new link
575 BNE PFIND1 continue if link not=0
582 PFIND8 PSHS B ; ** emulating CBA:
586 PFIND9 LDB 0,X scan forward to end of this name
593 FOUND LDA PD compute CFA
612 * ######>> screen 20 <<
615 FCC 'ENCLOS' ; 'ENCLOSE'
619 * FC means offset (bytes) to First Character of next word
620 * EW " " to End of Word
621 * NC " " to Next Character to start next enclose at
624 PULS B ; now, get the low byte, for an 8-bit delimiter
628 * wait for a non-delimiter or a NUL
631 PSHS B ; ** emulating CBA:
632 CMPA ,S+ ; CHECK FOR DELIM
637 * found first character. Push FC
638 ENCL3 LDA N found first char.
642 * wait for a delimiter or a NUL
645 PSHS B ; ** emulating CBA:
646 CMPA ,S+ ; ckech for delim.
656 * advance and push NC
659 * found NUL before non-delimiter, therefore there is no word
660 ENCL6 LDB N found NUL
665 * found NUL following the word instead of SPACE
674 * ######>> screen 21 <<
675 * The next 4 words call system dependant I/O routines
676 * which are listed after word "-->" ( lable: "arrow" )
691 ****WARNING**** HARD OFFSET: *+4 ****
709 FCC '?TERMINA' ; '?TERMINAL'
715 JMP PUSHBA stack the flag
726 * ######>> screen 22 <<
729 FCC 'CMOV' ; 'CMOVE' : source, destination, count
732 CMOVE FDB *+2 takes ( 43+47*count cycles )
736 STA 0,X move parameters to scratch area
758 * ######>> screen 23 <<
770 * The following is a subroutine which
771 * multiplies top 2 words on stack,
772 * leaving 32-bit result: high order word in A,B
773 * low order word in 2nd word of stack.
775 USTARS LDA #16 bits/word counter
780 USTAR2 ROR 5,X shift multiplier
790 USTAR4 LEAS 1,S ; dump counter
793 * ######>> screen 24 <<
810 USL2 ANDCC #~$01 ; CLC :
828 JMP SWAP+4 reverse quotient & remainder
830 * ######>> screen 25 <<
870 * ######>> screen 26 <<
890 TFR X,S ; TXS : watch it ! X and S are not equal.
898 LDX RINIT initialize from rom constant
912 LDX 0,X get address we have just finished.
913 JMP NEXT+2 increment the return address & do next word
915 * ######>> screen 27 <<
969 * ######>> screen 28 <<
982 ZEQU2 TFR S,X ; TSX :
992 LDA #$80 check the sign bit
1001 * ######>> screen 29 <<
1037 FCC 'MINU' ; 'MINUS'
1051 FCC 'DMINU' ; 'DMINUS'
1068 * ######>> screen 30 <<
1120 * ######>> screen 31 <<
1131 PULS A ; get stack data
1133 ADDB 1,X add & store low byte
1135 ADCA 0,X add & store hi byte
1141 FCC 'TOGGL' ; 'TOGGLE'
1144 TOGGLE FDB DOCOL,OVER,CAT,XOR,SWAP,CSTORE
1147 * ######>> screen 32 <<
1200 * ######>> screen 33 <<
1205 COLON FDB DOCOL,QEXEC,SCSP,CURENT,AT,CONTXT,STORE
1209 * Here is the IP pusher for allowing
1210 * nested words in the virtual machine:
1211 * ( ;S is the equivalent un-nester )
1213 DOCOL LDX RP make room in the stack
1219 STA 2,X Store address of the high level word
1220 STB 3,X that we are starting to execute
1221 LDX W Get first sub-word of that definition
1222 JMP NEXT+2 and execute it
1225 FCB $C1 ; imnediate code
1228 SEMI FDB DOCOL,QCSP,COMPIL,SEMIS,SMUDGE,LBRAK
1231 * ######>> screen 34 <<
1234 FCC 'CONSTAN' ; 'CONSTANT'
1237 CON FDB DOCOL,CREATE,SMUDGE,COMMA,PSCODE
1240 LDB 3,X A & B now contain the constant
1245 FCC 'VARIABL' ; 'VARIABLE'
1248 VAR FDB DOCOL,CON,PSCODE
1252 ADCA #0 A,B now contain the address of the variable
1260 USER FDB DOCOL,CON,PSCODE
1261 DOUSER LDX W get offset into user's table
1264 ADDB UP+1 add to users base address
1266 JMP PUSHBA push address of user's variable
1268 * ######>> screen 35 <<
1302 BL FDB DOCON ascii blank
1307 FCC 'FIRS' ; 'FIRST'
1311 FDB MEMEND-528 (132 * NBLK)
1315 FCC 'LIMI' ; 'LIMIT' : ( the end of memory +1 )
1323 FCC 'B/BU' ; 'B/BUF' : (bytes/buffer)
1331 FCC 'B/SC' ; 'B/SCR' : (blocks/screen)
1336 * blocks/screen = 1024 / "B/BUF" = 8
1340 FCC '+ORIGI' ; '+ORIGIN'
1343 PORIG FDB DOCOL,LIT,ORIG,PLUS
1346 * ######>> screen 36 <<
1373 FCC 'WIDT' ; 'WIDTH'
1381 FCC 'WARNIN' ; 'WARNING'
1389 FCC 'FENC' ; 'FENCE'
1397 FCC 'D' ; 'DP' : points to first free byte at end of dictionary
1405 FCC 'VOC-LIN' ; 'VOC-LINK'
1421 FCC 'I' ; 'IN' : scan pointer for input line buffer
1442 * ######>> screen 37 <<
1446 FCC 'OFFSE' ; 'OFFSET'
1454 FCC 'CONTEX' ; 'CONTEXT' : points to pointer to vocab to search first
1462 FCC 'CURREN' ; 'CURRENT' : points to ptr. to vocab being extended
1470 FCC 'STAT' ; 'STATE' : 1 if compiling, 0 if not
1478 FCC 'BAS' ; 'BASE' : number base for all input & output
1524 * ======>> 82.5 <<== SPECIAL
1526 FCC 'COLUMN' ; 'COLUMNS' : line width of terminal
1532 * ######>> screen 38 <<
1538 ONEP FDB DOCOL,ONE,PLUS
1546 TWOP FDB DOCOL,TWO,PLUS
1554 HERE FDB DOCOL,DP,AT
1559 FCC 'ALLO' ; 'ALLOT'
1562 ALLOT FDB DOCOL,DP,PSTORE
1569 COMMA FDB DOCOL,HERE,STORE,TWO,ALLOT
1577 CCOMM FDB DOCOL,HERE,CSTORE,ONE,ALLOT
1584 SUB FDB DOCOL,MINUS,PLUS
1591 EQUAL FDB DOCOL,SUB,ZEQU
1619 GREAT FDB DOCOL,SWAP,LESS
1627 ROT FDB DOCOL,TOR,SWAP,FROMR,SWAP
1632 FCC 'SPAC' ; 'SPACE'
1635 SPACE FDB DOCOL,BL,EMIT
1643 MIN FDB DOCOL,OVER,OVER,GREAT,ZBRAN
1654 MAX FDB DOCOL,OVER,OVER,LESS,ZBRAN
1665 DDUP FDB DOCOL,DUP,ZBRAN
1670 * ######>> screen 39 <<
1673 FCC 'TRAVERS' ; 'TRAVERSE'
1677 TRAV2 FDB OVER,PLUS,CLITER
1679 FDB OVER,CAT,LESS,ZBRAN
1686 FCC 'LATES' ; 'LATEST'
1689 LATEST FDB DOCOL,CURENT,AT,AT
1697 LFA FDB DOCOL,CLITER
1707 CFA FDB DOCOL,TWO,SUB
1715 NFA FDB DOCOL,CLITER
1717 FDB SUB,ONE,MINUS,TRAV
1725 PFA FDB DOCOL,ONE,TRAV,CLITER
1730 * ######>> screen 40 <<
1736 SCSP FDB DOCOL,SPAT,CSP,STORE
1741 FCC '?ERRO' ; '?ERROR'
1744 QERR FDB DOCOL,SWAP,ZBRAN
1753 FCC '?COM' ; '?COMP'
1756 QCOMP FDB DOCOL,STATE,AT,ZEQU,CLITER
1763 FCC '?EXE' ; '?EXEC'
1766 QEXEC FDB DOCOL,STATE,AT,CLITER
1773 FCC '?PAIR' ; '?PAIRS'
1776 QPAIRS FDB DOCOL,SUB,CLITER
1786 QCSP FDB DOCOL,SPAT,CSP,AT,SUB,CLITER
1793 FCC '?LOADIN' ; '?LOADING'
1796 QLOAD FDB DOCOL,BLK,AT,ZEQU,CLITER
1801 * ######>> screen 41 <<
1804 FCC 'COMPIL' ; 'COMPILE'
1807 COMPIL FDB DOCOL,QCOMP,FROMR,TWOP,DUP,TOR,AT,COMMA
1814 LBRAK FDB DOCOL,ZERO,STATE,STORE
1821 RBRAK FDB DOCOL,CLITER
1828 FCC 'SMUDG' ; 'SMUDGE'
1831 SMUDGE FDB DOCOL,LATEST,CLITER
1849 FCC 'DECIMA' ; 'DECIMAL'
1854 FCB 10 note: hex "A"
1858 * ######>> screen 42 <<
1861 FCC '(;CODE' ; '(;CODE)'
1864 PSCODE FDB DOCOL,FROMR,TWOP,LATEST,PFA,CFA,STORE
1869 FCC ';COD' ; ';CODE'
1872 SEMIC FDB DOCOL,QCSP,COMPIL,PSCODE,SMUDGE,LBRAK,QSTACK
1874 * note: "QSTACK" will be replaced by "ASSEMBLER" later
1876 * ######>> screen 43 <<
1879 FCC '<BUILD' ; '<BUILDS'
1882 BUILDS FDB DOCOL,ZERO,CON
1887 FCC 'DOES' ; 'DOES>'
1890 DOES FDB DOCOL,FROMR,TWOP,LATEST,PFA,STORE
1894 LDX RP make room on return stack
1898 STA 2,X push return address
1900 LDX W get addr of pointer to run-time code
1903 STX N stash it in scratch area
1906 CLRA ; get address of parameter
1910 PSHS B ; and push it on data stack
1914 * ######>> screen 44 <<
1917 FCC 'COUN' ; 'COUNT'
1920 COUNT FDB DOCOL,DUP,ONEP,SWAP,CAT
1928 TYPE FDB DOCOL,DDUP,ZBRAN
1930 FDB OVER,PLUS,SWAP,XDO
1931 TYPE2 FDB I,CAT,EMIT,XLOOP
1940 FCC '-TRAILIN' ; '-TRAILING'
1943 DTRAIL FDB DOCOL,DUP,ZERO,XDO
1944 DTRAL2 FDB OVER,OVER,PLUS,ONE,SUB,CAT,BL
1959 PDOTQ FDB DOCOL,R,TWOP,COUNT,DUP,ONEP
1960 FDB FROMR,PLUS,TOR,TYPE
1973 FDB COMPIL,PDOTQ,WORD
1974 FDB HERE,CAT,ONEP,ALLOT,BRAN
1976 DOTQ1 FDB WORD,HERE,COUNT,TYPE
1979 * ######>> screen 45 <<
1980 * ======>> 126 <<== MACHINE DEPENDENT
1982 FCC '?STAC' ; '?STACK'
1985 QSTACK FDB DOCOL,CLITER
1987 FDB PORIG,AT,TWO,SUB,SPAT,LESS,ONE
1989 * prints 'empty stack'
1992 * Here, we compare with a value at least 128
1993 * higher than dict. ptr. (DP)
2000 * prints 'full stack'
2004 * ======>> 127 << this word's function
2005 * is done by ?STACK in this version
2010 *QFREE FDB DOCOL,SPAT,HERE,CLITER
2012 * FDB PLUS,LESS,TWO,QERR,SEMIS
2014 * ######>> screen 46 <<
2017 FCC 'EXPEC' ; 'EXPECT'
2020 EXPECT FDB DOCOL,OVER,PLUS,OVER,XDO
2021 EXPEC2 FDB KEY,DUP,CLITER
2023 FDB PORIG,AT,EQUAL,ZBRAN
2026 FCB 8 ( backspace character to emit )
2027 FDB OVER,I,EQUAL,DUP,FROMR,TWO,SUB,PLUS
2030 EXPEC3 FDB DUP,CLITER
2031 FCB $D ( carriage return )
2034 FDB LEAVE,DROP,BL,ZERO,BRAN
2037 EXPEC5 FDB I,CSTORE,ZERO,I,ONEP,STORE
2038 EXPEC6 FDB EMIT,XLOOP
2045 FCC 'QUER' ; 'QUERY'
2048 QUERY FDB DOCOL,TIB,AT,COLUMS
2049 FDB AT,EXPECT,ZERO,IN,STORE
2053 FCB $C1 immediate < carriage return >
2056 NULL FDB DOCOL,BLK,AT,ZBRAN
2059 FDB ZERO,IN,STORE,BLK,AT,BSCR,MOD
2061 * check for end of screen
2064 FDB QEXEC,FROMR,DROP
2067 NULL2 FDB FROMR,DROP
2070 * ######>> screen 47 <<
2076 FILL FDB DOCOL,SWAP,TOR,OVER,CSTORE,DUP,ONEP
2077 FDB FROMR,ONE,SUB,CMOVE
2082 FCC 'ERAS' ; 'ERASE'
2085 ERASE FDB DOCOL,ZERO,FILL
2090 FCC 'BLANK' ; 'BLANKS'
2093 BLANKS FDB DOCOL,BL,FILL
2101 HOLD FDB DOCOL,LIT,$FFFF,HLD,PSTORE,HLD,AT,CSTORE
2109 PAD FDB DOCOL,HERE,CLITER
2114 * ######>> screen 48 <<
2120 WORD FDB DOCOL,BLK,AT,ZBRAN
2122 FDB BLK,AT,BLOCK,BRAN
2125 WORD3 FDB IN,AT,PLUS,SWAP,ENCLOS,HERE,CLITER
2127 FDB BLANKS,IN,PSTORE,OVER,SUB,TOR,R,HERE
2128 FDB CSTORE,PLUS,HERE,ONEP,FROMR,CMOVE
2131 * ######>> screen 49 <<
2134 FCC '(NUMBER' ; '(NUMBER)'
2138 PNUMB2 FDB ONEP,DUP,TOR,CAT,BASE,AT,DIGIT,ZBRAN
2140 FDB SWAP,BASE,AT,USTAR,DROP,ROT,BASE
2141 FDB AT,USTAR,DPLUS,DPL,AT,ONEP,ZBRAN
2144 PNUMB3 FDB FROMR,BRAN
2151 FCC 'NUMBE' ; 'NUMBER'
2154 NUMB FDB DOCOL,ZERO,ZERO,ROT,DUP,ONEP,CAT,CLITER
2156 FDB EQUAL,DUP,TOR,PLUS,LIT,$FFFF
2157 NUMB1 FDB DPL,STORE,PNUMB,DUP,CAT,BL,SUB
2162 FDB SUB,ZERO,QERR,ZERO,BRAN
2164 NUMB2 FDB DROP,FROMR,ZBRAN
2171 FCC '-FIN' ; '-FIND'
2174 DFIND FDB DOCOL,BL,WORD,HERE,CONTXT,AT,AT
2175 FDB PFIND,DUP,ZEQU,ZBRAN
2177 FDB DROP,HERE,LATEST,PFIND
2180 * ######>> screen 50 <<
2183 FCC '(ABORT' ; '(ABORT)'
2186 PABORT FDB DOCOL,ABORT
2191 FCC 'ERRO' ; 'ERROR'
2194 ERROR FDB DOCOL,WARN,AT,ZLESS
2196 * note: WARNING is -1 to abort, 0 to print error #
2197 * and 1 to print error message from disc
2200 ERROR2 FDB HERE,COUNT,TYPE,PDOTQ
2203 FDB MESS,SPSTOR,IN,AT,BLK,AT,QUIT
2211 IDDOT FDB DOCOL,PAD,CLITER
2214 FCB $5F ( underline )
2215 FDB FILL,DUP,PFA,LFA,OVER,SUB,PAD
2216 FDB SWAP,CMOVE,PAD,COUNT,CLITER
2221 * ######>> screen 51 <<
2224 FCC 'CREAT' ; 'CREATE'
2227 CREATE FDB DOCOL,DFIND,ZBRAN
2233 FDB NFA,IDDOT,CLITER
2236 CREAT2 FDB HERE,DUP,CAT,WIDTH,AT,MIN
2237 FDB ONEP,ALLOT,DUP,CLITER
2239 FDB TOGGLE,HERE,ONE,SUB,CLITER
2241 FDB TOGGLE,LATEST,COMMA,CURENT,AT,STORE
2245 * ######>> screen 52 <<
2248 FCC '[COMPILE' ; '[COMPILE]'
2251 BCOMP FDB DOCOL,DFIND,ZEQU,ZERO,QERR,DROP,CFA,COMMA
2256 FCC 'LITERA' ; 'LITERAL'
2259 LITER FDB DOCOL,STATE,AT,ZBRAN
2261 FDB COMPIL,LIT,COMMA
2266 FCC 'DLITERA' ; 'DLITERAL'
2269 DLITER FDB DOCOL,STATE,AT,ZBRAN
2271 FDB SWAP,LITER,LITER
2274 * ######>> screen 53 <<
2277 FCC 'INTERPRE' ; 'INTERPRET'
2281 INTER2 FDB DFIND,ZBRAN
2291 INTER5 FDB HERE,NUMB,DPL,AT,ONEP,ZBRAN
2295 INTER6 FDB DROP,LITER
2296 INTER7 FDB QSTACK,BRAN
2298 * FDB SEMIS never executed
2301 * ######>> screen 54 <<
2304 FCC 'IMMEDIAT' ; 'IMMEDIATE'
2307 IMMED FDB DOCOL,LATEST,CLITER
2314 FCC 'VOCABULAR' ; 'VOCABULARY'
2317 VOCAB FDB DOCOL,BUILDS,LIT,$81A0,COMMA,CURENT,AT,CFA
2318 FDB COMMA,HERE,VOCLIN,AT,COMMA,VOCLIN,STORE,DOES
2319 DOVOC FDB TWOP,CONTXT,STORE
2324 * Note: FORTH does not go here in the rom-able dictionary,
2325 * since FORTH is a type of variable.
2330 FCC 'DEFINITION' ; 'DEFINITIONS'
2333 DEFIN FDB DOCOL,CONTXT,AT,CURENT,STORE
2340 PAREN FDB DOCOL,CLITER
2345 * ######>> screen 55 <<
2351 QUIT FDB DOCOL,ZERO,BLK,STORE
2354 * Here is the outer interpretter
2355 * which gets a line of input, does it, prints " OK"
2357 QUIT2 FDB RPSTOR,CR,QUERY,INTERP,STATE,AT,ZEQU
2365 * FDB SEMIS ( never executed )
2369 FCC 'ABOR' ; 'ABORT'
2372 ABORT FDB DOCOL,SPSTOR,DEC,QSTACK,DRZERO,CR,PDOTQ
2377 * FDB SEMIS never executed
2380 * ######>> screen 56 <<
2381 * bootstrap code... moves rom contents to ram :
2388 CENT LDS #REND-1 top of destination
2389 LDX #ERAM top of stuff to move
2392 PSHS A ; move TASK & FORTH to ram
2396 LDS #XFENCE-1 put stack at a safe place for now
2409 WENT LDS #XFENCE-1 top of destination
2410 LDX #FENCIN top of stuff to move
2419 STX UP init user ram pointer
2422 NOP Here is a place to jump to special user
2423 NOP initializations such as I/0 interrups
2426 * For systems with TRACE:
2428 STX TRLIM clear trace mode
2430 STX BRKPT clear breakpoint address
2431 JMP RPSTOR+2 start the virtual machine running !
2433 * Here is the stuff that gets copied to ram :
2436 RAM FDB $3000,$3000,0,0
2440 FCC 'FORT' ; 'FORTH'
2443 RFORTH FDB DODOES,DOVOC,$81A0,TASK-7
2445 FCC "(C) Forth Interest Group, 1979"
2450 RTASK FDB DOCOL,SEMIS
2451 ERAM FCC "David Lion"
2454 * ######>> screen 57 <<
2460 STOD FDB DOCOL,DUP,ZLESS,MINUS
2480 SLMOD FDB DOCOL,TOR,STOD,FROMR,USLASH
2487 SLASH FDB DOCOL,SLMOD,SWAP,DROP
2495 MOD FDB DOCOL,SLMOD,DROP
2500 FCC '*/MO' ; '*/MOD'
2503 SSMOD FDB DOCOL,TOR,USTAR,FROMR,USLASH
2511 SSLASH FDB DOCOL,SSMOD,SWAP,DROP
2516 FCC 'M/MO' ; 'M/MOD'
2519 MSMOD FDB DOCOL,TOR,ZERO,R,USLASH
2520 FDB FROMR,SWAP,TOR,USLASH,FROMR
2528 ABS FDB DOCOL,DUP,ZLESS,ZBRAN
2538 DABS FDB DOCOL,DUP,ZLESS,ZBRAN
2543 * ######>> screen 58 <<
2564 PBUF FDB DOCOL,CLITER
2566 FDB PLUS,DUP,LIMIT,EQUAL,ZBRAN
2569 PBUF2 FDB DUP,PREV,AT,SUB
2574 FCC 'UPDAT' ; 'UPDATE'
2577 UPDATE FDB DOCOL,PREV,AT,AT,LIT,$8000,OR,PREV,AT,STORE
2582 FCC 'EMPTY-BUFFER' ; 'EMPTY-BUFFERS'
2585 MTBUF FDB DOCOL,FIRST,LIMIT,OVER,SUB,ERASE
2593 DRZERO FDB DOCOL,ZERO,OFSET,STORE
2596 * ======>> 174 <<== system dependant word
2601 DRONE FDB DOCOL,LIT,$07D0,OFSET,STORE
2604 * ######>> screen 59 <<
2607 FCC 'BUFFE' ; 'BUFFER'
2610 BUFFER FDB DOCOL,USE,AT,DUP,TOR
2611 BUFFR2 FDB PBUF,ZBRAN
2613 FDB USE,STORE,R,AT,ZLESS
2616 FDB R,TWOP,R,AT,LIT,$7FFF,AND,ZERO,RW
2617 BUFFR3 FDB R,STORE,R,PREV,STORE,FROMR,TWOP
2620 * ######>> screen 60 <<
2623 FCC 'BLOC' ; 'BLOCK'
2626 BLOCK FDB DOCOL,OFSET,AT,PLUS,TOR
2627 FDB PREV,AT,DUP,AT,R,SUB,DUP,PLUS,ZBRAN
2629 BLOCK3 FDB PBUF,ZEQU,ZBRAN
2631 FDB DROP,R,BUFFER,DUP,R,ONE,RW,TWO,SUB
2632 BLOCK4 FDB DUP,AT,R,SUB,DUP,PLUS,ZEQU,ZBRAN
2635 BLOCK5 FDB FROMR,DROP,TWOP
2638 * ######>> screen 61 <<
2641 FCC '(LINE' ; '(LINE)'
2644 PLINE FDB DOCOL,TOR,CLITER
2646 FDB BBUF,SSMOD,FROMR,BSCR,STAR,PLUS,BLOCK,PLUS,CLITER
2652 FCC '.LIN' ; '.LINE'
2655 DLINE FDB DOCOL,PLINE,DTRAIL,TYPE
2660 FCC 'MESSAG' ; 'MESSAGE'
2663 MESS FDB DOCOL,WARN,AT,ZBRAN
2669 FDB OFSET,AT,BSCR,SLASH,SUB,DLINE,BRAN
2673 FCC 'err # ' ; 'err # '
2679 FCC 'LOA' ; 'LOAD' : input:scr #
2682 LOAD FDB DOCOL,BLK,AT,TOR,IN,AT,TOR,ZERO,IN,STORE
2683 FDB BSCR,STAR,BLK,STORE
2684 FDB INTERP,FROMR,IN,STORE,FROMR,BLK,STORE
2692 ARROW FDB DOCOL,QLOAD,ZERO,IN,STORE,BSCR
2693 FDB BLK,AT,OVER,MOD,SUB,BLK,PSTORE
2698 * ######>> screen 63 <<
2699 * The next 4 subroutines are machine dependent, and are
2700 * called by words 13 through 16 in the dictionary.
2702 * ======>> 182 << code for EMIT
2706 BITB #2 check ready bit
2707 BEQ PEMIT+4 if not ready for more data
2713 RTS only A register may change
2714 * PEMIT JMP $E1D1 for MIKBUG
2715 * PEMIT FCB $3F,$11,$39 for PROTO
2716 * PEMIT JMP $D286 for Smoke Signal DOS
2718 * ======>> 183 << code for KEY
2723 BCC PKEY+4 no incoming data yet
2725 ANDA #$7F strip parity bit
2727 STB IOSTAT+1-UORIG,X
2731 * PKEY JMP $E1AC for MIKBUG
2732 * PKEY FCB $3F,$14,$39 for PROTO
2733 * PKEY JMP $D289 for Smoke Signal DOS
2735 * ######>> screen 64 <<
2736 * ======>> 184 << code for ?TERMINAL
2737 PQTER LDA ACIAC Test for 'break' condition
2738 ANDA #$11 mask framing error bit and
2741 LDA ACIAD clear input buffer
2748 * ======>> 185 << code for CR
2749 PCR LDA #$D carriage return
2755 LDB XDELAY+1-UORIG,X
2757 BMI PQTER2 return if minus
2758 PSHS B ; save counter
2759 BSR PEMIT print RUBOUTs to delay.....
2766 * ######>> screen 66 <<
2769 FCC '?DIS' ; '?DISC'
2775 * ######>> screen 67 <<
2778 FCC 'BLOCK-WRIT' ; 'BLOCK-WRITE'
2784 * ######>> screen 68 <<
2787 FCC 'BLOCK-REA' ; 'BLOCK-READ'
2793 *The next 3 words are written to create a substitute for disc
2794 * mass memory,located between $3210 & $3FFF in ram.
2801 FDB MEMEND a system dependent equate at front
2809 FDB MEMTOP ( $3FFF in this version )
2811 * ######>> screen 69 <<
2817 RW FDB DOCOL,TOR,BBUF,STAR,LO,PLUS,DUP,HI,GREAT,ZBRAN
2821 FCC ' Range ?' ; ' Range ?'
2829 * ######>> screen 72 <<
2834 TICK FDB DOCOL,DFIND,ZEQU,ZERO,QERR,DROP,LITER
2839 FCC 'FORGE' ; 'FORGET'
2842 FORGET FDB DOCOL,CURENT,AT,CONTXT,AT,SUB,CLITER
2844 FDB QERR,TICK,DUP,FENCE,AT,LESS,CLITER
2846 FDB QERR,DUP,ZERO,PORIG,GREAT,CLITER
2848 FDB QERR,DUP,NFA,DP,STORE,LFA,AT,CONTXT,AT,STORE
2851 * ######>> screen 73 <<
2857 BACK FDB DOCOL,HERE,SUB,COMMA
2862 FCC 'BEGI' ; 'BEGIN'
2865 BEGIN FDB DOCOL,QCOMP,HERE,ONE
2870 FCC 'ENDI' ; 'ENDIF'
2873 ENDIF FDB DOCOL,QCOMP,TWO,QPAIRS,HERE
2874 FDB OVER,SUB,SWAP,STORE
2882 THEN FDB DOCOL,ENDIF
2890 DO FDB DOCOL,COMPIL,XDO,HERE,THREE
2898 LOOP FDB DOCOL,THREE,QPAIRS,COMPIL,XLOOP,BACK
2903 FCC '+LOO' ; '+LOOP'
2906 PLOOP FDB DOCOL,THREE,QPAIRS,COMPIL,XPLOOP,BACK
2911 FCC 'UNTI' ; 'UNTIL' : ( same as END )
2914 UNTIL FDB DOCOL,ONE,QPAIRS,COMPIL,ZBRAN,BACK
2917 * ######>> screen 74 <<
2928 FCC 'AGAI' ; 'AGAIN'
2931 AGAIN FDB DOCOL,ONE,QPAIRS,COMPIL,BRAN,BACK
2936 FCC 'REPEA' ; 'REPEAT'
2939 REPEAT FDB DOCOL,TOR,TOR,AGAIN,FROMR,FROMR
2948 IF FDB DOCOL,COMPIL,ZBRAN,HERE,ZERO,COMMA,TWO
2956 ELSE FDB DOCOL,TWO,QPAIRS,COMPIL,BRAN,HERE
2957 FDB ZERO,COMMA,SWAP,TWO,ENDIF,TWO
2962 FCC 'WHIL' ; 'WHILE'
2965 WHILE FDB DOCOL,IF,TWOP
2968 * ######>> screen 75 <<
2971 FCC 'SPACE' ; 'SPACES'
2974 SPACES FDB DOCOL,ZERO,MAX,DDUP,ZBRAN
2977 SPACE2 FDB SPACE,XLOOP
2986 BDIGS FDB DOCOL,PAD,HLD,STORE
2994 EDIGS FDB DOCOL,DROP,DROP,HLD,AT,PAD,OVER,SUB
3002 SIGN FDB DOCOL,ROT,ZLESS,ZBRAN
3013 DIG FDB DOCOL,BASE,AT,MSMOD,ROT,CLITER
3031 DIGS2 FDB DIG,OVER,OVER,OR,ZEQU,ZBRAN
3035 * ######>> screen 76 <<
3041 DOTR FDB DOCOL,TOR,STOD,FROMR,DDOTR
3049 DDOTR FDB DOCOL,TOR,SWAP,OVER,DABS,BDIGS,DIGS,SIGN
3050 FDB EDIGS,FROMR,OVER,SUB,SPACES,TYPE
3058 DDOT FDB DOCOL,ZERO,DDOTR,SPACE
3065 DOT FDB DOCOL,STOD,DDOT
3072 QUEST FDB DOCOL,AT,DOT
3075 * ######>> screen 77 <<
3081 LIST FDB DOCOL,DEC,CR,DUP,SCR,STORE,PDOTQ
3087 LIST2 FDB CR,I,THREE
3088 FDB DOTR,SPACE,I,SCR,AT,DLINE,XLOOP
3095 FCC 'INDE' ; 'INDEX'
3098 INDEX FDB DOCOL,CR,ONEP,SWAP,XDO
3099 INDEX2 FDB CR,I,THREE
3100 FDB DOTR,SPACE,ZERO,I,DLINE
3110 FCC 'TRIA' ; 'TRIAD'
3113 TRIAD FDB DOCOL,THREE,SLASH,THREE,STAR
3114 FDB THREE,OVER,PLUS,SWAP,XDO
3116 FDB LIST,QTERM,ZBRAN
3126 * ######>> screen 78 <<
3129 FCC 'VLIS' ; 'VLIST'
3132 VLIST FDB DOCOL,CLITER
3134 FDB OUT,STORE,CONTXT,AT,AT
3135 VLIST1 FDB OUT,AT,COLUMS,AT,CLITER
3139 FDB CR,ZERO,OUT,STORE
3140 VLIST2 FDB DUP,IDDOT,SPACE,SPACE,PFA,LFA,AT
3141 FDB DUP,ZEQU,QTERM,OR,ZBRAN
3151 NOOP FDB NEXT a useful no-op
3152 ZZZZ FDB 0,0,0,0,0,0,0,0 end of rom program