3 * fig-FORTH FOR 6809, converted by unintelligent conversion from 6800 source.
8 * then add trace routines
11 * ASSEMBLY SOURCE LISTING
15 * WITH COMPILER SECURITY
16 * AND VARIABLE LENGTH NAMES
18 * This public domain publication is provided
19 * through the courtesy of:
25 * P.O. Box 8231 - San Jose, CA 95155 - (408) 277-0668
26 * Further distribution must include this notice.
28 NAM Copyright:FORTH Interest Group
31 * === FORTH-6800 06-06-79 21:OO
34 * This listing is in the PUBLIC DOMAIN and
35 * may be freely copied or published with the
36 * restriction that a credit line is printed
37 * with the material, crediting the
38 * authors and the FORTH INTEREST GROUP.
44 * === The Forth Interest Group
46 * === San Carlos, CA 94070
48 * === Unbounded Computing
49 * === 1134-K Aster Ave.
50 * === Sunnyvale, CA 94086
52 * This version was developed on an AMI EVK 300 PROTO
53 * system using an ACIA for the I/O. All terminal 1/0
54 * is done in three subroutines:
55 * PEMIT ( word # 182 )
58 * Note: PCR, also. (PRTCR)
60 * The FORTH words for disc related I/O follow the model
61 * of the FORTH Interest Group, but have not been
62 * tested using a real disc.
64 * Addresses in this implementation reflect the fact that,
65 * on the development system, it was convenient to
66 * write-protect memory at hex 1000, and leave the first
67 * 4K bytes write-enabled. As a consequence, code from
68 * location $1000 to lable ZZZZ could be put in ROM.
69 * Minor deviations from the model were made in the
70 * initialization and words ?STACK and FORGET
71 * in order to do this.
76 NBLK EQU 4 # of disc buffer blocks for virtual memory
77 * MEMEND EQU 132*NBLK+$3000 end of ram
78 MEMEND EQU 132*NBLK+$5000+132 end of ram with some breathing room (32K Coco)
79 * each block is 132 bytes in size,
80 * holding 128 characters
82 * MEMTOP EQU $3FFF absolute end of all ram
83 MEMTOP EQU $7FFF putative absolute end of all ram (32K Coco)
84 * No ACIA in Coco (how sad).
85 * ACIAC EQU $FBCE the ACIA control address and
86 * ACIAD EQU ACIAC+1 data address for PROTO
88 * MEMORY MAP for this 16K system (32K Coco):
89 * ( positioned so that systems with 4k byte write-
90 * protected segments can write protect FORTH )
92 * Read below and calculate it yourself:
93 * addr. contents pointer init by
94 * **** ******************************* ******* ******
96 * substitute for disc mass memory
99 * 4 buffer sectors of VIRTUAL MEMORY
101 * >>>>>> memory from here up must be RAM <<<<<<
104 * 6k of romable "FORTH" <== IP ABORT
106 * the VIRTUAL FORTH MACHINE
108 * 1004 (3004) <<< WARM START ENTRY >>>
109 * 1000 (3000) <<< COLD START ENTRY >>>
111 * >>>>>> memory from here down must be RAM <<<<<<
112 * FFE RETURN STACK base <== RP RINIT
116 * holds up to 132 characters
117 * and is scanned upward by IN
120 * F2F DATA STACK <== SP SP0,SINIT
121 * | grows downward from F2F
125 * I DICTIONARY grows upward
127 * 183 end of ram-dictionary. <== DP DPINIT
130 * 150 "FORTH" ( a word ) <=, <== CONTEXT
132 * 148 start of ram-dictionary.
134 * 100 user #l table of variables <= UP DPINIT
135 * F0 registers & pointers for the virtual machine
136 * scratch area used by various words
137 * E0 lowest address used by FORTH
143 * CONVENTIONS USED IN THIS PROGRAM ARE AS FOLLOWS :
145 * IP points to the current instruction ( pre-increment mode )
146 * RP points to second free byte (first free word) in return stack
147 * SP (hardware SP) points to first free byte in data stack
149 * when A AND B hold one 16 bit FORTH data word,
150 * A contains the high byte, B, the low byte.
162 N RMB 10 used as scratch by (FIND),ENCLOSE,CMOVE,EMIT,KEY,
163 * SP@,SWAP,DOES>,COLD
166 * These locations are used by the TRACE routine :
168 TRLIM RMB 1 the count for tracing without user intervention
169 TRACEM RMB 1 non-zero = trace mode
170 BRKPT RMB 2 the breakpoint address at which
171 * the program will go into trace mode
172 VECT RMB 2 vector to machine code
173 * (only needed if the TRACE routine is resident)
176 * Registers used by the FORTH virtual machine:
180 W RMB 2 the instruction register points to 6800 code
181 IP RMB 2 the instruction pointer points to pointer to 6800 code
182 RP RMB 2 the return stack pointer
183 UP RMB 2 the pointer to base of current user's 'USER' table
184 * ( altered during multi-tasking )
187 * This system is shown with one user, but additional users
188 * may be added by allocating additional user tables:
189 * UORIG2 RMB 64 data table for user #2
192 * Some of this stuff gets initialized during
193 * COLD start and WARM start:
194 * [ names correspond to FORTH words of similar (no X) name ]
198 UORIG RMB 6 3 reserved variables
199 XSPZER RMB 2 initial top of data stack for this user
200 XRZERO RMB 2 initial top of return stack
201 XTIB RMB 2 start of terminal input buffer
202 XWIDTH RMB 2 name field width
203 XWARN RMB 2 warning message mode (0 = no disc)
204 XFENCE RMB 2 fence for FORGET
205 XDP RMB 2 dictionary pointer
206 XVOCL RMB 2 vocabulary linking
207 XBLK RMB 2 disc block being accessed
208 XIN RMB 2 scan pointer into the block
209 XOUT RMB 2 cursor position
210 XSCR RMB 2 disc screen being accessed ( O=terminal )
211 XOFSET RMB 2 disc sector offset for multi-disc
212 XCONT RMB 2 last word in primary search vocabulary
213 XCURR RMB 2 last word in extensible vocabulary
214 XSTATE RMB 2 flag for 'interpret' or 'compile' modes
215 XBASE RMB 2 number base for I/O numeric conversion
216 XDPL RMB 2 decimal point place
218 XCSP RMB 2 current stack position, for compile checks
221 XDELAY RMB 2 carriage return delay count
222 XCOLUM RMB 2 carriage width
223 IOSTAT RMB 2 last acia status from write/read
234 * end of user table, start of common system variables
243 * These things, up through the lable 'REND', are overwritten
244 * at time of cold load and should have the same contents
251 FORTH FDB DODOES,DOVOC,$81A0,TASK-7
254 FCC "(C) Forth Interest Group, 1979"
262 REND EQU * ( first empty location in dictionary )
265 * Check the addresses yourself:
266 * The FORTH program ( address $1000 to $27FF ) is written
267 * so that it can be in a ROM, or write-protected if desired
270 * ######>> screen 3 <<
272 ***************************
273 ** C O L D E N T R Y **
274 ***************************
277 ***************************
278 ** W A R M E N T R Y **
279 ***************************
281 JMP WENT warm-start code, keeps current dictionary intact
284 ******* startup parmeters **************************
286 RPTIB EQU $200 Give us more room to breath.
287 SBUMPR EQU $10 Bumper area for stacks.
289 FDB $6800,6809 cpu & revision
290 FDB 0 topmost word in FORTH vocabulary
291 BACKSP FDB $7F backspace character for editing
292 UPINIT FDB UORIG initial user area
293 * SINIT FDB ORIG-$D0 initial top of data stack
294 SINIT FDB ORIG-RPTIB-SBUMPR*2
295 * RINIT FDB ORIG-2 initial top of return stack
296 RINIT FDB ORIG-SBUMPR
297 * FDB ORIG-$D0 terminal input buffer
298 FDB ORIG-RPTIB-SBUMPR
299 FDB 31 initial name field width
300 FDB 0 initial warning mode (0 = no disc)
301 FENCIN FDB REND initial fence
302 DPINIT FDB REND cold start value for DP
304 COLINT FDB 132 initial terminal carriage width
305 DELINT FDB 4 initial carriage return delay
306 ****************************************************
310 * ######>> screen 13 <<
311 * Calculate the cycles yourself:
312 PULABX PULS A 24 cycles until 'NEXT'
314 STABX STA 0,X 16 cycles until 'NEXT'
317 GETX LDA 0,X 18 cycles until 'NEXT'
319 PUSHBA PSHS B 8 cycles until 'NEXT'
325 * "NEXT" takes 38 cycles if TRACE is removed,
327 * and 95 cycles if NOT tracing. (Way bogus numbers by now.)
329 * = = = = = = = t h e v i r t u a l m a c h i n e = = = = =
332 LEAX 1,X pre-increment mode
335 NEXT2 LDX 0,X get W which points to CFA of word to be done
337 LDX 0,X get VECT which points to executable code
339 * The next instruction could be patched to JMP TRACE =
340 * if a TRACE routine is available: =
344 * JMP TRACE ( an alternate for the above )
346 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
353 FCC 'LI' ; 'LIT' : NOTE: this is different from LITERAL
355 FDB 0 link of zero to terminate dictionary scan
365 * ######>> screen 14 <<
367 CLITER FDB *+2 (this is an invisible word, with no header)
377 FCC 'EXECUT' ; 'EXECUTE'
382 LDX 0,X get code field address (CFA)
387 * ######>> screen 15 <<
390 FCC 'BRANC' ; 'BRANCH'
393 BRAN FDB ZBYES Go steal code in ZBRANCH
397 FCC '0BRANC' ; '0BRANCH'
403 * ABA is only used here.
404 * Could immediately convert PULs to LDD ,S++ ;
405 * with no need for trailing BCS to look for overflow
406 * because we are only testing for non-zero, but,
407 * converting as if by unintelligent macro:
410 * End of unintelligent ABA conversion.
413 ZBYES LDX IP Note: code is shared with BRANCH, (+LOOP), (LOOP)
421 ZBNO LDX IP no branch. This code is shared with (+LOOP), (LOOP).
422 LEAX 1,X jump over branch delta
427 * ######>> screen 16 <<
430 FCC '(LOOP' ; '(LOOP)'
435 LDB #1 get set to increment counter by 1
436 BRA XPLOP2 go steal other guy's code!
440 FCC '(+LOOP' ; '(+LOOP)'
443 XPLOOP FDB *+2 Note: +LOOP has an un-signed loop counter
447 BPL XPLOF forward looping
453 BRA XPLONO fall through
457 ADDB 3,X add it to counter
459 STB 3,X store new counter value
468 XPLONO LEAX 1,X done, don't branch back
473 BRA ZBNO use ZBRAN to skip over unused delta
475 * ######>> screen 17 <<
481 XDO FDB *+2 This is the RUNTIME DO, not the COMPILING DO
508 * ######>> screen 18 <<
514 DIGIT FDB *+2 NOTE: legal input range is 0-9, A-Z
518 BMI DIGIT2 IF LESS THAN '0', ILLEGAL
520 BMI DIGIT0 IF '9' OR LESS
522 BMI DIGIT2 if less than 'A'
524 BPL DIGIT2 if greater than 'Z'
525 SUBA #7 translate 'A' thru 'F'
527 BPL DIGIT2 if not less than the base
530 DIGIT1 STB 1,X store the flag
534 LEAS 1,S pop bottom number
536 STB 0,X make sure both bytes are 00
539 * ######>> screen 19 <<
541 * The word format in the dictionary is:
543 * char-count + $80 lowest address
548 * link high byte \___point to previous word
550 * CFA high byte \___pnt to 6800 code
559 FCC '(FIND' ; '(FIND)'
565 PD EQU N ptr to dict word being checked
568 PCT EQU N+6 ; PC in 6800 source
571 PFIND0 PULS A loop to get arguments
578 PFIND1 LDB 0,X get count dict count
584 LDA 0,X get count from arg
588 CMPA ,S+ compare lengths
598 TSTB is dict entry neg. ?
604 PFIND3 LDX 0,X get new link
605 BNE PFIND1 continue if link not=0
612 PFIND8 PSHS B ; sim CBA
616 PFIND9 LDB 0,X scan forward to end of this name
623 FOUND LDA PD compute CFA
642 * ######>> screen 20 <<
645 FCC 'ENCLOS' ; 'ENCLOSE'
649 * FC means offset (bytes) to First Character of next word
650 * EW " " to End of Word
651 * NC " " to Next Character to start next enclose at
654 PULS B now, get the low byte, for an 8-bit delimiter
658 * wait for a non-delimiter or a NUL
662 CMPA ,S+ CHECK FOR DELIM
667 * found first character. Push FC
668 ENCL3 LDA N found first char.
672 * wait for a delimiter or a NUL
676 CMPA ,S+ ckech for delim.
686 * advance and push NC
689 * found NUL before non-delimiter, therefore there is no word
690 ENCL6 LDB N found NUL
695 * found NUL following the word instead of SPACE
704 * ######>> screen 21 <<
705 * The next 4 words call system dependant I/O routines
706 * which are listed after word "-->" ( lable: "arrow" )
738 FCC '?TERMINA' ; '?TERMINAL'
744 JMP PUSHBA stack the flag
755 * ######>> screen 22 <<
758 FCC 'CMOV' ; 'CMOVE' : source, destination, count
761 CMOVE FDB *+2 takes ( 43+47*count cycles )
765 STA 0,X move parameters to scratch area
787 * ######>> screen 23 <<
799 * The following is a subroutine which
800 * multiplies top 2 words on stack,
801 * leaving 32-bit result: high order word in A,B
802 * low order word in 2nd word of stack.
804 USTARS LDA #16 bits/word counter
809 USTAR2 ROR 5,X shift multiplier
819 USTAR4 LEAS 1,S dump counter
822 * ######>> screen 24 <<
857 JMP SWAP+4 reverse quotient & remainder
859 * ######>> screen 25 <<
899 * ######>> screen 26 <<
919 * Potential problem area? No. ******
920 TFR X,S watch it ! X and S are not equal -- on 6800.
921 * But they are on 6809, and that's what we want here.
929 LDX RINIT initialize from rom constant
943 LDX 0,X get address we have just finished.
944 JMP NEXT+2 increment the return address & do next word
946 * ######>> screen 27 <<
1000 * ######>> screen 28 <<
1023 LDA #$80 check the sign bit
1032 * ######>> screen 29 <<
1068 FCC 'MINU' ; 'MINUS'
1082 FCC 'DMINU' ; 'DMINUS'
1099 * ######>> screen 30 <<
1151 * ######>> screen 31 <<
1162 PULS A get stack data
1164 ADDB 1,X add & store low byte
1166 ADCA 0,X add & store hi byte
1172 FCC 'TOGGL' ; 'TOGGLE'
1175 TOGGLE FDB DOCOL,OVER,CAT,XOR,SWAP,CSTORE
1178 * ######>> screen 32 <<
1231 * ######>> screen 33 <<
1236 COLON FDB DOCOL,QEXEC,SCSP,CURENT,AT,CONTXT,STORE
1240 * Here is the IP pusher for allowing
1241 * nested words in the virtual machine:
1242 * ( ;S is the equivalent un-nester )
1244 DOCOL LDX RP make room in the stack
1250 STA 2,X Store address of the high level word
1251 STB 3,X that we are starting to execute
1252 LDX W Get first sub-word of that definition
1253 JMP NEXT+2 and execute it
1256 FCB $C1 ; imnediate code
1259 SEMI FDB DOCOL,QCSP,COMPIL,SEMIS,SMUDGE,LBRAK
1262 * ######>> screen 34 <<
1265 FCC 'CONSTAN' ; 'CONSTANT'
1268 CON FDB DOCOL,CREATE,SMUDGE,COMMA,PSCODE
1271 LDB 3,X A & B now contain the constant
1276 FCC 'VARIABL' ; 'VARIABLE'
1279 VAR FDB DOCOL,CON,PSCODE
1283 ADCA #0 A,B now contain the address of the variable
1291 USER FDB DOCOL,CON,PSCODE
1292 DOUSER LDX W get offset into user's table
1295 ADDB UP+1 add to users base address
1297 JMP PUSHBA push address of user's variable
1299 * ######>> screen 35 <<
1333 BL FDB DOCON ascii blank
1338 FCC 'FIRS' ; 'FIRST'
1342 FDB MEMEND-528 (132 * NBLK)
1346 FCC 'LIMI' ; 'LIMIT' : ( the end of memory +1 )
1354 FCC 'B/BU' ; 'B/BUF' : (bytes/buffer)
1362 FCC 'B/SC' ; 'B/SCR' : (blocks/screen)
1367 * blocks/screen = 1024 / "B/BUF" = 8
1371 FCC '+ORIGI' ; '+ORIGIN'
1374 PORIG FDB DOCOL,LIT,ORIG,PLUS
1377 * ######>> screen 36 <<
1404 FCC 'WIDT' ; 'WIDTH'
1412 FCC 'WARNIN' ; 'WARNING'
1420 FCC 'FENC' ; 'FENCE'
1428 FCC 'D' ; 'DP' : points to first free byte at end of dictionary
1431 DICPT FDB DOUSER ; DP in 6800 source
1436 FCC 'VOC-LIN' ; 'VOC-LINK'
1452 FCC 'I' ; 'IN' : scan pointer for input line buffer
1473 * ######>> screen 37 <<
1477 FCC 'OFFSE' ; 'OFFSET'
1485 FCC 'CONTEX' ; 'CONTEXT' : points to pointer to vocab to search first
1493 FCC 'CURREN' ; 'CURRENT' : points to ptr. to vocab being extended
1501 FCC 'STAT' ; 'STATE' : 1 if compiling, 0 if not
1509 FCC 'BAS' ; 'BASE' : number base for all input & output
1555 * ======>> 82.5 <<== SPECIAL
1557 FCC 'COLUMN' ; 'COLUMNS' : line width of terminal
1563 * ######>> screen 38 <<
1569 ONEP FDB DOCOL,ONE,PLUS
1577 TWOP FDB DOCOL,TWO,PLUS
1585 HERE FDB DOCOL,DICPT,AT
1590 FCC 'ALLO' ; 'ALLOT'
1593 ALLOT FDB DOCOL,DICPT,PSTORE
1600 COMMA FDB DOCOL,HERE,STORE,TWO,ALLOT
1608 CCOMM FDB DOCOL,HERE,CSTORE,ONE,ALLOT
1615 SUB FDB DOCOL,MINUS,PLUS
1622 EQUAL FDB DOCOL,SUB,ZEQU
1650 GREAT FDB DOCOL,SWAP,LESS
1658 ROT FDB DOCOL,TOR,SWAP,FROMR,SWAP
1663 FCC 'SPAC' ; 'SPACE'
1666 SPACE FDB DOCOL,BL,EMIT
1674 MIN FDB DOCOL,OVER,OVER,GREAT,ZBRAN
1685 MAX FDB DOCOL,OVER,OVER,LESS,ZBRAN
1696 DDUP FDB DOCOL,DUP,ZBRAN
1701 * ######>> screen 39 <<
1704 FCC 'TRAVERS' ; 'TRAVERSE'
1708 TRAV2 FDB OVER,PLUS,CLITER
1710 FDB OVER,CAT,LESS,ZBRAN
1717 FCC 'LATES' ; 'LATEST'
1720 LATEST FDB DOCOL,CURENT,AT,AT
1728 LFA FDB DOCOL,CLITER
1738 CFA FDB DOCOL,TWO,SUB
1746 NFA FDB DOCOL,CLITER
1748 FDB SUB,ONE,MINUS,TRAV
1756 PFA FDB DOCOL,ONE,TRAV,CLITER
1761 * ######>> screen 40 <<
1767 SCSP FDB DOCOL,SPAT,CSP,STORE
1772 FCC '?ERRO' ; '?ERROR'
1775 QERR FDB DOCOL,SWAP,ZBRAN
1784 FCC '?COM' ; '?COMP'
1787 QCOMP FDB DOCOL,STATE,AT,ZEQU,CLITER
1794 FCC '?EXE' ; '?EXEC'
1797 QEXEC FDB DOCOL,STATE,AT,CLITER
1804 FCC '?PAIR' ; '?PAIRS'
1807 QPAIRS FDB DOCOL,SUB,CLITER
1817 QCSP FDB DOCOL,SPAT,CSP,AT,SUB,CLITER
1824 FCC '?LOADIN' ; '?LOADING'
1827 QLOAD FDB DOCOL,BLK,AT,ZEQU,CLITER
1832 * ######>> screen 41 <<
1835 FCC 'COMPIL' ; 'COMPILE'
1838 COMPIL FDB DOCOL,QCOMP,FROMR,TWOP,DUP,TOR,AT,COMMA
1845 LBRAK FDB DOCOL,ZERO,STATE,STORE
1852 RBRAK FDB DOCOL,CLITER
1859 FCC 'SMUDG' ; 'SMUDGE'
1862 SMUDGE FDB DOCOL,LATEST,CLITER
1880 FCC 'DECIMA' ; 'DECIMAL'
1885 FCB 10 note: hex "A"
1889 * ######>> screen 42 <<
1892 FCC '(;CODE' ; '(;CODE)'
1895 PSCODE FDB DOCOL,FROMR,TWOP,LATEST,PFA,CFA,STORE
1900 FCC ';COD' ; ';CODE'
1903 SEMIC FDB DOCOL,QCSP,COMPIL,PSCODE,SMUDGE,LBRAK,QSTACK
1905 * note: "QSTACK" will be replaced by "ASSEMBLER" later
1907 * ######>> screen 43 <<
1910 FCC '<BUILD' ; '<BUILDS'
1913 BUILDS FDB DOCOL,ZERO,CON
1918 FCC 'DOES' ; 'DOES>'
1921 DOES FDB DOCOL,FROMR,TWOP,LATEST,PFA,STORE
1925 LDX RP make room on return stack
1929 STA 2,X push return address
1931 LDX W get addr of pointer to run-time code
1934 STX N stash it in scratch area
1937 CLRA get address of parameter
1941 PSHS B and push it on data stack
1945 * ######>> screen 44 <<
1948 FCC 'COUN' ; 'COUNT'
1951 COUNT FDB DOCOL,DUP,ONEP,SWAP,CAT
1959 TYPE FDB DOCOL,DDUP,ZBRAN
1961 FDB OVER,PLUS,SWAP,XDO
1962 TYPE2 FDB I,CAT,EMIT,XLOOP
1971 FCC '-TRAILIN' ; '-TRAILING'
1974 DTRAIL FDB DOCOL,DUP,ZERO,XDO
1975 DTRAL2 FDB OVER,OVER,PLUS,ONE,SUB,CAT,BL
1990 PDOTQ FDB DOCOL,R,TWOP,COUNT,DUP,ONEP
1991 FDB FROMR,PLUS,TOR,TYPE
2004 FDB COMPIL,PDOTQ,WORD
2005 FDB HERE,CAT,ONEP,ALLOT,BRAN
2007 DOTQ1 FDB WORD,HERE,COUNT,TYPE
2010 * ######>> screen 45 <<
2011 * ======>> 126 <<== MACHINE DEPENDENT
2013 FCC '?STAC' ; '?STACK'
2016 QSTACK FDB DOCOL,CLITER
2018 FDB PORIG,AT,TWO,SUB,SPAT,LESS,ONE
2020 * prints 'empty stack'
2023 * Here, we compare with a value at least 128
2024 * higher than dict. ptr. (DP)
2031 * prints 'full stack'
2035 * ======>> 127 << this word's function
2036 * is done by ?STACK in this version
2041 *QFREE FDB DOCOL,SPAT,HERE,CLITER
2043 * FDB PLUS,LESS,TWO,QERR,SEMIS
2045 * ######>> screen 46 <<
2048 FCC 'EXPEC' ; 'EXPECT'
2051 EXPECT FDB DOCOL,OVER,PLUS,OVER,XDO
2052 EXPEC2 FDB KEY,DUP,CLITER
2054 FDB PORIG,AT,EQUAL,ZBRAN
2057 FCB 8 ( backspace character to emit )
2058 FDB OVER,I,EQUAL,DUP,FROMR,TWO,SUB,PLUS
2061 EXPEC3 FDB DUP,CLITER
2062 FCB $D ( carriage return )
2065 FDB LEAVE,DROP,BL,ZERO,BRAN
2068 EXPEC5 FDB I,CSTORE,ZERO,I,ONEP,STORE
2069 EXPEC6 FDB EMIT,XLOOP
2076 FCC 'QUER' ; 'QUERY'
2079 QUERY FDB DOCOL,TIB,AT,COLUMS
2080 FDB AT,EXPECT,ZERO,IN,STORE
2084 FCB $C1 immediate < carriage return >
2087 NULL FDB DOCOL,BLK,AT,ZBRAN
2090 FDB ZERO,IN,STORE,BLK,AT,BSCR,MOD
2092 * check for end of screen
2095 FDB QEXEC,FROMR,DROP
2098 NULL2 FDB FROMR,DROP
2101 * ######>> screen 47 <<
2107 FILL FDB DOCOL,SWAP,TOR,OVER,CSTORE,DUP,ONEP
2108 FDB FROMR,ONE,SUB,CMOVE
2113 FCC 'ERAS' ; 'ERASE'
2116 ERASE FDB DOCOL,ZERO,FILL
2121 FCC 'BLANK' ; 'BLANKS'
2124 BLANKS FDB DOCOL,BL,FILL
2132 HOLD FDB DOCOL,LIT,$FFFF,HLD,PSTORE,HLD,AT,CSTORE
2140 PAD FDB DOCOL,HERE,CLITER
2145 * ######>> screen 48 <<
2151 WORD FDB DOCOL,BLK,AT,ZBRAN
2153 FDB BLK,AT,BLOCK,BRAN
2156 WORD3 FDB IN,AT,PLUS,SWAP,ENCLOS,HERE,CLITER
2158 FDB BLANKS,IN,PSTORE,OVER,SUB,TOR,R,HERE
2159 FDB CSTORE,PLUS,HERE,ONEP,FROMR,CMOVE
2162 * ######>> screen 49 <<
2165 FCC '(NUMBER' ; '(NUMBER)'
2169 PNUMB2 FDB ONEP,DUP,TOR,CAT,BASE,AT,DIGIT,ZBRAN
2171 FDB SWAP,BASE,AT,USTAR,DROP,ROT,BASE
2172 FDB AT,USTAR,DPLUS,DPL,AT,ONEP,ZBRAN
2175 PNUMB3 FDB FROMR,BRAN
2182 FCC 'NUMBE' ; 'NUMBER'
2185 NUMB FDB DOCOL,ZERO,ZERO,ROT,DUP,ONEP,CAT,CLITER
2187 FDB EQUAL,DUP,TOR,PLUS,LIT,$FFFF
2188 NUMB1 FDB DPL,STORE,PNUMB,DUP,CAT,BL,SUB
2193 FDB SUB,ZERO,QERR,ZERO,BRAN
2195 NUMB2 FDB DROP,FROMR,ZBRAN
2202 FCC '-FIN' ; '-FIND'
2205 DFIND FDB DOCOL,BL,WORD,HERE,CONTXT,AT,AT
2206 FDB PFIND,DUP,ZEQU,ZBRAN
2208 FDB DROP,HERE,LATEST,PFIND
2211 * ######>> screen 50 <<
2214 FCC '(ABORT' ; '(ABORT)'
2217 PABORT FDB DOCOL,ABORT
2222 FCC 'ERRO' ; 'ERROR'
2225 ERROR FDB DOCOL,WARN,AT,ZLESS
2227 * note: WARNING is -1 to abort, 0 to print error #
2228 * and 1 to print error message from disc
2231 ERROR2 FDB HERE,COUNT,TYPE,PDOTQ
2234 FDB MESS,SPSTOR,IN,AT,BLK,AT,QUIT
2242 IDDOT FDB DOCOL,PAD,CLITER
2245 FCB $5F ( underline )
2246 FDB FILL,DUP,PFA,LFA,OVER,SUB,PAD
2247 FDB SWAP,CMOVE,PAD,COUNT,CLITER
2252 * ######>> screen 51 <<
2255 FCC 'CREAT' ; 'CREATE'
2258 CREATE FDB DOCOL,DFIND,ZBRAN
2264 FDB NFA,IDDOT,CLITER
2267 CREAT2 FDB HERE,DUP,CAT,WIDTH,AT,MIN
2268 FDB ONEP,ALLOT,DUP,CLITER
2270 FDB TOGGLE,HERE,ONE,SUB,CLITER
2272 FDB TOGGLE,LATEST,COMMA,CURENT,AT,STORE
2276 * ######>> screen 52 <<
2279 FCC '[COMPILE' ; '[COMPILE]'
2282 BCOMP FDB DOCOL,DFIND,ZEQU,ZERO,QERR,DROP,CFA,COMMA
2287 FCC 'LITERA' ; 'LITERAL'
2290 LITER FDB DOCOL,STATE,AT,ZBRAN
2292 FDB COMPIL,LIT,COMMA
2297 FCC 'DLITERA' ; 'DLITERAL'
2300 DLITER FDB DOCOL,STATE,AT,ZBRAN
2302 FDB SWAP,LITER,LITER
2305 * ######>> screen 53 <<
2308 FCC 'INTERPRE' ; 'INTERPRET'
2312 INTER2 FDB DFIND,ZBRAN
2322 INTER5 FDB HERE,NUMB,DPL,AT,ONEP,ZBRAN
2326 INTER6 FDB DROP,LITER
2327 INTER7 FDB QSTACK,BRAN
2329 * FDB SEMIS never executed
2332 * ######>> screen 54 <<
2335 FCC 'IMMEDIAT' ; 'IMMEDIATE'
2338 IMMED FDB DOCOL,LATEST,CLITER
2345 FCC 'VOCABULAR' ; 'VOCABULARY'
2348 VOCAB FDB DOCOL,BUILDS,LIT,$81A0,COMMA,CURENT,AT,CFA
2349 FDB COMMA,HERE,VOCLIN,AT,COMMA,VOCLIN,STORE,DOES
2350 DOVOC FDB TWOP,CONTXT,STORE
2355 * Note: FORTH does not go here in the rom-able dictionary,
2356 * since FORTH is a type of variable.
2361 FCC 'DEFINITION' ; 'DEFINITIONS'
2364 DEFIN FDB DOCOL,CONTXT,AT,CURENT,STORE
2371 PAREN FDB DOCOL,CLITER
2376 * ######>> screen 55 <<
2382 QUIT FDB DOCOL,ZERO,BLK,STORE
2385 * Here is the outer interpretter
2386 * which gets a line of input, does it, prints " OK"
2388 QUIT2 FDB RPSTOR,CR,QUERY,INTERP,STATE,AT,ZEQU
2396 * FDB SEMIS ( never executed )
2400 FCC 'ABOR' ; 'ABORT'
2403 ABORT FDB DOCOL,SPSTOR,DEC,QSTACK,DRZERO,CR,PDOTQ
2408 * FDB SEMIS never executed
2411 * ######>> screen 56 <<
2412 * bootstrap code... moves rom contents to ram :
2419 * CENT LDS #REND-1 top of destination on 6800
2420 CENT LDA #PGBASE/$100
2422 LDS #REND top of destination on 6809
2423 LDX #ERAM top of stuff to move
2426 PSHS A move TASK & FORTH to ram
2430 * LDS #XFENCE-1 put stack at a safe place for now -- 6800
2431 * But only matters if we're interrupted.
2432 LDS #XFENCE put stack at a safe place for now -- 6809
2445 * WENT LDS #XFENCE-1 top of destination -- 6800
2446 WENT LDS #XFENCE top of destination -- 6809
2447 LDX #FENCIN top of stuff to move
2454 * Don't get faked out.
2455 * This is just a safe place for the stack if we're interrupted.
2456 * ABORT sends us through RP! and then SP!
2457 * And SP! loads S through X, which is just fine for the 6809, too.
2460 STX UP init user ram pointer
2463 NOP Here is a place to jump to special user
2464 NOP initializations such as I/0 interrups
2467 * For systems with TRACE:
2469 STX TRLIM clear trace mode
2471 STX BRKPT clear breakpoint address
2472 JMP RPSTOR+2 start the virtual machine running !
2474 * Here is the stuff that gets copied to ram :
2477 RAM FDB $3000,$3000,0,0
2481 FCC 'FORT' ; 'FORTH'
2484 RFORTH FDB DODOES,DOVOC,$81A0,TASK-7
2486 FCC "(C) Forth Interest Group, 1979"
2491 RTASK FDB DOCOL,SEMIS
2492 ERAM FCC "David Lion"
2495 * ######>> screen 57 <<
2501 STOD FDB DOCOL,DUP,ZLESS,MINUS
2521 SLMOD FDB DOCOL,TOR,STOD,FROMR,USLASH
2528 SLASH FDB DOCOL,SLMOD,SWAP,DROP
2536 MOD FDB DOCOL,SLMOD,DROP
2541 FCC '*/MO' ; '*/MOD'
2544 SSMOD FDB DOCOL,TOR,USTAR,FROMR,USLASH
2552 SSLASH FDB DOCOL,SSMOD,SWAP,DROP
2557 FCC 'M/MO' ; 'M/MOD'
2560 MSMOD FDB DOCOL,TOR,ZERO,R,USLASH
2561 FDB FROMR,SWAP,TOR,USLASH,FROMR
2569 ABS FDB DOCOL,DUP,ZLESS,ZBRAN
2579 DABS FDB DOCOL,DUP,ZLESS,ZBRAN
2584 * ######>> screen 58 <<
2605 PBUF FDB DOCOL,CLITER
2607 FDB PLUS,DUP,LIMIT,EQUAL,ZBRAN
2610 PBUF2 FDB DUP,PREV,AT,SUB
2615 FCC 'UPDAT' ; 'UPDATE'
2618 UPDATE FDB DOCOL,PREV,AT,AT,LIT,$8000,OR,PREV,AT,STORE
2623 FCC 'EMPTY-BUFFER' ; 'EMPTY-BUFFERS'
2626 MTBUF FDB DOCOL,FIRST,LIMIT,OVER,SUB,ERASE
2634 DRZERO FDB DOCOL,ZERO,OFSET,STORE
2637 * ======>> 174 <<== system dependant word
2642 DRONE FDB DOCOL,LIT,$07D0,OFSET,STORE
2645 * ######>> screen 59 <<
2648 FCC 'BUFFE' ; 'BUFFER'
2651 BUFFER FDB DOCOL,USE,AT,DUP,TOR
2652 BUFFR2 FDB PBUF,ZBRAN
2654 FDB USE,STORE,R,AT,ZLESS
2657 FDB R,TWOP,R,AT,LIT,$7FFF,AND,ZERO,RW
2658 BUFFR3 FDB R,STORE,R,PREV,STORE,FROMR,TWOP
2661 * ######>> screen 60 <<
2664 FCC 'BLOC' ; 'BLOCK'
2667 BLOCK FDB DOCOL,OFSET,AT,PLUS,TOR
2668 FDB PREV,AT,DUP,AT,R,SUB,DUP,PLUS,ZBRAN
2670 BLOCK3 FDB PBUF,ZEQU,ZBRAN
2672 FDB DROP,R,BUFFER,DUP,R,ONE,RW,TWO,SUB
2673 BLOCK4 FDB DUP,AT,R,SUB,DUP,PLUS,ZEQU,ZBRAN
2676 BLOCK5 FDB FROMR,DROP,TWOP
2679 * ######>> screen 61 <<
2682 FCC '(LINE' ; '(LINE)'
2685 PLINE FDB DOCOL,TOR,CLITER
2687 FDB BBUF,SSMOD,FROMR,BSCR,STAR,PLUS,BLOCK,PLUS,CLITER
2693 FCC '.LIN' ; '.LINE'
2696 DLINE FDB DOCOL,PLINE,DTRAIL,TYPE
2701 FCC 'MESSAG' ; 'MESSAGE'
2704 MESS FDB DOCOL,WARN,AT,ZBRAN
2710 FDB OFSET,AT,BSCR,SLASH,SUB,DLINE,BRAN
2714 FCC 'err # ' ; 'err # '
2720 FCC 'LOA' ; 'LOAD' : input:scr #
2723 LOAD FDB DOCOL,BLK,AT,TOR,IN,AT,TOR,ZERO,IN,STORE
2724 FDB BSCR,STAR,BLK,STORE
2725 FDB INTERP,FROMR,IN,STORE,FROMR,BLK,STORE
2733 ARROW FDB DOCOL,QLOAD,ZERO,IN,STORE,BSCR
2734 FDB BLK,AT,OVER,MOD,SUB,BLK,PSTORE
2739 * ######>> screen 63 <<
2740 * The next 4 subroutines are machine dependent, and are
2741 * called by words 13 through 16 in the dictionary.
2743 * ======>> 182 << code for EMIT
2744 * character to output in A
2752 * PEMIT STB N save B
2755 * BITB #2 check ready bit
2756 * BEQ PEMIT+4 if not ready for more data
2759 * STB IOSTAT-UORIG,X
2760 * LDB N recover B & X
2762 * RTS only A register may change
2763 * PEMIT JMP $E1D1 for MIKBUG
2764 * PEMIT FCB $3F,$11,$39 for PROTO
2765 * PEMIT JMP $D286 for Smoke Signal DOS
2767 * ======>> 183 << code for KEY
2768 * Returns input character in A
2774 LDB [$0088] (locate) save
2785 * BCC PKEY+4 no incoming data yet
2787 * ANDA #$7F strip parity bit
2789 * STB IOSTAT+1-UORIG,X
2793 * PKEY JMP $E1AC for MIKBUG
2794 * PKEY FCB $3F,$14,$39 for PROTO
2795 * PKEY JMP $D289 for Smoke Signal DOS
2797 * ######>> screen 64 <<
2798 * ======>> 184 << code for ?TERMINAL
2799 * Returns flag in A (non-zero if BREAK).
2810 PQTERN PULS Y,U,DP,PC
2812 * PQTER LDA ACIAC Test for 'break' condition
2813 * ANDA #$11 mask framing error bit and
2814 ** input buffer full
2816 * LDA ACIAD clear input buffer
2823 * ======>> 185 << code for CR
2825 PRTCR LDA #$D carriage return ; PCR in 6800 source
2826 BRA PEMIT Let PEMIT return
2833 * LDB XDELAY+1-UORIG,X
2835 * BMI PQTER2 return if minus
2836 * PSHS B save counter
2837 * BSR PEMIT print RUBOUTs to delay.....
2844 * ######>> screen 66 <<
2847 FCC '?DIS' ; '?DISC'
2853 * ######>> screen 67 <<
2856 FCC 'BLOCK-WRIT' ; 'BLOCK-WRITE'
2862 * ######>> screen 68 <<
2865 FCC 'BLOCK-REA' ; 'BLOCK-READ'
2871 *The next 3 words are written to create a substitute for disc
2872 * mass memory,located between $3210 & $3FFF in ram.
2879 FDB MEMEND a system dependent equate at front
2887 FDB MEMTOP ( $3FFF in this version )
2889 * ######>> screen 69 <<
2895 RW FDB DOCOL,TOR,BBUF,STAR,LO,PLUS,DUP,HI,GREAT,ZBRAN
2899 FCC ' Range ?' ; ' Range ?'
2907 * ######>> screen 72 <<
2912 TICK FDB DOCOL,DFIND,ZEQU,ZERO,QERR,DROP,LITER
2917 FCC 'FORGE' ; 'FORGET'
2920 FORGET FDB DOCOL,CURENT,AT,CONTXT,AT,SUB,CLITER
2922 FDB QERR,TICK,DUP,FENCE,AT,LESS,CLITER
2924 FDB QERR,DUP,ZERO,PORIG,GREAT,CLITER
2926 FDB QERR,DUP,NFA,DICPT,STORE,LFA,AT,CONTXT,AT,STORE
2929 * ######>> screen 73 <<
2935 BACK FDB DOCOL,HERE,SUB,COMMA
2940 FCC 'BEGI' ; 'BEGIN'
2943 BEGIN FDB DOCOL,QCOMP,HERE,ONE
2948 FCC 'ENDI' ; 'ENDIF'
2951 ENDIF FDB DOCOL,QCOMP,TWO,QPAIRS,HERE
2952 FDB OVER,SUB,SWAP,STORE
2960 THEN FDB DOCOL,ENDIF
2968 DO FDB DOCOL,COMPIL,XDO,HERE,THREE
2976 LOOP FDB DOCOL,THREE,QPAIRS,COMPIL,XLOOP,BACK
2981 FCC '+LOO' ; '+LOOP'
2984 PLOOP FDB DOCOL,THREE,QPAIRS,COMPIL,XPLOOP,BACK
2989 FCC 'UNTI' ; 'UNTIL' : ( same as END )
2992 UNTIL FDB DOCOL,ONE,QPAIRS,COMPIL,ZBRAN,BACK
2995 * ######>> screen 74 <<
3006 FCC 'AGAI' ; 'AGAIN'
3009 AGAIN FDB DOCOL,ONE,QPAIRS,COMPIL,BRAN,BACK
3014 FCC 'REPEA' ; 'REPEAT'
3017 REPEAT FDB DOCOL,TOR,TOR,AGAIN,FROMR,FROMR
3026 IF FDB DOCOL,COMPIL,ZBRAN,HERE,ZERO,COMMA,TWO
3034 ELSE FDB DOCOL,TWO,QPAIRS,COMPIL,BRAN,HERE
3035 FDB ZERO,COMMA,SWAP,TWO,ENDIF,TWO
3040 FCC 'WHIL' ; 'WHILE'
3043 WHILE FDB DOCOL,IF,TWOP
3046 * ######>> screen 75 <<
3049 FCC 'SPACE' ; 'SPACES'
3052 SPACES FDB DOCOL,ZERO,MAX,DDUP,ZBRAN
3055 SPACE2 FDB SPACE,XLOOP
3064 BDIGS FDB DOCOL,PAD,HLD,STORE
3072 EDIGS FDB DOCOL,DROP,DROP,HLD,AT,PAD,OVER,SUB
3080 SIGN FDB DOCOL,ROT,ZLESS,ZBRAN
3091 DIG FDB DOCOL,BASE,AT,MSMOD,ROT,CLITER
3109 DIGS2 FDB DIG,OVER,OVER,OR,ZEQU,ZBRAN
3113 * ######>> screen 76 <<
3119 DOTR FDB DOCOL,TOR,STOD,FROMR,DDOTR
3127 DDOTR FDB DOCOL,TOR,SWAP,OVER,DABS,BDIGS,DIGS,SIGN
3128 FDB EDIGS,FROMR,OVER,SUB,SPACES,TYPE
3136 DDOT FDB DOCOL,ZERO,DDOTR,SPACE
3143 DOT FDB DOCOL,STOD,DDOT
3150 QUEST FDB DOCOL,AT,DOT
3153 * ######>> screen 77 <<
3159 LIST FDB DOCOL,DEC,CR,DUP,SCR,STORE,PDOTQ
3165 LIST2 FDB CR,I,THREE
3166 FDB DOTR,SPACE,I,SCR,AT,DLINE,XLOOP
3173 FCC 'INDE' ; 'INDEX'
3176 INDEX FDB DOCOL,CR,ONEP,SWAP,XDO
3177 INDEX2 FDB CR,I,THREE
3178 FDB DOTR,SPACE,ZERO,I,DLINE
3188 FCC 'TRIA' ; 'TRIAD'
3191 TRIAD FDB DOCOL,THREE,SLASH,THREE,STAR
3192 FDB THREE,OVER,PLUS,SWAP,XDO
3194 FDB LIST,QTERM,ZBRAN
3204 * ######>> screen 78 <<
3207 FCC 'VLIS' ; 'VLIST'
3210 VLIST FDB DOCOL,CLITER
3212 FDB OUT,STORE,CONTXT,AT,AT
3213 VLIST1 FDB OUT,AT,COLUMS,AT,CLITER
3217 FDB CR,ZERO,OUT,STORE
3218 VLIST2 FDB DUP,IDDOT,SPACE,SPACE,PFA,LFA,AT
3219 FDB DUP,ZEQU,QTERM,OR,ZBRAN
3229 NOOP FDB NEXT a useful no-op
3230 ZZZZ FDB 0,0,0,0,0,0,0,0 end of rom program