home *** CD-ROM | disk | FTP | other *** search
/ ProfitPress Mega CDROM2 …eeware (MSDOS)(1992)(Eng) / ProfitPress-MegaCDROM2.B6I / PROG / MISC / FPC355_5.ZIP / TCOM96.ZIP / TCOM96 / COMPILER / LIB96.SEQ < prev    next >
Encoding:
Text File  |  1990-10-16  |  61.7 KB  |  1,947 lines

  1. \ LIBRARY.SEQ           Target Library Source           by Tom Zimmer
  2.  
  3. \ Version for 80c196 by Mike Mayo
  4.  
  5. \ ***************************************************************************
  6. \ Target specific words used by the compiler to complete compilation of
  7. \ the the various types of library and target definitions.  These words
  8. \ will need to be re-written when a new traget is being written.
  9.  
  10. \ ***************************************************************************
  11. \                       Target Library words
  12. \ ***************************************************************************
  13.  
  14. >LIBRARY
  15.  
  16. TARGET DEFINITIONS
  17.  
  18. \ ***************************************************************************
  19. \ This macro puts a literal number on the data stack. The instructon
  20. \ sequence used is not optimal, but is likely to be optimized later by the
  21. \ automatic SAVE_BX optimizer.
  22.  
  23. MACRO (LIT)     ( n1 -- )       \ Special macro to compile an inline number
  24.                 SAVE_TTOS       \ to the stack.
  25.                 [FORTH]
  26.                 HERE-T IMM-HERE !
  27.                 [ASM96]
  28.                 LD TTOS #    swap A;
  29.         END-MACRO       NO-INTERPRET
  30.  
  31. ' (LIT) >EXECUTE IS COMP_SINGLE \ link into number compiler
  32.  
  33.  
  34. CODE EXEC:     ( n1 -- )       \ execute the n-th CALL following EXEC:
  35.                                 \ MUST be followed by CALL's, not MACROS
  36.                 LD      W0 TTOS
  37.                 SHL     W0 # 1
  38.                 ADD     W0 TTOS         \ n1 * 3
  39.                 ADD     W0 []+ SP       \ POP and add the return address
  40.                 INC     W0              \ W0 now points to the CALL address
  41.                 LOAD_TTOS
  42.                 LDB     W2 []+ W0
  43.                 LDB     W3 []+ W0
  44.                 ADD     W0 W2
  45.                 BR[]    W0      \ jump where the CALL instruction would go
  46.         END-CODE        NO-INTERPRET
  47.  
  48.  
  49. CODE BOUNDS    ( n1 n2 --- n3 n4 )  \ Calculate limits used in DO-loop
  50.                 LD      W0 [] PSP
  51.                 ADD     TTOS W0
  52.                 ST      TTOS [] PSP
  53.                 LD      TTOS W0
  54.                 RET
  55.         END-CODE        NO-INTERPRET
  56.  
  57. MACRO ?EXIT     ( f1 -- )       \ If boolean f1 is true, exit from definition.
  58.                 LD      W0 TTOS
  59.                 LD      TTOS []+ PSP
  60.                 OR      W0 W0
  61.                 [ASM96]
  62.             0<> IF      RET
  63.                 THEN            END-MACRO       NO-INTERPRET
  64.  
  65. MACRO EXIT      ( -- )          \ Terminate a high-level definition
  66.                 RET             END-MACRO       NO-INTERPRET
  67.  
  68.  
  69. MACRO BEGIN     ( -- )
  70.                 +BR# $:|        END-MACRO       NO-INTERPRET
  71.  
  72. MACRO AGAIN     ( -- )          \ an unconditional branch
  73.                 LJMP -BR# DUP $  01LAB
  74.                                 END-MACRO       NO-INTERPRET
  75.  
  76. MACRO IF        ( f -- )        \ branch if flag is zero
  77.                 LD      W0 TTOS
  78.                 LOAD_TTOS
  79.                 OR      W0 W0
  80.                 [ASM96]
  81.                 JNE here 5 +    A;      \ branch around JMP
  82.                 LJMP +BR# $     A;
  83.                 [FORTH]
  84.                 [ASM96]     END-MACRO       NO-INTERPRET
  85.  
  86. TARGET ' IF ALIAS WHILE     ( f1 -- )
  87.  
  88. MACRO ELSE      ( -- )
  89.                 LJMP +BR# $ A;
  90.                 BR#SWAP
  91.                 -BR# DUP $:| 01LAB A;
  92.                 END-MACRO       NO-INTERPRET
  93.  
  94. MACRO THEN      ( -- )          \ resolve branch
  95.                 -BR# DUP $:| 01LAB A;
  96.                 END-MACRO       NO-INTERPRET
  97.  
  98. ' THEN ALIAS ENDIF
  99.  
  100.  
  101. FORTH   >FORTH
  102.  
  103. MACRO REPEAT    ( -- )
  104.                 BR#SWAP
  105.                 LJMP -BR# DUP $   01LAB
  106.                      -BR# DUP $:| 01LAB
  107.                 END-MACRO                       NO-INTERPRET
  108.  
  109. MACRO UNTIL     ( f1 -- )
  110.                 LD      W0 TTOS
  111.                 LD      TTOS []+ PSP
  112.                 OR      W0 W0
  113.                 JNE here 5 +    A;      \ branch around JMP
  114.                 LJMP -BR# DUP $ 01LAB A;
  115.         END-MACRO       NO-INTERPRET
  116.  
  117. MACRO FOR       ( n1 -- )
  118.                 PUSH    TTOS
  119.                 LOAD_TTOS
  120.                 +BR# $:|
  121.         END-MACRO       NO-INTERPRET
  122.  
  123. MACRO NEXT      ( -- )
  124.                 POP     W0
  125.                 OR      W0 W0
  126.             0<> IF
  127.                         DEC W0
  128.                         PUSH W0
  129.                         LJMP -BR# DUP $  01LAB
  130.                 THEN            END-MACRO       NO-INTERPRET
  131.  
  132. MACRO UNDO      ( --- )
  133.                 ADD SP # 4     END-MACRO       NO-INTERPRET
  134.  
  135. MACRO DO        ( l i -- )
  136.                 [FORTH]
  137.                 ?DOING   OFF
  138.                 [ASM96]
  139.                 LD      W0 []+ PSP
  140.                 ADD     W0 # $8000
  141.                 PUSH    W0
  142.                 SUB     TTOS W0
  143.                 PUSH    TTOS
  144.                 LOAD_TTOS
  145.                 +BR# $:|
  146.         END-MACRO       NO-INTERPRET
  147.  
  148. MACRO (LOOP)    ( -- )
  149.                 LD      W0 [] SP
  150.                 INC     W0
  151.                 ST      W0 [] SP
  152.                 JV here 5 +             A;      \ branch around JMP
  153.                 LJMP -BR# DUP $ 01LAB   A;
  154.         END-MACRO       NO-INTERPRET
  155.  
  156. MACRO (+LOOP)   ( n -- )
  157.                 ADD     TTOS [] SP
  158.                 ST      TTOS [] SP
  159.                 LD      TTOS []+ PSP
  160.                 JV here 5 +             A;      \ branch around JMP
  161.                 JMP -BR# DUP $ 01LAB   A;
  162.         END-MACRO       NO-INTERPRET
  163.  
  164. MACRO DO?       ( -- )
  165.                 -BR# DUP $:| 01LAB
  166.                 [FORTH]
  167.                 ?DOING OFF      END-MACRO       NO-INTERPRET
  168.  
  169. MACRO LEAVE?    ( -- )
  170.                 20 DUP $:| 01LAB
  171.                 [FORTH]
  172.                 ?LEAVING DECR   END-MACRO       NO-INTERPRET
  173.  
  174. FORTH   >FORTH
  175.  
  176. : %LOOP         ( -- )
  177.                 ['] (LOOP) >EXECUTE EXECUTE
  178.                 [FORTH]
  179.                 ?LEAVING @
  180.                 IF      ['] LEAVE? >EXECUTE EXECUTE
  181.                 THEN
  182.                 [TARGET]
  183.                 ['] UNDO >EXECUTE EXECUTE
  184.                 [FORTH]
  185.                 ?DOING @
  186.                 IF      ['] DO? >EXECUTE EXECUTE
  187.                 THEN
  188.                 [TARGET]
  189.                 ;
  190.  
  191. FORTH
  192.  
  193. : LOOP          ( -- )
  194.                 [FORTH]
  195.                 ?LIB
  196.                 IF      COMPILE %LOOP
  197.                 ELSE    %LOOP
  198.                 THEN
  199.                 [TARGET]
  200.                 ; IMMEDIATE
  201.  
  202. FORTH
  203.  
  204. : %+LOOP        ( -- )
  205.                 ['] (+LOOP) >EXECUTE EXECUTE
  206.                 [FORTH]
  207.                 ?LEAVING @
  208.                 IF      ['] LEAVE? >EXECUTE EXECUTE
  209.                 THEN
  210.                 [TARGET]
  211.                 ['] UNDO >EXECUTE EXECUTE
  212.                 [FORTH]
  213.                 ?DOING @
  214.                 IF      ['] DO? >EXECUTE EXECUTE
  215.                 THEN
  216.                 [TARGET]
  217.                 ;
  218.  
  219. FORTH
  220.  
  221. : +LOOP         ( -- )
  222.                 [FORTH]
  223.                 ?LIB
  224.                 IF      COMPILE %+LOOP
  225.                 ELSE    %+LOOP
  226.                 THEN
  227.                 [TARGET]
  228.                 ; IMMEDIATE
  229.  
  230. TARGET  >LIBRARY
  231.  
  232. MACRO LEAVE     ( -- )
  233.                 [FORTH] ?LEAVING INCR [ASM96]
  234.                 LJMP 20 $         END-MACRO       NO-INTERPRET
  235.  
  236. MACRO ?LEAVE    ( f -- )
  237.                 [FORTH] ?LEAVING INCR [ASM96]
  238.                 LD      W0 TTOS
  239.                 LOAD_TTOS
  240.                 OR      W0 W0
  241.                 JE here 5 +             A;      \ branch around JMP
  242.                 JMP 20 $                A;
  243.         END-MACRO       NO-INTERPRET
  244.  
  245. MACRO I        ( -- n )
  246.                 SAVE_TTOS
  247.                 LD      TTOS [] SP
  248.                 ADD     TTOS [I] 2 SP
  249.         END-MACRO       NO-INTERPRET
  250.  
  251. MACRO J         ( -- n )
  252.                 SAVE_TTOS
  253.                 LD      TTOS [I] 4 SP
  254.                 ADD     TTOS [I] 6 SP
  255.         END-MACRO       NO-INTERPRET
  256.  
  257. MACRO K         ( -- n )
  258.                 SAVE_TTOS
  259.                 LD      TTOS [I] 8 SP
  260.                 ADD     TTOS [I] 10 SP
  261.         END-MACRO       NO-INTERPRET
  262.  
  263.  
  264.  
  265. MACRO @         ( addr -- n )
  266.                 ld      ttos [] ttos
  267.                 END-MACRO       EXECUTES> @
  268.  
  269. ' @ >EXECUTE IS COMP_FETCH              \ link into compiler
  270.  
  271. MACRO !         ( n addr -- )
  272.                 LD      W0 []+ PSP
  273.                 ST      W0 [] TTOS
  274.                 LOAD_TTOS
  275.                 END-MACRO       EXECUTES> !
  276.  
  277. ' ! >EXECUTE IS COMP_STORE      \ link to compiler
  278.  
  279. MACRO %SAVE>R   ( a1 -- )
  280.                 LD      W0 [] TTOS
  281.                 PUSH    W0
  282.                 LOAD_TTOS
  283.                 END-MACRO       NO-INTERPRET
  284.  
  285. ' %SAVE>R >EXECUTE IS COMP_SAVE
  286.  
  287.  
  288. MACRO C@        ( addr -- char )
  289.                 LDB     TTOS [] TTOS
  290.                 CLRB    TTOSH
  291.                 END-MACRO       EXECUTES> C@
  292.  
  293. MACRO C!        ( char addr -- )
  294.                 LD      W0 []+ PSP
  295.                 STB     W0 [] TTOS
  296.                 LOAD_TTOS
  297.                 END-MACRO       EXECUTES> C!
  298. comment:
  299.  
  300. ICODE CMOVE     (  from to count -- )
  301.                 MOV CX, BX
  302.                 LODSW           MOV DI, AX
  303.                 LODSW           MOV BX, SI      MOV SI, AX
  304.                 MOV DX, ES      MOV AX, DS      MOV ES, AX
  305.                 REPNZ           MOVSB
  306.                 MOV SI, BX      MOV ES, DX
  307.                 LOAD_TTOS
  308.                 RET             END-ICODE
  309.  
  310. ICODE CMOVE>    ( from to count -- )
  311.                 MOV CX, BX      DEC CX
  312.                 LODSW           MOV DI, AX
  313.                 LODSW           MOV BX, SI      MOV SI, AX
  314.                 ADD DI, CX      ADD IP, CX      INC CX
  315.                 MOV DX, ES      MOV AX, DS      MOV ES, AX
  316.                 STD
  317.                 REPNZ           MOVSB
  318.                 CLD
  319.                 MOV SI, BX      MOV ES, DX
  320.                 LOAD_TTOS
  321.                 RET             END-ICODE
  322.  
  323. ICODE COMP      ( addr1 addr2 len -- -1 | 0 | 1 )
  324.                 [ASM96]
  325.                 XCHG SI, SP
  326.                 MOV DX, SI      MOV CX, BX
  327.                 POP DI          POP SI
  328.           CX<>0 IF      PUSH ES
  329.                         MOV AX, DS
  330.                         MOV ES, AX
  331.                         REPZ CMPSB
  332.                     0<> IF
  333.                              0< IF      MOV CX, # -1
  334.                                 ELSE    MOV CX, # 1
  335.                                 THEN
  336.                         THEN
  337.                         POP ES
  338.                 THEN
  339.                 MOV SI, DX
  340.                 MOV BX, CX
  341.                 XCHG SI, SP
  342.                 RET             END-ICODE
  343.  
  344. ICODE CAPS-COMP ( addr1 addr2 len -- -1 | 0 | 1 )
  345.                 [ASM96]
  346.                 XCHG SI, SP
  347.                 MOV DX, SI      MOV CX, BX
  348.                 POP DI          POP SI
  349.                 BEGIN
  350.                     JCXZ  0 $
  351.                     MOV AH, 0 [SI]      INC SI
  352.                     MOV AL, 0 [DI]      INC DI
  353.                     OR AX, # $02020     CMP AH, AL
  354.                     JNE 1 $             DEC CX
  355.                 AGAIN
  356.         1 $: 0< IF
  357.                    MOV CX, # -1
  358.                 ELSE
  359.                    MOV CX, # 1
  360.                 THEN
  361.         0 $:    MOV SI, DX
  362.                 MOV BX, CX
  363.                 XCHG SI, SP
  364.                 RET             END-ICODE
  365.  
  366. ICODE PLACE     ( from cnt to -- )
  367.                 MOV DI, BX
  368.                 LODSW           MOV CX, AX
  369.                 LODSW           XCHG AX, SI
  370.                 MOV 0 [DI], CL
  371.                 INC DI
  372.                 CLD
  373.                 MOV DX, ES
  374.                 MOV BX, DS      MOV ES, BX
  375.                 REPNZ           MOVSB
  376.                 MOV SI, AX
  377.                 MOV ES, DX
  378.                 LOAD_TTOS
  379.                 RET             END-ICODE
  380.  
  381. ICODE +PLACE    ( from cnt to -- )      \ append text to counted string
  382.                 MOV DI, BX
  383.                 LODSW           MOV CX, AX
  384.                 LODSW
  385.                 PUSH ES
  386.                 XCHG AX, SI
  387.                 SUB DX, DX
  388.                 MOV DL, 0 [DI]          \ pick up current length
  389.                 ADD 0 [DI], CL          \ adj current length plus cnt
  390.                 INC DI                  \ step to text start
  391.                 ADD DI, DX              \ adjust to current text end
  392.                 CLD
  393.                 MOV BX, DS      MOV ES, BX
  394.                 REPNZ           MOVSB   \ append the text
  395.                 MOV SI, AX
  396.                 POP ES
  397.                 LOAD_TTOS
  398.                 RET             END-ICODE
  399.  
  400. MACRO TIB       ( -- a1 )       \ Terminal Input Buffer address above stack
  401.                 SAVE_BX
  402.                 MOV BX, 'TIB    END-MACRO       EXECUTES> TIB
  403.  
  404. MACRO DEPTH     ( -- n1 )
  405.                 SAVE_TTOS
  406.                 LD      TTOS PSP
  407.                 SUB     TTOS PSP0
  408.                 SHR     TTOS # 1
  409.                 END-MACRO       EXECUTES> DEPTH
  410. comment;
  411.  
  412. MACRO SP@       ( -- n )
  413.                 SAVE_TTOS
  414.                 LD      TTOS PSP
  415.                 END-MACRO       NO-INTERPRET
  416.  
  417. MACRO SP!       ( n -- )
  418.                 LD      PSP TTOS
  419.                 END-MACRO       NO-INTERPRET
  420.  
  421. MACRO RP@       ( -- addr )
  422.                 SAVE_TTOS
  423.                 LD      TTOS SP
  424.                 END-MACRO       NO-INTERPRET
  425.  
  426. MACRO RP!       ( n -- )
  427.                 LD      SP TTOS
  428.                 LOAD_TTOS         END-MACRO       NO-INTERPRET
  429.  
  430. MACRO DROP      ( n1 -- )
  431.                 LOAD_TTOS         END-MACRO       EXECUTES> DROP
  432.  
  433. MACRO DUP       ( n1 -- n1 n1 )
  434.                 SAVE_TTOS
  435.         END-MACRO       EXECUTES> DUP
  436.  
  437. MACRO SWAP      ( n1 n2 -- n2 n1 )
  438.                 LD      W0 [] PSP
  439.                 ST      TTOS [] PSP
  440.                 LD      TTOS W0
  441.         END-MACRO       EXECUTES> SWAP
  442.  
  443. MACRO OVER      ( n1 n2 -- n1 n2 n1 )
  444.                 SAVE_TTOS
  445.                 LD      TTOS [I] 2 PSP
  446.         END-MACRO       EXECUTES> OVER
  447.  
  448.  
  449. MACRO PLUCK     ( n1 n2 n3 --- n1 n2 n3 n1 )
  450.                 SAVE_TTOS
  451.                 LD      TTOS [I] 4 PSP
  452.         END-MACRO       NO-INTERPRET
  453.  
  454. CODE TUCK       ( n1 n2 -- n2 n1 n2 )
  455.                 LD      W0 [] PSP
  456.                 SUB     PSP # 2
  457.                 ST      W0 [] PSP
  458.                 ST      TTOS [I] 2 PSP
  459.                 RET             END-CODE        EXECUTES> TUCK
  460.  
  461. MACRO NIP       ( n1 n2 -- n2 )
  462.                 ADD     PSP # 2
  463.                 END-MACRO       EXECUTES> NIP
  464.  
  465. CODE ROT        ( n1 n2 n3 --- n2 n3 n1 )
  466.                 LD  W0 [I] 2 PSP  \ get n1
  467.                 LD  W2 [] PSP     \ get n2
  468.                 ST  TTOS [] PSP   \ store n3
  469.                 ST  W2 [I] 2 PSP  \ store n2
  470.                 LD  TTOS W0       \ store n1
  471.                 RET             END-CODE        EXECUTES> ROT
  472.  
  473. CODE -ROT       ( n1 n2 n3 --- n3 n1 n2 )
  474.                 LD  W0 [I] 2 PSP    \ get n1
  475.                 LD  W2 [] PSP       \ get n2
  476.                 ST  TTOS [I] 2 PSP  \ store n3
  477.                 ST  W0 [] PSP       \ store n1
  478.                 LD  TTOS W0         \ store n2
  479.                 RET             END-CODE        EXECUTES> -ROT
  480.  
  481. MACRO FLIP      ( n1 -- n2 )
  482.                 LD      W0 TTOS
  483.                 LDB     TTOS W1
  484.                 LDB     TTOSH W0
  485.                 END-MACRO       EXECUTES> FLIP
  486.  
  487. CODE SPLIT      ( n1 --- n2 n3 )
  488.                 LD      W0 TTOS
  489.                 CLR     TTOSH
  490.                 SAVE_TTOS
  491.                 LDB     TTOS W1
  492.                 RET             END-CODE        EXECUTES> SPLIT
  493.  
  494. MACRO ?DUP      ( n1 -- [n1] n1 )
  495.                 OR  TTOS TTOS
  496.                 [ASM96]
  497.             0<> IF      SAVE_TTOS
  498.                 THEN            END-MACRO       EXECUTES> ?DUP
  499.  
  500. MACRO R>        ( -- n )
  501.                 SAVE_TTOS
  502.                 POP TTOS        END-MACRO       NO-INTERPRET
  503.  
  504. IMACRO R>DROP   ( --- )
  505.                 ADD SP # 2      END-IMACRO
  506.  
  507. IMACRO DUP>R    ( n1 --- n1 )
  508.                 PUSH TTOS       END-IMACRO
  509.  
  510. IMACRO >R       ( n -- )
  511.                 PUSH TTOS
  512.                 LOAD_TTOS       END-IMACRO
  513.  
  514. IMACRO 2R>      ( -- n1 n2 )
  515.                 SAVE_TTOS
  516.                 POP TTOS
  517.                 SAVE_TTOS
  518.                 POP TTOS        END-IMACRO
  519.  
  520. IMACRO 2>R      ( n1 n2 -- )
  521.                 PUSH TTOS
  522.                 LOAD_TTOS
  523.                 PUSH TTOS
  524.                 LOAD_TTOS       END-IMACRO
  525.  
  526. IMACRO R@       ( -- n )
  527.                 SAVE_TTOS
  528.                 LD  TTOS [] SP  END-IMACRO
  529.  
  530. IMACRO 2R@      ( -- n1 n2 )
  531.                 SAVE_TTOS
  532.                 LD  TTOS [] SP
  533.                 SAVE_TTOS
  534.                 LD  TTOS [I] 2 SP       END-IMACRO
  535.  
  536. MACRO PICK      ( nm ... n2 n1 k -- nm ... n2 n1 nk )
  537.                 SHL  TTOS # 1
  538.                 ADD  TTOS PSP
  539.                 LD   TTOS [I] -2 TTOS
  540.                         END-MACRO       NO-INTERPRET
  541.  
  542. IMACRO RPICK    ( nm ... n2 n1 k -- nm ... n2 n1 nk )
  543.                 SHL  TTOS # 1
  544.                 ADD  TTOS SP
  545.                 LD   TTOS [I] -2 TTOS
  546.                         END-IMACRO
  547.  
  548. MACRO AND       ( n1 n2 -- n3 )
  549.                 AND     TTOS []+ PSP
  550.                 END-MACRO       EXECUTES> AND
  551.  
  552. MACRO OR        ( n1 n2 -- n3 )
  553.                 OR      TTOS []+ PSP
  554.                 END-MACRO       EXECUTES> OR
  555.  
  556. MACRO NOT       ( n -- n' )
  557.                 NOT     TTOS
  558.                 END-MACRO       EXECUTES> NOT
  559.  
  560. IMACRO CSET     ( b addr -- )
  561.                 LDB  W0 []+ PSP
  562.                 ORB  W0 [] TTOS
  563.                 STB  W0 [] TTOS
  564.                 LOAD_TTOS         END-IMACRO
  565.  
  566. IMACRO CRESET   ( b addr -- )
  567.                 LDB  W0 []+ PSP
  568.                 NOTB  W0
  569.                 ANDB  W0 [] TTOS
  570.                 STB  W0 [] TTOS
  571.                 LOAD_TTOS         END-IMACRO
  572.  
  573. IMACRO CTOGGLE  ( b addr -- )
  574.                 LDB     W0 [] TTOS
  575.                 XORB    W0 []+ PSP
  576.                 STB     W0 [] TTOS
  577.                 LOAD_TTOS         END-IMACRO
  578.  
  579. MACRO ON        ( addr -- )
  580.                 LD      W0 # $0FFFF
  581.                 ST      W0 [] TTOS
  582.                 LOAD_TTOS
  583.                 END-MACRO       NO-INTERPRET
  584.  
  585. ' ON  >EXECUTE IS COMP_ON         \ link to compiler
  586.  
  587. MACRO OFF       ( addr -- )
  588.                 ST      0 [] TTOS
  589.                 LOAD_TTOS
  590.                 END-MACRO       NO-INTERPRET
  591.  
  592. ' OFF >EXECUTE IS COMP_OFF        \ link to compiler
  593.  
  594. MACRO INCR      ( addr --- )
  595.                 LD      W0 [] TTOS
  596.                 INC     W0
  597.                 ST      W0 [] TTOS
  598.                 LOAD_TTOS
  599.                 END-MACRO       NO-INTERPRET
  600.  
  601. ' INCR >EXECUTE IS COMP_INCR       \ link to compiler
  602.  
  603. MACRO DECR      ( addr --- )
  604.                 LD      W0 [] TTOS
  605.                 DEC     W0
  606.                 ST      W0 [] TTOS
  607.                 LOAD_TTOS
  608.                 END-MACRO       NO-INTERPRET
  609.  
  610. ' DECR >EXECUTE IS COMP_DECR       \ link to compiler
  611.  
  612.  
  613. MACRO +         ( n1 n2 -- sum )
  614.                 ADD     TTOS []+ PSP
  615.                 END-MACRO       EXECUTES> +
  616.  
  617.  
  618. MACRO NEGATE    ( n -- n' )
  619.                 NEG TTOS        END-MACRO       EXECUTES> NEGATE
  620.  
  621. MACRO -         ( n1 n2 -- n1-n2 )
  622.                 SUB     TTOS []+ PSP
  623.                 NEG     TTOS
  624.                 END-MACRO       EXECUTES> -
  625.  
  626. MACRO ABS       ( n1 -- n2 )
  627.                 LDBSE   W0 TTOSH        \ get sign of TTOS in W1
  628.                 LDB     W0 W1           \ and W0
  629.                 XOR     TTOS  W0        \ complement TTOS if negative
  630.                 SUB     TTOS  W0        \ and add 1 if TTOS was negative
  631.                 END-MACRO       EXECUTES> ABS
  632.  
  633. comment:
  634.  
  635. ICODE D+!       ( d addr -- )
  636.                 XCHG SI, SP
  637.                 POP AX          POP DX
  638.                 ADD 2 [BX], DX
  639.                 ADC 0 [BX], AX
  640.                 POP BX
  641.                 XCHG SI, SP
  642.                 RET             END-ICODE
  643.  
  644. MACRO +!        ( n addr -- )
  645.                 [FORTH]
  646.                 IMM/ABS_OPT ?DUP
  647.                 IF      0<
  648.                         IF
  649.                                 [ASM96]
  650.                                 ADD ( xxxx ) BX
  651.                                 [FORTH]
  652.                         ELSE
  653.                                 [ASM96]
  654.                                 MOV DI, ( xxxx )
  655.                                 ADD 0 [DI], BX
  656.                                 [FORTH]
  657.                         THEN
  658.                 ELSE
  659.                         [ASM96]
  660.                         LODSW
  661.                         ADD 0 [BX], AX
  662.                         [FORTH]
  663.                 THEN
  664.                 LOAD_TTOS
  665.                 [TARGET]        END-MACRO       NO-INTERPRET
  666.  
  667. ' +!   >EXECUTE IS COMP_PSTORE     \ link to compiler
  668.  
  669. MACRO C+!       ( n addr -- )
  670.                 [FORTH]
  671.                 IMM/ABS_OPT ?DUP
  672.                 IF      0<
  673.                         IF
  674.                                 [ASM96]
  675.                                 ADD ( xxxx ) BL
  676.                                 [FORTH]
  677.                         ELSE
  678.                                 [ASM96]
  679.                                 MOV DI, ( xxxx )
  680.                                 ADD 0 [DI], BL
  681.                                 [FORTH]
  682.                         THEN
  683.                 ELSE
  684.                         [ASM96]
  685.                         LODSW
  686.                         ADD 0 [BX], AL
  687.                         [FORTH]
  688.                 THEN
  689.                 LOAD_TTOS         END-MACRO       NO-INTERPRET
  690. comment;
  691.  
  692. MACRO 2*        ( n -- 2*n )
  693.                 SHL ttos # 1    END-MACRO       EXECUTES> 2*
  694.  
  695. MACRO 4*        ( n -- 2*n )
  696.                 SHL ttos # 1
  697.                 SHL ttos # 1    END-MACRO       NO-INTERPRET
  698.  
  699. MACRO 2/        ( n -- n/2 )
  700.                 SHRA TTOS # 1   END-MACRO       EXECUTES> 2/
  701.  
  702. MACRO U2/       ( u -- u/2 )
  703.                 SHR TTOS # 1    END-MACRO       EXECUTES> U2/
  704.  
  705. ICODE U16/      ( u -- u/16 )
  706.                 SHR TTOS # 1     SHR TTOS # 1
  707.                 SHR TTOS # 1     SHR TTOS # 1
  708.                 RET             END-ICODE
  709.  
  710. ICODE U8/       ( u -- u/8 )
  711.                 SHR TTOS # 1
  712.                 SHR TTOS # 1
  713.                 SHR TTOS # 1
  714.                 RET             END-ICODE
  715.  
  716. ICODE 8*        ( n -- 8*n )
  717.                 SHL TTOS # 1
  718.                 SHL TTOS # 1
  719.                 SHL TTOS # 1
  720.                 RET             END-ICODE
  721.  
  722. MACRO 1+        ( n1 --- n2 )
  723.                 INC TTOS        END-MACRO       EXECUTES> 1+
  724.  
  725. MACRO 2+        ( n1 --- n2 )
  726.                 ADD TTOS # 2    END-MACRO      EXECUTES> 2+
  727.  
  728. MACRO 1-        ( n1 --- n2 )
  729.                 DEC TTOS        END-MACRO       EXECUTES> 1-
  730.  
  731. MACRO 2-        ( n1 --- n2 )
  732.                 SUB TTOS # 2    END-MACRO      EXECUTES> 2-
  733.  
  734. comment:
  735.  
  736. ICODE UM*       ( n1 n2 -- d )
  737.                 MOV AX, 0 [SI]
  738.                 MUL BX
  739.                 MOV 0 [SI], AX
  740.                 XCHG BX, DX
  741.                 RET             END-ICODE
  742. comment;
  743.  
  744. MACRO *         ( n1 n2 -- n3 )
  745. \                LD      W0 []+ PSP
  746. \                CLR     W2
  747. \                MUL     W0 TTOS
  748. \                CLR     TTOS+
  749.                 CLR     W2
  750.                 MUL     W0  <-- TTOS  []+ PSP
  751.                 LD      TTOS W0
  752.                 END-MACRO       EXECUTES> *
  753. comment:
  754.  
  755. : U*D           ( n1 n2 -- d )
  756.                 UM*   ;                         NO-INTERPRET
  757.  
  758. ICODE UM/MOD    ( ud un -- URemainder UQuotient )
  759.                 XCHG SI, SP
  760.                 POP DX
  761.                 POP AX
  762.                 CMP DX, BX
  763.                 [ASM96]
  764.             U>= IF                      \ divide by zero?
  765.                         MOV AX, # -1
  766.                         MOV DX, AX
  767.                         PUSH DX
  768.                         MOV BX, AX
  769.                         XCHG SI, SP
  770.                         RET
  771.                 THEN
  772.                 DIV BX
  773.                 PUSH DX
  774.                 MOV BX, AX
  775.                 XCHG SI, SP
  776.                 RET             END-ICODE
  777. COMMENT;
  778.  
  779. MACRO 0=        ( n -- f )
  780.                 SUB TTOS # 1
  781.                 SUBC TTOS TTOS  END-MACRO       EXECUTES> 0=
  782.  
  783. MACRO 0<        ( n -- f )
  784.                 BITSET TTOSH 7 IF  LD TTOS # -1
  785.                              ELSE  CLR TTOS
  786.                              THEN
  787. \                MOV AX, BX
  788. \                CWD
  789. \                MOV BX, DX
  790.                 END-MACRO       EXECUTES> 0<
  791.  
  792. COMMENT:
  793.  
  794. ICODE 0>        ( n -- f )
  795.                 MOV AX, BX
  796.                 NEG AX
  797.                 [ASM96]
  798.            OV<> IF      CWD
  799.                         MOV BX, DX
  800.                         RET
  801.                 THEN
  802.                 SUB BX, BX
  803.                 RET             END-ICODE
  804.  
  805. IMACRO 0<>      ( n -- f )
  806.                 NEG BX
  807.                 SBB BX, BX      END-IMACRO
  808.  
  809. MACRO =         ( n1 n2 -- f )
  810.                 [FORTH]
  811.                 IMM/ABS_OPT ?DUP
  812.                 IF      0<
  813.                         IF
  814.                                 [ASM96]
  815.                                 SUB BX, # ( xxxx )
  816.                                 [FORTH]
  817.                         ELSE
  818.                                 [ASM96]
  819.                                 SUB BX, ( xxxx )
  820.                                 [FORTH]
  821.                         THEN
  822.                 ELSE
  823.                         [ASM96]
  824.                         LODSW
  825.                         SUB BX, AX
  826.                         [FORTH]
  827.                 THEN
  828.                 [ASM96]
  829.                 SUB BX, # 1
  830.                 SBB BX, BX
  831.                 [TARGET]        END-MACRO       NO-INTERPRET
  832.  
  833. MACRO <>        ( n1 n2 -- f )
  834.                 [FORTH]
  835.                 IMM/ABS_OPT ?DUP
  836.                 IF      0<
  837.                         IF
  838.                                 [ASM96]
  839.                                 SUB BX, # ( xxxx )
  840.                                 [FORTH]
  841.                         ELSE
  842.                                 [ASM96]
  843.                                 SUB BX, ( xxxx )
  844.                                 [FORTH]
  845.                         THEN
  846.                 ELSE
  847.                         [ASM96]
  848.                         LODSW
  849.                         SUB BX, AX
  850.                         [FORTH]
  851.                 THEN
  852.                 [ASM96]
  853.                 NEG BX
  854.                 SBB BX, BX
  855.                 [TARGET]        END-MACRO       NO-INTERPRET
  856.  
  857. : ?NEGATE       ( n1 n2 -- n3 )
  858.                 0< IF    NEGATE   THEN   ;      NO-INTERPRET
  859.  
  860. MACRO U<        ( n1 n2 -- f )
  861.         LD      W0 []+ PSP
  862.         SUB     W0 TTOS
  863.         SUBC    W0 W0
  864.         LD      TTOS W0
  865. \                LODSW
  866. \                SUB AX, BX
  867. \                SBB AX, AX
  868. \                MOV BX, AX
  869.         END-MACRO       NO-INTERPRET
  870.  
  871.  
  872. MACRO U>        ( n1 n2 -- f )
  873.                 [FORTH]
  874.                 IMM/ABS_OPT ?DUP
  875.                 IF      0<
  876.                         IF
  877.                                 [ASM96]
  878.                                 MOV AX, # ( xxxx )
  879.                                 SUB AX, BX
  880.                                 SBB AX, AX
  881.                                 MOV BX, AX
  882.                                 [FORTH]
  883.                         ELSE
  884.                                 [ASM96]
  885.                                 MOV AX, ( xxxx )
  886.                                 SUB AX, BX
  887.                                 SBB AX, AX
  888.                                 MOV BX, AX
  889.                                 [FORTH]
  890.                         THEN
  891.                 ELSE
  892.                         [ASM96]
  893.                         LODSW
  894.                         SUB BX, AX
  895.                         SBB BX, BX
  896.                         [FORTH]
  897.                 THEN
  898.                 [TARGET]        END-MACRO       NO-INTERPRET
  899.  
  900. ICODE <         ( n1 n2 -- f )
  901.                 LODSW
  902.                 MOV DI, # TRUE
  903.                 CMP AX, BX
  904.                 [ASM96]
  905.              >= IF      SUB DI, DI
  906.                 THEN
  907.                 MOV BX, DI
  908.                 RET             END-ICODE
  909.  
  910. ICODE >         ( n1 n2 -- f )
  911.                 LODSW
  912.                 MOV DI, # TRUE
  913.                 CMP AX, BX
  914.                 [ASM96]
  915.              <= IF      SUB DI, DI
  916.                 THEN
  917.                 MOV BX, DI
  918.                 RET             END-ICODE
  919.  
  920. ICODE UMIN      ( n1 n2 -- n3 )
  921.                 LODSW
  922.                 CMP BX, AX
  923.                 [ASM96]
  924.              U> IF      MOV BX, AX
  925.                 THEN
  926.                 RET             END-ICODE
  927.  
  928. ICODE MIN       ( n1 n2 -- n3 )
  929.                 LODSW
  930.                 CMP BX, AX
  931.                 [ASM96]
  932.               > IF      MOV BX, AX
  933.                 THEN
  934.                 RET             END-ICODE
  935.  
  936. ICODE MAX       ( n1 n2 -- n3 )
  937.                 LODSW
  938.                 CMP BX, AX
  939.                 [ASM96]
  940.              <= IF      MOV BX, AX
  941.                 THEN
  942.                 RET             END-ICODE
  943.  
  944. IMACRO 0MAX     ( n1 -- n3 )
  945.                 [ASM96]
  946.                 CMP BX, BP
  947.              <= IF      SUB BX, BX
  948.                 THEN            END-IMACRO
  949.  
  950. ICODE UMAX      ( n1 n2 -- n3 )
  951.                 [ASM96]
  952.                 LODSW
  953.                 CMP BX, AX
  954.             U<= IF      MOV BX, AX
  955.                 THEN
  956.                 RET             END-ICODE
  957.  
  958. ICODE WITHIN    ( n lo hi -- flag )
  959.                 [ASM96]
  960.                 MOV DI, BX
  961.                 LODSW
  962.                 MOV CX, AX
  963.                 LODSW
  964.                 SUB BX, BX
  965.                 CMP AX, DI
  966.               < IF      CMP AX, CX
  967.                      >= IF      DEC BX
  968.                         THEN
  969.                 THEN
  970.                 RET             END-ICODE
  971.  
  972. ICODE BETWEEN   ( n lo hi -- flag )
  973.                 [ASM96]
  974.                 MOV DX, BX
  975.                 LODSW
  976.                 MOV CX, AX
  977.                 LODSW
  978.                 SUB BX, BX
  979.                 CMP AX, DX
  980.              <= IF      CMP AX, CX
  981.                      >= IF      DEC BX
  982.                         THEN
  983.                 THEN
  984.                 RET             END-ICODE
  985.  
  986. $FFFF CONSTANT TRUE
  987. $0000 CONSTANT FALSE
  988.  
  989. ICODE 2@        ( addr -- d )
  990.                 XCHG SI, SP
  991.                 PUSH 2 [BX]
  992.                 MOV BX, 0 [BX]
  993.                 XCHG SI, SP
  994.                 RET             END-ICODE
  995.  
  996. ICODE 2!        ( d addr -- )
  997.                 XCHG SI, SP
  998.                 POP 0 [BX]
  999.                 POP 2 [BX]
  1000.                 POP BX
  1001.                 XCHG SI, SP
  1002.                 RET             END-ICODE
  1003.  
  1004. MACRO 2DROP     ( d -- )
  1005.                 INC SI
  1006.                 INC SI
  1007.                 LOAD_TTOS         END-MACRO       EXECUTES> 2DROP
  1008.  
  1009. IMACRO 3DROP    ( n1 n2 n3 -- )
  1010.                 ADD SI, # 4
  1011.                 LOAD_TTOS         END-IMACRO
  1012.  
  1013. CODE 2DUP       ( d -- d d )
  1014.                 XCHG SI, SP
  1015.                 MOV DI, SP
  1016.                 PUSH BX
  1017.                 PUSH 0 [DI]
  1018.                 XCHG SI, SP
  1019.                 RET             END-CODE        EXECUTES> 2DUP
  1020.  
  1021. ICODE 3DUP      ( n1 n2 n3 -- n1 n2 n3 n1 n2 n3 )
  1022.                 XCHG SI, SP
  1023.                 MOV DI, SP
  1024.                 PUSH BX
  1025.                 PUSH 2 [DI]
  1026.                 PUSH 0 [DI]
  1027.                 XCHG SI, SP
  1028.                 RET             END-ICODE
  1029.  
  1030. ICODE 2SWAP     ( d1 d2 -- d2 d1 )
  1031.                 XCHG SI, SP
  1032.                 POP CX          XCHG BX, CX
  1033.                 POP AX          POP DX
  1034.                 PUSH BX         PUSH CX
  1035.                 PUSH DX
  1036.                 MOV BX, AX
  1037.                 XCHG SI, SP
  1038.                 RET             END-ICODE
  1039.  
  1040. ICODE 2OVER     ( d1 d2 -- d1 d2 d1 )
  1041.                 XCHG SI, SP
  1042.                 MOV DI, SP
  1043.                 PUSH BX
  1044.                 PUSH 4 [DI]
  1045.                 MOV BX, 2 [DI]
  1046.                 XCHG SI, SP
  1047.                 RET             END-ICODE
  1048.  
  1049. ICODE D+        ( d1 d2 -- dsum )
  1050.                 MOV DX, BX
  1051.                 LODSW
  1052.                 ADD 2 [SI], AX
  1053.                 LOAD_TTOS
  1054.                 ADC BX, DX
  1055.                 RET             END-ICODE
  1056.  
  1057. IMACRO DNEGATE  ( d# -- d#' )
  1058.                 NEG BX
  1059.                 NEG 0 [SI] WORD
  1060.                 SBB BX, BP      END-IMACRO
  1061.  
  1062. ICODE S>D       ( n -- d )
  1063.                 MOV AX, BX
  1064.                 CWD
  1065.                 DEC SI
  1066.                 DEC SI
  1067.                 MOV 0 [SI], DX
  1068.                 MOV BX, AX
  1069.                 RET             END-ICODE
  1070.  
  1071. ICODE DABS      ( d1 -- d2 )
  1072.                 [ASM96]
  1073.                 OR BX, BP
  1074.              0< IF      NEG BX
  1075.                         NEG 0 [SI] WORD
  1076.                         SBB BX, BP
  1077.                 THEN
  1078.                 RET             END-ICODE
  1079.  
  1080. IMACRO D2*      ( d -- d*2 )
  1081.                 SHL 0 [SI], # 1 WORD
  1082.                 RCL BX, # 1     END-IMACRO
  1083.  
  1084. IMACRO D2/      ( d -- d/2 )
  1085.                 SAR BX, # 1
  1086.                 RCR 0 [SI], # 1 WORD
  1087.                 END-IMACRO
  1088.  
  1089. : D-            ( d1 d2 -- d3 )
  1090.                 DNEGATE D+   ;                  NO-INTERPRET
  1091.  
  1092. : ?DNEGATE      ( d1 n -- d2 )
  1093.                 0< IF   DNEGATE   THEN   ;      NO-INTERPRET
  1094.  
  1095. : D0=           ( d -- f )
  1096.                 OR 0= ;                         NO-INTERPRET
  1097.  
  1098. : D=            ( d1 d2 -- f )
  1099.                 D-  D0=  ;                      NO-INTERPRET
  1100.  
  1101. : DU<           ( ud1 ud2 -- f )
  1102.                 ROT SWAP 2DUP U<
  1103.                 IF      2DROP 2DROP TRUE
  1104.                 ELSE    <> IF   2DROP FALSE  ELSE  U<  THEN
  1105.                 THEN  ;                         NO-INTERPRET
  1106.  
  1107. : D<            ( d1 d2 -- f )
  1108.                 2 PICK OVER =
  1109.                 IF      DU<
  1110.                 ELSE  NIP ROT DROP <  THEN  ;   NO-INTERPRET
  1111.  
  1112. : D>            ( d1 d2 -- f )
  1113.                 2SWAP D<   ;                    NO-INTERPRET
  1114.  
  1115. : 4DUP          ( a b c d -- a b c d a b c d )
  1116.                 2OVER 2OVER   ;                 NO-INTERPRET
  1117.  
  1118. : DMIN          ( d1 d2 -- d3 )
  1119.                 4DUP D> IF  2SWAP  THEN 2DROP ; NO-INTERPRET
  1120.  
  1121. : DMAX          ( d1 d2 -- d3 )
  1122.                 4DUP D< IF 2SWAP THEN 2DROP ;   NO-INTERPRET
  1123.  
  1124. ICODE *D        ( n1 n2 -- d# )
  1125.                 MOV AX, 0 [SI]
  1126.                 IMUL BX
  1127.                 MOV 0 [SI], AX
  1128.                 MOV BX, DX
  1129.                 RET             END-ICODE
  1130.  
  1131. : MU/MOD        ( ud# un1 -- rem d#quot )
  1132.                 >R  0  R@  UM/MOD  R>  SWAP  >R  UM/MOD  R>   ;
  1133.  
  1134. comment;
  1135.  
  1136. MACRO /         ( num den --- quot )
  1137.                 LD      W0 []+ PSP
  1138.                 CLR     W2
  1139.                 DIV     W0 TTOS
  1140.                 LD      TTOS W0
  1141.                 END-MACRO       EXECUTES> /
  1142.  
  1143. comment:
  1144.  
  1145. ICODE /MOD      ( num den --- rem quot )
  1146.                 RET             END-ICODE
  1147.  
  1148. : MOD           ( n1 n2 -- rem )
  1149.                 /MOD  DROP  ;                   EXECUTES> MOD
  1150.  
  1151. ICODE */MOD     ( n1 n2 n3 --- rem quot )
  1152.                 XCHG SI, SP
  1153.                 POP AX          POP CX
  1154.                 IMUL CX         MOV CX, BX
  1155.                 XOR CX, DX
  1156.                 [ASM96]
  1157.             0>= IF
  1158.                         IDIV BX
  1159.                 ELSE
  1160.                         IDIV BX
  1161.                         OR DX, DX
  1162.                     0<> IF
  1163.                                 ADD DX, BX
  1164.                                 DEC AX
  1165.                         THEN
  1166.                 THEN
  1167.                 PUSH DX
  1168.                 MOV BX, AX
  1169.                 XCHG SI, SP
  1170.                 RET             END-ICODE
  1171.  
  1172. MACRO XOR       ( n1 n2 -- n3 )
  1173.                 [FORTH]
  1174.                 IMM/ABS_OPT ?DUP
  1175.                 IF      0<
  1176.                         IF
  1177.                                 [ASM96]
  1178.                                 XOR BX, # ( xxxx )
  1179.                                 [FORTH]
  1180.                         ELSE
  1181.                                 [ASM96]
  1182.                                 XOR BX, ( xxxx )
  1183.                                 [FORTH]
  1184.                         THEN
  1185.                 ELSE
  1186.                         [ASM96]
  1187.                         LODSW
  1188.                         XOR BX, AX
  1189.                         [FORTH]
  1190.                 THEN
  1191.                 [TARGET]        END-MACRO       EXECUTES> XOR
  1192.  
  1193. : M/MOD         ( d# n1 -- rem quot )
  1194.                 ?DUP
  1195.                 IF  DUP>R  2DUP XOR >R  >R DABS R@ ABS  UM/MOD
  1196.                         SWAP R> ?NEGATE
  1197.                         SWAP R> 0<
  1198.                         IF  NEGATE OVER
  1199.                                 IF  1- R@ ROT - SWAP  THEN
  1200.                         THEN    R>DROP
  1201.                 THEN  ;                         NO-INTERPRET
  1202.  
  1203. : */            ( n1 n2 n3 -- n1*n2/n3 )
  1204.                 */MOD  NIP  ;                   NO-INTERPRET
  1205.  
  1206. : ROLL          ( n1 n2 .. nk k -- n2 n3 .. nk n1 )
  1207.                 >R R@ PICK   SP@ DUP 2+   R> 1+ 2* CMOVE>  DROP  ;
  1208.                                                 NO-INTERPRET
  1209. : 2ROT          ( a b c d e f - c d e f a b )
  1210.                 5 ROLL  5 ROLL  ;               NO-INTERPRET
  1211.  
  1212. comment;
  1213.  
  1214. CODE FILL      (  start-addr count char -- )
  1215.                 LD      W2 []+ PSP
  1216.                 LD      W0 []+ PSP
  1217.         1 $:|
  1218.                 STB     TTOS []+ W0
  1219.                 DEC     W2
  1220.                 JNE     1 $
  1221.                 LOAD_TTOS
  1222.                 RET             END-CODE
  1223.  
  1224. : ERASE         ( addr len -- )
  1225.                 0 FILL   ;                      NO-INTERPRET
  1226.  
  1227. $20 CONSTANT BL                 \ a blank
  1228.  
  1229. : BLANK         ( addr len -- )
  1230.                 BL FILL   ;                     NO-INTERPRET
  1231.  
  1232. \S
  1233. ICODE COUNT     ( a1 --- a2 n1 )
  1234.                 SUB AX, AX
  1235.                 MOV AL, 0 [BX]
  1236.                 INC BX
  1237.                 DEC SI
  1238.                 DEC SI
  1239.                 MOV 0 [SI], BX
  1240.                 MOV BX, AX
  1241.                 RET             END-ICODE
  1242.  
  1243. ICODE COUNTL    ( seg addr -- seg addr+1 len )
  1244.                 MOV AX, 0 [SI]
  1245.                 MOV DX, DS      MOV DS, AX
  1246.                 XOR AX, AX      MOV AL, 0 [BX]
  1247.                 INC BX
  1248.                 MOV DS, DX
  1249.                 DEC SI
  1250.                 DEC SI
  1251.                 MOV 0 [SI], BX
  1252.                 MOV BX, AX
  1253.                 RET             END-ICODE
  1254.  
  1255. ICODE LENGTH    ( a1 --- a2 n1 )
  1256.                 MOV AX, 0 [BX]
  1257.                 INC BX
  1258.                 INC BX
  1259.                 DEC SI
  1260.                 DEC SI
  1261.                 MOV 0 [SI], BX
  1262.                 MOV BX, AX
  1263.                 RET             END-ICODE
  1264.  
  1265. ICODE CMOVEL    ( sseg sptr dseg dptr cnt -- )
  1266.                 PUSH DS
  1267.                 PUSH ES
  1268.                 XCHG SI, SP
  1269.                 MOV CX, BX              \ count to CX
  1270.                 MOV BX, SI              \ preserve SI
  1271.                 CLD
  1272.                 POP DI
  1273.                 POP ES          POP SI
  1274.                 POP DS
  1275.                 [ASM96]
  1276.           CX<>0 IF
  1277.                         REPNZ   MOVSB
  1278.                 THEN
  1279.                 MOV SI, BX              \ restore SI
  1280.                 POP BX
  1281.                 XCHG SI, SP
  1282.                 POP ES
  1283.                 POP DS
  1284.                 RET             END-ICODE
  1285.  
  1286. ICODE CMOVEL>   ( sseg sptr dseg dptr cnt -- )
  1287.                 PUSH DS
  1288.                 PUSH ES
  1289.                 XCHG SI, SP
  1290.                 MOV CX, BX              \ count to BX
  1291.                 MOV BX, SI              \ preserve SI
  1292.                 STD
  1293.                 POP DI
  1294.                 POP ES          POP SI
  1295.                 POP DS
  1296.                 [ASM96]
  1297.           CX<>0 IF
  1298.                         DEC CX          ADD DI, CX
  1299.                         ADD SI, CX      INC CX
  1300.                         REPNZ           MOVSB
  1301.                 THEN
  1302.                 CLD
  1303.                 MOV SI, BX              \ restore SI
  1304.                 POP BX
  1305.                 XCHG SI, SP
  1306.                 POP ES
  1307.                 POP DS
  1308.                 RET             END-ICODE
  1309.  
  1310. : MOVE          ( from to len -- )
  1311.                 -ROT   2DUP U< IF   ROT CMOVE>   ELSE   ROT CMOVE   THEN ;
  1312.                                                 NO-INTERPRET
  1313.  
  1314. ICODE SKIP      ( addr len char -- addr' len' ) \ skip char forwards
  1315.                 [ASM96]
  1316.                 LODSW   MOV CX, AX
  1317.                 MOV AX, BX
  1318.           CX<>0 IF      MOV DI, 0 [SI]
  1319.                         MOV DX, ES
  1320.                         MOV BX, DS      MOV ES, BX
  1321.                         REPZ            SCASB
  1322.                         MOV ES, DX
  1323.                     0<> IF
  1324.                                 INC CX
  1325.                                 DEC DI
  1326.                         THEN
  1327.                         MOV 0 [SI], DI
  1328.                 THEN    MOV BX, CX
  1329.                 RET             END-ICODE
  1330.  
  1331. ICODE -SKIP     ( addr len char -- addr' len' ) \ skip char backwards
  1332.                 [ASM96]
  1333.                 LODSW   MOV CX, AX
  1334.                 MOV AX, BX
  1335.           CX<>0 IF      MOV DI, 0 [SI]
  1336.                         MOV DX, ES
  1337.                         MOV BX, DS      MOV ES, BX
  1338.                         STD     REPZ    SCASB   CLD
  1339.                         MOV ES, DX
  1340.                     0<> IF
  1341.                                 INC CX
  1342.                                 INC DI
  1343.                         THEN
  1344.                         MOV 0 [SI], DI
  1345.                 THEN    MOV BX, CX
  1346.                 RET             END-ICODE
  1347.  
  1348. ICODE SCAN      ( addr len char -- addr' len' ) \ scan char forwards
  1349.                 [ASM96]
  1350.                 LODSW   MOV CX, AX
  1351.                 MOV AX, BX
  1352.           CX<>0 IF      MOV DI, 0 [SI]
  1353.                         MOV DX, ES
  1354.                         MOV BX, DS      MOV ES, BX
  1355.                         REPNZ           SCASB
  1356.                         MOV ES, DX
  1357.                      0= IF              INC CX
  1358.                                         DEC DI
  1359.                         THEN
  1360.                         MOV 0 [SI], DI
  1361.                 THEN    MOV BX, CX
  1362.                 RET     END-ICODE
  1363.  
  1364. ICODE  -SCAN    ( addr len char -- addr' len' ) \ scan char backwards
  1365.                 [ASM96]
  1366.                 LODSW   MOV CX, AX
  1367.                 MOV AX, BX
  1368.           CX<>0 IF      MOV DI, 0 [SI]
  1369.                         MOV DX, ES
  1370.                         MOV BX, DS      MOV ES, BX
  1371.                         STD     REPNZ   SCASB   CLD
  1372.                         MOV ES, DX
  1373.                      0= IF              DEC CX
  1374.                                         INC DI
  1375.                         THEN
  1376.                         MOV 0 [SI], DI
  1377.                 THEN    MOV BX, CX
  1378.                 RET     END-ICODE
  1379.  
  1380. ICODE /STRING   ( addr len n -- addr' len' )
  1381.                 LODSW
  1382.                 XCHG BX, AX
  1383.                 CMP BX, AX
  1384.                 [ASM96]
  1385.             U<= IF      MOV AX, BX      \ AX = SMALLER OF AX BX
  1386.                 THEN
  1387.                 ADD 0 [SI], AX
  1388.                 SUB BX, AX
  1389.                 RET             END-ICODE
  1390.  
  1391. ICODE DIGIT     ( char base -- n f )
  1392.                 [ASM96]
  1393.                 MOV AX, 0 [SI]
  1394.                 SUB AL, # $30           \ ASCII 0    can't user ASCII in CODE
  1395.                 JB 0 $
  1396.                         CMP AL, # 9
  1397.               > IF
  1398.                         CMP AL, # 17
  1399.                         JB 0 $
  1400.                         SUB AL, # 7
  1401.                 THEN
  1402.                 CMP AL, BL
  1403.                 JAE 0 $
  1404.                         MOV 0 [SI], AX
  1405.                         MOV BX, # -1
  1406.                         RET
  1407.            0 $: SUB BX, BX
  1408.                 RET             END-ICODE
  1409.  
  1410. VARIABLE DPL
  1411. VARIABLE BASE
  1412. VARIABLE HLD
  1413. VARIABLE CAPS
  1414. VARIABLE SSEG
  1415. VARIABLE SPAN
  1416. VARIABLE #OUT
  1417. VARIABLE #LINE
  1418. VARIABLE SAVECUR
  1419. VARIABLE ESC_FLG
  1420. VARIABLE #TIB
  1421. VARIABLE >IN
  1422. VARIABLE #EXSTRT
  1423. VARIABLE FUDGE
  1424. VARIABLE ATTRIB
  1425. VARIABLE LMARGIN
  1426. VARIABLE RMARGIN
  1427. VARIABLE TABSIZE
  1428.  
  1429. : HERE          ( -- A1 )       \ return a1 the address of the next available
  1430.                                 \ free memory space in data ram
  1431.                 DP @ ;                          EXECUTES> HERE
  1432.  
  1433. : PAD           ( -- a1 )       \ a place to put things for a bit
  1434.                 DP @ 82 + ;                     EXECUTES> PAD
  1435.  
  1436. : ALLOT         ( n1 -- )       \ allot some DS: ram
  1437.                 DP +! ;                         NO-INTERPRET
  1438.  
  1439. : DS:ALLOC      ( n1 -- a1 )    \ allocate n1 bytes of ram at runtime,
  1440.                                 \ returning a1 the address of the ram
  1441.                 HERE SWAP ALLOT ;               NO-INTERPRET
  1442.  
  1443. : DS:FREE?      ( -- n1 )       \ return the amount of free ram at runtime
  1444.                 SP0 @ HERE - 300 - ;            NO-INTERPRET
  1445.  
  1446. : WORD          ( c1 -- a1 )    \ return a1 a word from TIB
  1447.                 >R
  1448.                 TIB #TIB @ >IN @ /STRING        \ starting point for word
  1449.                 R@ SKIP 2DUP R> SCAN NIP        \ parse out a word
  1450.                 #TIB @ OVER - >IN !             \ adj >in to new point in $
  1451.                 - HERE PLACE HERE               \ return string in HERE
  1452.                 $2020 HERE COUNT + ! ;          \ append blanks
  1453.                                                 NO-INTERPRET
  1454.  
  1455. : DOS_TO_TIB    ( -- )          \ Move the DOS commandline to Forths TIB
  1456.                 ?CS: DOS_CMD_TAIL COUNTL DUP #TIB ! ?DS: TIB ROT CMOVEL
  1457.                 >IN OFF ;                       NO-INTERPRET
  1458.  
  1459. : HEX           ( -- )
  1460.                 $10 BASE ! ;                    EXECUTES> HEX
  1461.  
  1462. : DECIMAL       ( -- )
  1463.                 $0A BASE ! ;                    EXECUTES> DECIMAL
  1464.  
  1465. : OCTAL         ( -- )
  1466.                 $08 BASE ! ;                    EXECUTES> OCTAL
  1467.  
  1468. : COMPARE       ( addr1 addr2 len -- -1 | 0 | 1 )
  1469.                 CAPS @ IF   CAPS-COMP   ELSE   COMP   THEN   ;
  1470.                                                 NO-INTERPRET
  1471. : DOUBLE?       ( -- f )
  1472.                 DPL @ 1+   0<> ;                NO-INTERPRET
  1473.  
  1474. : CONVERT       ( +d1 adr1 -- +d2 adr2 )
  1475.                 BEGIN   1+  DUP>R  C@  BASE @  DIGIT
  1476.                 WHILE   SWAP  BASE @ UM*  DROP  ROT  BASE @ UM*  D+
  1477.                         DOUBLE?  IF  DPL INCR THEN  R>
  1478.                 REPEAT  DROP  R>  ;             NO-INTERPRET
  1479.  
  1480. : (NUMBER?)     ( adr -- d flag )
  1481.                 0 0  ROT  DUP 1+  C@  ASCII -  =  DUP  >R  -  -1 DPL !
  1482.                 BEGIN   CONVERT  DUP C@  ASCII , ASCII / BETWEEN
  1483.                 WHILE   0 DPL !
  1484.                 REPEAT  -ROT  R> IF  DNEGATE  THEN   ROT C@ BL =  ;
  1485.                                                 NO-INTERPRET
  1486.  
  1487. : NUMBER?       ( adr -- d flag )
  1488.                 FALSE  OVER COUNT BOUNDS
  1489.                 ?DO     I C@ BASE @ DIGIT NIP
  1490.                         IF      DROP TRUE LEAVE THEN
  1491.                 (LOOP) LEAVE? UNDO DO?
  1492.                 IF  (NUMBER?)  ELSE  DROP  0 0 FALSE  THEN  ;
  1493.                                                 NO-INTERPRET
  1494.  
  1495. ICODE %DOSEXPECT ( addr +n --- n2 )
  1496.                 PUSH BP
  1497.                 XCHG SI, SP
  1498.                 MOV AX, BX                      \ count to ax
  1499.                 MOV BX, SP
  1500.                 SUB BX, # $100                  \ buffer 256 bytes below stck
  1501.                 MOV 0 [BX], AL                  \ 1st byte buffer = chars
  1502.                 MOV DX, BX                      \ DX = ^buffer
  1503.                 MOV AH, # $0A                   \ buffered keyboard input
  1504.                 INT $21                         \ DOS function call
  1505.                 SUB CX, CX                      \ zero CX
  1506.                 INC BX                          \ BX = ^#chars read
  1507.                 MOV CL, 0 [BX]                  \ CX = #chars READ
  1508.                 POP DI                          \ DI = forth address
  1509.                 PUSH CX                         \ return CX
  1510.                 INC BX                          \ BX = ^buffer
  1511.                 MOV DX, SI                      \ DX saves SI
  1512.                 MOV AX, ES                      \ AX saves ES
  1513.                 MOV SI, BX                      \ SI = DOS address
  1514.                 MOV BX, DS
  1515.                 MOV ES, BX                      \ set ES = DS
  1516.                 REPNZ MOVSB                     \ move it
  1517.                 MOV SI, DX                      \ restore SI
  1518.                 MOV ES, AX                      \ restore ES
  1519.                 POP BX
  1520.                 XCHG SI, SP
  1521.                 POP BP
  1522.                 RET             END-ICODE
  1523.  
  1524. ICODE DEALLOC   ( n1 -- f1 )
  1525.                 PUSH ES         MOV ES, BX
  1526.                 MOV AH, # $49
  1527.                 INT $21
  1528.                 [ASM96]
  1529.              U< IF      SUB AH, AH
  1530.                 ELSE    SUB AX, AX
  1531.                 THEN
  1532.                 POP ES
  1533.                 MOV BX, AX
  1534.                 RET             END-ICODE
  1535.  
  1536. ICODE ALLOC     ( n1 -- n2 n3 f1 )
  1537.                 XCHG SI, SP
  1538.                 MOV AH, # $48
  1539.                 INT $21
  1540.                 PUSH BX
  1541.                 PUSH AX
  1542.                 [ASM96]
  1543.              U< IF      SUB AH, AH
  1544.                 ELSE    SUB AX, AX
  1545.                 THEN
  1546.                 MOV BX, AX
  1547.                 XCHG SI, SP
  1548.                 RET             END-ICODE
  1549.  
  1550. ICODE SETBLOCK  ( seg siz -- f1 )
  1551.                 LODSW
  1552.                 MOV DX, AX
  1553.                 MOV AH, # $4A           \ setblock call
  1554.                 PUSH ES
  1555.                 MOV ES, DX
  1556.                 INT $21
  1557.                 [ASM96]
  1558.              U< IF      SUB AH, AH
  1559.                 ELSE    SUB AX, AX
  1560.                 THEN
  1561.                 POP ES
  1562.                 MOV BX, AX
  1563.                 RET             END-ICODE
  1564.  
  1565. : PARAGRAPH     ( offset -- paragraph-inc )
  1566.                 15 + U16/ ;             EXECUTES> PARAGRAPH
  1567.  
  1568. ICODE EXECF     ( string PARMS --- return-code )
  1569.                 [ASM96]             \ BX contains PARMS
  1570.                 LODSW
  1571.                 MOV DX, AX              \ DX contains string
  1572.                 PUSH ES                 PUSH SI
  1573.                 PUSH BP                 PUSH DS
  1574.                 MOV AX, DS              MOV ES, AX
  1575.                 MOV AX, # $4B00
  1576.                 INT $21
  1577.                 POP DS                  POP BP
  1578.                 POP SI                  POP ES
  1579.              U< IF                      \ ONLY when carry is NON ZERO
  1580.                         AND AX, # $FF
  1581.                 ELSE    SUB AX, AX
  1582.                 THEN
  1583.                 MOV BX, AX
  1584.                 RET             END-ICODE
  1585.  
  1586. ICODE VIDEO     ( DX CX BX AX -- DX AX )        \ perform a VIDEO interrupt
  1587.                                                 \ call.
  1588.                 MOV DX, BX
  1589.                 LOAD_TTOS
  1590.                 LODSW   MOV CX, AX
  1591.                 LODSW   XCHG DX, AX
  1592.                 PUSH SI         PUSH BP
  1593.                 INT $10
  1594.                 POP BP          POP SI
  1595.                 DEC SI
  1596.                 DEC SI
  1597.                 MOV 0 [SI], DX
  1598.                 MOV BX, AX
  1599.                 RET             END-ICODE
  1600.  
  1601. : AT?           ( -- x y )              \ return the current cursor position
  1602.                 0 0 0 $0300 VIDEO DROP SPLIT ;  NO-INTERPRET
  1603.  
  1604. : AT            ( X Y -- )              \ set the current cursor position
  1605.                 2DUP #LINE ! #OUT !
  1606.                 FLIP OR 0 0 $0200 VIDEO 2DROP ; NO-INTERPRET
  1607.  
  1608. : VMODE@        ( -- n1 )               \ get the current video mode.
  1609.                 0 0 0 $0F00 VIDEO NIP $FF AND ; NO-INTERPRET
  1610.  
  1611. : VMODE!        ( n1 -- )               \ use to set video modes. n1 is the
  1612.                                         \ desired mode number. For example
  1613.                                         \ 6 VMODE! will select 640x200
  1614.                                         \ black & white graphics.
  1615.                 >R 0 0 0 R> VIDEO 2DROP ;       NO-INTERPRET
  1616.  
  1617. : DARK          ( -- )                  \ fetch and store video mode thus
  1618.                                         \ clearing the screen.
  1619.                 VMODE@ VMODE! #OUT OFF #LINE OFF ;  EXECUTES> DARK
  1620.  
  1621. ' DARK ALIAS CLS
  1622.  
  1623. ICODE ?VMODE    ( --- N1 )              \ Get the video mode from DOS
  1624.                 DEC SI
  1625.                 DEC SI
  1626.                 MOV 0 [SI], BX
  1627.                 MOV AH, # $0F
  1628.                 INT $10
  1629.                 SUB AH, AH
  1630.                 MOV BX, AX
  1631.                 RET             END-ICODE
  1632.  
  1633. ICODE SET-CURSOR ( n1 --- )              \ set the cursor shape
  1634.                 MOV CX, BX
  1635.                 MOV AH, # 1
  1636.                 PUSH SI         PUSH BP
  1637.                 INT $10
  1638.                 POP BP          POP SI
  1639.                 LOAD_TTOS
  1640.                 RET             END-ICODE
  1641.  
  1642. : GET-CURSOR    ( --- shape )           \ get the cursor shape
  1643.                 0 $460 @L ;                     NO-INTERPRET
  1644.  
  1645. : INIT-CURSOR   ( -- )
  1646.                 GET-CURSOR SAVECUR ! ;                  NO-INTERPRET
  1647.  
  1648. : CURSOR-OFF    ( --- )
  1649.                 GET-CURSOR $2000  OR SET-CURSOR ;       NO-INTERPRET
  1650.  
  1651. : CURSOR-ON     ( --- )
  1652.                 GET-CURSOR $0F0F AND SET-CURSOR ;       NO-INTERPRET
  1653.  
  1654. : NORM-CURSOR   ( --- )
  1655.                 SAVECUR C@ DUP 1- FLIP + SET-CURSOR ;   NO-INTERPRET
  1656.  
  1657. : BIG-CURSOR    ( --- )
  1658.                 SAVECUR C@ SET-CURSOR ;                 NO-INTERPRET
  1659.  
  1660. : SAVECURSOR    ( -- )          \ save all of the current cursor stuff
  1661.                 R>
  1662.                 ATTRIB @ >R            \ save attribute
  1663.                 GET-CURSOR >R           \ cursor shape
  1664.                 #OUT @ #LINE @ 2>R    \ and position
  1665.                 >R ;                                    NO-INTERPRET
  1666.  
  1667. : RESTCURSOR    ( -- )          \ restore all of the cursor stuff
  1668.                 R>
  1669.                 2R> AT                  \ restore position
  1670.                 R> SET-CURSOR           \ shape
  1671.                 R> ATTRIB !             \ and attribute
  1672.                 >R ;                                    NO-INTERPRET
  1673.  
  1674. ICODE BDOS2     ( CX DX AL -- CX DX AX )
  1675.                 MOV AX, BX
  1676.                 MOV DX, 0 [SI]
  1677.                 MOV CX, 2 [SI]
  1678.                 MOV AH, AL      INT $21
  1679.                 MOV BX, AX
  1680.                 MOV 0 [SI], DX
  1681.                 MOV 2 [SI], CX
  1682.                 RET             END-ICODE
  1683.  
  1684. : OS2           BDOS2 255 AND ;                         NO-INTERPRET
  1685.  
  1686. ICODE BDOS      ( DX AH -- AL )
  1687.                 LODSW
  1688.                 MOV DX, AX
  1689.                 MOV AH, BL
  1690.                 INT $21
  1691.                 SUB AH, AH
  1692.                 MOV BX, AX
  1693.                 RET             END-ICODE
  1694.  
  1695. : DOSVER        ( -- n1 )
  1696.                 0 $030 BDOS $0FF AND ;                  NO-INTERPRET
  1697.  
  1698. : BYE           ( -- )
  1699.                 0 0 BDOS DROP ;                         EXECUTES> BYE
  1700.  
  1701. : DOSEMIT       ( c1 -- )
  1702.                 6 BDOS DROP #OUT INCR ;                 NO-INTERPRET
  1703.  
  1704. ICODE PR-STATUS ( n1 -- b1 )
  1705.                 MOV DX, BX      \ PRINTER NUMBER
  1706.                 MOV AH, # 2
  1707.                 PUSH SI         PUSH BP
  1708.                 INT $17
  1709.                 POP BP          POP SI
  1710.                 MOV BL, AH
  1711.                 SUB BH, BH
  1712.                 RET             END-ICODE
  1713.  
  1714. : ?PRINTER.READY ( -- f1 )
  1715.                 0 PR-STATUS ( $090 AND ) $090 = ;       NO-INTERPRET
  1716.  
  1717. ICODE PEMIT     ( c1 -- )
  1718.                 MOV DX, # 0     \ PRINTER NUMBER
  1719.                 MOV AL, BL
  1720.                 MOV AH, # 0
  1721.                 PUSH SI         PUSH BP
  1722.                 INT $17
  1723.                 POP BP          POP SI
  1724.                 LOAD_TTOS
  1725.                 RET             END-ICODE
  1726.  
  1727. ICODE KEY?      ( -- f1 )               \ BIOS KEY?, NO redirection!
  1728.                 DEC SI
  1729.                 DEC SI
  1730.                 MOV 0 [SI], BX
  1731.                 MOV AH, # 1
  1732.                 PUSH SI         PUSH BP
  1733.                 INT $16
  1734.                 POP BP          POP SI
  1735.                 [ASM96]
  1736.              0= IF      SUB AX, AX
  1737.                 ELSE    MOV AX, # -1
  1738.                 THEN
  1739.                 MOV BX, AX
  1740.                 RET             END-ICODE
  1741.  
  1742. : BDOSKEY?      ( -- c1 )               \ DOS KEY?, redirectable
  1743.                 255 6 BDOS $FF AND ;            NO-INTERPRET
  1744.  
  1745. : BDOSKEY       ( -- c1 )               \ DOS KEY, redirectable, RAW
  1746.                 0 7 BDOS $FF AND ;              NO-INTERPRET
  1747.  
  1748. : %KEY          ( -- c1 )               \ DOS KEY, redirectable, translates
  1749.                 BDOSKEY ?DUP 0=         \ function keys to above 128.
  1750.                 IF      BDOSKEY 128 OR
  1751.                 THEN    ;                       NO-INTERPRET
  1752.  
  1753. DEFER KEY
  1754. DEFER EMIT
  1755. DEFER TYPE
  1756. DEFER SPACES
  1757.  
  1758. : SPACE         ( -- )
  1759.                 BL EMIT ;                       EXECUTES> SPACE
  1760.  
  1761. : %SPACES       ( n1 -- )
  1762.                 0 MAX   ?DUP
  1763.                 IF      1-
  1764.                         FOR BL EMIT NEXT
  1765.                 THEN    ;                       NO-INTERPRET
  1766.  
  1767. : %TYPE         ( a1 n1 -- )
  1768.                 0 MAX   ?DUP
  1769.                 IF      1-
  1770.                         FOR     DUP C@ EMIT 1+
  1771.                         NEXT    DROP
  1772.                 ELSE    DROP
  1773.                 THEN    ;                               NO-INTERPRET
  1774.  
  1775. : EEOL          ( -- )          \ Erase to end of line
  1776.                 80 #OUT @ - 0MAX SPACES ;               EXECUTES> EEOL
  1777.  
  1778. : CR            ( -- )
  1779.                 $0D DOSEMIT $0A DOSEMIT
  1780.                 #OUT OFF #LINE @ 1+ 24 MIN #LINE ! ;    EXECUTES> CR
  1781.  
  1782. : $>TIB         ( A1 --- )
  1783.                 COUNT DUP #TIB ! TIB SWAP CMOVE >IN OFF ; NO-INTERPRET
  1784.  
  1785. : ?LINE         ( N -- )
  1786.                 AT? DROP +  RMARGIN @ > IF CR LMARGIN @ SPACES THEN ;
  1787.                                                         NO-INTERPRET
  1788. : ?CR           ( -- )
  1789.                 0 ?LINE  ;                              NO-INTERPRET
  1790.  
  1791. : MARGIN_INIT   ( -- )
  1792.                 LMARGIN OFF 64 RMARGIN !        \ default margins
  1793.                 8 TABSIZE ! ;                           NO-INTERPRET
  1794.  
  1795. : ABORT         ( -- )          \ Just leave when we abort
  1796.                 CR BYE ;                                EXECUTES> ABORT
  1797.  
  1798. : ?ABORT"       ( f1 a1 n1 -- ) \ display string a1,n1 & abort if f1 true
  1799.                 ROT
  1800.                 IF      TYPE ABORT
  1801.                 ELSE    2DROP
  1802.                 THEN    ;
  1803.  
  1804. : MS            ( n1 -- )       \ Delay n1 units of about a millisecond.
  1805.                 FOR     FUDGE @ 1+ FOR NEXT
  1806.                 NEXT    ;                               EXECUTES> MS
  1807.  
  1808. FORTH   >FORTH
  1809.  
  1810. : %T."          ( | string" -- )
  1811.                 [COMPILE] T"
  1812.                 ['] TYPE RES_COMP_DEFER ; IMMEDIATE
  1813.  
  1814. ' %T." IS T."                   \ link into defered word
  1815.  
  1816. : %L."          ( | string" -- )
  1817.                 [COMPILE] L"
  1818.                 COMPILE RES_COMP_DEF ['] TYPE X, ; IMMEDIATE
  1819.  
  1820. ' %L." IS L."                   \ link into defered word
  1821.  
  1822. : %TABORT"      ( | string" -- )
  1823.                 [COMPILE] T" ['] ?ABORT" COMP_CALL ; IMMEDIATE
  1824.  
  1825. ' %TABORT" IS TABORT"
  1826.  
  1827. : %LABORT"      ( | string" -- )
  1828.                 [COMPILE] L"
  1829.                 COMPILE <'> COMPILE ?ABORT" COMPILE COMP_CALL ; IMMEDIATE
  1830.  
  1831. ' %LABORT" IS LABORT"
  1832.  
  1833. TARGET  >LIBRARY
  1834.  
  1835.  
  1836. ICODE [']       ( -- a1 )       \ get address of routine following this one
  1837.                 DEC SI
  1838.                 DEC SI
  1839.                 MOV 0 [SI], BX
  1840.                 POP BX          \ get address where we came from
  1841.                 INC BX
  1842.                 MOV AX, BX
  1843.                 INC AX
  1844.                 INC AX
  1845.                 PUSH AX         \ push adjusted return address on return stk
  1846.                 ADD AX, CS: 0 [BX]
  1847.                 MOV BX, AX      \ BX holds address of routine following
  1848.                 RET             END-ICODE
  1849.  
  1850.  
  1851. : TAB           ( -- )
  1852.                 AT? DROP TABSIZE @ MOD TABSIZE @ SWAP - SPACES ;
  1853.                                                         EXECUTES> TAB
  1854.  
  1855. : BEEP          ( -- )
  1856.                 7 DOSEMIT #OUT DECR ;                   EXECUTES> BEEP
  1857.  
  1858. : HOLD          ( char -- )
  1859.                 HLD DECR HLD @ C!   ;                   NO-INTERPRET
  1860.  
  1861. : <#            ( -- )
  1862.                 PAD  HLD  !  ;                          NO-INTERPRET
  1863.  
  1864. : #>            ( d# -- addr len )
  1865.                 2DROP  HLD  @  PAD  OVER  -  ;          NO-INTERPRET
  1866.  
  1867. : SIGN          ( n1 -- )
  1868.                 0< IF  ASCII -  HOLD  THEN  ;           NO-INTERPRET
  1869.  
  1870. : #             ( d1 -- d2 )
  1871.                 BASE @ MU/MOD ROT 9 OVER <
  1872.                 IF  7 + THEN ASCII 0  +  HOLD  ;        NO-INTERPRET
  1873.  
  1874. : #S            ( d -- 0 0 )
  1875.                 BEGIN  #  2DUP  OR  0=  UNTIL  ;        NO-INTERPRET
  1876.  
  1877. : (U.)          ( u -- a l )
  1878.                 0    <# #S #>   ;                       NO-INTERPRET
  1879.  
  1880. : U.            ( u -- )
  1881.                 (U.)   TYPE SPACE   ;                   EXECUTES> U.
  1882.  
  1883. : U.R           ( u l -- )
  1884.                 >R   (U.)   R> OVER - SPACES   TYPE   ; EXECUTES> U.R
  1885.  
  1886. : (.)           ( n -- a l )
  1887.                 DUP ABS 0   <# #S   ROT SIGN   #>   ;   NO-INTERPRET
  1888.  
  1889. : .             ( n -- )
  1890.                 (.)   TYPE SPACE   ;                    EXECUTES> .
  1891.  
  1892. : .R            ( n l -- )
  1893.                 >R   (.)   R> OVER - SPACES   TYPE   ;  EXECUTES> .R
  1894.  
  1895. : (UD.)         ( ud -- a l )
  1896.                 <# #S #>   ;                            NO-INTERPRET
  1897.  
  1898. : UD.           ( ud -- )
  1899.                 (UD.)   TYPE SPACE   ;                  NO-INTERPRET
  1900.  
  1901. : UD.R          ( ud l -- )
  1902.                 >R   (UD.)   R> OVER - SPACES   TYPE  ; NO-INTERPRET
  1903.  
  1904. : (D.)          ( d -- a l )
  1905.                 TUCK DABS   <# #S   ROT SIGN  #>   ;    NO-INTERPRET
  1906.  
  1907. : D.            ( d -- )
  1908.                 (D.)   TYPE SPACE   ;                   NO-INTERPRET
  1909.  
  1910. : D.R           ( d l -- )
  1911.                 >R   (D.)   R> OVER - SPACES   TYPE   ; NO-INTERPRET
  1912.  
  1913.  
  1914. : NOOP          ( -- )
  1915.                 ;                                       EXECUTES> NOOP
  1916.  
  1917. : H.R           ( n1 n2 -- )
  1918.                 BASE @ >R HEX U.R R> BASE ! ;
  1919.  
  1920. : H.            ( n1 -- )
  1921.                 1 H.R SPACE ;                           EXECUTES> H.
  1922.  
  1923. : ">$           ( a1 n1 -- a2 )
  1924.                 DROP 1- ;                               NO-INTERPRET
  1925.  
  1926. : U<=           ( u1 u2 -- f )   U> NOT   ;             NO-INTERPRET
  1927. : U>=           ( u1 u2 -- f )   U< NOT   ;             NO-INTERPRET
  1928. : <=            ( n1 n2 -- f )    > NOT   ;             NO-INTERPRET
  1929. : >=            ( n1 n2 -- f )    < NOT   ;             NO-INTERPRET
  1930. : 0>=           ( n1 n2 -- f )   0< NOT   ;             NO-INTERPRET
  1931. : 0<=           ( n1 n2 -- f )   0> NOT   ;             NO-INTERPRET
  1932.  
  1933. : DUMP          ( addr len -- )
  1934.                 0
  1935.                 DO      CR DUP 6 H.R SPACE
  1936.                         15 FOR DUP C@ 3 H.R 1+ NEXT
  1937.             16 +LOOP    DROP   ;                        EXECUTES> DUMP
  1938.  
  1939.  
  1940. ' !> ALIAS =: IMMEDIATE
  1941. ' !> ALIAS IS IMMEDIATE
  1942.  
  1943. comment;
  1944.  
  1945. >FORTH
  1946.  
  1947.