home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / FORTH / FIG_4TH.ZIP / 4THMAIN.ASM < prev    next >
Encoding:
Assembly Source File  |  1987-01-14  |  48.5 KB  |  2,497 lines

  1. TITLE Forth Interest Group  8086 FORTH
  2. NAME FORTH
  3. PAGE 62,132
  4. .SALL
  5. .XCREF
  6.  
  7. COMMENT \
  8.         Forth Interest Group  8086 FORTH 
  9.  
  10.         Version 1.0
  11.  
  12.         Original implementation by Thomas Newman
  13.         made available by the
  14.             FORTH INTEREST GROUP
  15.             P.O. Box 1105
  16.             San Carlos, CA  94070
  17.  
  18.         Modified by
  19.             Joe Smith
  20.             U. of Penn./Dept. of Chemistry
  21.             34th & Spruce St.
  22.             Philadelphia, PA  19104
  23.             215 898-4797
  24.  
  25.         Available through
  26.             SIG/86
  27.             c/o Joseph Boykin
  28.             47-4 Sheridan Drive
  29.             Shrewsbury, MA  01545
  30.             617 845-1074
  31.  
  32.         Latest revision: June, 1983
  33.  
  34. This is a revision of fig-FORTH which includes the following changes:
  35.  
  36.     Source compatible with Microsoft's 8086 Macro Assembler
  37.  
  38.     Macros for dictionary headers
  39.  
  40.     Complete interface to MS-DOS, including screen files
  41.  
  42.     Command line arguments are interpreted
  43.  
  44.     All i/o is redirectable through execution vectors
  45.  
  46. \
  47. SUBTTL Assembly switches (TRUE/FALSE) and EQUATES
  48. PAGE
  49.  
  50.  
  51. INCLUDE    4TH-OPTS.H        ;assembly options
  52.  
  53. ; Version number:
  54.  
  55. FIGREL        EQU    1    ;fig release number
  56. FIGREV        EQU    0    ;fig revision number
  57. USRVER        EQU    0    ;user version number,0-25,printed as A-Z
  58.  
  59. ; Memory allocation parameters:
  60.  
  61. EM        EQU    0000        ;64K top of memory + 1
  62. NSCR        EQU    8        ;No. of 1K block buffers
  63. BUFSIZE        EQU    1024        ;size of FORTH's disk buffers
  64. US        EQU    80        ;User area size ( in bytes )
  65. RTS        EQU    160        ;Return stack/TIB size
  66.  
  67. BUF1        EQU    EM-(NSCR*(BUFSIZE+4))    ;first buffer addr.
  68. INITR0        EQU    BUF1-US        ;Start of return stack (R0)
  69. INITS0        EQU    INITR0-RTS    ;Start of param. stack (S0)
  70.  
  71. ; ASCII characters used
  72.  
  73. ANUL        EQU    0        ;ASCII NUL
  74. BELL        EQU    7        ;ASCII bell: ^G
  75. BSOUT        EQU    8        ;output backspace: ^H
  76. LF        EQU    10        ;ASCII linefeed
  77. FF        EQU    12        ;ASCII form feed
  78. ACR        EQU    13        ;ASCII carriage return
  79. BSIN        EQU    127        ;input delete char: DEL
  80.  
  81. SUBTTL Main entry points and COLD start data
  82. PAGE +
  83.  
  84.  
  85. INCLUDE    4TH-LIB.MAC        ;Required support macros
  86.  
  87. ; Note: FORTH only uses one segment, and runs as a .COM program
  88.  
  89. MAIN        SEGMENT
  90.         ASSUME    CS:MAIN,DS:MAIN,SS:MAIN,ES:MAIN
  91.  
  92.         ORG    100H
  93.  
  94. ORIG:         NOP
  95.         JMP    CLD        ;vector to COLD start
  96.         NOP
  97.         JMP    WRM        ;vector to WARM start
  98.  
  99.  
  100.         DB    FIGREL        ;version # printed by COLD
  101.         DB    FIGREV
  102.         DB    USRVER
  103.         DB    0EH        ;version attributes
  104.         DW    LASTNFA        ;top word in FORTH vocabulary
  105.         DW    BSIN        ;backspace recognised by EXPECT
  106.         DW    INITR0        ;initial UP
  107.  
  108. ; COLD start moves the following to USER var's. 3-10
  109. ; MUST BE IN SAME ORDER AS USER VARIABLES
  110.  
  111.         DW    INITS0        ;  S0
  112.         DW    INITR0        ;  R0
  113.         DW    INITS0        ;  TIB
  114.         DW    32        ;  WIDTH
  115.         DW    0        ;  WARNING
  116.         DW    INITDP        ;  FENCE
  117.         DW    INITDP        ;  DP
  118.         DW    FORTH+6        ;  VOC-LINK
  119.  
  120. ; CPU id printed by COLD
  121.  
  122.     IF    _ALIGN
  123.         DD    0B3260005H    ;"8086" ( in base 36 ! )
  124.     ELSE
  125.         DD    0B3280005H    ;"8088" ( in base 36 ! )
  126.     ENDIF
  127.  
  128. UP         DW    INITR0        ;user area pointer
  129. RPP         DW    INITR0        ;return stack pointer
  130.  
  131.     $REPORT    <Boot parameters completed>
  132.     $REPORT    <LIMIT    =>,%EM
  133.     $REPORT    <FIRST    =>,%BUF1
  134.     $REPORT    <R0    =>,%INITR0
  135.     $REPORT    <S0    =>,%INITS0
  136.  
  137. SUBTTL FORTH register usage
  138. PAGE +
  139.  
  140.  
  141. COMMENT \
  142.  
  143. FORTH    8086    Preservation rules
  144. ------------------------------------------------------------------------
  145. IP    SI    Interpreter pointer
  146.         Must be preserved across words
  147.         NOTE: Also preserve the direction flag (always UP)!
  148.  
  149. W    DX    Working register
  150.         Jump to label DPUSH will push contents onto
  151.         the parameter stack before falling into APUSH
  152.  
  153. SP    SP    Parameter stack pointer
  154.         Must be preserved across words
  155.  
  156. RP    BP    Return stack pointer
  157.         Must be preserved across words
  158.  
  159.     AX    General purpose register
  160.         Jump to label APUSH pushes contents onto
  161.         the parameter stack
  162.  
  163.     CS,DS,SS
  164.         Must be preserved across words
  165.  
  166.         All other registers are available
  167.  
  168. \
  169. SUBTTL Comment conventions
  170. PAGE
  171.  
  172.  
  173. COMMENT \
  174.  
  175. ==    means    is equal to
  176. :=    means    is assigned the value
  177.  
  178. name    ==    address of name
  179. (name)    ==    contents at address name
  180. ((name))==    contents at address contained in name
  181.  
  182. NFA    ==    Name Field Address
  183. LFA    ==    Link Field Address
  184. CFA    ==    Code Field Address
  185. PFA    ==    Parameter Field Address
  186.  
  187. S1,S2    ==    parameter stack: top item, next item
  188. R1,R2    ==    return stack: top word, next word
  189.  
  190. LSB    ==    Least Significant Bit
  191. MSB    ==    Most Significant Bit
  192. LB,LW    ==    Low Byte, Low Word
  193. HB,HW    ==    High Byte, High Word
  194. \
  195.  
  196.     IF    _DEBUG
  197. SUBTTL Debugging support
  198. PAGE +
  199.  
  200. BIP         DW    0    ;breakpoint start address
  201. BIPE         DW    0    ;breakpoint end address
  202.  
  203. COMMENT \
  204.  
  205. BIP    BIPE    effect
  206. -----    -----    -------------------------------------------
  207. 0    ?    trace off
  208. -1    ?    trace all NEXT calls
  209. addr1    0    trace addr1 only
  210. addr1    addr2    trace NEXT calls between addr1 and addr2
  211.  
  212. NOTE: addr1/addr2 can't be CFA's
  213. \
  214.  
  215. ; NEXT with code to trace FORTH word execution
  216.  
  217. TNEXT:         PUSHF        ;save executing word's data
  218.         PUSH    AX
  219.         MOV    AX,BIP    ;addr1
  220.         OR    AX,AX
  221.         JZ    TNEXT2    ;no trace if addr1==0
  222.         CMP    AX,-1
  223.         JZ    TNEXT1    ;trace all
  224.         CMP    AX,SI
  225.         JZ    TNEXT1    ;in range, so trace
  226.         JA    TNEXT2    ;not in range
  227.         MOV    AX,BIPE
  228.         OR    AX,AX
  229.         JZ    TNEXT2    ;trace addr1 only
  230.         CMP    AX,SI
  231.         JB    TNEXT2    ;no longer in range
  232.  
  233. ; Pause on address
  234.  
  235. TNEXT1:     POP    AX    ;restore executing word's reg's.
  236.         POPF
  237.         INT    3    ;Break to DEBUG
  238. BREAK:         JMP    SHORT TNEXT3    ;continue
  239.  
  240. ; No pause, restore registers
  241.  
  242. TNEXT2:     POP    AX
  243.         POPF
  244. TNEXT3:     LODSW        ;AX:=(IP)
  245.         MOV    BX,AX
  246.         JMP    SHORT NEXT1
  247.  
  248.     $REPORT    <Debug trace included>
  249.     ENDIF
  250. SUBTTL Inner interpreter, DPUSH, APUSH entry points
  251. PAGE +
  252.  
  253.  
  254. DPUSH:         PUSH    DX    ;common entry point; DX, AX to S2, S1
  255. APUSH:         PUSH    AX    ;common entry point, AX to S1
  256.  
  257. NEXT:
  258.     IF    _DEBUG
  259.         JMP    TNEXT
  260.     ELSE
  261.         LODSW            ; AX:=(IP), IP:=IP+1
  262.         MOV    BX,AX
  263.     ENDIF
  264.  
  265. NEXT1:         MOV    DX,BX
  266.         INC    DX        ; W:=(IP)+1
  267.         JMP    WORD PTR [BX]    ;to CFA
  268. SUBTTL FORTH dictionary 
  269. PAGE +
  270.  
  271.  
  272. ;=C   LIT    push an inline literal            -- n
  273.  
  274.         $CODE    83H,LI,T,LIT
  275.         LODSW
  276.         JMP    APUSH
  277.  
  278. ;=C   EXECUTE    executes the word at CFA        CFA -- ?
  279.  
  280.         $CODE    87H,EXECUT,E,EXEC
  281.         POP    BX
  282.         JMP    NEXT1
  283.  
  284. ;=C   BRANCH    adds an inline offset to IP        --
  285.  
  286.         $CODE    86H,BRANC,H,BRAN
  287. BRAN1:        ADD    SI,[SI]        ; IP:=IP+(IP)
  288.         JMP    NEXT
  289.  
  290. ;=C   0BRANCH    branch if f is zero            f --
  291.  
  292.         $CODE    87H,0BRANC,H,ZBRAN
  293.         POP    AX
  294.         OR    AX,AX
  295.         JZ    BRAN1        ;f==0, so branch
  296.         INC    SI        ;point IP to next word
  297.         INC    SI
  298.         JMP    NEXT
  299.  
  300. ;=C   (LOOP)    execution time loop code        --
  301.  
  302.         $CODE    86H,(LOOP,),XLOOP
  303.         MOV    BX,1
  304. XLOO1:         ADD    [BP],BX        ;R1:=R1+1
  305.         MOV    AX,[BP]
  306.         SUB    AX,2[BP]    ;compare new index to limit
  307.         XOR    AX,BX
  308.         JS    BRAN1        ;branch - keep looping
  309.  
  310.         ADD    BP,4        ;end of loop, drop R1, R2
  311.         INC    SI        ;skip branch offset
  312.         INC    SI
  313.         JMP    NEXT
  314.  
  315. ;=C   (+LOOP)    (LOOP) with increment on S1        n --
  316.  
  317.         $CODE    87H,(+LOOP,),XPLOO
  318.         POP    BX
  319.         JMP    XLOO1
  320.  
  321. ;=C   (DO)    run-time loop initialization        n2 n1 --
  322.  
  323.         $CODE    84H,(DO,),XDO
  324.         POP    DX        ;index
  325.         POP    AX        ;limit
  326.         XCHG    BP,SP        ;put them on the return stack
  327.         PUSH    AX        ;R2:=S2
  328.         PUSH    DX        ;R1:=S2
  329.         XCHG    BP,SP
  330.         JMP    NEXT
  331.  
  332. ;=C   I        leave index value            -- n
  333.  
  334.         $CODE    81H,,I,IDO
  335.         MOV    AX,[BP]        ;AX:=R1 (index)
  336.         JMP    APUSH
  337.  
  338. ;=C   DIGIT    convert c to binary using base n1    c n1 -- [n2] f
  339.  
  340.         $CODE    85H,DIGI,T,DIGIT
  341.         POP    DX        ;base
  342.         POP    AX        ;ASCII char
  343.         SUB    AL,'0'
  344.         JB    DIGI2        ;error if c < '0'
  345.         CMP    AL,9
  346.         JBE    DIGI1        ;number 0-9
  347.         SUB    AL,7
  348.         CMP    AL,10        ;number A-Z?
  349.         JB    DIGI2        ;no, error
  350. DIGI1:         CMP    AL,DL
  351.         JAE    DIGI2        ;error if digit > base
  352.         SUB    DX,DX
  353.         MOV    DL,AL        ;new binary number
  354.         MOV    AL,1        ;f==TRUE if OK
  355.         JMP    DPUSH
  356. DIGI2:         SUB    AX,AX
  357.         JMP    APUSH        ;f==FALSE if error
  358.  
  359. PAGE
  360.  
  361.  
  362. ;=C*  (FIND)    dictionary search primtive        a1 NFA -- [PFA b] f
  363.  
  364.         $CODE    86H,(FIND,),PFIND
  365.         MOV    AX,DS
  366.         MOV    ES,AX        ;DI defaults to ES
  367.         POP    BX        ;BX:=NFA
  368.         POP    CX        ;CX:=a1 ( search string )
  369.  
  370. PFIN1:         MOV    DI,CX        ;get addr
  371.         MOV    AL,[BX]        ;get word length
  372.         MOV    DL,AL
  373.         XOR    AL,[DI]
  374.         AND    AL,3FH        ;check lengths+smudge bit
  375.         JNZ    PFIN5        ;lengths differ
  376.  
  377. PFIN2:         INC    BX        ;length matches, check chars
  378.         INC    DI
  379.         MOV    AL,[BX]
  380.         XOR    AL,[DI]
  381.         ADD    AL,AL        ;this checks bit 8
  382.         JNZ    PFIN5        ;chars differ
  383.         JNB    PFIN2        ;OK so far
  384.  
  385.     IF    _ALIGN
  386.         ADD    BX,6        ;Compute PFA ( could be 5 or 6)
  387.         AND    BX,0FFFEH    ;Clear LSB to align
  388.     ELSE
  389.         ADD    BX,5
  390.     ENDIF
  391.         ;end of word (bit 8 set), a match
  392.  
  393.         PUSH    BX        ;S3:=PFA
  394.         MOV    AX,1        ;f:=TRUE
  395.         SUB    DH,DH        ;DX:=length byte
  396.         JMP    DPUSH        ;S2:=f, S1:=l
  397.  
  398.         ; No match, try the next dictionary entry
  399.  
  400. PFIN5:         INC    BX        ;advance BX to LFA
  401.         JB    PFIN6        ;bit 8 set - must be the end
  402.         MOV    AL,[BX]
  403.         ADD    AL,AL
  404.         JMP    PFIN5
  405. PFIN6:
  406.  
  407.     IF    _ALIGN
  408.         INC    BX        ;This could be one too many...
  409.         AND    BX,0FFFEH    ;Clear LSB to align
  410.     ENDIF
  411.  
  412.         MOV    BX,[BX]        ;BX:=(LFA)
  413.         OR    BX,BX        ;start of dictionary?
  414.         JNZ    PFIN1        ;no, keep looking
  415.         MOV    AX,0        ;no match, f:=FALSE
  416.         JMP    APUSH        ;S1:=f
  417.  
  418. PAGE
  419.  
  420.  
  421. ;=C   ENCLOSE    text scanning primitive            a1 c -- a1 n1 n2 n3
  422.  
  423.         $CODE    87H,ENCLOS,E,ENCL
  424.         POP    AX        ;delimiter c
  425.         POP    BX        ;text addr
  426.         PUSH    BX        ;S4:=text addr
  427.         MOV    AH,0
  428.         MOV    DX,-1        ;DX is counter
  429.         DEC    BX        ;BX points to text
  430.  
  431.         ; Scan to first non-delimiter
  432.  
  433. ENCL1:         INC    BX        ;next char
  434.         INC    DX        ;count it
  435.         CMP    AL,[BX]        ;delimiter found?
  436.         JZ    ENCL1        ;not yet, keep looking
  437.         PUSH    DX        ;yes, S3:=count
  438.         CMP    AH,[BX]        ;found NUL char?
  439.         JNZ    ENCL2        ;no...
  440.         MOV    AX,DX        ;yes, n2:=n3
  441.         INC    DX        ;n3:=n3+1
  442.         JMP    DPUSH        ;exit
  443.  
  444.         ; Enclose text to first delimiter
  445.  
  446. ENCL2:         INC    BX
  447.         INC    DX
  448.         CMP    AL,[BX]
  449.         JZ    ENCL4        ;found it...
  450.         CMP    AH,[BX]        ;NUL?
  451.         JNZ    ENCL2        ;no, keep looking
  452.  
  453.         ; Found NUL at end of text
  454.  
  455. ENCL3:         MOV    AX,DX
  456.         JMP    DPUSH
  457.  
  458.         ; Found delimiter
  459.  
  460. ENCL4:         MOV    AX,DX        ;count to delimiter
  461.         INC    AX        ;count to first > delimiter
  462.         JMP    DPUSH        ;S2, S1
  463.  
  464. SUBTTL Input/output primitives
  465. PAGE
  466.  
  467.  
  468. ;=:*  EMIT    char output                c --
  469.  
  470.         $COLON    84H,EMI,T,EMIT
  471.         DW    TICKEMIT,    AT,    EXEC
  472.         DW    ONE,OUTT
  473.         DW    PSTOR,SEMIS
  474.  
  475. ;=:*  KEY    char input                -- c
  476.  
  477.         $COLON    83H,KE,Y,KEY
  478.         DW    TICKEY,    AT,    EXEC,    SEMIS
  479.  
  480. ;=C   ?TERMINAL    console status                -- f
  481.  
  482.         $CODE    89H,?TERMINA,L,QTERM
  483.         JMP    PQTER
  484.  
  485. ;=:*  CR    output carriage return/line feed    --
  486.  
  487.         $COLON 82H,C,R,CR
  488.         DW    TICKCR,    AT,    EXEC,    SEMIS
  489.  
  490. SUBTTL
  491. PAGE
  492.  
  493.  
  494. ;=C   CMOVE    byte block move                a1 a2 n --
  495.  
  496.         $CODE    85H,CMOV,E,CMOVE
  497.         CLD            ;count up
  498.         MOV    BX,SI        ;save IP
  499.         POP    CX        ;move count
  500.         POP    DI        ;a2 ( destination )
  501.         POP    SI        ;a1 ( source )
  502.         MOV    AX,DS
  503.         MOV    ES,AX        ;intrasegment only
  504.     REP    MOVSB            ;all that for this?
  505.         MOV    SI,BX
  506.         JMP    NEXT
  507.  
  508. ;=C   U*    unsigned mixed multiply            u1 u2 -- ud
  509.  
  510.         $CODE    82H,U,*,USTAR
  511.         POP    AX
  512.         POP    BX
  513.         MUL    BX
  514.         XCHG    AX,DX        ;S1:=MSW, S2:=LSW
  515.         JMP    DPUSH
  516.  
  517. ;=C   U/    unsigned mixed divide            ud u -- urem uquot
  518.  
  519.         $CODE    82H,U,/,USLAS
  520.         POP    BX        ;BX:=divisor
  521.         POP    DX        ;DX:=MSW of dividend
  522.         POP    AX        ;AX:=LSW
  523.         CMP    DX,BX        ;0?
  524.         JNB    DZERO
  525.         DIV    BX
  526.         JMP    DPUSH
  527. DZERO:         MOV    AX,-1        ;divide by zero! leave -1
  528.         MOV    DX,AX
  529.         JMP    DPUSH
  530.  
  531. ;=C   AND    bitwise AND                n n -- n
  532.  
  533.         $CODE    83H,AN,D,ANDD
  534.         POP    AX
  535.         POP    BX
  536.         AND    AX,BX
  537.         JMP    APUSH
  538.  
  539. ;=C   OR    bitwise OR                n n -- n
  540.  
  541.         $CODE    82H,O,R,ORR
  542.         POP    AX
  543.         POP    BX
  544.         OR    AX,BX
  545.         JMP    APUSH
  546.  
  547. ;=C   XOR    bitwise exclusive OR            n n -- n
  548.  
  549.         $CODE    83H,XO,R,XORR
  550.         POP    AX
  551.         POP    BX
  552.         XOR    AX,BX
  553.         JMP    APUSH
  554.  
  555. ;=C   SP@    push current parameter stack pointer    -- SP
  556.  
  557.         $CODE    83H,SP,@,SPAT
  558.         MOV    AX,SP
  559.         JMP    APUSH
  560.  
  561. ;=C   SP!    reset parameter stack            ? --
  562.  
  563.         $CODE    83H,SP,!!!!,SPSTO
  564.         MOV    BX,UP        ;USER variable base addr
  565.         MOV    SP,6[BX]    ;S0 is 6 bytes above base
  566.         JMP    NEXT
  567.  
  568. ;=C   RP@    push current RP onto parameter stack    -- RP
  569.  
  570.         $CODE    83H,RP,@,RPAT
  571.         MOV    AX,BP
  572.         JMP    APUSH
  573.  
  574. ;=C   RP!    reset return stack            ? --
  575.  
  576.         $CODE    83H,RP,!!!!,RPSTO
  577.         MOV    BX,UP        ;USER variable base addr
  578.         MOV    BP,8[BX]    ;offset of R0 is 8
  579.         JMP    NEXT
  580.  
  581. ;=C   ;S    end of screen or run time colon word    --
  582.  
  583.         $CODE    82H,!!!;,S,SEMIS
  584.         MOV    SI,[BP]        ;IP:=R1 - pop return stack
  585.         INC    BP        ;adjust RP
  586.         INC    BP
  587.         JMP    NEXT
  588.  
  589. ;=C   LEAVE    force loop exit                --
  590.  
  591.         $CODE    85H,LEAV,E,LEAVE
  592.         MOV    AX,[BP]
  593.         MOV    2[BP],AX    ;limit:=index
  594.         JMP    NEXT
  595.  
  596. ;=C   >R    push parm. stack to return stack    n --
  597.  
  598.         _NFA    = $
  599.         DB    82H,'>','R'+80H        ;macro can't handle it!
  600.         $LINKS    $+2,TOR
  601.  
  602.         POP    BX        ;BX:=S1
  603.         DEC    BP        ;adjust RP
  604.         DEC    BP
  605.         MOV    [BP],BX        ;push it
  606.         JMP    NEXT
  607.  
  608. ;=C   R>    pop return stack to parm. stack        -- n
  609.  
  610.         $CODE    82H,R,!!!>,FROMR
  611.         MOV    AX,[BP]        ;AX:=R1
  612.         INC    BP        ;adjust RP
  613.         INC    BP
  614.         JMP    APUSH
  615.  
  616. ;=C   R        top of return stack to parm. stack    -- n
  617.  
  618.         $NAME    81H,,R
  619.         $LINKS    IDO+2,RR    ;synonym for I
  620.  
  621. ;=C   0=    test top of stack for zero        n -- f
  622.  
  623.         $CODE    82H,0,=,ZEQU
  624.         POP    AX
  625.         OR    AX,AX
  626.         MOV    AX,1
  627.         JZ    ZEQU1
  628.         DEC    AX
  629. ZEQU1:        JMP    APUSH
  630.  
  631. ;=C   0<    test top of stack for negative value    n -- f
  632.  
  633.         $CODE    82H,0,!!!<,ZLESS
  634.         POP    AX
  635.         OR    AX,AX
  636.         MOV    AX,1
  637.         JS    ZLESS1
  638.         DEC    AX
  639. ZLESS1:        JMP    APUSH
  640.  
  641. ;=C   +        16-bit addition                n1 n2 -- nsum
  642.  
  643.         $CODE    81H,,+,PLUS
  644.         POP    AX
  645.         POP    BX
  646.         ADD    AX,BX
  647.         JMP    APUSH
  648.  
  649. ;=C   D+    32-bit addition                d1 d2 -- dsum
  650.  
  651.         $CODE    82H,D,+,DPLUS
  652.         POP    AX        ;AX:=d2 MSW
  653.         POP    DX        ;DX:=d2 LSW
  654.         POP    BX        ;BX:=d1 MSW
  655.         POP    CX        ;CX:=d1 LSW
  656.         ADD    DX,CX        ;add low words
  657.         ADC    AX,BX        ;add high words with carry
  658.         JMP    DPUSH
  659.  
  660. ;=C   MINUS    16-bit two's complement            n -- -n
  661.  
  662.         $CODE    85H,MINU,S,MINUS
  663.         POP    AX
  664.         NEG    AX
  665.         JMP    APUSH
  666.  
  667. ;=C   DMINUS    32-bit two's complement            d -- -d
  668.  
  669.         $CODE    86H,DMINU,S,DMINU
  670.         POP    BX        ;MSW
  671.         POP    CX        ;LSW
  672.         SUB    AX,AX
  673.         MOV    DX,AX
  674.         SUB    DX,CX        ;subtract from 0
  675.         SBB    AX,BX        ;again for high word
  676.         JMP    DPUSH
  677.  
  678. ;=C   OVER    copy second stack item to top        n1 n2 -- n1 n2 n1
  679.  
  680.         $CODE    84H,OVE,R,OVER
  681.         POP    DX
  682.         POP    AX
  683.         PUSH    AX
  684.         JMP    DPUSH
  685.  
  686. ;=C   DROP    throw out top stack item        n --
  687.  
  688.         $CODE    84H,DRO,P,DROP
  689.         POP    AX
  690.         JMP    NEXT
  691.  
  692. ;=C   SWAP    exchange top two stack items        n1 n2 -- n2 n1
  693.  
  694.         $CODE    84H,SWA,P,SWAP
  695.         POP    DX
  696.         POP    AX
  697.         JMP    DPUSH
  698.  
  699. ;=C   DUP    duplicate the top stack item        n -- n n
  700.  
  701.         $CODE    83H,DU,P,DUPP
  702.         POP    AX
  703.         PUSH    AX
  704.         JMP    APUSH
  705.  
  706. ;=C   2DUP    duplicate the top two stack items    n1 n2 -- n1 n2 n1 n2
  707.  
  708.         $CODE    84H,2DU,P,TDUP
  709.         POP    AX
  710.         POP    DX
  711.         PUSH    DX
  712.         PUSH    AX
  713.         JMP    DPUSH
  714.  
  715. ;=C   +!    add to a memory location        n addr --
  716.  
  717.         $CODE    82H,+,!!!!,PSTOR
  718.         POP    BX
  719.         POP    AX
  720.         ADD    [BX],AX
  721.         JMP    NEXT
  722.  
  723. ;=C   TOGGLE    toggle bits at a memory location    n addr --
  724.  
  725.         $CODE    86H,TOGGL,E,TOGGL
  726.         POP    AX
  727.         POP    BX
  728.         XOR    [BX],AL
  729.         JMP    NEXT
  730.  
  731. ;=C   @        push memory location to stack        addr -- n
  732.  
  733.         $CODE    81H,,@,AT
  734.         POP    BX
  735.         MOV    AX,[BX]
  736.         JMP    APUSH
  737.  
  738. ;=C   C@    push byte location to stack        addr -- b
  739.  
  740.         $CODE    82H,C,@,CAT
  741.         POP    BX
  742.         MOV    AL,[BX]
  743.         SUB    AH,AH
  744.         JMP    APUSH
  745.  
  746. ;=C   2@    fetch 32-bit number            addr -- d
  747.  
  748.         $CODE    82H,2,@,TAT
  749.         POP    BX
  750.         MOV    AX,[BX]        ;LSW at addr
  751.         MOV    DX,[BX+2]    ;MSW at addr+2
  752.         JMP    DPUSH
  753.  
  754. ;=C   !        pop stack to memory - "store"        n addr --
  755.  
  756.         $CODE    81H,,!!!!,STORE
  757.         POP    BX
  758.         POP    AX
  759.         MOV    [BX],AX
  760.         JMP    NEXT
  761.  
  762. ;=C   C!    byte store - "see-store"        b addr --
  763.  
  764.         $CODE    82H,C,!!!!,CSTOR
  765.         POP    BX
  766.         POP    AX
  767.         MOV    [BX],AL
  768.         JMP    NEXT
  769.  
  770. ;=C   2!    32-bit store                d addr --
  771.  
  772.         $CODE    82H,2,!!!!,TSTOR
  773.         POP    BX
  774.         POP    AX
  775.         MOV    [BX],AX        ;move LSW to addr
  776.         POP    AX
  777.         MOV    2[BX],AX    ;move MSW to addr+2
  778.         JMP    NEXT
  779. SUBTTL Defining words
  780. PAGE
  781.  
  782.  
  783. ;=C   :        begin colon definition            --
  784.  
  785.         $COLON    0C1H,,:
  786.         DW    QEXEC,    SCSP    ;compile time code
  787.         DW    CURR,    AT
  788.         DW    CONT,    STORE
  789.         DW    CREAT,    RBRAC
  790.         DW    PSCOD
  791.                     ;run time code
  792. DOCOL:         INC    DX        ;W:=W+1
  793.         DEC    BP
  794.         DEC    BP        ;RP:=RP-2
  795.         MOV    [BP],SI        ;push IP onto return stack
  796.         MOV    SI,DX        ;IP:=W
  797.         JMP    NEXT
  798.  
  799. ;=:   ;        end colon definition            --
  800.  
  801.         $COLON    0C1H,,!!!;
  802.         DW    QCSP,    COMP
  803.         DW    SEMIS,    SMUDG
  804.         DW    LBRAC,    SEMIS
  805.  
  806. ;=:   NOOP    do nothing - no operation        --
  807.  
  808.         $COLON    84H,NOO,P,NOOP
  809.         DW    SEMIS
  810.  
  811. ;=:   CONSTANT    define a symbolic constant        n --
  812.  
  813.         $COLON    88H,CONSTAN,T,CON
  814.         DW    CREAT,    SMUDG    ;compile time code
  815.         DW    COMMA,    PSCOD
  816.                     ;run time code
  817. DOCON:         INC    DX        ;point W to PFA
  818.         MOV    BX,DX
  819.         MOV    AX,[BX]        ;get data at PFA
  820.         JMP    APUSH        ;here it is!
  821.  
  822. ;=:   VARIABLE    define a symbolic variable        n --
  823.  
  824.         $COLON    88H,VARIABL,E
  825.         DW    CON,    PSCOD    ;compile time code
  826.                     ;run time code
  827. DOVAR:         INC    DX        ;point W to PFA
  828.         PUSH    DX        ;return PFA
  829.         JMP    NEXT
  830.  
  831. ;=:   USER    define a user variable            n --
  832.  
  833.         $COLON    84H,USE,R
  834.         DW    CON,    PSCOD    ;compile time code
  835.                     ;run time code
  836. DOUSE:         INC    DX        ;point W to PFA
  837.         MOV    BX,DX        ;BX:=(PFA)   offset
  838.         MOV    BL,[BX]        ;BX:=(PFA)  offset<256
  839.         SUB    BH,BH        ;just to be safe...
  840.         MOV    DI,UP        ;DI:=UP  (user area base addr)
  841.         LEA    AX,[BX+DI]    ;load effective address
  842.         JMP    APUSH        ;push address to stack
  843.  
  844.     $REPORT    <Code-level kernel completed>
  845.  
  846. SUBTTL Constants and USER variables
  847. PAGE +
  848.  
  849.  
  850. ;=#   0        zero                    -- 0
  851.  
  852.         $CONST    81H,,0,ZERO
  853.         DW    0
  854.  
  855. ;=#   1        one                    -- 1
  856.  
  857.         $CONST    81H,,1,ONE
  858.         DW    1
  859.  
  860. ;=#   2        two                    -- 2
  861.  
  862.         $CONST    81H,,2,TWO
  863.         DW    2
  864.  
  865. ;=#   3        three                    -- 3
  866.  
  867.         $CONST    81H,,3,THREE
  868.         DW    3
  869.  
  870. ;=#   BL    ASCII blank                -- 32
  871.  
  872.         $CONST    82H,B,L,BLS
  873.         DW    20H
  874.  
  875. ;=#   C/L    characters per line            -- 64
  876.  
  877.         $CONST    83H,C/,L,CSLL
  878.         DW    64
  879.  
  880. ;=#   FIRST    address of lowest disk buffer        -- addr
  881.  
  882.         $CONST    85H,FIRS,T,FIRST
  883.         DW    BUF1
  884.  
  885. ;=#   LIMIT    last available memory address + 1    -- addr
  886.  
  887.         $CONST    85H,LIMI,T,LIMIT
  888.         DW    EM
  889.  
  890. ;=#   B/BUF    size of disk buffers in bytes        -- 1024
  891.  
  892.         $CONST    85H,B/BU,F,BBUF
  893.         DW    BUFSIZE
  894.  
  895. ;=#   B/SCR    number of disk buffers per screen    -- 1
  896.  
  897.         $CONST    85H,B/SC,R,BSCR
  898.         DW    1
  899. SUBTTL
  900. PAGE +
  901.  
  902.  
  903. ;=:   +ORIGIN    word for accessing data in low memory    n -- addr
  904.  
  905.         $COLON    87H,+ORIGI,N,PORIG
  906.         DW    LIT,    ORIG
  907.         DW    PLUS,    SEMIS
  908.  
  909. SUBTTL USER variables
  910. PAGE +
  911.  
  912.  
  913. ;=U   S0    parameter stack base            -- addr
  914.  
  915.         $USER    82H,S,0,SZERO
  916.         DW    6        ;offset in user area
  917.  
  918. ;=U   R0    return stack base            -- addr
  919.  
  920.         $USER    82H,R,0,RZERO
  921.         DW    8
  922.  
  923. ;=U   TIB    Terminal Input Buffer address        -- addr
  924.  
  925.         $USER    83H,TI,B,TIB
  926.         DW    10
  927.  
  928. ;=U   WIDTH    maximum length of word names        -- addr
  929.  
  930.         $USER    85H,WIDT,H,NWIDTH
  931.         DW    12
  932.  
  933. ;=U   WARNING    switch for error processing: 0, 1, -1    -- addr
  934.  
  935.         $USER    87H,WARNIN,G,WARN
  936.         DW    14
  937.  
  938. ;=U   FENCE    pointer to protected dictionary        -- addr
  939.  
  940.         $USER    85H,FENC,E,FENCE
  941.         DW    16
  942.  
  943. ;=U   DP    top address used in dictionary        -- addr
  944.  
  945.         $USER    82H,D,P,DP
  946.         DW    18
  947.  
  948. ;=U   VOC-LINK    pointer to top vocabulary        -- addr
  949.  
  950.         $USER    88H,VOC-LIN,K,VOCL
  951.         DW    20
  952.  
  953. ;The following user variables hold CFA's for their
  954. ;respective logical functions
  955.  
  956.  
  957. ;=U+  @KEY    CFA of function to do character input    -- addr
  958.  
  959.         $USER    84H,@KE,Y,TICKEY
  960.         DW    22
  961.  
  962. ;=U+  @EMIT    CFA of function to do character output    -- addr
  963.  
  964.         $USER    85H,@EMI,T,TICKEMIT
  965.         DW    24
  966.  
  967. ;=U+  @CR    CFA of function to output newline    -- addr
  968.  
  969.         $USER    83H,@C,R,TICKCR
  970.         DW    58
  971.  
  972. ;=U+  @BLKRD    CFA of function to read one block    -- addr
  973.  
  974.         $USER    86H,@BLKR,D,TICKBRD
  975.         DW    26
  976.  
  977. ;=U+  @BLKWRT    CFA of function to write one block    -- addr
  978.  
  979.         $USER    87H,@BLKWR,T,TICKBWRT
  980.         DW    28
  981.  
  982. ;=U   BLK    current block, 0 if terminal        -- addr
  983.  
  984.         $USER    83H,BL,K,BLK
  985.         DW    30
  986.  
  987. ;=U   IN    current character in input stream    -- addr
  988.  
  989.         $USER    82H,I,N,INN
  990.         DW    32
  991.  
  992. ;=U   OUT    count of characters output        -- addr
  993.  
  994.         $USER    83H,OU,T,OUTT
  995.         DW    34
  996.  
  997. ;=U   SCR    current screen                -- addr
  998.  
  999.         $USER    83H,SC,R,SCR
  1000.         DW    36
  1001.  
  1002. ;=U   OFFSET    number of lowest block to be used    -- addr
  1003.  
  1004.         $USER    86H,OFFSE,T,OFSET
  1005.         DW    38
  1006.  
  1007. ;=U   CONTEXT    current vocabulary for execution    -- addr
  1008.  
  1009.         $USER    87H,CONTEX,T,CONT
  1010.         DW    40
  1011.  
  1012. ;=U   CURRENT    current vocabulary for definitions    -- addr
  1013.  
  1014.         $USER    87H,CURREN,T,CURR
  1015.         DW    42
  1016.  
  1017. ;=U   STATE    current interpreter state        -- addr
  1018.  
  1019.         $USER    85H,STAT,E,STATE
  1020.         DW    44
  1021.  
  1022. ;=U   BASE    current number base for i/o        -- addr
  1023.  
  1024.         $USER    84H,BAS,E,BASE
  1025.         DW    46
  1026.  
  1027. ;=U   DPL    Decimal Point Locator             -- addr
  1028.  
  1029.         $USER    83H,DP,L,DPL
  1030.         DW    48
  1031.  
  1032. ;=U   CSP    temporary storage for Current SP    -- addr
  1033.  
  1034.         $USER    83H,CS,P,CSPP
  1035.         DW    52
  1036.  
  1037. ;=U   R#    current editing cursor location        -- addr
  1038.  
  1039.         $USER    82H,R,#,RNUM
  1040.         DW    54
  1041.  
  1042. ;=U   HLD    text pointer used in number formatting    -- addr
  1043.  
  1044.         $USER    83H,HL,D,HLD
  1045.         DW    56
  1046.  
  1047.     $REPORT    <Constants and user variables completed>
  1048.  
  1049. SUBTTL FORTH definitions
  1050. PAGE +
  1051.  
  1052.  
  1053. ;=C   1+    increment the top stack item        n -- n+1
  1054.  
  1055.         $CODE    82H,1,+,ONEP
  1056.         POP    AX
  1057.         INC    AX
  1058.         JMP    APUSH
  1059.  
  1060. ;=C   2+    add 2 to the top stack item        n -- n+2
  1061.  
  1062.         $CODE    82H,2,+,TWOP
  1063.         POP    AX
  1064.         INC    AX
  1065.         INC    AX
  1066.         JMP    APUSH
  1067.  
  1068. ;=C+  1-    decrement the top stack item        n -- n-1
  1069.  
  1070.         $CODE    82H,1,-,ONEM
  1071.         POP    AX
  1072.         DEC    AX
  1073.         JMP    APUSH
  1074.  
  1075. ;=C+  2-    subtract 2 from the top stack item    n -- n-2
  1076.  
  1077.         $CODE    82H,2,-,TWOM
  1078.         POP    AX
  1079.         DEC    AX
  1080.         DEC    AX
  1081.         JMP    APUSH
  1082.  
  1083. ;=:   HERE    next available dictionary location    -- addr
  1084.  
  1085.         $COLON    84H,HER,E,HERE
  1086.         DW    DP,    AT,    SEMIS
  1087.  
  1088. ;=:   ALLOT    reserve n bytes in the dictionary    n --
  1089.  
  1090.         $COLON    85H,ALLO,T,ALLOT
  1091.         DW    DP,    PSTOR,    SEMIS
  1092.  
  1093. ;=:   ,        compile n into the dictionary        n --
  1094.  
  1095.         $COLON    81H,,!!!,,COMMA
  1096.         DW    HERE,    STORE
  1097.         DW    TWO,    ALLOT,    SEMIS
  1098.  
  1099. ;=:   C,    compile a byte into the dictionary    b --
  1100.  
  1101.         $COLON    82H,C,!!!,,CCOMM
  1102.         DW    HERE,    CSTOR
  1103.         DW    ONE,    ALLOT,    SEMIS
  1104.  
  1105. ;=C   -        16-bit subtraction            n1 n2 -- n1-n2
  1106.  
  1107.         $CODE    81H,,-,SUBB
  1108.         POP    DX
  1109.         POP    AX
  1110.         SUB    AX,DX
  1111.         JMP    APUSH
  1112.  
  1113. ;=:   =        test top two items for equality        n1 n2 -- f
  1114.  
  1115.         $COLON    81H,,=,EQUAL
  1116.         DW    SUBB,    ZEQU,    SEMIS
  1117.  
  1118. ;=C   <        test for top number > second number    n1 n2 -- f
  1119.  
  1120.         $CODE    81H,,!!!<,LESS
  1121.         POP    DX
  1122.         POP    AX
  1123.         MOV    BX,DX
  1124.         XOR    BX,AX
  1125.         JS    LES1        ;signs different
  1126.         SUB    AX,DX
  1127. LES1:         OR    AX,AX        ;test sign bit
  1128.         MOV    AX,0        ;assume false
  1129.         JNS    LES2        ;not less than
  1130.         INC    AX        ;return true (1)
  1131. LES2:         JMP    APUSH
  1132.  
  1133. ;=:   U<    unsigned test for top > next item    u1 u2 -- f
  1134.  
  1135.         $COLON    82H,U,!!!<,ULESS
  1136.         DW    TDUP,    XORR,    ZLESS
  1137.             $GO?0    ULES1
  1138.         DW    DROP,    ZLESS,    ZEQU
  1139.             $GOTO    ULES2
  1140. ULES1:         DW    SUBB,    ZLESS
  1141. ULES2:         DW    SEMIS
  1142.  
  1143. ;=:   >        test for second item > top of stack    n1 n2 -- f
  1144.  
  1145.         $COLON    81H,,!!!>,GREAT
  1146.         DW    SWAP,    LESS,    SEMIS
  1147.  
  1148. ;=C   ROT    bring the third stack item to top    n1 n2 n3 -- n2 n3 n1
  1149.  
  1150.         $CODE    83H,RO,T,ROT
  1151.         POP    DX
  1152.         POP    BX
  1153.         POP    AX
  1154.         PUSH    BX
  1155.         JMP    DPUSH
  1156.  
  1157. ;=:   SPACE    output a blank                --
  1158.  
  1159.         $COLON    85H,SPAC,E,SPACE
  1160.         DW    BLS,    EMIT,    SEMIS
  1161.  
  1162. ;=:   -DUP    duplicate the top number if it isn't 0    n -- n [n]
  1163.  
  1164.         $COLON    84H,-DU,P,DDUP
  1165.         DW    DUPP
  1166.             $GO?0    DDUP1
  1167.         DW    DUPP
  1168. DDUP1:         DW    SEMIS
  1169.  
  1170. ;=:   TRAVERSE    move across a fig-FORTH name field    addr1 n -- addr2
  1171.  
  1172.         $COLON    88H,TRAVERS,E,TRAV
  1173.         DW    SWAP
  1174. TRAV1:         DW    OVER,    PLUS
  1175.         DW    LIT,    7FH
  1176.         DW    OVER,    CAT,    LESS
  1177.             $GO?0    TRAV1
  1178.         DW    SWAP,    DROP,    SEMIS
  1179.  
  1180. ;=:   LATEST    return the top NFA in CURRENT        -- NFA
  1181.  
  1182.         $COLON    86H,LATES,T,LATES
  1183.         DW    CURR,    AT,    AT,    SEMIS
  1184.  
  1185. ;=:   LFA    convert a PFA to LFA            PFA -- LFA
  1186.  
  1187.         $COLON    83H,LF,A,LFA
  1188.         DW    LIT,    4
  1189.         DW    SUBB,    SEMIS
  1190.  
  1191. ;=:   CFA    convert a PFA to CFA            PFA -- CFA
  1192.  
  1193.         $COLON    83H,CF,A,CFA
  1194.         DW    TWO,    SUBB,    SEMIS
  1195.  
  1196. ;=:*  NFA    convert a PFA to NFA            PFA -- NFA
  1197.  
  1198.         $COLON    83H,NF,A,NFA
  1199.         DW    LIT,    5
  1200.         DW    SUBB
  1201.  
  1202.     IF    _ALIGN
  1203.         DW    DUPP,    CAT
  1204.         DW    LIT,    90H,    EQUAL    ;90H==NOP!
  1205.             $GO?0    NFA1
  1206.         DW    ONEM
  1207. NFA1:
  1208.     ENDIF
  1209.  
  1210.         DW    LIT,    -1
  1211.         DW    TRAV,    SEMIS
  1212.  
  1213. ;=:*  PFA    convert a NFA to PFA            NFA -- PFA
  1214.  
  1215.         $COLON    83H,PF,A,PFA
  1216.         DW    ONE,    TRAV
  1217.     IF    _ALIGN
  1218.         DW    LIT,    6,    PLUS
  1219.         DW    LIT,    -2,    ANDD
  1220.     ELSE
  1221.         DW    LIT,    5,    PLUS
  1222.     ENDIF
  1223.         DW    SEMIS
  1224.  
  1225. ;=:   !CSP    save SP at CSP                --
  1226.  
  1227.         $COLON    84H,!!!!CS,P,SCSP
  1228.         DW    SPAT,    CSPP
  1229.         DW    STORE,    SEMIS
  1230.  
  1231. ;=:   ?ERROR    issue error message m if f is TRUE    f m --
  1232.  
  1233.         $COLON    86H,?ERRO,R,QERR
  1234.         DW    SWAP
  1235.             $GO?0    QERR1
  1236.         DW    ERROR
  1237.             $GOTO    QERR2
  1238. QERR1:         DW    DROP
  1239. QERR2:         DW    SEMIS
  1240.  
  1241. ;=:   ?COMP    issue a message if not compiling    --
  1242.  
  1243.         $COLON    85H,?COM,P,QCOMP
  1244.         DW    STATE,    AT
  1245.         DW    ZEQU,    LIT,    17
  1246.         DW    QERR,    SEMIS
  1247.  
  1248. ;=:   ?EXEC    issue a message if not executing    --
  1249.  
  1250.         $COLON    85H,?EXE,C,QEXEC
  1251.         DW    STATE,    AT
  1252.         DW    LIT,    18
  1253.         DW    QERR,    SEMIS
  1254.  
  1255. ;=:   ?PAIRS    issue a message if n1 <> n2        n1 n2 --
  1256.  
  1257.         $COLON    86H,?PAIR,S,QPAIR
  1258.         DW    SUBB
  1259.         DW    LIT,    19
  1260.         DW    QERR,    SEMIS
  1261.  
  1262. ;=:   ?CSP    issue a message if SP <> (CSP)        --
  1263.  
  1264.         $COLON    84H,?CS,P,QCSP
  1265.         DW    SPAT,    CSPP,    AT,    SUBB
  1266.         DW    LIT,    20
  1267.         DW    QERR,    SEMIS
  1268.  
  1269. ;=:   ?LOADING    issue a message if not loading        --
  1270.  
  1271.         $COLON    88H,?LOADIN,G,QLOAD
  1272.         DW    BLK,    AT,    ZEQU
  1273.         DW    LIT,    22
  1274.         DW    QERR,    SEMIS
  1275.  
  1276. ;=:   COMPILE    compile the following word at run time    --
  1277.  
  1278.         $COLON    87H,COMPIL,E,COMP
  1279.         DW    QCOMP
  1280.         DW    FROMR,    DUPP,    TWOP,    TOR
  1281.         DW    AT,    COMMA,    SEMIS
  1282.  
  1283. ;=:   [        suspend compilation to do calculations    --
  1284.  
  1285.         $COLON    0C1H,,[,LBRAC
  1286.         DW    ZERO,    STATE,    STORE,    SEMIS
  1287.  
  1288. ;=:   ]        resume compilation after [        --
  1289.  
  1290.         $COLON    81H,,],RBRAC
  1291.         DW    LIT,    0C0H
  1292.         DW    STATE,    STORE,    SEMIS
  1293.  
  1294. ;=:   SMUDGE    make the latest definition unFINDable    --
  1295.  
  1296.         $COLON    86H,SMUDG,E,SMUDG
  1297.         DW    LATES
  1298.         DW    LIT,    20H
  1299.         DW    TOGGL,    SEMIS
  1300.  
  1301. ;=:   HEX    set the current number base to 16    --
  1302.  
  1303.         $COLON    83H,HE,X
  1304.         DW    LIT,    16
  1305.         DW    BASE,    STORE,    SEMIS
  1306.  
  1307. ;=:   DECIMAL    set the current number base to 10    --
  1308.  
  1309.         $COLON    87H,DECIMA,L,DECA
  1310.         DW    LIT,    10
  1311.         DW    BASE,    STORE,    SEMIS
  1312.  
  1313. ;=:   (;CODE)    run time code for ;CODE            --
  1314.  
  1315.         $COLON    87H,(!!!;CODE,),PSCOD
  1316.         DW    FROMR,    LATES,    PFA
  1317.         DW    CFA,    STORE,    SEMIS
  1318.  
  1319. ;=:   ;CODE    end colon compilation, start CODE    --
  1320.  
  1321.         $COLON    0C5H,!!!;COD,E,SEMIC
  1322.         DW    QCSP
  1323.         DW    COMP,    PSCOD,    LBRAC
  1324. SEMI1        DW    NOOP    ; (ASSEMBLER)
  1325.         DW    SEMIS
  1326.  
  1327. ;=:   <BUILDS    define compile time behavior        --
  1328.  
  1329.         $COLON    87H,!!!<BUILD,S,BUILD
  1330.         DW    ZERO,    CON,    SEMIS
  1331.  
  1332. ;=:   DOES>    define run time behavior        --
  1333.  
  1334.         $COLON    85H,DOES,!!!>,DOES
  1335.         DW    FROMR,    LATES,    PFA,    STORE
  1336.         DW    PSCOD
  1337.  
  1338. DODOE:         XCHG    BP,SP        ;get RP
  1339.         PUSH    SI        ;RP:=IP
  1340.         XCHG    BP,SP
  1341.         INC    DX        ;point W to PFA
  1342.         MOV    BX,DX
  1343.         MOV    SI,[BX]        ;IP:=(PFA)
  1344.         INC    DX
  1345.         INC    DX        ;W points to PFA
  1346.         PUSH    DX
  1347.         JMP    NEXT
  1348.  
  1349. ;=:   COUNT    prepare to type a string        addr -- addr+1 n
  1350.  
  1351.         $COLON    85H,COUN,T,COUNT
  1352.         DW    DUPP,    ONEP,    SWAP,    CAT,    SEMIS
  1353.  
  1354. ;=:   TYPE    output n characters beginning at addr    addr n --
  1355.  
  1356.         $COLON    84H,TYP,E,TYPES
  1357.         DW    DDUP
  1358.             $GO?0    TYPE1
  1359.         DW    OVER,    PLUS
  1360.         DW    SWAP,    XDO
  1361. TYPE2:         DW    IDO,    CAT,    EMIT
  1362.             $LOOP    TYPE2
  1363.             $GOTO    TYPE3
  1364. TYPE1:         DW    DROP
  1365. TYPE3:         DW    SEMIS
  1366.  
  1367. ;=:   -TRAILING    adjust addr/n to avoid trailing blanks    addr n1 -- addr n2
  1368.  
  1369.         $COLON    89H,-TRAILIN,G,DTRAI
  1370.         DW    DUPP,    ZERO,    XDO
  1371. DTRA1:         DW    OVER,    OVER,    PLUS
  1372.         DW    ONE,    SUBB,    CAT
  1373.         DW    BLS,    SUBB
  1374.             $GO?0    DTRA2
  1375.         DW    LEAVE
  1376.             $GOTO    DTRA3
  1377. DTRA2:         DW    ONE,    SUBB
  1378. DTRA3:             $LOOP    DTRA1
  1379.         DW    SEMIS
  1380.  
  1381. ;=:   (.")    run time code for ."            --
  1382.  
  1383.         $COLON    84H,(.!!!",),PDOTQ
  1384.         DW    RR
  1385.         DW    COUNT,    DUPP,    ONEP
  1386.         DW    FROMR,    PLUS,    TOR
  1387.         DW    TYPES,    SEMIS
  1388.  
  1389. ;=:   ."    print the following string        --
  1390.  
  1391.         $COLON    0C2H,.,!!!",DOTQ
  1392.         DW    LIT,    '"'
  1393.         DW    STATE,    AT
  1394.             $GO?0    DOTQ1
  1395.         DW    COMP
  1396.         DW    PDOTQ,    WORDS,    HERE
  1397.         DW    CAT,    ONEP,    ALLOT
  1398.             $GOTO    DOTQ2
  1399. DOTQ1:         DW    WORDS,    HERE,    COUNT,    TYPES
  1400. DOTQ2:         DW    SEMIS
  1401.  
  1402. ;=:   EXPECT    input up to n characters to addr    addr n --
  1403.  
  1404.         $COLON    86H,EXPEC,T,EXPEC
  1405.         DW    OVER,    PLUS,    OVER
  1406.         DW    XDO
  1407. EXPE1:         DW    KEY,    DUPP
  1408.         DW    LIT,    0EH
  1409.         DW    PORIG,    AT,    EQUAL
  1410.             $GO?0    EXPE2
  1411.         DW    DROP,    DUPP,    IDO
  1412.         DW    EQUAL,    DUPP,    FROMR
  1413.         DW    TWO,    SUBB,    PLUS
  1414.         DW    TOR
  1415.             $GO?0    EXPE6
  1416.         DW    LIT,    BELL
  1417.             $GOTO    EXPE7
  1418. EXPE6:         DW    LIT,    BSOUT,    EMIT
  1419.         DW    BLS,    EMIT
  1420.         DW    LIT,    BSOUT
  1421. EXPE7:             $GOTO    EXPE3
  1422. EXPE2:         DW    DUPP,    LIT,    ACR
  1423.         DW    EQUAL
  1424.             $GO?0    EXPE4
  1425.         DW    LEAVE,    DROP,    BLS,    ZERO
  1426.             $GOTO    EXPE5
  1427. EXPE4:         DW    DUPP
  1428. EXPE5:         DW    IDO
  1429.         DW    CSTOR,    ZERO,    IDO,    ONEP
  1430.         DW    STORE
  1431. EXPE3:         DW    EMIT
  1432.             $LOOP    EXPE1
  1433.         DW    DROP,    SEMIS
  1434.  
  1435. ;=:   QUERY    EXPECT 80 characters to TIB        --
  1436.  
  1437.         $COLON    85H,QUER,Y,QUERY
  1438.         DW    TIB,    AT
  1439.         DW    LIT,    80,    EXPEC
  1440.         DW    ZERO,    INN,    STORE,    SEMIS
  1441.  
  1442. ;=:   <nul>    0 in input: resets interpreter        --
  1443.  
  1444.         _NFA    = $
  1445.         DB    0C1H,80H    ;zero header
  1446.         $LINKS    DOCOL
  1447.  
  1448.         DW    BLK,    AT
  1449.             $GO?0    NULL1
  1450.         DW    ONE,    BLK,    PSTOR
  1451.         DW    ZERO,    INN,    STORE
  1452.         DW    BLK,    AT
  1453.         DW    BSCR,    ONE,    SUBB,    ANDD
  1454.         DW    ZEQU
  1455.             $GO?0    NULL2
  1456.         DW    QEXEC,    FROMR,    DROP
  1457. NULL2:             $GOTO    NULL3
  1458. NULL1:         DW    FROMR,    DROP
  1459. NULL3:         DW    SEMIS
  1460.  
  1461. ;=C   FILL    fill n bytes at address with c        addr n c --
  1462.  
  1463.         $CODE    84H,FIL,L,FILL
  1464.         POP    AX        ;fill char
  1465.         POP    CX        ;fill count
  1466.         POP    DI        ;destination address
  1467.         MOV    BX,DS
  1468.         MOV    ES,BX        ;same segment
  1469.         CLD            ;fill toward higher address
  1470.     REP    STOSB            ;GO!
  1471.         JMP    NEXT
  1472.  
  1473. ;=:   ERASE    fill n bytes at addr with 0's        addr n --
  1474.  
  1475.         $COLON    85H,ERAS,E,ERASEE
  1476.         DW    ZERO,    FILL,    SEMIS
  1477.  
  1478. ;=:   BLANKS    fill n bytes at addr with blanks    addr n --
  1479.  
  1480.         $COLON    86H,BLANK,S,BLANK
  1481.         DW    BLS,    FILL,    SEMIS
  1482.  
  1483. ;=:   HOLD    insert char in formatted output        c --
  1484.  
  1485.         $COLON    84H,HOL,D,HOLD
  1486.         DW    LIT,    -1
  1487.         DW    HLD,    PSTOR
  1488.         DW    HLD,    AT,    CSTOR,    SEMIS
  1489.  
  1490. ;=:   PAD    returns addr of the text output buffer    -- addr
  1491.  
  1492.         $COLON    83H,PA,D,PAD
  1493.         DW    HERE,    LIT,    68,    PLUS,    SEMIS
  1494.         DW    PLUS,    SEMIS
  1495.  
  1496. ;=:   WORD    get a word delimited by char to HERE    c --
  1497.  
  1498.         $COLON    84H,WOR,D,WORDS
  1499.         DW    BLK,    AT
  1500.             $GO?0    WORD1
  1501.         DW    BLK,    AT,    BLOCK
  1502.             $GOTO    WORD2
  1503. WORD1:         DW    TIB,    AT
  1504. WORD2:         DW    INN,    AT,    PLUS,    SWAP
  1505.         DW    ENCL,    HERE
  1506.         DW    LIT,    34
  1507.         DW    BLANK,    INN,    PSTOR
  1508.         DW    OVER,    SUBB,    TOR
  1509.         DW    RR,    HERE,    CSTOR
  1510.         DW    PLUS,    HERE,    ONEP
  1511.         DW    FROMR,    CMOVE,    SEMIS
  1512.  
  1513. ;=:   (NUMBER)    ASCII to binary conversion primitive    d1 addr1 -- d2 addr2
  1514.  
  1515.         $COLON    88H,(NUMBER,),PNUMB
  1516. PNUM1:         DW    ONEP
  1517.         DW    DUPP,    TOR
  1518.         DW    CAT,    BASE,    AT,    DIGIT
  1519.             $GO?0    PNUM2
  1520.         DW    SWAP,    BASE,    AT,    USTAR
  1521.         DW    DROP,    ROT,    BASE,    AT
  1522.         DW    USTAR,    DPLUS
  1523.         DW    DPL,    AT,    ONEP
  1524.             $GO?0    PNUM3
  1525.         DW    ONE,    DPL,    PSTOR
  1526. PNUM3:         DW    FROMR
  1527.             $GOTO    PNUM1
  1528. PNUM2:         DW    FROMR,    SEMIS
  1529.  
  1530. ;=:   NUMBER    convert string at addr to 32-bit number    addr -- d
  1531.  
  1532.         $COLON    86H,NUMBE,R,NUMB
  1533.         DW    ZERO,    ZERO
  1534.         DW    ROT,    DUPP,    ONEP,    CAT
  1535.         DW    LIT,    "-",    EQUAL
  1536.         DW    DUPP,    TOR,    PLUS
  1537.         DW    LIT,    -1
  1538. NUMB1:         DW    DPL,    STORE
  1539.         DW    PNUMB
  1540.         DW    DUPP,    CAT,    BLS,    SUBB
  1541.             $GO?0    NUMB2
  1542.         DW    DUPP,    CAT
  1543.         DW    LIT,    ".",    SUBB
  1544.         DW    ZERO,    QERR,    ZERO
  1545.             $GOTO    NUMB1
  1546. NUMB2:         DW    DROP,    FROMR
  1547.             $GO?0    NUMB3
  1548.         DW    DMINU
  1549. NUMB3:         DW    SEMIS
  1550.  
  1551. ;=:   -FIND    search dictionary for next input word    -- [PFA b] f
  1552.  
  1553.         $COLON    85H,-FIN,D,DFIND
  1554.         DW    BLS,    WORDS
  1555.         DW    HERE,    CONT,    AT,    AT
  1556.         DW    PFIND,    DUPP,    ZEQU
  1557.             $GO?0    DFIN1
  1558.         DW    DROP
  1559.         DW    HERE,    LATES,    PFIND
  1560. DFIN1:         DW    SEMIS
  1561.  
  1562. ;=:   (ABORT)    error function when WARNING is -1    --
  1563.  
  1564.         $COLON    87H,(ABORT,),PABOR
  1565.         DW    ABORT,    SEMIS
  1566.  
  1567. ;=:   ERROR    system error handler - n is line no.    n -- [IN BLK]
  1568.  
  1569.         $COLON    85H,ERRO,R,ERROR
  1570.         DW    WARN,    AT,    ZLESS
  1571.             $GO?0    ERRO1
  1572.         DW    PABOR
  1573. ERRO1:         DW    HERE,    COUNT,    TYPES
  1574.         DW    PDOTQ
  1575.         DB    2,"? "
  1576.         DW    MESS
  1577.         DW    SPSTO
  1578.         DW    BLK,    AT,    DDUP
  1579.             $GO?0    ERRO2
  1580.         DW    INN,    AT,    SWAP
  1581. ERRO2:         DW    QUIT
  1582.  
  1583. ;=:   ID.    print dictionary name field        NFA --
  1584.  
  1585.         $COLON    83H,ID,.,IDDOT
  1586.         DW    PAD
  1587.         DW    LIT,    32
  1588.         DW    LIT,    '_'
  1589.         DW    FILL
  1590.         DW    DUPP,    PFA,    LFA
  1591.         DW    OVER,    SUBB
  1592.         DW    PAD,    SWAP,    CMOVE
  1593.         DW    PAD,    COUNT
  1594.         DW    LIT,    1FH    ;use low 5 bits of length
  1595.  
  1596. ; ID. was changed to clear the MSB of the last char in the name
  1597.  
  1598.         DW    ANDD,    DUPP,    PAD,    PLUS
  1599.         DW    LIT,    80H,    TOGGL    ;Zero the MSB
  1600.         DW    TYPES,    SPACE,    SEMIS
  1601.  
  1602. ;=:*  CREATE    create a dictionary header        --
  1603.  
  1604.         $COLON    86H,CREAT,E,CREAT
  1605.         DW    DFIND
  1606.             $GO?0    CREA1
  1607.         DW    DROP,    NFA,    IDDOT
  1608.         DW    LIT,    4,    MESS    ;"not unique"
  1609.         DW    SPACE
  1610. CREA1:         DW    HERE,    DUPP,    CAT
  1611.         DW    NWIDTH,    AT,    MIN
  1612.         DW    ONEP,    ALLOT
  1613.         DW    DUPP
  1614.         DW    LIT,    0A0H
  1615.         DW    TOGGL            ;smudge it
  1616.         DW    HERE,    ONE,    SUBB
  1617.         DW    LIT,    80H
  1618.         DW    TOGGL            ;last char has bit 8 set
  1619.  
  1620.     IF    _ALIGN
  1621. ;This section of code forces the body of a compiled FORTH word to
  1622. ;lie on even addresses.  This allows the threaded CFA's to be
  1623. ;fetched by the inner interpreter in one bus cycle.  For the 8088
  1624. ;this means nothing, and the extra space required for alignment
  1625. ;should be saved by setting _ALIGN to FALSE.  The literal 90H is
  1626. ;used because MASM uses NOP's to align words.  NFA expects
  1627. ;90H to be used also.
  1628.         DW    LIT,    90H,    CCOMM
  1629.         DW    DP,    AT
  1630.         DW    LIT,    -2,    ANDD
  1631.         DW    DP,    STORE
  1632.     ENDIF
  1633.         DW    LATES,    COMMA        ;compile LFA
  1634.         DW    CURR,    AT,    STORE    ;update vocabulary
  1635.         DW    HERE,    TWOP,    COMMA,    SEMIS    ;CFA:=PFA
  1636.  
  1637. ;=:   [COMPILE]    compile an otherwise immediate word    --
  1638.  
  1639.         $COLON    0C9H,[COMPILE,]
  1640.         DW    DFIND
  1641.         DW    ZEQU,    ZERO,    QERR
  1642.         DW    DROP,    CFA,    COMMA,    SEMIS
  1643.  
  1644. ;=:   LITERAL    compile n to be used at run time    n --
  1645.  
  1646.         $COLON    0C7H,LITERA,L,LITER
  1647.         DW    STATE,    AT
  1648.             $GO?0    LITE1
  1649.         DW    COMP,    LIT,    COMMA
  1650. LITE1:         DW    SEMIS
  1651.  
  1652. ;=:   DLITERAL    compile d to be used at run time    d --
  1653.  
  1654.         $COLON    0C8H,DLITERA,L,DLITE
  1655.         DW    STATE,    AT
  1656.             $GO?0    DLIT1
  1657.         DW    SWAP,    LITER,    LITER
  1658. DLIT1:        DW    SEMIS
  1659.  
  1660. ;=:   ?STACK    check if the stack is out of bounds    --
  1661.  
  1662.         $COLON    86H,?STAC,K,QSTAC
  1663.         DW    SPAT,    SZERO,    AT
  1664.         DW    SWAP,    ULESS,    ONE,    QERR    ;underflow
  1665.         DW    SPAT,    HERE
  1666.         DW    LIT,    80H
  1667.         DW    PLUS,    ULESS
  1668.         DW    LIT,    7
  1669.         DW    QERR                ;overflow
  1670.         DW    SEMIS
  1671.  
  1672. ;=:   INTERPRET    outer text interpreter            --
  1673.  
  1674.         $COLON    89H,INTERPRE,T,INTER
  1675. INTE1:         DW    DFIND            ;begin
  1676.             $GO?0    INTE2
  1677.         DW    STATE,     AT,    LESS
  1678.             $GO?0    INTE3
  1679.         DW    CFA,    COMMA        ;compile it
  1680.             $GOTO    INTE4
  1681. INTE3:         DW    CFA,    EXEC        ;execute it
  1682. INTE4:         DW    QSTAC
  1683.             $GOTO    INTE5
  1684. INTE2:         DW    HERE,    NUMB,    DPL,    AT,    ONEP
  1685.             $GO?0    INTE6
  1686.         DW    DLITE            ;32-bit number
  1687.             $GOTO    INTE7
  1688. INTE6:         DW    DROP,    LITER        ;16-bit number
  1689. INTE7:        DW    QSTAC
  1690. INTE5:            $GOTO    INTE1        ;repeat forever
  1691.  
  1692. ;=:   IMMEDIATE    mark the latest word to be executed    --
  1693.  
  1694.         $COLON    89H,IMMEDIAT,E
  1695.         DW    LATES
  1696.         DW    LIT,    40H    ;bit 7 is precedence
  1697.         DW    TOGGL,    SEMIS
  1698.  
  1699. ;=:   VOCABULARY    define a new vocabulary        --
  1700.  
  1701.         $COLON    8AH,VOCABULAR,Y
  1702.         DW    BUILD
  1703.         DW    LIT,    0A081H
  1704.         DW    COMMA
  1705.         DW    CURR,    AT
  1706.         DW    CFA,    COMMA,    HERE,    VOCL
  1707.         DW    AT,    COMMA,    VOCL,    STORE
  1708.         DW    DOES
  1709. DOVOC:         DW    TWOP,    CONT,    STORE,    SEMIS
  1710.  
  1711. ;=:   FORTH    FORTH vocabulary header            --
  1712.  
  1713.         $DOES    0C5H,FORT,H,FORTH
  1714.         DW    DOVOC
  1715.         DW    0A081H        ;fake a null name field!
  1716.         DW    LASTNFA        ;link changes as def's are added
  1717.         DW    0        ;end of voc list
  1718.  
  1719. ;=:   DEFINITIONS    set CURRENT to CONTEXT        --
  1720.  
  1721.         $COLON    8BH,DEFINITION,S,DEFIN
  1722.         DW    CONT,    AT
  1723.         DW    CURR,    STORE,    SEMIS
  1724.  
  1725. ;=:   (        begin a comment ended by ')'        --
  1726.  
  1727.         $COLON    0C1H,,(
  1728.         DW    LIT,    ')',    WORDS,    SEMIS
  1729.  
  1730. ;=:   QUIT    halt execution, reset interpreter    --
  1731.  
  1732.         $COLON    84H,QUI,T,QUIT
  1733.         DW    ZERO,    BLK,    STORE
  1734.         DW    LBRAC
  1735. QUIT1:         DW    RPSTO,    CR,    QUERY
  1736.         DW    INTER
  1737.         DW    STATE,    AT,    ZEQU
  1738.             $GO?0    QUIT2
  1739.         DW    PDOTQ
  1740.         DB    2,"ok"
  1741. QUIT2:             $GOTO    QUIT1
  1742.  
  1743. ;=:   ABORT    clear stacks and begin execution    --
  1744.  
  1745.         $COLON    85H,ABOR,T,ABORT
  1746.         DW    SPSTO,    DECA,    QSTAC,    CR
  1747.         DW    DOTCPU,    PDOTQ
  1748.         DB    16H,'Fig-FORTH  Version '
  1749.         DB    FIGREL+30H, '.', FIGREV+30H
  1750.         DW    LIT,    10,    PORIG,    CAT
  1751.         DW    LIT,    41H,    PLUS,    EMIT
  1752.         DW    FORTH,    DEFIN
  1753.         DW    LIT,    0,    PRTER,    STORE    ;Reset echo
  1754.  
  1755. ; The following lines add command line interpretation.
  1756. ; Any text at 80H is copied to the TIB and interpreted.
  1757. ; This code should probably go somewhere else, but I never bothered
  1758. ; to move it...
  1759.  
  1760.         DW    LIT,    80H,    COUNT,    DUPP    ;anyone here?
  1761.             $GO?0    AB1            ;no...
  1762.         DW    ZERO,    LIT,    80H,    CSTOR    ;don't do twice
  1763.         DW    TIB,    AT,    DUPP
  1764.         DW    LIT,    64,    ERASEE        ;ensure NUL end
  1765.         DW    SWAP,    CMOVE            ;move it
  1766.         DW    ZERO,    INN,    STORE
  1767.         DW    ZERO,    BLK,    STORE,    LBRAC
  1768.         DW    CR,    CR,    INTER        ;interpret it
  1769.             $GOTO AB2
  1770. AB1:        DW    DROP,    DROP            ;nothing to do
  1771. AB2:        DW    QUIT                ;back to normal
  1772.  
  1773. ; Warm start vector comes here
  1774.  
  1775. WRM:         MOV    SI,OFFSET WRM1
  1776.         JMP    NEXT
  1777. WRM1        DW    WARM
  1778.  
  1779. ;=:   WARM    empty disk buffers and abort        --
  1780.  
  1781.         $COLON    84H,WAR,M,WARM
  1782.         DW    MTBUF,    ABORT
  1783.  
  1784. ; Cold start vector comes here
  1785.  
  1786. CLD:         MOV    SI,OFFSET CLD1        ;initialize IP
  1787.         MOV    AX,CS
  1788.         MOV    DS,AX            ;all in one segment
  1789.         MOV    SP,12H[ORIG]        ;initialize SP
  1790.         MOV    SS,AX
  1791.         MOV    ES,AX
  1792.         CLD                ;SI gets incremented
  1793.         MOV    BP,RPP            ;init RP
  1794.  
  1795.         CALL NEAR PTR SYSINIT    ;system dependent initialization
  1796.  
  1797.         JMP    NEXT
  1798.  
  1799. CLD1         DW    COLD
  1800.  
  1801. ;=:*  COLD    full initialization and restart        --
  1802.  
  1803.         $COLON    84H,COL,D,COLD
  1804.         DW    DRZER,    MTBUF
  1805.         DW    FIRST,    USE,    STORE
  1806.         DW    FIRST,    PREV,    STORE
  1807.         DW    LIT,    ORIG+12H
  1808.         DW    LIT,    UP,    AT
  1809.         DW    LIT,    6,    PLUS
  1810.         DW    LIT,    16,    CMOVE    ;USER variables
  1811.         DW    LIT,    ORIG+12,AT
  1812.         DW    LIT,    FORTH+6,STORE    ;vocabulary link
  1813.  
  1814. ; Initialize i/o vectors
  1815.  
  1816.         DW    LIT,    PKEY,    TICKEY,        STORE
  1817.         DW    LIT,    PEMIT,    TICKEMIT,    STORE
  1818.         DW    LIT,    PCR,    TICKCR,        STORE
  1819.         DW    LIT,    BLKRD,    TICKBRD,    STORE
  1820.         DW    LIT,    BLKWRT,    TICKBWRT,    STORE
  1821.  
  1822.         DW    ABORT
  1823.  
  1824. ;=C   S->D    convert a 16-bit number to 32-bits    n -- d
  1825.  
  1826.         _NFA    = $
  1827.         DB    84H,'S->','D'+80H
  1828.         $LINKS    $+2,STOD
  1829.  
  1830.         POP    DX        ;n, becomes LSW of result
  1831.         SUB    AX,AX
  1832.         OR    DX,DX        ;is n negative?
  1833.         JNS    STOD1        ;no, MSW:=AX=0
  1834.         DEC    AX        ;yes, MSW:=-1
  1835. STOD1:         JMP    DPUSH        ;S1=MSW, S2=LSW
  1836.  
  1837. ;=:   +-    apply the sign of n2 to n1        n1 n2 -- n3
  1838.  
  1839.         $COLON    82H,+,-,PM
  1840.         DW    ZLESS
  1841.             $GO?0    PM1
  1842.         DW    MINUS
  1843. PM1:         DW    SEMIS
  1844.  
  1845. ;=:   D+-    apply the sign of n to d1        d1 n -- d2
  1846.  
  1847.         $COLON    83H,D+,-,DPM
  1848.         DW    ZLESS
  1849.             $GO?0    DPM1
  1850.         DW    DMINU
  1851. DPM1:         DW    SEMIS
  1852.  
  1853. ;=:   ABS    take the absolute value of n1        n1 -- n2
  1854.  
  1855.         $COLON    83H,AB,S,ABBS
  1856.         DW    DUPP,    PM,    SEMIS
  1857.  
  1858. ;=:   DABS    take the absolute value of d1        d1 -- d2
  1859.  
  1860.         $COLON    84H,DAB,S,DABS
  1861.         DW    DUPP,    DPM,    SEMIS
  1862.  
  1863. ;=:   MIN    return the smaller of n1 and n2        n1 n2 -- n
  1864.  
  1865.         $COLON    83H,MI,N,MIN
  1866.         DW    TDUP,    GREAT
  1867.             $GO?0    MIN1
  1868.         DW    SWAP
  1869. MIN1:         DW    DROP,    SEMIS
  1870. ;=:   MAX    return the larger of two numbers    n1 n2 -- n
  1871.  
  1872.         $COLON    83H,MA,X,MAX
  1873.         DW    TDUP,    LESS
  1874.             $GO?0    MAX1
  1875.         DW    SWAP
  1876. MAX1:         DW    DROP,    SEMIS
  1877.  
  1878. ;=:   M*    mixed multiplication            n1 n2 -- d
  1879.  
  1880.         $COLON    82H,M,*,MSTAR
  1881.         DW    TDUP,    XORR,    TOR
  1882.         DW    ABBS
  1883.         DW    SWAP,    ABBS,    USTAR
  1884.         DW    FROMR,    DPM,    SEMIS
  1885.  
  1886. ;=:   M/    mixed division                d n1 -- nrem nquot
  1887.  
  1888.         $COLON    82H,M,/,MSLAS
  1889.         DW    OVER,    TOR,    TOR
  1890.         DW    DABS
  1891.         DW    RR,    ABBS,    USLAS
  1892.         DW    FROMR,    RR,    XORR
  1893.         DW    PM,    SWAP,    FROMR
  1894.         DW    PM,    SWAP,    SEMIS
  1895.  
  1896. ;=:   *        16-bit signed multipication        n1 n2 -- n1*n2
  1897.  
  1898.         $COLON    81H,,*,STAR
  1899.         DW    MSTAR,    DROP,    SEMIS
  1900.  
  1901. ;=:   /MOD    16-bit signed division with remainder    n1 n2 -- nrem nquot
  1902.  
  1903.         $COLON    84H,/MO,D,SLMOD
  1904.         DW    TOR,    STOD,    FROMR
  1905.         DW    MSLAS,    SEMIS
  1906.  
  1907. ;=:   /        16-bit signed division            n1 n2 -- nquot
  1908.  
  1909.         $COLON    81H,,/,SLASH
  1910.         DW    SLMOD,    SWAP,    DROP,    SEMIS
  1911.  
  1912. ;=:   MOD    16-bit modulo division            n1 n2 -- nrem
  1913.  
  1914.         $COLON    83H,MO,D,MODD
  1915.         DW    SLMOD,    DROP,    SEMIS
  1916.  
  1917. ;=:   */MOD    scale n1 by the ratio of n2 to n3    n1 n2 n3 -- nrem nquot
  1918.  
  1919.         $COLON    85H,*/MO,D,SSMOD
  1920.         DW    TOR,    MSTAR,    FROMR
  1921.         DW    MSLAS,    SEMIS
  1922.  
  1923. ;=:   */    scale n1 by the ratio of n2 to n3    n1 n2 n3 -- nquot
  1924.  
  1925.         $COLON    82H,*,/,SSLA
  1926.         DW    SSMOD,    SWAP,    DROP,    SEMIS
  1927.  
  1928. ;=:   M/MOD    mixed unsigned scaler            ud1 u -- urem udquot
  1929.  
  1930.         $COLON    85H,M/MO,D,MSMOD
  1931.         DW    TOR,    ZERO,    RR,    USLAS
  1932.         DW    FROMR,    SWAP,    TOR
  1933.         DW    USLAS,    FROMR,    SEMIS
  1934.  
  1935. ;=:   (LINE)    convert a line/screen to addr/count    l s -- addr count
  1936.  
  1937.         $COLON    86H,(LINE,),PLINE
  1938.         DW    TOR
  1939.         DW    LIT,    64
  1940.         DW    BBUF,    SSMOD
  1941.         DW    FROMR,    BSCR,    STAR
  1942.         DW    PLUS
  1943.         DW    BLOCK,    PLUS
  1944.         DW    LIT,    64,    SEMIS
  1945.  
  1946. ;=:   .LINE    type line n1 in screen n2        n1 n2 --
  1947.  
  1948.         $COLON    85H,.LIN,E,DLINE
  1949.         DW    PLINE,    DTRAI,    TYPES,    SEMIS
  1950.  
  1951. ;=:   MESSAGE    type error message n            n --
  1952.  
  1953.         $COLON    87H,MESSAG,E,MESS
  1954.         DW    WARN,    AT
  1955.             $GO?0    MESS1
  1956.         DW    DDUP
  1957.             $GO?0    MESS2
  1958.         DW    LIT,    4
  1959.         DW    OFSET,    AT,    BSCR,    SLASH
  1960.         DW    SUBB,    DLINE,    SPACE
  1961. MESS2:             $GOTO    MESS3
  1962. MESS1:         DW    PDOTQ
  1963.         DB    6,"MSG # "
  1964.         DW    DOT
  1965. MESS3:         DW    SEMIS
  1966.  
  1967.     $REPORT    <FORTH kernel completed>
  1968.  
  1969. INCLUDE    4TH-SYSD.ASM            ;System dependent code
  1970.  
  1971. SUBTTL Disk interface words
  1972. PAGE +
  1973.  
  1974. ;=?   DRIVE    disk drive last accessed        -- addr
  1975.  
  1976.         $VAR    85H,DRIV,E,DRIVE
  1977.         DW    0
  1978.  
  1979. ;=?+  RECORD    disk record last accessed        -- addr
  1980.  
  1981.         $VAR    86H,RECOR,D,REC
  1982.         DW    0
  1983.  
  1984. ;=?+  DTA    disk transfer address last used        -- addr
  1985.  
  1986.         $VAR    83H,DT,A,DTA
  1987.         DW    FIRST
  1988.  
  1989. ;=?   USE    pointer to disk buffer to use next    -- addr
  1990.  
  1991.         $VAR    83H,US,E,USE
  1992.         DW    BUF1
  1993.  
  1994. ;=?   PREV    pointer to disk buffer last accessed    -- addr
  1995.  
  1996.         $VAR    84H,PRE,V,PREV
  1997.         DW    BUF1
  1998.  
  1999. ;=#   #BUFF    total number of block buffers        -- n
  2000.  
  2001.         $CONST    85H,#BUF,F,NOBUF
  2002.         DW    NSCR
  2003.  
  2004. ;=?   DISK-ERROR    status of last disk operation    -- addr
  2005.  
  2006.         $VAR    8AH,DISK-ERRO,R,DSKERR
  2007.         DW    0
  2008.  
  2009. ;=?*  PRINTER    flag controlling printer        -- addr
  2010.  
  2011.         $VAR    87H,PRINTE,R,PRTER
  2012.         DW    0
  2013.  
  2014. ;Block read/write words modified to use execution vectors.
  2015. ;The functions called by BLOCK-READ/-WRITE have the following stack
  2016. ;effect: ( addr blk -- ) and set DISK-ERROR accordingly.
  2017.  
  2018. ;=:+  BLOCK-READ    read one block to addr        addr blk --
  2019.  
  2020.         $COLON    8AH,BLOCK-REA,D,BLOCKRD
  2021.         DW    TICKBRD,    AT,    EXEC,    SEMIS
  2022.  
  2023. ;=:+  BLOCK-WRITE    write one block from addr    addr blk --
  2024.  
  2025.         $COLON    8BH,BLOCK-WRIT,E,BLOCKWRT
  2026.         DW    TICKBWRT,    AT,    EXEC,    SEMIS
  2027.  
  2028. ;=:*  +BUF    advance addr to next buffer        addr1 -- addr2
  2029.  
  2030.         $COLON    84H,+BU,F,PBUF
  2031.         DW    BBUF,    TWOP,    TWOP    ;B/BUF+4
  2032.         DW    PLUS,    DUPP,    LIMIT,    EQUAL
  2033.             $GO?0    PBUF1
  2034.         DW    DROP,    FIRST
  2035. PBUF1:         DW    DUPP,    PREV,    AT
  2036.         DW    SUBB,    SEMIS
  2037.  
  2038. ;=:   UPDATE    mark PREV buffer to be saved        --
  2039.  
  2040.         $COLON    86H,UPDAT,E,UPDAT
  2041.         DW    PREV,    AT,    AT
  2042.         DW    LIT,    8000H
  2043.         DW    ORR
  2044.         DW    PREV,    AT,    STORE,    SEMIS
  2045.  
  2046. ;=:*  EMPTY-BUFFERS    wipe out disk buffers        --
  2047.  
  2048.         $COLON    8DH,EMPTY-BUFFER,S,MTBUF
  2049.         DW    FIRST,    LIMIT,    OVER
  2050.         DW    SUBB,    ERASEE
  2051. ;Modified so that emptied buffers won't look like block 0:
  2052. ;instead, they're all assigned to block 32767.  If you want to
  2053. ;use FORTH on a disk that big - TOO BAD!
  2054.         DW    LIT,    7FFFH
  2055.         DW    NOBUF,    ONEP,    ZERO,    XDO
  2056. MTBUF1:        DW    DUPP,    BUFFE,    DROP
  2057.             $LOOP    MTBUF1
  2058.         DW    DROP,    SEMIS
  2059.  
  2060. ;Words added to save buffers:
  2061.  
  2062. ;=:+  SAVBUF    saves buffer at addr if updated        addr --
  2063.  
  2064.         $COLON    86H,SAVBU,F,SAVBUF
  2065.         DW    DUPP,    TOR,    AT,    ZLESS
  2066.             $GO?0    SVBF1        ;not updated, return
  2067.         DW    RR,    TWOP,    RR,    AT
  2068.         DW    LIT,    7FFFH,    ANDD    ;15-bits only!
  2069.         DW    ZERO,    RSLW        ;write it
  2070.         DW    DSKERR,    AT,    ZEQU
  2071.             $GO?0    SVBF1        ;don't un-update if error
  2072.         DW    RR,    ONEP        ;high byte!
  2073.         DW    LIT,    80H,    TOGGL    ;un-update buffer
  2074. SVBF1:        DW    FROMR,    DROP,    SEMIS
  2075.  
  2076. ;=:+  SAVE-BUFFERS    flush buffers but don't empty    --
  2077.  
  2078.         $COLON    8CH,SAVE-BUFFER,S,SAVBUFS
  2079.         DW    PREV,    AT
  2080. SVBFS1:        DW    PBUF,    OVER,    SAVBUF,    ZEQU
  2081.             $GO?0    SVBFS1
  2082.         DW    DROP,    SEMIS
  2083.  
  2084. ;=:*  BUFFER    assign an available buffer to block n    n -- addr
  2085.  
  2086. ;BUFFER changed to write out ALL dirty buffers when one is found.
  2087.  
  2088.         $COLON    86H,BUFFE,R,BUFFE
  2089.         DW    USE,    AT,    DUPP,    TOR
  2090. BUFF1:         DW    PBUF
  2091.             $GO?0    BUFF1        ;dont use PREV
  2092.         DW    USE,    STORE        ;use this one NEXT!
  2093.         DW    RR,    AT,    ZLESS    ;found a dirty one?
  2094.             $GO?0    BUFF2        ;no
  2095.         DW    SAVBUFS            ;yes, save ALL
  2096. BUFF2:        DW    RR,    STORE        ;set header to n
  2097.         DW    RR,    PREV,    STORE    ;this is now PREV
  2098.         DW    FROMR,    TWOP,    SEMIS    ;leave data addr
  2099.  
  2100. ;=:*  BLOCK    get block n                n -- addr
  2101.  
  2102.         $COLON    85H,BLOC,K,BLOCK
  2103.         DW    OFSET,    AT,    PLUS,    TOR    ;get n+offset
  2104.         DW    PREV,    AT,    DUPP        ;look in PREV first
  2105.         DW    AT,    RR,    SUBB
  2106.         DW    DUPP,    PLUS            ;throw out high bit
  2107.             $GO?0    BLOC1            ;n is in PREV
  2108. BLOC2:         DW    PBUF,    ZEQU            ;check next buffer
  2109.             $GO?0    BLOC3            ;found it
  2110.         DW    DROP,    RR            ;not in buffer
  2111.         DW    BUFFE,    DUPP            ;get a buffer
  2112.         DW    RR,    ONE,    RSLW        ;read blk
  2113.         DW    TWO,    SUBB            ;leave buffer addr
  2114. BLOC3:         DW    DUPP,    AT,    RR,    SUBB    ;check the buffer
  2115.         DW    DUPP,    PLUS,    ZEQU
  2116.             $GO?0    BLOC2
  2117.         DW    DUPP,    PREV,    STORE        ;either found it or read it
  2118. BLOC1:         DW    FROMR,    DROP            ;return
  2119.         DW    TWOP,    SEMIS
  2120.  
  2121. ;T&SCALC now done by D&RCALC in SYSD.ASM file...
  2122.  
  2123. ;=:*  R/W    block read/write, f=1=write, f=2=read    addr blk f --
  2124.  
  2125.         $COLON    83H,R/,W,RSLW
  2126. ;Modified to simply pass the address and blk to the R/W functions
  2127.             $GO?0    RSLW1
  2128.         DW    BLOCKRD
  2129.             $GOTO    RSLW2
  2130. RSLW1:        DW    BLOCKWRT
  2131. RSLW2:        DW    DSKERR,    AT,    DDUP
  2132.             $GO?0    RSLW5        ;OK
  2133.         DW    ZLESS
  2134.             $GO?0    RSLW3
  2135.         DW    LIT,    9        ;Write error
  2136.             $GOTO    RSLW4
  2137. RSLW3:        DW    LIT,    8        ;Read error
  2138. RSLW4:        DW    LIT,    7FFFH        ;Set buffer to 32767
  2139.         DW    PREV,    AT,    STORE    ; to mark as bad
  2140.         DW    WARN,    AT,    ZLESS    ;If WARNING<0 then
  2141.             $GO?0 RSLW6        ;assume he can handle it
  2142.             $GOTO RSLW7        ;otherwise,
  2143. RSLW6:        DW    ZERO,    WARN,    STORE    ;don't try to read!
  2144. RSLW7:        DW    QERR
  2145. RSLW5:        DW    SEMIS
  2146.  
  2147. ;=:*  FLUSH    empty buffers, saving changed ones    --
  2148.  
  2149.         $COLON    85H,FLUS,H,FLUSH
  2150.         DW    NOBUF,    ONEP
  2151.         DW    ZERO,    XDO
  2152. FLUS1:         DW    LIT,    7FFFH,    BUFFE,    DROP
  2153.             $LOOP    FLUS1
  2154.         DW    SEMIS
  2155.  
  2156. ;=:   LOAD    interpret screen n            n --
  2157.  
  2158.         $COLON    84H,LOA,D
  2159.         DW    BLK,    AT,    TOR
  2160.         DW    INN,    AT,    TOR
  2161.         DW    ZERO,    INN,    STORE
  2162.         DW    BSCR,    STAR,    BLK,    STORE
  2163.         DW    INTER
  2164.         DW    FROMR,    INN,    STORE
  2165.         DW    FROMR,    BLK,    STORE
  2166.         DW    SEMIS
  2167.  
  2168. ;=:   -->    continue with next screen        --
  2169.  
  2170.         $COLON    0C3H,--,!!!>
  2171.         DW    QLOAD
  2172.         DW    ZERO,    INN,    STORE
  2173.         DW    BSCR,    BLK,    AT
  2174.         DW    OVER,    MODD,    SUBB
  2175.         DW    BLK,    PSTOR,    SEMIS
  2176. SUBTTL
  2177. PAGE +
  2178.  
  2179.  
  2180. ;=:   '        find next input word in dictionary    -- PFA
  2181.  
  2182.         _NFA    = $
  2183.         DB    0C1H,"'"+80H
  2184.         $LINKS    DOCOL,TICK
  2185.  
  2186.         DW    DFIND,    ZEQU
  2187.         DW    ZERO,    QERR
  2188.         DW    DROP,    LITER,    SEMIS
  2189.  
  2190. ;=:*  FORGET    chop off the top of the dictionary    --
  2191.  
  2192.         $COLON    86H,FORGE,T
  2193.         DW    CURR,    AT
  2194.         DW    CONT,    AT
  2195.         DW    SUBB
  2196.         DW    LIT,    24,    QERR    ;"declare vocabulary"
  2197.         DW    TICK,    DUPP
  2198.         DW    FENCE,    AT,    ULESS    ;note change from fig
  2199.         DW    LIT,    21,    QERR    ;"in protected dictionary"
  2200.         DW    DUPP
  2201.         DW    NFA,    DP,    STORE
  2202.         DW    LFA,    AT
  2203.         DW    CONT,    AT,    STORE,    SEMIS
  2204. SUBTTL Control flow structures
  2205. PAGE
  2206.  
  2207. ;=:   BACK    compile a backward branch offset    target --
  2208.  
  2209.         $COLON    84H,BAC,K,BACK
  2210.         DW    HERE,    SUBB
  2211.         DW    COMMA,    SEMIS
  2212.  
  2213. ;=:   BEGIN    starting point of looping structures    -- HERE 1
  2214.  
  2215.         $COLON    0C5H,BEGI,N
  2216.         DW    QCOMP
  2217.         DW    HERE,    ONE,    SEMIS
  2218.  
  2219. ;=:   ENDIF    end of IF..ELSE..THEN structure        addr 2 --
  2220.  
  2221.         $COLON    0C5H,ENDI,F,ENDIFF
  2222.         DW    QCOMP
  2223.         DW    TWO,    QPAIR
  2224.         DW    HERE,    OVER,    SUBB
  2225.         DW    SWAP,    STORE,    SEMIS
  2226.  
  2227. ;=:   THEN    synonym for ENDIF            addr 2 --
  2228.  
  2229.         $COLON    0C4H,THE,N
  2230.         DW    ENDIFF,    SEMIS
  2231.  
  2232. ;=:   DO    start of DO..LOOP structure        -- HERE 3
  2233.  
  2234.         $COLON    0C2H,D,O
  2235.         DW    COMP,    XDO
  2236.         DW    HERE,    THREE,    SEMIS
  2237.  
  2238. ;=:   LOOP    end of DO..LOOP structure        addr 3 --
  2239.  
  2240.         $COLON    0C4H,LOO,P
  2241.         DW    THREE,    QPAIR
  2242.         DW    COMP,    XLOOP
  2243.         DW    BACK,    SEMIS
  2244.  
  2245. ;=:   +LOOP    end of DO..+LOOP structure        addr 3 --
  2246.  
  2247.         $COLON    0C5H,+LOO,P
  2248.         DW    THREE,    QPAIR
  2249.         DW    COMP,    XPLOO
  2250.         DW    BACK,    SEMIS
  2251.  
  2252. ;=:   UNTIL    end of BEGIN..UNTIL loop        addr 1 --
  2253.  
  2254.         $COLON    0C5H,UNTI,L,UNTIL
  2255.         DW    ONE,    QPAIR
  2256.         DW    COMP,    ZBRAN
  2257.         DW    BACK,    SEMIS
  2258.  
  2259. ;=:   END    synonym for UNTIL            addr 1 --
  2260.  
  2261.         $COLON    0C3H,EN,D
  2262.         DW    UNTIL,    SEMIS
  2263.  
  2264. ;=:   AGAIN    end of BEGIN..AGAIN infinite loop    addr 1 --
  2265.  
  2266.         $COLON    0C5H,AGAI,N,AGAIN
  2267.         DW    ONE,    QPAIR
  2268.         DW    COMP,    BRAN
  2269.         DW    BACK,    SEMIS
  2270.  
  2271. ;=:   REPEAT    end of BEGIN..WHILE..REPEAT structure    addr 1 --
  2272.  
  2273.         $COLON    0C6H,REPEA,T
  2274.         DW    TOR,    TOR
  2275.         DW    AGAIN
  2276.         DW    FROMR,    FROMR
  2277.         DW    TWO,    SUBB
  2278.         DW    ENDIFF,    SEMIS
  2279.  
  2280. ;=:   IF    conditional branch structure        -- 2
  2281.  
  2282.         $COLON    0C2H,I,F,IFF
  2283.         DW    COMP,    ZBRAN
  2284.         DW    HERE,    ZERO,    COMMA
  2285.         DW    TWO,    SEMIS
  2286.  
  2287. ;=:   ELSE    optional part of IF..ELSE..THEN        addr 2 -- HERE 2
  2288.  
  2289.         $COLON    0C4H,ELS,E
  2290.         DW    TWO,    QPAIR
  2291.         DW    COMP,    BRAN
  2292.         DW    HERE,    ZERO,    COMMA
  2293.         DW    SWAP
  2294.         DW    TWO,    ENDIFF,    TWO
  2295.         DW    SEMIS
  2296.  
  2297. ;=:   WHILE    conditional loop BEGIN..WHILE..REPEAT    addr 2 -- HERE 4
  2298.  
  2299.         $COLON    0C5H,WHIL,E
  2300.         DW    IFF,    TWOP,    SEMIS
  2301. SUBTTL Output formatting words
  2302. PAGE +
  2303.  
  2304.  
  2305. ;=:   SPACES    type n spaces                n --
  2306.  
  2307.         $COLON    86H,SPACE,S,SPACS
  2308.         DW    ZERO,    MAX
  2309.         DW    DDUP
  2310.             $GO?0    SPAX1
  2311.         DW    ZERO,    XDO
  2312. SPAX2:         DW    SPACE
  2313.             $LOOP    SPAX2
  2314. SPAX1:         DW    SEMIS
  2315.  
  2316. ;=:   <#    begin number formatting            --
  2317.  
  2318.         $COLON    82H,!!!<,#,BDIGS
  2319.         DW    PAD,    HLD,    STORE
  2320.         DW    SEMIS
  2321.  
  2322. ;=:   #>    end number formatting            d -- addr count
  2323.  
  2324.         $COLON    82H,#,!!!>,EDIGS
  2325.         DW    DROP,    DROP
  2326.         DW    HLD,    AT
  2327.         DW    PAD
  2328.         DW    OVER,    SUBB,    SEMIS
  2329.  
  2330. ;=:   SIGN    places a '-' in output if n < 0        n d -- d
  2331.  
  2332.         $COLON    84H,SIG,N,SIGN
  2333.         DW    ROT,    ZLESS
  2334.             $GO?0    SIGN1
  2335.         DW    LIT,    '-',    HOLD
  2336. SIGN1:         DW    SEMIS
  2337.  
  2338. ;=:   #        convert one digit of d1 to ASCII    d1 -- d2
  2339.  
  2340.         $COLON    81H,,#,DIG
  2341.         DW    BASE,    AT,    MSMOD
  2342.         DW    ROT
  2343.         DW    LIT,    9
  2344.         DW    OVER,    LESS
  2345.             $GO?0    DIG1
  2346.         DW    LIT,    7,    PLUS
  2347. DIG1:         DW    LIT,    '0',    PLUS
  2348.         DW    HOLD,    SEMIS
  2349.  
  2350. ;=:   #S    process all significant digits of d1    d1 -- 0.
  2351.  
  2352.         $COLON    82H,#,S,DIGS
  2353. DIGS1:         DW    DIG
  2354.         DW    OVER,    OVER
  2355.         DW    ORR,    ZEQU
  2356.             $GO?0    DIGS1
  2357.         DW    SEMIS
  2358.  
  2359. ;=:   D.R    print d right-aligned in n columns    d n --
  2360.  
  2361.         $COLON    83H,D.,R,DDOTR
  2362.         DW    TOR,    SWAP,    OVER
  2363.         DW    DABS
  2364.         DW    BDIGS
  2365.         DW    DIGS,    SIGN
  2366.         DW    EDIGS
  2367.         DW    FROMR,    OVER,    SUBB
  2368.         DW    SPACS,    TYPES,    SEMIS
  2369.  
  2370. ;=:   .R    print n1 right-aligned in n2 columns    n1 n2 --
  2371.  
  2372.         $COLON    82H,.,R,DOTR
  2373.         DW    TOR
  2374.         DW    STOD,    FROMR,    DDOTR,    SEMIS
  2375.  
  2376. ;=:   D.    print a 32-bit number            d --
  2377.  
  2378.         $COLON    82H,D,.,DDOT
  2379.         DW    ZERO
  2380.         DW    DDOTR,    SPACE,    SEMIS
  2381.  
  2382. ;=:   .        print a 16-bit number            n --
  2383.  
  2384.         $COLON    81H,,.,DOT
  2385.         DW    STOD,    DDOT,    SEMIS
  2386.  
  2387. ;=:   ?        print the value at addr            addr --
  2388.  
  2389.         $COLON    81H,,?,QUES
  2390.         DW    AT,    DOT,    SEMIS
  2391.  
  2392. ;=:   U.    print an unsigned 16-bit number        u --
  2393.  
  2394.         $COLON    82H,U,.,UDOT
  2395.         DW    ZERO,    DDOT,    SEMIS
  2396.  
  2397. ;=:   VLIST    print the words in CONTEXT vocabulary    --
  2398.  
  2399.         $COLON    85H,VLIS,T
  2400.         DW    LIT,    80H
  2401.         DW    OUTT,    STORE
  2402.         DW    CONT,    AT,    AT
  2403. VLIS1:         DW    OUTT,    AT
  2404.         DW    CSLL,    GREAT
  2405.             $GO?0    VLIS2
  2406.         DW    CR
  2407.         DW    ZERO,    OUTT,    STORE
  2408. VLIS2:         DW    DUPP
  2409.         DW    IDDOT
  2410.         DW    SPACE,    SPACE
  2411.         DW    PFA,    LFA,    AT
  2412.         DW    DUPP,    ZEQU
  2413.         DW    QTERM,    ORR
  2414.             $GO?0    VLIS1
  2415.         DW    DROP,    SEMIS
  2416.  
  2417. ;=:   LIST    list screen n, as 16 lines of 64 chars    n --
  2418.  
  2419.         $COLON    84H,LIS,T,LISTC
  2420.         DW    DUPP,    BLOCK    ,DROP    ;added 7-9-83
  2421.         DW    DECA,    CR
  2422.         DW    DUPP,    SCR,    STORE
  2423.         DW    PDOTQ
  2424.         DB    6,"SCR # "
  2425.         DW    DOT
  2426.         DW    LIT,    16,    ZERO,    XDO
  2427. LIST1:         DW    CR,    IDO
  2428.         DW    LIT,    3,    DOTR,    SPACE
  2429.         DW    IDO,    SCR,    AT,    DLINE
  2430.         DW    QTERM
  2431.             $GO?0    LIST2
  2432.         DW    LEAVE
  2433. LIST2:             $LOOP    LIST1
  2434.         DW    CR,    SEMIS
  2435.  
  2436. ;=:   INDEX    print line 0 of screens n1 thru n2    n1 n2 --
  2437.  
  2438.         $COLON    85H,INDE,X
  2439.         DW    LIT,    FF,    EMIT,    CR
  2440.         DW    ONEP,    SWAP,    XDO
  2441. INDE1:         DW    CR,    IDO
  2442.         DW    LIT,    3,    DOTR,    SPACE
  2443.         DW    ZERO,    IDO,    DLINE
  2444.         DW    QTERM
  2445.             $GO?0    INDE2
  2446.         DW    LEAVE
  2447. INDE2:             $LOOP    INDE1
  2448.         DW    SEMIS
  2449.  
  2450. ;=:   TRIAD    list screens in groups of three        n1 n2 --
  2451.  
  2452.         $COLON    85H,TRIA,D
  2453.         DW    LIT,    FF,    EMIT
  2454.         DW    LIT,    3,    SLASH
  2455.         DW    LIT,    3,    STAR
  2456.         DW    LIT,    3,    OVER
  2457.         DW    PLUS,    SWAP,    XDO
  2458. TRIA1:         DW    CR,    IDO,    LISTC
  2459.         DW    QTERM
  2460.             $GO?0    TRIA2
  2461.         DW    LEAVE
  2462. TRIA2:             $LOOP    TRIA1
  2463.         DW    CR
  2464.         DW    LIT,    15,    MESS,    CR
  2465.         DW    SEMIS
  2466. ;
  2467.         $COLON    84H,.CP,U,DOTCPU
  2468.         DW    BASE,    AT
  2469.         DW    LIT,    36,    BASE,    STORE
  2470.         DW    LIT,    22H,    PORIG,    TAT
  2471.         DW    DDOT
  2472.         DW    BASE,    STORE,    SEMIS
  2473.  
  2474. IF    _EXTEND
  2475. INCLUDE    4TH-XTNS.ASM
  2476. ENDIF
  2477.  
  2478.     $REPORT    <FORTH definitions completed>
  2479.  
  2480. SUBTTL End of FORTH dictionary
  2481. PAGE
  2482.  
  2483.  
  2484.  
  2485. ;=:   TASK    word to mark the end of the dictionary    --
  2486.  
  2487. LASTNFA:
  2488.         $COLON    84H,TAS,K,TASK
  2489.         DW    SEMIS
  2490. ;
  2491. INITDP        EQU    $
  2492. MAIN        ENDS
  2493.  
  2494.     $REPORT    <End of assembly source>
  2495.  
  2496.         END    ORIG
  2497.