home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / library.seq < prev    next >
Text File  |  1991-04-13  |  91KB  |  2,677 lines

  1. \ LIBRARY.SEQ           Target Library Source           by Tom Zimmer
  2.  
  3. \ ***************************************************************************
  4. \ Target specific words used by the compiler to complete compilation of
  5. \ the the various types of library and target definitions.  These words
  6. \ will need to be re-written when a new traget is being written.
  7.  
  8. \ ***************************************************************************
  9. \                       Target Library words
  10. \ ***************************************************************************
  11.  
  12. >LIBRARY
  13.  
  14. TARGET DEFINITIONS
  15.  
  16. \ ***************************************************************************
  17. \ This macro puts a literal number on the data stack. The instructon
  18. \ sequence used is not optimal, but is likely to be optimized later by the
  19. \ automatic SAVE_BX optimizer.
  20.  
  21. MACRO (LIT)     ( n1 -- )       \ Special macro to compile an inline number
  22.                 SAVE_BX A;      \ to the stack.
  23.                 [FORTH]
  24.                 HERE-T IMM-HERE !
  25.                 [ASSEMBLER]
  26.                 MOV BX, #       END-MACRO       NO-INTERPRET
  27.  
  28. ' (LIT) >EXECUTE IS COMP_SINGLE \ link into number compiler
  29.  
  30. ICODE EXEC:     ( n1 -- )       \ execute the n-th CALL following EXEC:
  31.                                 \ MUST be followed by CALL's, not MACROS
  32.                 MOV AX, BX              \ AX = BX
  33.                 SHL BX, # 1             \ BX * 2
  34.                 ADD AX, BX              \ BX + 1 equals n1*3
  35.                 POP DI                  \ get return address
  36.                 ADD DI, AX              \ offset to desired CALL
  37.                 INC DI                  \ step over the CALL opcode
  38.                 ADD DI, CS: 0 [DI]      \ add relative destination to pointer
  39.                 ADD DI, # 2             \ plus 2 to correct for relative CALL
  40.                 LOAD_BX                 \ reload BX
  41.                 JMP DI  END-ICODE       \ and finally jump to function
  42.  
  43. ICODE BOUNDS    ( n1 n2 --- n3 n4 )  \ Calculate limits used in DO-loop
  44.                 XCHG SI, SP
  45.                 POP AX
  46.                 ADD BX, AX
  47.                 XCHG BX, AX
  48.                 PUSH AX
  49.                 XCHG SI, SP
  50.                 RET             END-ICODE
  51.  
  52. MACRO ?CS:      ( -- cs )       \ where the code is located.
  53.                 SAVE_BX
  54.                 MOV BX, CS      END-MACRO       EXECUTES> ?CS:
  55.  
  56. MACRO ?DS:      ( -- ds )       \ where all of our @(fetch) & !(store) data
  57.                                 \ is located.
  58.                 SAVE_BX
  59.                 MOV BX, DS      END-MACRO       NO-INTERPRET
  60.  
  61. MACRO DS:!      ( ds -- )       \ set DS to the value on the stack
  62.                 MOV DS, BX
  63.                 LOAD_BX         END-MACRO       NO-INTERPRET
  64.  
  65. MACRO DS:->SS:  ( -- )          \ set SS to DS
  66.                 MOV AX, DS
  67.                 MOV SS, AX      END-MACRO
  68.  
  69. MACRO EXIT      ( -- )          \ Terminate a high-level definition
  70.                 RET             END-MACRO       NO-INTERPRET
  71.  
  72. MACRO ?EXIT     ( f1 -- )       \ If boolean f1 is true, exit from definition.
  73.                 LODSW
  74.                 XCHG BX, AX
  75.                 CMP AX, BP
  76.                 [ASSEMBLER]
  77.             0<> IF      RET
  78.                 THEN            END-MACRO       NO-INTERPRET
  79.  
  80. MACRO BEGIN     ( -- )
  81.                 +BR# $:|
  82.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  83.  
  84. MACRO AGAIN     ( -- )          \ an unconditional branch
  85.                 JMP -BR# DUP $  01LAB
  86.                                 END-MACRO       NO-INTERPRET
  87.  
  88. MACRO IF        ( f -- )        \ branch if flag is zero
  89.                 LODSW
  90.                 XCHG BX, AX
  91.                 CMP AX, BP              A;      \ BP ALWAYS EQUALS ZERO
  92.                 ?LONG   [FORTH]
  93.                 IF      [ASSEMBLER]
  94.                         JNZ here 5 +    A;      \ branch around JMP
  95.                         JMP +BR# $ WORD A;
  96.                         [FORTH]
  97.                 ELSE    [ASSEMBLER]
  98.                         JZ +BR# $       A;
  99.                         [FORTH]
  100.                 THEN
  101.                 [ASSEMBLER]     END-MACRO       NO-INTERPRET
  102.  
  103. TARGET ' IF ALIAS WHILE     ( f1 -- )
  104.  
  105. MACRO ELSE      ( -- )
  106.                 ?LONG   [FORTH]
  107.                 IF      [ASSEMBLER]
  108.                         JMP +BR# $ WORD
  109.                         [FORTH]
  110.                 ELSE    [ASSEMBLER]
  111.                         JMP +BR# $
  112.                         [FORTH]
  113.                 THEN    [ASSEMBLER]
  114.                 BR#SWAP
  115.                 -BR# DUP $:| 01LAB
  116.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  117.  
  118. MACRO THEN      ( -- )          \ resolve branch
  119.                 -BR# DUP $:| 01LAB
  120.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  121.  
  122. ' THEN ALIAS ENDIF
  123.  
  124. FORTH   >FORTH
  125.  
  126. 0 VALUE #CASES          \ a CASE counter
  127.  
  128. FORTH
  129.  
  130. : %CASE          ( -- )
  131.                 [FORTH]
  132.                 OFF> #CASES ;
  133.  
  134. FORTH
  135.  
  136. : CASE          ( -- )
  137.                 [FORTH]
  138.                 ?LIB
  139.                 IF      COMPILE %CASE
  140.                 ELSE    %CASE
  141.                 THEN
  142.                 [TARGET]
  143.                 ; IMMEDIATE
  144.  
  145. TARGET  >LIBRARY
  146.  
  147. MACRO OF        ( n1 n2  -- n1 )  ( n1 n2 -- )
  148.                 [FORTH]
  149.                 IMM/ABS_OPT ?DUP
  150.                 IF      0<
  151.                         IF
  152.                                 [ASSEMBLER]
  153.                                 CMP BX, # ( xxxx )
  154.                                 [FORTH]
  155.                         ELSE
  156.                                 [ASSEMBLER]
  157.                                 CMP BX, ( xxxx )
  158.                                 [FORTH]
  159.                         THEN
  160.                 ELSE
  161.                         [ASSEMBLER]
  162.                         LODSW
  163.                         XCHG AX, BX
  164.                         CMP BX, AX
  165.                         [FORTH]
  166.                 THEN
  167.                 INCR> #CASES                    \ bump number of cases
  168.                 ?LONG
  169.                 IF      [ASSEMBLER]
  170.                         JZ here 5 +     A;      \ branch around JMP
  171.                         JMP +BR# $ WORD A;
  172.                         [FORTH]
  173.                 ELSE    [ASSEMBLER]
  174.                         JNZ +BR# $       A;
  175.                         [FORTH]
  176.                 THEN
  177.                 [ASSEMBLER]
  178.                 LOAD_BX         END-MACRO       NO-INTERPRET
  179.  
  180. MACRO ENDOF     ( -- )
  181.                 JMP +BR# $ WORD
  182.                 BR#SWAP
  183.                 -BR# DUP $:| 01LAB
  184.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  185.  
  186. MACRO ENDCASE   ( -- )          \ resolve branch
  187.                 [FORTH]
  188.                 SAVE> ?LONG             \ save current branch length flag
  189.                 LONG_BRANCH             \ we default to long for ENDCASE
  190.                 #CASES  0               \ resolve #CASES case statments
  191.                 DO      [ASSEMBLER]
  192.                         -BR# DUP $:| 01LAB
  193.                         [FORTH]
  194.                 LOOP
  195.                 OFF> #CASES
  196.                 RESTORE> ?LONG          \ restore branch length flag
  197.                 [ASSEMBLER]
  198.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  199.  
  200. MACRO REPEAT    ( -- )
  201.                 BR#SWAP
  202.                 JMP -BR# DUP $   01LAB
  203.                     -BR# DUP $:| 01LAB
  204.                 END-MACRO                       NO-INTERPRET
  205.  
  206. MACRO UNTIL     ( f1 -- )
  207.                 LODSW
  208.                 XCHG BX, AX
  209.                 CMP AX, BP              A;
  210.                 ?LONG
  211.                 [FORTH]
  212.                 IF      [ASSEMBLER]
  213.                         JNZ here 5 +    A;      \ branch around JMP
  214.                         JMP -BR# DUP $ WORD 01LAB A;
  215.                         [FORTH]
  216.                 ELSE    [ASSEMBLER]
  217.                         JZ  -BR# DUP $  01LAB A;
  218.                         [FORTH]
  219.                 THEN
  220.                 [ASSEMBLER]     END-MACRO       NO-INTERPRET
  221.  
  222. MACRO FOR       ( n1 -- )
  223.                 PUSH BX
  224.                 LOAD_BX
  225.                 +BR# $:|
  226.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  227.  
  228. MACRO NEXT      ( -- )
  229.                 POP CX
  230.                 [ASSEMBLER]
  231.           CX<>0 IF
  232.                         DEC CX
  233.                         PUSH CX
  234.                         JMP -BR# DUP $  01LAB
  235.                 THEN            END-MACRO       NO-INTERPRET
  236.  
  237. MACRO UNDO      ( --- )
  238.                 ADD SP, # 4     END-MACRO       NO-INTERPRET
  239.  
  240. MACRO DO        ( l i -- )
  241.                 [FORTH]
  242.                 ?DOING   OFF
  243.                 [ASSEMBLER]
  244.                 LODSW
  245.                 ADD AX, # $8000
  246.                 PUSH AX
  247.                 SUB BX, AX
  248.                 PUSH BX
  249.                 LOAD_BX
  250.                 +BR# $:|
  251.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  252.  
  253. MACRO ?DO       ( l i -- )
  254.                 [FORTH]
  255.                 ?DOING   ON
  256.                 [ASSEMBLER]
  257.                 MOV DI, BX
  258.                 LODSW           MOV DX, AX
  259.                 LOAD_BX
  260.                 CMP DX, DI              A;
  261.                 ?LONG   [FORTH]
  262.                 IF      [ASSEMBLER]
  263.                         JNE here 5 +    A;      \ branch around JMP
  264.                         JMP +BR# $ WORD A;
  265.                         [FORTH]
  266.                 ELSE    [ASSEMBLER]
  267.                         JE +BR# $       A;
  268.                         [FORTH]
  269.                 THEN    [ASSEMBLER]
  270.                 ADD DX, # $8000
  271.                 PUSH DX
  272.                 SUB DI, DX
  273.                 PUSH DI
  274.                 +BR# $:|
  275.                 OPT_OFF1        END-MACRO       NO-INTERPRET
  276.  
  277. MACRO (LOOP)    ( -- )
  278.                 MOV DI, SP
  279.                 INC 0 [DI] WORD                 A;
  280.                 ?LONG
  281.                 [FORTH]
  282.                 IF      [ASSEMBLER]
  283.                         JO here 5 +             A;      \ branch around JMP
  284.                         JMP -BR# DUP $ WORD 01LAB   A;
  285.                         [FORTH]
  286.                 ELSE    [ASSEMBLER]
  287.                         JNO -BR# DUP $  01LAB   A;
  288.                         [FORTH]
  289.                 THEN
  290.                 [ASSEMBLER]     END-MACRO       NO-INTERPRET
  291.  
  292. MACRO (+LOOP)   ( n -- )
  293.                 LODSW
  294.                 XCHG BX, AX
  295.                 MOV DI, SP
  296.                 ADD 0 [DI], AX                  A;
  297.                 ?LONG
  298.                 [FORTH]
  299.                 IF      [ASSEMBLER]
  300.                         JO here 5 +             A;      \ branch around JMP
  301.                         JMP -BR# DUP $ WORD 01LAB   A;
  302.                         [FORTH]
  303.                 ELSE    [ASSEMBLER]
  304.                         JNO -BR# DUP $  01LAB   A;
  305.                         [FORTH]
  306.                 THEN
  307.                 [ASSEMBLER]     END-MACRO       NO-INTERPRET
  308.  
  309. MACRO DO?       ( -- )
  310.                 -BR# DUP $:| 01LAB
  311.                 [FORTH]
  312.                 ?DOING OFF      END-MACRO       NO-INTERPRET
  313.  
  314. MACRO LEAVE?    ( -- )
  315.                 20 DUP $:| 01LAB
  316.                 [FORTH]
  317.                 ?LEAVING DECR   END-MACRO       NO-INTERPRET
  318.  
  319. FORTH   >FORTH
  320.  
  321. : %LOOP         ( -- )
  322.                 F['] (LOOP) >EXECUTE EXECUTE
  323.                 [FORTH]
  324.                 ?LEAVING @
  325.                 IF      F['] LEAVE? >EXECUTE EXECUTE
  326.                 THEN
  327.                 [TARGET]
  328.                 F['] UNDO >EXECUTE EXECUTE
  329.                 [FORTH]
  330.                 ?DOING @
  331.                 IF      F['] DO? >EXECUTE EXECUTE
  332.                 THEN
  333.                 [TARGET]
  334.                 ;
  335.  
  336. FORTH
  337.  
  338. : LOOP          ( -- )
  339.                 [FORTH]
  340.                 ?LIB
  341.                 IF      COMPILE %LOOP
  342.                 ELSE    %LOOP
  343.                 THEN
  344.                 [TARGET]
  345.                 ; IMMEDIATE
  346.  
  347. FORTH
  348.  
  349. : %+LOOP        ( -- )
  350.                 F['] (+LOOP) >EXECUTE EXECUTE
  351.                 [FORTH]
  352.                 ?LEAVING @
  353.                 IF      F['] LEAVE? >EXECUTE EXECUTE
  354.                 THEN
  355.                 [TARGET]
  356.                 F['] UNDO >EXECUTE EXECUTE
  357.                 [FORTH]
  358.                 ?DOING @
  359.                 IF      F['] DO? >EXECUTE EXECUTE
  360.                 THEN
  361.                 [TARGET]
  362.                 ;
  363.  
  364. FORTH
  365.  
  366. : +LOOP         ( -- )
  367.                 [FORTH]
  368.                 ?LIB
  369.                 IF      COMPILE %+LOOP
  370.                 ELSE    %+LOOP
  371.                 THEN
  372.                 [TARGET]
  373.                 ; IMMEDIATE
  374.  
  375. TARGET  >LIBRARY
  376.  
  377. MACRO LEAVE     ( -- )
  378.                 [FORTH] ?LEAVING INCR [ASSEMBLER]
  379.                 JMP 20 $         END-MACRO       NO-INTERPRET
  380.  
  381. MACRO ?LEAVE    ( f -- )
  382.                 [FORTH] ?LEAVING INCR [ASSEMBLER]
  383.                 LODSW
  384.                 XCHG BX, AX
  385.                 OR AX, AX                       A;
  386.                 ?LONG
  387.                 [FORTH]
  388.                 IF      [ASSEMBLER]
  389.                         JE here 5 +             A;      \ branch around JMP
  390.                         JMP 20 $  WORD          A;
  391.                         [FORTH]
  392.                 ELSE    [ASSEMBLER]
  393.                         JNE 20 $                A;
  394.                         [FORTH]
  395.                 THEN
  396.                 [ASSEMBLER]     END-MACRO       NO-INTERPRET
  397.  
  398. MACRO I        ( -- n )
  399.                 SAVE_BX
  400.                 MOV DI, SP
  401.                 MOV BX, 0 [DI]
  402.                 ADD BX, 2 [DI]  END-MACRO       NO-INTERPRET
  403.  
  404. MACRO J         ( -- n )
  405.                 SAVE_BX
  406.                 MOV DI, SP
  407.                 MOV BX, 4 [DI]
  408.                 ADD BX, 6 [DI]  END-MACRO       NO-INTERPRET
  409.  
  410. MACRO K         ( -- n )
  411.                 SAVE_BX
  412.                 MOV DI, SP
  413.                 MOV BX,  8 [DI]
  414.                 ADD BX, 10 [DI] END-MACRO       NO-INTERPRET
  415.  
  416. MACRO EXECUTE   ( cfa -- )
  417.                 [FORTH]
  418.                 IMM/ABS_OPT ?DUP
  419.                 IF      0<
  420.                         IF                      \ Immediate
  421.                                 [ASSEMBLER]
  422.                                 CALL ( xxxx )
  423.                                 [FORTH]
  424.                         ELSE                    \ absolute
  425.                                 [ASSEMBLER]
  426.                                 CALL [] ( xxxx )
  427.                                 [FORTH]
  428.                         THEN
  429.                 ELSE
  430.                         [ASSEMBLER]
  431.                         LODSW
  432.                         XCHG BX, AX
  433.                         CALL AX
  434.                         [FORTH]
  435.                 THEN
  436.                 [TARGET]        END-MACRO       NO-INTERPRET
  437.  
  438. MACRO PERFORM   ( addr-of-cfa -- )
  439.                 [FORTH]
  440.                 IMM/ABS_OPT ?DUP
  441.                 IF      0<
  442.                         IF
  443.                                 [ASSEMBLER]
  444.                                 CALL [] ( xxxx )
  445.                                 [FORTH]
  446.                         ELSE
  447.                                 [ASSEMBLER]
  448.                                 MOV DI, ( xxxx )
  449.                                 MOV AX, 0 [DI]
  450.                                 CALL AX
  451.                                 [FORTH]
  452.                         THEN
  453.                 ELSE
  454.                         [ASSEMBLER]
  455.                         LODSW
  456.                         XCHG BX, AX
  457.                         MOV DI, AX
  458.                         MOV AX, 0 [DI]
  459.                         CALL AX
  460.                         [FORTH]
  461.                 THEN
  462.                 [TARGET]        END-MACRO       NO-INTERPRET
  463.  
  464. ' PERFORM >EXECUTE IS COMP_PERFORM      \ link into compiler
  465.  
  466. MACRO @         ( addr -- n )
  467.                 AT_OPT          END-MACRO       EXECUTES> @-D
  468.  
  469. ' @ >EXECUTE IS COMP_FETCH              \ link into compiler
  470.  
  471. MACRO !         ( n addr -- )
  472.                 STORE_OPT
  473.                 LOAD_BX
  474.                 STORE_OPT2
  475.                 STORE_OPT3      END-MACRO       EXECUTES> !-D
  476.  
  477. ' ! >EXECUTE IS COMP_STORE      \ link to compiler
  478.  
  479. MACRO %SAVE>R   ( a1 -- )
  480.                 MOV BX, 0 [BX]
  481.                 PUSH BX
  482.                 LOAD_BX         END-MACRO       NO-INTERPRET
  483.  
  484. ' %SAVE>R >EXECUTE IS COMP_SAVE
  485.  
  486. MACRO %SAVE!>R  ( n1 a1 -- )
  487.                 MOV DI, BX
  488.                 MOV DI, 0 [DI]
  489.                 PUSH DI
  490.                 LODSW
  491.                 MOV 0 [BX], AX
  492.                 LOAD_BX         END-MACRO       NO-INTERPRET
  493.  
  494. ' %SAVE!>R >EXECUTE IS COMP_SAVEST
  495.  
  496. MACRO %R>REST   ( a1 -- )
  497.                 POP AX
  498.                 MOV 0 [BX], AX
  499.                 LOAD_BX         END-MACRO       NO-INTERPRET
  500.  
  501. ' %R>REST >EXECUTE IS COMP_REST
  502.  
  503. ICODE @L        ( seg addr -- word )
  504.                 MOV DX, ES
  505.                 LODSW
  506.                 MOV ES, AX
  507.                 MOV BX, ES: 0 [BX]
  508.                 MOV ES, DX
  509.                 RET             END-ICODE
  510.  
  511. ICODE C@L       ( seg addr -- byte )
  512.                 MOV DX, ES
  513.                 LODSW
  514.                 MOV ES, AX
  515.                 MOV BL, ES: 0 [BX]
  516.                 MOV ES, DX
  517.                 SUB BH, BH
  518.                 RET             END-ICODE
  519.  
  520. ICODE C!L       ( byte seg addr -- )
  521.                 MOV DX, ES
  522.                 LODSW           MOV ES, AX
  523.                 LODSW
  524.                 MOV ES: 0 [BX], AL
  525.                 MOV ES, DX
  526.                 LOAD_BX
  527.                 RET             END-ICODE
  528.  
  529. ICODE !L        ( n1 seg addr -- )
  530.                 MOV DX, ES
  531.                 LODSW           MOV ES, AX
  532.                 LODSW
  533.                 MOV ES: 0 [BX], AX
  534.                 MOV ES, DX
  535.                 LOAD_BX
  536.                 RET             END-ICODE
  537.  
  538. MACRO C@        ( addr -- char )
  539.                 CAT_OPT
  540.                 SUB BH, BH      END-MACRO       EXECUTES> C@-D
  541.  
  542. MACRO C!        ( char addr -- )
  543.                 CSTORE_OPT
  544.                 LOAD_BX         END-MACRO       EXECUTES> C!-D
  545.  
  546. ICODE CMOVE     (  from to count -- )
  547.                 MOV CX, BX
  548.                 LODSW           MOV DI, AX
  549.                 LODSW           MOV BX, SI      MOV SI, AX
  550.                 MOV DX, ES      MOV AX, DS      MOV ES, AX
  551.                 REPNZ           MOVSB
  552.                 MOV SI, BX      MOV ES, DX
  553.                 LOAD_BX
  554.                 RET             END-ICODE
  555.  
  556. ICODE CMOVE>    ( from to count -- )
  557.                 MOV CX, BX      DEC CX
  558.                 LODSW           MOV DI, AX
  559.                 LODSW           MOV BX, SI      MOV SI, AX
  560.                 ADD DI, CX      ADD IP, CX      INC CX
  561.                 MOV DX, ES      MOV AX, DS      MOV ES, AX
  562.                 STD
  563.                 REPNZ           MOVSB
  564.                 CLD
  565.                 MOV SI, BX      MOV ES, DX
  566.                 LOAD_BX
  567.                 RET             END-ICODE
  568.  
  569. ICODE PLACE     ( from cnt to -- )
  570.                 MOV DI, BX
  571.                 LODSW           MOV CX, AX
  572.                 LODSW           XCHG AX, SI
  573.                 MOV 0 [DI], CL
  574.                 INC DI
  575.                 CLD
  576.                 MOV DX, ES
  577.                 MOV BX, DS      MOV ES, BX
  578.                 REPNZ           MOVSB
  579.                 MOV SI, AX
  580.                 MOV ES, DX
  581.                 LOAD_BX
  582.                 RET             END-ICODE
  583.  
  584. ICODE +PLACE    ( from cnt to -- )      \ append text to counted string
  585.                 MOV DI, BX
  586.                 LODSW           MOV CX, AX
  587.                 LODSW
  588.                 PUSH ES
  589.                 XCHG AX, SI
  590.                 SUB DX, DX
  591.                 MOV DL, 0 [DI]          \ pick up current length
  592.                 ADD 0 [DI], CL          \ adj current length plus cnt
  593.                 INC DI                  \ step to text start
  594.                 ADD DI, DX              \ adjust to current text end
  595.                 CLD
  596.                 MOV BX, DS      MOV ES, BX
  597.                 REPNZ           MOVSB   \ append the text
  598.                 MOV SI, AX
  599.                 POP ES
  600.                 LOAD_BX
  601.                 RET             END-ICODE
  602.  
  603. CODE DEPTH      ( -- n1 )
  604.                 SAVE_BX
  605.                 MOV BX, SP0
  606.                 SUB BX, SI
  607.                 SAR BX, # 1
  608.                 DEC BX
  609.                 RET             END-CODE        EXECUTES> DEPTH
  610.  
  611. MACRO TIB       ( -- a1 )       \ Terminal Input Buffer address above stack
  612.                 SAVE_BX
  613.                 MOV BX, 'TIB    END-MACRO       EXECUTES> TIB
  614.  
  615. MACRO SP@       ( -- n )
  616.                 SAVE_BX
  617.                 MOV BX, SI      END-MACRO       NO-INTERPRET
  618.  
  619. MACRO SP!       ( n -- )
  620.                 MOV SI, BX
  621.                 SUB BX, BX      END-MACRO       NO-INTERPRET
  622.  
  623. MACRO RP@       ( -- addr )
  624.                 SAVE_BX
  625.                 MOV BX, SP      END-MACRO       NO-INTERPRET
  626.  
  627. MACRO RP!       ( n -- )
  628.                 MOV SP, BX
  629.                 LOAD_BX         END-MACRO       NO-INTERPRET
  630.  
  631. MACRO DROP      ( n1 -- )
  632.                 LOAD_BX         END-MACRO       EXECUTES> DROP
  633.  
  634. MACRO DUP       ( n1 -- n1 n1 )
  635.                 DEC SI
  636.                 DEC SI
  637.                 MOV 0 [SI], BX  END-MACRO       EXECUTES> DUP
  638.  
  639. MACRO SWAP      ( n1 n2 -- n2 n1 )
  640.                 XCHG 0 [SI], BX END-MACRO       EXECUTES> SWAP
  641.  
  642. MACRO OVER      ( n1 n2 -- n1 n2 n1 )
  643.                 SAVE_BX
  644.                 MOV BX, 2 [SI]  END-MACRO       EXECUTES> OVER
  645.  
  646.  
  647. MACRO PLUCK     ( n1 n2 n3 --- n1 n2 n3 n1 )
  648.                 SAVE_BX
  649.                 MOV BX, 4 [SI]  END-MACRO       NO-INTERPRET
  650.  
  651. CODE TUCK       ( n1 n2 -- n2 n1 n2 )
  652.                 LODSW
  653.                 SUB SI, # 4
  654.                 MOV 2 [SI], BX
  655.                 MOV 0 [SI], AX
  656.                 RET             END-CODE        EXECUTES> TUCK
  657.  
  658. MACRO NIP       ( n1 n2 -- n2 )
  659.                 INC SI
  660.                 INC SI          END-MACRO       EXECUTES> NIP
  661.  
  662. CODE ROT        ( n1 n2 n3 --- n2 n3 n1 )
  663.                 XCHG SI, SP
  664.                 POP DX
  665.                 POP AX
  666.                 PUSH DX
  667.                 XCHG BX, AX
  668.                 PUSH AX
  669.                 XCHG SI, SP
  670.                 RET             END-CODE        EXECUTES> ROT
  671.  
  672. CODE -ROT       ( n1 n2 n3 --- n3 n1 n2 )
  673.                 XCHG SI, SP
  674.                 POP AX
  675.                 POP DX
  676.                 XCHG BX, AX
  677.                 PUSH AX
  678.                 PUSH DX
  679.                 XCHG SI, SP
  680.                 RET             END-CODE        EXECUTES> -ROT
  681.  
  682. MACRO FLIP      ( n1 -- n2 )
  683.                 XCHG BL, BH     END-MACRO       EXECUTES> FLIP
  684.  
  685. CODE SPLIT      ( n1 --- n2 n3 )
  686.                 MOV AX, BX
  687.                 SUB AH, AH
  688.                 DEC SI
  689.                 DEC SI
  690.                 MOV 0 [SI], AX
  691.                 MOV BL, BH
  692.                 MOV BH, AH
  693.                 RET             END-CODE        EXECUTES> SPLIT
  694.  
  695. MACRO ?DUP      ( n1 -- [n1] n1 )
  696.                 MOV CX, BX
  697.                 [ASSEMBLER]
  698.           CX<>0 IF      DEC SI
  699.                         DEC SI
  700.                         MOV 0 [SI], BX
  701.                 THEN            END-MACRO       EXECUTES> ?DUP
  702.  
  703. MACRO R>        ( -- n )
  704.                 SAVE_BX
  705.                 POP BX          END-MACRO       NO-INTERPRET
  706.  
  707. IMACRO R>DROP   ( --- )
  708.                 ADD SP, # 2     END-IMACRO
  709.  
  710. IMACRO DUP>R    ( n1 --- n1 )
  711.                 PUSH BX         END-IMACRO
  712.  
  713. IMACRO >R       ( n -- )
  714.                 PUSH BX
  715.                 LOAD_BX         END-IMACRO
  716.  
  717. IMACRO 2R>      ( -- n1 n2 )
  718.                 SUB SI, # 4
  719.                 MOV 2 [SI], BX
  720.                 POP BX
  721.                 POP AX
  722.                 MOV 0 [SI], AX  END-IMACRO
  723.  
  724. IMACRO 2>R      ( n1 n2 -- )
  725.                 XCHG SI, SP
  726.                 SUB SI, # 4
  727.                 MOV 0 [SI], BX
  728.                 POP 2 [SI]
  729.                 POP BX
  730.                 XCHG SI, SP     END-IMACRO
  731.  
  732. IMACRO R@       ( -- n )
  733.                 XCHG SI, SP
  734.                 PUSH BX
  735.                 MOV BX, 0 [SI]
  736.                 XCHG SI, SP     END-IMACRO
  737.  
  738. IMACRO 2R@      ( -- n1 n2 )
  739.                 XCHG SI, SP
  740.                 PUSH BX
  741.                 PUSH 2 [SI]
  742.                 MOV BX, 0 [SI]
  743.                 XCHG SI, SP     END-IMACRO
  744.  
  745. MACRO PICK      ( nm ... n2 n1 k -- nm ... n2 n1 nk )
  746.                 SHL BX, # 1
  747.                 ADD BX, SI
  748.                 MOV BX, 0 [BX]  END-MACRO       NO-INTERPRET
  749.  
  750. IMACRO RPICK    ( nm ... n2 n1 k -- nm ... n2 n1 nk )
  751.                 SHL BX, # 1
  752.                 ADD BX, SP
  753.                 MOV BX, 0 [BX]  END-IMACRO
  754.  
  755. MACRO AND       ( n1 n2 -- n3 )
  756.                 [FORTH]
  757.                 IMM/ABS_OPT ?DUP
  758.                 IF      0<
  759.                         IF
  760.                                 [ASSEMBLER]
  761.                                 AND BX, # ( xxxx )
  762.                                 [FORTH]
  763.                         ELSE
  764.                                 [ASSEMBLER]
  765.                                 AND BX, ( xxxx )
  766.                                 [FORTH]
  767.                         THEN
  768.                 ELSE
  769.                         [ASSEMBLER]
  770.                         LODSW
  771.                         AND BX, AX
  772.                         [FORTH]
  773.                 THEN
  774.                 [TARGET]        END-MACRO       EXECUTES> AND
  775.  
  776. MACRO OR        ( n1 n2 -- n3 )
  777.                 [FORTH]
  778.                 IMM/ABS_OPT ?DUP
  779.                 IF      0<
  780.                         IF
  781.                                 [ASSEMBLER]
  782.                                 OR BX, # ( xxxx )
  783.                                 [FORTH]
  784.                         ELSE
  785.                                 [ASSEMBLER]
  786.                                 OR BX, ( xxxx )
  787.                                 [FORTH]
  788.                         THEN
  789.                 ELSE
  790.                         [ASSEMBLER]
  791.                         LODSW
  792.                         OR BX, AX
  793.                         [FORTH]
  794.                 THEN
  795.                 [TARGET]        END-MACRO       EXECUTES> OR
  796.  
  797. MACRO NOT       ( n -- n' )
  798.                 NOT BX          END-MACRO       EXECUTES> NOT
  799.  
  800. IMACRO CSET     ( b addr -- )
  801.                 LODSW
  802.                 OR 0 [BX], AL
  803.                 LOAD_BX         END-IMACRO
  804.  
  805. IMACRO CRESET   ( b addr -- )
  806.                 LODSW
  807.                 NOT AX
  808.                 AND 0 [BX], AL
  809.                 LOAD_BX         END-IMACRO
  810.  
  811. IMACRO CTOGGLE  ( b addr -- )
  812.                 LODSW
  813.                 XOR 0 [BX], AL
  814.                 LOAD_BX         END-IMACRO
  815.  
  816. MACRO ON        ( addr -- )
  817.                 [FORTH]
  818.                 IMM/ABS_OPT ?DUP
  819.                 IF      0<
  820.                         IF
  821.                                 [ASSEMBLER]
  822.                                 MOV ( xxxx ) # TRUE WORD
  823.                                 [FORTH]
  824.                         ELSE
  825.                                 [ASSEMBLER]
  826.                                 MOV DI, ( xxxx )
  827.                                 MOV 0 [DI], # TRUE WORD
  828.                                 [FORTH]
  829.                         THEN
  830.                 ELSE
  831.                         [ASSEMBLER]
  832.                         MOV 0 [BX], # TRUE WORD
  833.                         LOAD_BX
  834.                         [FORTH]
  835.                 THEN
  836.                 [TARGET]        END-MACRO       NO-INTERPRET
  837.  
  838. ' ON  >EXECUTE IS COMP_ON         \ link to compiler
  839.  
  840. MACRO OFF       ( addr -- )
  841.                 [FORTH]
  842.                 IMM/ABS_OPT ?DUP
  843.                 IF      0<
  844.                         IF
  845.                                 [ASSEMBLER]
  846.                                 MOV ( xxxx ) BP
  847.                                 [FORTH]
  848.                         ELSE
  849.                                 [ASSEMBLER]
  850.                                 MOV DI, ( xxxx )
  851.                                 MOV 0 [DI], BP
  852.                                 [FORTH]
  853.                         THEN
  854.                 ELSE
  855.                         [ASSEMBLER]
  856.                         MOV 0 [BX], BP          \ BP is always FALSE
  857.                         LOAD_BX
  858.                         [FORTH]
  859.                 THEN
  860.                 [TARGET]        END-MACRO       NO-INTERPRET
  861.  
  862. ' OFF >EXECUTE IS COMP_OFF        \ link to compiler
  863.  
  864. MACRO INCR      ( addr --- )
  865.                 [FORTH]
  866.                 IMM/ABS_OPT ?DUP
  867.                 IF      0<
  868.                         IF
  869.                                 [ASSEMBLER]
  870.                                 INC ( xxxx ) WORD
  871.                                 [FORTH]
  872.                         ELSE
  873.                                 [ASSEMBLER]
  874.                                 MOV DI, ( xxxx )
  875.                                 INC 0 [DI] WORD
  876.                                 [FORTH]
  877.                         THEN
  878.                 ELSE
  879.                         [ASSEMBLER]
  880.                         INC 0 [BX] WORD
  881.                         LOAD_BX
  882.                         [FORTH]
  883.                 THEN
  884.                 [TARGET]        END-MACRO       NO-INTERPRET
  885.  
  886. ' INCR >EXECUTE IS COMP_INCR       \ link to compiler
  887.  
  888. MACRO DECR      ( addr --- )
  889.                 [FORTH]
  890.                 IMM/ABS_OPT ?DUP
  891.                 IF      0<
  892.                         IF
  893.                                 [ASSEMBLER]
  894.                                 DEC ( xxxx ) WORD
  895.                                 [FORTH]
  896.                         ELSE
  897.                                 [ASSEMBLER]
  898.                                 MOV DI, ( xxxx )
  899.                                 DEC 0 [DI] WORD
  900.                                 [FORTH]
  901.                         THEN
  902.                 ELSE
  903.                         [ASSEMBLER]
  904.                         DEC 0 [BX] WORD
  905.                         LOAD_BX
  906.                         [FORTH]
  907.                 THEN
  908.                 [TARGET]        END-MACRO       NO-INTERPRET
  909.  
  910. ' DECR >EXECUTE IS COMP_DECR       \ link to compiler
  911.  
  912. MACRO +         ( n1 n2 -- sum )
  913.                 [FORTH]
  914.                 IMM/ABS_OPT ?DUP
  915.                 IF      0<
  916.                         IF
  917.                                 [ASSEMBLER]
  918.                                 ADD BX, # ( xxxx )
  919.                                 [FORTH]
  920.                         ELSE
  921.                                 [ASSEMBLER]
  922.                                 ADD BX, ( xxxx )
  923.                                 [FORTH]
  924.                         THEN
  925.                 ELSE
  926.                         [ASSEMBLER]
  927.                         LODSW
  928.                         ADD BX, AX
  929.                         [FORTH]
  930.                 THEN
  931.                 [TARGET]        END-MACRO       EXECUTES> +
  932.  
  933.  
  934. MACRO NEGATE    ( n -- n' )
  935.                 NEG BX          END-MACRO       EXECUTES> NEGATE
  936.  
  937. MACRO -         ( n1 n2 -- n1-n2 )
  938.                 [FORTH]
  939.                 IMM/ABS_OPT ?DUP
  940.                 IF      0<
  941.                         IF
  942.                                 [ASSEMBLER]
  943.                                 SUB BX, # ( xxxx )
  944.                                 [FORTH]
  945.                         ELSE
  946.                                 [ASSEMBLER]
  947.                                 SUB BX, ( xxxx )
  948.                                 [FORTH]
  949.                         THEN
  950.                 ELSE
  951.                         [ASSEMBLER]
  952.                         LODSW
  953.                         SUB AX, BX
  954.                         MOV BX, AX
  955.                         [FORTH]
  956.                 THEN
  957.                 [TARGET]        END-MACRO       EXECUTES> -
  958.  
  959. MACRO ABS       ( n1 -- n2 )
  960.                 MOV AX, BX
  961.                 CWD
  962.                 XOR AX, DX
  963.                 SUB AX, DX
  964.                 MOV BX, AX      END-MACRO       EXECUTES> ABS
  965.  
  966. ICODE D+!       ( d addr -- )
  967.                 XCHG SI, SP
  968.                 POP AX          POP DX
  969.                 ADD 2 [BX], DX
  970.                 ADC 0 [BX], AX
  971.                 POP BX
  972.                 XCHG SI, SP
  973.                 RET             END-ICODE
  974.  
  975. MACRO +!        ( n addr -- )
  976.                 [FORTH]
  977.                 IMM/ABS_OPT ?DUP
  978.                 IF      0<
  979.                         IF
  980.                                 [ASSEMBLER]
  981.                                 ADD ( xxxx ) BX
  982.                                 [FORTH]
  983.                         ELSE
  984.                                 [ASSEMBLER]
  985.                                 MOV DI, ( xxxx )
  986.                                 ADD 0 [DI], BX
  987.                                 [FORTH]
  988.                         THEN
  989.                 ELSE
  990.                         [ASSEMBLER]
  991.                         LODSW
  992.                         ADD 0 [BX], AX
  993.                         [FORTH]
  994.                 THEN
  995.                 LOAD_BX
  996.                 [TARGET]        END-MACRO       NO-INTERPRET
  997.  
  998. ' +!   >EXECUTE IS COMP_PSTORE     \ link to compiler
  999.  
  1000. MACRO C+!       ( n addr -- )
  1001.                 [FORTH]
  1002.                 IMM/ABS_OPT ?DUP
  1003.                 IF      0<
  1004.                         IF
  1005.                                 [ASSEMBLER]
  1006.                                 ADD ( xxxx ) BL
  1007.                                 [FORTH]
  1008.                         ELSE
  1009.                                 [ASSEMBLER]
  1010.                                 MOV DI, ( xxxx )
  1011.                                 ADD 0 [DI], BL
  1012.                                 [FORTH]
  1013.                         THEN
  1014.                 ELSE
  1015.                         [ASSEMBLER]
  1016.                         LODSW
  1017.                         ADD 0 [BX], AL
  1018.                         [FORTH]
  1019.                 THEN
  1020.                 LOAD_BX         END-MACRO       NO-INTERPRET
  1021.  
  1022. MACRO PC@       ( port# -- n )
  1023.                 IMM_BEFORE
  1024.                 [FORTH]
  1025.                 IF      DUP 255 >
  1026.                         IF
  1027.                                 [ASSEMBLER]
  1028.                                 MOV DX, # ( xxxx )
  1029.                                 IN AL, DX
  1030.                                 [FORTH]
  1031.                         ELSE
  1032.                                 [ASSEMBLER]
  1033.                                 IN AL, # ( xxxx )
  1034.                                 [FORTH]
  1035.                         THEN
  1036.                 ELSE
  1037.                         [ASSEMBLER]
  1038.                         MOV DX, BX
  1039.                         IN AL, DX
  1040.                         [FORTH]
  1041.                 THEN
  1042.                 [ASSEMBLER]
  1043.                 SUB AH, AH
  1044.                 MOV BX, AX
  1045.                 [TARGET]        END-MACRO       NO-INTERPRET
  1046.  
  1047. MACRO P@        ( port# -- n )
  1048.                 IMM_BEFORE
  1049.                 [FORTH]
  1050.                 IF      DUP 255 >
  1051.                         IF
  1052.                                 [ASSEMBLER]
  1053.                                 MOV DX, # ( xxxx )
  1054.                                 IN AX, DX
  1055.                                 MOV BX, AX
  1056.                                 [FORTH]
  1057.                         ELSE
  1058.                                 [ASSEMBLER]
  1059.                                 IN AX, # ( xxxx )
  1060.                                 MOV BX, AX
  1061.                                 [FORTH]
  1062.                         THEN
  1063.                 ELSE
  1064.                         [ASSEMBLER]
  1065.                         MOV DX, BX
  1066.                         IN AX, DX
  1067.                         MOV BX, AX
  1068.                         [FORTH]
  1069.                 THEN
  1070.                 [TARGET]        END-MACRO       NO-INTERPRET
  1071.  
  1072. MACRO PC!       ( n port# -- )
  1073.                 [FORTH]
  1074.                 IMM/ABS_OPT ?DUP
  1075.                 IF      0<
  1076.                         IF      DUP 255 >
  1077.                                 IF
  1078.                                         [ASSEMBLER]
  1079.                                         MOV AX, BX
  1080.                                         MOV DX, # ( xxxx )
  1081.                                         OUT DX, AL
  1082.                                         [FORTH]
  1083.                                 ELSE
  1084.                                         [ASSEMBLER]
  1085.                                         MOV AX, BX
  1086.                                         OUT # ( xxxx ) AL
  1087.                                         [FORTH]
  1088.                                 THEN
  1089.                         ELSE
  1090.                                 [ASSEMBLER]
  1091.                                 MOV AX, BX
  1092.                                 MOV DX, ( xxxx )
  1093.                                 OUT DX, AL
  1094.                                 [FORTH]
  1095.                         THEN
  1096.                 ELSE
  1097.                         [ASSEMBLER]
  1098.                         MOV DX, BX
  1099.                         LODSW
  1100.                         OUT DX, AL
  1101.                         [FORTH]
  1102.                 THEN
  1103.                 [ASSEMBLER]
  1104.                 LOAD_BX
  1105.                 [TARGET]        END-MACRO       NO-INTERPRET
  1106.  
  1107. MACRO P!        ( n port# -- )
  1108.                 [FORTH]
  1109.                 IMM/ABS_OPT ?DUP
  1110.                 IF      0<
  1111.                         IF      DUP 255 >
  1112.                                 IF
  1113.                                         [ASSEMBLER]
  1114.                                         MOV AX, BX
  1115.                                         MOV DX, # ( xxxx )
  1116.                                         OUT DX, AX
  1117.                                         [FORTH]
  1118.                                 ELSE
  1119.                                         [ASSEMBLER]
  1120.                                         MOV AX, BX
  1121.                                         OUT # ( xxxx ) AX
  1122.                                         [FORTH]
  1123.                                 THEN
  1124.                         ELSE
  1125.                                 [ASSEMBLER]
  1126.                                 MOV AX, BX
  1127.                                 MOV DX, ( xxxx )
  1128.                                 OUT DX, AX
  1129.                                 [FORTH]
  1130.                         THEN
  1131.                 ELSE
  1132.                         [ASSEMBLER]
  1133.                         MOV DX, BX
  1134.                         LODSW
  1135.                         OUT DX, AX
  1136.                         [FORTH]
  1137.                 THEN
  1138.                 [ASSEMBLER]
  1139.                 LOAD_BX
  1140.                 [TARGET]        END-MACRO       NO-INTERPRET
  1141.  
  1142. ICODE PDOS      ( addr drive# --- f1 )  \ get current directory to addr
  1143.                                         \ return f1 true if failed
  1144.                 MOV DX, BX
  1145.                 LODSW
  1146.                 PUSH SI         MOV SI, AX
  1147.                 MOV AH, # $47   INT $21
  1148.                 [ASSEMBLER]
  1149.              U< IF
  1150.                         MOV AL, # 1
  1151.                 ELSE
  1152.                         SUB AL, AL
  1153.                 THEN
  1154.                 SUB AH, AH      POP SI
  1155.                 MOV BX, AX
  1156.                 RET             END-ICODE
  1157.  
  1158. MACRO 2*        ( n -- 2*n )
  1159.                 SHL BX, # 1     END-MACRO       EXECUTES> 2*
  1160.  
  1161. MACRO 4*        ( n -- 2*n )
  1162.                 SHL BX, # 1
  1163.                 SHL BX, # 1     END-MACRO       NO-INTERPRET
  1164.  
  1165. MACRO 2/        ( n -- n/2 )
  1166.                 SAR BX, # 1     END-MACRO       EXECUTES> 2/
  1167.  
  1168. MACRO U2/       ( u -- u/2 )
  1169.                 SHR BX, # 1     END-MACRO       EXECUTES> U2/
  1170.  
  1171. ICODE U16/      ( u -- u/16 )
  1172.                 SHR BX, # 1     SHR BX, # 1
  1173.                 SHR BX, # 1     SHR BX, # 1
  1174.                 RET             END-ICODE
  1175.  
  1176. ICODE U8/       ( u -- u/8 )
  1177.                 SHR BX, # 1
  1178.                 SHR BX, # 1
  1179.                 SHR BX, # 1
  1180.                 RET             END-ICODE
  1181.  
  1182. ICODE 8*        ( n -- 8*n )
  1183.                 SHL BX, # 1
  1184.                 SHL BX, # 1
  1185.                 SHL BX, # 1
  1186.                 RET             END-ICODE
  1187.  
  1188. MACRO 1+        ( n1 --- n2 )
  1189.                 INC BX          END-MACRO       EXECUTES> 1+
  1190.  
  1191. MACRO 2+        ( n1 --- n2 )
  1192.                 ADD BX, # 2     END-MACRO       EXECUTES> 2+
  1193.  
  1194. MACRO 1-        ( n1 --- n2 )
  1195.                 DEC BX          END-MACRO       EXECUTES> 1-
  1196.  
  1197. MACRO 2-        ( n1 --- n2 )
  1198.                 SUB BX, # 2     END-MACRO       EXECUTES> 2-
  1199.  
  1200. ICODE UM*       ( n1 n2 -- d )
  1201.                 MOV AX, 0 [SI]
  1202.                 MUL BX
  1203.                 MOV 0 [SI], AX
  1204.                 XCHG BX, DX
  1205.                 RET             END-ICODE
  1206.  
  1207. MACRO *         ( n1 n2 -- n3 )
  1208.                 [FORTH]
  1209.                 IMM/ABS_OPT ?DUP
  1210.                 IF      0<
  1211.                         IF
  1212.                                 [ASSEMBLER]
  1213.                                 MOV AX, # ( xxxx )
  1214.                                 [FORTH]
  1215.                         ELSE
  1216.                                 [ASSEMBLER]
  1217.                                 MOV AX, ( xxxx )
  1218.                                 [FORTH]
  1219.                         THEN
  1220.                 ELSE
  1221.                         [ASSEMBLER]
  1222.                         LODSW
  1223.                         [FORTH]
  1224.                 THEN
  1225.                 [ASSEMBLER]
  1226.                 MUL BX
  1227.                 MOV BX, AX
  1228.                 [TARGET]        END-MACRO       EXECUTES> *
  1229.  
  1230. M: U*D          ( n1 n2 -- d )
  1231.                 UM*   ;                         NO-INTERPRET
  1232.  
  1233. CODE UM/MOD    ( ud un -- URemainder UQuotient )
  1234.                 NO_INLINE
  1235.                 XCHG SI, SP
  1236.                 POP DX
  1237.                 POP AX
  1238.                 CMP DX, BX
  1239.                 [ASSEMBLER]
  1240.             U>= IF                      \ divide by zero?
  1241.                         MOV AX, # -1
  1242.                         MOV DX, AX
  1243.                         PUSH DX
  1244.                         MOV BX, AX
  1245.                         XCHG SI, SP
  1246.                         RET
  1247.                 THEN
  1248.                 DIV BX
  1249.                 PUSH DX
  1250.                 MOV BX, AX
  1251.                 XCHG SI, SP
  1252.                 RET             END-CODE
  1253.  
  1254. MACRO 0=        ( n -- f )
  1255.                 SUB BX, # 1
  1256.                 SBB BX, BX      END-MACRO       EXECUTES> 0=
  1257.  
  1258. MACRO 0<        ( n -- f )
  1259.                 MOV AX, BX
  1260.                 CWD
  1261.                 MOV BX, DX      END-MACRO       EXECUTES> 0<
  1262.  
  1263. CODE 0>        ( n -- f )
  1264.                 NO_INLINE
  1265.                 MOV AX, BX
  1266.                 NEG AX
  1267.                 [ASSEMBLER]
  1268.            OV<> IF      CWD
  1269.                         MOV BX, DX
  1270.                         RET
  1271.                 THEN
  1272.                 SUB BX, BX
  1273.                 RET             END-CODE
  1274.  
  1275. IMACRO 0<>      ( n -- f )
  1276.                 NEG BX
  1277.                 SBB BX, BX      END-IMACRO
  1278.  
  1279. MACRO =         ( n1 n2 -- f )
  1280.                 [FORTH]
  1281.                 IMM/ABS_OPT ?DUP
  1282.                 IF      0<
  1283.                         IF
  1284.                                 [ASSEMBLER]
  1285.                                 SUB BX, # ( xxxx )
  1286.                                 [FORTH]
  1287.                         ELSE
  1288.                                 [ASSEMBLER]
  1289.                                 SUB BX, ( xxxx )
  1290.                                 [FORTH]
  1291.                         THEN
  1292.                 ELSE
  1293.                         [ASSEMBLER]
  1294.                         LODSW
  1295.                         SUB BX, AX
  1296.                         [FORTH]
  1297.                 THEN
  1298.                 [ASSEMBLER]
  1299.                 SUB BX, # 1
  1300.                 SBB BX, BX
  1301.                 [TARGET]        END-MACRO       NO-INTERPRET
  1302.  
  1303. MACRO <>        ( n1 n2 -- f )
  1304.                 [FORTH]
  1305.                 IMM/ABS_OPT ?DUP
  1306.                 IF      0<
  1307.                         IF
  1308.                                 [ASSEMBLER]
  1309.                                 SUB BX, # ( xxxx )
  1310.                                 [FORTH]
  1311.                         ELSE
  1312.                                 [ASSEMBLER]
  1313.                                 SUB BX, ( xxxx )
  1314.                                 [FORTH]
  1315.                         THEN
  1316.                 ELSE
  1317.                         [ASSEMBLER]
  1318.                         LODSW
  1319.                         SUB BX, AX
  1320.                         [FORTH]
  1321.                 THEN
  1322.                 [ASSEMBLER]
  1323.                 NEG BX
  1324.                 SBB BX, BX
  1325.                 [TARGET]        END-MACRO       NO-INTERPRET
  1326.  
  1327. : ?NEGATE       ( n1 n2 -- n3 )
  1328.                 0< IF    NEGATE   THEN   ;      NO-INTERPRET
  1329.  
  1330. MACRO U<        ( n1 n2 -- f )
  1331.                 LODSW
  1332.                 SUB AX, BX
  1333.                 SBB AX, AX
  1334.                 MOV BX, AX      END-MACRO       NO-INTERPRET
  1335.  
  1336. MACRO U>        ( n1 n2 -- f )
  1337.                 [FORTH]
  1338.                 IMM/ABS_OPT ?DUP
  1339.                 IF      0<
  1340.                         IF
  1341.                                 [ASSEMBLER]
  1342.                                 MOV AX, # ( xxxx )
  1343.                                 SUB AX, BX
  1344.                                 SBB AX, AX
  1345.                                 MOV BX, AX
  1346.                                 [FORTH]
  1347.                         ELSE
  1348.                                 [ASSEMBLER]
  1349.                                 MOV AX, ( xxxx )
  1350.                                 SUB AX, BX
  1351.                                 SBB AX, AX
  1352.                                 MOV BX, AX
  1353.                                 [FORTH]
  1354.                         THEN
  1355.                 ELSE
  1356.                         [ASSEMBLER]
  1357.                         LODSW
  1358.                         SUB BX, AX
  1359.                         SBB BX, BX
  1360.                         [FORTH]
  1361.                 THEN
  1362.                 [TARGET]        END-MACRO       NO-INTERPRET
  1363.  
  1364. ICODE <         ( n1 n2 -- f )
  1365.                 LODSW
  1366.                 MOV DI, # TRUE
  1367.                 CMP AX, BX
  1368.                 [ASSEMBLER]
  1369.              >= IF      SUB DI, DI
  1370.                 THEN
  1371.                 MOV BX, DI
  1372.                 RET             END-ICODE
  1373.  
  1374. ICODE >         ( n1 n2 -- f )
  1375.                 LODSW
  1376.                 MOV DI, # TRUE
  1377.                 CMP AX, BX
  1378.                 [ASSEMBLER]
  1379.              <= IF      SUB DI, DI
  1380.                 THEN
  1381.                 MOV BX, DI
  1382.                 RET             END-ICODE
  1383.  
  1384. ICODE UMIN      ( n1 n2 -- n3 )
  1385.                 LODSW
  1386.                 CMP BX, AX
  1387.                 [ASSEMBLER]
  1388.              U> IF      MOV BX, AX
  1389.                 THEN
  1390.                 RET             END-ICODE
  1391.  
  1392. ICODE MIN       ( n1 n2 -- n3 )
  1393.                 LODSW
  1394.                 CMP BX, AX
  1395.                 [ASSEMBLER]
  1396.               > IF      MOV BX, AX
  1397.                 THEN
  1398.                 RET             END-ICODE
  1399.  
  1400. ICODE MAX       ( n1 n2 -- n3 )
  1401.                 LODSW
  1402.                 CMP BX, AX
  1403.                 [ASSEMBLER]
  1404.              <= IF      MOV BX, AX
  1405.                 THEN
  1406.                 RET             END-ICODE
  1407.  
  1408. IMACRO 0MAX     ( n1 -- n3 )
  1409.                 [ASSEMBLER]
  1410.                 CMP BX, BP
  1411.              <= IF      SUB BX, BX
  1412.                 THEN            END-IMACRO
  1413.  
  1414. ICODE UMAX      ( n1 n2 -- n3 )
  1415.                 [ASSEMBLER]
  1416.                 LODSW
  1417.                 CMP BX, AX
  1418.             U<= IF      MOV BX, AX
  1419.                 THEN
  1420.                 RET             END-ICODE
  1421.  
  1422. ICODE WITHIN    ( n lo hi -- flag )
  1423.                 [ASSEMBLER]
  1424.                 MOV DI, BX
  1425.                 LODSW
  1426.                 MOV CX, AX
  1427.                 LODSW
  1428.                 SUB BX, BX
  1429.                 CMP AX, DI
  1430.               < IF      CMP AX, CX
  1431.                      >= IF      DEC BX
  1432.                         THEN
  1433.                 THEN
  1434.                 RET             END-ICODE
  1435.  
  1436. ICODE BETWEEN   ( n lo hi -- flag )
  1437.                 [ASSEMBLER]
  1438.                 MOV DX, BX
  1439.                 LODSW
  1440.                 MOV CX, AX
  1441.                 LODSW
  1442.                 SUB BX, BX
  1443.                 CMP AX, DX
  1444.              <= IF      CMP AX, CX
  1445.                      >= IF      DEC BX
  1446.                         THEN
  1447.                 THEN
  1448.                 RET             END-ICODE
  1449.  
  1450. ICODE UBETWEEN  ( n ulo uhi -- flag )
  1451.                 [ASSEMBLER]
  1452.                 MOV DX, BX
  1453.                 LODSW
  1454.                 MOV CX, AX
  1455.                 LODSW
  1456.                 SUB BX, BX
  1457.                 CMP AX, DX
  1458.             U<= IF      CMP AX, CX
  1459.                     U>= IF      DEC BX
  1460.                         THEN
  1461.                 THEN
  1462.                 RET             END-ICODE
  1463.  
  1464. $FFFF CONSTANT TRUE
  1465. $0000 CONSTANT FALSE
  1466.  
  1467. ICODE 2@        ( addr -- d )
  1468.                 XCHG SI, SP
  1469.                 PUSH 2 [BX]
  1470.                 MOV BX, 0 [BX]
  1471.                 XCHG SI, SP
  1472.                 RET             END-ICODE
  1473.  
  1474. ICODE 2!        ( d addr -- )
  1475.                 XCHG SI, SP
  1476.                 POP 0 [BX]
  1477.                 POP 2 [BX]
  1478.                 POP BX
  1479.                 XCHG SI, SP
  1480.                 RET             END-ICODE
  1481.  
  1482. MACRO 2DROP     ( d -- )
  1483.                 INC SI
  1484.                 INC SI
  1485.                 LOAD_BX         END-MACRO       EXECUTES> 2DROP
  1486.  
  1487. IMACRO 3DROP    ( n1 n2 n3 -- )
  1488.                 ADD SI, # 4
  1489.                 LOAD_BX         END-IMACRO
  1490.  
  1491. CODE 2DUP       ( d -- d d )
  1492.                 XCHG SI, SP
  1493.                 MOV DI, SP
  1494.                 PUSH BX
  1495.                 PUSH 0 [DI]
  1496.                 XCHG SI, SP
  1497.                 RET             END-CODE        EXECUTES> 2DUP
  1498.  
  1499. ICODE 3DUP      ( n1 n2 n3 -- n1 n2 n3 n1 n2 n3 )
  1500.                 XCHG SI, SP
  1501.                 MOV DI, SP
  1502.                 PUSH BX
  1503.                 PUSH 2 [DI]
  1504.                 PUSH 0 [DI]
  1505.                 XCHG SI, SP
  1506.                 RET             END-ICODE
  1507.  
  1508. ICODE 2SWAP     ( d1 d2 -- d2 d1 )
  1509.                 XCHG SI, SP
  1510.                 POP CX          XCHG BX, CX
  1511.                 POP AX          POP DX
  1512.                 PUSH BX         PUSH CX
  1513.                 PUSH DX
  1514.                 MOV BX, AX
  1515.                 XCHG SI, SP
  1516.                 RET             END-ICODE
  1517.  
  1518. ICODE 2OVER     ( d1 d2 -- d1 d2 d1 )
  1519.                 XCHG SI, SP
  1520.                 MOV DI, SP
  1521.                 PUSH BX
  1522.                 PUSH 4 [DI]
  1523.                 MOV BX, 2 [DI]
  1524.                 XCHG SI, SP
  1525.                 RET             END-ICODE
  1526.  
  1527. ICODE D+        ( d1 d2 -- dsum )
  1528.                 MOV DX, BX
  1529.                 LODSW
  1530.                 ADD 2 [SI], AX
  1531.                 LOAD_BX
  1532.                 ADC BX, DX
  1533.                 RET             END-ICODE
  1534.  
  1535. IMACRO DNEGATE  ( d# -- d#' )
  1536.                 NEG BX
  1537.                 NEG 0 [SI] WORD
  1538.                 SBB BX, BP      END-IMACRO
  1539.  
  1540. ICODE S>D       ( n -- d )
  1541.                 MOV AX, BX
  1542.                 CWD
  1543.                 DEC SI
  1544.                 DEC SI
  1545.                 MOV 0 [SI], DX
  1546.                 MOV BX, AX
  1547.                 RET             END-ICODE
  1548.  
  1549. ICODE DABS      ( d1 -- d2 )
  1550.                 [ASSEMBLER]
  1551.                 OR BX, BP
  1552.              0< IF      NEG BX
  1553.                         NEG 0 [SI] WORD
  1554.                         SBB BX, BP
  1555.                 THEN
  1556.                 RET             END-ICODE
  1557.  
  1558. IMACRO D2*      ( d -- d*2 )
  1559.                 SHL 0 [SI], # 1 WORD
  1560.                 RCL BX, # 1     END-IMACRO
  1561.  
  1562. IMACRO D2/      ( d -- d/2 )
  1563.                 SAR BX, # 1
  1564.                 RCR 0 [SI], # 1 WORD
  1565.                 END-IMACRO
  1566.  
  1567. M: D-           ( d1 d2 -- d3 )
  1568.                 DNEGATE D+   ;                  NO-INTERPRET
  1569.  
  1570. : ?DNEGATE      ( d1 n -- d2 )
  1571.                 0< IF   DNEGATE   THEN   ;      NO-INTERPRET
  1572.  
  1573. M: D0=          ( d -- f )
  1574.                 OR 0= ;                         NO-INTERPRET
  1575.  
  1576. M: D=           ( d1 d2 -- f )
  1577.                 D-  D0=  ;                      NO-INTERPRET
  1578.  
  1579. : DU<           ( ud1 ud2 -- f )
  1580.                 ROT SWAP 2DUP U<
  1581.                 IF      2DROP 2DROP TRUE
  1582.                 ELSE    <> IF   2DROP FALSE  ELSE  U<  THEN
  1583.                 THEN  ;                         NO-INTERPRET
  1584.  
  1585. : D<            ( d1 d2 -- f )
  1586.                 2 PICK OVER =
  1587.                 IF      DU<
  1588.                 ELSE  NIP ROT DROP <  THEN  ;   NO-INTERPRET
  1589.  
  1590. M: D>           ( d1 d2 -- f )
  1591.                 2SWAP D<   ;                    NO-INTERPRET
  1592.  
  1593. M: 4DUP         ( a b c d -- a b c d a b c d )
  1594.                 2OVER 2OVER   ;                 NO-INTERPRET
  1595.  
  1596. : DMIN          ( d1 d2 -- d3 )
  1597.                 4DUP D> IF  2SWAP  THEN 2DROP ; NO-INTERPRET
  1598.  
  1599. : DMAX          ( d1 d2 -- d3 )
  1600.                 4DUP D< IF 2SWAP THEN 2DROP ;   NO-INTERPRET
  1601.  
  1602. ICODE *D        ( n1 n2 -- d# )
  1603.                 MOV AX, 0 [SI]
  1604.                 IMUL BX
  1605.                 MOV 0 [SI], AX
  1606.                 MOV BX, DX
  1607.                 RET             END-ICODE
  1608.  
  1609. : MU/MOD        ( ud# un1 -- rem d#quot )
  1610.                 >R  0  R@  UM/MOD  R>  SWAP  >R  UM/MOD  R>   ;
  1611.  
  1612. CODE  /         ( num den --- quot )
  1613.                 LODSW
  1614.                 CWD
  1615.                 MOV CX, BX      XOR CX, DX
  1616.                 [ASSEMBLER]
  1617.             0>= IF                              \ POSITIVE QUOTIENT CASE
  1618.                         IDIV BX
  1619.                 ELSE
  1620.                         IDIV BX         OR DX, DX
  1621.                     0<> IF
  1622.                                 DEC AX
  1623.                         THEN
  1624.                 THEN
  1625.                 MOV BX, AX
  1626.                 RET             END-CODE        EXECUTES> /
  1627.  
  1628. ICODE /MOD      ( num den --- rem quot )
  1629.                 MOV AX, 0 [SI]  CWD
  1630.                 MOV CX, BX      XOR CX, DX
  1631.                 [ASSEMBLER]
  1632.             0>= IF
  1633.                         IDIV BX
  1634.                 ELSE
  1635.                         IDIV BX
  1636.                         OR DX, DX
  1637.                     0<> IF
  1638.                                 ADD DX, BX
  1639.                                 DEC AX
  1640.                         THEN
  1641.                 THEN
  1642.                 MOV 0 [SI], DX
  1643.                 MOV BX, AX
  1644.                 RET             END-ICODE
  1645.  
  1646. M: MOD          ( n1 n2 -- rem )
  1647.                 /MOD  DROP  ;                   EXECUTES> MOD
  1648.  
  1649. ICODE */MOD     ( n1 n2 n3 --- rem quot )
  1650.                 XCHG SI, SP
  1651.                 POP AX          POP CX
  1652.                 IMUL CX         MOV CX, BX
  1653.                 XOR CX, DX
  1654.                 [ASSEMBLER]
  1655.             0>= IF
  1656.                         IDIV BX
  1657.                 ELSE
  1658.                         IDIV BX
  1659.                         OR DX, DX
  1660.                     0<> IF
  1661.                                 ADD DX, BX
  1662.                                 DEC AX
  1663.                         THEN
  1664.                 THEN
  1665.                 PUSH DX
  1666.                 MOV BX, AX
  1667.                 XCHG SI, SP
  1668.                 RET             END-ICODE
  1669.  
  1670. MACRO XOR       ( n1 n2 -- n3 )
  1671.                 [FORTH]
  1672.                 IMM/ABS_OPT ?DUP
  1673.                 IF      0<
  1674.                         IF
  1675.                                 [ASSEMBLER]
  1676.                                 XOR BX, # ( xxxx )
  1677.                                 [FORTH]
  1678.                         ELSE
  1679.                                 [ASSEMBLER]
  1680.                                 XOR BX, ( xxxx )
  1681.                                 [FORTH]
  1682.                         THEN
  1683.                 ELSE
  1684.                         [ASSEMBLER]
  1685.                         LODSW
  1686.                         XOR BX, AX
  1687.                         [FORTH]
  1688.                 THEN
  1689.                 [TARGET]        END-MACRO       EXECUTES> XOR
  1690.  
  1691. : M/MOD         ( d# n1 -- rem quot )
  1692.                 ?DUP
  1693.                 IF  DUP>R  2DUP XOR >R  >R DABS R@ ABS  UM/MOD
  1694.                         SWAP R> ?NEGATE
  1695.                         SWAP R> 0<
  1696.                         IF  NEGATE OVER
  1697.                                 IF  1- R@ ROT - SWAP  THEN
  1698.                         THEN    R>DROP
  1699.                 THEN  ;                         NO-INTERPRET
  1700.  
  1701. M: */           ( n1 n2 n3 -- n1*n2/n3 )
  1702.                 */MOD  NIP  ;                   NO-INTERPRET
  1703.  
  1704. : ROLL          ( n1 n2 .. nk k -- n2 n3 .. nk n1 )
  1705.                 >R R@ PICK   SP@ DUP 2+   R> 1+ 2* CMOVE>  DROP  ;
  1706.                                                 NO-INTERPRET
  1707. : 2ROT          ( a b c d e f - c d e f a b )
  1708.                 5 ROLL  5 ROLL  ;               NO-INTERPRET
  1709.  
  1710. ICODE FILL      (  start-addr count char -- )
  1711.                 XCHG SI, SP
  1712.                 MOV AX, BX
  1713.                 CLD             MOV BX, DS
  1714.                 POP CX          POP DI
  1715.                 XCHG SI, SP
  1716.                 PUSH ES         MOV ES, BX
  1717.                 REPNZ           STOSB           POP ES
  1718.                 LOAD_BX
  1719.                 RET             END-ICODE
  1720.  
  1721. ICODE LFILL     (  seg start-addr count char -- )
  1722.                 XCHG SI, SP
  1723.                 CLD
  1724.                 MOV AX, BX      POP CX
  1725.                 POP DI          POP BX
  1726.                 XCHG SI, SP
  1727.                 PUSH ES         MOV ES, BX
  1728.                 REPNZ           STOSB           POP ES
  1729.                 LOAD_BX
  1730.                 RET             END-ICODE
  1731.  
  1732. ICODE LFILLW    (  seg start-addr BYTE-count WORD -- )
  1733.                 SAVE_BX
  1734.                 XCHG SI, SP
  1735.                 CLD             POP AX
  1736.                 POP CX
  1737.                 SHR CX, # 1
  1738.                 POP DI          POP BX
  1739.                 MOV DX, ES      MOV ES, BX
  1740.                 REPNZ           STOSW
  1741.                 MOV ES, DX
  1742.                 XCHG SI, SP
  1743.                 LOAD_BX
  1744.                 RET             END-ICODE
  1745.  
  1746. : ERASE         ( addr len -- )
  1747.                 0 FILL   ;                      NO-INTERPRET
  1748.  
  1749. $20 CONSTANT BL                 \ a blank
  1750. $80 CONSTANT DOS_CMD_TAIL       \ DOS command line pointer in ?CS: space
  1751.  
  1752. : BLANK         ( addr len -- )
  1753.                 BL FILL   ;                     NO-INTERPRET
  1754.  
  1755. ICODE COUNT     ( a1 --- a2 n1 )
  1756.                 SUB AX, AX
  1757.                 MOV AL, 0 [BX]
  1758.                 INC BX
  1759.                 DEC SI
  1760.                 DEC SI
  1761.                 MOV 0 [SI], BX
  1762.                 MOV BX, AX
  1763.                 RET             END-ICODE
  1764.  
  1765. ICODE COUNTL    ( seg addr -- seg addr+1 len )
  1766.                 MOV AX, 0 [SI]
  1767.                 MOV DX, DS      MOV DS, AX
  1768.                 XOR AX, AX      MOV AL, 0 [BX]
  1769.                 INC BX
  1770.                 MOV DS, DX
  1771.                 DEC SI
  1772.                 DEC SI
  1773.                 MOV 0 [SI], BX
  1774.                 MOV BX, AX
  1775.                 RET             END-ICODE
  1776.  
  1777. ICODE LENGTH    ( a1 --- a2 n1 )
  1778.                 MOV AX, 0 [BX]
  1779.                 INC BX
  1780.                 INC BX
  1781.                 DEC SI
  1782.                 DEC SI
  1783.                 MOV 0 [SI], BX
  1784.                 MOV BX, AX
  1785.                 RET             END-ICODE
  1786.  
  1787. ICODE CMOVEL    ( sseg sptr dseg dptr cnt -- )
  1788.                 PUSH DS
  1789.                 PUSH ES
  1790.                 XCHG SI, SP
  1791.                 MOV CX, BX              \ count to CX
  1792.                 MOV BX, SI              \ preserve SI
  1793.                 CLD
  1794.                 POP DI
  1795.                 POP ES          POP SI
  1796.                 POP DS
  1797.                 [ASSEMBLER]
  1798.           CX<>0 IF
  1799.                         REPNZ   MOVSB
  1800.                 THEN
  1801.                 MOV SI, BX              \ restore SI
  1802.                 POP BX
  1803.                 XCHG SI, SP
  1804.                 POP ES
  1805.                 POP DS
  1806.                 RET             END-ICODE
  1807.  
  1808. ICODE CMOVEL>   ( sseg sptr dseg dptr cnt -- )
  1809.                 PUSH DS
  1810.                 PUSH ES
  1811.                 XCHG SI, SP
  1812.                 MOV CX, BX              \ count to BX
  1813.                 MOV BX, SI              \ preserve SI
  1814.                 STD
  1815.                 POP DI
  1816.                 POP ES          POP SI
  1817.                 POP DS
  1818.                 [ASSEMBLER]
  1819.           CX<>0 IF
  1820.                         DEC CX          ADD DI, CX
  1821.                         ADD SI, CX      INC CX
  1822.                         REPNZ           MOVSB
  1823.                 THEN
  1824.                 CLD
  1825.                 MOV SI, BX              \ restore SI
  1826.                 POP BX
  1827.                 XCHG SI, SP
  1828.                 POP ES
  1829.                 POP DS
  1830.                 RET             END-ICODE
  1831.  
  1832. : MOVE          ( from to len -- )
  1833.                 -ROT   2DUP U< IF   ROT CMOVE>   ELSE   ROT CMOVE   THEN ;
  1834.                                                 NO-INTERPRET
  1835.  
  1836. CODE CRLF>BL'S  ( a1 --- a1 )   \ change CRLF at end of string to blanks
  1837.                                 \ leaving the string address on the stack
  1838.                 mov cx, bx      \ Same as -> DUP COUNT + 2- DUP @ $0D0A =
  1839.                 mov al, 0 [bx]  \            IF 8224 SWAP ! ELSE DROP DROP ;
  1840.                 sub ah, ah
  1841.                 add bx, ax
  1842.                 dec bx
  1843.                 cmp 0 [bx], # $0A0D word        \ if line ends in CRLF
  1844.              0= if      mov 0 [bx], # 8224 word \ change then to blanks
  1845.                 then
  1846.                 mov bx, cx
  1847.                 RET             END-CODE
  1848.  
  1849. VARIABLE DPL
  1850. VARIABLE BASE
  1851. VARIABLE HLD
  1852. VARIABLE CAPS
  1853. VARIABLE SSEG
  1854. VARIABLE SPAN
  1855. VARIABLE #OUT
  1856. VARIABLE #LINE
  1857. VARIABLE SAVECUR
  1858. VARIABLE ESC_FLG
  1859. VARIABLE #TIB
  1860. VARIABLE >IN
  1861. VARIABLE TIB0
  1862. VARIABLE #EXSTRT
  1863. VARIABLE FUDGE
  1864. VARIABLE ATTRIB
  1865. VARIABLE LMARGIN
  1866. VARIABLE RMARGIN
  1867. VARIABLE TABSIZE
  1868. VARIABLE PRINTING
  1869.  
  1870. DEFER AT?
  1871. DEFER AT
  1872. DEFER KEY
  1873. DEFER EMIT
  1874. DEFER TYPE
  1875. DEFER SPACES
  1876. DEFER CR        EXECUTES> CR
  1877. DEFER DARK      EXECUTES> DARK
  1878.  
  1879. ' DARK ALIAS CLS
  1880.  
  1881. CODE COMP       ( addr1 addr2 len -- -1 | 0 | 1 )
  1882.                 [ASSEMBLER]
  1883.                 XCHG SI, SP
  1884.                 MOV DX, SI      MOV CX, BX
  1885.                 POP DI          POP SI
  1886.           CX<>0 IF      PUSH ES         MOV ES, SSEG
  1887.                         REPZ CMPSB
  1888.                     0<> IF
  1889.                              0< IF      MOV CX, # -1
  1890.                                 ELSE    MOV CX, # 1
  1891.                                 THEN
  1892.                         THEN
  1893.                         POP ES
  1894.                 THEN
  1895.                 MOV SI, DX
  1896.                 MOV BX, CX
  1897.                 XCHG SI, SP
  1898.                 RET             END-CODE
  1899.  
  1900. CODE CAPS-COMP ( addr1 addr2 len -- -1 | 0 | 1 )
  1901.                 [ASSEMBLER]
  1902.                 PUSH ES
  1903.                 XCHG SI, SP
  1904.                 MOV DX, SI      MOV CX, BX
  1905.                 POP DI          POP SI
  1906.                 MOV ES, SSEG
  1907.                 BEGIN
  1908.                     JCXZ  0 $
  1909.                     MOV AH,     0 [SI]  INC SI
  1910.                     MOV AL, ES: 0 [DI]  INC DI
  1911.                     OR AX, # $02020     CMP AH, AL
  1912.                     JNE 1 $             DEC CX
  1913.                 AGAIN
  1914.         1 $: 0< IF
  1915.                    MOV CX, # -1
  1916.                 ELSE
  1917.                    MOV CX, # 1
  1918.                 THEN
  1919.         0 $:    MOV SI, DX
  1920.                 MOV BX, CX
  1921.                 XCHG SI, SP
  1922.                 POP ES
  1923.                 RET             END-CODE
  1924.  
  1925. CODE SKIP      ( addr len char -- addr' len' ) \ skip char forwards
  1926.                 [ASSEMBLER]
  1927.                 LODSW   MOV CX, AX
  1928.                 MOV AX, BX
  1929.           CX<>0 IF      MOV DI, 0 [SI]
  1930.                         MOV DX, ES      MOV ES, SSEG
  1931.                         REPZ            SCASB
  1932.                         MOV ES, DX
  1933.                     0<> IF
  1934.                                 INC CX
  1935.                                 DEC DI
  1936.                         THEN
  1937.                         MOV 0 [SI], DI
  1938.                 THEN    MOV BX, CX
  1939.                 RET             END-CODE
  1940.  
  1941. CODE -SKIP     ( addr len char -- addr' len' ) \ skip char backwards
  1942.                 [ASSEMBLER]
  1943.                 LODSW   MOV CX, AX
  1944.                 MOV AX, BX
  1945.           CX<>0 IF      MOV DI, 0 [SI]
  1946.                         MOV DX, ES      MOV ES, SSEG
  1947.                         STD     REPZ    SCASB   CLD
  1948.                         MOV ES, DX
  1949.                     0<> IF
  1950.                                 INC CX
  1951.                                 DEC DI
  1952.                         THEN
  1953.                         MOV 0 [SI], DI
  1954.                 THEN    MOV BX, CX
  1955.                 RET             END-CODE
  1956.  
  1957. CODE SCAN      ( addr len char -- addr' len' ) \ scan char forwards
  1958.                 [ASSEMBLER]
  1959.                 LODSW   MOV CX, AX
  1960.                 MOV AX, BX
  1961.           CX<>0 IF      MOV DI, 0 [SI]
  1962.                         MOV DX, ES      MOV ES, SSEG
  1963.                         REPNZ           SCASB
  1964.                         MOV ES, DX
  1965.                      0= IF              INC CX
  1966.                                         DEC DI
  1967.                         THEN
  1968.                         MOV 0 [SI], DI
  1969.                 THEN    MOV BX, CX
  1970.                 RET     END-CODE
  1971.  
  1972. CODE  -SCAN    ( addr len char -- addr' len' ) \ scan char backwards
  1973.                 [ASSEMBLER]
  1974.                 LODSW   MOV CX, AX
  1975.                 MOV AX, BX
  1976.           CX<>0 IF      MOV DI, 0 [SI]
  1977.                         MOV DX, ES      MOV ES, SSEG
  1978.                         STD     REPNZ   SCASB   CLD
  1979.                         MOV ES, DX
  1980.                      0= IF              DEC CX
  1981.                                         INC DI
  1982.                         THEN
  1983.                         MOV 0 [SI], DI
  1984.                 THEN    MOV BX, CX
  1985.                 RET     END-CODE
  1986.  
  1987. ICODE /STRING   ( addr len n -- addr' len' )
  1988.                 LODSW
  1989.                 XCHG BX, AX
  1990.                 CMP BX, AX
  1991.                 [ASSEMBLER]
  1992.             U<= IF      MOV AX, BX      \ AX = SMALLER OF AX BX
  1993.                 THEN
  1994.                 ADD 0 [SI], AX
  1995.                 SUB BX, AX
  1996.                 RET             END-ICODE
  1997.  
  1998. CODE DIGIT     ( char base -- n f )
  1999.                 NO_INLINE
  2000.                 [ASSEMBLER]
  2001.                 MOV AX, 0 [SI]
  2002.                 SUB AL, # $30           \ ASCII 0    can't user ASCII in CODE
  2003.                 JB 0 $
  2004.                         CMP AL, # 9
  2005.               > IF
  2006.                         CMP AL, # 17
  2007.                         JB 0 $
  2008.                         SUB AL, # 7
  2009.                 THEN
  2010.                 CMP AL, BL
  2011.                 JAE 0 $
  2012.                         MOV 0 [SI], AX
  2013.                         MOV BX, # -1
  2014.                         RET
  2015.            0 $: SUB BX, BX
  2016.                 RET             END-CODE
  2017.  
  2018. M: HERE         ( -- A1 )       \ return a1 the address of the next available
  2019.                                 \ free memory space in data ram
  2020.                 DP @ ;                          EXECUTES> HERE
  2021.  
  2022. M: PAD          ( -- a1 )       \ a place to put things for a bit
  2023.                 DP @ 82 + ;                     EXECUTES> PAD
  2024.  
  2025. M: ALLOT        ( n1 -- )       \ allot some DS: ram
  2026.                 DP +! ;                         EXECUTES> ALLOT-D
  2027.  
  2028. : DS:ALLOC      ( n1 -- a1 )    \ allocate n1 bytes of ram at runtime,
  2029.                                 \ returning a1 the address of the ram
  2030.                 HERE SWAP ALLOT ;               NO-INTERPRET
  2031.  
  2032. : DS:FREE?      ( -- n1 )       \ return the amount of free ram at runtime
  2033.                 SP0 @ HERE - 300 - ;            NO-INTERPRET
  2034.  
  2035. : WORD          ( c1 -- a1 )    \ return a1 a word from TIB
  2036.                 >R
  2037.                 TIB #TIB @ >IN @ /STRING        \ starting point for word
  2038.                 R@ SKIP 2DUP R> SCAN NIP        \ parse out a word
  2039.                 #TIB @ OVER - >IN !             \ adj >in to new point in $
  2040.                 - HERE PLACE HERE               \ return string in HERE
  2041.                 $2020 HERE COUNT + ! ;          \ append blanks
  2042.                                                 NO-INTERPRET
  2043.  
  2044. : DOS_TO_TIB    ( -- )          \ Move the DOS commandline to Forths TIB
  2045.                 ?CS: DOS_CMD_TAIL COUNTL DUP #TIB ! ?DS: TIB ROT CMOVEL
  2046.                 >IN OFF ;                       NO-INTERPRET
  2047.  
  2048. M: HEX          ( -- )
  2049.                 $10 BASE ! ;                    EXECUTES> HEX
  2050.  
  2051. M: DECIMAL      ( -- )
  2052.                 $0A BASE ! ;                    EXECUTES> DECIMAL
  2053.  
  2054. M: OCTAL        ( -- )
  2055.                 $08 BASE ! ;                    EXECUTES> OCTAL
  2056.  
  2057. : COMPARE       ( addr1 addr2 len -- -1 | 0 | 1 )
  2058.                 CAPS @ IF   CAPS-COMP   ELSE   COMP   THEN   ;
  2059.                                                 NO-INTERPRET
  2060. : DOUBLE?       ( -- f )
  2061.                 DPL @ 1+   0<> ;                NO-INTERPRET
  2062.  
  2063. : CONVERT       ( +d1 adr1 -- +d2 adr2 )
  2064.                 BEGIN   1+  DUP>R  C@  BASE @  DIGIT
  2065.                 WHILE   SWAP  BASE @ UM*  DROP  ROT  BASE @ UM*  D+
  2066.                         DOUBLE?  IF  DPL INCR THEN  R>
  2067.                 REPEAT  DROP  R>  ;             NO-INTERPRET
  2068.  
  2069. : (NUMBER?)     ( adr -- d flag )
  2070.                 0 0  ROT  DUP 1+  C@  ASCII -  =  DUP  >R  -  -1 DPL !
  2071.                 BEGIN   CONVERT  DUP C@  ASCII , ASCII / BETWEEN
  2072.                 WHILE   0 DPL !
  2073.                 REPEAT  -ROT  R> IF  DNEGATE  THEN   ROT C@ BL =  ;
  2074.                                                 NO-INTERPRET
  2075.  
  2076. : NUMBER?       ( adr -- d flag )
  2077.                 FALSE  OVER COUNT BOUNDS
  2078.                 ?DO     I C@ BASE @ DIGIT NIP
  2079.                         IF      DROP TRUE LEAVE THEN
  2080.                 (LOOP) LEAVE? UNDO DO?
  2081.                 IF  (NUMBER?)  ELSE  DROP  0 0 FALSE  THEN  ;
  2082.                                                 NO-INTERPRET
  2083.  
  2084. ICODE %DOSEXPECT ( addr +n --- n2 )
  2085.                 PUSH BP
  2086.                 XCHG SI, SP
  2087.                 MOV AX, BX                      \ count to ax
  2088.                 MOV BX, SP
  2089.                 SUB BX, # $100                  \ buffer 256 bytes below stck
  2090.                 MOV 0 [BX], AL                  \ 1st byte buffer = chars
  2091.                 MOV DX, BX                      \ DX = ^buffer
  2092.                 MOV AH, # $0A                   \ buffered keyboard input
  2093.                 INT $21                         \ DOS function call
  2094.                 SUB CX, CX                      \ zero CX
  2095.                 INC BX                          \ BX = ^#chars read
  2096.                 MOV CL, 0 [BX]                  \ CX = #chars READ
  2097.                 POP DI                          \ DI = forth address
  2098.                 PUSH CX                         \ return CX
  2099.                 INC BX                          \ BX = ^buffer
  2100.                 MOV DX, SI                      \ DX saves SI
  2101.                 MOV AX, ES                      \ AX saves ES
  2102.                 MOV SI, BX                      \ SI = DOS address
  2103.                 MOV BX, DS
  2104.                 MOV ES, BX                      \ set ES = DS
  2105.                 REPNZ MOVSB                     \ move it
  2106.                 MOV SI, DX                      \ restore SI
  2107.                 MOV ES, AX                      \ restore ES
  2108.                 POP BX
  2109.                 XCHG SI, SP
  2110.                 POP BP
  2111.                 RET             END-ICODE
  2112.  
  2113. ICODE DEALLOC   ( n1 -- f1 )            \ n1 = segment returned by ALLOC
  2114.                 PUSH ES         MOV ES, BX
  2115.                 MOV AH, # $49
  2116.                 INT $21
  2117.                 [ASSEMBLER]
  2118.              U< IF      SUB AH, AH
  2119.                 ELSE    SUB AX, AX
  2120.                 THEN
  2121.                 POP ES
  2122.                 MOV BX, AX
  2123.                 RET             END-ICODE
  2124.  
  2125. ICODE ALLOC     ( n1 -- n2 n3 f1 )      \ n1 = "PARAGRAPHS" not bytes
  2126.                                         \ n2 = largest available if failed
  2127.                                         \ n3 = segment start if succeeded
  2128.                                         \ f1 = 8 if failed else don't care
  2129.                 XCHG SI, SP
  2130.                 MOV AH, # $48
  2131.                 INT $21
  2132.                 PUSH BX
  2133.                 PUSH AX
  2134.                 [ASSEMBLER]
  2135.              U< IF      SUB AH, AH
  2136.                 ELSE    SUB AX, AX
  2137.                 THEN
  2138.                 MOV BX, AX
  2139.                 XCHG SI, SP
  2140.                 RET             END-ICODE
  2141.  
  2142. ICODE SETBLOCK  ( seg siz -- f1 )
  2143.                 LODSW
  2144.                 MOV DX, AX
  2145.                 MOV AH, # $4A           \ setblock call
  2146.                 PUSH ES
  2147.                 MOV ES, DX
  2148.                 INT $21
  2149.                 [ASSEMBLER]
  2150.              U< IF      SUB AH, AH
  2151.                 ELSE    SUB AX, AX
  2152.                 THEN
  2153.                 POP ES
  2154.                 MOV BX, AX
  2155.                 RET             END-ICODE
  2156.  
  2157. : PARAGRAPH     ( offset -- paragraph-inc )
  2158.                 15 + U16/ ;             EXECUTES> PARAGRAPH
  2159.  
  2160. ICODE EXECF     ( string PARMS --- return-code )
  2161.                 [ASSEMBLER]             \ BX contains PARMS
  2162.                 LODSW
  2163.                 MOV DX, AX              \ DX contains string
  2164.                 PUSH ES                 PUSH SI
  2165.                 PUSH BP                 PUSH DS
  2166.                 MOV AX, DS              MOV ES, AX
  2167.                 MOV AX, # $4B00
  2168.                 INT $21
  2169.                 POP DS                  POP BP
  2170.                 POP SI                  POP ES
  2171.              U< IF                      \ ONLY when carry is NON ZERO
  2172.                         AND AX, # $FF
  2173.                 ELSE    SUB AX, AX
  2174.                 THEN
  2175.                 MOV BX, AX
  2176.                 RET             END-ICODE
  2177.  
  2178. ICODE VIDEO     ( DX CX BX AX -- DX AX )        \ perform a VIDEO interrupt
  2179.                                                 \ call.
  2180.                 MOV DX, BX
  2181.                 LOAD_BX
  2182.                 LODSW   MOV CX, AX
  2183.                 LODSW   XCHG DX, AX
  2184.                 PUSH SI         PUSH BP
  2185.                 INT $10
  2186.                 POP BP          POP SI
  2187.                 DEC SI
  2188.                 DEC SI
  2189.                 MOV 0 [SI], DX
  2190.                 MOV BX, AX
  2191.                 RET             END-ICODE
  2192.  
  2193. : IBM-AT?       ( -- x y )              \ return the current cursor position
  2194.                 0 0 0 $0300 VIDEO DROP SPLIT ;  NO-INTERPRET
  2195.  
  2196. : IBM-AT        ( X Y -- )              \ set the current cursor position
  2197.                 2DUP #LINE ! #OUT !
  2198.                 FLIP OR 0 0 $0200 VIDEO 2DROP ; NO-INTERPRET
  2199.  
  2200. : VMODE@        ( -- n1 )               \ get the current video mode.
  2201.                 0 0 0 $0F00 VIDEO NIP $FF AND ; NO-INTERPRET
  2202.  
  2203. : VMODE!        ( n1 -- )               \ use to set video modes. n1 is the
  2204.                                         \ desired mode number. For example
  2205.                                         \ 6 VMODE! will select 640x200
  2206.                                         \ black & white graphics.
  2207.                 >R 0 0 0 R> VIDEO 2DROP ;       NO-INTERPRET
  2208.  
  2209. : IBM-DARK      ( -- )                  \ fetch and store video mode thus
  2210.                                         \ clearing the screen.
  2211.                 VMODE@ VMODE! #OUT OFF #LINE OFF ; NO-INTERPRET
  2212.  
  2213. ICODE ?VMODE    ( --- N1 )              \ Get the video mode from DOS
  2214.                 DEC SI
  2215.                 DEC SI
  2216.                 MOV 0 [SI], BX
  2217.                 MOV AH, # $0F
  2218.                 INT $10
  2219.                 SUB AH, AH
  2220.                 MOV BX, AX
  2221.                 RET             END-ICODE
  2222.  
  2223. ICODE SET-CURSOR ( n1 --- )              \ set the cursor shape
  2224.                 MOV CX, BX
  2225.                 MOV AH, # 1
  2226.                 PUSH SI         PUSH BP
  2227.                 INT $10
  2228.                 POP BP          POP SI
  2229.                 LOAD_BX
  2230.                 RET             END-ICODE
  2231.  
  2232. : GET-CURSOR    ( --- shape )           \ get the cursor shape
  2233.                 0 $460 @L ;                     NO-INTERPRET
  2234.  
  2235. : INIT-CURSOR   ( -- )
  2236.                 GET-CURSOR SAVECUR ! ;                  NO-INTERPRET
  2237.  
  2238. : CURSOR-OFF    ( --- )
  2239.                 GET-CURSOR $2000  OR SET-CURSOR ;       NO-INTERPRET
  2240.  
  2241. : CURSOR-ON     ( --- )
  2242.                 GET-CURSOR $0F0F AND SET-CURSOR ;       NO-INTERPRET
  2243.  
  2244. : NORM-CURSOR   ( --- )
  2245.                 SAVECUR C@ DUP 1- FLIP + SET-CURSOR ;   NO-INTERPRET
  2246.  
  2247. : BIG-CURSOR    ( --- )
  2248.                 SAVECUR C@ SET-CURSOR ;                 NO-INTERPRET
  2249.  
  2250. : SAVECURSOR    ( -- )          \ save all of the current cursor stuff
  2251.                 R>
  2252.                 ATTRIB @ >R            \ save attribute
  2253.                 GET-CURSOR >R           \ cursor shape
  2254.                 #OUT @ #LINE @ 2>R    \ and position
  2255.                 >R ;                                    NO-INTERPRET
  2256.  
  2257. : RESTCURSOR    ( -- )          \ restore all of the cursor stuff
  2258.                 R>
  2259.                 2R> AT                  \ restore position
  2260.                 R> SET-CURSOR           \ shape
  2261.                 R> ATTRIB !             \ and attribute
  2262.                 >R ;                                    NO-INTERPRET
  2263.  
  2264. ICODE BDOS2     ( CX DX AL -- CX DX AX )
  2265.                 MOV AX, BX
  2266.                 MOV DX, 0 [SI]
  2267.                 MOV CX, 2 [SI]
  2268.                 MOV AH, AL      INT $21
  2269.                 MOV BX, AX
  2270.                 MOV 0 [SI], DX
  2271.                 MOV 2 [SI], CX
  2272.                 RET             END-ICODE
  2273.  
  2274. : OS2           BDOS2 255 AND ;                         NO-INTERPRET
  2275.  
  2276. ICODE BDOS      ( DX AH -- AL )
  2277.                 LODSW
  2278.                 MOV DX, AX
  2279.                 MOV AH, BL
  2280.                 INT $21
  2281.                 SUB AH, AH
  2282.                 MOV BX, AX
  2283.                 RET             END-ICODE
  2284.  
  2285. : DOSVER        ( -- n1 )
  2286.                 0 $030 BDOS $0FF AND ;                  NO-INTERPRET
  2287.  
  2288. : BYE           ( -- )
  2289.                 0 0 BDOS DROP ;                         EXECUTES> BYE
  2290.  
  2291. : DOSEMIT       ( c1 -- )
  2292.                 6 BDOS DROP #OUT INCR ;                 NO-INTERPRET
  2293.  
  2294. ICODE PR-STATUS ( n1 -- b1 )
  2295.                 MOV DX, BX      \ PRINTER NUMBER
  2296.                 MOV AH, # 2
  2297.                 PUSH SI         PUSH BP
  2298.                 INT $17
  2299.                 POP BP          POP SI
  2300.                 MOV BL, AH
  2301.                 SUB BH, BH
  2302.                 RET             END-ICODE
  2303.  
  2304. : ?PRINTER.READY ( -- f1 )
  2305.                 0 PR-STATUS ( $090 AND ) $090 = ;       NO-INTERPRET
  2306.  
  2307. CODE PEMIT      ( c1 -- )
  2308.                 MOV DX, # 0     \ PRINTER NUMBER
  2309.                 MOV AL, BL
  2310.                 MOV AH, # 0
  2311.                 PUSH SI         PUSH BP
  2312.                 INT $17
  2313.                 POP BP          POP SI
  2314.                 INC #OUT WORD
  2315.                 LOAD_BX
  2316.                 RET             END-CODE
  2317.  
  2318. : (EMIT)        ( C1 -- )
  2319.                 PRINTING @
  2320.                 IF      PEMIT
  2321.                 ELSE    DOSEMIT
  2322.                 THEN    ;                               NO-INTERPRET
  2323.  
  2324. ICODE KEY?      ( -- f1 )               \ BIOS KEY?, NO redirection!
  2325.                 DEC SI
  2326.                 DEC SI
  2327.                 MOV 0 [SI], BX
  2328.                 MOV AH, # 1
  2329.                 PUSH SI         PUSH BP
  2330.                 INT $16
  2331.                 POP BP          POP SI
  2332.                 [ASSEMBLER]
  2333.              0= IF      SUB AX, AX
  2334.                 ELSE    MOV AX, # -1
  2335.                 THEN
  2336.                 MOV BX, AX
  2337.                 RET             END-ICODE
  2338.  
  2339. : BDOSKEY?      ( -- c1 )               \ DOS KEY?, redirectable
  2340.                 255 6 BDOS $FF AND ;            NO-INTERPRET
  2341.  
  2342. : BDOSKEY       ( -- c1 )               \ DOS KEY, redirectable, RAW
  2343.                 0 7 BDOS $FF AND ;              NO-INTERPRET
  2344.  
  2345. : %KEY          ( -- c1 )               \ DOS KEY, redirectable, translates
  2346.                 BDOSKEY ?DUP 0=         \ function keys to above 128.
  2347.                 IF      BDOSKEY 128 OR
  2348.                 THEN    ;                       NO-INTERPRET
  2349.  
  2350. ' %KEY ALIAS (KEY)
  2351.  
  2352. : SPACE         ( -- )
  2353.                 BL EMIT ;                       EXECUTES> SPACE
  2354.  
  2355. : %SPACES       ( n1 -- )
  2356.                 0 MAX   ?DUP
  2357.                 IF      1-
  2358.                         FOR BL EMIT NEXT
  2359.                 THEN    ;                       NO-INTERPRET
  2360.  
  2361. : %TYPE         ( a1 n1 -- )
  2362.                 0 MAX   ?DUP
  2363.                 IF      1-
  2364.                         FOR     DUP C@ EMIT 1+
  2365.                         NEXT    DROP
  2366.                 ELSE    DROP
  2367.                 THEN    ;                               NO-INTERPRET
  2368.  
  2369. ' %TYPE ALIAS (TYPE)
  2370.  
  2371. : EEOL          ( -- )          \ Erase to end of line
  2372.                 80 #OUT @ - 0MAX SPACES ;               EXECUTES> EEOL
  2373.  
  2374. : CRLF          ( -- )
  2375.                 $0D (EMIT) $0A (EMIT)
  2376.                 #OUT OFF #LINE @ 1+ ( 24 MIN ) #LINE ! ;
  2377.  
  2378. : $>TIB         ( A1 --- )
  2379.                 COUNT DUP #TIB ! TIB SWAP CMOVE >IN OFF ; NO-INTERPRET
  2380.  
  2381. : MARGIN_INIT   ( -- )
  2382.                 LMARGIN OFF 64 RMARGIN !        \ default margins
  2383.                 8 TABSIZE ! ;                           NO-INTERPRET
  2384.  
  2385. : MS            ( n1 -- )       \ Delay n1 units of about a millisecond.
  2386.                 FOR     FUDGE @ 1+ FOR NEXT
  2387.                 NEXT    ;                               EXECUTES> MS
  2388.  
  2389. ICODE TT[']     ( -- a1 )       \ get address of routine following this one
  2390.                 DEC SI
  2391.                 DEC SI
  2392.                 MOV 0 [SI], BX
  2393.                 POP BX          \ get address where we came from
  2394.                 INC BX
  2395.                 MOV AX, BX
  2396.                 INC AX
  2397.                 INC AX
  2398.                 PUSH AX         \ push adjusted return address on return stk
  2399.                 ADD AX, CS: 0 [BX]
  2400.                 MOV BX, AX      \ BX holds address of routine following
  2401.                 RET             END-ICODE
  2402.  
  2403. : DOSIO_INIT    ( -- )          \ initialize the DOS I/O words
  2404.                 TT['] CRLF      !> CR
  2405.                 TT['] IBM-AT?   !> AT?
  2406.                 TT['] IBM-AT    !> AT             \ init AT
  2407.                 TT['] %KEY      !> KEY            \      KEY,
  2408.                 TT['] (EMIT)    !> EMIT           \      EMIT,
  2409.                 TT['] (TYPE)    !> TYPE           \      TYPE,
  2410.                 TT['] %SPACES   !> SPACES         \      SPACES
  2411.                 TT['] IBM-DARK  !> DARK           \ and  DARK
  2412.                 AT? AT ;
  2413.  
  2414. : ?LINE         ( N -- )
  2415.                 #OUT @ +  RMARGIN @ > IF CR LMARGIN @ SPACES THEN ;
  2416.                                                         NO-INTERPRET
  2417. : ?CR           ( -- )
  2418.                 0 ?LINE  ;                              NO-INTERPRET
  2419.  
  2420. 0 VALUE ABORT_FUNC
  2421.  
  2422. : ABORT         ( -- )          \ Just leave when we abort
  2423.                 ABORT_FUNC ?DUP
  2424.                 IF      EXECUTE
  2425.                 ELSE    CR BYE
  2426.                 THEN    ;                               EXECUTES> ABORT
  2427.  
  2428. : ?ABORT"       ( f1 a1 n1 -- ) \ display string a1,n1 & abort if f1 true
  2429.                 ROT
  2430.                 IF      TYPE ABORT
  2431.                 ELSE    2DROP
  2432.                 THEN    ;
  2433.  
  2434. FORTH   >FORTH
  2435.  
  2436. : %T[']         ( | <name> -- a1 )
  2437.                 F['] TT[']    RES_COMP_CALL
  2438.                 [FORTH] ' DUP RES_COMP_CALL >DTYPE C@ {S} <>
  2439.                 ABORT" is NOT a subroutine, Can ONLY ['] subroutines!" ;
  2440.                 IMMEDIATE
  2441. ' %T['] IS T[']
  2442.  
  2443. : %L[']         ( | <name> -- a1 )
  2444.                 COMPILE RES_COMP_CLL F['] TT['] X,
  2445.                 COMPILE RES_COMP_CLL [FORTH] ' DUP  X,
  2446.                 >DTYPE C@ {S} <>
  2447.                 ABORT" is NOT a subroutine, Can ONLY ['] subroutines!" ;
  2448.                 IMMEDIATE
  2449. ' %L['] IS L[']
  2450.  
  2451. : %T."          ( | string" -- )
  2452.                 [COMPILE] T"
  2453.                 F['] TYPE RES_COMP_DEFER ; IMMEDIATE
  2454. ' %T." IS T."
  2455.  
  2456. : %L."          ( | string" -- )
  2457.                 [COMPILE] L"
  2458.                 COMPILE RES_COMP_DEF F['] TYPE X, ; IMMEDIATE
  2459. ' %L." IS L."
  2460.  
  2461. : %TABORT"      ( | string" -- )
  2462.                 [COMPILE] T" F['] ?ABORT" COMP_CALL ; IMMEDIATE
  2463. ' %TABORT" IS TABORT"
  2464.  
  2465. : %LABORT"      ( | string" -- )
  2466.                 [COMPILE] L"
  2467.                 COMPILE <'> COMPILE ?ABORT" COMPILE COMP_CALL ; IMMEDIATE
  2468. ' %LABORT" IS LABORT"
  2469.  
  2470. TARGET  >LIBRARY
  2471.  
  2472.                                 \ n1 = DS: ram in bytes for target program
  2473. : SET_MEMORY    ( n1 -- )       \ adjust allocated memory for target
  2474.                 PAD 40 + UMAX                   \ clip to above used ram
  2475.                 65500 400 -
  2476.                 UMIN DUP PAD !                  \ save end of DS: mem
  2477.                 DUP 2+ DUP TIB0 ! 'TIB !        \ reset TIB
  2478.                 DUP SP0 ! SP!                   \ reset data stack
  2479.                 RP@ RP0 @ OVER - >R PAD @ 300 + R@ - R@ CMOVE R>
  2480.                                                 \ move return stack down
  2481.                 PAD @ 300 + DUP RP0 ! SWAP - RP!        \ reset return stack
  2482.                 PAD @ 400 + PARAGRAPH                   \ paragraphs desired
  2483.                 ?DS: ?CS: - +                   \ + CODE memory + segments
  2484.                 ?CS: SWAP SETBLOCK              \ adj memory
  2485.                 IF      CR ." Couldn't adjust memory size!"
  2486.                         BYE
  2487.                 THEN    ;
  2488.  
  2489. : TAB           ( -- )
  2490.                 #OUT @ TABSIZE @ MOD TABSIZE @ SWAP - SPACES ;
  2491.                                                         EXECUTES> TAB
  2492.  
  2493. : BEEP          ( -- )
  2494.                 7 (EMIT) #OUT DECR ;                   EXECUTES> BEEP
  2495.  
  2496. : HOLD          ( char -- )
  2497.                 HLD DECR HLD @ C!   ;                   NO-INTERPRET
  2498.  
  2499. : <#            ( -- )
  2500.                 PAD  HLD  !  ;                          NO-INTERPRET
  2501.  
  2502. : #>            ( d# -- addr len )
  2503.                 2DROP  HLD  @  PAD  OVER  -  ;          NO-INTERPRET
  2504.  
  2505. : SIGN          ( n1 -- )
  2506.                 0< IF  ASCII -  HOLD  THEN  ;           NO-INTERPRET
  2507.  
  2508. : #             ( d1 -- d2 )
  2509.                 BASE @ MU/MOD ROT 9 OVER <
  2510.                 IF  7 + THEN ASCII 0  +  HOLD  ;        NO-INTERPRET
  2511.  
  2512. : #S            ( d -- 0 0 )
  2513.                 BEGIN  #  2DUP  OR  0=  UNTIL  ;        NO-INTERPRET
  2514.  
  2515. : (U.)          ( u -- a l )
  2516.                 0    <# #S #>   ;                       NO-INTERPRET
  2517.  
  2518. : U.            ( u -- )
  2519.                 (U.)   TYPE SPACE   ;                   EXECUTES> U.
  2520.  
  2521. : U.R           ( u l -- )
  2522.                 >R   (U.)   R> OVER - SPACES   TYPE   ; EXECUTES> U.R
  2523.  
  2524. : (.)           ( n -- a l )
  2525.                 DUP ABS 0   <# #S   ROT SIGN   #>   ;   NO-INTERPRET
  2526.  
  2527. : .             ( n -- )
  2528.                 (.)   TYPE SPACE   ;                    EXECUTES> .
  2529.  
  2530. : .R            ( n l -- )
  2531.                 >R   (.)   R> OVER - SPACES   TYPE   ;  EXECUTES> .R
  2532.  
  2533. : (UD.)         ( ud -- a l )
  2534.                 <# #S #>   ;                            NO-INTERPRET
  2535.  
  2536. : UD.           ( ud -- )
  2537.                 (UD.)   TYPE SPACE   ;                  NO-INTERPRET
  2538.  
  2539. : UD.R          ( ud l -- )
  2540.                 >R   (UD.)   R> OVER - SPACES   TYPE  ; NO-INTERPRET
  2541.  
  2542. : (D.)          ( d -- a l )
  2543.                 TUCK DABS   <# #S   ROT SIGN  #>   ;    NO-INTERPRET
  2544.  
  2545. : D.            ( d -- )
  2546.                 (D.)   TYPE SPACE   ;                   NO-INTERPRET
  2547.  
  2548. : D.R           ( d l -- )
  2549.                 >R   (D.)   R> OVER - SPACES   TYPE   ; NO-INTERPRET
  2550.  
  2551. : DOS_EXPECT    ( a1 n1 -- )
  2552.                 AT? >R >R
  2553.                 %DOSEXPECT DUP SPAN ! R> + R> AT ;      NO-INTERPRET
  2554.  
  2555. ALSO HTARGET DEFINITIONS TARGET
  2556.  
  2557. : DOEXP1        ( A1 C1 N1 -- A2 N2 )   \ n2 = loop count
  2558.                 OVER $C7 =      ( HOME )        \ if Home, then clear line
  2559.                 IF      DUP>R AT? >R SWAP - R> 2DUP AT R@ SPACES AT R>
  2560.                         NEGATE >R DROP R@ + R>
  2561.                         EXIT
  2562.                 THEN
  2563.                 OVER $08 =      ( BACKSPACE )   \ if BS then backup one
  2564.                 IF      0=
  2565.                         IF      DROP BEEP 0     \ or BEEP if at beginning
  2566.                         ELSE    (EMIT)         \ backup one char
  2567.                                 BL (EMIT)
  2568.                                 8 (EMIT)       \ erase chars space
  2569.                                 -4 #OUT +!
  2570.                                 1- -1
  2571.                         THEN    EXIT            \ leave if BACKSPACE
  2572.                 THEN    DROP                    \ discard current index
  2573.                 DUP $1B =       ( ESC )         \ char = ESC?, then cancel
  2574.                 IF      DROP                    \ discard char
  2575.                         #EXSTRT @ ?DUP
  2576.                         IF      SPAN @ SWAP ABS SPAN !
  2577.                         ELSE    SPAN @ SPAN OFF \ skip to end
  2578.                         THEN
  2579.                         ESC_FLG ON              \ set escaped flag
  2580.                 ELSE                            \ else emit, and bump to next
  2581.                         DUP EMIT OVER C! 1+ 1
  2582.                 THEN    ;
  2583.  
  2584. : #EXSTRT_@+    ( a1 -- a2 n1 )         \ adj a1 by #exstrt
  2585.                 #EXSTRT @ DUP>R + R> DUP NEGATE #EXSTRT ! ;
  2586.  
  2587. TARGET DEFINITIONS PREVIOUS
  2588.  
  2589. : #EXPECT       ( a1 n1 n1 -- )         \ EXPECT chars n1 into addr a1.
  2590.                                         \ starting at char n2 in string
  2591.                 0MAX    DUP #EXSTRT ! ?DUP
  2592.                 IF      2 PICK SWAP TYPE        \ display text sofar
  2593.                 THEN
  2594.                 ESC_FLG OFF
  2595.                 DUP SPAN ! 0
  2596.                 ?DO     #EXSTRT @ 0>
  2597.                         IF      #EXSTRT_@+
  2598.                         ELSE    KEY DUP $0D =   \ if CR then leave, done
  2599.                                 IF      DROP I SPAN ! LEAVE
  2600.                                 ELSE    I DOEXP1
  2601.                                 THEN
  2602.                         THEN
  2603.                 +LOOP   DROP ;
  2604.  
  2605. : EXPECT        ( a1 n1 -- )            \ expect chars n1 into addr a1
  2606.                 0 #EXPECT ;                             NO-INTERPRET
  2607.  
  2608. : QUERY         ( -- )
  2609.                 TIB 80 EXPECT  SPAN @ #TIB ! >IN OFF  ; NO-INTERPRET
  2610.  
  2611. : UPC           ( c1 -- c2 )
  2612.                 DUP 'a' 'z' BETWEEN
  2613.                 IF      $5F AND
  2614.                 THEN    ;                               NO-INTERPRET
  2615.  
  2616. : UPPER         ( addr len -- )
  2617.                 BOUNDS
  2618.                 ?DO     I C@ UPC I C!
  2619.                 LOOP    ;                               NO-INTERPRET
  2620.  
  2621. : ?UPPERCASE    ( a1 -- a1 )
  2622.                 CAPS @
  2623.                 IF      DUP COUNT UPPER
  2624.                 THEN    ;                               NO-INTERPRET
  2625.  
  2626. : NOOP          ( -- )
  2627.                 ;                                       EXECUTES> NOOP
  2628.  
  2629. : H.R           ( n1 n2 -- )
  2630.                 BASE @ >R HEX U.R R> BASE ! ;
  2631.  
  2632. : H.            ( n1 -- )
  2633.                 1 H.R SPACE ;                           EXECUTES> H.
  2634.  
  2635. M: ">$          ( a1 n1 -- a2 )
  2636.                 DROP 1- ;                               NO-INTERPRET
  2637.  
  2638. M: U<=          ( u1 u2 -- f )   U> NOT   ;             NO-INTERPRET
  2639. M: U>=          ( u1 u2 -- f )   U< NOT   ;             NO-INTERPRET
  2640. M: <=           ( n1 n2 -- f )    > NOT   ;             NO-INTERPRET
  2641. M: >=           ( n1 n2 -- f )    < NOT   ;             NO-INTERPRET
  2642. M: 0>=          ( n1 n2 -- f )   0< NOT   ;             NO-INTERPRET
  2643. M: 0<=          ( n1 n2 -- f )   0> NOT   ;             NO-INTERPRET
  2644.  
  2645. : ?KEYPAUSE     ( --- )         \ Pause if key pressed
  2646.                 KEY?
  2647.                 IF      KEY 27 = IF ABORT THEN
  2648.                         KEY 27 = IF ABORT THEN
  2649.                 THEN    ;                               NO-INTERPRET
  2650.  
  2651. 0 VALUE DUMP_OFF
  2652.  
  2653. : DUMP_1LINE    ( seg a1 -- seg a2 )
  2654.                 CR DUP DUMP_OFF + 4 H.R ."  | "
  2655.                 2DUP 15 FOR 2DUP C@L 3 H.R 1+ NEXT 2DROP ."  | "
  2656.                      15 FOR 2DUP C@L $7F AND BL MAX EMIT 1+ NEXT ;
  2657.  
  2658. : %LDUMP        ( seg addr len -- )
  2659.                 0
  2660.                 DO      DUMP_1LINE ?KEYPAUSE
  2661.             16 +LOOP    2DROP   ;
  2662.  
  2663. : LDUMP         ( seg addr len -- )
  2664.                 OFF> DUMP_OFF %LDUMP ;
  2665.  
  2666. : DUMP          ( addr len -- )
  2667.                 ?DS: -ROT LDUMP ;                       EXECUTES> DUMP
  2668.  
  2669. : #input        ( --- n1 )
  2670.                 query bl word number? 0= abort" Must be a NUMBER" drop ;
  2671.  
  2672. ' !> ALIAS =: IMMEDIATE
  2673. ' !> ALIAS IS IMMEDIATE
  2674.  
  2675. >FORTH
  2676.  
  2677.