3 * fig-FORTH FOR 6800 -- converted mechanically to 6809
4 * ASSEMBLY SOURCE LISTING
8 * WITH COMPILER SECURITY
9 * AND VARIABLE LENGTH NAMES
13 * Modified for TRS-80/Tandy Color Computer, Dragon, etc., JMR
15 * This public domain publication is provided
16 * through the courtesy of:
22 * P.O. Box 8231 - San Jose, CA 95155 - (408) 277-0668
23 * Further distribution must include this notice.
25 NAM Copyright:FORTH Interest Group
28 * === FORTH-6800 06-06-79 21:OO
31 * The following constitutes the original license:
32 *=====================LICENSE====================
33 * This listing is in the PUBLIC DOMAIN and
34 * may be freely copied or published with the
35 * restriction that a credit line is printed
36 * with the material, crediting the
37 * authors and the FORTH INTEREST GROUP.
43 * === The Forth Interest Group
45 * === San Carlos, CA 94070
47 * === Unbounded Computing
48 * === 1134-K Aster Ave.
49 * === Sunnyvale, CA 94086
50 *===================END-LICENSE==================
51 * Note that the assertion of attribution terms contradicts with a
52 * pure assignment to the public domain.
53 * Because of the terms, copyright should be understood
54 * to be asserted by the authors.
55 * Attribution, according to the above, should be understood
58 * === Conversion to 6809
59 * === and modifications for Color Computer, etc., by Joel Rees, Reiisi Kenkyuu
60 * Conversions and modifications copyright Joel Rees, 2018.
61 * Permission to use, modify, distribute, and publish the modifications
62 * is extended under the attribution terms given above,
63 * with the explicitly affirmed obligation to retain intact
64 * all authorship and copyright notices, and license notices.
66 * Note that, under my (Joel Rees) recollection and understanding of the
67 * legal/political context of the original context of publication,
68 * right to use source code in one's possession was not considered
69 * deniable in any practical or meaningful sense.
70 * (Laws such as the DMCA had been proposed by certain advocates for
71 * the concept of intellectual property under other names,
72 * but were considered unenforceable and impracticable,
73 * thus contrary to the purpose of law,
74 * a waste of resources, and the height of discourtesy
75 * by the general community of software practicioners at the time,
76 * to the best of my understanding and recollection.)
77 * Thus, the lack of explicit mention of a right to use in the terms of
78 * the effective license should in no wise be considered to imply a
82 * This version was developed on an AMI EVK 300 PROTO
83 * system using an ACIA for the I/O. All terminal 1/0
84 * is done in three subroutines:
85 * PEMIT ( word # 182 )
88 * =6809= See the above routines for Color Computer calls. JMR
90 * The FORTH words for disc related I/O follow the model
91 * of the FORTH Interest Group, but have not been
92 * tested using a real disc.
93 * === True disk I/O not implemented in v. 1.00.01. JMR
95 * Addresses in this implementation reflect the fact that,
96 * on the development system, it was convenient to
97 * write-protect memory at hex 1000, and leave the first
98 * 4K bytes write-enabled. As a consequence, code from
99 * location $1000 to lable ZZZZ could be put in ROM.
100 * Minor deviations from the model were made in the
101 * initialization and words ?STACK and FORGET
102 * in order to do this.
103 * =6809= Note that there is no write-protect on stock Color Computer,
104 * =6809= and other addresses will be adjusted, rather, for the Color Computer hardware.
109 NBLK EQU 4 # of disc buffer blocks for virtual memory
110 * MEMEND EQU 132*NBLK+$3000 end of ram
111 MEMEND EQU 132*NBLK+$4000+132 end of ram with some breathing room
112 * each block is 132 bytes in size,
113 * holding 128 characters
115 * MEMTOP EQU $3FFF absolute end of all ram
116 MEMTOP EQU $7FFF putative absolute end of all ram
117 * ACIAC EQU $FBCE the ACIA control address and
118 ACIAC EQU $FCF4 the ACIA control address and
119 ACIAD EQU ACIAC+1 data address for PROTO
120 * =6809= There is no ACIA (darn it!), but we need the addresses until we redefine the I/O routines.
122 * MEMORY MAP for this (not) 16K system:
123 * ( (*not*) positioned so that systems with 4k byte write-
124 * protected segments can write protect FORTH )
126 * addr. contents pointer init by
127 * **** ******************************* ******* ******
129 * substitute for disc mass memory
130 * 3210 (5294) LO,MEMEND
132 * 4 buffer sectors of VIRTUAL MEMORY
134 * >>>>>> memory from here up must be RAM <<<<<<
136 * 27FF (37FF, but 38XX, with debugging code included the the "ROMable" image.)
137 * 6k of romable "FORTH" <== IP ABORT
139 * the VIRTUAL FORTH MACHINE
141 * 1004 <<< WARM START ENTRY >>> (4004)
142 * 1000 <<< COLD START ENTRY >>> (4000)
144 * >>>>>> memory from here down must be RAM <<<<<<
145 * FFE (3FF0) RETURN STACK base <== RP RINIT
147 * FB4 (less than 3EB4)
149 * holds up to 132 characters
150 * and is scanned upward by IN
152 * F30 (3E00) <== IN TIB
153 * F2F (3DF0) DATA STACK <== SP SP0,SINIT
154 * | grows downward from F2F
158 * I DICTIONARY grows upward
160 * 183 (1483) end of ram-dictionary. <== DP DPINIT
163 * 150 (1450) "FORTH" ( a word ) <=, <== CONTEXT
165 * 148 (1448) start of ram-dictionary.
167 * 100 (1400) user #l table of variables <= UP DPINIT
168 * F0 (13B0) registers & pointers for the virtual machine
169 * scratch area used by various words
170 * E0 (13A0) lowest address used by FORTH
176 * CONVENTIONS USED IN THIS PROGRAM ARE AS FOLLOWS :
178 * IP points to the current instruction ( pre-increment mode )
179 * RP points to second free byte (first free word) in return stack
180 * =6809= S stack will be the return/flow-of-control stack.
181 * SP (hardware SP) points to first free byte in data stack
182 = =6809= U stack will be the parameter stack.
184 * when A and B hold one 16 bit FORTH data word,
185 * A contains the high byte, B, the low byte.
195 * N RMB 10 used as scratch by (FIND),ENCLOSE,CMOVE,EMIT,KEY,
196 * SP@,SWAP,DOES>,COLD
197 * =6809= All these will use scratch space on stack, to the extent they need it.
200 * These locations are used by the TRACE routine :
202 TRLIM RMB 1 the count for tracing without user intervention
203 TRACEM RMB 1 non-zero = trace mode
204 BRKPT RMB 2 the breakpoint address at which
205 * the program will go into trace mode
206 VECT RMB 2 vector to machine code
207 * (only needed if the TRACE routine is resident)
210 * Registers used by the FORTH virtual machine:
211 * Starting at $OOFO ($00B0):
214 W RMB 2 the instruction register points to 6800 code
215 IP RMB 2 the instruction pointer points to pointer to 6800 code
216 * =6809= after NEXT, Y will retain IP, and X will retain W until overwritten
217 * RP RMB 2 the return stack pointer
218 * =6809= S stack is fine for the flow of control stack.
219 * =6809= SP will be U
220 UP RMB 2 the pointer to base of current user's 'USER' table
221 * ( altered during multi-tasking )
222 * UP will be early in the DP variables.
225 * =6809= Trace variables will also be in the direct page.
233 * This system is shown with one user, but additional users
234 * may be added by allocating additional user tables:
235 * UORIG2 RMB 64 data table for user #2
238 * =6809= Should the TASK record be in the DP or not?
239 * Some of this stuff gets initialized during
240 * COLD start and WARM start:
241 * [ names correspond to FORTH words of similar (no X) name ]
245 UORIG RMB 6 3 reserved variables
246 XSPZER RMB 2 initial top of data stack for this user
247 XRZERO RMB 2 initial top of return stack
248 XTIB RMB 2 start of terminal input buffer
249 XWIDTH RMB 2 name field width
250 XWARN RMB 2 warning message mode (0 = no disc)
251 XFENCE RMB 2 fence for FORGET
252 XDP RMB 2 dictionary pointer
253 XVOCL RMB 2 vocabulary linking
254 XBLK RMB 2 disc block being accessed
255 XIN RMB 2 scan pointer into the block
256 XOUT RMB 2 cursor position
257 XSCR RMB 2 disc screen being accessed ( O=terminal )
258 XOFSET RMB 2 disc sector offset for multi-disc
259 XCONT RMB 2 last word in primary search vocabulary
260 XCURR RMB 2 last word in extensible vocabulary
261 XSTATE RMB 2 flag for 'interpret' or 'compile' modes
262 XBASE RMB 2 number base for I/O numeric conversion
263 XDPL RMB 2 decimal point place
265 XCSP RMB 2 current stack position, for compile checks
268 XDELAY RMB 2 carriage return delay count
269 XCOLUM RMB 2 carriage width
270 IOSTAT RMB 2 last acia status from write/read
281 * end of user table, start of common system variables
290 * These things, up through the lable 'REND', are overwritten
291 * at time of cold load and should have the same contents
298 FORTH FDB DODOES,DOVOC,$81A0,TASK-7
301 FCC "(C) Forth Interest Group, 1979"
309 REND EQU * ( first empty location in dictionary )
312 * The FORTH program ( address $1000 ($2000) to $27FF (37FF?) ) is written
313 * so that it can be in a ROM, or write-protected if desired
316 * ######>> screen 3 <<
318 ***************************
319 ** C O L D E N T R Y **
320 ***************************
323 ***************************
324 ** W A R M E N T R Y **
325 ***************************
327 JMP WENT warm-start code, keeps current dictionary intact
330 ******* startup parmeters **************************
332 FDB $6800,0000 cpu & revision
333 FDB 0 topmost word in FORTH vocabulary
334 BACKSP FDB $7F backspace character for editing
335 UPINIT FDB UORIG initial user area
336 *SINIT FDB ORIG-$D0 initial top of data stack
337 SINIT FDB ORIG-$210 initial top of data stack
338 *RINIT FDB ORIG-2 initial top of return stack
339 RINIT FDB ORIG-$10 initial top of return stack
340 * FDB ORIG-$D0 terminal input buffer
341 FDB ORIG-$200 terminal input buffer
342 FDB 31 initial name field width
343 FDB 0 initial warning mode (0 = no disc)
344 FENCIN FDB REND initial fence
345 DPINIT FDB REND cold start value for DP
347 COLINT FDB 132 initial terminal carriage width
348 DELINT FDB 4 initial carriage return delay
349 ****************************************************
353 * ######>> screen 13 <<
354 * PULABX PUL A 24 cycles until 'NEXT'
356 * STABX STA A 0,X 16 cycles until 'NEXT'
359 * GETX LDA A 0,X 18 cycles until 'NEXT'
361 * PUSHBA PSH B 8 cycles until 'NEXT'
363 * PULABX PUL A 24 cycles until 'NEXT'
365 * STABX STA A 0,X 16 cycles until 'NEXT'
368 * GETX LDA A 0,X 18 cycles until 'NEXT'
371 * =6809= These really aren't all that useful.
374 BRA NEXT ; Used less than seven times.
376 PUSHBA PSHU D ; Used only seven times, saves only 14 bytes.
377 * Must fall through to NEXT
381 * "NEXT" takes 38 cycles if TRACE is removed,
383 * and 95 cycles if NOT tracing.
385 * = = = = = = = t h e v i r t u a l m a c h i n e = = = = =
388 * INX pre-increment mode
391 * NEXT2 LDX 0,X get W which points to CFA of word to be done
393 * LDX 0,X get VECT which points to executable code
398 JMP [,Y++] ; Or use the tracing routine below.
400 * The next instruction could be patched to JMP TRACE =
401 * if a TRACE routine is available: =
403 * Or add the TRACE routine in-line, since we are assembling it.
409 * TSX ; So the funn 6800 stack doesn't beach us.
420 * DEX ; allocation link
423 leay -3,y ; last char
425 NAMTST DEX ; length byte?
430 NAMTDN AND B #31 ; It's the length byte whether it wants to be or not.
436 * show the virtual registers
466 * JMP TRACE ( an alternate for the above )
493 * = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
500 FCC 2,LIT NOTE: this is different from LITERAL
502 FDB 0 link of zero to terminate dictionary scan
517 * ######>> screen 14 <<
521 FCC 4,XCLIT ; for debugging
523 FDB LIT-6 ; should never link
525 CLITER FDB *+2 (this is an invisible word, with no header)
544 * LDX 0,X get code field address (CFA)
551 * ######>> screen 15 <<
557 BRAN FDB ZBYES Go steal code in ZBRANCH
573 * ZBYES LDX <IP Note: code is shared with BRANCH, (+LOOP), (LOOP)
581 ZBYES LDD ,X ; X still has IP
584 * ZBNO LDX IP no branch. This code is shared with (+LOOP), (LOOP).
585 * INX jump over branch delta
592 * ######>> screen 16 <<
600 * LDA B #1 get set to increment counter by 1
601 * BRA XPLOP2 go steal other guy's code!
610 XPLOOP FDB *+2 Note: +LOOP has an un-signed loop counter
611 * PUL A get increment
614 * BPL XPLOF forward looping
620 * BRA XPLONO fall through
626 **** Have to think about this.
630 * ADD B 3,X add it to counter
632 * STA B 3,X store new counter value
641 XPLONO INX done, don't branch back
646 BRA ZBNO use ZBRAN to skip over unused delta
648 * ######>> screen 17 <<
654 XDO FDB *+2 This is the RUNTIME DO, not the COMPILING DO
681 * ######>> screen 18 <<
687 DIGIT FDB *+2 NOTE: legal input range is 0-9, A-Z
690 SUB A #$30 ascii zero
691 BMI DIGIT2 IF LESS THAN '0', ILLEGAL
693 BMI DIGIT0 IF '9' OR LESS
695 BMI DIGIT2 if less than 'A'
697 BPL DIGIT2 if greater than 'Z'
698 SUB A #7 translate 'A' thru 'F'
700 BPL DIGIT2 if not less than the base
702 STA A 3,X store digit
703 DIGIT1 STA B 1,X store the flag
707 INS pop bottom number
709 STA B 0,X make sure both bytes are 00
712 * ######>> screen 19 <<
714 * The word format in the dictionary is:
716 * char-count + $80 lowest address
721 * link high byte \___point to previous word
723 * CFA high byte \___pnt to 6800 code
738 PD EQU N ptr to dict word being checked
744 PFIND0 PUL A loop to get arguments
751 PFIND1 LDA B 0,X get count dict count
757 LDA A 0,X get count from arg
770 TST B is dict entry neg. ?
772 AND B #$7F clear sign
775 PFIND3 LDX 0,X get new link
776 BNE PFIND1 continue if link not=0
786 PFIND9 LDA B 0,X scan forward to end of this name
793 FOUND LDA A PD compute CFA
812 * ######>> screen 20 <<
819 * FC means offset (bytes) to First Character of next word
820 * EW " " to End of Word
821 * NC " " to Next Character to start next enclose at
824 PUL B now, get the low byte, for an 8-bit delimiter
828 * wait for a non-delimiter or a NUL
836 * found first character. Push FC
837 ENCL3 LDA A N found first char.
841 * wait for a delimiter or a NUL
854 * advance and push NC
857 * found NUL before non-delimiter, therefore there is no word
858 ENCL6 LDA B N found NUL
863 * found NUL following the word instead of SPACE
867 ENCL8 LDA B N save NC
872 * ######>> screen 21 <<
873 * The next 4 words call system dependant I/O routines
874 * which are listed after word "-->" ( lable: "arrow" )
912 JMP PUSHBA stack the flag
923 * ######>> screen 22 <<
926 FCC 4,CMOVE source, destination, count
929 CMOVE FDB *+2 takes ( 43+47*count cycles )
933 STA A 0,X move parameters to scratch area
955 * ######>> screen 23 <<
967 * The following is a subroutine which
968 * multiplies top 2 words on stack,
969 * leaving 32-bit result: high order word in A,B
970 * low order word in 2nd word of stack.
972 USTARS LDA A #16 bits/word counter
977 USTAR2 ROR 5,X shift multiplier
987 USTAR4 INS dump counter
990 * ######>> screen 24 <<
1025 JMP SWAP+4 reverse quotient & remainder
1027 * ######>> screen 25 <<
1067 * ######>> screen 26 <<
1087 TXS watch it ! X and S are not equal.
1095 LDX RINIT initialize from rom constant
1109 LDX 0,X get address we have just finished.
1110 JMP NEXT+2 increment the return address & do next word
1112 * ######>> screen 27 <<
1166 * ######>> screen 28 <<
1189 LDA A #$80 check the sign bit
1198 * ######>> screen 29 <<
1265 * ######>> screen 30 <<
1317 * ######>> screen 31 <<
1328 PUL A get stack data
1330 ADD B 1,X add & store low byte
1332 ADC A 0,X add & store hi byte
1341 TOGGLE FDB DOCOL,OVER,CAT,XOR,SWAP,CSTORE
1344 * ######>> screen 32 <<
1397 * ######>> screen 33 <<
1402 COLON FDB DOCOL,QEXEC,SCSP,CURENT,AT,CONTXT,STORE
1406 * Here is the IP pusher for allowing
1407 * nested words in the virtual machine:
1408 * ( ;S is the equivalent un-nester )
1410 DOCOL LDX RP make room in the stack
1416 STA A 2,X Store address of the high level word
1417 STA B 3,X that we are starting to execute
1418 LDX W Get first sub-word of that definition
1419 JMP NEXT+2 and execute it
1422 FCB $C1 ; imnediate code
1425 SEMI FDB DOCOL,QCSP,COMPIL,SEMIS,SMUDGE,LBRAK
1428 * ######>> screen 34 <<
1434 CON FDB DOCOL,CREATE,SMUDGE,COMMA,PSCODE
1437 LDA B 3,X A & B now contain the constant
1445 VAR FDB DOCOL,CON,PSCODE
1449 ADC A #0 A,B now contain the address of the variable
1457 USER FDB DOCOL,CON,PSCODE
1458 DOUSER LDX W get offset into user's table
1461 ADD B UP+1 add to users base address
1463 JMP PUSHBA push address of user's variable
1465 * ######>> screen 35 <<
1499 BL FDB DOCON ascii blank
1508 FDB MEMEND-528 (132 * NBLK)
1512 FCC 4,LIMIT ( the end of memory +1 )
1520 FCC 4,B/BUF (bytes/buffer)
1528 FCC 4,B/SCR (blocks/screen)
1533 * blocks/screen = 1024 / "B/BUF" = 8
1540 PORIG FDB DOCOL,LIT,ORIG,PLUS
1543 * ######>> screen 36 <<
1594 FCC 1,DP points to first free byte at end of dictionary
1618 FCC 1,IN scan pointer for input line buffer
1639 * ######>> screen 37 <<
1651 FCC 6,CONTEXT points to pointer to vocab to search first
1659 FCC 6,CURRENT points to ptr. to vocab being extended
1667 FCC 4,STATE 1 if compiling, 0 if not
1675 FCC 3,BASE number base for all input & output
1721 * ======>> 82.5 <<== SPECIAL
1723 FCC 6,COLUMNS line width of terminal
1729 * ######>> screen 38 <<
1735 ONEP FDB DOCOL,ONE,PLUS
1743 TWOP FDB DOCOL,TWO,PLUS
1751 HERE FDB DOCOL,DP,AT
1759 ALLOT FDB DOCOL,DP,PSTORE
1766 COMMA FDB DOCOL,HERE,STORE,TWO,ALLOT
1774 CCOMM FDB DOCOL,HERE,CSTORE,ONE,ALLOT
1781 SUB FDB DOCOL,MINUS,PLUS
1788 EQUAL FDB DOCOL,SUB,ZEQU
1816 GREAT FDB DOCOL,SWAP,LESS
1824 ROT FDB DOCOL,TOR,SWAP,FROMR,SWAP
1832 SPACE FDB DOCOL,BL,EMIT
1840 MIN FDB DOCOL,OVER,OVER,GREAT,ZBRAN
1851 MAX FDB DOCOL,OVER,OVER,LESS,ZBRAN
1862 DDUP FDB DOCOL,DUP,ZBRAN
1867 * ######>> screen 39 <<
1874 TRAV2 FDB OVER,PLUS,CLITER
1876 FDB OVER,CAT,LESS,ZBRAN
1886 LATEST FDB DOCOL,CURENT,AT,AT
1894 LFA FDB DOCOL,CLITER
1904 CFA FDB DOCOL,TWO,SUB
1912 NFA FDB DOCOL,CLITER
1914 FDB SUB,ONE,MINUS,TRAV
1922 PFA FDB DOCOL,ONE,TRAV,CLITER
1927 * ######>> screen 40 <<
1933 SCSP FDB DOCOL,SPAT,CSP,STORE
1941 QERR FDB DOCOL,SWAP,ZBRAN
1953 QCOMP FDB DOCOL,STATE,AT,ZEQU,CLITER
1963 QEXEC FDB DOCOL,STATE,AT,CLITER
1973 QPAIRS FDB DOCOL,SUB,CLITER
1983 QCSP FDB DOCOL,SPAT,CSP,AT,SUB,CLITER
1993 QLOAD FDB DOCOL,BLK,AT,ZEQU,CLITER
1998 * ######>> screen 41 <<
2004 COMPIL FDB DOCOL,QCOMP,FROMR,TWOP,DUP,TOR,AT,COMMA
2011 LBRAK FDB DOCOL,ZERO,STATE,STORE
2018 RBRAK FDB DOCOL,CLITER
2028 SMUDGE FDB DOCOL,LATEST,CLITER
2051 FCB 10 note: hex "A"
2055 * ######>> screen 42 <<
2061 PSCODE FDB DOCOL,FROMR,TWOP,LATEST,PFA,CFA,STORE
2069 SEMIC FDB DOCOL,QCSP,COMPIL,PSCODE,SMUDGE,LBRAK,QSTACK
2071 * note: "QSTACK" will be replaced by "ASSEMBLER" later
2073 * ######>> screen 43 <<
2079 BUILDS FDB DOCOL,ZERO,CON
2087 DOES FDB DOCOL,FROMR,TWOP,LATEST,PFA,STORE
2091 LDX RP make room on return stack
2095 STA A 2,X push return address
2097 LDX W get addr of pointer to run-time code
2100 STX N stash it in scratch area
2103 CLR A get address of parameter
2107 PSH B and push it on data stack
2111 * ######>> screen 44 <<
2117 COUNT FDB DOCOL,DUP,ONEP,SWAP,CAT
2125 TYPE FDB DOCOL,DDUP,ZBRAN
2127 FDB OVER,PLUS,SWAP,XDO
2128 TYPE2 FDB I,CAT,EMIT,XLOOP
2140 DTRAIL FDB DOCOL,DUP,ZERO,XDO
2141 DTRAL2 FDB OVER,OVER,PLUS,ONE,SUB,CAT,BL
2156 PDOTQ FDB DOCOL,R,TWOP,COUNT,DUP,ONEP
2157 FDB FROMR,PLUS,TOR,TYPE
2170 FDB COMPIL,PDOTQ,WORD
2171 FDB HERE,CAT,ONEP,ALLOT,BRAN
2173 DOTQ1 FDB WORD,HERE,COUNT,TYPE
2176 * ######>> screen 45 <<
2177 * ======>> 126 <<== MACHINE DEPENDENT
2182 QSTACK FDB DOCOL,CLITER
2184 FDB PORIG,AT,TWO,SUB,SPAT,LESS,ONE
2186 * prints 'empty stack'
2189 * Here, we compare with a value at least 128
2190 * higher than dict. ptr. (DP)
2197 * prints 'full stack'
2201 * ======>> 127 << this word's function
2202 * is done by ?STACK in this version
2207 *QFREE FDB DOCOL,SPAT,HERE,CLITER
2209 * FDB PLUS,LESS,TWO,QERR,SEMIS
2211 * ######>> screen 46 <<
2217 EXPECT FDB DOCOL,OVER,PLUS,OVER,XDO
2218 EXPEC2 FDB KEY,DUP,CLITER
2220 FDB PORIG,AT,EQUAL,ZBRAN
2223 FCB 8 ( backspace character to emit )
2224 FDB OVER,I,EQUAL,DUP,FROMR,TWO,SUB,PLUS
2227 EXPEC3 FDB DUP,CLITER
2228 FCB $D ( carriage return )
2231 FDB LEAVE,DROP,BL,ZERO,BRAN
2234 EXPEC5 FDB I,CSTORE,ZERO,I,ONEP,STORE
2235 EXPEC6 FDB EMIT,XLOOP
2245 QUERY FDB DOCOL,TIB,AT,COLUMS
2246 FDB AT,EXPECT,ZERO,IN,STORE
2253 FCB $C1 immediate < carriage return >
2256 NULL FDB DOCOL,BLK,AT,ZBRAN
2259 FDB ZERO,IN,STORE,BLK,AT,BSCR,MOD
2261 * check for end of screen
2264 FDB QEXEC,FROMR,DROP
2267 NULL2 FDB FROMR,DROP
2270 * ######>> screen 47 <<
2276 FILL FDB DOCOL,SWAP,TOR,OVER,CSTORE,DUP,ONEP
2277 FDB FROMR,ONE,SUB,CMOVE
2285 ERASE FDB DOCOL,ZERO,FILL
2293 BLANKS FDB DOCOL,BL,FILL
2301 HOLD FDB DOCOL,LIT,$FFFF,HLD,PSTORE,HLD,AT,CSTORE
2309 PAD FDB DOCOL,HERE,CLITER
2314 * ######>> screen 48 <<
2320 WORD FDB DOCOL,BLK,AT,ZBRAN
2322 FDB BLK,AT,BLOCK,BRAN
2325 WORD3 FDB IN,AT,PLUS,SWAP,ENCLOS,HERE,CLITER
2327 FDB BLANKS,IN,PSTORE,OVER,SUB,TOR,R,HERE
2328 FDB CSTORE,PLUS,HERE,ONEP,FROMR,CMOVE
2331 * ######>> screen 49 <<
2338 PNUMB2 FDB ONEP,DUP,TOR,CAT,BASE,AT,DIGIT,ZBRAN
2340 FDB SWAP,BASE,AT,USTAR,DROP,ROT,BASE
2341 FDB AT,USTAR,DPLUS,DPL,AT,ONEP,ZBRAN
2344 PNUMB3 FDB FROMR,BRAN
2354 NUMB FDB DOCOL,ZERO,ZERO,ROT,DUP,ONEP,CAT,CLITER
2356 FDB EQUAL,DUP,TOR,PLUS,LIT,$FFFF
2357 NUMB1 FDB DPL,STORE,PNUMB,DUP,CAT,BL,SUB
2362 FDB SUB,ZERO,QERR,ZERO,BRAN
2364 NUMB2 FDB DROP,FROMR,ZBRAN
2374 DFIND FDB DOCOL,BL,WORD,HERE,CONTXT,AT,AT
2384 FDB DROP,HERE,LATEST,PFIND
2387 * ######>> screen 50 <<
2393 PABORT FDB DOCOL,ABORT
2401 ERROR FDB DOCOL,WARN,AT,ZLESS
2403 * note: WARNING is -1 to abort, 0 to print error #
2404 * and 1 to print error message from disc
2407 ERROR2 FDB HERE,COUNT,TYPE,PDOTQ
2410 FDB MESS,SPSTOR,IN,AT,BLK,AT,QUIT
2418 IDDOT FDB DOCOL,PAD,CLITER
2421 FCB $5F ( underline )
2422 FDB FILL,DUP,PFA,LFA,OVER,SUB,PAD
2423 FDB SWAP,CMOVE,PAD,COUNT,CLITER
2428 * ######>> screen 51 <<
2434 CREATE FDB DOCOL,DFIND,ZBRAN
2440 FDB NFA,IDDOT,CLITER
2443 CREAT2 FDB HERE,DUP,CAT,WIDTH,AT,MIN
2444 FDB ONEP,ALLOT,DUP,CLITER
2446 FDB TOGGLE,HERE,ONE,SUB,CLITER
2448 FDB TOGGLE,LATEST,COMMA,CURENT,AT,STORE
2452 * ######>> screen 52 <<
2458 BCOMP FDB DOCOL,DFIND,ZEQU,ZERO,QERR,DROP,CFA,COMMA
2466 LITER FDB DOCOL,STATE,AT,ZBRAN
2468 FDB COMPIL,LIT,COMMA
2476 DLITER FDB DOCOL,STATE,AT,ZBRAN
2478 FDB SWAP,LITER,LITER
2481 * ######>> screen 53 <<
2491 * FDB OVER,OVER,HEX,DOT,DOT,DEC
2503 INTER5 FDB HERE,NUMB,DPL,AT,ONEP,ZBRAN
2507 INTER6 FDB DROP,LITER
2508 INTER7 FDB QSTACK,BRAN
2510 * FDB SEMIS never executed
2513 * ######>> screen 54 <<
2519 IMMED FDB DOCOL,LATEST,CLITER
2529 VOCAB FDB DOCOL,BUILDS,LIT,$81A0,COMMA,CURENT,AT,CFA
2530 FDB COMMA,HERE,VOCLIN,AT,COMMA,VOCLIN,STORE,DOES
2531 DOVOC FDB TWOP,CONTXT,STORE
2536 * Note: FORTH does not go here in the rom-able dictionary,
2537 * since FORTH is a type of variable.
2545 DEFIN FDB DOCOL,CONTXT,AT,CURENT,STORE
2552 PAREN FDB DOCOL,CLITER
2557 * ######>> screen 55 <<
2563 QUIT FDB DOCOL,ZERO,BLK,STORE
2566 * Here is the outer interpretter
2567 * which gets a line of input, does it, prints " OK"
2569 QUIT2 FDB RPSTOR,CR,QUERY,INTERP,STATE,AT,ZEQU
2577 * FDB SEMIS ( never executed )
2584 ABORT FDB DOCOL,SPSTOR,DEC,QSTACK,DRZERO,CR,PDOTQ
2607 * FDB SEMIS never executed
2610 * ######>> screen 56 <<
2611 * bootstrap code... moves rom contents to ram :
2618 CENT LDS #REND-1 top of destination
2619 LDX #ERAM top of stuff to move
2622 PSH A move TASK & FORTH to ram
2626 LDS #XFENCE-1 put stack at a safe place for now
2639 WENT LDS #XFENCE-1 top of destination
2640 LDX #FENCIN top of stuff to move
2649 STX UP init user ram pointer
2652 NOP Here is a place to jump to special user
2653 NOP initializations such as I/0 interrups
2656 * For systems with TRACE:
2658 STX TRLIM clear trace mode
2660 STX BRKPT clear breakpoint address
2661 JMP RPSTOR+2 start the virtual machine running !
2663 * Here is the stuff that gets copied to ram :
2666 * Thus, MAGIC numbers that initialize USE and PREV, magically! (JMR)
2667 * RAM FDB $3000,$3000,0,0
2668 RAM FDB $4000+132,$4000+132,0,0
2675 RFORTH FDB DODOES,DOVOC,$81A0,TASK-7
2677 FCC "(C) Forth Interest Group, 1979"
2682 RTASK FDB DOCOL,SEMIS
2683 ERAM FCC "David Lion"
2686 * ######>> screen 57 <<
2692 STOD FDB DOCOL,DUP,ZLESS,MINUS
2712 SLMOD FDB DOCOL,TOR,STOD,FROMR,USLASH
2719 SLASH FDB DOCOL,SLMOD,SWAP,DROP
2727 MOD FDB DOCOL,SLMOD,DROP
2735 SSMOD FDB DOCOL,TOR,USTAR,FROMR,USLASH
2743 SSLASH FDB DOCOL,SSMOD,SWAP,DROP
2751 MSMOD FDB DOCOL,TOR,ZERO,R,USLASH
2752 FDB FROMR,SWAP,TOR,USLASH,FROMR
2760 ABS FDB DOCOL,DUP,ZLESS,ZBRAN
2770 DABS FDB DOCOL,DUP,ZLESS,ZBRAN
2775 * ######>> screen 58 <<
2796 PBUF FDB DOCOL,CLITER
2798 FDB PLUS,DUP,LIMIT,EQUAL,ZBRAN
2801 PBUF2 FDB DUP,PREV,AT,SUB
2809 UPDATE FDB DOCOL,PREV,AT,AT,LIT,$8000,OR,PREV,AT,STORE
2814 FCC 12,EMPTY-BUFFERS
2817 MTBUF FDB DOCOL,FIRST,LIMIT,OVER,SUB,ERASE
2825 DRZERO FDB DOCOL,ZERO,OFSET,STORE
2828 * ======>> 174 <<== system dependant word
2833 *DRONE FDB DOCOL,LIT,$07D0,OFSET,STORE
2834 DRONE FDB DOCOL,LIT,RAMDSZ,OFSET,STORE
2837 * ######>> screen 59 <<
2843 BUFFER FDB DOCOL,USE,AT,DUP,TOR
2844 BUFFR2 FDB PBUF,ZBRAN
2846 FDB USE,STORE,R,AT,ZLESS
2849 FDB R,TWOP,R,AT,LIT,$7FFF,AND,ZERO,RW
2850 BUFFR3 FDB R,STORE,R,PREV,STORE,FROMR,TWOP
2853 * ######>> screen 60 <<
2859 BLOCK FDB DOCOL,OFSET,AT,PLUS,TOR
2860 FDB PREV,AT,DUP,AT,R,SUB,DUP,PLUS,ZBRAN
2862 BLOCK3 FDB PBUF,ZEQU,ZBRAN
2864 FDB DROP,R,BUFFER,DUP,R,ONE,RW,TWO,SUB
2865 BLOCK4 FDB DUP,AT,R,SUB,DUP,PLUS,ZEQU,ZBRAN
2868 BLOCK5 FDB FROMR,DROP,TWOP
2871 * ######>> screen 61 <<
2877 PLINE FDB DOCOL,TOR,CLITER
2879 FDB BBUF,SSMOD,FROMR,BSCR,STAR,PLUS,BLOCK,PLUS,CLITER
2888 DLINE FDB DOCOL,PLINE,DTRAIL,TYPE
2896 MESS FDB DOCOL,WARN,AT,ZBRAN
2902 FDB OFSET,AT,BSCR,SLASH,SUB,DLINE,BRAN
2906 FCC 6,err # ; Make sure there's a space there at the end.
2912 FCC 3,LOAD input:scr #
2915 LOAD FDB DOCOL,BLK,AT,TOR,IN,AT,TOR,ZERO,IN,STORE
2916 FDB BSCR,STAR,BLK,STORE
2917 FDB INTERP,FROMR,IN,STORE,FROMR,BLK,STORE
2925 ARROW FDB DOCOL,QLOAD,ZERO,IN,STORE,BSCR
2926 FDB BLK,AT,OVER,MOD,SUB,BLK,PSTORE
2931 * ######>> screen 63 <<
2932 * The next 4 subroutines are machine dependent, and are
2933 * called by words 13 through 16 in the dictionary.
2935 * ======>> 182 << code for EMIT
2936 * PEMIT JMP $F018 ; EXBUG outch, rob the RTS.
2937 PEMIT STA B N+1 save B
2940 BIT B #2 check ready bit
2941 BEQ PEMIT+4 if not ready for more data
2946 STA B IOSTAT-UORIG,X
2948 LDA B N+1 recover B & X
2950 RTS only A register may change
2951 * PEMIT JMP $E1D1 for MIKBUG
2952 * PEMIT FCB $3F,$11,$39 for PROTO
2953 * PEMIT JMP $D286 for Smoke Signal DOS
2955 * ======>> 183 << code for KEY
2957 INC $FF53 ; shut off echo
2958 JMP $F015 ; EXBUG inch, rob the RTS.
2963 * BCC PKEY+4 no incoming data yet
2965 * AND A #$7F strip parity bit
2967 * STA B IOSTAT+1-UORIG,X
2971 * PKEY JMP $E1AC for MIKBUG
2972 * PKEY FCB $3F,$14,$39 for PROTO
2973 * PKEY JMP $D289 for Smoke Signal DOS
2975 * ######>> screen 64 <<
2976 * ======>> 184 << code for ?TERMINAL
2977 PQTER LDA A ACIAC Test for 'break' condition
2978 AND A #$11 mask framing error bit and
2981 LDA A ACIAD clear input buffer
2988 * ======>> 185 << code for CR
2989 PCR JMP $F021 ; EXBUG pcrlf, rob the RTS.
2990 * PCR LDA A #$D carriage return
2992 * LDA A #$A line feed
2996 * LDA B XDELAY+1-UORIG,X
2998 * BMI PQTER2 return if minus
2999 * PSH B save counter
3000 * BSR PEMIT print RUBOUTs to delay.....
3007 * ######>> screen 66 <<
3016 * ######>> screen 67 <<
3025 * ######>> screen 68 <<
3034 *The next 3 words are written to create a substitute for disc
3035 * mass memory,located between $3210 & $3FFF in ram.
3042 FDB MEMEND a system dependent equate at front
3050 * FDB MEMTOP ( $3FFF ($7FFF) in this version )
3053 * ######>> screen 69 <<
3059 RW FDB DOCOL,TOR,BBUF,STAR,LO,PLUS,DUP,HI,GREAT,ZBRAN
3071 * ######>> screen 72 <<
3076 TICK FDB DOCOL,DFIND,ZEQU,ZERO,QERR,DROP,LITER
3084 FORGET FDB DOCOL,CURENT,AT,CONTXT,AT,SUB,CLITER
3086 FDB QERR,TICK,DUP,FENCE,AT,LESS,CLITER
3088 FDB QERR,DUP,ZERO,PORIG,GREAT,CLITER
3090 FDB QERR,DUP,NFA,DP,STORE,LFA,AT,CONTXT,AT,STORE
3093 * ######>> screen 73 <<
3099 BACK FDB DOCOL,HERE,SUB,COMMA
3107 BEGIN FDB DOCOL,QCOMP,HERE,ONE
3115 ENDIF FDB DOCOL,QCOMP,TWO,QPAIRS,HERE
3116 FDB OVER,SUB,SWAP,STORE
3124 THEN FDB DOCOL,ENDIF
3132 DO FDB DOCOL,COMPIL,XDO,HERE,THREE
3140 LOOP FDB DOCOL,THREE,QPAIRS,COMPIL,XLOOP,BACK
3148 PLOOP FDB DOCOL,THREE,QPAIRS,COMPIL,XPLOOP,BACK
3153 FCC 4,UNTIL ( same as END )
3156 UNTIL FDB DOCOL,ONE,QPAIRS,COMPIL,ZBRAN,BACK
3159 * ######>> screen 74 <<
3173 AGAIN FDB DOCOL,ONE,QPAIRS,COMPIL,BRAN,BACK
3181 REPEAT FDB DOCOL,TOR,TOR,AGAIN,FROMR,FROMR
3190 IF FDB DOCOL,COMPIL,ZBRAN,HERE,ZERO,COMMA,TWO
3198 ELSE FDB DOCOL,TWO,QPAIRS,COMPIL,BRAN,HERE
3199 FDB ZERO,COMMA,SWAP,TWO,ENDIF,TWO
3207 WHILE FDB DOCOL,IF,TWOP
3210 * ######>> screen 75 <<
3216 SPACES FDB DOCOL,ZERO,MAX,DDUP,ZBRAN
3219 SPACE2 FDB SPACE,XLOOP
3228 BDIGS FDB DOCOL,PAD,HLD,STORE
3236 EDIGS FDB DOCOL,DROP,DROP,HLD,AT,PAD,OVER,SUB
3244 SIGN FDB DOCOL,ROT,ZLESS,ZBRAN
3255 DIG FDB DOCOL,BASE,AT,MSMOD,ROT,CLITER
3273 DIGS2 FDB DIG,OVER,OVER,OR,ZEQU,ZBRAN
3277 * ######>> screen 76 <<
3283 DOTR FDB DOCOL,TOR,STOD,FROMR,DDOTR
3291 DDOTR FDB DOCOL,TOR,SWAP,OVER,DABS,BDIGS,DIGS,SIGN
3292 FDB EDIGS,FROMR,OVER,SUB,SPACES,TYPE
3300 DDOT FDB DOCOL,ZERO,DDOTR,SPACE
3307 DOT FDB DOCOL,STOD,DDOT
3314 QUEST FDB DOCOL,AT,DOT
3317 * ######>> screen 77 <<
3323 LIST FDB DOCOL,DEC,CR,DUP,SCR,STORE,PDOTQ
3329 LIST2 FDB CR,I,THREE
3330 FDB DOTR,SPACE,I,SCR,AT,DLINE,XLOOP
3340 INDEX FDB DOCOL,CR,ONEP,SWAP,XDO
3341 INDEX2 FDB CR,I,THREE
3342 FDB DOTR,SPACE,ZERO,I,DLINE
3355 TRIAD FDB DOCOL,THREE,SLASH,THREE,STAR
3356 FDB THREE,OVER,PLUS,SWAP,XDO
3358 FDB LIST,QTERM,ZBRAN
3368 * ######>> screen 78 <<
3374 VLIST FDB DOCOL,CLITER
3376 FDB OUT,STORE,CONTXT,AT,AT
3377 VLIST1 FDB OUT,AT,COLUMS,AT,CLITER
3381 FDB CR,ZERO,OUT,STORE
3384 FDB IDDOT,SPACE,SPACE,PFA,LFA,AT
3385 FDB DUP,ZEQU,QTERM,OR
3397 NOOP FDB NEXT a useful no-op
3424 NOP a place to insert a machine-level breakpoint.
3427 ZZZZ FDB 0,0,0,0,0,0,0,0 end of rom program
3429 ORG MEMEND simulating disc on-line
3431 FCC "0) Index to BIF HI-LEVEL disk "
3433 FCC "2) Title page, Copr. notice "
3434 FCC "3) MONITOR CALL TO DEBUG "
3435 FCC "4) ERROR MESSAGES "
3465 FCC " ( FORTH 68 RAM resident utilities and testing stuff ) " 0
3466 FCC " ( Copyright 2013 Joel Rees ) " 1
3482 FCC " ( No need to call the monitor in exorsim, just ctrl-c. ) " 0
3483 FCC " ( But maybe we can put some other useful stuff here. ) " 1
3485 FCC " 1 WARNING ! " 3
3487 FCC " VOCABULARY DEBUG DEFINITIONS " 5
3488 FCC " ( addr n -- ) " 6
3489 FCC " : DUMPHEX BASE @ >R HEX " 7
3490 FCC " 0 DO DUP I + C@ 0 <# # # #> TYPE SPACE LOOP " 8
3491 FCC " DROP R> BASE ! ; " 9
3497 FCC " FORTH DEFINITIONS " 15
3499 FCC "( ERROR MESSAGES ) " 0
3500 FCC "DATA STACK UNDERFLOW " 1
3501 FCC "DICTIONARY FULL " 2
3502 FCC "ADDRESS RESOLUTION ERROR " 3
3503 FCC "HIDES DEFINITION IN " 4
3504 FCC "NULL VECTOR WRITTEN " 5
3505 FCC "DISC RANGE? " 6
3506 FCC "DATA STACK OVERFLOW " 7
3507 FCC "DISC ERROR! " 8
3508 FCC "CAN'T EXECUTE A NULL! " 9
3509 FCC "CONTROL STACK UNDERFLOW " 10
3510 FCC "CONTROL STACK OVERFLOW " 11
3511 FCC "ARRAY REFERENCE OUT OF BOUNDS " 12
3512 FCC "ARRAY DIMENSION NOT VALID " 13
3513 FCC "NO PROCEDURE TO ENTER " 14
3514 FCC " ( WAS REGISTER ) " 15
3517 FCC "COMPILATION ONLY, USE IN DEF " 1
3518 FCC "EXECUTION ONLY " 2
3519 FCC "CONDITIONALS NOT PAIRED " 3
3520 FCC "DEFINITION INCOMPLETE " 4
3521 FCC "IN PROTECTED DICTIONARY " 5
3522 FCC "USE ONLY WHEN LOADING " 6
3523 FCC "OFF CURRENT EDITING SCREEN " 7
3524 FCC "DECLARE VOCABULARY " 8
3525 FCC "DEFINITION NOT IN VOCABULARY " 9
3526 FCC "IN FORWARD BLOCK " 10
3527 FCC "ALLOCATION LIST CORRUPTED: LOST " 11
3528 FCC "CAN'T REDEFINE nul! " 12
3529 FCC "NOT FORWARD REFERENCE " 13
3530 FCC " ( WAS IMMEDIATE ) " 14
3533 FCC "( MORE ERROR MESSAGES asm6809 ) " 0
3534 FCC "HAS INCORRECT ADDRESS MODE " 1
3535 FCC "HAS INCORRECT INDEX MODE " 2
3536 FCC "OPERAND NOT REGISTER " 3
3537 FCC "HAS ILLEGAL IMMEDIATE " 4
3538 FCC "PC OFFSET MUST BE ABSOLUTE " 5
3539 FCC "ACCUMULATOR OFFSET REQUIRED " 6
3540 FCC "ILLEGAL MEMORY INDIRECTION (6809) " 7
3541 FCC "ILLEGAL INDEX BASE (6809) " 8
3542 FCC "ILLEGAL TARGET SPECIFIED " 9
3543 FCC "CAN'T STACK ON SELF (6809) " 10
3544 FCC "DUPLICATE IN LIST " 11
3545 FCC "REGISTER NOT STACK (6809) " 12
3546 FCC "EMPTY REGISTER LIST (6809) " 13
3547 FCC "IMMEDIATE OPERAND REQUIRED " 14
3548 FCC "REQUIRES CONDITION " 15
3552 FCC "COMPILE-TIME STACK UNDERFLOW " 1
3553 FCC "COMPILE-TIME STACK OVERFLOW " 2
3569 FCC " ( Crude editing facilities. -- one byte characters ) " 0
3571 FCC " VOCABULARY EDITOR DEFINITIONS " 2
3573 FCC " ( n -- nb nc ) ( convert line number to block, count offset ) " 4
3574 FCC " : L2BLOCK 64 * B/BUF /MOD ; ( 64 characters per line magic # ) " 5
3576 FCC " ( n -- n ) ( convert screen number to block number ) " 7
3577 FCC " : S2BLOCK B/SCR * ; ( magic numbers hidden in B/SCR ) " 8
3579 FCC " ( ns nl -- addr ) ( screen, line to address in block ) " 10
3580 FCC " : SL2BB SWAP S2BLOCK SWAP L2BLOCK SWAP >R + BLOCK R> + ; " 11
3582 FCC " ( ns nl -- ) ( show one line of the screen ) " 13
3583 FCC " : SHOWLINE SL2BB CR 64 TYPE ; ( list just one line ) " 14
3587 FCC " ( More crude editing facilities. -- one byte characters ) " 0
3589 FCC " 0 VARIABLE LNEDBUF 62 ALLOT ( buffer for line editing ) " 2
3591 FCC " ( ns nl -- ) ( overwrite one line of the screen ) " 4
3592 FCC " : PUTLINE LNEDBUF 64 BLANKS ( just enough to write to disc ) " 5
3593 FCC " CR LNEDBUF 64 EXPECT CR ( just enough to write ) " 6
3594 FCC " SL2BB LNEDBUF SWAP 64 CMOVE UPDATE ; " 7
3595 FCC " ( Full screen editing requires keyboard control codes. ) " 8
3604 * I don't know enough about the EXORciser, and don't want to take the time
3605 * to try to work through the disk simulation in exorsim to get real simulated
3606 * disk access running.
3607 * This gives me enough to check my understanding of forth, to help me figure
3608 * out my bif-c project or whatever my next step is.
3610 * Going farther with the exorsim version of the fig-FORTH 6800 model would be
3611 * a good student exercise, maybe? (For what coursework?)
3612 * But I think I need to move on.
3669 RAMDSZ EQU RAMDEN-MEMEND
3671 ORG ORIG ; set the COLD entry address