First cut at separating out the compileable definitions into a bootstrap file
authorNick Downing <nick@ndcode.org>
Wed, 26 Jun 2019 14:09:28 +0000 (00:09 +1000)
committerNick Downing <nick@ndcode.org>
Wed, 26 Jun 2019 14:09:28 +0000 (00:09 +1000)
Makefile
boot.f [new file with mode: 0644]
hf86exe.asm

index f0194c0..c497414 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,5 @@
-all: hf86exe.exe eturtle.exe\r
+all: hf86exe.exe\r
+# eturtle.exe\r
 \r
 hf86exe.exe: hf86exe.asm\r
        tasm /ml hf86exe\r
diff --git a/boot.f b/boot.f
new file mode 100644 (file)
index 0000000..c9f5c41
--- /dev/null
+++ b/boot.f
@@ -0,0 +1,3993 @@
+\ Nick\r
+10 CONSTANT linefeed-char\r
+13 CONSTANT carriage-return-char\r
+32 CONSTANT blank-char-value\r
+\r
+1 CONSTANT char-size\r
+2 CONSTANT cell-size\r
+\r
+16 BASE !\r
+  0FF CONSTANT max-char\r
+  7FFF CONSTANT max-signed\r
+  0FFFF CONSTANT max-unsigned\r
+  8000 CONSTANT max-negative\r
+\r
+  20 CONSTANT =compo\r
+  40 CONSTANT =immed\r
+  80 CONSTANT =seman\r
+  1F CONSTANT =mask\r
+DECIMAL\r
+\r
+258 CONSTANT size-of-PAD\r
+\r
+8 CONSTANT bsp#\r
+9 CONSTANT tab#\r
+13 CONSTANT cr#\r
+10 CONSTANT lf#\r
+127 CONSTANT del#\r
+\r
+16 BASE !\r
+  0E890 CONSTANT call-code\r
+DECIMAL\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ System dependent words -- Must be re-definded for each system.\r
+\ ;;;;;;;;;;;;;;;\r
+\ I/O words must be redefined if serial communication is used instead of\r
+\ keyboard. Following words are for MS-DOS system.\r
+\r
+\   TX?        ( -- flag )\r
+\              Return true if output device is ready or device state is\r
+\              indeterminate.\r
+\r
+\              $CONST  NameTXQ,TXQ,TRUEE       ;always true for MS-DOS\r
+\r
+\   CR         ( -- )                          \ CORE\r
+\              Carriage return and linefeed.\r
+\r
+: CR           carriage-return-char EMIT  linefeed-char EMIT ;\r
+\r
+\              $COLON  NameCR,CR\r
+\              DW      DoLIT,CRR,EMIT,DoLIT,LFF,EMIT,EXIT\r
+\r
+\   hi         ( -- )\r
+\r
+: hi           CR ." hForth "\r
+               S" CPU" ENVIRONMENT? DROP TYPE SPACE\r
+               S" model" ENVIRONMENT? DROP TYPE SPACE [CHAR] v EMIT\r
+               S" version"  ENVIRONMENT? DROP TYPE\r
+               ."  by Wonyong Koh, 1997" CR\r
+               ." ALL noncommercial and commercial uses are granted." CR\r
+               ." Please send comment, bug report and suggestions to:" CR\r
+               ."   wykoh@pado.krict.re.kr or wykoh@hitel.kol.co.kr" CR ;\r
+\r
+\              $COLON  NameHI,HI\r
+\              DW      CR,DoLIT,HiStr1,COUNT,TYPEE\r
+\              DW      DoLIT,CPUQStr,COUNT,ENVIRONMENTQuery,DROP,TYPEE,SPACE\r
+\              DW      DoLIT,ModelQStr,COUNT,ENVIRONMENTQuery,DROP,TYPEE\r
+\              DW      SPACE,DoLIT,'v',EMIT\r
+\              DW      DoLIT,VersionQStr,COUNT,ENVIRONMENTQuery,DROP,TYPEE\r
+\              DW      DoLIT,HiStr2,COUNT,TYPEE,CR\r
+\              DW      DoLIT,HiStr3,COUNT,TYPEE,CR\r
+\              DW      DoLIT,HiStr4,COUNT,TYPEE,CR\r
+\              DW      DoLIT,HiStr5,COUNT,TYPEE,CR,EXIT\r
+\r
+\   COLD       ( -- )\r
+\              The cold start sequence execution word.\r
+\r
+: COLD         sp0 sp! rp0 rp!                 \ initialize stack\r
+               'init-i/o EXECUTE\r
+               'boot EXECUTE\r
+               QUIT ;                          \ start interpretation\r
+\r
+\              $COLON  NameCOLD,COLD\r
+\              DW      SPZero,SPStore,RPZero,RPStore\r
+\              DW      TickINIT_IO,EXECUTE,TickBoot,EXECUTE\r
+\              DW      QUIT\r
+\r
+\   set-i/o ( -- )\r
+\              Set input/output device.\r
+\r
+: set-i/o      S" CON" stdin ;                 \ MS-DOS only\r
+\r
+\              $COLON  NameSet_IO,Set_IO\r
+\ Nick removed this, want to use ordinary DOS redirection instead\r
+\              DW      DoLIT,Set_IOstr         ;MS-DOS only\r
+\              DW      COUNT,STDIN             ;MS-DOS only\r
+\              DW      EXIT\r
+\r
+\   asciiz     ( ca1 u -- ca2 )\r
+\              Return ASCIIZ string.\r
+\r
+: asciiz       HERE SWAP 2DUP + 0 SWAP C! CHARS MOVE HERE ;\r
+\r
+\              $COLON  NameASCIIZ,ASCIIZ\r
+\              DW      HERE,SWAP,TwoDUP,Plus,DoLIT,0\r
+\              DW      SWAP,CStore,CHARS,MOVE,HERE,EXIT\r
+\r
+\   stdin      ( ca u -- )\r
+\r
+: stdin                asciiz redirect ?DUP\r
+               IF -38 THROW THEN       \ non-existent file\r
+               ; COMPILE-ONLY\r
+\r
+\              $COLON  NameSTDIN,STDIN\r
+\              DW      ASCIIZ,Redirect,QuestionDUP,ZBranch,STDIN1\r
+\              DW      DoLIT,-38,THROW\r
+\ STDIN1               DW      EXIT\r
+\r
+\   <<         ( "<spaces>ccc" -- )\r
+\              Redirect input from the file 'ccc'. Should be used only in\r
+\              interpretation state.\r
+\r
+: <<           STATE @ IF ." Do not use '<<' in a definition." ABORT THEN\r
+               PARSE-WORD stdin SOURCE >IN !  DROP ; IMMEDIATE\r
+\r
+\              $COLON  NameFROM,FROM\r
+\              DW      DoLIT,AddrSTATE,Fetch,ZBranch,FROM1\r
+\              DW      CR\r
+\              DW      DoLIT,FROMstr\r
+\              DW      COUNT,TYPEE,ABORT\r
+\ FROM1                DW      PARSE_WORD,STDIN,SOURCE,DoLIT,AddrToIN,Store,DROP,EXIT\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ Non-Standard words - Processor-dependent definitions\r
+\      16 bit Forth for 8086/8\r
+\ ;;;;;;;;;;;;;;;\r
+\r
+\   PAUSE      ( -- )\r
+\              Stop current task and transfer control to the task of which\r
+\              'status' USER variable is stored in 'follower' USER variable\r
+\              of current task.\r
+\r
+: PAUSE                rp@ DUP sp@ stackTop !  follower @ code@ >R ; COMPILE-ONLY\r
+\r
+\                $COLON  NamePAUSE,PAUSE\r
+\                DW      RPFetch,DUPP,SPFetch,StackTop,Store\r
+\                DW      Follower,Fetch,CodeFetch,ToR,EXIT\r
+\r
+\              $CODE   NamePAUSE,PAUSE\r
+\              PUSH    BX\r
+\              XCHG    BP,SP\r
+\              PUSH    SI\r
+\              XCHG    BP,SP\r
+\              PUSH    BP\r
+\              MOV     BX,WORD PTR AddrUserP\r
+\ StackTopOffset = SysStackTop - SysUserP\r
+\              MOV     [BX+StackTopOffset],SP\r
+\ FollowerOffset = SysFollower - SysUserP\r
+\              MOV     BX,[BX+FollowerOffset]\r
+\              MOV     SI,CS:[BX]\r
+\              $NEXT\r
+\r
+\   wake       ( -- )\r
+\              Wake current task.\r
+\r
+: wake         R> CELL+ code@ userP !  \ userP points 'follower' of current task\r
+               stackTop @ sp! DROP     \ set data stack\r
+               rp! ; COMPILE-ONLY      \ set return stack\r
+\r
+\                $COLON  NameWake,Wake\r
+\                DW      RFrom,CELLPlus,CodeFetch,DoLIT,AddrUserP,Store\r
+\                DW      StackTop,Fetch,SPStore,DROP,RPStore,EXIT\r
+\r
+\              $CODE   NameWake,Wake\r
+\              MOV     BX,CS:[SI+CELLL]\r
+\              MOV     WORD PTR AddrUserP,BX\r
+\              MOV     SP,[BX+StackTopOffset]\r
+\              POP     BP\r
+\              XCHG    BP,SP\r
+\              POP     SI\r
+\              XCHG    BP,SP\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   same?      ( c-addr1 c-addr2 u -- -1|0|1 )\r
+\              Return 0 if two strings, ca1 u and ca2 u, are same; -1 if\r
+\              string, ca1 u is smaller than ca2 u; 1 otherwise. Used by\r
+\              '(search-wordlist)'. Code definition is preferred to speed up\r
+\              interpretation. Colon definition is shown below.\r
+\r
+: same?                ?DUP IF         \ null strings are always same\r
+                  0 DO OVER C@ OVER C@ XOR\r
+                       IF UNLOOP C@ SWAP C@ > 2* 1+ EXIT THEN\r
+                       CHAR+ SWAP CHAR+ SWAP\r
+                  LOOP\r
+               THEN 2DROP 0 ;\r
+\r
+\                $COLON  NameSameQ,SameQ\r
+\                DW      QuestionDUP,ZBranch,SAMEQ4\r
+\                DW      DoLIT,0,DoDO\r
+\ SAMEQ3         DW      OVER,CFetch,OVER,CFetch,XORR,ZBranch,SAMEQ2\r
+\                DW      UNLOOP,CFetch,SWAP,CFetch,GreaterThan\r
+\                DW      TwoStar,OnePlus,EXIT\r
+\ SAMEQ2         DW      CHARPlus,SWAP,CHARPlus\r
+\                DW      DoLOOP,SAMEQ3\r
+\ SAMEQ4         DW      TwoDROP,DoLIT,0,EXIT\r
+\r
+\              $CODE   NameSameQ,SameQ\r
+\              MOV     CX,BX\r
+\              MOV     AX,DS\r
+\              MOV     ES,AX\r
+\              MOV     DX,SI           ;save SI\r
+\              MOV     BX,-1\r
+\              POP     DI\r
+\              POP     SI\r
+\              OR      CX,CX\r
+\              JZ      SAMEQ5\r
+\              REPE CMPSB\r
+\              JL      SAMEQ1\r
+\              JZ      SAMEQ5\r
+\              INC     BX\r
+\ SAMEQ5:      INC     BX\r
+\ SAMEQ1:      MOV     SI,DX\r
+\              $NEXT\r
+\r
+\   (search-wordlist)  ( c-addr u wid -- 0 | xt f 1 | xt f -1)\r
+\              Search word list for a match with the given name.\r
+\              Return execution token and not-compile-only flag and\r
+\              -1 or 1 ( IMMEDIATE) if found. Return 0 if not found.\r
+\\r
+\              format is: wid---->[   a    ]\r
+\                                     |\r
+\                                     V\r
+\              [   xt'  ][   a'   ][ccbbaann][ggffeedd]...\r
+\                            |\r
+\                            +--------+\r
+\                                     V\r
+\              [   xt'' ][   a''  ][ccbbaann][ggffeedd]...\r
+\\r
+\              a, a' etc. point to the cell that contains the name of the\r
+\              word. The length is in the low byte of the cell (little byte\r
+\              for little-endian, big byte for big-endian).\r
+\              Eventually, a''' contains 0 to indicate the end of the wordlist\r
+\              (oldest entry). a=0 indicates an empty wordlist.\r
+\              xt is the xt of the word. aabbccddeedd etc. is the name of\r
+\              the word, packed into cells.\r
+\r
+: (search-wordlist)\r
+               ROT >R SWAP DUP 0= IF -16 THROW THEN\r
+                               \ attempt to use zero-length string as a name\r
+               >R              \ wid  R: ca1 u\r
+               BEGIN @         \ ca2  R: ca1 u\r
+                  DUP 0= IF R> R> 2DROP EXIT THEN      \ not found\r
+                  DUP COUNT [ =mask ] LITERAL AND R@ = \ ca2 ca2+char f\r
+                     IF   R> R@ SWAP DUP >R            \ ca2 ca2+char ca1 u\r
+                          same?                        \ ca2 flag\r
+                   \ ELSE DROP -1      \ unnecessary since ca2+char is not 0.\r
+                     THEN\r
+               WHILE cell-             \ pointer to next word in wordlist\r
+               REPEAT\r
+               R> R> 2DROP DUP name>xt SWAP            \ xt ca2\r
+               C@ 2DUP [ =seman ] LITERAL AND 0= 0=    \ xt char xt f\r
+               AND TO specialComp?\r
+               DUP [ =compo ] LITERAL AND 0= SWAP\r
+               [ =immed ] LITERAL AND 0= 2* 1+ ;\r
+\r
+\                $COLON  NameParenSearch_Wordlist,ParenSearch_Wordlist\r
+\                DW      ROT,ToR,SWAP,DUPP,ZBranch,PSRCH6\r
+\                DW      ToR\r
+\ PSRCH1         DW      Fetch\r
+\                DW      DUPP,ZBranch,PSRCH9\r
+\                DW      DUPP,COUNT,DoLIT,MASKK,ANDD,RFetch,Equals\r
+\                DW      ZBranch,PSRCH5\r
+\                DW      RFrom,RFetch,SWAP,DUPP,ToR,SameQ\r
+\ PSRCH5         DW      ZBranch,PSRCH3\r
+\                DW      CellMinus,Branch,PSRCH1\r
+\ PSRCH3         DW      RFrom,RFrom,TwoDROP,DUPP,NameToXT,SWAP\r
+\                DW      CFetch,TwoDUP,DoLIT,SEMAN,ANDD,ZeroEquals,ZeroEquals\r
+\                DW      ANDD,DoTO,AddrSpecialCompQ\r
+\                DW      DUPP,DoLIT,COMPO,ANDD,ZeroEquals,SWAP\r
+\                DW      DoLIT,IMMED,ANDD,ZeroEquals,TwoStar,OnePlus,EXIT\r
+\ PSRCH9         DW      RFrom,RFrom,TwoDROP,EXIT\r
+\ PSRCH6         DW      DoLIT,-16,THROW\r
+\r
+\              $CODE   NameParenSearch_Wordlist,ParenSearch_Wordlist\r
+\              POP     AX      ;u\r
+\              POP     DX      ;c-addr\r
+\              OR      AX,AX\r
+\              JZ      PSRCH1\r
+\              PUSH    SI\r
+\              MOV     CX,DS\r
+\              MOV     ES,CX\r
+\              SUB     CX,CX\r
+\ PSRCH2:      MOV     BX,[BX]\r
+\              OR      BX,BX\r
+\              JZ      PSRCH4          ; end of wordlist?\r
+\              MOV     CL,[BX]\r
+\              SUB     BX,CELLL        ;pointer to nextword\r
+\              AND     CL,MASKK        ;max name length = MASKK\r
+\              CMP     CL,AL\r
+\              JNZ     PSRCH2\r
+\              MOV     SI,DX\r
+\              MOV     DI,BX\r
+\              ADD     DI,CELLL+CHARR\r
+\              REPE CMPSB\r
+\              JNZ     PSRCH2\r
+\              POP     SI\r
+\              PUSH    [BX-CELLL]      ;xt\r
+\              MOV     AL,0FFh\r
+\              MOV     CL,[BX+CELLL]\r
+\              AND     AL,CL           ;test SEMAN = 080h\r
+\              CBW\r
+\              CWD\r
+\              AND     DX,[BX-CELLL]\r
+\              MOV     AddrSpecialCompQ,DX\r
+\              XOR     DX,DX\r
+\              TEST    CL,COMPO\r
+\              JNZ     PSRCH5\r
+\              DEC     DX\r
+\ PSRCH5:      PUSH    DX\r
+\              TEST    CL,IMMED\r
+\              MOV     BX,-1\r
+\              JZ      PSRCH3\r
+\              NEG     BX\r
+\ PSRCH3:      $NEXT\r
+\ PSRCH1:      MOV     BX,-16  ;attempt to use zero-length string as a name\r
+\              JMP     THROW\r
+\ PSRCH4:      POP     SI\r
+\              $NEXT\r
+\r
+\   ?call      ( xt1 -- xt1 0 | code-addr xt2 )\r
+\              Return xt of the CALLed run-time word if xt starts with machine\r
+\              CALL instruction and leaves the next cell address after the\r
+\              CALL instruction. Otherwise leaves the original xt1 and zero.\r
+\r
+: ?call                DUP code@ call-code =\r
+               IF   CELL+ DUP code@ SWAP CELL+ DUP ROT + EXIT THEN\r
+                       \ Direct Threaded Code 8086 relative call\r
+               0 ;\r
+\r
+\                $COLON  NameQCall,QCall\r
+\                DW      DUPP,CodeFetch,DoLIT,CALLL,Equals,ZBranch,QCALL1\r
+\                DW      CELLPlus,DUPP,CodeFetch,SWAP,CELLPlus,DUPP,ROT,Plus\r
+\                DW      EXIT\r
+\ QCALL1         DW      DoLIT,0,EXIT\r
+\r
+\              $CODE   NameQCall,QCall\r
+\              MOV     AX,CS:[BX]\r
+\              CMP     AX,CALLL\r
+\              JE      QCALL1\r
+\              PUSH    BX\r
+\              XOR     BX,BX\r
+\              $NEXT\r
+\ QCALL1:      ADD     BX,2*CELLL\r
+\              PUSH    BX\r
+\              ADD     BX,CS:[BX-CELLL]\r
+\              $NEXT\r
+\r
+\   xt,        ( xt1 -- xt2 )\r
+\              Take a run-time word xt1 for :NONAME , CONSTANT , VARIABLE and\r
+\              CREATE . Return xt2 of current definition.\r
+\r
+: xt,          xhere ALIGNED DUP TO xhere SWAP\r
+               call-code code,         \ Direct Threaded Code\r
+               xhere CELL+ - code, ;   \ 8086 relative call\r
+\r
+\                $COLON  NamextComma,xtComma\r
+\                DW      XHere,ALIGNED,DUPP,DoTO,AddrXHere,SWAP\r
+\                DW      DoLIT,CALLL,CodeComma\r
+\                DW      XHere,CELLPlus,Minus,CodeComma,EXIT\r
+\r
+\              $CODE   NamextComma,xtComma\r
+\              MOV     AX,AddrXHere\r
+\              XCHG    BX,AX\r
+\              INC     BX\r
+\              AND     BX,0FFFEh\r
+\              MOV     WORD PTR CS:[BX],CALLL\r
+\              MOV     CX,BX\r
+\              ADD     CX,2*CELLL\r
+\              MOV     AddrXHere,CX\r
+\              SUB     AX,CX\r
+\              MOV     CS:[BX+CELLL],AX\r
+\              $NEXT\r
+\r
+\   doLIT      ( -- x )\r
+\              Push an inline literal. The inline literal is at the current\r
+\              value of the fpc, so put it onto the stack and point past it.\r
+\r
+\              $CODE   NameDoLIT,DoLIT\r
+\              PUSH    BX\r
+\              LODS    WORD PTR CS:[SI]\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\r
+\   doCONST    ( -- x )\r
+\              Run-time routine of CONSTANT and initializable system\r
+\              VARIABLE. When you quote a constant or variable you execute\r
+\              its code, which consists of a call to here, followed by an\r
+\              inline literal. The literal is a constant (for a CONSTANT) or\r
+\              the address at which a VARIABLE's value is stored. Although\r
+\              you come here as the result of a native machine call, you\r
+\              never go back to the return address -- you jump back up a\r
+\              level by continuing at the new fpc value. For 8086, Z80 the\r
+\              inline literal is at the return address stored on the top of\r
+\              the hardware stack.\r
+\r
+\              $CODE   NameDoCONST,DoCONST\r
+\              MOV     DI,SP\r
+\              XCHG    BX,[DI]\r
+\              MOV     BX,CS:[BX]\r
+\              $NEXT\r
+\r
+\   doVALUE    ( -- x )\r
+\              Run-time routine of VALUE. Return the value of VALUE word.\r
+\              This is like an invocation of doCONST for a VARIABLE but\r
+\              instead of returning the address of the variable, we return\r
+\              the value of the variable -- in other words, there is another\r
+\              level of indirection.\r
+\r
+\              $CODE   NameDoVALUE,DoVALUE\r
+\              MOV     DI,SP\r
+\              XCHG    BX,[DI]\r
+\              MOV     BX,CS:[BX]\r
+\              MOV     BX,[BX]\r
+\              $NEXT\r
+\r
+\   doCREATE   ( -- a-addr )\r
+\              Run-time routine of CREATE. For CREATEd words with an\r
+\              associated DOES>, get the address of the CREATEd word's data\r
+\              space and execute the DOES> actions. For CREATEd word without\r
+\              an associated DOES>, return the address of the CREATE'd word's\r
+\              data space. A CREATEd word starts its execution through this\r
+\              routine in exactly the same way as a colon definition uses\r
+\              doLIST. In other words, we come here through a native machine\r
+\              branch.\r
+\\r
+\              Structure of CREATEd word:\r
+\                      | call-doCREATE | 0 or DOES> code addr | a-addr |\r
+\\r
+\              The DOES> address holds a native call to doLIST. This routine\r
+\              doesn't alter the fpc. We never come back *here* so we never\r
+\              need to preserve an address that would bring us back *here*.\r
+\\r
+\              Example : myVARIABLE CREATE , DOES> ;\r
+\              56 myVARIABLE JIM\r
+\              JIM \ stacks the address of the data cell that contains 56\r
+\r
+: doCREATE               SWAP            \ switch BX and top of 8086 stack item\r
+                 DUP CELL+ code@ SWAP code@ ?DUP IF EXECUTE THEN\r
+                 ; COMPILE-ONLY\r
+\r
+\                $COLON  NameDoCREATE,DoCREATE\r
+\                DW      SWAP,CELLPlus,DUPP,CodeFetch,SWAP,CodeFetch\r
+\                DW      QuestionDUP,ZBranch,DOCREAT1\r
+\                DW      EXECUTE\r
+\ DOCREAT1       DW      EXIT\r
+\r
+\              $CODE   NameDoCREATE,DoCREATE\r
+\              MOV     DI,SP\r
+\              XCHG    BX,[DI]\r
+\              MOV     AX,CS:[BX]\r
+\              MOV     BX,CS:[BX+CELLL]\r
+\              OR      AX,AX\r
+\              JNZ     DOCREAT1\r
+\              $NEXT\r
+\ DOCREAT1:    JMP     AX\r
+\              $ALIGN\r
+\r
+\   doTO       ( x -- )\r
+\              Run-time routine of TO. Store x at the address in the\r
+\              following cell. The inline literal holds the address\r
+\              to be modified.\r
+\r
+\              $CODE   NameDoTO,DoTO\r
+\              LODS    WORD PTR CS:[SI]\r
+\              XCHG    BX,AX\r
+\              MOV     [BX],AX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   doUSER     ( -- a-addr )\r
+\              Run-time routine of USER. Return address of data space.\r
+\              This is like doCONST but a variable offset is added to the\r
+\              result. By changing the value at AddrUserP (which happens\r
+\              on a taskswap) the whole set of user variables is switched\r
+\              to the set for the new task.\r
+\r
+\              $CODE   NameDoUSER,DoUSER\r
+\              MOV     DI,SP\r
+\              XCHG    BX,[DI]\r
+\              MOV     BX,CS:[BX]\r
+\              ADD     BX,AddrUserP\r
+\              $NEXT\r
+\r
+\   doLIST     ( -- ) ( R: -- nest-sys )\r
+\              Process colon list.\r
+\              The first word of a definition (the xt for the word) is a\r
+\              native machine-code instruction for the target machine. For\r
+\              high-level definitions, that code is emitted by xt, and\r
+\              performs a call to doLIST. doLIST executes the list of xt that\r
+\              make up the definition. The final xt in the definition is EXIT.\r
+\              The address of the first xt to be executed is passed to doLIST\r
+\              in a target-specific way. Two examples:\r
+\              Z80, 8086: native machine call, leaves the return address on\r
+\              the hardware stack pointer, which is used for the data stack.\r
+\r
+\              $CODE   NameDoLIST,DoLIST\r
+\              SUB     BP,2\r
+\              MOV     [BP],SI                 ;push return stack\r
+\              POP     SI                      ;new list address\r
+\              $NEXT\r
+\r
+\   doLOOP     ( -- ) ( R: loop-sys1 -- | loop-sys2 )\r
+\              Run time routine for LOOP.\r
+\r
+\              $CODE   NameDoLOOP,DoLOOP\r
+\              INC     WORD PTR [BP]           ;increase loop count\r
+\              JO      DoLOOP1                 ;?loop end\r
+\              MOV     SI,CS:[SI]              ;no, go back\r
+\              $NEXT\r
+\ DoLOOP1:     ADD     SI,CELLL                ;yes, continue past the branch offset\r
+\              ADD     BP,2*CELLL              ;clear return stack\r
+\              $NEXT\r
+\r
+\   do+LOOP    ( n -- ) ( R: loop-sys1 -- | loop-sys2 )\r
+\              Run time routine for +LOOP.\r
+\r
+\              $CODE   NameDoPLOOP,DoPLOOP\r
+\              ADD     WORD PTR [BP],BX        ;increase loop count\r
+\              JO      DoPLOOP1                ;?loop end\r
+\              MOV     SI,CS:[SI]              ;no, go back\r
+\              POP     BX\r
+\              $NEXT\r
+\ DoPLOOP1:    ADD     SI,CELLL                ;yes, continue past the branch offset\r
+\              ADD     BP,2*CELLL              ;clear return stack\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   0branch    ( flag -- )\r
+\              Branch if flag is zero.\r
+\r
+\              $CODE   NameZBranch,ZBranch\r
+\              OR      BX,BX                   ;?flag=0\r
+\              JZ      ZBRAN1                  ;yes, so branch\r
+\              ADD     SI,CELLL                ;point IP to next cell\r
+\              POP     BX\r
+\              $NEXT\r
+\ ZBRAN1:      MOV     SI,CS:[SI]              ;IP:=(IP)\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   branch     ( -- )\r
+\              Branch to an inline address.\r
+\r
+\              $CODE   NameBranch,Branch\r
+\              MOV     SI,CS:[SI]              ;IP:=(IP)\r
+\              $NEXT\r
+\r
+\   rp@        ( -- a-addr )\r
+\              Push the current RP to the data stack.\r
+\r
+\              $CODE   NameRPFetch,RPFetch\r
+\              PUSH    BX\r
+\              MOV     BX,BP\r
+\              $NEXT\r
+\r
+\   rp!        ( a-addr -- )\r
+\              Set the return stack pointer.\r
+\r
+\              $CODE   NameRPStore,RPStore\r
+\              MOV     BP,BX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   sp@        ( -- a-addr )\r
+\              Push the current data stack pointer.\r
+\r
+\              $CODE   NameSPFetch,SPFetch\r
+\              PUSH    BX\r
+\              MOV     BX,SP\r
+\              $NEXT\r
+\r
+\   sp!        ( a-addr -- )\r
+\              Set the data stack pointer.\r
+\r
+\              $CODE   NameSPStore,SPStore\r
+\              MOV     SP,BX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   um+        ( u1 u2 -- u3 1|0 )\r
+\              Add two unsigned numbers, return the sum and carry.\r
+\r
+\              $CODE   NameUMPlus,UMPlus\r
+\              XOR     CX,CX\r
+\              POP     AX\r
+\              ADD     BX,AX\r
+\              PUSH    BX                      ;push sum\r
+\              RCL     CX,1                    ;get carry\r
+\              MOV     BX,CX\r
+\              $NEXT\r
+\r
+\   code!      ( x code-addr -- )\r
+\              Store x at a code space address.\r
+\r
+\              $CODE   NameCodeStore,CodeStore\r
+\              POP     CS:[BX]\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   codeB!     ( b code-addr -- )\r
+\              Store byte at a code space address.\r
+\r
+\              $CODE   NameCodeBStore,CodeBStore\r
+\              POP     AX\r
+\              MOV     CS:[BX],AL\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   code@      ( code-addr -- x )\r
+\              Push the contents at code space addr to the data stack.\r
+\r
+\              $CODE   NameCodeFetch,CodeFetch\r
+\              MOV     BX,CS:[BX]\r
+\              $NEXT\r
+\r
+\   codeB@     ( code-addr -- b )\r
+\              Push the contents at code space byte addr to the data stack.\r
+\r
+\              $CODE   NameCodeBFetch,CodeBFetch\r
+\              MOV     BL,CS:[BX]\r
+\              XOR     BH,BH\r
+\              $NEXT\r
+\r
+\   code,      ( x -- )\r
+\              Reserve one cell in code space and store x in it.\r
+\r
+: code,                xhere DUP CELL+ TO xhere code! ; COMPILE-ONLY\r
+\r
+\                $COLON  NameCodeComma,CodeComma\r
+\                DW      XHere,DUPP,CELLPlus,DoTO,AddrXHere,CodeStore,EXIT\r
+\r
+\              $CODE   NameCodeComma,CodeComma\r
+\              MOV     DI,AddrXHere\r
+\              MOV     CS:[DI],BX\r
+\              ADD     DI,CELLL\r
+\              POP     BX\r
+\              MOV     AddrXHere,DI\r
+\              $NEXT\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ Standard words - Processor-dependent definitions\r
+\      16 bit Forth for 8086/8\r
+\ ;;;;;;;;;;;;;;;\r
+\r
+\   ALIGN      ( -- )                          \ CORE\r
+\              Align the data space pointer.\r
+\r
+: ALIGN                HERE ALIGNED TO HERE ;\r
+\r
+\              $COLON  NameALIGNN,ALIGNN\r
+\              DW      HERE,ALIGNED,DoTO,AddrHERE,EXIT\r
+\r
+\   ALIGNED    ( addr -- a-addr )              \ CORE\r
+\              Align address to the cell boundary.\r
+\r
+: ALIGNED      DUP 0 cell-size UM/MOD DROP DUP\r
+               IF cell-size SWAP - THEN + ;\r
+\r
+\                $COLON  NameALIGNED,ALIGNED\r
+\                DW      DUPP,DoLIT,0,DoLIT,CELLL\r
+\                DW      UMSlashMOD,DROP,DUPP\r
+\                DW      ZBranch,ALGN1\r
+\                DW      DoLIT,CELLL,SWAP,Minus\r
+\ ALGN1          DW      Plus,EXIT\r
+\r
+\              $CODE   NameALIGNED,ALIGNED\r
+\              INC     BX\r
+\              AND     BX,0FFFEh\r
+\              $NEXT\r
+\r
+\   CELLS      ( n1 -- n2 )                    \ CORE\r
+\              Calculate number of address units for n1 cells.\r
+\r
+\ : CELLS              cell-size * ;   \ slow, very portable\r
+: CELLS                2* ;            \ fast, must be redefined for each system\r
+\r
+\                $COLON  NameCELLS,CELLS\r
+\                DW      TwoStar,EXIT\r
+\r
+\              $CODE   NameCELLS,CELLS\r
+\              SHL     BX,1\r
+\              $NEXT\r
+\r
+\   CHARS      ( n1 -- n2 )                    \ CORE\r
+\              Calculate number of address units for n1 characters.\r
+\r
+\ : CHARS              char-size * ;   \ slow, very portable\r
+: CHARS                ;               \ fast, must be redefined for each system\r
+\r
+\             $COLON  NameCHARS,CHARS\r
+\             DW      EXIT\r
+\r
+\   1chars/    ( n1 -- n2 )\r
+\              Calculate number of chars for n1 address units.\r
+\r
+\ : 1chars/            1 CHARS / ;     \ slow, very portable\r
+: 1chars/              ;               \ fast, must be redefined for each system\r
+\r
+\              $COLON  NameOneCharsSlash,OneCharsSlash\r
+\              DW      EXIT\r
+\r
+\   !          ( x a-addr -- )                 \ CORE\r
+\              Store x at a aligned address.\r
+\r
+\              $CODE   NameStore,Store\r
+\              POP     [BX]\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   0<         ( n -- flag )                   \ CORE\r
+\              Return true if n is negative.\r
+\r
+\              $CODE   NameZeroLess,ZeroLess\r
+\              MOV     AX,BX\r
+\              CWD             ;sign extend\r
+\              MOV     BX,DX\r
+\              $NEXT\r
+\r
+\   0=         ( x -- flag )                   \ CORE\r
+\              Return true if x is zero.\r
+\r
+\              $CODE   NameZeroEquals,ZeroEquals\r
+\              OR      BX,BX\r
+\              MOV     BX,TRUEE\r
+\              JZ      ZEQUAL1\r
+\              INC     BX\r
+\ ZEQUAL1:     $NEXT\r
+\r
+\   2*         ( x1 -- x2 )                    \ CORE\r
+\              Bit-shift left, filling the least significant bit with 0.\r
+\r
+\              $CODE   NameTwoStar,TwoStar\r
+\              SHL     BX,1\r
+\              $NEXT\r
+\r
+\   2/         ( x1 -- x2 )                    \ CORE\r
+\              Bit-shift right, leaving the most significant bit unchanged.\r
+\r
+\              $CODE   NameTwoSlash,TwoSlash\r
+\              SAR     BX,1\r
+\              $NEXT\r
+\r
+\   >R         ( x -- ) ( R: -- x )            \ CORE\r
+\              Move top of the data stack item to the return stack.\r
+\r
+\              $CODE   NameToR,ToR\r
+\              SUB     BP,CELLL                ;adjust RP\r
+\              MOV     [BP],BX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   @          ( a-addr -- x )                 \ CORE\r
+\              Push the contents at a-addr to the data stack.\r
+\r
+\              $CODE   NameFetch,Fetch\r
+\              MOV     BX,[BX]\r
+\              $NEXT\r
+\r
+\   AND        ( x1 x2 -- x3 )                 \ CORE\r
+\              Bitwise AND.\r
+\r
+\              $CODE   NameANDD,ANDD\r
+\              POP     AX\r
+\              AND     BX,AX\r
+\              $NEXT\r
+\r
+\   C!         ( char c-addr -- )              \ CORE\r
+\              Store char at c-addr.\r
+\r
+\              $CODE   NameCStore,CStore\r
+\              POP     AX\r
+\              MOV     [BX],AL\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   C@         ( c-addr -- char )              \ CORE\r
+\              Fetch the character stored at c-addr.\r
+\r
+\              $CODE   NameCFetch,CFetch\r
+\              MOV     BL,[BX]\r
+\              XOR     BH,BH\r
+\              $NEXT\r
+\r
+\   DROP       ( x -- )                        \ CORE\r
+\              Discard top stack item.\r
+\r
+\              $CODE   NameDROP,DROP\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   DUP        ( x -- x x )                    \ CORE\r
+\              Duplicate the top stack item.\r
+\r
+\              $CODE   NameDUPP,DUPP\r
+\              PUSH    BX\r
+\              $NEXT\r
+\r
+\   EXECUTE    ( i*x xt -- j*x )               \ CORE\r
+\              Perform the semantics indentified by execution token, xt.\r
+\r
+\              $CODE   NameEXECUTE,EXECUTE\r
+\              MOV     AX,BX\r
+\              POP     BX\r
+\              JMP     AX                      ;jump to the code address\r
+\              $ALIGN\r
+\r
+\   EXIT       ( -- ) ( R: nest-sys -- )       \ CORE\r
+\              Return control to the calling definition.\r
+\r
+\              $CODE   NameEXIT,EXIT\r
+\              XCHG    BP,SP                   ;exchange pointers\r
+\              POP     SI                      ;pop return stack\r
+\              XCHG    BP,SP                   ;restore the pointers\r
+\              $NEXT\r
+\r
+\   MOVE       ( addr1 addr2 u -- )            \ CORE\r
+\              Copy u address units from addr1 to addr2 if u is greater\r
+\              than zero. This word is CODE defined since no other Standard\r
+\              words can handle address unit directly.\r
+\r
+\              $CODE   NameMOVE,MOVE\r
+\              POP     DI\r
+\              POP     DX\r
+\              OR      BX,BX\r
+\              JZ      MOVE2\r
+\              MOV     CX,BX\r
+\              XCHG    DX,SI                   ;save SI\r
+\              MOV     AX,DS\r
+\              MOV     ES,AX                   ;set ES same as DS\r
+\              CMP     SI,DI\r
+\              JC      MOVE1\r
+\              REP MOVSB\r
+\              MOV     SI,DX\r
+\ MOVE2:               POP     BX\r
+\              $NEXT\r
+\ MOVE1:               STD\r
+\              ADD     DI,CX\r
+\              DEC     DI\r
+\              ADD     SI,CX\r
+\              DEC     SI\r
+\              REP MOVSB\r
+\              CLD\r
+\              MOV     SI,DX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   OR         ( x1 x2 -- x3 )                 \ CORE\r
+\              Return bitwise inclusive-or of x1 with x2.\r
+\r
+\              $CODE   NameORR,ORR\r
+\              POP     AX\r
+\              OR      BX,AX\r
+\              $NEXT\r
+\r
+\   OVER       ( x1 x2 -- x1 x2 x1 )           \ CORE\r
+\              Copy second stack item to top of the stack.\r
+\r
+\              $CODE   NameOVER,OVER\r
+\              MOV     DI,SP\r
+\              PUSH    BX\r
+\              MOV     BX,[DI]\r
+\              $NEXT\r
+\r
+\   R>         ( -- x ) ( R: x -- )            \ CORE\r
+\              Move x from the return stack to the data stack.\r
+\r
+\              $CODE   NameRFrom,RFrom\r
+\              PUSH    BX\r
+\              MOV     BX,[BP]\r
+\              ADD     BP,CELLL                ;adjust RP\r
+\              $NEXT\r
+\r
+\   R@         ( -- x ) ( R: x -- x )          \ CORE\r
+\              Copy top of return stack to the data stack.\r
+\r
+\              $CODE   NameRFetch,RFetch\r
+\              PUSH    BX\r
+\              MOV     BX,[BP]\r
+\              $NEXT\r
+\r
+\   SWAP       ( x1 x2 -- x2 x1 )              \ CORE\r
+\              Exchange top two stack items.\r
+\r
+\              $CODE   NameSWAP,SWAP\r
+\              MOV     DI,SP\r
+\              XCHG    BX,[DI]\r
+\              $NEXT\r
+\r
+\   XOR        ( x1 x2 -- x3 )                 \ CORE\r
+\              Bitwise exclusive OR.\r
+\r
+\              $CODE   NameXORR,XORR\r
+\              POP     AX\r
+\              XOR     BX,AX\r
+\              $NEXT\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ System constants and variables\r
+\ ;;;;;;;;;;;;;;;\r
+\r
+\   #order0    ( -- a-addr )\r
+\              Start address of default search order.\r
+\r
+\              $CONST  NameNumberOrder0,NumberOrder0,AddrNumberOrder0\r
+\r
+\   'ekey?      ( -- a-addr )\r
+\              Execution vector of EKEY?.\r
+\r
+\              $VALUE  NameTickEKEYQ,TickEKEYQ,AddrTickEKEYQ\r
+\r
+\   'ekey       ( -- a-addr )\r
+\              Execution vector of EKEY.\r
+\r
+\              $VALUE  NameTickEKEY,TickEKEY,AddrTickEKEY\r
+\r
+\   'emit?      ( -- a-addr )\r
+\              Execution vector of EMIT?.\r
+\r
+\              $VALUE  NameTickEMITQ,TickEMITQ,AddrTickEMITQ\r
+\r
+\   'emit       ( -- a-addr )\r
+\              Execution vector of EMIT.\r
+\r
+\              $VALUE  NameTickEMIT,TickEMIT,AddrTickEMIT\r
+\r
+\   'init-i/o   ( -- a-addr )\r
+\              Execution vector to initialize input/output devices.\r
+\r
+\              $VALUE  NameTickINIT_IO,TickINIT_IO,AddrTickINIT_IO\r
+\r
+\   'prompt     ( -- a-addr )\r
+\              Execution vector of '.prompt'.\r
+\r
+\              $VALUE  NameTickPrompt,TickPrompt,AddrTickPrompt\r
+\r
+\   'boot       ( -- a-addr )\r
+\              Execution vector of COLD.\r
+\r
+\              $VALUE  NameTickBoot,TickBoot,AddrTickBoot\r
+\r
+\   SOURCE-ID  ( -- 0 | -1 )                   \ CORE EXT\r
+\              Identify the input source. -1 for string (via EVALUATE) and\r
+\              0 for user input device.\r
+\r
+\              $VALUE  NameSOURCE_ID,SOURCE_ID,AddrSOURCE_ID\r
+\r
+\   HERE       ( -- addr )                     \ CORE\r
+\              Return data space pointer.\r
+\r
+\              $VALUE  NameHERE,HERE,AddrHERE\r
+\r
+\   xhere      ( -- code-addr )\r
+\              Return next available code space address.\r
+\r
+\              $VALUE  NameXHere,XHere,AddrXHere\r
+\r
+\   'doWord     ( -- a-addr )\r
+\              Execution vectors for 'interpret'.\r
+\r
+\              $CONST  NameTickDoWord,TickDoWord,AddrTickDoWord\r
+\r
+\   BASE       ( -- a-addr )                   \ CORE\r
+\              Return the address of the radix base for numeric I/O.\r
+\r
+\              $CONST  NameBASE,BASE,AddrBASE\r
+\r
+\   THROWMsgTbl ( -- a-addr )                  \ CORE\r
+\              Return the address of the THROW message table.\r
+\r
+\              $CONST  NameTHROWMsgTbl,THROWMsgTbl,AddrTHROWMsgTbl\r
+\r
+\   memTop     ( -- a-addr )\r
+\              Top of free memory.\r
+\r
+\              $VALUE  NameMemTop,MemTop,AddrMemTop\r
+\r
+\   bal        ( -- n )\r
+\              Return the depth of control-flow stack.\r
+\r
+\              $VALUE  NameBal,Bal,AddrBal\r
+\r
+\   notNONAME? ( -- f )\r
+\              Used by ';' whether to do 'linkLast' or not\r
+\r
+\              $VALUE  NameNotNONAMEQ,NotNONAMEQ,AddrNotNONAMEQ\r
+\r
+\   rakeVar    ( -- a-addr )\r
+\              Used by 'rake' to gather LEAVE.\r
+\r
+\              $CONST  NameRakeVar,RakeVar,AddrRakeVar\r
+\r
+\   #order     ( -- a-addr )\r
+\              Hold the search order stack depth.\r
+\r
+\              $CONST  NameNumberOrder,NumberOrder,AddrNumberOrder\r
+\r
+\   current    ( -- a-addr )\r
+\              Point to the wordlist to be extended.\r
+\r
+\              $CONST  NameCurrent,Current,AddrCurrent\r
+\r
+\   FORTH-WORDLIST   ( -- wid )                \ SEARCH\r
+\              Return wid of Forth wordlist.\r
+\r
+\              $CONST  NameFORTH_WORDLIST,FORTH_WORDLIST,AddrFORTH_WORDLIST\r
+\r
+\   NONSTANDARD-WORDLIST   ( -- wid )\r
+\              Return wid of non-standard wordlist.\r
+\r
+\              $CONST  NameNONSTANDARD_WORDLIST,NONSTANDARD_WORDLIST,AddrNONSTANDARD_WORDLIST\r
+\r
+\   envQList   ( -- wid )\r
+\              Return wid of ENVIRONMENT? string list. Never put this wid in\r
+\              search-order. It should be used only by SET-CURRENT to add new\r
+\              environment query string after addition of a complete wordset.\r
+\r
+\              $CONST  NameEnvQList,EnvQList,AddrEnvQList\r
+\r
+\   userP      ( -- a-addr )\r
+\              Return address of USER variable area of current task.\r
+\r
+\              $CONST  NameUserP,UserP,AddrUserP\r
+\r
+\   SystemTask ( -- a-addr )\r
+\              Return system task's tid.\r
+\r
+\              $CONST  NameSystemTask,SystemTask,SysTask\r
+\r
+\   follower   ( -- a-addr )\r
+\              Point next task's 'status' USER variable.\r
+\r
+\              $USER   NameFollower,Follower,SysFollower-SysUserP\r
+\r
+\   status     ( -- a-addr )\r
+\              Status of current task. Point 'pass' or 'wake'.\r
+\r
+\              $USER   NameStatus,Status,SysStatus-SysUserP\r
+\r
+\   stackTop   ( -- a-addr )\r
+\              Store current task's top of stack position.\r
+\r
+\              $USER   NameStackTop,StackTop,SysStackTop-SysUserP\r
+\r
+\   throwFrame ( -- a-addr )\r
+\              THROW frame for CATCH and THROW need to be saved for eack task.\r
+\r
+\              $USER   NameThrowFrame,ThrowFrame,SysThrowFrame-SysUserP\r
+\r
+\   taskName   ( -- a-addr )\r
+\              Current task's task ID.\r
+\r
+\              $USER   NameTaskName,TaskName,SysTaskName-SysUserP\r
+\r
+\   user1      ( -- a-addr )\r
+\              One free USER variable for each task.\r
+\r
+\              $USER   NameUser1,User1,SysUser1-SysUserP\r
+\r
+\ ENVIRONMENT? strings can be searched using SEARCH-WORDLIST and can be\r
+\ EXECUTEd. This wordlist is completely hidden to Forth system except\r
+\ ENVIRONMENT? .\r
+\r
+\ CPU:\r
+\              NOP\r
+\              CALL    DoLIST\r
+\              DW      DoLIT,CPUStr,COUNT,EXIT\r
+\r
+\ Model:\r
+\              NOP\r
+\              CALL    DoLIST\r
+\              DW      DoLIT,ModelStr,COUNT,EXIT\r
+\r
+\ Version:\r
+\              NOP\r
+\              CALL    DoLIST\r
+\              DW      DoLIT,VersionStr,COUNT,EXIT\r
+\r
+\ SlashCOUNTED_STRING:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      MaxChar\r
+\r
+\ SlashHOLD:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      PADSize\r
+\r
+\ SlashPAD:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      PADSize\r
+\r
+\ ADDRESS_UNIT_BITS:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      8\r
+\r
+\ CORE:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      TRUEE\r
+\r
+\ FLOORED:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      TRUEE\r
+\r
+\ MAX_CHAR:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      MaxChar         ;max value of character set\r
+\r
+\ MAX_D:\r
+\              NOP\r
+\              CALL    DoLIST\r
+\              DW      DoLIT,MaxUnsigned,DoLIT,MaxSigned,EXIT\r
+\r
+\ MAX_N:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      MaxSigned\r
+\r
+\ MAX_U:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      MaxUnsigned\r
+\r
+\ MAX_UD:\r
+\              NOP\r
+\              CALL    DoLIST\r
+\              DW      MAX_U,MAX_U,EXIT\r
+\r
+\ RETURN_STACK_CELLS:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      RTCells\r
+\r
+\ STACK_CELLS:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      DTCells\r
+\r
+\ EXCEPTION:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      TRUEE\r
+\r
+\ EXCEPTION_EXT:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      TRUEE\r
+\r
+\ WORDLISTS:\r
+\              NOP\r
+\              CALL    DoCONST\r
+\              DW      OrderDepth\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ Non-Standard words - Colon definitions\r
+\ ;;;;;;;;;;;;;;;\r
+\r
+\   (')         ( "<spaces>name" -- xt 1 | xt -1 )\r
+\              Parse a name, find it and return execution token and\r
+\              -1 or 1 ( IMMEDIATE) if found\r
+\r
+: (')          PARSE-WORD search-word ?DUP IF NIP EXIT THEN\r
+               errWord 2!      \ if not found error\r
+               -13 THROW ;     \ undefined word\r
+\r
+\              $COLON  NameParenTick,ParenTick\r
+\              DW      PARSE_WORD,Search_word,QuestionDUP,ZBranch,PTICK1\r
+\              DW      NIP,EXIT\r
+\ PTICK1               DW      DoLIT,AddrErrWord,TwoStore,DoLIT,-13,THROW\r
+\r
+\   (d.)       ( d -- c-addr u )\r
+\              Convert a double number to a string.\r
+\r
+: (d.)         SWAP OVER  DUP 0< IF  DNEGATE  THEN\r
+               <#  #S ROT SIGN  #> ;\r
+\r
+\              $COLON  NameParenDDot,ParenDDot\r
+\              DW      SWAP,OVER,DUPP,ZeroLess,ZBranch,PARDD1\r
+\              DW      DNEGATE\r
+\ PARDD1               DW      LessNumberSign,NumberSignS,ROT\r
+\              DW      SIGN,NumberSignGreater,EXIT\r
+\r
+\   .ok        ( -- )\r
+\              Display 'ok'.\r
+\r
+: .ok          ." okay" ;\r
+\r
+\              $COLON  NameDotOK,DotOK\r
+\              DW      DoLIT,DotOKStr\r
+\              DW      COUNT,TYPEE,EXIT\r
+\r
+\   .prompt        ( -- )\r
+\              Disply Forth prompt. This word is vectored.\r
+\r
+: .prompt              'prompt EXECUTE ;\r
+\r
+\              $COLON  NameDotOK,DotPrompt\r
+\              DW      TickPrompt,EXECUTE,EXIT\r
+\r
+\   0          ( -- 0 )\r
+\              Return zero.\r
+\r
+\              $CONST  NameZero,Zero,0\r
+\r
+\   1          ( -- 1 )\r
+\              Return one.\r
+\r
+\              $CONST  NameOne,One,1\r
+\r
+\   -1         ( -- -1 )\r
+\              Return -1.\r
+\r
+\              $CONST  NameMinusOne,MinusOne,-1\r
+\r
+\   abort"msg   ( -- a-addr )\r
+\              Abort" error message string address.\r
+\r
+\              $CONST  NameAbortQMsg,AbortQMsg,AddrAbortQMsg\r
+\r
+\   bal+       ( -- )\r
+\              Increase bal by 1.\r
+\r
+: bal+         bal 1+ TO bal ;\r
+\r
+\                $COLON  4,'bal+',BalPlus,_SLINK\r
+\                DW      Bal,OnePlus,DoTO,AddrBal,EXIT\r
+\r
+\              $CODE   NameBalPlus,BalPlus\r
+\              INC     AddrBal\r
+\              $NEXT\r
+\r
+\   bal-       ( -- )\r
+\              Decrease bal by 1.\r
+\r
+: bal-         bal 1- TO bal ;\r
+\r
+\                $COLON  NameBalMinus,BalMinus\r
+\                DW      Bal,OneMinus,DoTO,AddrBal,EXIT\r
+\r
+\              $CODE   NameBalMinus,BalMinus\r
+\              DEC     AddrBal\r
+\              $NEXT\r
+\r
+\   cell-      ( a-addr1 -- a-addr2 )\r
+\              Return previous aligned cell address.\r
+\r
+: cell-                [ cell-size NEGATE ] LITERAL + ;\r
+\r
+\               $COLON  NameCellMinus,CellMinus\r
+\               DW      DoLIT,0-CELLL,Plus,EXIT\r
+\r
+\              $CODE   NameCellMinus,CellMinus\r
+\              SUB     BX,CELLL\r
+\              $NEXT\r
+\r
+\   COMPILE-ONLY   ( -- )\r
+\              Make the most recent definition an compile-only word.\r
+\r
+: COMPILE-ONLY lastName [ =compo ] LITERAL OVER @ OR SWAP ! ;\r
+\r
+\              $COLON  NameCOMPILE_ONLY,COMPILE_ONLY\r
+\              DW      LastName,DoLIT,COMPO,OVER,Fetch,ORR,SWAP,Store,EXIT\r
+\r
+\   doDO       ( n1|u1 n2|u2 -- ) ( R: -- n1 n2-n1-max_negative )\r
+\              Run-time funtion of DO.\r
+\r
+: doDO         >R max-negative + R> OVER - SWAP R> SWAP >R SWAP >R >R ;\r
+\r
+\                $COLON  NameDoDO,DoDO\r
+\                DW      ToR,DoLIT,MaxNegative,Plus,RFrom\r
+\                DW      OVER,Minus,SWAP,RFrom,SWAP,ToR,SWAP,ToR,ToR,EXIT\r
+\r
+\              $CODE   NameDoDO,DoDO\r
+\              SUB     BP,2*CELLL\r
+\              POP     AX\r
+\              ADD     AX,MaxNegative\r
+\              MOV     [BP+CELLL],AX\r
+\              SUB     BX,AX\r
+\              MOV     [BP],BX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   errWord    ( -- a-addr )\r
+\              Last found word. To be used to display the word causing error.\r
+\r
+\              $CONST  NameErrWord,ErrWord,AddrErrWord\r
+\r
+\   head,      ( xt "<spaces>name" -- )\r
+\              Parse a word and build a dictionary entry.\r
+\r
+: head,                >R  PARSE-WORD DUP 0=\r
+               IF errWord 2! -16 THROW THEN\r
+                               \ attempt to use zero-length string as a name\r
+               DUP =mask > IF -19 THROW THEN   \ definition name too long\r
+               2DUP GET-CURRENT SEARCH-WORDLIST  \ name exist?\r
+               IF DROP ." redefine " 2DUP TYPE SPACE THEN \ warn if redefined\r
+               ALIGN R@ ,                      \ align and store xt\r
+               GET-CURRENT @ ,                 \ build wordlist link\r
+               HERE DUP >R pack" ALIGNED TO HERE \ pack the name in name space\r
+               R> DUP R> cell- code!           \ store name addr in code space\r
+               TO lastName ;\r
+\r
+\              $COLON  NameHeadComma,HeadComma\r
+\              DW      ToR,PARSE_WORD,DUPP,ZBranch,HEADC1\r
+\              DW      DUPP,DoLIT,MASKK,GreaterThan,ZBranch,HEADC3\r
+\              DW      DoLIT,-19,THROW\r
+\ HEADC3               DW      TwoDUP,GET_CURRENT,SEARCH_WORDLIST,ZBranch,HEADC2\r
+\              DW      DROP\r
+\              DW      DoLIT,HEADCstr\r
+\              DW      COUNT,TYPEE,TwoDUP,TYPEE,SPACE\r
+\ HEADC2               DW      ALIGNN,RFetch,Comma\r
+\              DW      GET_CURRENT,Fetch,Comma\r
+\              DW      HERE,DUPP,ToR,PackQuote,ALIGNED,DoTO,AddrHERE\r
+\              DW      RFrom,DUPP,RFrom,CellMinus,CodeStore\r
+\              DW      DoTO,AddrLastName,EXIT\r
+\ HEADC1               DW      DoLIT,AddrErrWord,TwoStore,DoLIT,-16,THROW\r
+\r
+\   hld        ( -- a-addr )\r
+\              Hold a pointer in building a numeric output string.\r
+\r
+\              $CONST  NameHLD,HLD,AddrHLD\r
+\r
+\   interpret  ( i*x -- j*x )\r
+\              Intrepret input string.\r
+\r
+: interpret    BEGIN  DEPTH 0< IF -4 THROW THEN        \ stack underflow\r
+                      PARSE-WORD DUP\r
+               WHILE  2DUP errWord 2!\r
+                      search-word          \ ca u 0 | xt f -1 | xt f 1\r
+                      DUP IF\r
+                        SWAP STATE @ OR 0= \ compile-only in interpretation\r
+                        IF -14 THROW THEN  \ interpreting a compile-only word\r
+                      THEN\r
+                      1+ 2* STATE @ 1+ + CELLS 'doWord + @ EXECUTE\r
+               REPEAT 2DROP ;\r
+\r
+\              $COLON  NameInterpret,Interpret\r
+\ INTERP1      DW      DEPTH,ZeroLess,ZBranch,INTERP2\r
+\              DW      DoLIT,-4,THROW\r
+\ INTERP2      DW      PARSE_WORD,DUPP,ZBranch,INTERP3\r
+\              DW      TwoDUP,DoLIT,AddrErrWord,TwoStore\r
+\              DW      Search_word,DUPP,ZBranch,INTERP5\r
+\              DW      SWAP,DoLIT,AddrSTATE,Fetch,ORR,ZBranch,INTERP4\r
+\ INTERP5      DW      OnePlus,TwoStar,DoLIT,AddrSTATE,Fetch,OnePlus,Plus,CELLS\r
+\              DW      DoLIT,AddrTickDoWord,Plus,Fetch,EXECUTE\r
+\              DW      Branch,INTERP1\r
+\ INTERP3      DW      TwoDROP,EXIT\r
+\ INTERP4      DW      DoLIT,-14,THROW\r
+\r
+\   optiCOMPILE, ( xt -- )\r
+\              Optimized COMPILE, . Reduce doLIST ... EXIT sequence if\r
+\              xt is COLON definition which contains less than two words.\r
+\r
+: optiCOMPILE,\r
+               DUP ?call ['] doLIST = IF\r
+                   DUP code@ ['] EXIT = IF         \ if first word is EXIT\r
+                     2DROP EXIT THEN\r
+                   DUP CELL+ code@ ['] EXIT = IF   \ if second word is EXIT\r
+                     code@ DUP ['] doLIT XOR   \ make sure it is not literal\r
+                     IF SWAP THEN THEN\r
+               THEN DROP COMPILE, ;\r
+\r
+\                $COLON  NameOptiCOMPILEComma,OptiCOMPILEComma\r
+\                DW      DUPP,QCall,DoLIT,DoLIST,Equals,ZBranch,OPTC2\r
+\                DW      DUPP,CodeFetch,DoLIT,EXIT,Equals,ZBranch,OPTC1\r
+\                DW      TwoDROP,EXIT\r
+\ OPTC1          DW      DUPP,CELLPlus,CodeFetch,DoLIT,EXIT,Equals\r
+\                DW      ZBranch,OPTC2\r
+\                DW      CodeFetch,DUPP,DoLIT,DoLIT,XORR,ZBranch,OPTC2\r
+\                DW      SWAP\r
+\ OPTC2          DW      DROP,COMPILEComma,EXIT\r
+\r
+\              $CODE   NameOptiCOMPILEComma,OptiCOMPILEComma\r
+\              CMP     WORD PTR CS:[BX],CALLL\r
+\              JNE     OPTC1\r
+\              MOV     AX,CS:[BX+CELLL]\r
+\              ADD     AX,BX\r
+\              ADD     AX,2*CELLL\r
+\              CMP     AX,OFFSET DoLIST\r
+\              JNE     OPTC1\r
+\              MOV     DX,OFFSET EXIT\r
+\              MOV     AX,CS:[BX+2*CELLL]\r
+\              CMP     AX,DX\r
+\              JE      OPTC2\r
+\              CMP     DX,CS:[BX+3*CELLL]\r
+\              JNE     OPTC1\r
+\              CMP     AX,OFFSET DoLIT\r
+\              JE      OPTC1\r
+\              MOV     BX,AX\r
+\ OPTC1:               JMP     COMPILEComma\r
+\ OPTC2:               POP     BX\r
+\              $NEXT\r
+\r
+\   singleOnly ( c-addr u -- x )\r
+\              Handle the word not found in the search-order. If the string\r
+\              is legal, leave a single cell number in interpretation state.\r
+\r
+: singleOnly\r
+               0 DUP 2SWAP OVER C@ [CHAR] -\r
+               = DUP >R IF 1 /STRING THEN\r
+               >NUMBER IF -13 THROW THEN       \ undefined word\r
+               2DROP R> IF NEGATE THEN ;\r
+\r
+\              $COLON  NameSingleOnly,SingleOnly\r
+\              DW      DoLIT,0,DUPP,TwoSWAP,OVER,CFetch,DoLIT,'-'\r
+\              DW      Equals,DUPP,ToR,ZBranch,SINGLEO4\r
+\              DW      DoLIT,1,SlashSTRING\r
+\ SINGLEO4     DW      ToNUMBER,ZBranch,SINGLEO1\r
+\              DW      DoLIT,-13,THROW\r
+\ SINGLEO1     DW      TwoDROP,RFrom,ZBranch,SINGLEO2\r
+\              DW      NEGATE\r
+\ SINGLEO2     DW      EXIT \r
+\   singleOnly, ( c-addr u -- )\r
+\              Handle the word not found in the search-order. Compile a\r
+\              single cell number in compilation state.\r
+\r
+: singleOnly,\r
+               singleOnly POSTPONE LITERAL ;\r
+\r
+\              $COLON  NameSingleOnlyComma,SingleOnlyComma\r
+\              DW      SingleOnly,LITERAL,EXIT\r
+\r
+\   (doubleAlso) ( c-addr u -- x 1 | x x 2 )\r
+\              If the string is legal, leave a single or double cell number\r
+\              and size of the number.\r
+\r
+: (doubleAlso)\r
+               0 DUP 2SWAP OVER C@ [CHAR] -\r
+               = DUP >R IF 1 /STRING THEN\r
+               >NUMBER ?DUP\r
+               IF   1- IF -13 THROW THEN     \ more than one char is remained\r
+                    DUP C@ [CHAR] . XOR      \ last char is not '.'\r
+                    IF -13 THROW THEN        \ undefined word\r
+                    R> IF DNEGATE THEN\r
+                    2 EXIT               THEN\r
+               2DROP R> IF NEGATE THEN       \ single number\r
+               1 ;\r
+\r
+\              $COLON  NameParenDoubleAlso,ParenDoubleAlso\r
+\              DW      DoLIT,0,DUPP,TwoSWAP,OVER,CFetch,DoLIT,'-'\r
+\              DW      Equals,DUPP,ToR,ZBranch,DOUBLEA1\r
+\              DW      DoLIT,1,SlashSTRING\r
+\ DOUBLEA1     DW      ToNUMBER,QuestionDUP,ZBranch,DOUBLEA4\r
+\              DW      OneMinus,ZBranch,DOUBLEA3\r
+\ DOUBLEA2     DW      DoLIT,-13,THROW\r
+\ DOUBLEA3     DW      CFetch,DoLIT,'.',Equals,ZBranch,DOUBLEA2\r
+\              DW      RFrom,ZBranch,DOUBLEA5\r
+\              DW      DNEGATE\r
+\ DOUBLEA5     DW      DoLIT,2,EXIT\r
+\ DOUBLEA4     DW      TwoDROP,RFrom,ZBranch,DOUBLEA6\r
+\              DW      NEGATE\r
+\ DOUBLEA6     DW      DoLIT,1,EXIT\r
+\r
+\   doubleAlso ( c-addr u -- x | x x )\r
+\              Handle the word not found in the search-order. If the string\r
+\              is legal, leave a single or double cell number in\r
+\              interpretation state.\r
+\r
+: doubleAlso\r
+               (doubleAlso) DROP ;\r
+\r
+\              $COLON  NameDoubleAlso,DoubleAlso\r
+\              DW      ParenDoubleAlso,DROP,EXIT\r
+\r
+\   doubleAlso, ( c-addr u -- )\r
+\              Handle the word not found in the search-order. If the string\r
+\              is legal, compile a single or double cell number in\r
+\              compilation state.\r
+\r
+: doubleAlso,\r
+               (doubleAlso) 1- IF SWAP POSTPONE LITERAL THEN POSTPONE LITERAL ;\r
+\r
+\              $COLON  NameDoubleAlsoComma,DoubleAlsoComma\r
+\              DW      ParenDoubleAlso,OneMinus,ZBranch,DOUBC1\r
+\              DW      SWAP,LITERAL\r
+\ DOUBC1               DW      LITERAL,EXIT\r
+\r
+\   -.         ( -- )\r
+\              You don't need this word unless you care that '-.' returns\r
+\              double cell number 0. Catching illegal number '-.' in this way\r
+\              is easier than make 'interpret' catch this exception.\r
+\r
+: -.           -13 THROW ; IMMEDIATE   \ undefined word\r
+\r
+\              $COLON  NameMinusDot,MinusDot\r
+\              DW      DoLIT,-13,THROW\r
+\r
+\   lastName   ( -- c-addr )\r
+\              Return the address of the last definition name.\r
+\r
+\              $VALUE  NameLastName,LastName,AddrLastName\r
+\r
+\   linkLast   ( -- )\r
+\              Link the word being defined to the current wordlist.\r
+\              Do nothing if the last definition is made by :NONAME .\r
+\r
+: linkLast     lastName  GET-CURRENT ! ;\r
+\r
+\                $COLON  NameLinkLast,LinkLast\r
+\                DW      LastName,GET_CURRENT,Store,EXIT\r
+\r
+\              $CODE   NameLinkLast,LinkLast\r
+\              MOV     AX,AddrLastName\r
+\              MOV     DI,AddrCurrent\r
+\              MOV     [DI],AX\r
+\              $NEXT\r
+\r
+\   name>xt    ( c-addr -- xt )\r
+\              Return execution token using counted string at c-addr.\r
+\r
+: name>xt              cell- cell- @ ;\r
+\r
+\                $COLON  NameNameToXT,NameToXT\r
+\                DW      CellMinus,CellMinus,Fetch,EXIT\r
+\r
+\              $CODE   NameNameToXT,NameToXT\r
+\              MOV     BX,[BX-2*CELLL]\r
+\              $NEXT\r
+\r
+\   pack"       ( c-addr u a-addr -- a-addr2 )\r
+\              Place a string c-addr u at a-addr and gives the next\r
+\              cell-aligned address. Fill the rest of the last cell with\r
+\              null character.\r
+\r
+: pack"                2DUP SWAP CHARS + CHAR+ DUP >R  \ ca u aa aa+u+1\r
+               ALIGNED cell- 0 SWAP !          \ fill 0 at the end of string\r
+               2DUP C! CHAR+ SWAP              \ c-addr a-addr+1 u\r
+               CHARS MOVE R> ALIGNED ; COMPILE-ONLY\r
+\r
+\                $COLON  5,'pack"',PackQuote,_SLINK\r
+\                DW      TwoDUP,SWAP,CHARS,Plus,CHARPlus,DUPP,ToR\r
+\                DW      ALIGNED,CellMinus,Zero,SWAP,Store\r
+\                DW      TwoDUP,CStore,CHARPlus,SWAP\r
+\                DW      CHARS,MOVE,RFrom,ALIGNED,EXIT\r
+\r
+\              $CODE   NamePackQuote,PackQuote\r
+\              MOV     DI,BX\r
+\              MOV     DX,SI\r
+\              MOV     AX,DS\r
+\              MOV     ES,AX\r
+\              POP     CX\r
+\              POP     SI\r
+\              MOV     BYTE PTR [DI],CL\r
+\              INC     DI\r
+\              REP MOVSB\r
+\              TEST    DI,1            ;odd address?\r
+\              JZ      PACKQ2\r
+\              MOV     BYTE PTR [DI],0\r
+\              INC     DI\r
+\ PACKQ2:      MOV     BX,DI\r
+\              MOV     SI,DX\r
+\              $NEXT\r
+\r
+\   PARSE-WORD ( "<spaces>ccc<space>" -- c-addr u )\r
+\              Skip leading spaces and parse a word. Return the name.\r
+\r
+: PARSE-WORD   BL skipPARSE ;\r
+\r
+\                $COLON  NamePARSE_WORD,PARSE_WORD\r
+\                DW      DoLIT,' ',SkipPARSE,EXIT\r
+\r
+\              $CODE   NamePARSE_WORD,PARSE_WORD\r
+\              PUSH    BX\r
+\              MOV     BX,' '\r
+\              JMP     SkipPARSE\r
+\              $ALIGN\r
+\r
+\   pipe       ( -- ) ( R: xt -- )\r
+\              Connect most recently defined word to code following DOES>.\r
+\              Structure of CREATEd word:\r
+\              |compile_xt|name_ptr| call-doCREATE | 0 or DOES>_xt | a-addr |\r
+\r
+: pipe         lastName name>xt ?call DUP IF   \ code-addr xt2\r
+                   ['] doCREATE = IF\r
+                   R> SWAP code!       \ change DOES> code of CREATEd word\r
+                   EXIT\r
+               THEN THEN\r
+               -32 THROW       \ invalid name argument, no-CREATEd last name\r
+               ; COMPILE-ONLY\r
+\r
+\              $COLON  NamePipe,Pipe\r
+\              DW      LastName,NameToXT,QCall,DUPP,ZBranch,PIPE1\r
+\              DW      DoLIT,DoCREATE,Equals,ZBranch,PIPE1\r
+\              DW      RFrom,SWAP,CodeStore,EXIT\r
+\ PIPE1                DW      DoLIT,-32,THROW\r
+\r
+\   skipPARSE  ( char "<chars>ccc<char>" -- c-addr u )\r
+\              Skip leading chars and parse a word using char as a\r
+\              delimeter. Return the name.\r
+\r
+: skipPARSE\r
+               >R SOURCE >IN @ /STRING    \ c_addr u  R: char\r
+               DUP IF\r
+                  BEGIN  OVER C@ R@ =\r
+                  WHILE  1- SWAP CHAR+ SWAP DUP 0=\r
+                  UNTIL  R> DROP EXIT\r
+                  ELSE THEN\r
+                  DROP SOURCE DROP - 1chars/ >IN ! R> PARSE EXIT\r
+               THEN R> DROP ;\r
+\r
+\                $COLON  NameSkipPARSE,SkipPARSE\r
+\                DW      ToR,SOURCE,DoLIT,AddrToIN,Fetch,SlashSTRING\r
+\                DW      DUPP,ZBranch,SKPAR1\r
+\ SKPAR2         DW      OVER,CFetch,RFetch,Equals,ZBranch,SKPAR3\r
+\                DW      OneMinus,SWAP,CHARPlus,SWAP\r
+\                DW      DUPP,ZeroEquals,ZBranch,SKPAR2\r
+\                DW      RFrom,DROP,EXIT\r
+\ SKPAR3         DW      DROP,SOURCE,DROP,Minus,OneCharsSlash\r
+\                DW      DoLIT,AddrToIN,Store,RFrom,PARSE,EXIT\r
+\ SKPAR1         DW      RFrom,DROP,EXIT\r
+\r
+\              $CODE   NameSkipPARSE,SkipPARSE\r
+\              MOV     AH,BL\r
+\              MOV     DX,SI\r
+\              MOV     SI,AddrSourceVar+CELLL\r
+\              MOV     BX,AddrSourceVar\r
+\              MOV     CX,AddrToIN\r
+\              ADD     SI,CX\r
+\              SUB     BX,CX\r
+\              MOV     CX,SI\r
+\              OR      BX,BX\r
+\              JZ      PARSW1\r
+\ PARSW5:      LODSB\r
+\              CMP     AL,AH\r
+\              JNE     PARSW4\r
+\              DEC     BX\r
+\              OR      BX,BX\r
+\              JNZ     PARSW5\r
+\              MOV     AX,AddrSourceVar\r
+\              MOV     AddrToIN,AX\r
+\ PARSW1:      PUSH    SI\r
+\              MOV     SI,DX\r
+\              $NEXT\r
+\ PARSW4:      DEC     SI\r
+\              SUB     SI,AddrSourceVar+CELLL\r
+\              MOV     AddrToIN,SI\r
+\              XOR     BX,BX\r
+\              MOV     BL,AH\r
+\              MOV     SI,DX\r
+\              JMP     PARSE\r
+\              $ALIGN\r
+\r
+\   specialComp? ( -- xt|0 )\r
+\              Return xt for special compilation semantics of the last found\r
+\              word. Return 0 if there is no special compilation action.\r
+\r
+\              $VALUE  NameSpecialCompQ,SpecialCompQ,AddrSpecialCompQ\r
+\r
+\   rake       ( C: do-sys -- )\r
+\              Gathers LEAVEs.\r
+\r
+: rake         DUP code, rakeVar @\r
+               BEGIN  2DUP U<\r
+               WHILE  DUP code@ xhere ROT code!\r
+               REPEAT rakeVar ! DROP\r
+               ?DUP IF                 \ check for ?DO\r
+                  1 bal+ POSTPONE THEN \ orig type is 1\r
+               THEN bal- ; COMPILE-ONLY\r
+\r
+\              $COLON  Namerake,rake\r
+\              DW      DUPP,CodeComma,DoLIT,AddrRakeVar,Fetch\r
+\ RAKE1                DW      TwoDUP,ULess,ZBranch,RAKE2\r
+\              DW      DUPP,CodeFetch,XHere,ROT,CodeStore,Branch,RAKE1\r
+\ RAKE2                DW      DoLIT,AddrRakeVar,Store,DROP\r
+\              DW      QuestionDUP,ZBranch,RAKE3\r
+\              DW      One,BalPlus,THENN\r
+\ RAKE3                DW      BalMinus,EXIT\r
+\r
+\   rp0        ( -- a-addr )\r
+\              Pointer to bottom of the return stack.\r
+\r
+: rp0          userP @ CELL+ CELL+ @ ;\r
+\r
+\              $COLON  NameRPZero,RPZero\r
+\              DW      DoLIT,AddrUserP,Fetch,CELLPlus,CELLPlus,Fetch,EXIT\r
+\r
+\   search-word ( c-addr u -- c-addr u 0 | xt f 1 | xt f -1)\r
+\              Search dictionary for a match with the given name. Return\r
+\              execution token, not-compile-only flag and -1 or 1\r
+\              ( IMMEDIATE) if found; c-addr u 0 if not.\r
+\r
+: search-word\r
+               #order @ DUP                    \ not found if #order is 0\r
+               IF 0\r
+                  DO 2DUP                      \ ca u ca u\r
+                     I CELLS #order CELL+ + @  \ ca u ca u wid\r
+                     (search-wordlist)         \ ca u; 0 | w f 1 | w f -1\r
+                     ?DUP IF                   \ ca u; 0 | w f 1 | w f -1\r
+                        >R 2SWAP 2DROP R> UNLOOP EXIT \ xt f 1 | xt f -1\r
+                     THEN                      \ ca u\r
+                  LOOP 0                       \ ca u 0\r
+               THEN ;\r
+\r
+\              $COLON  NameSearch_word,Search_word\r
+\              DW      NumberOrder,Fetch,DUPP,ZBranch,SEARCH1\r
+\              DW      DoLIT,0,DoDO\r
+\ SEARCH2      DW      TwoDUP,I,CELLS,NumberOrder,CELLPlus,Plus,Fetch\r
+\              DW      ParenSearch_Wordlist,QuestionDUP,ZBranch,SEARCH3\r
+\              DW      ToR,TwoSWAP,TwoDROP,RFrom,UNLOOP,EXIT\r
+\ SEARCH3      DW      DoLOOP,SEARCH2\r
+\              DW      DoLIT,0\r
+\ SEARCH1      DW      EXIT\r
+\r
+\   sourceVar  ( -- a-addr )\r
+\              Hold the current count and address of the terminal input buffer.\r
+\r
+\              $CONST  NameSourceVar,SourceVar,AddrSourceVar\r
+\r
+\   sp0        ( -- a-addr )\r
+\              Pointer to bottom of the data stack.\r
+\r
+: sp0          userP @ CELL+ @ ;\r
+\r
+\              $COLON  NameSPZero,SPZero\r
+\              DW      DoLIT,AddrUserP,Fetch,CELLPlus,Fetch,EXIT\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ Essential Standard words - Colon definitions\r
+\ ;;;;;;;;;;;;;;;\r
+\r
+\   #          ( ud1 -- ud2 )                  \ CORE\r
+\              Extract one digit from ud1 and append the digit to\r
+\              pictured numeric output string. ( ud2 = ud1 / BASE )\r
+\r
+: #            0 BASE @ UM/MOD >R BASE @ UM/MOD SWAP\r
+               9 OVER < [ CHAR A CHAR 9 1 + - ] LITERAL AND +\r
+               [ CHAR 0 ] LITERAL + HOLD R> ;\r
+\r
+\                $COLON  NameNumberSign,NumberSign\r
+\                DW      DoLIT,0,DoLITFetch,AddrBASE,UMSlashMOD,ToR\r
+\                DW      DoLITFetch,AddrBASE,UMSlashMOD,SWAP\r
+\                DW      DoLIT,9,OVER,LessThan,DoLIT,'A'-'9'-1,ANDD,Plus\r
+\                DW      DoLIT,'0',Plus,HOLD,RFrom,EXIT\r
+\r
+\              $CODE   NameNumberSign,NumberSign\r
+\              XOR     DX,DX\r
+\              MOV     AX,BX\r
+\              MOV     CX,AddrBASE\r
+\              DIV     CX              ;0:TOS / BASE\r
+\              MOV     BX,AX           ;quotient\r
+\              POP     AX\r
+\              DIV     CX\r
+\              PUSH    AX              ;BX:AX = ud2\r
+\              MOV     AL,DL\r
+\              CMP     AL,9\r
+\              JBE     NUMSN1\r
+\              ADD     AL,'A'-'9'-1\r
+\ NUMSN1:      ADD     AL,'0'\r
+\              MOV     DI,AddrHLD\r
+\              DEC     DI\r
+\              MOV     AddrHLD,DI\r
+\              MOV     [DI],AL\r
+\              $NEXT\r
+\r
+\   #>         ( xd -- c-addr u )              \ CORE\r
+\              Prepare the output string to be TYPE'd.\r
+\              ||HERE>WORD/#-work-area|\r
+\r
+: #>           2DROP hld @ HERE size-of-PAD + OVER - 1chars/ ;\r
+\r
+\              $COLON  NameNumberSignGreater,NumberSignGreater\r
+\              DW      TwoDROP,DoLIT,AddrHLD,Fetch,HERE,DoLIT,PADSize*CHARR,Plus\r
+\              DW      OVER,Minus,OneCharsSlash,EXIT\r
+\r
+\   #S         ( ud -- 0 0 )                   \ CORE\r
+\              Convert ud until all digits are added to the output string.\r
+\r
+: #S           BEGIN # 2DUP OR 0= UNTIL ;\r
+\r
+\              $COLON  NameNumberSignS,NumberSignS\r
+\ NUMSS1               DW      NumberSign,TwoDUP,ORR\r
+\              DW      ZeroEquals,ZBranch,NUMSS1\r
+\              DW      EXIT\r
+\r
+\   '           ( "<spaces>name" -- xt )        \ CORE\r
+\              Parse a name, find it and return xt.\r
+\r
+: '            (') DROP ;\r
+\r
+\              $COLON  NameTick,Tick\r
+\              DW      ParenTick,DROP,EXIT\r
+\r
+\   +          ( n1|u1 n2|u2 -- n3|u3 )        \ CORE\r
+\              Add top two items and gives the sum.\r
+\r
+: +            um+ DROP ;\r
+\r
+\                $COLON  NamePlus,Plus\r
+\                DW      UMPlus,DROP,EXIT\r
+\r
+\              $CODE   NamePlus,Plus\r
+\              POP     AX\r
+\              ADD     BX,AX\r
+\              $NEXT\r
+\r
+\   +!         ( n|u a-addr -- )               \ CORE\r
+\              Add n|u to the contents at a-addr.\r
+\r
+: +!           SWAP OVER @ + SWAP ! ;\r
+\r
+\                $COLON  NamePlusStore,PlusStore\r
+\                DW      SWAP,OVER,Fetch,Plus\r
+\                DW      SWAP,Store,EXIT\r
+\r
+\              $CODE   NamePlusStore,PlusStore\r
+\              POP     AX\r
+\              ADD     [BX],AX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   ,          ( x -- )                        \ CORE\r
+\              Reserve one cell in data space and store x in it.\r
+\r
+: ,            HERE !  HERE CELL+ TO HERE ;\r
+\r
+\                $COLON  NameComma,Comma\r
+\                DW      HERE,Store,HERE,CELLPlus,DoTO,AddrHERE,EXIT\r
+\r
+\              $CODE   NameComma,Comma\r
+\              MOV     DI,AddrHERE\r
+\              MOV     [DI],BX\r
+\              ADD     DI,CELLL\r
+\              MOV     AddrHERE,DI\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   -          ( n1|u1 n2|u2 -- n3|u3 )        \ CORE\r
+\              Subtract n2|u2 from n1|u1, giving the difference n3|u3.\r
+\r
+: -            NEGATE + ;\r
+\r
+\                $COLON  NameMinus,Minus\r
+\                DW      NEGATE,Plus,EXIT\r
+\\r
+\              $CODE   NameMinus,Minus\r
+\              POP     AX\r
+\              SUB     AX,BX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\r
+\   .          ( n -- )                        \ CORE\r
+\              Display a signed number followed by a space.\r
+\r
+: .            S>D D. ;\r
+\r
+\              $COLON  NameDot,Dot\r
+\              DW      SToD,DDot,EXIT\r
+\r
+\   /          ( n1 n2 -- n3 )                 \ CORE\r
+\              Divide n1 by n2, giving single-cell quotient n3.\r
+\r
+: /            /MOD NIP ;\r
+\r
+\              $COLON  NameSlash,Slash\r
+\              DW      SlashMOD,NIP,EXIT\r
+\r
+\   /MOD       ( n1 n2 -- n3 n4 )              \ CORE\r
+\              Divide n1 by n2, giving single-cell remainder n3 and\r
+\              single-cell quotient n4.\r
+\r
+: /MOD         >R S>D R> FM/MOD ;\r
+\r
+\                $COLON  NameSlashMOD,SlashMOD\r
+\                DW      ToR,SToD,RFrom,FMSlashMOD,EXIT\r
+\r
+\              $CODE   NameSlashMOD,SlashMOD\r
+\              POP     AX\r
+\              CWD\r
+\              PUSH    AX\r
+\              PUSH    DX\r
+\              JMP     FMSlashMOD\r
+\              $ALIGN\r
+\r
+\   /STRING    ( c-addr1 u1 n -- c-addr2 u2 )  \ STRING\r
+\              Adjust the char string at c-addr1 by n chars.\r
+\r
+: /STRING      DUP >R - SWAP R> CHARS + SWAP ;\r
+\r
+\                $COLON  NameSlashSTRING,SlashSTRING\r
+\                DW      DUPP,ToR,Minus,SWAP,RFrom,CHARS,Plus,SWAP,EXIT\r
+\r
+\              $CODE   NameSlashSTRING,SlashSTRING\r
+\              POP     AX\r
+\              SUB     AX,BX\r
+\              POP     DX\r
+\              ADD     DX,BX\r
+\              PUSH    DX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\r
+\   1+         ( n1|u1 -- n2|u2 )              \ CORE\r
+\              Increase top of the stack item by 1.\r
+\r
+: 1+           1 + ;\r
+\r
+\                $COLON  NameOnePlus,OnePlus\r
+\                DW      DoLIT,1,Plus,EXIT\r
+\r
+\              $CODE   NameOnePlus,OnePlus\r
+\              INC     BX\r
+\              $NEXT\r
+\r
+\   1-         ( n1|u1 -- n2|u2 )              \ CORE\r
+\              Decrease top of the stack item by 1.\r
+\r
+: 1-           -1 + ;\r
+\r
+\                $COLON  NameOneMinus,OneMinus\r
+\                DW      DoLIT,-1,Plus,EXIT\r
+\r
+\              $CODE   NameOneMinus,OneMinus\r
+\              DEC     BX\r
+\              $NEXT\r
+\r
+\   2!         ( x1 x2 a-addr -- )             \ CORE\r
+\              Store the cell pare x1 x2 at a-addr, with x2 at a-addr and\r
+\              x1 at the next consecutive cell.\r
+\r
+: 2!           SWAP OVER ! CELL+ ! ;\r
+\r
+\                $COLON  NameTwoStore,TwoStore\r
+\                DW      SWAP,OVER,Store,CELLPlus,Store,EXIT\r
+\\r
+\              $CODE   NameTwoStore,TwoStore\r
+\              POP     [BX]\r
+\              POP     [BX+CELLL]\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   2@         ( a-addr -- x1 x2 )             \ CORE\r
+\              Fetch the cell pair stored at a-addr. x2 is stored at a-addr\r
+\              and x1 at the next consecutive cell.\r
+\r
+: 2@           DUP CELL+ @ SWAP @ ;\r
+\r
+\                $COLON  NameTwoFetch,TwoFetch\r
+\                DW      DUPP,CELLPlus,Fetch,SWAP,Fetch,EXIT\r
+\r
+\              $CODE   NameTwoFetch,TwoFetch\r
+\              PUSH    [BX+CELLL]\r
+\              MOV     BX,[BX]\r
+\              $NEXT\r
+\r
+\   2DROP      ( x1 x2 -- )                    \ CORE\r
+\              Drop cell pair x1 x2 from the stack.\r
+\r
+: 2DROP                DROP DROP ;\r
+\r
+\                $COLON  NameTwoDROP,TwoDROP\r
+\                DW      DROP,DROP,EXIT\r
+\r
+\              $CODE   NameTwoDROP,TwoDROP\r
+\              POP     BX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   2DUP       ( x1 x2 -- x1 x2 x1 x2 )        \ CORE\r
+\              Duplicate cell pair x1 x2.\r
+\r
+: 2DUP         OVER OVER ;\r
+\r
+\                $COLON  NameTwoDUP,TwoDUP\r
+\                DW      OVER,OVER,EXIT\r
+\r
+\              $CODE   NameTwoDUP,TwoDUP\r
+\              MOV     DI,SP\r
+\              PUSH    BX\r
+\              PUSH    [DI]\r
+\              $NEXT\r
+\r
+\   2SWAP      ( x1 x2 x3 x4 -- x3 x4 x1 x2 )  \ CORE\r
+\              Exchange the top two cell pairs.\r
+\r
+: 2SWAP                ROT >R ROT R> ;\r
+\r
+\                $COLON  NameTwoSWAP,TwoSWAP\r
+\                DW      ROT,ToR,ROT,RFrom,EXIT\r
+\r
+\              $CODE   NameTwoSWAP,TwoSWAP\r
+\              POP     AX\r
+\              POP     CX\r
+\              POP     DX\r
+\              PUSH    AX\r
+\              PUSH    BX\r
+\              PUSH    DX\r
+\              MOV     BX,CX\r
+\              $NEXT\r
+\r
+\   :          ( "<spaces>name" -- colon-sys ) \ CORE\r
+\              Start a new colon definition using next word as its name.\r
+\r
+: :            xhere ALIGNED CELL+ TO xhere  \ reserve a cell for name pointer\r
+               :NONAME ROT head,  -1 TO notNONAME? ;\r
+\r
+\              $COLON  NameCOLON,COLON\r
+\              DW      XHere,ALIGNED,CELLPlus,DoTO,AddrXHere\r
+\              DW      ColonNONAME,ROT,HeadComma\r
+\              DW      DoLIT,-1,DoTO,AddrNotNONAMEQ,EXIT\r
+\r
+\   :NONAME    ( -- xt colon-sys )             \ CORE EXT\r
+\              Create an execution token xt, enter compilation state and\r
+\              start the current definition.\r
+\r
+: :NONAME      bal IF -29 THROW THEN           \ compiler nesting\r
+               ['] doLIST xt, DUP -1\r
+               0 TO notNONAME?  1 TO bal  ] ;\r
+\r
+\              $COLON  NameColonNONAME,ColonNONAME\r
+\              DW      Bal,ZBranch,NONAME1\r
+\              DW      DoLIT,-29,THROW\r
+\ NONAME1      DW      DoLIT,DoLIST,xtComma,DUPP,DoLIT,-1\r
+\              DW      DoLIT,0,DoTO,AddrNotNONAMEQ\r
+\              DW      One,DoTO,AddrBal,RightBracket,EXIT\r
+\r
+\   ;          ( colon-sys -- )                \ CORE\r
+\              Terminate a colon definition.\r
+\r
+: ;            bal 1- IF -22 THROW THEN        \ control structure mismatch\r
+               NIP 1+ IF -22 THROW THEN        \ colon-sys type is -1\r
+               notNONAME? IF   \ if the last definition is not created by ':'\r
+                 linkLast  0 TO notNONAME?     \ link the word to wordlist\r
+               THEN  POSTPONE EXIT     \ add EXIT at the end of the definition\r
+               0 TO bal  POSTPONE [ ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameSemicolon,Semicolon\r
+\              DW      Bal,OneMinus,ZBranch,SEMI1\r
+\              DW      DoLIT,-22,THROW\r
+\ SEMI1                DW      NIP,OnePlus,ZBranch,SEMI2\r
+\              DW      DoLIT,-22,THROW\r
+\ SEMI2                DW      NotNONAMEQ,ZBranch,SEMI3\r
+\              DW      LinkLast,DoLIT,0,DoTO,AddrNotNONAMEQ\r
+\ SEMI3                DW      DoLIT,EXIT,COMPILEComma\r
+\              DW      DoLIT,0,DoTO,AddrBal,LeftBracket,EXIT\r
+\r
+\   <          ( n1 n2 -- flag )               \ CORE\r
+\              Returns true if n1 is less than n2.\r
+\r
+: <            2DUP XOR 0<             \ same sign?\r
+               IF DROP 0< EXIT THEN    \ different signs, true if n1 <0\r
+               - 0< ;                  \ same signs, true if n1-n2 <0\r
+\r
+\                $COLON  NameLessThan,LessThan\r
+\                DW      TwoDUP,XORR,ZeroLess,ZBranch,LESS1\r
+\                DW      DROP,ZeroLess,EXIT\r
+\ LESS1          DW      Minus,ZeroLess,EXIT\r
+\r
+\              $CODE   NameLessThan,LessThan\r
+\              POP     AX\r
+\              SUB     AX,BX\r
+\              MOV     BX,-1\r
+\              JL      LESS1\r
+\              INC     BX\r
+\ LESS1:               $NEXT\r
+\r
+\   <#         ( -- )                          \ CORE\r
+\              Initiate the numeric output conversion process.\r
+\              ||HERE>WORD/#-work-area|\r
+\r
+: <#           HERE size-of-PAD + hld ! ;\r
+\r
+\              $COLON  NameLessNumberSign,LessNumberSign\r
+\              DW      HERE,DoLIT,PADSize*CHARR,Plus,DoLIT,AddrHLD,Store,EXIT\r
+\r
+\   =          ( x1 x2 -- flag )               \ CORE\r
+\              Return true if top two are equal.\r
+\r
+: =            XOR 0= ;\r
+\r
+\                $COLON  NameEquals,Equals\r
+\                DW      XORR,ZeroEquals,EXIT\r
+\r
+\              $CODE   NameEquals,Equals\r
+\              POP     AX\r
+\              CMP     BX,AX\r
+\              MOV     BX,-1\r
+\              JE      EQUAL1\r
+\              INC     BX\r
+\ EQUAL1:      $NEXT\r
+\r
+\   >          ( n1 n2 -- flag )               \ CORE\r
+\              Returns true if n1 is greater than n2.\r
+\r
+: >            SWAP < ;\r
+\r
+\                $COLON  NameGreaterThan,GreaterThan\r
+\                DW      SWAP,LessThan,EXIT\r
+\r
+\              $CODE   NameGreaterThan,GreaterThan\r
+\              POP     AX\r
+\              SUB     AX,BX\r
+\              MOV     BX,-1\r
+\              JG      GREAT1\r
+\              INC     BX\r
+\ GREAT1:      $NEXT\r
+\r
+\   >IN        ( -- a-addr )\r
+\              Hold the character pointer while parsing input stream.\r
+\r
+\              $CONST  NameToIN,ToIN,AddrToIN\r
+\r
+\   >NUMBER    ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 )    \ CORE\r
+\              Add number string's value to ud1. Leaves string of any\r
+\              unconverted chars.\r
+\r
+: >NUMBER      BEGIN  DUP\r
+               WHILE  >R  DUP >R C@                    \ ud char  R: u c-addr\r
+                      DUP [ CHAR 9 1+ ] LITERAL [CHAR] A WITHIN\r
+                          IF DROP R> R> EXIT THEN\r
+                      [ CHAR 0 ] LITERAL - 9 OVER <\r
+                      [ CHAR A CHAR 9 1 + - ] LITERAL AND -\r
+                      DUP 0 BASE @ WITHIN\r
+               WHILE  SWAP BASE @ UM* DROP ROT BASE @ UM* D+ R> R> 1 /STRING\r
+               REPEAT DROP R> R>\r
+               THEN ;\r
+\r
+\                $COLON  NameToNUMBER,ToNUMBER\r
+\ TONUM1         DW      DUPP,ZBranch,TONUM3\r
+\                DW      ToR,DUPP,ToR,CFetch,DUPP\r
+\                DW      DoLIT,'9'+1,DoLIT,'A',WITHIN,ZeroEquals,ZBranch,TONUM2\r
+\                DW      DoLIT,'0',Minus,DoLIT,9,OVER,LessThan\r
+\                DW      DoLIT,'A'-'9'-1,ANDD,Minus,DUPP\r
+\                DW      DoLIT,0,DoLIT,AddrBASE,Fetch,WITHIN,ZBranch,TONUM2\r
+\                DW      SWAP,DoLIT,AddrBASE,Fetch,UMStar,DROP,ROT,DoLIT,AddrBASE,Fetch\r
+\                DW      UMStar,DPlus,RFrom,RFrom,DoLIT,1,SlashSTRING\r
+\                DW      Branch,TONUM1\r
+\ TONUM2         DW      DROP,RFrom,RFrom\r
+\ TONUM3         DW      EXIT\r
+\r
+\              $CODE   NameToNUMBER,ToNUMBER\r
+\              POP     DI\r
+\ TONUM4:      OR      BX,BX\r
+\              JZ      TONUM2\r
+\              XOR     CX,CX\r
+\              MOV     CL,[DI]\r
+\              SUB     CX,'0'\r
+\              JS      TONUM2          ;not valid digit\r
+\              CMP     CX,'9'-'0'\r
+\              JLE     TONUM3\r
+\              CMP     CX,'A'-'0'\r
+\              JL      TONUM2          ;not valid digit\r
+\              SUB     CX,'A'-'9'-1\r
+\ TONUM3:      CMP     CX,AddrBASE\r
+\              JGE     TONUM2          ;not valid digit\r
+\              POP     AX\r
+\              MUL     AddrBASE\r
+\              POP     DX\r
+\              PUSH    AX\r
+\              MOV     AX,DX\r
+\              MUL     AddrBASE\r
+\              ADD     AX,CX\r
+\              POP     CX\r
+\              ADC     DX,CX\r
+\              PUSH    AX\r
+\              PUSH    DX\r
+\              INC     DI\r
+\              DEC     BX\r
+\              JMP     TONUM4\r
+\ TONUM2:      PUSH    DI\r
+\              $NEXT\r
+\r
+\   ?DUP       ( x -- x x | 0 )                \ CORE\r
+\              Duplicate top of the stack if it is not zero.\r
+\r
+: ?DUP         DUP IF DUP THEN ;\r
+\r
+\                $COLON  NameQuestionDUP,QuestionDUP\r
+\                DW      DUPP,ZBranch,QDUP1\r
+\                DW      DUPP\r
+\ QDUP1          DW      EXIT\r
+\r
+\              $CODE   NameQuestionDUP,QuestionDUP\r
+\              OR      BX,BX\r
+\              JZ      QDUP1\r
+\              PUSH    BX\r
+\ QDUP1:               $NEXT\r
+\r
+\   ABORT      ( i*x -- ) ( R: j*x -- )        \ EXCEPTION EXT\r
+\              Reset data stack and jump to QUIT.\r
+\r
+: ABORT                -1 THROW ;\r
+\r
+\              $COLON  NameABORT,ABORT\r
+\              DW      DoLIT,-1,THROW\r
+\r
+\   ACCEPT     ( c-addr +n1 -- +n2 )           \ CORE\r
+\              Accept a string of up to +n1 chars. Return with actual count.\r
+\              Implementation-defined editing. Stops at EOL# .\r
+\              Supports backspace and delete editing.\r
+\r
+: ACCEPT       >R 0\r
+               BEGIN  DUP R@ <                 \ ca n2 f  R: n1\r
+               WHILE  EKEY max-char AND\r
+                      DUP BL <\r
+                      IF   DUP  cr# = IF ROT 2DROP R> DROP EXIT THEN\r
+                           DUP  tab# =\r
+                           IF   DROP 2DUP + BL DUP EMIT SWAP C! 1+\r
+                           ELSE DUP  bsp# =\r
+                                SWAP del# = OR\r
+                                IF DROP DUP\r
+                                       \ discard the last char if not 1st char\r
+                                IF 1- bsp# EMIT BL EMIT bsp# EMIT THEN THEN\r
+                           THEN\r
+                      ELSE >R 2DUP CHARS + R> DUP EMIT SWAP C! 1+  \ Nick THEN\r
+                      THEN\r
+               REPEAT SWAP  R> 2DROP ;\r
+\r
+\              $COLON  NameACCEPT,ACCEPT\r
+\              DW      ToR,DoLIT,0\r
+\ ACCPT1               DW      DUPP,RFetch,LessThan,ZBranch,ACCPT5\r
+\              DW      EKEY,DoLIT,MaxChar,ANDD\r
+\              DW      DUPP,DoLIT,' ',LessThan,ZBranch,ACCPT3\r
+\              DW      DUPP,DoLIT,CRR,Equals,ZBranch,ACCPT4\r
+\              DW      ROT,TwoDROP,RFrom,DROP,EXIT\r
+\ ACCPT4               DW      DUPP,DoLIT,TABB,Equals,ZBranch,ACCPT6\r
+\              DW      DROP,TwoDUP,Plus,DoLIT,' ',DUPP,EMIT,SWAP,CStore,OnePlus\r
+\              DW      Branch,ACCPT1\r
+\ ACCPT6               DW      DUPP,DoLIT,BKSPP,Equals\r
+\              DW      SWAP,DoLIT,DEL,Equals,ORR,ZBranch,ACCPT1\r
+\              DW      DUPP,ZBranch,ACCPT1\r
+\              DW      OneMinus,DoLIT,BKSPP,EMIT,DoLIT,' ',EMIT,DoLIT,BKSPP,EMIT\r
+\              DW      Branch,ACCPT1\r
+\ ACCPT3               DW      ToR,TwoDUP,CHARS,Plus,RFrom,DUPP,EMIT,SWAP,CStore\r
+\              DW      OnePlus,Branch,ACCPT1\r
+\ ACCPT5               DW      SWAP,RFrom,TwoDROP,EXIT\r
+\r
+\   AGAIN      ( C: dest -- )                  \ CORE EXT\r
+\              Resolve backward reference dest. Typically used as\r
+\              BEGIN ... AGAIN . Move control to the location specified by\r
+\              dest on execution.\r
+\r
+: AGAIN                IF -22 THROW THEN  \ control structure mismatch; dest type is 0\r
+               POSTPONE branch code, bal- ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameAGAIN,AGAIN\r
+\              DW      ZBranch,AGAIN1\r
+\              DW      DoLIT,-22,THROW\r
+\ AGAIN1               DW      DoLIT,Branch,COMPILEComma,CodeComma,BalMinus,EXIT\r
+\r
+\   AHEAD      ( C: -- orig )                  \ TOOLS EXT\r
+\              Put the location of a new unresolved forward reference onto\r
+\              control-flow stack.\r
+\r
+: AHEAD                POSTPONE branch xhere 0 code,\r
+               1 bal+          \ orig type is 1\r
+               ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameAHEAD,AHEAD\r
+\              DW      DoLIT,Branch,COMPILEComma,XHere,DoLIT,0,CodeComma\r
+\              DW      One,BalPlus,EXIT\r
+\r
+\   BL         ( -- char )                     \ CORE\r
+\              Return the value of the blank character.\r
+\r
+: BL           blank-char-value EXIT ;\r
+\r
+\              $CONST NameBLank,BLank,' '\r
+\r
+\   CATCH      ( i*x xt -- j*x 0 | i*x n )     \ EXCEPTION\r
+\              Push an exception frame on the exception stack and then execute\r
+\              the execution token xt in such a way that control can be\r
+\              transferred to a point just after CATCH if THROW is executed\r
+\              during the execution of xt.\r
+\r
+: CATCH                sp@ >R throwFrame @ >R          \ save error frame\r
+               rp@ throwFrame !  EXECUTE       \ execute\r
+               R> throwFrame !                 \ restore error frame\r
+               R> DROP  0 ;                    \ no error\r
+\r
+\              $COLON  NameCATCH,CATCH\r
+\              DW      SPFetch,ToR,ThrowFrame,Fetch,ToR\r
+\              DW      RPFetch,ThrowFrame,Store,EXECUTE\r
+\              DW      RFrom,ThrowFrame,Store\r
+\              DW      RFrom,DROP,DoLIT,0,EXIT\r
+\r
+\   CELL+      ( a-addr1 -- a-addr2 )          \ CORE\r
+\              Return next aligned cell address.\r
+\r
+: CELL+                cell-size + ;\r
+\r
+\                $COLON  NameCELLPlus,CELLPlus\r
+\                DW      DoLIT,CELLL,Plus,EXIT\r
+\r
+\              $CODE   NameCELLPlus,CELLPlus\r
+\              ADD     BX,CELLL\r
+\              $NEXT\r
+\r
+\   CHAR+      ( c-addr1 -- c-addr2 )          \ CORE\r
+\              Returns next character-aligned address.\r
+\r
+: CHAR+                char-size + ;\r
+\r
+\                $COLON  NameCHARPlus,CHARPlus\r
+\                DW      DoLIT,CHARR,Plus,EXIT\r
+\r
+\              $CODE   NameCHARPlus,CHARPlus\r
+\              INC     BX\r
+\              $NEXT\r
+\r
+\   COMPILE,   ( xt -- )                       \ CORE EXT\r
+\              Compile the execution token on data stack into current\r
+\              colon definition.\r
+\              Structure of words with special compilation action\r
+\                  for default compilation behavior\r
+\              |compile_xt|name_ptr| execution_code |\r
+\r
+: COMPILE,     DUP specialComp? = IF DUP cell- cell- code@ EXECUTE EXIT THEN\r
+               code, ;\r
+\r
+\                $COLON  NameCOMPILEComma,COMPILEComma\r
+\                DW      DUPP,SpecialCompQ,Equals,ZBranch,COMPILEC1\r
+\                DW      DUPP,CellMinus,CellMinus,CodeFetch,EXECUTE,EXIT\r
+\ COMPILEC1      DW      CodeComma,EXIT\r
+\r
+\              $CODE   NameCOMPILEComma,COMPILEComma\r
+\              CMP     BX,AddrSpecialCompQ\r
+\              JE      COMPILEC1\r
+\              MOV     DI,AddrXHere\r
+\              MOV     CS:[DI],BX\r
+\              ADD     DI,CELLL\r
+\              POP     BX\r
+\              MOV     AddrXHere,DI\r
+\              $NEXT\r
+\ COMPILEC1:   MOV     AX,CS:[BX-2*CELLL]\r
+\              JMP     AX\r
+\              $ALIGN\r
+\r
+\   compileCONST ( xt -- )\r
+\              Compile a CONSTANT word of which xt is given.\r
+\              Structure of CONSTANT word:\r
+\              |compile_xt|name_ptr| call-doCONST | x |\r
+\r
+: compileCONST\r
+               CELL+ CELL+ code@ POSTPONE LITERAL ;\r
+\r
+\                $COLON  NameCompileCONST,CompileCONST\r
+\                DW      CELLPlus,CELLPlus,CodeFetch,LITERAL,EXIT\r
+\r
+\              $CODE   NameCompileCONST,CompileCONST\r
+\              MOV     CX,CS:[BX+2*CELLL]\r
+\              MOV     DI,AddrXHere\r
+\              MOV     AX,OFFSET DoLIT\r
+\              MOV     CS:[DI],AX\r
+\              MOV     CS:[DI+CELLL],CX\r
+\              ADD     DI,2*CELLL\r
+\              POP     BX\r
+\              MOV     AddrXHere,DI\r
+\              $NEXT\r
+\r
+\   CONSTANT   ( x "<spaces>name" -- )         \ CORE\r
+\              name Execution: ( -- x )\r
+\              Create a definition for name which pushes x on the stack on\r
+\              execution.\r
+\r
+: CONSTANT     bal IF -29 THROW THEN           \ compiler nesting\r
+               xhere ALIGNED TO xhere\r
+               ['] compileCONST code,\r
+               xhere CELL+ TO xhere\r
+               ['] doCONST xt, head,\r
+               code, linkLast\r
+               lastName [ =seman ] LITERAL OVER @ OR SWAP ! ;\r
+\r
+\              $COLON  NameCONSTANT,CONSTANT\r
+\              DW      Bal,ZBranch,CONST1\r
+\              DW      DoLIT,-29,THROW\r
+\ CONST1               DW      XHere,ALIGNED,DoTO,AddrXHere\r
+\              DW      DoLIT,CompileCONST,CodeComma\r
+\              DW      XHere,CELLPlus,DoTO,AddrXHere\r
+\              DW      DoLIT,DoCONST,xtComma,HeadComma\r
+\              DW      CodeComma,LinkLast\r
+\              DW      LastName,DoLIT,SEMAN,OVER,Fetch,ORR,SWAP,Store,EXIT\r
+\r
+\   COUNT      ( c-addr1 -- c-addr2 u )        \ CORE\r
+\              Convert counted string to string specification. c-addr2 is\r
+\              the next char-aligned address after c-addr1 and u is the\r
+\              contents at c-addr1.\r
+\r
+: COUNT                DUP CHAR+ SWAP C@ ;\r
+\r
+\                $COLON  NameCOUNT,COUNT\r
+\                DW      DUPP,CHARPlus,SWAP,CFetch,EXIT\r
+\r
+\              $CODE   NameCOUNT,COUNT\r
+\              MOV     AX,BX\r
+\              INC     AX\r
+\              MOV     BL,[BX]\r
+\              XOR     BH,BH\r
+\              PUSH    AX\r
+\              $NEXT\r
+\r
+\   compileCREATE ( xt -- )\r
+\              Compile a CREATEd word of which xt is given.\r
+\              Structure of CREATEd word:\r
+\              |compile_xt|name_ptr| call-doCREATE | 0 or DOES>_xt | a-addr |\r
+\r
+: compileCREATE\r
+               DUP CELL+ CELL+ code@           \ 0 or DOES>_xt\r
+               IF code, EXIT THEN\r
+               CELL+ CELL+ CELL+ code@ POSTPONE LITERAL ;\r
+\r
+\              $COLON  NameCompileCREATE,CompileCREATE\r
+\              DW      DUPP,CELLPlus,CELLPlus,CodeFetch,ZBranch,COMPCREAT1\r
+\              DW      CodeComma,EXIT\r
+\ COMPCREAT1   DW      CELLPlus,CELLPlus,CELLPlus,CodeFetch,LITERAL,EXIT\r
+\r
+\   CREATE     ( "<spaces>name" -- )           \ CORE\r
+\              name Execution: ( -- a-addr )\r
+\              Create a data object in RAM/ROM data space, which return\r
+\              data object address on execution\r
+\r
+: CREATE       bal IF -29 THROW THEN           \ compiler nesting\r
+               xhere ALIGNED TO xhere\r
+               ['] compileCREATE code,\r
+               xhere CELL+ TO xhere    \ reserve space for nfa\r
+               ['] doCREATE xt, head,\r
+               0 code,                 \ no DOES> code yet\r
+               ALIGN HERE code,        \ >BODY returns this address\r
+               linkLast                \ link CREATEd word to current wordlist\r
+               lastName [ =seman ] LITERAL OVER @ OR SWAP ! ;\r
+\r
+\              $COLON  NameCREATE,CREATE\r
+\              DW      Bal,ZBranch,CREAT1\r
+\              DW      DoLIT,-29,THROW\r
+\ CREAT1               DW      XHere,ALIGNED,DoTO,AddrXHere\r
+\              DW      DoLIT,CompileCREATE,CodeComma\r
+\              DW      XHere,CELLPlus,DoTO,AddrXHere\r
+\              DW      DoLIT,DoCREATE,xtComma,HeadComma,DoLIT,0,CodeComma\r
+\              DW      ALIGNN,HERE,CodeComma,LinkLast\r
+\              DW      LastName,DoLIT,SEMAN,OVER,Fetch,ORR,SWAP,Store,EXIT\r
+\r
+\   D+         ( d1|ud1 d2|ud2 -- d3|ud3 )     \ DOUBLE\r
+\              Add double-cell numbers.\r
+\r
+: D+           >R SWAP >R um+ R> R> + + ;\r
+\r
+\                $COLON  NameDPlus,DPlus\r
+\                DW      ToR,SWAP,ToR,UMPlus\r
+\                DW      RFrom,RFrom,Plus,Plus,EXIT\r
+\r
+\              $CODE   NameDPlus,DPlus\r
+\              POP     CX\r
+\              POP     DX\r
+\              POP     AX\r
+\              ADD     CX,AX\r
+\              ADC     BX,DX\r
+\              PUSH    CX\r
+\              $NEXT\r
+\r
+\   D.         ( d -- )                        \ DOUBLE\r
+\              Display d in free field format followed by a space.\r
+\r
+: D.           (d.) TYPE SPACE ;\r
+\r
+\              $COLON  NameDDot,DDot\r
+\              DW      ParenDDot,TYPEE,SPACE,EXIT\r
+\r
+\   DECIMAL    ( -- )                          \ CORE\r
+\              Set the numeric conversion radix to decimal 10.\r
+\r
+: DECIMAL      10 BASE ! ;\r
+\r
+\              $COLON  NameDECIMAL,DECIMAL\r
+\              DW      DoLIT,10,DoLIT,AddrBASE,Store,EXIT\r
+\r
+\   DEPTH      ( -- +n )                       \ CORE\r
+\              Return the depth of the data stack.\r
+\r
+: DEPTH                sp@ sp0 SWAP - cell-size / ;\r
+\r
+\                $COLON  NameDEPTH,DEPTH\r
+\                DW      SPFetch,SPZero,SWAP,Minus\r
+\                DW      DoLIT,CELLL,Slash,EXIT\r
+\r
+\              $CODE   NameDEPTH,DEPTH\r
+\              PUSH    BX\r
+\              MOV     BX,AddrUserP\r
+\              MOV     BX,[BX+CELLL]\r
+\              SUB     BX,SP\r
+\              SAR     BX,1\r
+\              $NEXT\r
+\r
+\   DNEGATE    ( d1 -- d2 )                    \ DOUBLE\r
+\              Two's complement of double-cell number.\r
+\r
+: DNEGATE      INVERT >R INVERT 1 um+ R> + ;\r
+\r
+\                $COLON  NameDNEGATE,DNEGATE\r
+\                DW      INVERT,ToR,INVERT\r
+\                DW      DoLIT,1,UMPlus\r
+\                DW      RFrom,Plus,EXIT\r
+\r
+\              $CODE   NameDNEGATE,DNEGATE\r
+\              POP     AX\r
+\              NEG     AX\r
+\              PUSH    AX\r
+\              ADC     BX,0\r
+\              NEG     BX\r
+\              $NEXT\r
+\r
+\   EKEY       ( -- u )                        \ FACILITY EXT\r
+\              Receive one keyboard event u.\r
+\r
+: EKEY         BEGIN PAUSE EKEY? UNTIL 'ekey EXECUTE ;\r
+\r
+\              $COLON  NameEKEY,EKEY\r
+\ EKEY1                DW      PAUSE,EKEYQuestion,ZBranch,EKEY1\r
+\              DW      TickEKEY,EXECUTE,EXIT\r
+\r
+\   EMIT       ( x -- )                        \ CORE\r
+\              Send a character to the output device.\r
+\r
+: EMIT         'emit EXECUTE ;\r
+\r
+\                $COLON  NameEMIT,EMIT\r
+\                DW      TickEMIT,EXECUTE,EXIT\r
+\r
+\              $CODE   NameEMIT,EMIT\r
+\              MOV     AX,AddrTickEMIT\r
+\              JMP     AX\r
+\              $ALIGN\r
+\r
+\   FM/MOD     ( d n1 -- n2 n3 )               \ CORE\r
+\              Signed floored divide of double by single. Return mod n2\r
+\              and quotient n3.\r
+\r
+: FM/MOD       DUP >R 2DUP XOR >R >R DUP 0< IF DNEGATE THEN\r
+               R@ ABS UM/MOD DUP 0<\r
+               IF DUP [ 16 BASE ! ] 8000 [ DECIMAL ] XOR IF -11 THROW THEN THEN \ result out of range\r
+               SWAP R> 0< IF NEGATE THEN\r
+               SWAP R> 0< IF NEGATE OVER IF R@ ROT - SWAP 1- THEN THEN\r
+               R> DROP ;\r
+\r
+\                $COLON  6,'FM/MOD',FMSlashMOD,_FLINK\r
+\                DW      DUPP,ToR,TwoDUP,XORR,ToR,ToR,DUPP,ZeroLess\r
+\                DW      ZBranch,FMMOD1\r
+\                DW      DNEGATE\r
+\ FMMOD1         DW      RFetch,ABSS,UMSlashMOD,DUPP,ZeroLess,ZBranch,FMMOD2\r
+\                DW      DUPP,DoLIT,08000h,XORR,ZBranch,FMMOD2\r
+\                DW      DoLIT,-11,THROW\r
+\ FMMOD2         DW      SWAP,RFrom,ZeroLess,ZBranch,FMMOD3\r
+\                DW      NEGATE\r
+\ FMMOD3         DW      SWAP,RFrom,ZeroLess,ZBranch,FMMOD4\r
+\                DW      NEGATE,OVER,ZBranch,FMMOD4\r
+\                DW      RFetch,ROT,Minus,SWAP,OneMinus\r
+\ FMMOD4         DW      RFrom,DROP,EXIT\r
+\r
+\              $CODE   NameFMSlashMOD,FMSlashMOD\r
+\              POP     DX\r
+\              POP     AX\r
+\              OR      DX,DX\r
+\              JS      FMMOD2\r
+\              OR      BX,BX\r
+\              JZ      FMMOD1\r
+\              JS      FMMOD3\r
+\              CMP     DX,BX\r
+\              JAE     FMMOD6\r
+\              DIV     BX              ;positive dividend, positive divisor\r
+\              CMP     AX,08000h\r
+\              JA      FMMOD6\r
+\              PUSH    DX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\ FMMOD3:      NEG     BX              ;positive dividend, negative divisor\r
+\              CMP     DX,BX\r
+\              JAE     FMMOD6\r
+\              DIV     BX\r
+\              CMP     AX,08000h\r
+\              JA      FMMOD6\r
+\              OR      DX,DX\r
+\              JZ      FMMOD7          ;modulo = 0\r
+\              SUB     DX,BX\r
+\              NOT     AX              ;AX=-AX-1\r
+\              PUSH    DX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\ FMMOD2:      NEG     AX              ;DNEGATE\r
+\              ADC     DX,0\r
+\              NEG     DX\r
+\              OR      BX,BX\r
+\              JZ      FMMOD1\r
+\              JS      FMMOD4\r
+\              CMP     DX,BX           ;negative dividend, positive divisor\r
+\              JAE     FMMOD6\r
+\              DIV     BX\r
+\              CMP     AX,08000h\r
+\              JA      FMMOD6\r
+\              OR      DX,DX\r
+\              JZ      FMMOD7\r
+\              SUB     BX,DX\r
+\              NOT     AX              ;AX=-AX-1\r
+\              PUSH    BX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\ FMMOD7:      NEG     AX\r
+\              PUSH    DX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\ FMMOD4:      NEG     BX              ;negative dividend, negative divisor\r
+\              CMP     DX,BX\r
+\              JAE     FMMOD6\r
+\              DIV     BX\r
+\              CMP     AX,08000h\r
+\              JA      FMMOD6\r
+\              NEG     DX\r
+\              MOV     BX,AX\r
+\              PUSH    DX\r
+\              $NEXT\r
+\ FMMOD6:      MOV     BX,-11          ;result out of range\r
+\              JMP     THROW\r
+\ FMMOD1:      MOV     BX,-10          ;divide by zero\r
+\              JMP     THROW\r
+\              $ALIGN\r
+\r
+\   GET-CURRENT   ( -- wid )                   \ SEARCH\r
+\              Return the indentifier of the compilation wordlist.\r
+\r
+: GET-CURRENT  current @ ;\r
+\r
+\              $COLON  NameGET_CURRENT,GET_CURRENT\r
+\              DW      DoLIT,AddrCurrent,Fetch,EXIT\r
+\r
+\   HOLD       ( char -- )                     \ CORE\r
+\              Add char to the beginning of pictured numeric output string.\r
+\r
+: HOLD         hld @  1 CHARS - DUP hld ! C! ;\r
+\r
+\                $COLON  NameHOLD,HOLD\r
+\                DW      DoLIT,AddrHLD,Fetch,DoLIT,0-CHARR,Plus\r
+\                DW      DUPP,DoLIT,AddrHLD,Store,CStore,EXIT\r
+\r
+\              $CODE   NameHOLD,HOLD\r
+\              MOV     DI,AddrHLD\r
+\              DEC     DI\r
+\              MOV     AddrHLD,DI\r
+\              MOV     [DI],BL\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   I          ( -- n|u ) ( R: loop-sys -- loop-sys )  \ CORE\r
+\              Push the innermost loop index.\r
+\r
+: I            rp@ [ 1 CELLS ] LITERAL + @\r
+               rp@ [ 2 CELLS ] LITERAL + @  +  ; COMPILE-ONLY\r
+\r
+\                $COLON  NameI,I\r
+\                DW      RPFetch,DoLIT,CELLL,Plus,Fetch\r
+\                DW      RPFetch,DoLIT,2*CELLL,Plus,Fetch,Plus,EXIT\r
+\r
+\              $CODE   NameI,I\r
+\              PUSH    BX\r
+\              MOV     BX,[BP]\r
+\              ADD     BX,[BP+2]\r
+\              $NEXT\r
+\r
+\   IF         Compilation: ( C: -- orig )             \ CORE\r
+\              Run-time: ( x -- )\r
+\              Put the location of a new unresolved forward reference orig\r
+\              onto the control flow stack. On execution jump to location\r
+\              specified by the resolution of orig if x is zero.\r
+\r
+: IF           POSTPONE 0branch xhere 0 code,\r
+               1 bal+ ;                \ orig type is 1\r
+\r
+\              $COLON  NameIFF,IFF\r
+\              DW      DoLIT,ZBranch,COMPILEComma,XHere,DoLIT,0,CodeComma\r
+\              DW      One,BalPlus,EXIT\r
+\r
+\   INVERT     ( x1 -- x2 )                    \ CORE\r
+\              Return one's complement of x1.\r
+\r
+: INVERT       -1 XOR ;\r
+\r
+\                $COLON  NameINVERT,INVERT\r
+\                DW      DoLIT,-1,XORR,EXIT\r
+\r
+\              $CODE   NameINVERT,INVERT\r
+\              NOT     BX\r
+\              $NEXT\r
+\r
+\   KEY        ( -- char )                     \ CORE\r
+\              Receive a character. Do not display char.\r
+\r
+: KEY          EKEY max-char AND ;\r
+\r
+\              $COLON  NameKEY,KEY\r
+\              DW      EKEY,DoLIT,MaxChar,ANDD,EXIT\r
+\r
+\   LITERAL    Compilation: ( x -- )           \ CORE\r
+\              Run-time: ( -- x )\r
+\              Append following run-time semantics. Put x on the stack on\r
+\              execution\r
+\r
+: LITERAL      POSTPONE doLIT code, ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameLITERAL,LITERAL\r
+\              DW      DoLIT,DoLIT,COMPILEComma,CodeComma,EXIT\r
+\r
+\   NEGATE     ( n1 -- n2 )                    \ CORE\r
+\              Return two's complement of n1.\r
+\r
+: NEGATE       INVERT 1+ ;\r
+\r
+\                $COLON  NameNEGATE,NEGATE\r
+\                DW      INVERT,OnePlus,EXIT\r
+\r
+\              $CODE   NameNEGATE,NEGATE\r
+\              NEG     BX\r
+\              $NEXT\r
+\r
+\   NIP        ( n1 n2 -- n2 )                 \ CORE EXT\r
+\              Discard the second stack item.\r
+\r
+: NIP          SWAP DROP ;\r
+\r
+\                $COLON  NameNIP,NIP\r
+\                DW      SWAP,DROP,EXIT\r
+\r
+\              $CODE   NameNIP,NIP\r
+\              POP     AX\r
+\              $NEXT\r
+\r
+\   PARSE      ( char "ccc<char>"-- c-addr u )         \ CORE EXT\r
+\              Scan input stream and return counted string delimited by char.\r
+\r
+: PARSE                >R  SOURCE >IN @ /STRING        \ c-addr u  R: char\r
+               DUP IF\r
+                  OVER CHARS + OVER       \ c-addr c-addr+u c-addr  R: char\r
+                  BEGIN  DUP C@ R@ XOR\r
+                  WHILE  CHAR+ 2DUP =\r
+                  UNTIL  DROP OVER - 1chars/ DUP\r
+                  ELSE   NIP  OVER - 1chars/ DUP CHAR+\r
+                  THEN   >IN +!\r
+               THEN   R> DROP EXIT ;\r
+\r
+\                $COLON  5,'PARSE',PARSE,_FLINK\r
+\                DW      ToR,SOURCE,DoLIT,AddrToIN,Fetch,SlashSTRING\r
+\                DW      DUPP,ZBranch,PARSE4\r
+\                DW      OVER,CHARS,Plus,OVER\r
+\ PARSE1         DW      DUPP,CFetch,RFetch,XORR,ZBranch,PARSE3\r
+\                DW      CHARPlus,TwoDUP,Equals,ZBranch,PARSE1\r
+\ PARSE2         DW      DROP,OVER,Minus,DUPP,OneCharsSlash,Branch,PARSE5\r
+\ PARSE3         DW      NIP,OVER,Minus,DUPP,OneCharsSlash,CHARPlus\r
+\ PARSE5         DW      DoLIT,AddrToIN,PlusStore\r
+\ PARSE4         DW      RFrom,DROP,EXIT\r
+\r
+\              $CODE   NamePARSE,PARSE\r
+\              MOV     AH,BL\r
+\              MOV     DX,SI\r
+\              MOV     SI,AddrSourceVar+CELLL\r
+\              MOV     BX,AddrSourceVar\r
+\              MOV     CX,AddrToIN\r
+\              ADD     SI,CX\r
+\              SUB     BX,CX\r
+\              MOV     CX,SI\r
+\              PUSH    SI\r
+\              OR      BX,BX\r
+\              JZ      PARSE1\r
+\ PARSE5:      LODSB\r
+\              CMP     AL,AH\r
+\              JE      PARSE4\r
+\              DEC     BX\r
+\              OR      BX,BX\r
+\              JNZ     PARSE5\r
+\              MOV     BX,SI\r
+\              SUB     SI,AddrSourceVar+CELLL\r
+\              SUB     BX,CX\r
+\              MOV     AddrToIN,SI\r
+\ PARSE1:      MOV     SI,DX\r
+\              $NEXT\r
+\ PARSE4:      MOV     BX,SI\r
+\              SUB     SI,AddrSourceVar+CELLL\r
+\              SUB     BX,CX\r
+\              DEC     BX\r
+\              MOV     AddrToIN,SI\r
+\              MOV     SI,DX\r
+\              $NEXT\r
+\r
+\   QUIT       ( -- ) ( R: i*x -- )            \ CORE\r
+\              Empty the return stack, store zero in SOURCE-ID, make the user\r
+\              input device the input source, and start text interpreter.\r
+\r
+: QUIT         BEGIN\r
+                 rp0 rp!  0 TO SOURCE-ID  0 TO bal  POSTPONE [\r
+                 BEGIN CR REFILL DROP SPACE    \ REFILL returns always true\r
+                       ['] interpret CATCH ?DUP 0=\r
+                 WHILE STATE @ 0= IF .prompt THEN\r
+                 REPEAT\r
+                 DUP -1 XOR IF                                 \ ABORT\r
+                 DUP -2 = IF SPACE abort"msg 2@ TYPE    ELSE   \ ABORT"\r
+                 SPACE errWord 2@ TYPE\r
+                 SPACE [CHAR] ? EMIT SPACE\r
+                 DUP -1 -58 WITHIN IF ." Exception # " . ELSE \ undefined exception\r
+                 CELLS THROWMsgTbl + @ COUNT TYPE       THEN THEN THEN\r
+                 sp0 sp!\r
+               AGAIN ;\r
+\r
+\              $COLON  NameQUIT,QUIT\r
+\ QUIT1                DW      RPZero,RPStore,DoLIT,0,DoTO,AddrSOURCE_ID\r
+\              DW      DoLIT,0,DoTO,AddrBal,LeftBracket\r
+\ QUIT2                DW      CR,REFILL,DROP,SPACE\r
+\              DW      DoLIT,Interpret,CATCH,QuestionDUP,ZeroEquals\r
+\              DW      ZBranch,QUIT3\r
+\              DW      DoLIT,AddrSTATE,Fetch,ZeroEquals,ZBranch,QUIT2\r
+\              DW      DotPrompt,Branch,QUIT2\r
+\ QUIT3                DW      DUPP,DoLIT,-1,XORR,ZBranch,QUIT5\r
+\              DW      DUPP,DoLIT,-2,Equals,ZBranch,QUIT4\r
+\              DW      SPACE,DoLIT,AddrAbortQMsg,TwoFetch,TYPEE,Branch,QUIT5\r
+\ QUIT4                DW      SPACE,DoLIT,AddrErrWord,TwoFetch,TYPEE\r
+\              DW      SPACE,DoLIT,'?',EMIT,SPACE\r
+\              DW      DUPP,DoLIT,-1,DoLIT,-58,WITHIN,ZBranch,QUIT7\r
+\              DW      DoLIT,QUITstr\r
+\              DW      COUNT,TYPEE,Dot,Branch,QUIT5\r
+\ QUIT7                DW      CELLS,DoLIT,AddrTHROWMsgTbl,Plus,Fetch,COUNT,TYPEE\r
+\ QUIT5                DW      SPZero,SPStore,Branch,QUIT1\r
+\r
+\   REFILL     ( -- flag )                     \ CORE EXT\r
+\              Attempt to fill the input buffer from the input source. Make\r
+\              the result the input buffer, set >IN to zero, and return true\r
+\              if successful. Return false if the input source is a string\r
+\              from EVALUATE.\r
+\r
+\ Nick, possible problem here\r
+\ : REFILL     SOURCE-ID IF 0 EXIT THEN\r
+\              memTop [ size-of-PAD CHARS ] LITERAL - DUP\r
+\              size-of-PAD ACCEPT sourceVar 2!\r
+\              0 >IN ! -1 ;\r
+\r
+\              $COLON  NameREFILL,REFILL\r
+\              DW      SOURCE_ID,ZBranch,REFIL1\r
+\              DW      DoLIT,0,EXIT\r
+\ REFIL1               DW      MemTop,DoLIT,0-PADSize*CHARR,Plus,DUPP\r
+\              DW      DoLIT,PADSize*CHARR,ACCEPT,DoLIT,AddrSourceVar,TwoStore\r
+\              DW      DoLIT,0,DoLIT,AddrToIN,Store,DoLIT,-1,EXIT\r
+\r
+\   ROT        ( x1 x2 x3 -- x2 x3 x1 )        \ CORE\r
+\              Rotate the top three data stack items.\r
+\r
+: ROT          >R SWAP R> SWAP ;\r
+\r
+\                $COLON  NameROT,ROT\r
+\                DW      ToR,SWAP,RFrom,SWAP,EXIT\r
+\r
+\               $CODE  NameROT,ROT\r
+\               POP    AX\r
+\               POP    CX\r
+\               PUSH   AX\r
+\               PUSH   BX\r
+\               MOV    BX,CX\r
+\               $NEXT\r
+\r
+\   S>D        ( n -- d )                      \ CORE\r
+\              Convert a single-cell number n to double-cell number.\r
+\r
+: S>D          DUP 0< ;\r
+\r
+\                $COLON  NameSToD,SToD\r
+\                DW      DUPP,ZeroLess,EXIT\r
+\r
+\              $CODE   NameSToD,SToD\r
+\              PUSH    BX\r
+\              MOV     AX,BX\r
+\              CWD\r
+\              MOV     BX,DX\r
+\              $NEXT\r
+\r
+\   SEARCH-WORDLIST    ( c-addr u wid -- 0 | xt 1 | xt -1)     \ SEARCH\r
+\              Search word list for a match with the given name.\r
+\              Return execution token and -1 or 1 ( IMMEDIATE) if found.\r
+\              Return 0 if not found.\r
+\r
+: SEARCH-WORDLIST\r
+               (search-wordlist) DUP IF NIP THEN ;\r
+\r
+\              $COLON  NameSEARCH_WORDLIST,SEARCH_WORDLIST\r
+\              DW      ParenSearch_Wordlist,DUPP,ZBranch,SRCHW1\r
+\              DW      NIP\r
+\ SRCHW1               DW      EXIT\r
+\r
+\   SIGN       ( n -- )                        \ CORE\r
+\              Add a minus sign to the numeric output string if n is negative.\r
+\r
+: SIGN         0< IF [CHAR] - HOLD THEN ;\r
+\r
+\                $COLON  NameSIGN,SIGN\r
+\                DW      ZeroLess,ZBranch,SIGN1\r
+\                DW      DoLIT,'-',HOLD\r
+\ SIGN1          DW      EXIT\r
+\r
+\              $CODE   NameSIGN,SIGN\r
+\              OR      BX,BX\r
+\              JNS     SIGN1\r
+\              MOV     AL,'-'\r
+\              MOV     DI,AddrHLD\r
+\              DEC     DI\r
+\              MOV     AddrHLD,DI\r
+\              MOV     [DI],AL\r
+\ SIGN1:               POP     BX\r
+\              $NEXT\r
+\r
+\   SOURCE     ( -- c-addr u )                 \ CORE\r
+\              Return input buffer string.\r
+\r
+: SOURCE               sourceVar 2@ ;\r
+\r
+\              $COLON  NameSOURCE,SOURCE\r
+\              DW      DoLIT,AddrSourceVar,TwoFetch,EXIT\r
+\r
+\   SPACE      ( -- )                          \ CORE\r
+\              Send the blank character to the output device.\r
+\r
+: SPACE                32 EMIT ;\r
+\r
+\                $COLON  NameSPACE,SPACE\r
+\                DW      DoLIT,' ',EMIT,EXIT\r
+\r
+\              $CODE   NameSPACE,SPACE\r
+\              PUSH    BX\r
+\              MOV     BX,' '\r
+\              MOV     AX,AddrTickEMIT\r
+\              JMP     AX\r
+\              $ALIGN\r
+\r
+\   STATE      ( -- a-addr )                   \ CORE\r
+\              Return the address of a cell containing compilation-state flag\r
+\              which is true in compilation state or false otherwise.\r
+\r
+\              $CONST  NameSTATE,STATE,AddrSTATE\r
+\r
+\   THEN       Compilation: ( C: orig -- )     \ CORE\r
+\              Run-time: ( -- )\r
+\              Resolve the forward reference orig.\r
+\r
+: THEN         1- IF -22 THROW THEN    \ control structure mismatch\r
+                                       \ orig type is 1\r
+               xhere SWAP code! bal- ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameTHENN,THENN\r
+\              DW      OneMinus,ZBranch,THEN1\r
+\              DW      DoLIT,-22,THROW\r
+\ THEN1                DW      XHere,SWAP,CodeStore,BalMinus,EXIT\r
+\r
+\   THROW      ( k*x n -- k*x | i*x n )        \ EXCEPTION\r
+\              If n is not zero, pop the topmost exception frame from the\r
+\              exception stack, along with everything on the return stack\r
+\              above the frame. Then restore the condition before CATCH and\r
+\              transfer control just after the CATCH that pushed that\r
+\              exception frame.\r
+\r
+: THROW                ?DUP\r
+               IF   throwFrame @ rp!   \ restore return stack\r
+                    R> throwFrame !    \ restore THROW frame\r
+                    R> SWAP >R sp!     \ restore data stack\r
+                    DROP R>\r
+                    'init-i/o EXECUTE\r
+               THEN ;\r
+\r
+\              $COLON  NameTHROW,THROW\r
+\              DW      QuestionDUP,ZBranch,THROW1\r
+\              DW      ThrowFrame,Fetch,RPStore,RFrom,ThrowFrame,Store\r
+\              DW      RFrom,SWAP,ToR,SPStore,DROP,RFrom\r
+\              DW      TickINIT_IO,EXECUTE\r
+\ THROW1               DW      EXIT\r
+\r
+\   TYPE       ( c-addr u -- )                 \ CORE\r
+\              Display the character string if u is greater than zero.\r
+\r
+: TYPE         ?DUP IF 0 DO DUP C@ EMIT CHAR+ LOOP THEN DROP ;\r
+\r
+\                $COLON  NameTYPEE,TYPEE\r
+\                DW      QuestionDUP,ZBranch,TYPE2\r
+\                DW      DoLIT,0,DoDO\r
+\ TYPE1          DW      DUPP,CFetch,EMIT,CHARPlus,DoLOOP,TYPE1\r
+\ TYPE2          DW      DROP,EXIT\r
+\r
+\              $CODE   NameTYPEE,TYPEE\r
+\              POP     DI\r
+\              OR      BX,BX\r
+\              JZ      TYPE2\r
+\              PUSH    SI\r
+\              SUB     BP,CELLL\r
+\              MOV     [BP],BX\r
+\              MOV     BX,DI\r
+\ TYPE4:               MOV     DI,BX\r
+\              XOR     BX,BX\r
+\              MOV     BL,[DI]\r
+\              INC     DI\r
+\              PUSH    DI\r
+\              MOV     SI,OFFSET TYPE3\r
+\              MOV     AX,AddrTickEMIT\r
+\              JMP     AX\r
+\ TYPE1:               DEC     WORD PTR [BP]\r
+\              JNZ     TYPE4\r
+\              POP     SI\r
+\              ADD     BP,CELLL\r
+\ TYPE2:               POP     BX\r
+\              $NEXT\r
+\ TYPE3                DW      TYPE1\r
+\r
+\   U<         ( u1 u2 -- flag )               \ CORE\r
+\              Unsigned compare of top two items. True if u1 < u2.\r
+\r
+: U<           2DUP XOR 0< IF NIP 0< EXIT THEN - 0< ;\r
+\r
+\                $COLON  NameULess,ULess\r
+\                DW      TwoDUP,XORR,ZeroLess\r
+\                DW      ZBranch,ULES1\r
+\                DW      NIP,ZeroLess,EXIT\r
+\ ULES1          DW      Minus,ZeroLess,EXIT\r
+\r
+\              $CODE   NameULess,ULess\r
+\              POP     AX\r
+\              SUB     AX,BX\r
+\              MOV     BX,-1\r
+\              JB      ULES1\r
+\              INC     BX\r
+\ ULES1:               $NEXT\r
+\r
+\   UM*        ( u1 u2 -- ud )                 \ CORE\r
+\              Unsigned multiply. Return double-cell product.\r
+\r
+: UM*          0 SWAP cell-size-in-bits 0 DO\r
+                  DUP um+ >R >R DUP um+ R> +\r
+                  R> IF >R OVER um+ R> + THEN     \ if carry\r
+               LOOP ROT DROP ;\r
+\r
+\                $COLON  NameUMStar,UMStar\r
+\                DW      DoLIT,0,SWAP,DoLIT,CELLL*8,DoLIT,0,DoDO\r
+\ UMST1          DW      DUPP,UMPlus,ToR,ToR\r
+\                DW      DUPP,UMPlus,RFrom,Plus,RFrom\r
+\                DW      ZBranch,UMST2\r
+\                DW      ToR,OVER,UMPlus,RFrom,Plus\r
+\ UMST2          DW      DoLOOP,UMST1\r
+\                DW      ROT,DROP,EXIT\r
+\r
+\              $CODE   NameUMStar,UMStar\r
+\              POP     AX\r
+\              MUL     BX\r
+\              PUSH    AX\r
+\              MOV     BX,DX\r
+\              $NEXT\r
+\r
+\   UM/MOD     ( ud u1 -- u2 u3 )              \ CORE\r
+\              Unsigned division of a double-cell number ud by a single-cell\r
+\              number u1. Return remainder u2 and quotient u3.\r
+\r
+: UM/MOD       DUP 0= IF -10 THROW THEN        \ divide by zero\r
+               2DUP U< IF\r
+                  NEGATE cell-size-in-bits 0\r
+                  DO   >R DUP um+ >R >R DUP um+ R> + DUP\r
+                       R> R@ SWAP >R um+ R> OR\r
+                       IF >R DROP 1+ R> THEN\r
+                       ELSE DROP THEN\r
+                       R>\r
+                  LOOP DROP SWAP EXIT\r
+               ELSE -11 THROW          \ result out of range\r
+               THEN ;\r
+\r
+\                $COLON  NameUMSlashMOD,UMSlashMOD\r
+\                DW      DUPP,ZBranch,UMM5\r
+\                DW      TwoDUP,ULess,ZBranch,UMM4\r
+\                DW      NEGATE,DoLIT,CELLL*8,DoLIT,0,DoDO\r
+\ UMM1           DW      ToR,DUPP,UMPlus,ToR,ToR,DUPP,UMPlus,RFrom,Plus,DUPP\r
+\                DW      RFrom,RFetch,SWAP,ToR,UMPlus,RFrom,ORR,ZBranch,UMM2\r
+\                DW      ToR,DROP,OnePlus,RFrom,Branch,UMM3\r
+\ UMM2           DW      DROP\r
+\ UMM3           DW      RFrom,DoLOOP,UMM1\r
+\                DW      DROP,SWAP,EXIT\r
+\ UMM5           DW      DoLIT,-10,THROW\r
+\ UMM4           DW      DoLIT,-11,THROW\r
+\r
+\              $CODE   NameUMSlashMOD,UMSlashMOD\r
+\              OR      BX,BX\r
+\              JZ      UMM1\r
+\              POP     DX\r
+\              CMP     DX,BX\r
+\              JAE     UMM2\r
+\              POP     AX\r
+\              DIV     BX\r
+\              PUSH    DX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\ UMM1:                MOV     BX,-10          ;divide by zero\r
+\              JMP     THROW\r
+\ UMM2:                MOV     BX,-11          ;result out of range\r
+\              JMP     THROW\r
+\              $ALIGN\r
+\r
+\   UNLOOP     ( -- ) ( R: loop-sys -- )       \ CORE\r
+\              Discard loop-control parameters for the current nesting level.\r
+\              An UNLOOP is required for each nesting level before the\r
+\              definition may be EXITed.\r
+\r
+: UNLOOP       R> R> R> 2DROP >R ;\r
+\r
+\                $COLON  NameUNLOOP,UNLOOP\r
+\                DW      RFrom,RFrom,RFrom,TwoDROP,ToR,EXIT\r
+\r
+\              $CODE   NameUNLOOP,UNLOOP\r
+\              ADD     BP,2*CELLL\r
+\              $NEXT\r
+\r
+\   WITHIN     ( n1|u1 n2|n2 n3|u3 -- flag )   \ CORE EXT\r
+\              Return true if (n2|u2<=n1|u1 and n1|u1<n3|u3) or\r
+\              (n2|u2>n3|u3 and (n2|u2<=n1|u1 or n1|u1<n3|u3)).\r
+\r
+: WITHIN       OVER - >R - R> U< ;\r
+\r
+\                $COLON  NameWITHIN,WITHIN\r
+\                DW      OVER,Minus,ToR                  ;ul <= u < uh\r
+\                DW      Minus,RFrom,ULess,EXIT\r
+\r
+\              $CODE   NameWITHIN,WITHIN\r
+\              POP     AX\r
+\              SUB     BX,AX\r
+\              POP     DX\r
+\              SUB     DX,AX\r
+\              CMP     DX,BX\r
+\              MOV     BX,-1\r
+\              JB      WITHIN1\r
+\              INC     BX\r
+\ WITHIN1:     $NEXT\r
+\r
+\   [          ( -- )                          \ CORE\r
+\              Enter interpretation state.\r
+\r
+: [            0 STATE ! ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameLeftBracket,LeftBracket\r
+\              DW      DoLIT,0,DoLIT,AddrSTATE,Store,EXIT\r
+\r
+\   ]          ( -- )                          \ CORE\r
+\              Enter compilation state.\r
+\r
+: ]            -1 STATE ! ;\r
+\r
+\              $COLON  NameRightBracket,RightBracket\r
+\              DW      DoLIT,-1,DoLIT,AddrSTATE,Store,EXIT\r
+\r
+\ ;;;;;;;;;;;;;;;\r
+\ Rest of CORE words and two facility words, EKEY? and EMIT?\r
+\ ;;;;;;;;;;;;;;;\r
+\      Following definitions can be removed from assembler source and\r
+\      can be colon-defined later.\r
+\r
+\   (          ( "ccc<)>" -- )                 \ CORE\r
+\              Ignore following string up to next ) . A comment.\r
+\r
+: (            [CHAR] ) PARSE 2DROP ;\r
+\r
+\              $COLON  NameParen,Paren\r
+\              DW      DoLIT,')',PARSE,TwoDROP,EXIT\r
+\r
+\   *          ( n1|u1 n2|u2 -- n3|u3 )        \ CORE\r
+\              Multiply n1|u1 by n2|u2 giving a single product.\r
+\r
+: *            UM* DROP ;\r
+\r
+\                $COLON  NameStar,Star\r
+\                DW      UMStar,DROP,EXIT\r
+\r
+\              $CODE   NameStar,Star\r
+\              POP     AX\r
+\              IMUL    BX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\r
+\   */         ( n1 n2 n3 -- n4 )              \ CORE\r
+\              Multiply n1 by n2 producing double-cell intermediate,\r
+\              then divide it by n3. Return single-cell quotient.\r
+\r
+: */           */MOD NIP ;\r
+\r
+\              $COLON  NameStarSlash,StarSlash\r
+\              DW      StarSlashMOD,NIP,EXIT\r
+\r
+\   */MOD      ( n1 n2 n3 -- n4 n5 )           \ CORE\r
+\              Multiply n1 by n2 producing double-cell intermediate,\r
+\              then divide it by n3. Return single-cell remainder and\r
+\              single-cell quotient.\r
+\r
+: */MOD                >R M* R> FM/MOD ;\r
+\r
+\                $COLON  NameStarSlashMOD,StarSlashMOD\r
+\                DW      ToR,MStar,RFrom,FMSlashMOD,EXIT\r
+\r
+\              $CODE   NameStarSlashMOD,StarSlashMOD\r
+\              POP     AX\r
+\              POP     CX\r
+\              IMUL    CX\r
+\              PUSH    AX\r
+\              PUSH    DX\r
+\              JMP     FMSlashMOD\r
+\              $ALIGN\r
+\r
+\   +LOOP      Compilation: ( C: do-sys -- )   \ CORE\r
+\              Run-time: ( n -- ) ( R: loop-sys1 -- | loop-sys2 )\r
+\              Terminate a DO-+LOOP structure. Resolve the destination of all\r
+\              unresolved occurences of LEAVE.\r
+\              On execution add n to the loop index. If loop index did not\r
+\              cross the boundary between loop_limit-1 and loop_limit,\r
+\              continue execution at the beginning of the loop. Otherwise,\r
+\              finish the loop.\r
+\r
+: +LOOP                POSTPONE do+LOOP  rake ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NamePlusLOOP,PlusLOOP\r
+\              DW      DoLIT,DoPLOOP,COMPILEComma,rake,EXIT\r
+\r
+\   ."          ( "ccc<">" -- )                 \ CORE\r
+\              Run-time ( -- )\r
+\              Compile an inline string literal to be typed out at run time.\r
+\r
+: ."           POSTPONE S" POSTPONE TYPE ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameDotQuote,DotQuote\r
+\              DW      SQuote,DoLIT,TYPEE,COMPILEComma,EXIT\r
+\r
+\   2OVER      ( x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2 )      \ CORE\r
+\              Copy cell pair x1 x2 to the top of the stack.\r
+\r
+: 2OVER                >R >R 2DUP R> R> 2SWAP ;\r
+\r
+\                $COLON  NameTwoOVER,TwoOVER\r
+\                DW      ToR,ToR,TwoDUP,RFrom,RFrom,TwoSWAP,EXIT\r
+\r
+\              $CODE   NameTwoOVER,TwoOVER\r
+\              MOV     DI,SP\r
+\              PUSH    BX\r
+\              PUSH    [DI+2*CELLL]\r
+\              MOV     BX,[DI+CELLL]\r
+\              $NEXT\r
+\r
+\   >BODY      ( xt -- a-addr )                \ CORE\r
+\              Push data field address of CREATEd word.\r
+\r
+: >BODY                ?call DUP IF                    \ code-addr xt2\r
+                   ['] doCREATE = IF           \ should be call-doCREATE\r
+                   CELL+ code@ EXIT\r
+               THEN THEN\r
+               -31 THROW ;             \ >BODY used on non-CREATEd definition\r
+\r
+\              $COLON  NameToBODY,ToBODY\r
+\              DW      QCall,DUPP,ZBranch,TBODY1\r
+\              DW      DoLIT,DoCREATE,Equals,ZBranch,TBODY1\r
+\              DW      CELLPlus,CodeFetch,EXIT\r
+\ TBODY1               DW      DoLIT,-31,THROW\r
+\r
+\   ABORT"      ( "ccc<">" -- )                 \ EXCEPTION EXT\r
+\              Run-time ( i*x x1 -- | i*x ) ( R: j*x -- | j*x )\r
+\              Conditional abort with an error message.\r
+\r
+: ABORT"       S" POSTPONE ROT\r
+               POSTPONE IF POSTPONE abort"msg POSTPONE 2!\r
+               -2 POSTPONE LITERAL POSTPONE THROW\r
+               POSTPONE ELSE POSTPONE 2DROP POSTPONE THEN\r
+               ;  COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameABORTQuote,ABORTQuote\r
+\              DW      SQuote,DoLIT,ROT,COMPILEComma\r
+\              DW      IFF,DoLIT,AbortQMsg,COMPILEComma ; IF is immediate\r
+\              DW      DoLIT,TwoStore,COMPILEComma\r
+\              DW      DoLIT,-2,LITERAL                 ; LITERAL is immediate\r
+\              DW      DoLIT,THROW,COMPILEComma\r
+\              DW      ELSEE,DoLIT,TwoDROP,COMPILEComma ; ELSE and THEN are\r
+\              DW      THENN,EXIT                       ; immediate\r
+\r
+\   ABS        ( n -- u )                      \ CORE\r
+\              Return the absolute value of n.\r
+\r
+: ABS          DUP 0< IF NEGATE THEN ;\r
+\r
+\                $COLON  NameABSS,ABSS\r
+\                DW      DUPP,ZeroLess,ZBranch,ABS1\r
+\                DW      NEGATE\r
+\ ABS1           DW      EXIT\r
+\r
+\              $CODE   NameABSS,ABSS\r
+\              OR      BX,BX\r
+\              JNS     ABS1\r
+\              NEG     BX\r
+\ ABS1:                $NEXT\r
+\r
+\   ALLOT      ( n -- )                        \ CORE\r
+\              Allocate n bytes in data space.\r
+\r
+: ALLOT                HERE + TO HERE ;\r
+\r
+\              $COLON  NameALLOT,ALLOT\r
+\              DW      HERE,Plus,DoTO,AddrHERE,EXIT\r
+\r
+\   BEGIN      ( C: -- dest )                  \ CORE\r
+\              Start an infinite or indefinite loop structure. Put the next\r
+\              location for a transfer of control, dest, onto the data\r
+\              control stack.\r
+\r
+: BEGIN                xhere 0 bal+            \ dest type is 0\r
+               ; COMPILE-ONLY IMMDEDIATE\r
+\r
+\              $COLON  NameBEGIN,BEGIN\r
+\              DW      XHere,DoLIT,0,BalPlus,EXIT\r
+\r
+\   C,         ( char -- )                     \ CORE\r
+\              Compile a character into data space.\r
+\r
+: C,           HERE C!  HERE CHAR+ TO HERE ;\r
+\r
+\                $COLON  NameCComma,CComma\r
+\                DW      HERE,CStore,HERE,CHARPlus,DoTO,AddrHERE,EXIT\r
+\r
+\              $CODE   NameCComma,CComma\r
+\              MOV     DI,AddrHERE\r
+\              MOV     [DI],BL\r
+\              INC     DI\r
+\              MOV     AddrHERE,DI\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   CHAR       ( "<spaces>ccc" -- char )       \ CORE\r
+\              Parse next word and return the value of first character.\r
+\r
+: CHAR         PARSE-WORD DROP C@ ;\r
+\r
+\              $COLON  NameCHAR,CHAR\r
+\              DW      PARSE_WORD,DROP,CFetch,EXIT\r
+\r
+\   DO         Compilation: ( C: -- do-sys )   \ CORE\r
+\              Run-time: ( n1|u1 n2|u2 -- ) ( R: -- loop-sys )\r
+\              Start a DO-LOOP structure in a colon definition. Place do-sys\r
+\              on control-flow stack, which will be resolved by LOOP or +LOOP.\r
+\r
+: DO           0 rakeVar !  0                  \ ?DO-orig is 0 for DO\r
+\              POSTPONE doDO xhere  bal+       \ DO-dest\r
+\r
+\              $COLON  NameDO,DO\r
+\              DW      DoLIT,0,RakeVar,Store,DoLIT,0\r
+\              DW      DoLIT,DoDO,COMPILEComma,XHere,BalPlus,EXIT\r
+\r
+\   DOES>      ( C: colon-sys1 -- colon-sys2 ) \ CORE\r
+\              Build run time code of the data object CREATEd.\r
+\r
+: DOES>                bal 1- IF -22 THROW THEN        \ control structure mismatch\r
+               NIP 1+ IF -22 THROW THEN        \ colon-sys type is -1\r
+               POSTPONE pipe ['] doLIST xt, -1 ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameDOESGreater,DOESGreater\r
+\              DW      Bal,OneMinus,ZBranch,DOES1\r
+\              DW      DoLIT,-22,THROW\r
+\ DOES1                DW      NIP,OnePlus,ZBranch,DOES2\r
+\              DW      DoLIT,-22,THROW\r
+\ DOES2                DW      DoLIT,Pipe,COMPILEComma\r
+\              DW      DoLIT,DoLIST,xtComma,DoLIT,-1,EXIT\r
+\r
+\   ELSE       Compilation: ( C: orig1 -- orig2 )      \ CORE\r
+\              Run-time: ( -- )\r
+\              Start the false clause in an IF-ELSE-THEN structure.\r
+\              Put the location of new unresolved forward reference orig2\r
+\              onto control-flow stack.\r
+\r
+: ELSE         POSTPONE AHEAD 2SWAP POSTPONE THEN ; COMPILE-ONLY IMMDEDIATE\r
+\r
+\              $COLON  NameELSEE,ELSEE\r
+\              DW      AHEAD,TwoSWAP,THENN,EXIT\r
+\r
+\   ENVIRONMENT?   ( c-addr u -- false | i*x true )    \ CORE\r
+\              Environment query.\r
+\r
+: ENVIRONMENT?\r
+               envQList SEARCH-WORDLIST\r
+               DUP >R IF EXECUTE THEN R> ;\r
+\r
+\              $COLON  NameENVIRONMENTQuery,ENVIRONMENTQuery\r
+\              DW      DoLIT,AddrEnvQList,SEARCH_WORDLIST\r
+\              DW      DUPP,ToR,ZBranch,ENVRN1\r
+\              DW      EXECUTE\r
+\ ENVRN1               DW      RFrom,EXIT\r
+\r
+\   EVALUATE   ( i*x c-addr u -- j*x )         \ CORE\r
+\              Evaluate the string. Save the input source specification.\r
+\              Store -1 in SOURCE-ID.\r
+\r
+: EVALUATE     SOURCE >R >R >IN @ >R  SOURCE-ID >R\r
+               -1 TO SOURCE-ID\r
+               sourceVar 2!  0 >IN !  interpret\r
+               R> TO SOURCE-ID\r
+               R> >IN ! R> R> sourceVar 2! ;\r
+\r
+\              $COLON  NameEVALUATE,EVALUATE\r
+\              DW      SOURCE,ToR,ToR,DoLIT,AddrToIN,Fetch,ToR,SOURCE_ID,ToR\r
+\              DW      DoLIT,-1,DoTO,AddrSOURCE_ID\r
+\              DW      DoLIT,AddrSourceVar,TwoStore,DoLIT,0,DoLIT,AddrToIN,Store,Interpret\r
+\              DW      RFrom,DoTO,AddrSOURCE_ID\r
+\              DW      RFrom,DoLIT,AddrToIN,Store,RFrom,RFrom,DoLIT,AddrSourceVar,TwoStore,EXIT\r
+\r
+\   FILL       ( c-addr u char -- )            \ CORE\r
+\              Store char in each of u consecutive characters of memory\r
+\              beginning at c-addr.\r
+\r
+: FILL         ROT ROT ?DUP IF 0 DO 2DUP C! CHAR+ LOOP THEN 2DROP ;\r
+\r
+\                $COLON  NameFILL,FILL\r
+\                DW      ROT,ROT,QuestionDUP,ZBranch,FILL2\r
+\                DW      DoLIT,0,DoDO\r
+\ FILL1          DW      TwoDUP,CStore,CHARPlus,DoLOOP,FILL1\r
+\ FILL2          DW      TwoDROP,EXIT\r
+\r
+\              $CODE   NameFILL,FILL\r
+\              POP     CX\r
+\              MOV     DX,SI\r
+\              POP     SI\r
+\              OR      CX,CX\r
+\              JZ      FILL1\r
+\              MOV     [SI],BL\r
+\              MOV     AX,DS\r
+\              MOV     ES,AX\r
+\              MOV     DI,SI\r
+\              DEC     CX\r
+\              INC     DI\r
+\              REP MOVSB\r
+\ FILL1:               MOV     SI,DX\r
+\              POP     BX\r
+\              $NEXT\r
+\r
+\   FIND       ( c-addr -- c-addr 0 | xt 1 | xt -1)     \ SEARCH\r
+\              Search dictionary for a match with the given counted name.\r
+\              Return execution token and -1 or 1 ( IMMEDIATE) if found;\r
+\              c-addr 0 if not found.\r
+\r
+: FIND         DUP COUNT search-word ?DUP IF NIP ROT DROP EXIT THEN\r
+               2DROP 0 ;\r
+\r
+\              $COLON  NameFIND,FIND\r
+\              DW      DUPP,COUNT,Search_word,QuestionDUP,ZBranch,FIND1\r
+\              DW      NIP,ROT,DROP,EXIT\r
+\ FIND1                DW      TwoDROP,DoLIT,0,EXIT\r
+\r
+\   IMMEDIATE  ( -- )                          \ CORE\r
+\              Make the most recent definition an immediate word.\r
+\r
+: IMMEDIATE    lastName [ =immed ] LITERAL OVER @ OR SWAP ! ;\r
+\r
+\              $COLON  NameIMMEDIATE,IMMEDIATE\r
+\              DW      LastName,DoLIT,IMMED,OVER,Fetch,ORR,SWAP,Store,EXIT\r
+\r
+\   J          ( -- n|u ) ( R: loop-sys -- loop-sys )  \ CORE\r
+\              Push the index of next outer loop.\r
+\r
+: J            rp@ [ 3 CELLS ] LITERAL + @\r
+               rp@ [ 4 CELLS ] LITERAL + @  +  ; COMPILE-ONLY\r
+\r
+\                $COLON  NameJ,J\r
+\                DW      RPFetch,DoLIT,3*CELLL,Plus,Fetch\r
+\                DW      RPFetch,DoLIT,4*CELLL,Plus,Fetch,Plus,EXIT\r
+\r
+\              $CODE   NameJ,J\r
+\              PUSH    BX\r
+\              MOV     BX,[BP+2*CELLL]\r
+\              ADD     BX,[BP+3*CELLL]\r
+\              $NEXT\r
+\r
+\   LEAVE      ( -- ) ( R: loop-sys -- )       \ CORE\r
+\              Terminate definite loop, DO|?DO  ... LOOP|+LOOP, immediately.\r
+\r
+: LEAVE                POSTPONE UNLOOP POSTPONE branch\r
+               xhere rakeVar DUP @ code, ! ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameLEAVEE,LEAVEE\r
+\              DW      DoLIT,UNLOOP,COMPILEComma,DoLIT,Branch,COMPILEComma\r
+\              DW      XHere,DoLIT,AddrRakeVar,DUPP,Fetch,CodeComma,Store,EXIT\r
+\r
+\   LOOP       Compilation: ( C: do-sys -- )   \ CORE\r
+\              Run-time: ( -- ) ( R: loop-sys1 -- loop-sys2 )\r
+\              Terminate a DO|?DO ... LOOP structure. Resolve the destination\r
+\              of all unresolved occurences of LEAVE.\r
+\r
+: LOOP         POSTPONE doLOOP  rake ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameLOOPP,LOOPP\r
+\              DW      DoLIT,DoLOOP,COMPILEComma,rake,EXIT\r
+\r
+\   LSHIFT     ( x1 u -- x2 )                  \ CORE\r
+\              Perform a logical left shift of u bit-places on x1, giving x2.\r
+\              Put 0 into the least significant bits vacated by the shift.\r
+\r
+: LSHIFT       ?DUP IF 0 DO 2* LOOP THEN ;\r
+\r
+\                $COLON  NameLSHIFT,LSHIFT\r
+\                DW      QuestionDUP,ZBranch,LSHIFT2\r
+\                DW      DoLIT,0,DoDO\r
+\ LSHIFT1        DW      TwoStar,DoLOOP,LSHIFT1\r
+\ LSHIFT2        DW      EXIT\r
+\r
+\              $CODE   NameLSHIFT,LSHIFT\r
+\              MOV     CX,BX\r
+\              POP     BX\r
+\              OR      CX,CX\r
+\              JZ      LSHIFT2\r
+\              SHL     BX,CL\r
+\ LSHIFT2:     $NEXT\r
+\r
+\   M*         ( n1 n2 -- d )                  \ CORE\r
+\              Signed multiply. Return double product.\r
+\r
+: M*           2DUP XOR 0< >R ABS SWAP ABS UM* R> IF DNEGATE THEN ;\r
+\r
+\                $COLON  NameMStar,MStar\r
+\                DW      TwoDUP,XORR,ZeroLess,ToR,ABSS,SWAP,ABSS\r
+\                DW      UMStar,RFrom,ZBranch,MSTAR1\r
+\                DW      DNEGATE\r
+\ MSTAR1         DW      EXIT\r
+\r
+\              $CODE   NameMStar,MStar\r
+\              POP     AX\r
+\              IMUL    BX\r
+\              PUSH    AX\r
+\              MOV     BX,DX\r
+\              $NEXT\r
+\r
+\   MAX        ( n1 n2 -- n3 )                 \ CORE\r
+\              Return the greater of two top stack items.\r
+\r
+: MAX          2DUP < IF SWAP THEN DROP ;\r
+\r
+\                $COLON  NameMAX,MAX\r
+\                DW      TwoDUP,LessThan,ZBranch,MAX1\r
+\                DW      SWAP\r
+\ MAX1           DW      DROP,EXIT\r
+\r
+\              $CODE   NameMAX,MAX\r
+\              POP     AX\r
+\              CMP     AX,BX\r
+\              JLE     MAX1\r
+\              MOV     BX,AX\r
+\ MAX1:                $NEXT\r
+\r
+\   MIN        ( n1 n2 -- n3 )                 \ CORE\r
+\              Return the smaller of top two stack items.\r
+\r
+: MIN          2DUP > IF SWAP THEN DROP ;\r
+\r
+\                $COLON  NameMIN,MIN\r
+\                DW      TwoDUP,GreaterThan,ZBranch,MIN1\r
+\                DW      SWAP\r
+\ MIN1           DW      DROP,EXIT\r
+\r
+\              $CODE   NameMIN,MIN\r
+\              POP     AX\r
+\              CMP     AX,BX\r
+\              JGE     MIN1\r
+\              MOV     BX,AX\r
+\ MIN1:                $NEXT\r
+\r
+\   MOD        ( n1 n2 -- n3 )                 \ CORE\r
+\              Divide n1 by n2, giving the single cell remainder n3.\r
+\              Returns modulo of floored division in this implementation.\r
+\r
+: MOD          /MOD DROP ;\r
+\r
+\              $COLON  NameMODD,MODD\r
+\              DW      SlashMOD,DROP,EXIT\r
+\r
+\   PICK       ( x_u ... x1 x0 u -- x_u ... x1 x0 x_u )        \ CORE EXT\r
+\              Remove u and copy the uth stack item to top of the stack. An\r
+\              ambiguous condition exists if there are less than u+2 items\r
+\              on the stack before PICK is executed.\r
+\r
+: PICK         DEPTH DUP 2 < IF -4 THROW THEN    \ stack underflow\r
+               2 - OVER U< IF -4 THROW THEN\r
+               1+ CELLS sp@ + @ ;\r
+\r
+\                $COLON  NamePICK,PICK\r
+\                DW      DEPTH,DUPP,DoLIT,2,LessThan,ZBranch,PICK1\r
+\                DW      DoLIT,-4,THROW\r
+\ PICK1          DW      DoLIT,2,Minus,OVER,ULess,ZBranch,PICK2\r
+\                DW      DoLIT,-4,THROW\r
+\ PICK2          DW      OnePlus,CELLS,SPFetch,Plus,Fetch,EXIT\r
+\r
+\              $CODE   NamePICK,PICK\r
+\              MOV     DI,AddrUserP\r
+\              MOV     DI,[DI+CELLL]   ; sp0\r
+\              SUB     DI,SP\r
+\              SAR     DI,1            ; depth-1 in DI\r
+\              DEC     DI\r
+\              JS      PICK1\r
+\              CMP     DI,BX\r
+\              JB      PICK1\r
+\              SHL     BX,1\r
+\              ADD     BX,SP\r
+\              MOV     BX,[BX]\r
+\              $NEXT\r
+\ PICK1:               MOV     BX,-4\r
+\              JMP     THROW\r
+\              $ALIGN\r
+\r
+\   POSTPONE   ( "<spaces>name" -- )           \ CORE\r
+\              Parse name and find it. Append compilation semantics of name\r
+\              to current definition.\r
+\              Structure of words with special compilation action\r
+\                  for default compilation behavior\r
+\              |compile_xt|name_ptr| call-doCREATE | 0 or DOES>_xt | a-addr |\r
+\r
+: POSTPONE     (') 0< IF\r
+                   specialComp? OVER = IF      \ special compilation action\r
+                       DUP POSTPONE LITERAL\r
+                       cell- cell- code@\r
+                       POSTPONE LITERAL\r
+                       POSTPONE EXECUTE EXIT  THEN\r
+                   POSTPONE LITERAL                    \ non-IMMEDIATE\r
+                   POSTPONE code, EXIT        THEN\r
+               code, ; COMPILE-ONLY IMMEDIATE          \ IMMEDIATE\r
+\r
+\              $COLON  NamePOSTPONE,POSTPONE\r
+\              DW      ParenTick,ZeroLess,ZBranch,POSTP1\r
+\              DW      SpecialCompQ,OVER,Equals,ZBranch,POSTP2\r
+\              DW      DUPP,LITERAL,CellMinus,CellMinus,CodeFetch\r
+\              DW      LITERAL,DoLIT,EXECUTE,CodeComma,EXIT\r
+\ POSTP2               DW      LITERAL,DoLIT,CodeComma\r
+\ POSTP1               DW      CodeComma,EXIT\r
+\r
+\   RECURSE    ( -- )                          \ CORE\r
+\              Append the execution semactics of the current definition to\r
+\              the current definition.\r
+\r
+: RECURSE      bal 1- 2* PICK 1+ IF -22 THROW THEN\r
+                       \ control structure mismatch; colon-sys type is -1\r
+               bal 1- 2* 1+ PICK       \ xt of current definition\r
+               COMPILE, ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameRECURSE,RECURSE\r
+\              DW      Bal,OneMinus,TwoStar,PICK,OnePlus,ZBranch,RECUR1\r
+\              DW      DoLIT,-22,THROW\r
+\ RECUR1               DW      Bal,OneMinus,TwoStar,OnePlus,PICK\r
+\              DW      COMPILEComma,EXIT\r
+\r
+\   REPEAT     ( C: orig dest -- )             \ CORE\r
+\              Terminate a BEGIN-WHILE-REPEAT indefinite loop. Resolve\r
+\              backward reference dest and forward reference orig.\r
+\r
+: REPEAT       AGAIN THEN ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameREPEAT,REPEATT\r
+\              DW      AGAIN,THENN,EXIT\r
+\r
+\   RSHIFT     ( x1 u -- x2 )                  \ CORE\r
+\              Perform a logical right shift of u bit-places on x1, giving x2.\r
+\              Put 0 into the most significant bits vacated by the shift.\r
+\r
+: RSHIFT       ?DUP IF\r
+                       0 SWAP  cell-size-in-bits SWAP -\r
+                       0 DO  2DUP D+  LOOP\r
+                       NIP\r
+               THEN ;\r
+\r
+\                $COLON  NameRSHIFT,RSHIFT\r
+\                DW      QuestionDUP,ZBranch,RSHIFT2\r
+\                DW      DoLIT,0,SWAP,DoLIT,CELLL*8,SWAP,Minus,DoLIT,0,DoDO\r
+\ RSHIFT1        DW      TwoDUP,DPlus,DoLOOP,RSHIFT1\r
+\                DW      NIP\r
+\ RSHIFT2        DW      EXIT\r
+\r
+\              $CODE   NameRSHIFT,RSHIFT\r
+\              MOV     CX,BX\r
+\              POP     BX\r
+\              OR      CX,CX\r
+\              JZ      RSHIFT2\r
+\              SHR     BX,CL\r
+\ LSHIFT2:     $NEXT\r
+\r
+\   SLITERAL   ( c-addr1 u -- )                \ STRING\r
+\              Run-time ( -- c-addr2 u )\r
+\              Compile a string literal. Return the string on execution.\r
+\r
+: SLITERAL     ALIGN HERE POSTPONE LITERAL DUP POSTPONE LITERAL\r
+               CHARS HERE  2DUP + ALIGNED TO HERE\r
+               SWAP MOVE ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameSLITERAL,SLITERAL\r
+\              DW      ALIGNN,HERE,LITERAL,DUPP,LITERAL\r
+\              DW      CHARS,HERE,TwoDUP,Plus,ALIGNED,DoTO,AddrHERE\r
+\              DW      SWAP,MOVE,EXIT\r
+\r
+\   S"          Compilation: ( "ccc<">" -- )    \ CORE\r
+\              Run-time: ( -- c-addr u )\r
+\              Parse ccc delimetered by " . Return the string specification\r
+\              c-addr u on execution.\r
+\r
+: S"           [CHAR] " PARSE POSTPONE SLITERAL ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameSQuote,SQuote\r
+\              DW      DoLIT,'"',PARSE,SLITERAL,EXIT\r
+\r
+\   SM/REM     ( d n1 -- n2 n3 )               \ CORE\r
+\              Symmetric divide of double by single. Return remainder n2\r
+\              and quotient n3.\r
+\r
+: SM/REM       OVER >R >R DUP 0< IF DNEGATE THEN\r
+               R@ ABS UM/MOD DUP 0<\r
+               IF DUP [ 16 BASE ! ] 8000 [ DECIMAL ] XOR IF -11 THROW THEN THEN \ result out of range\r
+               R> R@ XOR 0< IF NEGATE THEN\r
+               R> 0< IF SWAP NEGATE SWAP THEN ;\r
+\r
+\                $COLON  6,'SM/REM',SMSlashREM,_FLINK\r
+\                DW      OVER,ToR,ToR,DUPP,ZeroLess,ZBranch,SMREM1\r
+\                DW      DNEGATE\r
+\ SMREM1         DW      RFetch,ABSS,UMSlashMOD,DUPP,ZeroLess,ZBranch,SMREM4\r
+\                DW      DUPP,DoLIT,08000h,XORR,ZBranch,SMREM4\r
+\                DW      DoLIT,-11,THROW\r
+\ SMREM4         DW      RFrom,RFetch,XORR,ZeroLess,ZBranch,SMREM2\r
+\                DW      NEGATE\r
+\ SMREM2         DW      RFrom,ZeroLess,ZBranch,SMREM3\r
+\                DW      SWAP,NEGATE,SWAP\r
+\ SMREM3         DW      EXIT\r
+\r
+\              $CODE   NameSMSlashREM,SMSlashREM\r
+\              POP     DX\r
+\              POP     AX\r
+\              OR      DX,DX\r
+\              JS      SMREM2\r
+\              OR      BX,BX\r
+\              JZ      SMREM1\r
+\              JS      SMREM3\r
+\              CMP     DX,BX\r
+\              JAE     SMREM6\r
+\              DIV     BX              ;positive dividend, positive divisor\r
+\              CMP     AX,08000h\r
+\              JA      SMREM6\r
+\              PUSH    DX\r
+\              MOV     BX,AX\r
+\              $NEXT\r
+\ SMREM3:      NEG     BX              ;positive dividend, negative divisor\r
+\              CMP     DX,BX\r
+\              JAE     SMREM6\r
+\              DIV     BX\r
+\              CMP     AX,08000h\r
+\              JA      SMREM6\r
+\              MOV     BX,AX\r
+\              PUSH    DX\r
+\              NEG     BX\r
+\              $NEXT\r
+\ SMREM2:      NEG     AX              ;DNEGATE\r
+\              ADC     DX,0\r
+\              NEG     DX\r
+\              OR      BX,BX\r
+\              JZ      SMREM1\r
+\              JS      SMREM4\r
+\              CMP     DX,BX           ;negative dividend, positive divisor\r
+\              JAE     SMREM6\r
+\              DIV     BX\r
+\              CMP     AX,08000h\r
+\              JA      SMREM6\r
+\              NEG     DX\r
+\              MOV     BX,AX\r
+\              PUSH    DX\r
+\              NEG     BX\r
+\              $NEXT\r
+\ SMREM4:      NEG     BX              ;negative dividend, negative divisor\r
+\              CMP     DX,BX\r
+\              JAE     SMREM6\r
+\              DIV     BX\r
+\              CMP     AX,08000h\r
+\              JA      SMREM6\r
+\              NEG     DX\r
+\              MOV     BX,AX\r
+\              PUSH    DX\r
+\              $NEXT\r
+\ SMREM6:      MOV     BX,-11          ;result out of range\r
+\              JMP     THROW\r
+\ SMREM1:      MOV     BX,-10          ;divide by zero\r
+\              JMP     THROW\r
+\              $ALIGN\r
+\r
+\   SPACES     ( n -- )                        \ CORE\r
+\              Send n spaces to the output device if n is greater than zero.\r
+\r
+: SPACES       DUP 0 > IF 0 DO SPACE LOOP EXIT THEN  DROP;\r
+\r
+\                $COLON  6,'SPACES',SPACES,_FLINK\r
+\                DW      DUPP,Zero,GreaterThan,ZBranch,SPACES1\r
+\                DW      Zero,DoDO\r
+\ SPACES2        DW      SPACE,DoLOOP,SPACES2\r
+\                DW      EXIT\r
+\ SPACES1        DW      DROP,EXIT\r
+\r
+\              $CODE   NameSPACES,SPACES\r
+\              OR      BX,BX\r
+\              JLE     SPACES2\r
+\              PUSH    SI\r
+\              SUB     BP,CELLL\r
+\              MOV     [BP],BX\r
+\              MOV     BX,' '\r
+\ SPACES4:     PUSH    BX\r
+\              MOV     SI,OFFSET SPACES3\r
+\              MOV     AX,AddrTickEMIT\r
+\              JMP     AX\r
+\ SPACES1:     DEC     WORD PTR [BP]\r
+\              JNZ     SPACES4\r
+\              POP     SI\r
+\              ADD     BP,CELLL\r
+\ SPACES2:     POP     BX\r
+\              $NEXT\r
+\ SPACES3      DW      SPACES1\r
+\r
+\   TO         Interpretation: ( x "<spaces>name" -- ) \ CORE EXT\r
+\              Compilation:    ( "<spaces>name" -- )\r
+\              Run-time:       ( x -- )\r
+\              Store x in name.\r
+\r
+: TO           ' ?call ?DUP IF         \ should be CALL\r
+                 ['] doVALUE =         \ verify VALUE marker\r
+                 IF code@ STATE @\r
+                    IF POSTPONE doTO code, EXIT THEN\r
+                    ! EXIT\r
+                    THEN THEN\r
+               -32 THROW ; IMMEDIATE   \ invalid name argument (e.g. TO xxx)\r
+\r
+\              $COLON  NameTO,TO\r
+\              DW      Tick,QCall,QuestionDUP,ZBranch,TO1\r
+\              DW      DoLIT,DoVALUE,Equals,ZBranch,TO1\r
+\              DW      CodeFetch,DoLIT,AddrSTATE,Fetch,ZBranch,TO2\r
+\              DW      DoLIT,DoTO,COMPILEComma,CodeComma,EXIT\r
+\ TO2          DW      Store,EXIT\r
+\ TO1          DW      DoLIT,-32,THROW\r
+\r
+\   U.         ( u -- )                        \ CORE\r
+\              Display u in free field format followed by space.\r
+\r
+: U.           0 D. ;\r
+\r
+\              $COLON  NameUDot,UDot\r
+\              DW      DoLIT,0,DDot,EXIT\r
+\r
+\   UNTIL      ( C: dest -- )                  \ CORE\r
+\              Terminate a BEGIN-UNTIL indefinite loop structure.\r
+\r
+: UNTIL                IF -22 THROW THEN  \ control structure mismatch; dest type is 0\r
+               POSTPONE 0branch code, bal- ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameUNTIL,UNTIL\r
+\              DW      ZBranch,UNTIL1\r
+\              DW      DoLIT,-22,THROW\r
+\ UNTIL1               DW      DoLIT,ZBranch,COMPILEComma,CodeComma,BalMinus,EXIT\r
+\r
+\   VALUE      ( x "<spaces>name" -- )         \ CORE EXT\r
+\              name Execution: ( -- x )\r
+\              Create a value object with initial value x.\r
+\r
+: VALUE                bal IF -29 THROW THEN           \ compiler nesting\r
+               xhere ALIGNED CELL+ TO xhere\r
+               ['] doVALUE xt, head,\r
+               ALIGN HERE code,\r
+               , linkLast ; \ store x and link CREATEd word to current wordlist\r
+\r
+\              $COLON  NameVALUE,VALUE\r
+\              DW      Bal,ZBranch,VALUE1\r
+\              DW      DoLIT,-29,THROW\r
+\ VALUE1               DW      XHere,ALIGNED,CELLPlus,DoTO,AddrXHere\r
+\              DW      DoLIT,DoVALUE,xtComma,HeadComma\r
+\              DW      ALIGNN,HERE,CodeComma\r
+\              DW      Comma,LinkLast,EXIT\r
+\r
+\   VARIABLE   ( "<spaces>name" -- )           \ CORE\r
+\              name Execution: ( -- a-addr )\r
+\              Parse a name and create a variable with the name.\r
+\              Resolve one cell of data space at an aligned address.\r
+\              Return the address on execution.\r
+\r
+: VARIABLE     bal IF -29 THROW THEN           \ compiler nesting\r
+               xhere ALIGNED TO xhere\r
+               ['] compileCONST code,\r
+               xhere CELL+ TO xhere\r
+               ['] doCONST xt, head,\r
+               ALIGN HERE\r
+               1 CELLS ALLOT           \ allocate one cell in data space\r
+               code, linkLast\r
+               lastName [ =seman ] LITERAL OVER @ OR SWAP ! ;\r
+\r
+\              $COLON  NameVARIABLE,VARIABLE\r
+\              DW      Bal,ZBranch,VARIA1\r
+\              DW      DoLIT,-29,THROW\r
+\ VARIA1               DW      XHere,ALIGNED,DoTO,AddrXHere\r
+\              DW      DoLIT,CompileCONST,CodeComma\r
+\              DW      XHere,CELLPlus,DoTO,AddrXHere\r
+\              DW      DoLIT,DoCONST,xtComma,HeadComma\r
+\              DW      ALIGNN,HERE,DoLIT,1*CELLL,ALLOT\r
+\              DW      CodeComma,LinkLast\r
+\              DW      LastName,DoLIT,SEMAN,OVER,Fetch,ORR,SWAP,Store,EXIT\r
+\r
+\   WHILE      ( C: dest -- orig dest )        \ CORE\r
+\              Put the location of a new unresolved forward reference orig\r
+\              onto the control flow stack under the existing dest. Typically\r
+\              used in BEGIN ... WHILE ... REPEAT structure.\r
+\r
+: WHILE                POSTPONE IF 2SWAP ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameWHILE,WHILEE\r
+\              DW      IFF,TwoSWAP,EXIT\r
+\r
+\   WORD       ( char "<chars>ccc<char>" -- c-addr )   \ CORE\r
+\              Skip leading delimeters and parse a word. Return the address\r
+\              of a transient region containing the word as counted string.\r
+\r
+: WORD         skipPARSE HERE pack" DROP HERE ;\r
+\r
+\              $COLON  NameWORDD,WORDD\r
+\              DW      SkipPARSE,HERE,PackQuote,DROP,HERE,EXIT\r
+\r
+\   [']         Compilation: ( "<spaces>name" -- )      \ CORE\r
+\              Run-time: ( -- xt )\r
+\              Parse name. Return the execution token of name on execution.\r
+\r
+: [']          ' POSTPONE LITERAL ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameBracketTick,BracketTick\r
+\              DW      Tick,LITERAL,EXIT\r
+\r
+\   [CHAR]     Compilation: ( "<spaces>name" -- )      \ CORE\r
+\              Run-time: ( -- char )\r
+\              Parse name. Return the value of the first character of name\r
+\              on execution.\r
+\r
+: [CHAR]       CHAR POSTPONE LITERAL ; COMPILE-ONLY IMMEDIATE\r
+\r
+\              $COLON  NameBracketCHAR,BracketCHAR\r
+\              DW      CHAR,LITERAL,EXIT\r
+\r
+\   \          ( "ccc<eol>" -- )               \ CORE EXT\r
+\              Parse and discard the remainder of the parse area.\r
+\r
+: \            SOURCE >IN ! DROP ; IMMEDIATE\r
+\r
+\              $COLON  NameBackslash,Backslash\r
+\              DW      SOURCE,DoLIT,AddrToIN,Store,DROP,EXIT\r
+\r
+\ Optional Facility words\r
+\r
+\   EKEY?      ( -- flag )                     \ FACILITY EXT\r
+\              If a keyboard event is available, return true.\r
+\r
+: EKEY?                'ekey? EXECUTE ;\r
+\r
+\                $COLON  NameEKEYQuestion,EKEYQuestion\r
+\                DW      TickEKEYQ,EXECUTE,EXIT\r
+\r
+\              $CODE   NameEKEYQuestion,EKEYQuestion\r
+\              MOV     AX,AddrTickEKEYQ\r
+\              JMP     AX\r
+\              $ALIGN\r
+\r
+\   EMIT?      ( -- flag )                     \ FACILITY EXT\r
+\              flag is true if the user output device is ready to accept data\r
+\              and the execution of EMIT in place of EMIT? would not have\r
+\              suffered an indefinite delay. If device state is indeterminate,\r
+\              flag is true.\r
+\r
+: EMIT?                'emit? EXECUTE ;\r
+\r
+\                $COLON  NameEMITQuestion,EMITQuestion\r
+\                DW      TickEMITQ,EXECUTE,EXIT\r
+\r
+\              $CODE   NameEMITQuestion,EMITQuestion\r
+\              MOV     AX,AddrTickEMITQ\r
+\              JMP     AX\r
+\              $ALIGN\r
+\r
+\ Nick\r
+\ ' RX? TO 'ekey?\r
+\ ' RX@ TO 'ekey\r
+\ ' TX? TO 'emit?\r
+\ ' TX! TO 'emit\r
+' set-i/o TO 'init-i/o\r
+' .ok TO 'prompt\r
+' hi TO 'boot\r
+' optiCOMPILE, 'doWord !\r
+\ ' EXECUTE 'doWord 2 + !\r
+' doubleAlso, 'doWord 4 + !\r
+' doubleAlso 'doWord 6 + !\r
+\ ' EXECUTE 'doWord 8 + !\r
+\ ' EXECUTE 'doWord 10 + !\r
+\r
+<< CON\r
index fb7977a..5e1eb83 100644 (file)
@@ -1032,8 +1032,9 @@ RXFET1:   $NEXT
 \r
                $COLON  NameSet_IO,Set_IO\r
 ; Nick removed this, want to use ordinary DOS redirection instead\r
-;              DW      DoLIT,Set_IOstr         ;MS-DOS only\r
-;              DW      COUNT,STDIN             ;MS-DOS only\r
+               DW      DoLIT,Set_IOstr         ;MS-DOS only\r
+               DW      COUNT,STDIN             ;MS-DOS only\r
+; to here... now back in again\r
                DW      EXIT\r
 \r
 ;;;;;;;;;;;;;;;;\r