home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / FFA.ZIP / KERNEL2.SEQ < prev    next >
Encoding:
Text File  |  1988-01-06  |  27.6 KB  |  798 lines

  1. \ KERNEL2.SEQ   More kernel stuff
  2.  
  3. FILES DEFINITIONS
  4.  
  5. VARIABLE KERNEL2.SEQ
  6.  
  7. FORTH DEFINITIONS
  8.  
  9. USER DEFINITIONS
  10. VARIABLE  TOS         ( TOP OF STACK )
  11. VARIABLE  ENTRY       ( ENTRY POINT, CONTAINS MACHINE CODE )
  12. VARIABLE  LINK        ( LINK TO NEXT TASK )
  13. VARIABLE  SP0         ( INITIAL PARAMETER STACK )
  14. VARIABLE  RP0         ( INITIAL RETURN STACK )
  15. VARIABLE  DP          ( DICTIONARY POINTER )
  16. VARIABLE  OFFSET      ( RELATIVE TO ABSOLUTE DISK BLOCK 0 )
  17. VARIABLE  BASE        ( FOR NUMERIC INPUT AND OUTPUT )
  18. VARIABLE  HLD         ( POINTS TO LAST CHARACTER HELD IN PAD )
  19. VARIABLE  PRINTING
  20. VARIABLE  YDP         ( HEADER SEG POINTER )
  21.    DEFER  EMIT
  22.    DEFER  KEY?
  23.    DEFER  KEY
  24.    DEFER  TYPE
  25. VARIABLE  XDP
  26.  
  27. META DEFINITIONS
  28. VARIABLE  PRIOR     ( USED FOR DICTIONARY SEARCHES )
  29. VARIABLE  STATE     ( COMPILATION OR INTERPRETATION )
  30. VARIABLE  WARNING   ( GIVE USER DUPLICATE WARNINGS IF ON )
  31. VARIABLE  DPL       ( NUMERIC INPUT PUNCTUATION )
  32. VARIABLE  R#        ( EDITING CURSOR POSITION )
  33. VARIABLE  LAST      ( POINTS TO NFA OF LATEST DEFINITION )
  34. VARIABLE  CSP       ( HOLDS STACK POINTER FOR ERROR CHECKING )
  35. VARIABLE  CURRENT   ( VOCABULARY WHICH GETS DEFINITIONS )
  36. 8 CONSTANT #VOCS    ( THE NUMBER OF VOCABULARIES TO SEARCH )
  37. VARIABLE  CONTEXT   ( VOCABULARY SEARCHED FIRST )
  38.    HERE THERE #VOCS 2* DUP ALLOT ERASE
  39.  
  40. VARIABLE  'TIB      ( ADDRESS OF TERMINAL INPUT BUFFER )
  41. VARIABLE  WIDTH     ( WIDTH OF NAME FIELD )
  42. VARIABLE  VOC-LINK  ( POINTS TO NEWEST VOCABULARY )
  43. VARIABLE  >IN       ( OFFSET INTO INPUT STREAM )
  44. VARIABLE  SPAN      ( NUMBER OF CHARACTERS EXPECTED )
  45. VARIABLE  #TIB      ( NUMBER OF CHARACTERS TO INTERPRET )
  46. VARIABLE  END?      ( TRUE IF INPUT STREAM EXHAUSTED )
  47. VARIABLE  #OUT      ( NUMBER OF CHARACTERS EMITTED )
  48. VARIABLE  #LINE     ( THE NUMBER OF LINES SENT SO FAR )
  49.  
  50. VARIABLE YSTART         \ HEAD  START OFFSET
  51. VARIABLE XSTART         \ LIST  START OFFSET
  52. VARIABLE XMOVED         \ FLAG TO TELL IF LIST HAS BEEN MOVED
  53. VARIABLE YSEG           \ HEAD  SEGMENT
  54. VARIABLE XSEG           \ BODY  SEGMENT
  55. VARIABLE SSEG           \ SEARCH & SCAN SEGMENT
  56.  
  57. VARIABLE SHNDL          \ the sequential handl POINTER
  58. VARIABLE LOADLINE       \ Offset to line we loaded from
  59. VARIABLE ERRORLINE      \ Last loaded line #
  60.  
  61. 32 CONSTANT BL
  62.  8 CONSTANT BS
  63.  7 CONSTANT BELL
  64.  
  65. VARIABLE CAPS
  66.  
  67. CODE FILL       (  start-addr count char -- )
  68.                 CLD             MOV BX, DS
  69.                 POP AX          POP CX          POP DI
  70.                 PUSH ES         MOV ES, BX
  71.                 REPNZ           STOSB           POP ES
  72.                 NEXT            END-CODE
  73.  
  74. CODE LFILL      (  seg start-addr count char -- )
  75.                 CLD             POP AX          POP CX
  76.                 POP DI          POP BX
  77.                 PUSH ES         MOV ES, BX
  78.                 REPNZ           STOSB           POP ES
  79.                 NEXT            END-CODE
  80.  
  81. : ERASE         ( addr len -- ) 0 FILL   ;
  82. : BLANK         ( addr len -- ) BL FILL   ;
  83.  
  84. CODE COUNT      ( addr -- addr+1 len )
  85.                 POP BX          SUB AX, AX      MOV AL, 0 [BX]
  86.                 INC BX          PUSH BX
  87.                 1PUSH           END-CODE
  88.  
  89. CODE LENGTH     ( addr -- addr+2 len )    \ REALLY WORD COUNT
  90.                 POP BX          MOV AX, 0 [BX]
  91.                 INC BX          INC BX
  92.                 PUSH BX         1PUSH           END-CODE
  93.  
  94. : MOVE          ( from to len -- )
  95.                 -ROT   2DUP U< IF   ROT CMOVE>   ELSE   ROT CMOVE   THEN ;
  96.  
  97. DECIMAL
  98.  
  99. CREATE ATBL     \ Uppercase translation table
  100.  0  C,   1  C,   2  C,   3  C,   4  C,   5  C,   6  C,   7  C,
  101.  8  C,  32  C,  10  C,  11  C,  12  C,  13  C,  14  C,  15  C,
  102. 16  C,  17  C,  18  C,  19  C,  20  C,  21  C,  22  C,  23  C,
  103. 24  C,  25  C,  26  C,  27  C,  28  C,  29  C,  30  C,  31  C,
  104. 32  C,  '!' C,  '"' C,  '#' C,  '$' C,  '%' C,  '&' C,  ''' C,
  105. '(' C,  ')' C,  '*' C,  '+' C,  ',' C,  '-' C,  '.' C,  '/' C,
  106. '0' C,  '1' C,  '2' C,  '3' C,  '4' C,  '5' C,  '6' C,  '7' C,
  107. '8' C,  '9' C,  ':' C,  ';' C,  '<' C,  '=' C,  '>' C,  '?' C,
  108. '@' C,  'A' C,  'B' C,  'C' C,  'D' C,  'E' C,  'F' C,  'G' C,
  109. 'H' C,  'I' C,  'J' C,  'K' C,  'L' C,  'M' C,  'N' C,  'O' C,
  110. 'P' C,  'Q' C,  'R' C,  'S' C,  'T' C,  'U' C,  'V' C,  'W' C,
  111. 'X' C,  'Y' C,  'Z' C,  '[' C,  '\' C,  ']' C,  '^' C,  '_' C,
  112. '`' C,  'A' C,  'B' C,  'C' C,  'D' C,  'E' C,  'F' C,  'G' C,
  113. 'H' C,  'I' C,  'J' C,  'K' C,  'L' C,  'M' C,  'N' C,  'O' C,
  114. 'P' C,  'Q' C,  'R' C,  'S' C,  'T' C,  'U' C,  'V' C,  'W' C,
  115. 'X' C,  'Y' C,  'Z' C,  '{' C,  '|' C,  '}' C,  '~' C,  127 C,
  116. \ Characters above 127 are translated to below 127
  117.  0  C,   1  C,   2  C,   3  C,   4  C,   5  C,   6  C,   7  C,
  118.  8  C,   9  C,  10  C,  11  C,  12  C,  13  C,  14  C,  15  C,
  119. 16  C,  17  C,  18  C,  19  C,  20  C,  21  C,  22  C,  23  C,
  120. 24  C,  25  C,  26  C,  27  C,  28  C,  29  C,  30  C,  31  C,
  121. 32  C,  '!' C,  '"' C,  '#' C,  '$' C,  '%' C,  '&' C,  ''' C,
  122. '(' C,  ')' C,  '*' C,  '+' C,  ',' C,  '-' C,  '.' C,  '/' C,
  123. '0' C,  '1' C,  '2' C,  '3' C,  '4' C,  '5' C,  '6' C,  '7' C,
  124. '8' C,  '9' C,  ':' C,  ';' C,  '<' C,  '=' C,  '>' C,  '?' C,
  125. '@' C,  'A' C,  'B' C,  'C' C,  'D' C,  'E' C,  'F' C,  'G' C,
  126. 'H' C,  'I' C,  'J' C,  'K' C,  'L' C,  'M' C,  'N' C,  'O' C,
  127. 'P' C,  'Q' C,  'R' C,  'S' C,  'T' C,  'U' C,  'V' C,  'W' C,
  128. 'X' C,  'Y' C,  'Z' C,  '[' C,  '\' C,  ']' C,  '^' C,  '_' C,
  129. '`' C,  'A' C,  'B' C,  'C' C,  'D' C,  'E' C,  'F' C,  'G' C,
  130. 'H' C,  'I' C,  'J' C,  'K' C,  'L' C,  'M' C,  'N' C,  'O' C,
  131. 'P' C,  'Q' C,  'R' C,  'S' C,  'T' C,  'U' C,  'V' C,  'W' C,
  132. 'X' C,  'Y' C,  'Z' C,  '{' C,  '|' C,  '}' C,  '~' C,  127 C,
  133.  
  134. CODE UPC        ( char -- char' )
  135.                 POP AX
  136.                 MOV BX, # ATBL
  137.                 XLAT
  138.                 1PUSH
  139.                 END-CODE
  140.  
  141. CODE UPPER      ( addr len -- )         \ convert string to upper case
  142. LABEL >UPPER            POP CX                  \ get length
  143.                         POP DI                  \ and starting address
  144.                         PUSH SI                 \ save IP
  145.                         PUSH ES                 \ and LIST POINTER
  146.                         MOV DX, DS
  147.                         MOV ES, DX              \ set ES to DS
  148.                         MOV SI, DI              \ set SI to DI
  149.                         MOV BX, # ATBL          \ loadup BX with table
  150.                         CLD                     \ clear direction flag
  151.                         OR CX, CX               \ test length not zero
  152.                 0<> IF
  153.                         HERE                    \ get a char and traslate it
  154.                                 LODSB   XLAT
  155.                                 STOSB
  156.                         LOOPNZ                  \ until all chars are done
  157.                     THEN
  158.                         POP ES                  \ restore ES=LIST
  159.                         POP SI                  \     and SI=IP
  160.                         NEXT    END-CODE
  161.  
  162. \ : ?UPPERCASE    ( adr -- adr )
  163. \                 CAPS @ IF  DUP COUNT UPPER   THEN  ;
  164.  
  165. CODE ?UPPERCASE ( A1 --- A1 )           \ conditionally convert to upper case
  166.                 MOV AX, CAPS            \ test CAPS variable
  167.                 OR AX, AX
  168.         0= IF                           \ leave if CAPS is not on
  169.                 NEXT
  170.         THEN                            \ it is is, then do COUNT
  171.                 POP BX          PUSH BX         \ get a copy of address a1
  172.                 SUB AX, AX      MOV AL, 0 [BX]
  173.                 INC BX          PUSH BX         \ push a1+1
  174.                 PUSH AX                         \ and count
  175.                 JMP >UPPER                      \ go translate to upper case
  176.                 END-CODE
  177.  
  178. CODE <HERE>     ( -- adr )
  179.                 MOV BX, UP      MOV AX, DP [BX]
  180.                 1PUSH           END-CODE
  181.  
  182. DEFER HERE ' <HERE> IS HERE
  183.  
  184. : PAD           ( -- addr ) HERE 80 +   ;
  185.  
  186. : -TRAILING     ( addr len -- addr len' )
  187.                 DUP 0 ?DO   2DUP + 1- C@   BL <> ?LEAVE   1-   LOOP   ;
  188.  
  189. CODE COMP       ( addr1 addr2 len -- -1 | 0 | 1 )
  190.                 MOV DX, SI      POP CX
  191.                 POP DI          POP SI
  192.   CX<>0 IF
  193.                 PUSH ES         MOV ES, SSEG
  194.                 REPZ            CMPSB
  195.         0<> IF
  196. LABEL COMPX  0< IF
  197.                    MOV CX, # -1
  198.                 ELSE
  199.                    MOV CX, # 1
  200.                 THEN
  201.             THEN
  202.         THEN
  203. LABEL NOMORE    MOV SI, DX
  204.                 POP ES
  205.                 PUSH CX
  206.                 NEXT            END-CODE
  207.  
  208. HEX
  209.  
  210. CODE CAPS-COMP  ( addr1 addr2 len -- -1 | 0 | 1 )
  211.                 MOV DX, SI      POP CX
  212.                 POP DI          POP SI
  213.                 PUSH ES         MOV ES, SSEG
  214.             BEGIN
  215.                 JCXZ NOMORE
  216.                 MOV     AH, 0 [SI]      INC SI
  217.                 MOV ES: AL, 0 [DI]      INC DI
  218.                 OR AX, # 2020           CMP AH, AL
  219.                 JNE COMPX               DEC CX
  220.             AGAIN
  221.                 END-CODE
  222.  
  223. DECIMAL
  224.  
  225. : COMPARE       ( addr1 addr2 len -- -1 | 0 | 1 )
  226.                 CAPS @ IF   CAPS-COMP   ELSE   COMP   THEN   ;
  227.  
  228. VARIABLE OSF
  229.  
  230. LABEL FCDOS     PUSH SI         PUSH BP
  231.                 INC CS: OSF WORD
  232.                 INT 33
  233.                 DEC CS: OSF WORD
  234.                 POP BP          POP SI
  235.                 RET             END-CODE
  236.  
  237. CODE XFDOS      ( DX CX BX AX ES DS-CX BX AX CY)
  238.                 POP DI          POP DS          POP AX
  239.                 POP BX          POP CX          POP DX
  240.                 PUSH ES         PUSH DS         POP ES
  241.                 PUSH CS
  242.                 MOV DS, DI      CALL FCDOS
  243.                 POP DS          POP ES          MOV DX, # -1
  244.             U>= IF
  245.                 XOR DX, DX
  246.             THEN
  247.                 PUSH CX         PUSH BX
  248.                 PUSH AX         PUSH DX
  249.                 NEXT            END-CODE
  250.  
  251. CODE ?CS:       ( -- CS )
  252.                 PUSH CS         NEXT            END-CODE
  253.  
  254. CODE ?ES:       ( -- CS )
  255.                 PUSH ES         NEXT            END-CODE
  256.  
  257. CODE @L         ( seg addr --- word )
  258.                 POP BX          POP DS          MOV AX, 0 [BX]
  259.                 MOV BX, CS      MOV DS, BX
  260.                 1PUSH           END-CODE
  261.  
  262. CODE C@L        ( seg addr --- byte )
  263.                 POP BX          POP DS          MOV AL, 0 [BX]
  264.                 XOR AH, AH      MOV BX, CS      MOV DS, BX
  265.                 1PUSH           END-CODE
  266.  
  267. CODE C!L        ( byt seg adr )
  268.                 POP BX          POP DS          POP AX
  269.                 MOV 0 [BX], AL  MOV BX, CS      MOV DS, BX
  270.                 NEXT            END-CODE
  271.  
  272. CODE !L         ( n seg adr -- )
  273.                 POP BX          POP DS          POP AX
  274.                 MOV 0 [BX], AX  MOV BX, CS      MOV DS, BX
  275.                 NEXT            END-CODE
  276.  
  277. CODE <BDOS>     ( n fun -- m )
  278.                 POP AX          MOV AH, AL      POP DX
  279.                 INT 33          SUB AH, AH
  280.                 1PUSH           END-CODE
  281.  
  282. DEFER BDOS      ' <BDOS> IS BDOS
  283.  
  284. CODE BDOS2      ( CX DX AX -- CX DX AX )
  285.                 POP AX          POP DX          POP CX
  286.                 MOV AH, AL      INT 33
  287.                 PUSH CX         PUSH DX         PUSH AX
  288.                 NEXT            END-CODE
  289.  
  290. : OS2           BDOS2 255 AND ;
  291.  
  292. HEX
  293.  
  294. VARIABLE BIOSCHAR       \ Holds the char from BIOS on scan by BIOSKEY?
  295. VARIABLE BIOSKEYVAL     \ Holds the key value from BIOSKEY
  296.  
  297. CODE BIOSKEY?   ( --- f1 )
  298.                 MOV AH, # 1
  299.                 INT 16
  300.                 MOV BIOSCHAR AX
  301.              0= IF
  302.                 MOV AX, # 0
  303.              ELSE
  304.                 MOV AX, # -1
  305.              THEN
  306.                 1PUSH           END-CODE
  307.  
  308. CODE BIOSKEY    ( --- c1 )
  309.                 MOV AH, # 0
  310.                 INT 16
  311.                 MOV BIOSKEYVAL AX
  312.                 1PUSH           END-CODE
  313.  
  314. DECIMAL
  315.  
  316. DEFER KEYFILTER ' NOOP IS KEYFILTER     \ Pre-filter keys before passing on.
  317.  
  318. DEFER BGSTUFF   ' NOOP IS BGSTUFF       \ BACKGROUND STUFF
  319.  
  320. : (KEY?)        ( -- f ) BGSTUFF BIOSKEY? ;
  321.  
  322. : (KEY)         ( -- CHAR )
  323.                 BEGIN   PAUSE KEY? UNTIL
  324.                 BIOSKEY DUP 127 AND 0=
  325.                 IF      FLIP 127 AND 128 OR
  326.                 ELSE    127 AND
  327.                 THEN    KEYFILTER ;
  328.  
  329. DEFER OUTPAUSE  ( ' PAUSE ) ' NOOP IS OUTPAUSE
  330.  
  331. : (CONSOLE)     ( char -- )
  332.                 OUTPAUSE   6 BDOS DROP #OUT INCR
  333.                 PRINTING @ 0=
  334.                 IF      #OUT @ 79 >   \ if at right edge
  335.                         IF      #OUT OFF    \ fix counters
  336.                                 #LINE @ 1+ 24 MIN #LINE !
  337.                         THEN
  338.                 THEN    ;
  339.  
  340. CODE CMOVEL     ( sseg sptr dseg dptr cnt )
  341.                 CLD             MOV BX, SI
  342.                 POP CX          POP DI
  343.                 POP AX          POP SI
  344.                 POP DS          PUSH ES         MOV ES, AX
  345.                 OR CX, CX
  346.             0<> IF
  347.                 REPNZ           MOVSB
  348.             THEN
  349.                 POP ES
  350.                 MOV AX, CS      MOV DS, AX
  351.                 MOV SI, BX
  352.                 NEXT            END-CODE
  353.  
  354. CODE CMOVEL>    ( sseg sptr dseg dptr cnt )
  355.                 STD             MOV BX, SI
  356.                 POP CX          POP DI
  357.                 POP AX          POP SI
  358.                 POP DS          PUSH ES         MOV ES, AX
  359.                 OR CX, CX
  360.             0<> IF
  361.                 DEC CX          ADD DI, CX
  362.                 ADD SI, CX      INC CX
  363.                 REPNZ           MOVSB
  364.             THEN
  365.                 POP ES
  366.                 MOV AX, CS      MOV DS, AX
  367.                 MOV SI, BX
  368.                 CLD
  369.                 NEXT            END-CODE
  370.  
  371. HEX
  372. 1000 CONSTANT #CODESEGS \ Number of segments needed for CODE.  64k
  373. 1000 CONSTANT #LISTSEGS \ Number of segments needed for : definitions. 64k
  374.  C00 CONSTANT #HEADSEGS \ Number of segments needed for HEADS. 48k
  375.  
  376. DECIMAL
  377.  
  378.  
  379. : MEMCHK        ( F1 --- )
  380.                 IF      ." Insufficient Memory"
  381.                         0 0 BDOS
  382.                 THEN ;
  383.  
  384. HEX
  385.  
  386. CODE DEALLOC    ( N1 -- F1 ) \ N1 = BLOCK TO DE-ALLOCATE, F1 = 0 IS OK
  387.                 MOV AH, # 49 \ F1 = 9 INVALID BLOCK ADDRESS
  388.                 POP DX
  389.                 PUSH ES         MOV ES, DX      INT 21
  390.              u< if
  391.                 sub ah, ah
  392.              else
  393.                 mov ax, # 0
  394.              then
  395.                 POP ES          1PUSH           END-CODE
  396.  
  397. CODE ALLOC      ( N1 -- N2 N3 F1 )      \ N1 = SIZE NEEDED, N3 = SEGMENT
  398.                                         \ N2 = LARGEST SEGMENT AVAILABLE
  399.                 MOV AH, # 48            \ F1 = 8 NOT ENOUGH MEMORY.
  400.                 POP BX
  401.                 INT 21
  402.                 PUSH BX         PUSH AX
  403.              u< if
  404.                 sub ah, ah
  405.              else
  406.                 mov ax, # 0
  407.              then
  408.                 1PUSH           END-CODE
  409.  
  410. : MEMSET        ( N1 --- F1 )
  411.                 0 0 ROT 4A00 ?CS: DUP XFDOS >R 3DROP R> ;
  412.  
  413. : DOSVER        0 30 BDOS 0FF AND ;
  414.  
  415. : SETYSEG       ( --- )   \ SETS HEAD SEGMENT + MORE SPACE
  416.                 [ LABEL 'SETYSEG ]
  417.                 ?CS: SSEG !
  418.                 ?ES: XSEG !
  419.                 XSTART @ DP !
  420.                 DOSVER 2 <
  421.                 IF      ." Must have DOS 2.x or higher, prefer 3.x"
  422.                         0 0 BDOS
  423.                 THEN
  424.                 #CODESEGS #LISTSEGS + #HEADSEGS + MEMSET MEMCHK
  425.                 #OUT 0! 18 ( 24 DECIMAL ) #LINE ! ;
  426.  
  427. DECIMAL
  428.  
  429. CODE YHERE      ( -- adr )
  430.                 MOV BX, UP      MOV AX, YDP [BX]
  431.                 1PUSH           END-CODE
  432.  
  433. CODE YS:        ( W -- YSEG W )
  434.                 POP AX          MOV DX, YSEG
  435.                 2PUSH           END-CODE
  436.  
  437. : YC@           ( yaddr -- char ) YS: C@L ;
  438. : YC!           ( yaddr -- char ) YS: C!L ;
  439. : Y@            ( ad -- n )       YS: @L ;
  440. : Y!            ( n yaddr -- )    YS: !L ;
  441. : Y,            ( n -- )          YHERE Y!  2 YDP +! ;
  442. : YCSET         ( byte yaddr -- ) TUCK YC@ OR SWAP YC! ;
  443. : YHASH         ( ystr vocaddr -- thread )
  444.                 SWAP
  445.                 DUP YC@ SWAP 1+ YC@ +
  446. \ ****          1+ YC@
  447.                 #THREADS 1- AND 2* + ;
  448.  
  449. CODE XHERE      ( -- adr )
  450.                 MOV BX, UP      MOV AX, XDP [BX]
  451.                 1PUSH           END-CODE
  452.  
  453. CODE XS:        ( W -- XSEG W )
  454.                 POP AX          MOV DX, XSEG
  455.                 2PUSH           END-CODE
  456.  
  457. : XC@           ( xaddr -- char ) XS: C@L ;
  458. : XC!           ( xaddr -- char ) XS: C!L ;
  459. : X@            ( ad -- n )       XS: @L ;
  460. : X!            ( n xaddr -- )    XS: !L ;
  461. : X,            ( n -- )          XHERE X!  2 XDP +! ;
  462. : XC,           ( n -- )          XHERE XC! 1 XDP +! ;
  463.  
  464.  
  465. CODE PR-STATUS  ( N1 --- F1 )
  466.                 POP DX          \ PRINTER NUMBER
  467.                 MOV AH, # 2
  468.                 PUSH SI         PUSH BP
  469.                 INT 23          POP BP
  470.                 POP SI          MOV AL, AH
  471.                 MOV AH, # 0
  472.                 1PUSH           END-CODE
  473.  
  474. HEX
  475.                 \ 90 is printer not busy & printer selected.
  476. : ?PRINTER.READY ( --- F1 )     0 PR-STATUS ( 90 AND ) 90 = ;
  477.  
  478. DECIMAL
  479.  
  480. : (PRINT)       ( char -- )
  481.                 BEGIN   OUTPAUSE  ?PRINTER.READY
  482.                 UNTIL   5 BDOS DROP  #OUT INCR ;
  483.  
  484. DEFER CR
  485. DEFER PEMIT     ' (PRINT) IS PEMIT
  486.  
  487. : (EMIT)        ( char -- )
  488.                 PRINTING @ IF DUP PEMIT #OUT DECR THEN (CONSOLE) ;
  489.  
  490. : CRLF          ( -- )
  491.                 13 EMIT 10 EMIT #OUT OFF
  492.                 #LINE DUP @ 1+
  493.                 PRINTING @ 0=
  494.                 IF      24 MIN  THEN SWAP ! ;
  495.  
  496. : (TYPE)        ( addr len -- ) 0 ?DO  COUNT EMIT LOOP DROP ;
  497.  
  498. : FEMIT         ( C1 --- ) SP@ 1 TYPE DROP ;
  499.  
  500. : SPACE         ( -- )    BL EMIT ;
  501.  
  502. : SPACES        ( n -- )  0 MAX   0 ?DO   SPACE   LOOP   ;
  503.  
  504. : BACKSPACES    ( n -- )  0 ?DO   BS EMIT -2 #OUT +! LOOP  ;
  505.  
  506. : BEEP          ( -- )    BELL (EMIT) #OUT DECR ;
  507.  
  508. : BS-IN         ( n c -- 0 | n-1 )
  509.                 >R DUP
  510.                 IF      1-   BS
  511.                 ELSE    BELL
  512.                 THEN    EMIT #OUT DUP @ 2- 0 MAX SWAP ! R> ;
  513.  
  514. : (DEL-IN)      ( n c -- 0 | n-1 )
  515.                 >R DUP
  516.                 IF      1-  #OUT @ BS EMIT SPACE #OUT ! BS
  517.                 ELSE    BELL
  518.                 THEN    EMIT #OUT DUP @ 2- 0 MAX SWAP ! R> ;
  519.  
  520. DEFER DEL-IN    ' (DEL-IN) IS DEL-IN
  521.  
  522. : BACK-UP       ( n c -- 0 c )
  523.                 >R DUP BACKSPACES   DUP SPACES   BACKSPACES   0  R> ;
  524.  
  525. : RESET-IN      ( c -- ) FORTH   TRUE ABORT" Reset"  ;
  526.  
  527. DEFER RES-IN    ' RESET-IN IS RES-IN
  528.  
  529. : P-IN          ( c -- c ) PRINTING @ 0= PRINTING !  ;
  530.  
  531. : (ESC-IN)      ( C -- ) >R 2DUP + @ EMIT 1+ R> ;
  532.  
  533. DEFER ESC-IN    ' (ESC-IN) IS ESC-IN
  534.  
  535. : CR-IN         ( m a n c -- m a m C )
  536.                 >R SPAN !   OVER   BL EMIT R>  ;
  537.  
  538. : (CHAR)        ( a n char -- a n+1 CHAR )
  539.                 DUP >R 3DUP EMIT + C!   1+  R> ;
  540.  
  541. DEFER CHAR      ' (CHAR) IS CHAR
  542. DEFER ^CHAR     ' CHAR   IS ^CHAR
  543.  
  544. VARIABLE KEYTBL
  545.  
  546. ( XHERE ) HERE-X ]
  547.    ^CHAR   ^CHAR  ^CHAR  RES-IN ^CHAR  ^CHAR   ^CHAR  ^CHAR
  548.    DEL-IN  ^CHAR  ^CHAR  ^CHAR  ^CHAR  CR-IN   ^CHAR  ^CHAR
  549.    P-IN    ^CHAR  ^CHAR  ^CHAR  ^CHAR  BACK-UP ^CHAR  ^CHAR
  550.    BACK-UP ^CHAR  ^CHAR  ESC-IN ^CHAR  ^CHAR   ^CHAR  ^CHAR [
  551. CONSTANT NORM-KEYTBL
  552.  
  553. : EXPECT        ( adr len -- )
  554.                 DUP SPAN !   SWAP 0   ( len adr 0 )
  555.                 BEGIN   2 PICK OVER - ( len adr #so-far #left )
  556.                 WHILE   KEY DUP BL <
  557.                         IF      DUP 2* KEYTBL @ + XPERFORM DROP
  558.                         ELSE    DUP 127 =
  559.                                 IF   DEL-IN   ELSE   CHAR   THEN  DROP
  560.                         THEN
  561.                 REPEAT  3DROP ;
  562.  
  563. : TIB           ( -- adr )      'TIB @  ;
  564.  
  565. : QUERY         ( -- )          TIB 80 EXPECT  SPAN @ #TIB ! >IN OFF  ;
  566.  
  567.       VARIABLE DISK-ERROR
  568.    -2 CONSTANT LIMIT
  569.  
  570. LIMIT 10 - CONSTANT FIRST
  571. FIRST 10 - CONSTANT INIT-R0
  572.  
  573. DECIMAL
  574.  
  575. FORTH DEFINITIONS
  576.  
  577. : HEX           ( -- )   16 BASE !  ;
  578. : DECIMAL       ( -- )   10 BASE !  ;
  579. : OCTAL         ( -- )    8 BASE !  ;
  580.  
  581. DEFER DEFAULT
  582.  
  583. LABEL FAIL      SUB AX, AX      1PUSH           END-CODE
  584.  
  585. CODE DIGIT      ( char base -- n f )
  586.                 POP DX          POP AX          PUSH AX
  587.                 SUB AL, # ASCII 0
  588.                 JB FAIL         CMP AL, # 9
  589.               > IF
  590.                 CMP AL, # 17    JB FAIL         SUB AL, # 7
  591.               THEN
  592.                 CMP AL, DL
  593.                 JAE FAIL
  594.                 MOV DL, AL      POP AX          MOV AX, # TRUE
  595.                 2PUSH           END-CODE
  596.  
  597. : DOUBLE?       ( -- f ) DPL @ 1+   0<> ;
  598.  
  599. : CONVERT       ( +d1 adr1 -- +d2 adr2 )
  600.                 BEGIN   1+  DUP >R  C@  BASE @  DIGIT
  601.                 WHILE   SWAP  BASE @ UM*  DROP  ROT  BASE @ UM*  D+
  602.                         DOUBLE?  IF  DPL INCR THEN  R>
  603.                 REPEAT  DROP  R>  ;
  604.  
  605. : (NUMBER?)     ( adr -- d flag )
  606.                 0 0  ROT  DUP 1+  C@  ASCII -  =  DUP  >R  -  DPL -1!
  607.                 BEGIN   CONVERT  DUP C@  ASCII , ASCII / BETWEEN
  608.                 WHILE   DPL 0!
  609.                 REPEAT  -ROT  R> IF  DNEGATE  THEN   ROT C@ BL =  ;
  610.  
  611. : NUMBER?       ( adr -- d flag )
  612.                 FALSE  OVER COUNT BOUNDS
  613.                 ?DO     I C@ BASE @ DIGIT NIP
  614.                         IF      DROP TRUE LEAVE THEN
  615.                 LOOP
  616.                 IF  (NUMBER?)  ELSE  DROP  0 0 FALSE  THEN  ;
  617.  
  618. \ : (NUMBER)      ( adr -- d# ) NUMBER? NOT ?MISSING  ;
  619.  
  620. comment:
  621.  
  622.   A simple word to make Forth accept numbers prefixed with $ as Hex
  623. numbers.
  624.  
  625. comment;
  626.  
  627. CODE +1=$?      ( A1 --- A1 F1 )        \ is second char in a1 a $ ?
  628.                 POP BX
  629.                 PUSH BX
  630.                 MOV AL, 1 [BX]
  631.                 CMP AL, # ASCII $
  632.             0<> IF
  633.                         SUB AX, AX
  634.                 THEN
  635.                 1PUSH
  636.                 END-CODE
  637.  
  638. CODE +1='?      ( A1 --- A1 F1 )        \ is second char in a1 a $ ?
  639.                 POP BX
  640.                 PUSH BX
  641.                 MOV AL, 1 [BX]
  642.                 CMP AL, # ASCII '
  643.             0<> IF
  644.                         SUB AX, AX
  645.                 THEN
  646.                 1PUSH
  647.                 END-CODE
  648.  
  649. : (NUMBER)      ( A1 --- D1 )           \ Prefix with $ for auto HEX base.
  650.                 +1=$?                     \ $ is for HEX
  651.                 IF      DUP >R DUP COUNT 1- 0 MAX >R
  652.                         DUP 1+ SWAP R> CMOVE    \ Extract the $.
  653.                         DUP C@ 1- OVER C!       \ Shorten count by 1.
  654.                         BL OVER COUNT + C!      \ Append a blank to string.
  655.                         BASE @ >R       \ Save the base for later restoral.
  656.                         HEX NUMBER?     \ Try to convert the number in HEX
  657.                         R> BASE !       \ Restore the BASE.
  658.                         DUP 0=          \ If its not a number, restore the $.
  659.                         IF      R@ COUNT >R DUP 1+ R> CMOVE>
  660.                                 R@ C@ 1+ R@ C!
  661.                                 ASCII $ R@ 1+ C!
  662.                         THEN    R> DROP
  663.                 ELSE    +1='?                   \ recognize ' for ascii
  664.                         IF      2+ C@ 0 TRUE
  665.                                 DPL ON
  666.                         ELSE    NUMBER?
  667.                         THEN
  668.                 THEN    NOT ?MISSING ;
  669.  
  670. DEFER NUMBER
  671.  
  672. : HOLD          ( char -- )
  673.                 HLD DECR HLD @ C!   ;
  674.  
  675. : <#            ( -- )  PAD  HLD  !  ;
  676.  
  677. : #>            ( d# -- addr len )
  678.                 2DROP  HLD  @  PAD  OVER  -  ;
  679.  
  680. : SIGN          ( n1 -- )
  681.                 0< IF  ASCII -  HOLD  THEN  ;
  682.  
  683. : #             ( -- )
  684.                 BASE @ MU/MOD ROT 9 OVER <
  685.                 IF  7 + THEN ASCII 0  +  HOLD  ;
  686.  
  687. : #S            ( -- )
  688.                 BEGIN  #  2DUP  OR  0=  UNTIL  ;
  689.  
  690. : (U.)          ( u -- a l )    0    <# #S #>   ;
  691. : U.            ( u -- )        (U.)   TYPE SPACE   ;
  692. : U.R           ( u l -- )      >R   (U.)   R> OVER - SPACES   TYPE   ;
  693.  
  694. : (.)           ( n -- a l )    DUP ABS 0   <# #S   ROT SIGN   #>   ;
  695. : .             ( n -- )        (.)   TYPE SPACE   ;
  696. : .R            ( n l -- )      >R   (.)   R> OVER - SPACES   TYPE   ;
  697.  
  698. : (UD.)         ( ud -- a l )   <# #S #>   ;
  699. : UD.           ( ud -- )       (UD.)   TYPE SPACE   ;
  700. : UD.R          ( ud l -- )     >R   (UD.)   R> OVER - SPACES   TYPE  ;
  701.  
  702. : (D.)          ( d -- a l )    TUCK DABS   <# #S   ROT SIGN  #>   ;
  703. : D.            ( d -- )        (D.)   TYPE SPACE   ;
  704. : D.R           ( d l -- )      >R   (D.)   R> OVER - SPACES   TYPE   ;
  705.  
  706. LABEL DONE
  707.                 PUSH CX         NEXT            END-CODE
  708.  
  709. CODE  SKIP      ( addr len char -- addr' len' )
  710.                 POP AX          POP CX
  711.                 JCXZ DONE
  712.                 POP DI          PUSH ES         MOV ES, SSEG
  713.                 REPZ            SCASB           POP ES
  714.             0<> IF
  715.                 INC CX          DEC DI
  716.             THEN
  717.                 PUSH DI         PUSH CX
  718.                 NEXT            END-CODE
  719.  
  720. CODE  SCAN      ( addr len char -- addr' len' )
  721.                 POP AX          POP CX
  722.                 JCXZ DONE
  723.                 POP DI          PUSH ES
  724.                 MOV ES, SSEG    MOV BX, CX
  725.                 REPNZ           SCASB           POP ES
  726.              0= IF
  727.                 INC CX          DEC DI
  728.              THEN
  729.                 PUSH DI         PUSH CX
  730.                 NEXT            END-CODE
  731.  
  732. CODE /STRING    ( addr len n -- addr' len' )
  733.                 POP AX          POP BX
  734.                 PUSH BX         CMP BX, AX
  735.              <= IF
  736.                 XCHG BX, AX     \ AX = SMALLER OF AX BX
  737.              THEN
  738.                 POP BX          POP DX
  739.                 ADD DX, AX      PUSH DX
  740.                 SUB BX, AX      PUSH BX
  741.                 NEXT            END-CODE
  742.  
  743. CODE PARSE-WRD  ( C1 A1 N1 --- A2 N2 )
  744.                 POP CX          POP DX          POP AX          DEC RP
  745.                 DEC RP          MOV 0 [RP], AX  PUSH CX         MOV AX, >IN
  746.                 CMP CX, AX
  747.              <= IF
  748.                 MOV AX, CX      \ AX = SMALLER OF AX CX
  749.              THEN
  750.                 ADD DX, AX      PUSH DX         SUB CX, AX      MOV AX, 0 [RP]
  751.           CX<>0 IF
  752.                 POP DI          MOV DX, DS      PUSH ES         MOV ES, DX
  753.                 REPZ            SCASB           POP ES
  754.                 0<> IF
  755.                         INC CX  DEC DI
  756.                     THEN
  757.                 PUSH DI
  758.            THEN
  759.                 POP AX          PUSH AX         PUSH AX         MOV AX, 0 [RP]
  760.                 INC RP          INC RP
  761.           CX<>0 IF
  762.                 POP DI          MOV DX, DS      PUSH ES
  763.                 MOV ES, DX      MOV BX, CX
  764.                 REPNZ           SCASB           POP ES
  765.                 0= IF
  766.                         INC CX  DEC DI
  767.                    THEN
  768.                 PUSH DI
  769.            THEN
  770.                 POP AX          POP BX          SUB AX, BX      POP DX
  771.                 XCHG DX, BX     PUSH DX         PUSH AX         MOV AX, CX
  772.                 OR AX, AX
  773.             0<> IF
  774.                 ADD AX, # TRUE
  775.             THEN
  776.                 SUB BX, AX      MOV >IN BX      NEXT            END-CODE
  777.  
  778. : (SOURCE)      ( -- addr len ) TIB #TIB @ ;
  779.  
  780. DEFER SOURCE
  781.  
  782. : PARSE         ( char -- addr len )
  783.                 >R   SOURCE >IN @ /STRING   OVER SWAP R> SCAN
  784.                 >R OVER -  DUP R>  0<> -  >IN +!  ;
  785.  
  786. DEFER 'WORD     ( -- adr )     ' HERE IS 'WORD
  787.  
  788. CODE SUFIX.BL   ( A1 -- A1 )
  789.                 POP BX          PUSH BX
  790.                 SUB AX, AX      MOV AL, 0 [BX]
  791.                 ADD BX, AX      MOV 1 [BX], # 32
  792.                 NEXT            END-CODE
  793.  
  794. : WORD          ( char -- addr )
  795.                 SOURCE PARSE-WRD 'WORD PLACE 'WORD SUFIX.BL ;
  796.  
  797.  
  798.