home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / forth / compiler / fpc / source / kernel4.seq < prev    next >
Text File  |  1991-02-05  |  22KB  |  568 lines

  1. \ KERNEL4.SEQ   Last part of the kernel file, finishes up the compile.
  2.  
  3. \ Link this file into the FILELIST chain.
  4.  
  5. FILES DEFINITIONS
  6.  
  7. VARIABLE KERNEL4.SEQ
  8.  
  9. FORTH DEFINITIONS   META IN-META
  10.  
  11. VARIABLE #USER
  12. \ A variable that holds the count of how many user variables are allocated.
  13.  
  14. VOCABULARY USER   USER DEFINITIONS
  15. \ Vocabulary that holds task versions of defining words.
  16.  
  17. : ALLOT         ( n -- )
  18. \ Allocate space in the user area for a multi-tasking word.
  19.                 #USER +!   ;
  20.  
  21. ' CREATE        \ avoid recursion: leave address for ,-X in CREATE
  22.  
  23. : CREATE        ( -- )
  24. \ Define a word that returns the address of the next available user
  25. \ memory location.
  26.                 [ ,-X ]         \ compile addr of CREATE
  27.                 #USER @ ,
  28.                 ;USES  DOUSER-VARIABLE ,-X
  29.  
  30. : VARIABLE      ( -- )
  31. \ Define a task type variable. Similar to the old FIG version word USER.
  32.                 CREATE   2 ALLOT   ;
  33.  
  34. : DEFER         ( -- )
  35. \ Defines an execution vector that is local to a task.
  36.                 VARIABLE   ;USES   DOUSER-DEFER  ,-X
  37.  
  38. FORTH DEFINITIONS   META IN-META
  39.  
  40. : >IS           ( cfa -- data-address )
  41. \ smart word converts from CFA to data field. Knows about user variables.
  42.                 DUP 1+ @ OVER >BODY +
  43.                 DUP [  [ASSEMBLER] DOUSER-VARIABLE META ] LITERAL = SWAP
  44.                 DUP [  [ASSEMBLER] DOUSER-DEFER    META ] LITERAL = SWAP
  45.                 DROP   OR IF   >BODY @ UP @ +   ELSE    >BODY   THEN   ;
  46.  
  47. : (IS)          ( cfa --- )
  48. \ This word is compiled by IS. Sets the following DEFERred word to the
  49. \ address on the parameter stack.
  50.                 2R@ @L >IS !   R> 2+ >R   ;
  51.  
  52. : IS            ( cfa --- )
  53. \ Depending on STATE, either sets the following DEFERred word immediatly
  54. \ or compiles (IS) to set it later.
  55.                 STATE @
  56.                 IF      COMPILE (IS)
  57.                 ELSE    ' >IS !
  58.                 THEN    ;       IMMEDIATE
  59.  
  60. : SELECT        ( N1 --- )
  61. \ Select drive n1 as the current disk drive. 0=A, 1=B etc.
  62.                 14 bdos drop
  63.                 seqhandle >hndle @ -2 =
  64.                 if      -1 seqhandle >hndle !
  65.                 then    ;
  66.  
  67. : A:            ( --- )         0 SELECT ;
  68. : B:            ( --- )         1 SELECT ;
  69. : C:            ( --- )         2 SELECT ;
  70. : D:            ( --- )         3 SELECT ;
  71. : E:            ( --- )         4 SELECT ;
  72. : F:            ( --- )         5 SELECT ;
  73. \ Select drive A:, B:, C:, D:, E: or F: as the default drive.
  74.  
  75. : QUIT          ( -- )
  76. \ The main loop in Forth. Gets input from the terminal and Interprets it.
  77. \ Responds with OK if healthy and repeats the process.
  78.                 SP0 @ 'TIB !    [COMPILE] [
  79.                 BEGIN   BEGIN RP0 @ RP! STATUS QUERY  RUN
  80.                               STATE @ NOT UNTIL ."  ok" AGAIN  ;
  81.  
  82. DEFER BOOT
  83. \ A defered word that performs initialization before executing QUIT.
  84.  
  85. DEFER INITSTUFF   ' SEQINIT IS INITSTUFF
  86. \ A defered word chain that performs various initialization operations
  87. \ at Forth initial cold start time.
  88.  
  89. DEFER SEGSET      ' SETYSEG IS SEGSET
  90. \ A DEFERed word that contain the current function used to set up the
  91. \ segment registers at cold start time. Typically contains SETYSEG.
  92.  
  93. : WARMSTRT      ( --- )
  94. \ The default function to be performed on a WARM start.
  95.                 FORTH
  96.                 TRUE ABORT" Warm Start" ;
  97.  
  98. DEFER WARMFUNC  ' WARMSTRT IS WARMFUNC
  99. \ A DEFERed word that is invoked when a warm start occurs.
  100. \ This function is also called whenever the CONTROL BREAK key is pressed.
  101.  
  102. TRUE VALUE 1STCOLD
  103. \ A flag to tell if COLD has been called yet.
  104.  
  105. : WARM          ( -- )
  106. \ The WARM entry point for Forth, just calles the DEFERed word WARMFUNC.
  107. \ A WARM start is invoked whenever the CONTROL BREAK key is pressed.
  108.                 [ LABEL WARMBODY ]
  109.                 WARMFUNC ;
  110.  
  111. : COLD          ( -- )
  112. \ The high level cold start code. For ordinary forth, BOOT should
  113. \ initialize and pass control to QUIT.
  114.                 [ LABEL COLDBODY ]
  115.                 1STCOLD                 \ Only do this stuff once each load
  116.                 IF      SEGSET
  117.                         VMODE.SET
  118.                         SETCRITICAL
  119.                         INITSTUFF
  120.                 THEN    %OFF> 1STCOLD
  121.                 BOOT QUIT   ;
  122.  
  123. : START         ( -- )
  124. \ Minimal default initialization. This word is stuffed into BOOT
  125. \ when compiling the KERNEL.COM file.
  126.                 SP0 @ 'TIB !
  127.                 >IN OFF
  128.                 SPAN OFF
  129.                 #TIB OFF
  130.                 LOADING OFF
  131.                 DEFAULT INTERPRET ;
  132.  
  133. VARIABLE BIOSBKSAVE     0 ,-T
  134. \ A double variable that holds the BIOS Control Break vector so it
  135. \ can be restored on exit.
  136.  
  137. VARIABLE DIV0SAVE       0 ,-T
  138. \ A double variable that holds the divide by zero interupt vector
  139. \ so it can be restored on exit from Forth.
  140.  
  141. VARIABLE CTRLBKSAVE
  142. \ A variable that holds the state of the low memory Control Break
  143. \ flag so it can be restored on exit from Forth.
  144.  
  145. CODE RESTORE_VECTORS    ( --- )
  146. \ Restores the saved vectors to their saved values.  This word is called
  147. \ just prior to returning to DOS.
  148.                 MOV AX, CS              MOV DS, AX
  149.                 MOV DX, CS: BIOSBKSAVE
  150.                 MOV DS, CS: BIOSBKSAVE 2+
  151.                 MOV AX, # $251B
  152.                 INT $21
  153.                 MOV AX, CS              MOV DS, AX
  154.                 MOV DX, CS: DIV0SAVE
  155.                 MOV DS, CS: DIV0SAVE 2+
  156.                 MOV AX, # $2500
  157.                 INT $21
  158.                 MOV AX, CS              MOV DS, AX
  159.                 MOV DX, CTRLBKSAVE
  160.                 MOV AX, # $3301         \ Control BREAK flag status
  161.                 INT $21
  162.                 NEXT                    END-CODE
  163.  
  164. : DIV0STRT      ( --- )
  165. \ The default function to perform when a DIVIDE by 0 trap occurs.
  166.                 TRUE ABORT" Divide OVERFLOW error" ;
  167.  
  168. DEFER DIV0FUNC  ' DIV0STRT IS DIV0FUNC
  169. \ F-PC traps divide by 0 errors, and calls this defered word when
  170. \ such an error is detected.
  171.  
  172. DEFER BYEFUNC   ' NOOP IS BYEFUNC
  173. \ A defered word which normally contains NOOP, provided so you
  174. \ can specify a function to be performed before leaving back to DOS.
  175.  
  176. : BYE           ( -- )
  177. \ Returns control to DOS. Performs the defered word BYEFUNC before
  178. \ actually leaving.
  179.                 RESTORE_VECTORS
  180.                 BYEFUNC
  181.                 ."  Leaving.." 0 0 BDOS  ;
  182.  
  183. : DIVIDE0       ( STATUS_reg, CS, IP, AX, BX, CX, DX, SI, BP --- )
  184. \ The actual entry point from the divide by 0 trap, this word just
  185. \ calls the deferd word DIV0FUNC.
  186.                 [ LABEL DIV0BODY ]
  187.                 DIV0FUNC BYE ;
  188.  
  189. LABEL DIV0BK
  190. \ Handle the Divide by 0 interupt processing. You cannot reliably return
  191. \ from a divide by zero interupt.
  192.                 STI
  193.                 PUSH AX
  194.                 PUSH BX
  195.                 PUSH CX
  196.                 PUSH DX
  197.                 PUSH SI
  198.                 PUSH DI
  199.                 PUSH BP
  200.                 MOV AX, # DIV0BODY 5 -
  201.                 JMP AX
  202.                 END-CODE
  203.  
  204. TRUE VALUE RESTNEXT
  205. \ A flag to determine if we want the next code restored.
  206.  
  207. LABEL SETBRK
  208. \ A subroutine not accessible directly from Forth that sets the
  209. \ various interupt vectors used by Forth.
  210.                 PUSH ES
  211.                 MOV AX, CS
  212.                 MOV DS, AX
  213.                 CMP ' RESTNEXT >BODY # 0 WORD   \ If RESTNEXT is NOT = 0
  214.             0<> IF      MOV AX, # $AD26      \ Value to restore in >NEXT
  215.                         MOV >NEXT AX         \ Restore it
  216.                         MOV AX, # $E0FF      \ Value to restore in >NEXT + 2
  217.                         MOV >NEXT 2+ AX      \ Restore it
  218.                 THEN
  219.                 MOV DX, # BIOSBK
  220.                 MOV AX, # $251B         \ BIOS Break
  221.                 INT $21
  222.                 MOV DX, # DOSBK
  223.                 MOV AX, # $2523         \ DOS Break
  224.                 INT $21
  225.                 MOV DX, # 0
  226.                 MOV AX, # $3301         \ DISABLE DOS Break
  227.                 INT $21
  228.                 MOV DX, # DIV0BK
  229.                 MOV AX, # $2500         \ BIOS Break
  230.                 INT $21
  231.                 POP ES
  232.                 RET             END-CODE
  233.  
  234. LABEL SAVEVECTORS ( --- )
  235. \ A subroutine not accessible directly from Forth that saves
  236. \ the Divide by 0 & Cntrl Brk interrupt vectors.
  237.                 PUSH ES
  238.                 MOV AX, # $351B          \ Get the interupt vector for
  239.                 INT $21                  \ BIOS control break vector
  240.                 MOV BIOSBKSAVE BX
  241.                 MOV BIOSBKSAVE 2+ ES    \ Save old vector
  242.                 MOV AX, # $3500          \ Get the interupt vector for
  243.                 INT $21                  \ DIVIDE by 0
  244.                 MOV DIV0SAVE BX
  245.                 MOV DIV0SAVE 2+ ES      \ Save old vector
  246.                 POP ES
  247.                 MOV AX, # $3300         \ Control BREAK flag status
  248.                 INT $21
  249.                 SUB DH, DH
  250.                 MOV CTRLBKSAVE DX       \ Save it away for later restoral
  251.                 RET             END-CODE
  252.  
  253. CODE SET_VECTORS ( --- )
  254. \ Set the CONTROL BREAK and DIVIDE by 0 traps to point to the
  255. \ Forth provided functions, so we can handle them smoothly.
  256.                 CALL SETBRK
  257.                 NEXT            END-CODE
  258.  
  259. CODE @REL>ABS   ( a1 --- a2 )
  260. \ Convert JMP address in a1+1 to an absolute memory address
  261.                 POP BX
  262.                 ADD BX, 1 [BX]
  263.                 ADD BX, # 3
  264.                 PUSH BX
  265.                 NEXT            END-CODE
  266.  
  267. [FORTH] ASSEMBLER
  268.  
  269. LABEL WORIG
  270. \ An inaccessible routine. You get here from the WARM entry at offset
  271. \ ORIGIN + 4, and get sent to the WARM colon definition.
  272. HERE ORIGIN 6 + - ORIGIN 4 + !-T  ( WARM ENTRY )
  273.         MOV AX, # WARMBODY 5 -
  274.         JMP AX
  275.         END-CODE
  276.  
  277. LABEL CORIG
  278. \ An inaccessible routine. You get here from the COLD entry at offset
  279. \ ORIGIN + 0, and get sent to the COLD colon definition.
  280. \ This routine expands out the compressed Forth system to its various
  281. \ segments.
  282. HERE ORIGIN 3 + - ORIGIN 1+ !-T  ( COLD ENTRY )
  283.         MOV AX, CS                      \ move CS to AX
  284.         MOV DS, AX
  285.         MOV SS, AX
  286.         MOV BX, YSTART                  \ Read YSTART
  287.         OR BX, BX 0<>                   \ If not reset, then move stuff
  288.      IF
  289.         ADD AX, ' #CODESEGS >BODY       \ Add CODE segments and
  290.         ADD AX, ' #OVSEGS   >BODY       \ add OVERLAY segments and
  291.         ADD AX, ' #LISTSEGS >BODY       \ LIST segments to get to head space.
  292.         MOV ES, AX                      \ move head seg to ES
  293.         MOV CX, YDP
  294.         MOV DI, # 0                     \ Clear DI
  295.         MOV SI, YSTART                  \ MOV YSTART to AX
  296.         OR CX, CX 0<>                   \ if YDP was not zero (0)
  297.         IF      CLD
  298.                 REPZ
  299.                 MOVSB                   \ move HEADS to head space
  300.                 CLD
  301.         THEN
  302.         MOV YSEG ES                     \ set YSEG to ES
  303.      THEN
  304.         MOV BX, XMOVED                  \ Has LIST been moved?
  305.         OR BX, BX 0=                    \ If not reset, then move stuff
  306.      IF
  307.         MOV AX, DS                      \ move DS to AX
  308.         ADD AX, ' #CODESEGS >BODY       \ Add CODE segments and
  309.         ADD AX, ' #OVSEGS   >BODY       \ add OVERLAY segments to get LIST
  310.         MOV ES, AX                      \ move head seg to ES
  311.         MOV CX, XSEGLEN
  312.         SHL CX, # 1                     \ MULTIPLY BY 16 DECIMAL
  313.         SHL CX, # 1
  314.         SHL CX, # 1
  315.         SHL CX, # 1
  316.         MOV DI, # 0                     \ Clear DI
  317.         MOV SI, DPSTART                 \ MOV source offset to SI
  318.         OR CX, CX 0<>                   \ if DPSTART was not zero (0)
  319.         IF      CLD             \ Forward move, NOT backwards this time.
  320.                 REPZ
  321.                 MOVSB                   \ move LISTS to LIST space
  322.                 CLD
  323.         THEN
  324.         MOV XSEG ES                     \ set XSEG to ES
  325.      THEN
  326.  
  327. \ The following few instructions patch two ADD instructions in KERNEL1, so
  328. \ we can do an ADD IMMEDIATE rather than an ADD MEMORY in NEST and DODOES.
  329.         MOV ES, XSEG                    \ Initialize ES in case we haven't??
  330.         MOV NESTPATCH 1+ ES             \ Patch NEST   ADD instruction
  331.         MOV DOESPATCH 1+ ES             \ Patch DODOES ADD instruction
  332.  
  333.         CALL SAVEVECTORS                \ Save existing vectors
  334.         MOV ' RESTNEXT >BODY # TRUE WORD \ We want NEXT restored
  335.         CALL SETBRK                     \ Install Break vectors &
  336.                                         \ restore NEXT
  337.         MOV AX, ' #CODESEGS >BODY
  338.         SUB AX, # 1                     \ One less than max
  339.         SHL AX, # 1
  340.         SHL AX, # 1
  341.         SHL AX, # 1
  342.         SHL AX, # 1
  343.         SUB AX, ' #OVBYTES  >BODY       \ reduce by OVERLAY bytes
  344.         MOV ' LIMIT 3 + AX              \ LIMIT
  345.         SUB AX, # 10
  346.         MOV ' FIRST 3 + AX              \ FIRST = LIMIT - 10h
  347.         SUB AX, # 10
  348.         MOV RP, AX                      \ RP = FIRST - 10h
  349.         MOV BX, # RP0
  350.         ADD BX, UP
  351.         MOV 0 [BX], RP                  \ RP0 = RP
  352.         SUB AX, # 250
  353.         MOV 'TIB AX                     \ TIB = RP - 250 DECIMAL
  354.         MOV BX, # SP0
  355.         ADD BX, UP
  356.         MOV 0 [BX], AX                  \ SP0 = TIB
  357.         MOV SP, AX                      \ SP = TIB
  358.         MOV ' 1STCOLD >BODY # TRUE WORD \ Make COLD to its initialization
  359.         MOV AX, COLDBODY 2-
  360.         ADD AX, XSEG
  361.         MOV ES, AX
  362.         MOV IP, # 0
  363.         NEXT
  364.         END-CODE
  365.   IN-META
  366.  
  367. \ Here we initialize the USER table with its default values.
  368. HERE UP !-T     ( SET UP USER AREA )
  369.        0 ,      ( TOS )
  370.        0 ,      ( ENTRY )
  371.        0 ,      ( LINK )
  372.        0 ,      ( ES0 )
  373. INIT-R0 256 - , ( SP0 )
  374.  INIT-R0 ,      ( RP0 )
  375.        0 ,      ( DP )          ( Must be patched later )
  376.        0 ,      ( OFFSET )
  377.       10 ,      ( BASE )
  378.        0 ,      ( HLD )
  379.    FALSE ,      ( PRINTING )
  380. ' (EMIT) ,      ( EMIT )
  381. ' (KEY?) ,      ( KEY? )
  382. ' (KEY)  ,      ( KEY  )
  383. ' (TYPE) ,      ( TYPE )
  384. ' (TYPEL) ,     ( TYPEL )
  385.  
  386. 0 , 0 , 0 , 0 , 0 ,             \ room for 10 additional USER variables
  387. 0 , 0 , 0 , 0 , 0 ,
  388.  
  389. : DEPTH         ( -- n )
  390. \ Returns the number of items on the parameter stack.
  391.                 SP@ SP0 @ SWAP - 2/   ;
  392.  
  393. VARIABLE MAX.S
  394. \ A variable that holds the maximum depth to be displayed of the
  395. \ data stack with .S following.
  396.  
  397. : .S            ( -- )
  398. \ Displays the contents of the parameter stack non destructively.
  399. \ Very useful when debugging.
  400.                 DEPTH 0< ABORT" Stack UNDERFLOW !! "
  401.                 DEPTH ?DUP MAX.S @ 1 < IF 4 MAX.S ! THEN
  402.                 IF      DUP ."  [" 1 .R ." ]" 0 SWAP 1- MAX.S @ 1- MIN
  403.                         DO I PICK 7 U.R SPACE -1 +LOOP
  404.                 ELSE    ."  Stack Empty. "  THEN ;
  405.  
  406. : %.ID          ( nfa -- )
  407. \ Display the variable length name whose name field address is on the
  408. \ stack. If it is shorter than its count, it is padded with underscores.
  409. \ Only valid Ascii is typed.
  410.                 DUP 1+ DUP YC@ ROT YC@ 31 AND 0
  411.                ?DO      DUP 127 AND FEMIT 128 AND
  412.                         IF   ASCII _ 128 OR   ELSE  1+ DUP YC@  THEN
  413.                 LOOP    2DROP SPACE ;
  414.  
  415. DEFER .ID       ' %.ID IS .ID   \ defer to allow for COLORIZER
  416. \ A defered word. Display the variable length name whose name field
  417. \ address is on the stack. If it is shorter than its count, it is
  418. \ padded with underscores. Only valid Ascii is typed.
  419.  
  420. : DUMP          ( addr len -- )
  421. \ A primitive little dump routine to help you debug after you have
  422. \ changed the system source and nothing works any more.
  423.               0 DO   CR DUP 6 .R SPACE  16 0 DO   DUP C@ 3 .R 1+   LOOP
  424.             16 +LOOP   DROP   ;
  425.  
  426. : RECURSE       ( -- )
  427. \ Makes the definition this word is used in call itself at the
  428. \ point where it is used. ie. "RECUSION"
  429.                 LAST @ NAME> X,  ;  IMMEDIATE
  430.  
  431. : H.            ( N1 --- )
  432. \ Display the unsigned number in hex, with trailing blank. Does not
  433. \ change the number base.
  434.                 BASE @ >R HEX U. R> BASE ! ;
  435.  
  436. VARIABLE LMARGIN    0 LMARGIN !-T
  437. \ The left margin setting used by ?LINE, ?CR.
  438.  
  439. VARIABLE RMARGIN   70 RMARGIN !-T
  440. \ Controls the right margin, used by ?LINE, ?CR.
  441.  
  442. VARIABLE TABSIZE    8 TABSIZE !-T
  443. \ Controls the TAB increment for TAB. Default is 8.
  444.  
  445. : ?LINE         ( n -- )
  446. \ Break the line at the cursor if there are less than n1 characters
  447. \ till RMARGIN is encountered.
  448.                 #OUT @ +  RMARGIN @ > IF CR LMARGIN @ SPACES THEN ;
  449.  
  450. : ?CR           ( -- )
  451. \ Break the line at the cursor, if we have reached the right margin
  452. \ as specified by RMARGIN.
  453.                 0 ?LINE  ;
  454.  
  455. : TAB           ( --- )
  456. \ Print spaces to get to the next TAB increment as specified by
  457. \ TABSIZE.
  458.                 #OUT @ TABSIZE @ MOD TABSIZE @ SWAP - SPACES ;
  459.  
  460. : \             ( --- )
  461. \ Comment till the end of this line.
  462.                 #TIB @ >IN ! ; IMMEDIATE
  463.  
  464. CODE SET-CURSOR ( n1 --- )
  465. \ Set the cursor shape to value n1
  466.                 POP CX
  467.                 MOV AH, # 1
  468.                 PUSH SI         PUSH BP
  469.                 INT $10
  470.                 POP BP          POP SI
  471.                 NEXT C;
  472.  
  473. : GET-CURSOR    ( --- n1 )      \ return n1 the shape of the cursor.
  474.                 0 $460 @L ;
  475.  
  476. \ : SS            ( | <name> )
  477. \                 ' >BODY @ +XSEG 0 ;
  478.  
  479. \ : NN            ( SEG OFF --- SEG OFF+2 )
  480. \                 2DUP @L DUP H. >NAME .ID 2+ ;
  481.  
  482. \ The :RESOLVES word resolves forward references in LIST space, while
  483. \ the  RESOLVES word resolves forward reverences in CODE space.
  484. \ It does not matter whether the word you are resolving is a CODE word
  485. \ or a COLON definitions, what matters is where it is being resolved which
  486. \ is typically in LIST space not CODE space.  All this to say you should
  487. \ normally use :RESOLVES rather than RESOLVES to resolve forward reverences.
  488.  
  489. \ Resolve some forward references.
  490.  
  491. ' (.")                            :RESOLVES <(.")>
  492. ' (")                             :RESOLVES <(")>
  493. ' (;CODE)                         :RESOLVES <(;CODE)>
  494. ' (;USES)                         :RESOLVES <(;USES)>
  495. ' (IS)                            :RESOLVES <(IS)>
  496. ' (ABORT")                        :RESOLVES <(ABORT")>
  497.  [ASSEMBLER] >NEXT    META         RESOLVES <VARIABLE>
  498.  [ASSEMBLER] DOUSER-DEFER META     RESOLVES <USER-DEFER>
  499.  [ASSEMBLER] DOUSER-VARIABLE META  RESOLVES <USER-VARIABLE>
  500.  
  501. ' DEFINITIONS                     :RESOLVES DEFINITIONS
  502. ' [                               :RESOLVES [
  503. ' ?MISSING                        :RESOLVES ?MISSING
  504. ' QUIT                            :RESOLVES QUIT
  505. ' .ID                             :RESOLVES .ID
  506. ' @REL>ABS                        :RESOLVES @REL>ABS
  507. ' >IS                             :RESOLVES >IS
  508. ' >BODY                           :RESOLVES >BODY
  509. ' 0POINTERS                       :RESOLVES 0POINTERS
  510.  
  511. \ Fill in some deferred words.
  512. ' CRLF          IS CR
  513. ' CR            IS STATUS
  514. ' START         IS BOOT
  515. ' (PRINT)       IS PEMIT
  516. ' (CONSOLE)     IS CONSOLE
  517.  
  518. \ Set CONTEXT and CURRENT to FORTH.
  519. ' FORTH >BODY-T CURRENT !-T
  520. ' FORTH >BODY-T CONTEXT !-T
  521.  
  522. HERE-T  DP UP @-T + !-T               \ INIT USER DP
  523. #USER-T @ #USER !-T                   \ INIT USER VAR COUNT
  524. TRUE  CAPS !-T                        \ SET TO IGNORE CASE
  525. TRUE WARNING !-T                      \ SET TO ISSUE WARNINGS
  526. 31 WIDTH !-T                          \ 31 CHARACTER NAMES
  527. VOC-LINK-T @ VOC-LINK !-T             \ INIT VOC-LINK
  528. PHEAD-T @ PHEAD !-T                   \ INIT PHEAD
  529.  
  530. \ Now display the statistics for this compile.
  531.  
  532. CR
  533. CR .( Unresolved references: )          CR   .UNRESOLVED ?NEWPAGE
  534. CR .(     Statistics: )
  535. CR .( Last  Host Address:        )      [FORTH] HERE U.
  536. CR .( First Target Code Address: )      META 256 THERE U.
  537. CR .( Last  Target Code Address: )      META HERE-T THERE U.
  538.                                         META 256 THERE          \ start addr
  539.                                         SVXSEG     DPSTART !-T
  540.                                         HERE-X DROP 1+
  541.                                         0 XS: DROP - XSEGLEN !-T
  542. CR .( CODE space used:           )      HERE-T U.
  543. CR .( LIST space used:           )      HERE-X SWAP 0 XS: DROP - 16 * + U.
  544. CR .( HEAD space used:           )      HERE-Y U.
  545.                                         HERE-X DROP 1+ 0 XS: DROP -
  546.                                         DUP 16 * ALLOT-T DROP
  547.                                         0 XDP !-T
  548.                                       SVYSEG DUP
  549.                                         YSTART !-T
  550.                                         0 XMOVED !-T
  551.                                       HERE-Y +
  552.                                         HERE-Y YDP !-T
  553.                                         THERE ONLY FORTH ALSO META ALSO
  554.                                       CODESEGS 16 * OVER -
  555. CR .( Free Target Program room:  )      U.
  556.                                         SP@ HERE -
  557. CR .( Free Symbol Table bytes:   )      U.
  558.  
  559. .COMPSTAT
  560.  
  561. ( A1 N1 --- )   ZSAVE KERNEL.COM        \ Save the KERNEL.COM file.
  562.  
  563. ONLY FORTH ALSO DEFINITIONS
  564.  
  565. CR .( Now type EXTEND <enter> at the DOS prompt.)
  566. CR
  567.  
  568.