fig-FORTH
      
                             INSTALLATION MANUAL




                                   GLOSSARY

                                    MODEL

                                    EDITOR






                                  RELEASE 1

                            WITH COMPILER SECURITY

                                     AND

                            VARIABLE LENGTH NAMES





                                      BY

                             WILLIAM F. RAGSDALE




                                                         November 1980



     Provided through the courtesy of the FORTH INTEREST GROUP, PO Box 
     1105, San Carlos, CA 94070

     Further distribution of this public domain publication must include 
     this notice.














































































                        fig-FORTH INSTALLATION MANUAL


                              1.0 INTRODUCTION

                              2.0 DISTRIBUTION

                              3.0 MODEL ORGANIZATION

                              4.0 INSTALLATION

                              5.0 MEMORY MAP

                              6.0 DOCUMENTATION SUMMARY



                              1.0  INTRODUCTION

     The fig-FORTH implementation project occurred because a key group of 
     Forth fanciers wished to make this valuable tool available on a 
     personal computing level.  In June of 1978, we gathered a team of 
     nine systems level programmers, each with a particular target 
     computer.  The charter of the group was to translate a common model 
     of Forth into assembly language listings for each computer.  It was 
     agreed that the group's work would be distributed in the public 
     domain by FIG.  This publication series is the conclusion of the 
     work.

      
                              2.0  DISTRIBUTION

     All publications of the Forth Interest Group are public domain.  
     They may be further reproduced and distributed by inclusion of this 
     credit notice:

                    This publication has been made available 
                    by the Forth Interest Group, 
                    P. O. box 1105,  San Carlos, CA 94070

     We intend that our primary recipients of the Implementation Project 
     be computer users groups, libraries, and commercial vendors.  We 
     expect that each will further customize for particular computers and 
     redistribute.  No restrictions are placed on cost, but we expect 
     faithfulness to the model.  FIG does not intend to distribute 
     machine readable versions, as that entails customization, revision, 
     and customer support better reserved for commercial vendors.  Of 
     course, another broad group of recipients of the work is the 
     community of personal computer users.  We hope that our publications 
     will aid in the use of Forth and increase the user expectation of 
     the performance of high level computer languages.





                                     1









                           3.0  MODEL ORGANIZATION

     The fig-FORTH model deviates a bit from the usual loading method of 
     Forth.  Existing systems load about 2k bytes in object form and then 
     self-compile the resident system (6 to 8 k bytes).  This technique 
     allows customization within the high level portion, but is 
     impractical for new implementors.

     Our model has 4 to 5 k bytes written as assembler listings.  The 
     remainder may be compiled typing in the Forth high-level source, by 
     more assembly source, or by disc compilation.  This method enhances 
     transportability, although the larger portion in assembly code 
     entails more effort.  About 8k bytes of memory is used plus 2 to 8k 
     for workspace.

      
                             3.1  MODEL OVER-VIEW

     The model consists of 7 distinct areas.  They occur sequentially 
     from low memory to high.

                         Boot-up parameters 
                         Machine code definitions 
                         High level utility definitions 
                         Installation dependent code 
                         High level definitions 
                         System tools (optional) 
                         RAM memory workspace

      
                              3.2  MODEL DETAILS

     Boot-up Parameters

     This area consists of 34 bytes containing a jump to the cold start, 
     jump to the warm re-start and initial values for user variables and 
     registers.  These values are altered as you make permanent 
     extensions to your installation.
      

     Machine Code Definitions

     This area consists of about 600 to 800 bytes of machine executable 
     code in the form of Forth word definitions.  Its purpose is to 
     convert your computer into a standard Forth stack computer.  Above 
     this code, the balance of Forth contains a pseudo-code compiled of 
     "execution-addresses" which are sequences of the machine address of 
     the "code-fields" of other Forth definitions.  All execution 
     ultimately refers to the machine code definitions.







                                     2








     High-level Utility Definitions

     These are colon-definitions, user variables, constants, and 
     variables that allow you to control the "Forth stack computer".  
     They comprise the bulk of the system, enabling you to execute and 
     compile from the terminal. If disc storage (or a RAM simulation of 
     disc) is available, you may also execute and compile from this 
     facility.  Changes in the high-level area are infrequent.  They may 
     be made thru the assembler source listings.


     Installation Dependent Code

     This area is the only portion that need change between different 
     installations of the same computer cpu.  There are four code 
     fragments:

          (KEY)  Push the next ascii value (7 bits) from the terminal 
          keystroke to the computation stack and execute NEXT.  High 9 
          bits are zero.  Do not echo this character, especially a 
          control character.

          (EMIT)  Pop the computation stack (16 bit value).  Display the 
          low 7 bits on the terminal device, then execute NEXT.  Control 
          characters have their natural functions.

          (?TERMINAL)  For terminals with a break key, wait till released 
          and push to the computation stack 0001 if it was found 
          depressed; otherwise 0000.  Execute NEXT.  If no break key is 
          available, sense any key depression as a break (sense but don't 
          wait for a key).  If both the above are unavailable, simply 
          push 0000 and execute NEXT.

          (CR)  Execute a terminal carriage return and line feed. Execute 
          NEXT.
      
     When each of these words is executed, the interpreter vectors from 
     the definition header to these code sequences.  On specific 
     implementations it may be necessary to preserve certain registers 
     and observe operating system protocols.  Understand the implementors 
     methods in the listing before proceeding!

          R/W   This colon-definition is the standard linkage to your 
          disc.  It requests the read or write of a disc sector.  It 
          usually requires supporting code definitions.  It may consist 
          of self-contained code or call ROM monitor code.  When R/W is 
          assembled, its code field address is inserted once in BLOCK and 
          once in BUFFER.

          An alternate version of R/W is included that simulates disc 
          storage in RAM.  If you have over 16 k bytes this is practical 
          for startup and limited operation with cassette.





                                     3








     High-level Definitions

     The next section contains about 30 definitions involving user 
     interaction: compiling aids, finding, forgetting, listing, and 
     number formatting.  These definitions are placed above the 
     installation dependent code to facilitate modification.  That is, 
     once your full system is up, you may FORGET part of the high-level 
     and re-compile altered definitions from disc.


     System Tools

     A text editor and machine code assembler are normally resident.  We 
     are including a sample editor, and hope to provide Forth assemblers.  
     The editor is compiled from the terminal the first time, and then 
     used to place the editor and assembler source code on disc.

     It is essential that you regard the assembly listing as just a way 
     to get Forth installed on your system.  Additions and changes must 
     be planned and tested at the usual Forth high level and then the 
     assembly routines updated.  Forth work planned and executed only at 
     an assembly level tends to be non-portable, and confusing.

      
     RAM Workspace

     For a single user system, at least 2k bytes must be available above 
     the compiled system (the dictionary).  A 16k byte total system is 
     most typical.

     The RAM workspace contains the computation and return stacks, user 
     area, terminal input buffer, disc buffer and compilation space for 
     the dictionary.


                              4.0  INSTALLATION

     We see the following methods of getting a functioning fig-FORTH 
     system:

     1.  Buy loadable object code from a vendor who has customized. 

     2.  Obtain an assembly listing with the installation dependent code 
         supplied by the vendor.  Assemble and execute. 

     3.  Edit the FIG assembly listing on your system, re-write the I-O 
         routines, and assemble. 

     4.  Load someone else's object code up to the installation dependent 
         code.  Hand assemble equivalents for your system and poke in 
         with your monitor.  Begin execution and type in (self-compile) 
         the rest of the system.  This takes about two hours once you 
         understand the structure of Forth (but that will take much more 
         time!).



                                     4








     Let us examine Step 3, above, in fuller detail.  If you wish to 
     bring up Forth only from this model, here are the sequential steps:

     4.1  Familiarize yourself with the model written in Forth, the 
          glossary, and specific assembly listings.

     4.2  Edit the assembly listings into your system.  Set the boot-up 
          parameters at origin offset 0A, 0B (bytes) to 0000 
          (warning=00).

     4.3  Alter the terminal support code (KEY, EMIT, etc,) to match your 
          system. Observe register protocol specific to your 
          implementation!

     4.4  Place a break to your monitor at the end of NEXT, just before 
          indirectly jumping via register W to execution.  W is the Forth 
          name for the register holding a code field address, and may be 
          differently referenced in your listings.

     4.5  Enter the cold start at the origin.  Upon the break, check that 
          the interpretive pointer IP points within ABORT and W points to 
          SP!.  If COLD is a colon-definition, then the IP has been 
          initialized on the way to NEXT and your testing will begin in 
          COLD.  The purpose of COLD is to initialize IP, SP, RP, UP, and 
          some user variables from the start-up parameters at the origin.

     4.6  Continue execution one word at a time.  Clever individuals 
          could write a simple trace routine to print IP, W, SP, RP and 
          the top of the stacks.  Run in this single step mode until the 
          greeting message is printed.  Note that the interpretation is 
          several hundred cycles to this stage!

     4.7  Execution errors may be localized by observing the above 
          pointers when a crash occurs.

     4.8  After the word QUIT is executed (incrementally), and you can 
          input a "return" key and get OK printed, remove the break. You 
          may have some remaining errors, but a reset and examination of 
          the above registers will again localize problems.

     4.9  When the system is interpreting from the keyboard, execute 
          EMPTY-BUFFERS to clear the disc buffer area.  You may test the 
          disc access by typing:  0  BLOCK  64  TYPE 
          This should bring sector zero from the disc to a buffer and 
          type the first 64 characters. This sector usually contains 
          ascii text of the disc directory.  If BLOCK (and R/W) doesn't 
          function--happy hunting!

     5.0  If your disc driver differs from the assembly version, you must 
          create your own R/W.  This word does a range check (with error 
          message), modulo math to derive sector, track, and drive and 
          passes values to a sector-read and sector-write routine.





                                     5









                             RAM DISC SIMULATION

     If disc is not available, a simulation of BLOCK and BUFFER may be 
     made in RAM.  The following definitions setup high memory as mass 
     storage.  Referenced 'screens' are then brought to the 'disc buffer' 
     area.  This is a good method to test the start-up program even if 
     disc may be available.

     HEX 
     4000  CONSTANT  LO  ( START OF BUFFER AREA ) 
     6800  CONSTANT  HI  ( 10 SCREEN EQUIVALENT ) 
     : R/W  >R  ( save boolean ) 
        B/BUF  *  LO  +  DUP 
        HI  >  6  ?ERROR ( range check ) 
        R>  IF ( read )  SWAP  ENDIF 
        B/BUF  CMOVE   ;

     Insert the code field address of R/W into BLOCK and BUFFER and 
     proceed as if testing disc.  R/W simulates screens 0 thru 9 when 
     B/BUF is 128, in the memory area $4000 thru $6BFF.


                        fig-FORTH VARIABLE NAME FIELD

     A major FIG innovation in this model, is the introduction of 
     variable length definition names in compiled dictionary entries. 
     Previous methods only saved three letters and the character count.

     The user may select the letter count saved, up to the full natural 
     length.  See the glossary definition for WIDTH.

     In this model, the following conventions have been established.

     1. The first byte of the name field has the natural character count 
        in the low 5 bits. 

     2. The sixth bit = 1 when smudged, and will prevent a match by 
        (FIND). 

     3. The seventh bit = 1 for IMMEDIATE definitions; it is called the 
        precedence bit. 

     4. The eighth or sign bit is always = 1. 

     5. The following bytes contain the names' letters, up to the value 
        in WIDTH. 

     6. In the byte containing the last letter saved, the sign bit = 1. 

     7. In word addressing computer, a name may be padded with a blank to 
        a word boundary.





                                     6








     The above methods are implemented in CREATE. Remember that -FIND 
     uses  BL WORD  to bring the next text to HERE with the count 
     preceding.  All that is necessary, is to limit by WIDTH and toggle 
     the proper delimiting bits.


                               5.0  MEMORY MAP

     The following memory map is broadly used. Specific installations may 
     require alterations but you may forfeit functions in future FIG 
     offerings.

     The disc buffer area is at the upper bound of RAM memory.  It is 
     comprised of an integral number of buffers, each B/BUF+4 bytes.  
     B/BUF is the number of bytes read from the disc, usually one sector.  
     B/BUF must be a power of two (64, 128, 256, 512 or 1024).  The 
     constant FIRST has the value of the address of the start of the 
     first buffer.  LIMIT has the value of the first address beyond the 
     top buffer.  The distance between FIRST and LIMIT must be 
     N*(B/BUF+4) bytes.  This N must be two or more.

     Constant B/SCR has the value of the number of buffers per screen; 
     i.e.  1024 / B/BUF.

     The user area must be at least 34 bytes; 48 is more appropriate.  In 
     a multi-user system, each user has his own user area, for his copy 
     of system variables.  This method allows re-entrant use of the Forth 
     vocabulary.

     The terminal input buffer is decimal 80 bytes (the hex 50 in QUERY) 
     plus 2 at the end.  If a different value is desired, change the 
     limit in QUERY.  A parameter in the boot-up literals locates the 
     address of this area for TIB.  The backspace character is also in 
     the boot-up origin parameters.  It is universally expected that 
     "rubout" is the backspace.

     The return stack grows downward from the user area toward the 
     terminal buffer.  Forty-eight bytes are sufficient.  The origin is 
     in R0 (R-zero) and is loaded from a boot-up literal.

     The computation stack grows downward from the terminal buffer toward 
     the dictionary, which grows upward.  The origin of the stack is in 
     variable S0 (S-zero) and is loaded from a boot-up literal.

     After a cold start, the user variables contain the addresses of the 
     above memory assignments.  An advanced user may relocate while the 
     system is running.  A newcomer should alter the startup literals and 
     execute COLD.  The word +ORIGIN is provided for this purpose.  
     +ORIGIN gives the address byte or word relative to the origin 
     depending on the computer addressing method.  To change the 
     backspace to control H type:

          HEX  08  0E  +ORIGIN  !  ( byte addresses)




                                     7









                          6.0  DOCUMENTATION SUMMARY

     The following manuals are in print:

     Caltech FORTH Manual, an advanced manual with internal details of 
     Forth.  Has some implementation peculiarities.  Approx. $6.50 from 
     the Caltech Book Store, Pasadena, CA.

     Kitt Peak Forth Primer, $20.00 postpaid from the Forth Interest 
     Group, P.O. Box 1105, San Carlos, CA 94070.

     microFORTH Primer, $15.00  Forth, Inc. 815 Manhattan Ave. Manhattan 
     Beach, CA 90266

     Forth Dimensions, newsletter of the Forth Interest Group, $5.00 for 
     6 issues including membership.  F.I.G. P.O. Box 1105 San Carlos, CA. 
     94070
      






































                                     8









                               STANDARD
                         fig-FORTH MEMORY MAP
      

     LIMIT --->  +----------------------------------+  <--- USE
                 |                                  |
                 |           DISC BUFFERS           |
                 |                                  |
     FIRST --->  +----------------------------------+  <--- PREV

                 +----------------------------------+
                 |                                  |
                 |            USER AREA             |
                 |                                  |
     UP    --->  +----------------------------------+

     R0    --->  +----------------------------------+  
                 |                                  |  \
                 |  RETURN STACK                    |   \
                 |       |               ^          |    \  IN
                 |       v               |          |    /
                 |                TERMINAL BUFFER   |   /
                 |                                  |  /
     RP    --->  +----------------------------------+  <--- TIB

     S0    --->  +----------------------------------+
                 |       |                          |
                 |       |      STACK               |
                 |       v                          |
     SP    --->  +----------------------------------+

                 +----------------------------------+
                 |                                  |
                 |           TEXT BUFFER            |
                 |                                  |
                 +----------------------------------+  <--- PAD
                            "WORD" BUFFER
     DP    --->  +----------------------------------+
                 |                                  |
                 |            DICTIONARY            |
                 |                                  |
                 +----------------------------------+

                 +----------------------------------+
                 |                                  |
                 |         BOOT-UP LITERALS         |
                 |                                  |
                 +----------------------------------+  <--- 0 +ORIGIN








                                     9









                                 6502
                         fig-FORTH MEMORY MAP
      

     LIMIT --->  +----------------------------------+  <--- USE
                 |                                  |
                 |           DISC BUFFERS           |
                 |                                  |
     FIRST --->  +----------------------------------+  <--- PREV

                 +----------------------------------+
                 |                                  |
                 |            USER AREA             |
                 |                                  |
     UP    --->  +----------------------------------+

                 +----------------------------------+
                 |                                  |
                 |           TEXT BUFFER            |
                 |                                  |
                 +----------------------------------+  <--- PAD
                             "WORD" BUFFER
     DP    --->  +----------------------------------+
                 |                                  |
                 |            DICTIONARY            |
                 |                                  |
                 | -------------------------------- |
                 |                                  |
     $200        |         BOOT-UP LITERALS         |
                 |                                  |
                 +----------------------------------+  <--- 0 +ORIGIN

     $01FF --->  +----------------------------------+  
     R0          |                                  |  \
                 |  RETURN STACK                    |   \
                 |       |               ^          |    \  IN
                 |       V               |          |    /
     RP    --->  |                TERMINAL BUFFER   |   /
                 |                                  |  /
     $0100 --->  +----------------------------------+  <--- TIB

                 +----------------------------------+
                 |                                  |
     Z-PAGE      |           UP  N  IP  W           |
                 |                                  |
                 +----------------------------------+

     S0    --->  +----------------------------------+  SP IS X REGISTER
                 |       |                          |  RP IS STACK POINTER
                 |       |      STACK               |        OF CPU
                 |       |  $009F - $0010           |
                 |       v                          |
     SP    --->  +----------------------------------+



                                     10









                              fig-FORTH GLOSSARY


     This  glossary contains all of the word definitions in Release 1 of 
     fig-FORTH.  The definitions are present in order of their ascii 
     sort.

     The first line of each entry shows a symbolic description of the 
     action of the procedure on the parameter stack.  The symbols 
     indicate the order in which input parameters have been placed on the 
     stack.  The three dashes "---" indicate the execution point; any 
     parameters left on the stack are listed.  In this notation, the top 
     of the stack is to the right.

     The symbols include:

     addr      memory address
     b         8 bit byte (ie. hi 8 bits zero)
     c         7 bit ascii character (hi 9 bits zero)
     d         32 bit signed double integer, most significant portion 
               with sign on top of stack.
     f         boolean flag.  0=false, non-zero=true
     ff        boolean false flag=0
     n         16 bit signed integer number
     u         16 bit unsigned integer
     tf        boolean true flag=non zero

     The capital letters on the right show definition characteristics:

     C         May only be used within a colon definition.  A digit 
               indicates number of memory addresses used, if other than 
               one.
     E         Intended for execution only.
     L0        Level Zero definition of FORTH-78
     L1        Level One definition of FORTH-78
     P         Has precedence bit set.  Will execute even when compiling.
     U         A user variable.

     Unless otherwise noted, all references to numbers are for 16 bit 
     signed integers.  On 8 bit data bus computers, the high byte of a 
     number is on top of the stack, with the sign in the leftmost bit.  
     For 32 bit signed double numbers, the most significant (with the 
     sign) is on top.

     All arithmetic is implicitly 16 bit signed integer math, with error 
     and under-flow indication unspecified.










                                     11








      !             n  addr  ---                            L0
               Store 16 bits of n at address.  Pronounced "store".

      !CSP
               Save the stack position in CSP.  Used as part of the 
               compiler security.

      #             d1  ---  d2                             L0
               Generate from a double number d1, the next ascii character 
               which is placed in an output string.  Result d2 is the 
               quotient after division by BASE, and is maintained for 
               further processing.  Used between <# and #>.  See #S.

      #>            d  ---  addr count                      L0
               Terminates numeric output conversion by dropping d, 
               leaving the text address and character count suitable for 
               TYPE.

      #S            d1  ---  d2                             L0
               Generates ascii text in the text output buffer, by the use 
               of #, until a zero double number n2 results.  Used between 
               <# and #>.

      '             ---  addr                               P,L0
               Used in the form:
                         '  nnnn
               Leaves the parameter field address of dictionary word 
               nnnn.  As a compiler directive, executes in a colon 
               definition to compile the address as a literal.  If the 
               word is not found after a search of CONTEXT and CURRENT, 
               an appropriate error message is given.  Pronounced "tick".

      (                                                      P,L0
               Used in the form:
                         ( cccc)
               Ignore a comment that will be delimited by a right 
               parenthesis on the same line.  May occur during execution 
               or in a colon-definition.  A blank after the leading 
               parenthesis is required.

      (.")                                                   C+
               The run-time procedure, compiled by ." which transmits the 
               following in-line text to the selected output device.  See 
               ."

      (;CODE)                                                C
               The run-time procedure, compiled by ;CODE, that rewrites 
               the code field of the most recently defined word to point 
               to the following machine code sequence.  See ;CODE.

      (+LOOP)       n  ---                                  C2
               The run-time procedure compiled by +LOOP, which increments 
               the loop index by n and tests for loop completion.  See 
               +LOOP.



                                     12








      (ABORT)
               Executes after an error when WARNING is -1.  This word 
               normally executes ABORT, but may be altered (with care) to 
               a user's alternative procedure.

      (DO)                                                   C
               The run-time procedure compiled by DO which moves the loop 
               control parameters to the return stack.  See DO.

      (FIND)        addr1  addr2  ---  pfa  b  tf      (ok)
                    addr1  addr2  ---  ff              (bad)
               Searches the dictionary starting at the name field address 
               addr2, matching to the text at addr1.  Returns parameter 
               field address, length byte of name field and boolean true 
               for a good match.  If no match is found, only a boolean 
               false is left.

      (LINE)        n1  n2  ---  addr  count
               Convert the line number n1 and the screen n2 to the disc 
               buffer address containing the data.  A count of 64 
               indicates the full line text length.

      (LOOP)                                                 C2
               The run-time procedure compiled by LOOP which increments 
               the loop index and tests for loop completion.  See LOOP.

      (NUMBER)      d1  addr1  ---  d2  addr2
               Convert the ascii text beginning at addr1+1 with regard to 
               BASE.  The new value is accumulated into double number d1,  
               being left as d2.  Addr2 is the address of the first 
               unconvertable digit.  Used by NUMBER.

      *             n1  n2  ---  prod                       L0
               Leave the signed product of two signed numbers.

      */            n1  n2  n3  ---  n4                     L0
               Leave the ratio n4 = n1*n2/n3 where all are signed 
               numbers.  Retention of an intermediate 31 bit product 
               permits greater accuracy than would be available with the 
               sequence:  n1 n2 * n3 /

      */MOD         n1  n2  n3  ---  n4  n5                 L0
               Leave the quotient n5 and remainder n4 of the operation 
               n1*n2/n3.  A 31 bit intermediate product is used as for 
               */.

      +             n1  n2  ---  sum                        L0
               Leave the sum of n1+n2.

      +!            n  addr  ---                            L0
               Add n to the value at the address.  Pronounced "plus-
               store".





                                     13








      +-            n1  n2  ---  n3
               Apply the sign of n2 to n1, which is left as n3.

      +BUF          addr1  ---  addr2  f
               Advance the disc buffer address addr1 to the address of 
               the next buffer addr2.  Boolean f is false when addr2 is 
               the buffer presently pointed to by variable PREV.

      +LOOP               n1  ---       (run)
                    addr  n2  ---       (compile)           P,C2,L0
               Used in a colon-definition in the form:
                         DO  ...  n1  +LOOP
               At run-time, +LOOP selectively controls branching back to 
               the corresponding DO based on n1, the loop index and the 
               loop limit.  The signed increment n1 is added to the index 
               and the total compared to the limit.  The branch back to 
               DO occurs until the new index is equal to or greater than 
               the limit (n1>0), or until the new index is equal to or 
               less than the limit (n1<0).  Upon exiting the loop, the 
               parameters are discarded and execution continues ahead.

               At compile time, +LOOP compiles the run-time word (+LOOP) 
               and the branch offset computed from HERE to the address 
               left on the stack by DO.  n2 is used for compile-time 
               error checking.

      +ORIGIN       n  ---  addr
               Leave the memory address relative by n to the origin 
               parameter area.  n is the minimum address unit, either 
               byte or word.  This definition is used to access or modify 
               the boot-up parameters at the origin area.

      ,             n  ---                                  L0
               Store n into the next available dictionary memory cell, 
               advancing the dictionary pointer.  (comma)

      -             n1  n2  ---  diff                       L0
               Leave the difference of n1-n2.

      -->                                                   P,L0
               Continue interpretation with the next disc screen.  
               (pronounced next-screen).

      -DUP          n1  ---  n1         (if zero)
                    n1  ---  n1  n1     (non-zero)          L0
               Reproduce n1 only if it is non-zero.  This is usually used 
               to copy a value just before IF, to eliminate the need for 
               an ELSE part to drop it.









                                     14








      -FIND         ---  pfa  b  tf     (found)
                    ---  ff             (not found)
               Accepts the next text word (delimited by blanks) in the 
               input stream to HERE, and searches the CONTEXT and then 
               CURRENT vocabularies for a matching entry.  If found, the 
               dictionary entry's parameter field address, its length 
               byte, and a boolean true is left.  Otherwise, only a 
               boolean false is left.

      -TRAILING     addr  n1  ---  addr  n2
               Adjusts the character count n1 of a text string beginning 
               address to suppress the output of trailing blanks.  ie. 
               the characters at addr+n2 are blanks.

      .             n  ---                                  L0
               Print a number from a signed 16 bit two's complement 
               value, converted according to the numeric BASE.  A 
               trailing blank follows.  Pronounced "dot".

      ."                                                    P,L0
               Used in the form:
                         ." cccc"
               Compiles an in-line string cccc (delimited by the trailing 
               ") with an execution procedure to transmit the text to the 
               selected output device.  If executed outside a definition, 
               ." will immediately print the text until the final ".  The 
               maximum number of characters may be an installation 
               dependent value.  See (.").

      .LINE         line  scr  ---
               Print on the terminal device, a line of text from the disc 
               by its line and screen number.  Trailing blanks are 
               suppressed.

      .R            n1  n2  ---
               Print the number n1 right aligned in a field of whose 
               width is n2.  No following blank is printed.

      /             n1  n2  ---  quot                       L0
               Leave the signed quotient of n1/n2.

      /MOD          n1  n2  ---  rem quot                   L0
               Leave the remainder and signed quotient of n1/n2.  The 
               remainder has the sign of the dividend.

      0 1 2 3        ---  n
               These small numbers are used so often that it is 
               attractive to define them by name in the dictionary as 
               constants.

      0<            n  ---  f                               L0
               Leave a true flag if the number is less than zero 
               (negative), otherwise leave a false flag.




                                     15








      0=            n  ---  f                               L0
               Leave a true flag if the number is equal to zero, 
               otherwise leave a false flag.

      0BRANCH       f  ---                                  C2
               The run-time procedure to conditionally branch.  If f is 
               false (zero), the following in-line parameter is added to 
               the interpretive pointer to branch ahead or back.  
               Compiled by IF, UNTIL, and WHILE.

      1+            n1  ---  n2                             L1
               Increment n1 by 1.

      2+            n1  ---  n2
               Leave n1 incremented by 2.

      :                                                     P,E,L0
               Used in the form called a colon-definition:
                         : cccc   ...  ;
               Creates a dictionary entry defining cccc as equivalent to 
               the following sequence of Forth word definitions '...' 
               until the next ';' or ';CODE'.  The compiling process is 
               done by the text interpreter as long as STATE is non-zero.  
               Other details are that the CONTEXT vocabulary is set to 
               the CURRENT vocabulary and that words with the precedence 
               bit set (P) are executed rather than being compiled.

      ;                                                     P,C,L0
               Terminate a colon-definition and stop further compilation.  
               Compiles the run-time ;S.

      ;CODE                                                 P,C,L0
               Used in the form:
                         : cccc  ...  ;CODE
                              assembly mnemonics
               Stop compilation and terminate a new defining word cccc by 
               compiling (;CODE).  Set the CONTEXT vocabulary to 
               ASSEMBLER, assembling to machine code the following 
               mnemonics.

               When cccc later executes in the form:
                         cccc  nnnn
               the word nnnn will be created with its execution procedure 
               given by the machine code following cccc.  That is, when 
               nnnn is executed, it does so by jumping to the code after 
               nnnn.  An existing defining word must exist in cccc prior 
               to ;CODE.

      ;S                                                    P,L0
               Stop interpretation of a screen.  ;S is also the run-time 
               word compiled at the end of a colon-definition which 
               returns execution to the calling procedure.





                                     16








      <             n1  n2  ---  f                          L0
               Leave a true flag if n1 is less than n2; otherwise leave a 
               false flag.

      <#                                                    L0
               Setup for pictured numeric output formatting using the 
               words:
                         <#  #  #S  SIGN  #>
               The conversion is done on a double number producing text 
               at PAD.

      <BUILDS                                               C,L0
               Used within a colon-definition:
                         : cccc  <BUILDS  ...  DOES>  ...  ;
               Each time cccc is executed, <BUILDS defines a new word 
               with a high-level execution procedure.  Executing cccc in 
               the form:
                         cccc  nnnn
               uses <BUILDS to create a dictionary entry for nnnn with a 
               call to the DOES> part for nnnn.  When nnnn is later 
               executed, it has the address of its parameter area on the 
               stack and executes the words after DOES> in cccc.  <BUILDS 
               and DOES> allow run-time procedures to be written in high-
               level rather than in assembler code (as required by 
               ;CODE ).

      =             n1  n2  ---  f                          L0
               Leave a true flag if n1=n2; otherwise leave a false flag.

      >             n1  n2  ---  f                          L0
               Leave a true flag if n1 is greater than n2; otherwise a 
               false flag.

      >R            n  ---                                  C,L0
               Remove a number from the computation stack and place as 
               the most accessable on the return stack.  Use should be 
               balanced with R> in the same definition.

      ?             addr  ---                               L0
               Print the value contained at the address in free format 
               according to the current base.

      ?COMP
               Issue error message if not compiling.

      ?CSP
               Issue error message if stack position differs from value 
               saved in CSP.

      ?ERROR        f  n  ---
               Issue an error message number n, if the boolean flag is 
               true.





                                     17








      ?EXEC
               Issue an error message if not executing.

      ?LOADING
               Issue an error message if not loading.

      ?PAIRS        n1  n2  ---
               Issue an error message if n1 does not equal n2.  The 
               message indicates that compiled conditionals do not match.

      ?STACK
               Issue an error message if the stack is out of bounds.  
               This definition may be installation dependent.

      ?TERMINAL     ---  f
               Perform a test of the terminal keyboard for actuation of 
               the break key.  A true flag indicates actuation.  This 
               definition is installation dependent.

      @             addr  ---  n                            L0
               Leave the 16 bit contents of address.

      ABORT                                                 L0
               Clear the stacks and enter the execution state.  Return 
               control to the operators terminal, printing a message 
               appropriate to the installation.

      ABS           n  ---  u                               L0
               Leave the absolute value of n as u.

      AGAIN         addr  n  ---        (compiling)         P,C2,L0
               Used in a colon-definition in the form:
                         BEGIN  ...  AGAIN
               At run-time, AGAIN forces execution to return to 
               corresponding BEGIN.  There is no effect on the stack.  
               Execution cannot leave this loop (unless R> DROP is 
               executed one level below).

               At compile time, AGAIN compiles BRANCH with an offset from 
               HERE to addr.  n is used for compile-time error checking.

      ALLOT         n  ---                                  L0
               Add the signed number to the dictionary pointer DP.  May 
               be used to reserve dictionary space or re-origin memory.  
               n is with regard to computer address type (byte or word).

      AND           n1  n2  ---  n3                         L0
               Leave the bitwise logical and of n1 and n2 as n3.

      B/BUF         ---  n
               This constant leaves the number of bytes per disc buffer, 
               the byte count read from disc by BLOCK.





                                     18








      B/SCR         ---  n
               This constant leaves the number of blocks per editing 
               screen.  By convention, an editing screen is 1024 bytes 
               organised as 16 lines of 64 characters each.

      BACK          addr ---
               Calculate the backward branch offset from HERE to addr and 
               compile into the next available dictionary memory address.

      BASE          ---  addr                               U,L0
               A user variable containing the current number base used 
               for input and output conversion.

      BEGIN         ---  addr  n        (compiling)         P,L0
               Occurs in a colon-definition in form:
                         BEGIN  ...  UNTIL
                         BEGIN  ...  AGAIN
                         BEGIN  ...  WHILE  ...  REPEAT
               At run-time, BEGIN marks the start of a sequence that may 
               be repetitively executed.  It serves as a return point 
               from the corresponding UNTIL, AGAIN or REPEAT.  When 
               executing UNTIL, a return to BEGIN will occur if the top 
               of the stack is false; for AGAIN and REPEAT a return to 
               BEGIN always occurs.

               At compile time BEGIN leaves its return address and n for 
               compiler error checking.

      BL            ---  c
               A constant that leaves the ascii value for "blank".

      BLANKS        addr  count  ---
               Fill an area of memory begining at addr with blanks.

      BLK           ---  addr                               U,L0
               A user variable containing the block number being 
               interpreted.  If zero, input is being taken from the 
               terminal input buffer.

      BLOCK         n  ---  addr                            L0
               Leave the memory address of the block buffer containing 
               block n.  If the block is not already in memory, it is 
               transferred from disc to which ever buffer was least 
               recently written.  If the block occupying that buffer has 
               been marked as being updated, it is re-written to disc 
               before block n is read into the buffer.  See also BUFFER, 
               R/W  UPDATE  FLUSH

      BLOCK-READ
      BLOCK-WRITE
               These are preferred names for the installation dependent 
               code to read and write one block to the disc.





                                     19








      BRANCH                                                C2,L0
               The run-time procedure to unconditionally branch.  An in-
               line offset is added to the interpretive pointer IP to 
               branch ahead or back.  BRANCH is compiled by ELSE, AGAIN, 
               REPEAT.

      BUFFER        n  ---  addr
               Obtain the next memory buffer, assigning it to block n.  
               If the contents of the buffer is marked as updated, it is 
               written to the disc.  The block is not read from the disc.  
               The address left is the first cell within the buffer for 
               data storage.

      C!            b  addr  ---
               Store 8 bits at address.  On word addressing computers, 
               further specification is necessary regarding byte 
               addressing.

      C,            b  ---
               Store 8 bits of b into the next available dictionary byte, 
               advancing the dictionary pointer.  This is only available 
               on byte addressing computers, and should be used with 
               caution on byte addressing minicomputers.

      C@            addr  ---  b
               Leave the 8 bit contents of memory address.  On word 
               addressing computers, further specification is needed 
               regarding byte addressing.

      CFA           pfa  ---  cfa
               Convert the parameter field address of a definition to its 
               code field address.

      CMOVE         from  to  count  ---
               Move the specified quantity of bytes beginning at address 
               from to address to.  The contents of address from is moved 
               first proceeding toward high memory.  Further 
               specification is necessary on word addressing computers.

      COLD
               The cold start procedure to adjust the dictionary pointer 
               to the minimum standard and restart via ABORT.  May be 
               called from the terminal to remove application programs 
               and restart.

      COMPILE                                               C2
               When the word containing COMPILE executes, the execution 
               address of the word following COMPILE is copied (compiled) 
               into the dictionary.  This allows specific compilation 
               situations to be handled in addition to simply compiling 
               an execution address (which the interpreter already does).






                                     20








      CONSTANT      n  ---                                  L0
               A defining word used in the form:
                         n  CONSTANT  cccc
               to create word cccc, with its parameter field containing 
               n.  When cccc is later executed, it will push the value of 
               n to the stack.

      CONTEXT       ---  addr                               U,L0
               A user variable containing a pointer to the vocabulary 
               within which dictionary searches will first begin.

      COUNT         addr1  ---  addr2  n                    L0
               Leave the byte address addr2 and byte count n of a message 
               text beginning at addr1.  It is presumed that the first 
               byte at addr1 contains the text byte count and the actual 
               text starts with the second byte.  Typically COUNT is 
               followed by TYPE.

      CR                                                    L0
               Transmit a carriage return and line feed to the selected 
               output device.

      CREATE
               A defining word used in the form:
                         CREATE  cccc
               by such words as CODE and CONSTANT to create a dictionary 
               header for a Forth definition.  The code field contains 
               the address of the word's parameter field.  The new word 
               is created in the CURRENT vocabulary.

      CSP           ---  addr                               U
               A user variable temporarily storing the stack pointer 
               position, for compilation error checking.

      D+            d1  d2  ---  dsum
               Leave the double number sum of two double numbers.

      D+-           d1  n  ---  d2
               Apply the sign of n to the double number d1, leaving it as 
               d2.

      D.            d  ---                                  L1
               Print a signed double number from a 32 bit two's 
               complement value.  The high-order 16 bits are most 
               accessable on the stack.  Conversion is performed 
               according to the current BASE.  A blank follows.
               Pronounced D-dot.

      D.R           d  n  ---
               Print a signed double number d right aligned in a field n 
               characters wide.

      DABS          d  ---  ud
               Leave the absolute value ud of a double number.



                                     21








      DECIMAL                                               L0
               Set the numeric conversion BASE for decimal input-output.

      DEFINITIONS                                           L1
               Used in the form:
                         cccc  DEFINITIONS
               Set the CURRENT vocabulary to the CONTEXT vocabulary.  In 
               the example, executing vocabulary name cccc made it the 
               CONTEXT vocabulary and executing DEFINITIONS made both 
               specify vocabulary cccc.

      DIGIT         c  n1  ---  n2  tf  (ok)
                    c  n1  ---  ff      (bad)
               Converts the ascii character c (using base n1) to its 
               binary equivalent n2, accompanied by a true flag.  If the 
               conversion is invalid, leaves only a false flag.

      DLIST
               List the names of the dictionary entries in the CONTEXT 
               vocabulary.

      DLITERAL      d  ---  d           (executing)
                    d  ---              (compiling)         P
               If compiling, compile a stack double number into a 
               literal.  Later execution of the definition containing 
               the literal will push it to the stack.  If executing, the 
               number will remain on the stack.

      DMINUS        d1  ---  d2
               Convert d1 to its double number two's complement.

      DO             n1  n2  ---        (execute)
                    addr  n  ---        (compile)           P,C2,L0
               Occurs in a colon-definition in the form:
                         DO  ...  LOOP
                         DO  ...  +LOOP
               At run-time, DO begins a sequence with repetitive 
               execution controlled by a loop limit n1 and an index with 
               initial value n2.  DO removes these from the stack.  Upon 
               reaching LOOP the index is incremented by one.  Until the 
               new index equals or exceeds the limit, execution loops 
               back to just after DO; otherwise the loop parameters are 
               discarded and execution continues ahead.  Both n1 and n2 
               are determined at run-time and may be the result of other 
               operations.  Within a loop 'I' will copy the current value 
               of the index to the stack.  See I, LOOP, +LOOP, LEAVE.

               When compiling within the colon-definition, DO compiles 
               (DO), leaves the following address addr and n for later 
               error checking.







                                     22








      DOES>                                                 L0
               A word which defines the run-time action within a high-
               level defining word.  DOES> alters the code field and 
               first parameter of the new word to execute the sequence of 
               compiled word addresses following DOES>.  Used in 
               combination with <BUILDS.  When the DOES> part executes it 
               begins with the address of the first parameter of the new 
               word on the stack.  This allows interpretation using this 
               area or its contents.  Typical uses include the Forth 
               assembler, multi-dimensional arrays, and compiler 
               generation.

      DP            ---  addr                               U,L
               A user variable, the dictionary pointer, which contains 
               the address of the next free memory above the dictionary.  
               The value may be read by HERE and altered by ALLOT.

      DPL           ---  addr                               U,L0
               A user variable containing the number of digits to the 
               right of the decimal on double integer input.  It may also 
               be used to hold output column location of a decimal point, 
               in user generated formatting.  The default value on single 
               number input is -1.

      DR0      Installation dependent commands to select disc drives, by 
      DR1      presetting OFFSET.  The contents of OFFSET is added to the 
               block number in BLOCK to allow for this selection.  Offset 
               is suppressed for error text so that it may always 
               originate from drive 0.

      DROP          n  ---                                  L0
               Drop the number from the stack.

      DUMP          addr  n  ---                            L0
               Print the contents of n memory locations beginning at 
               addr.  Both addresses and contents are shown in the 
               current numeric base.

      DUP           n  ---  n  n                            L0
               Duplicate the value on the stack.

      ELSE          addr1  n1  ---  addr2  n2  (compiling)  P,C2,L0
               Occurs within a colon-definition in the form:
                         IF  ...  ELSE  ...  ENDIF
               At run-time, ELSE executes after the true part following 
               IF.  ELSE forces execution to skip over the following 
               false part and resumes execution after the ENDIF.  It has 
               no stack effect.

               At compile-time ELSE emplaces BRANCH reserving a branch 
               offset, leaves the address addr2 and n2 for error testing.  
               ELSE also resolves the pending forward branch from IF by 
               calculating the offset from addr1 to HERE and storing at 
               addr1.



                                     23








      EMIT          c  ---                                  L0
               Transmit ascii character c to the selected output device.  
               OUT is incremented for each character output.

      EMPTY-BUFFERS                                         L0
               Mark all block-buffers as empty, not necessarily affecting 
               the contents.  Updated blocks are not written to the disc.  
               This is also an initialisation procedure before first use 
               of the disc.

      ENCLOSE       addr1  c  ---  addr1  n1  n2  n3
               The text scanning primitive used by WORD.  From the text 
               address addr1 and an ascii delimiting character c, is 
               determined the byte offset to the first non-delimiting 
               character n1, the offset to the first delimiter after the 
               text n2, and the offset to the first character not 
               included.  This procedure will not process past an ascii 
               'null', treating it as an unconditional delimiter.

      END                                                   P,C2,L0
               This is an 'alias' or duplicate definition for UNTIL.

      ENDIF         addr1  n  ---       (compile)           P,C0,L0
               Occurs in a colon-definition in the form:
                         IF  ...  ENDIF
                         IF  ...  ELSE  ...  ENDIF
               At run-time, ENDIF serves only as the destination of a 
               forward branch from IF or ELSE.  It marks the conclusion 
               of the conditional structure.  THEN is another name for 
               ENDIF.  Both names are supported in fig-FORTH.  See also 
               IF and ELSE.

               At compile-time, ENDIF computes the forward branch offset 
               from addr to HERE and stores it at addr.  n is used for 
               error tests.

      ERASE         addr  n  ---
               Clear a region of memory to zero from addr over n 
               addresses.

      ERROR         line  ---  in  blk
               Execute error notification and restart of system.  WARNING 
               is first examined.  If 1, the text of line n, relative to 
               screen 4 of drive 0 is printed.  This line number may be 
               positive or negative, and beyond just screen 4.  If 
               WARNING=0, n is just printed as a message number (non-disc 
               installation).  If WARNING is -1, the definition (ABORT) 
               is executed, which executes the system ABORT.  The user 
               may cautiously modify this execution by altering (ABORT).  
               fig-FORTH saves the contents of IN and BLK to assist in 
               determining the location of the error.  Final action is 
               execution of QUIT.





                                     24








      EXECUTE       addr  ---
               Execute the definition whose code field address is on the 
               stack.  The code field address is also called the 
               compilation address.

      EXPECT        addr  count  ---                        L0
               Transfer characters from the terminal to address, until a 
               "return" or the count of characters have been received.  
               One or more nulls are added at the end of the text.

      FENCE         ---  addr                               U
               A user variable containing an address below which 
               FORGETting is trapped.  To forget below this point the 
               user must alter the contents of FENCE.

      FILL          addr  quan  b  ---
               Fill memory at the address with the specified quantity of 
               bytes b.

      FIRST         ---  n
               A constant that leaves the address of the first (lowest) 
               block buffer.

      FLD           ---  addr                               U
               A user variable for control of number output field width.  
               Presently unused in fig-FORTH.

      FORGET                                                E,L0
               Executed in the form:
                         FORGET  cccc
               Deletes definition named cccc from the dictionary with all 
               entries physically following it.  In fig-FORTH, an error 
               message will occur if the CURRENT and CONTEXT vocabularies 
               are not currently the same.

      FORTH                                                 P,L1
               The name of the primary vocabulary.  Execution makes FORTH 
               the CONTEXT vocabulary.  Until additional user 
               vocabularies are defined, new user definitions become a 
               part of FORTH.  FORTH is immediate, so it will execute 
               during the creation of a colon-definition, to select this 
               vocabulary at compile-time.

      HERE          ---  addr                               L0
               Leave the address of the next available dictionary 
               location.

      HEX                                                   L0
               Set the numeric conversion base to sixteen (hexadecimal).

      HLD           ---  addr                               L0
               A user variable that holds the address of the latest 
               character of text during numeric output conversion.




                                     25








      HOLD          c  ---                                  L0
               Used between <# and #> to insert an ascii character into a 
               pictured numeric output string.  e.g. 2E HOLD will place a 
               decimal point.

      I             ---  n                                  C,L0
               Used within a DO-LOOP to copy the loop index to the stack.  
               Other use is implementation dependent.  See R.

      ID.           addr ---
               Print a definition's name from its name field address.

      IF            f  ---              (run-time)
                       ---  addr  n     (compile)           P,C2,L0
               Occurs in a colon definition in the form:
                         IF  (tp)  ...  ENDIF
                         IF  (tp)  ...  ELSE  (fp)  ...  ENDIF
               At run-time, IF selects execution based on a boolean flag.  
               If f is true (non-zero), execution continues ahead thru 
               the true part.  If f is false (zero), execution skips till 
               just after ELSE to execute the false part.  After either 
               part, execution resumes after ENDIF.  ELSE and its false 
               part are optional; if missing, false execution skips to 
               just after ENDIF.

               At compile-time IF compiles 0BRANCH and reserves space for 
               an offset at addr.  addr and n are used later for 
               resolution of the offset and error testing.

      IMMEDIATE
               Mark the most recently made definition so that when 
               encountered at compile time, it will be executed rather 
               than being compiled. i.e. the precedence bit in its header 
               is set.  This method allows definitions to handle unusual 
               compiling situations, rather than build them into the 
               fundamental compiler.  The user may force compilation of 
               an immediate definition by preceding it with [COMPILE].

      IN            ---  addr                               L0
               A user variable containing the byte offset within the 
               current input text buffer (terminal or disc) from which 
               the next text will be accepted.  WORD uses and moves the 
               value of IN.

      INDEX         from  to  ---
               Print the first line of each screen over the range from, 
               to.  This is used to view the comment lines of an area of 
               text on disc screens.









                                     26








      INTERPRET
               The outer text interpreter which sequentially executes or 
               compiles text from the input stream (terminal or disc) 
               depending on STATE.  If the word name cannot be found 
               after a search of CONTEXT and then CURRENT it is converted 
               to a number according to the current base.  That also 
               failing, an error message echoing the name with a " ?" 
               will be given.

               Text input will be taken according to the convention for 
               WORD.  If a decimal point is found as part of a number, a 
               double number value will be left.  The decimal point has 
               no other purpose than to force this action.  See NUMBER.

      KEY           ---  c                                  L0
               Leave the ascii value of the next terminal key struck.

      LATEST        ---  addr
               Leave the name field address of the topmost word in the 
               CURRENT vocabulary.

      LEAVE                                                 C,L0
               Force termination of a DO-LOOP at the next opportunity by 
               setting the loop limit to the current value of the index.  
               The index itself remains unchanged, and execution proceeds 
               normally until LOOP or +LOOP is encountered.

      LFA           pfa  ---  lfa
               Convert the parameter field address of a dictionary 
               definition to its link field address.

      LIMIT         ---  n
               A constant leaving the address just above the highest 
               memory available for a disc buffer.  Usually this is the 
               highest system memory.

      LIST          n  ---                                  L0
               Display the ascii text of screen n on the selected output 
               device.  SCR contains the screen number during and after 
               this process.

      LIT           ---  n                                  C2,L0
               Within a colon-definition, LIT is automatically compiled 
               before each 16 bit literal number encountered in input 
               text.  Later execution of LIT causes the contents of the 
               next dictionary address to be pushed to the stack.

      LITERAL       n  ---    (compiling)                   P,C2,L0
               If compiling, then compile the stack value n as a 16 bit 
               literal.  This definition is immediate so that it will 
               execute during a colon definition.  The intended use is:
                         : xxx   [ calculate ]  LITERAL  ;
               Compilation is suspended for the compile time calculation 
               of a value.  Compilation is resumed and LITERAL compiles 
               this value.


                                     27









      LOAD          n  ---                                  L0
               Begin interpretation of screen n.  Loading will terminate 
               at the end of the screen or at ;S.  See ;S and -->.

      LOOP          addr  n  ---        (compiling)         P,C2,L0
               Occurs in a colon-definition in the form:
                         DO  ...  LOOP
               At run-time, LOOP selectively controls branching back to 
               the corresponding DO based on the loop index and limit.  
               The  loop index is incremented by one and compared to the 
               limit.  The branch back to DO occurs until the index 
               equals or exceeds the limit; at that time, the parameters 
               are discarded and execution continues ahead.

               At compile-time, LOOP compiles (LOOP) and uses addr to 
               calculate an offset to DO.  n is used for error testing.

      M*            n1  n2  ---  d
               A mixed magnitude math operation which leaves the double 
               number signed product of two signed numbers.

      M/            d  n1  ---  n2  n3
               A mixed magnitude math operator which leaves the signed 
               remainder n2 and signed quotient n3, from a double number 
               dividend and divisor n1.  The remainder takes its sign 
               from the dividend.

      M/MOD         ud1  u2  ---  u3  u4
               An unsigned mixed magnitude math operation which leaves a 
               double quotient ud4 and remainder u3, from a double 
               dividend ud1 and single divisor u2.

      MAX           n1  n2  ---  max                        L0
               Leave the greater of two numbers.

      MESSAGE       n  ---
               Print on the selected output device the text of line n 
               relative to screen 4 of drive 0.  n may be positive or 
               negative.  MESSAGE may be used to print incidental text 
               such as report headers.  IF WARNING is zero, the message 
               will simply be printed as a number (disc-unavailable).

      MIN           n1  n2  ---  min                        L0
               Leave the smaller of two numbers.

      MINUS         n1  ---  n2                             L0
               Leave the two's complement of a number.

      MOD           n1  n2  ---  mod                        L0
               Leave the remainder of n1/n2, with the same sign as n1.






                                     28








      MON
               Exit to the system monitor, leaving a re-entry to Forth, 
               if possible.

      MOVE          addr1  addr2  n  ---
               Move the contents of n memory cells (16 bit contents) 
               beginning at addr1 into n cells beginning at addr2.  The 
               contents of addr1 is moved first.  This definition is 
               appropriate on word addressing computers.

      NEXT
               This is the inner interpreter that uses the interpretive 
               pointer IP to execute compiled Forth definitions.  It is 
               not directly executed but is the return point for all code 
               procedures.  It acts by fetching the address pointed by 
               IP, storing this value in register W.  It then jumps to 
               the address pointed to by W.  W points to the code field 
               of a definition which contains the address of the code 
               which executes for that definition.  This usage of 
               indirect threaded code is a major contributor to the 
               power, portability, and extensibility of forth.  Locations 
               of IP and W are computer specific.

      NFA           pfa  ---  nfa
               Convert the parameter field address of a definition to its 
               name field.

      NUMBER        addr  ---  d
               Convert a character string left at addr with a preceding 
               count, to a signed double number, using the current base.  
               If a decimal point is encountered in the text, its 
               position will be given in DPL, but no other effect occurs.  
               If numeric conversion is not possible, an error message 
               will be given.

      OFFSET        ---  addr                               U
               A user variable which may contain a block offset to disc 
               drives.  The contents of OFFSET is added to the stack 
               number by BLOCK.  Messages by MESSAGE are independent of 
               OFFSET.  See BLOCK, DR0, DR1, MESSAGE.

      OR            n1  n2  ---  or                         L0
               Leave the bit-wise logical or of two 16 bit values.

      OUT           ---  addr                               U
               A user variable that contains a value incremented by EMIT.  
               The user may alter and examine OUT to control display 
               formatting.

      OVER          n1  n2  ---  n1  n2  n1                 L0
               Copy the second stack value, placing it as the new top.






                                     29








      PAD           ---  addr                               L0
               Leave the address of the text output buffer, which is a 
               fixed offset above HERE.

      PFA           nfa  ---  pfa
               Convert the name field address of a compiled definition to 
               its parameter field address.

      POP
               The code sequence to remove a stack value and return to 
               NEXT.  POP is not directly executable, but is a forth re-
               entry point after machine code.

      PREV          ---  addr
               A variable containing the address of the disc buffer most 
               recently referenced.  The UPDATE command marks this buffer 
               to be later written to disc.

      PUSH
               This code sequence pushes machine registers to the 
               computation stack and returns to NEXT.  It is not directly 
               executable, but is a Forth re-entry point after machine 
               code.

      PUT
               This code sequence stores machine register contents over 
               the topmost computation stack value and returns to NEXT.  
               It is not directly executable, but is a Forth re-entry 
               point after machine code.

      QUERY
               Input 80 characters of text (or until a "return") from the 
               operators terminal.  Text is positioned at the address 
               contained in TIB with IN set to zero.

      QUIT                                                  L1
               Clear the return stack, stop compilation, and return 
               control to the operators terminal.  No message is given.

      R             ---  n
               Copy the top of the return stack to the computation stack.

      R#            ---  addr                               U
               A user variable which may contain the location of an 
               editing cursor, or other file related function.

      R/W           addr  blk  f  ---
               The fig-FORTH standard disc read-write linkage.  addr 
               specifies the source or destination block buffer, blk is 
               the sequential number of the referenced block; and f is a 
               flag for f=0 write and f=1 for read.  R/W determines the 
               location on mass storage, performs the read-write and 
               performs any error checking.




                                     30








      R>            ---  n                                  L0
               Remove the top value from the return stack and leave it on 
               the computation stack.  See >R and R.

      R0            ---  addr                               U
               A user variable containing the initial location of the 
               return stack.  Pronounced R-zero.  See RP!

      REPEAT        addr  n  ---        (compiling)         P,C2
               Used within a colon-definition in the form:
                         BEGIN  ...  WHILE  ...  REPEAT
               At run-time, REPEAT forces an unconditional branch back to 
               just after the corresponding BEGIN.

               At compile-time, REPEAT compiles BRANCH and the offset 
               from HERE to addr.  n is used for error testing.

      ROT           n1  n2  n3  ---  n2  n3  n1             L0
               Rotate the top three values on the stack, bringing the 
               third to the top.

      RP!
               A computer dependent procedure to initialise the return 
               stack pointer from user variable R0.

      S->D          n  ---  d
               Sign extend a single number to form a double number.

      S0            ---  addr                               U
               A user variable that contains the initial value for the 
               stack pointer.  Pronounced S-zero.  See SP!

      SCR           ---  addr                               U
               A user variable containing the screen number most recently 
               referenced by LIST.

      SIGN          n  d  ---  d                            L0
               Stores an ascii "-" sign just before a converted numeric 
               output string in the text output buffer when n is 
               negative.  n is discarded, but double number d is 
               maintained.  Must be between <# and #>.

      SMUDGE
               Used during word definition to toggle the "smudge bit" in 
               a definition's name field.  This prevents an un-completed 
               definition  from being found during dictionary searches, 
               until compiling is completed without error.

      SP!
               A computer dependent procedure to initialise the stack 
               pointer from S0.






                                     31








      SP@           ---  addr
               A computer dependent procedure to return the address of 
               the stack position to the top of the stack, as it was 
               before SP@ was executed.  (e.g. 1 2 SP@ @ . . . would type 
               2 2 1 )

      SPACE                                                 L0
               Transmit an ascii blank to the output device.

      SPACES        n  ---                                  L0
               Transmit n ascii blanks to the output device.

      STATE         ---  addr                               L0,U
               A user variable containing the compilation state.  A non-
               zero value indicates compilation.  The value itself may be 
               implementation dependent.

      SWAP          n1  n2  ---  n2  n1                     L0
               Exchange the top two values on the stack.

      TASK
               A no-operation word which can mark the boundary between 
               applications.  By forgetting TASK and re-compiling, an 
               application can be discarded in its entirety.

      THEN                                                  P,C0,L0
               An alias for ENDIF.

      TIB           ---  addr                               U
               A user variable containing the address of the terminal 
               input buffer.

      TOGGLE        addr  b  ---
               Complement the contents of addr by the bit pattern b.

      TRAVERSE      addr1  n  ---  addr2
               Move across the name field of a fig-FORTH variable length 
               name field.  addr1 is the address of either the length 
               byte or the last letter.  If n=1, the motion is toward 
               high memory; if n= -1, the motion is toward low memory.  
               The addr2 resulting is address of the other end of the 
               name.

      TRIAD         scr  ---
               Display on the selected output device the three screens 
               which include that numbered scr, beginning with a screen 
               evenly divisible by three.  Output is suitable for source 
               text records, and includes a reference line at the bottom 
               taken from line 15 of screen 4.

      TYPE          addr  count  ---                        L0
               Transmit count characters from addr to the selected output 
               device.




                                     32








      U*            u1  u2  ---  ud
               Leave the unsigned double number product of two unsigned 
               numbers.

      U/            ud  u1  ---  u2  u3
               Leave the unsigned remainder u2 and unsigned quotient u3 
               from the unsigned double dividend ud and unsigned divisor 
               u1.

      UNTIL               f  ---        (run-time)
                    addr  n  ---        (compile)           P,C2,L0
               Occurs within a colon-definition in the form:
                         BEGIN  ...  UNTIL
               At run-time, UNTIL controls the conditional branch back to 
               the corresponding BEGIN.  If f is false, execution returns 
               to just after begin; if true, execution continues ahead.

               At compile-time, UNTIL compiles (0BRANCH) and an offset 
               from HERE to addr.  n is used for error tests.

      UPDATE                                                L0
               Marks the most recently referenced block (pointed to by 
               PREV) as altered.  The block will subsequently be 
               transferred automatically to disc should its buffer be 
               required for storage of a different block.

      USE           ---  addr
               A variable containing the address of the block buffer to 
               use next, as the least recently written.

      USER          n  ---                                  L0
               A defining word used in the form:
                         n  USER  cccc
               which creates a user variable cccc.  The parameter field 
               of cccc contains n as a fixed offset relative to the user 
               pointer register UP for this user variable.  When cccc is 
               later executed, it places the sum of its offset and the 
               user area base address on the stack as the storage address 
               of that particular variable.

      VARIABLE                                              E,L0
               A defining word used in the form:
                         n  VARIABLE  cccc
               When VARIABLE is executed, it creates the definition cccc 
               with its parameter field initialised to n.  When cccc is 
               later executed, the address of its parameter field 
               (containing n) is left on the stack, so that a fetch or 
               store may access this location.

      VOC-LINK      ---  addr                               U
               A user variable containing the address of a field in the 
               definition of the most recently created vocabulary.  All 
               vocabulary names are linked by these fields to allow 
               control for FORGETting through multiple vocabularies.



                                     33








      VOCABULARY                                            E,L
               A defining word used in the form:
                         VOCABULARY  cccc
               to create a vocabulary definition cccc.  Subsequent use of 
               cccc will make it the CONTEXT vocabulary which is searched 
               first by INTERPRET.  The sequence "cccc DEFINITIONS" will 
               also make cccc the CURRENT vocabulary into which new 
               definitions are placed.

               In fig-FORTH, cccc will be so chained as to include all 
               definitions of the vocabulary in which cccc is itself 
               defined.  All vocabularies ultimately chain to Forth.  By 
               convention, vocabulary names are to be declared IMMEDIATE.  
               See VOC-LINK.

      VLIST
               List the names of the definitions in the context 
               vocabulary.  "Break" will terminate the listing.

      WARNING       ---  addr                               U
               A user variable containing a value controlling messages.  
               If = 1, disc is present and screen 4 of drive 0 is the 
               base location for messages.  If = 0, no disc is present 
               and messages will be presented by number.  If = -1, 
               execute (ABORT) for a user specified procedure.  See 
               MESSAGE, ERROR.

      WHILE               f  ---        (run-time)
                    ad1  n1  ---  ad1  n1  ad2  n2          P,C2
               Occurs in a colon-definition in the form:
                         BEGIN  ...  WHILE  (tp)  ...  REPEAT
               At run-time, WHILE selects conditional execution based on 
               boolean flag f.  If f is true (non-zero), WHILE continues 
               execution of the true part through to REPEAT, which then 
               branches back to BEGIN.  If f is false (zero), execution 
               skips to just after REPEAT, exiting the structure.

               At compile time, WHILE emplaces (0BRANCH) and leaves ad2 
               of the reserved offset.  The stack values will be resolved 
               by REPEAT.

      WIDTH         ---  addr                               U
               In fig-FORTH, a user variable containing the maximum 
               number of letters saved in the compilation of a 
               definition's name.  It must be 1 through 31, with a 
               default value of 31.  The name character count and its 
               natural characters are saved, up to the value in width.  
               The value may be changed at any time within the above 
               limits.








                                     34








      WORD          c  ---                                  L0
               Read the next text characters from the input stream being 
               interpreted, until a delimiter c is found, storing the 
               packed character string beginning at the dictionary buffer 
               HERE.  WORD leaves the character count in the first byte, 
               the characters, and ends with two or more blanks.  Leading 
               occurances of c are ignored.  If BLK is zero, text is 
               taken from the terminal input buffer, otherwise from the 
               disc block stored in BLK.  See BLK, IN.

      X
               This is a psuedonym for the "null" or dictionary entry for 
               a name of one character of ascii null.  It is the 
               execution procedure to terminate interpretation of a line 
               of text from the terminal or within a disc buffer, as both 
               buffers always have a null at the end.

      XOR           n1  n2  ---  xor                        L1
               Leave the bitwise logical exclusive-or of two values.

      [                                                     P,L1
               Used in a colon-definition in the form:
                         : xxx   [  words  ]   more  ;
               Suspend compilation.  The words after [ are executed, not 
               compiled.  This allows calculation or compilation 
               exceptions before resuming compilation with ].  See 
               LITERAL, ].

      [COMPILE]                                             P,C
               Used in a colon-definition in the form:
                         : xxx   [COMPILE]   FORTH  ;
               [COMPILE] will force the compilation of an immediate 
               definition, that would otherwise execute during 
               compilation.  The above example will select the FORTH 
               vocabulary when xxx executes, rather than at compile time.

      ]                                                     L1
               Resume compilation, to the completion of a colon-
               definition.  See [.


















                                     35

































































                                     36








     SCR # 3
       0 **********************  fig-FORTH  MODEL  **********************
       1
       2                      Through the courtesy of
       3
       4                       FORTH INTEREST GROUP
       5                          P. O. BOX 1105
       6                      SAN CARLOS, CA. 94070
       7
       8
       9                            RELEASE 1
      10                      WITH COMPILER SECURITY
      11                              AND
      12                      VARIABLE LENGTH NAMES
      13
      14
      15        Further distribution must include the above notice.

     SCR # 4
       0 (  ERROR MESSAGES  )
       1 EMPTY STACK
       2 DICTIONARY FULL
       3 HAS INCORRECT ADDRESS MODE
       4 ISN'T UNIQUE
       5
       6 DISC RANGE ?
       7 FULL STACK
       8 DISC ERROR !
       9
      10
      11
      12
      13
      14
      15 FORTH INTEREST GROUP                                 MAY 1, 1979

     SCR # 5
       0 (  ERROR MESSAGES  )
       1 COMPILATION ONLY, USE IN DEFINITION
       2 EXECUTION ONLY
       3 CONDITIONALS NOT PAIRED
       4 DEFINITION NOT FINISHED
       5 IN PROTECTED DICTIONARY
       6 USE ONLY WHEN LOADING
       7 OFF CURRENT EDITING SCREEN
       8 DECLARE VOCABULARY
       9
      10
      11
      12
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     37








                                   SOURCE CODE FOR WORD IS ON  LINE, SCREEN

     CODE LIT                   ( PUSH FOLLOWING LITERAL TO STACK *)  1 13
     LABEL PUSH      ( PUSH ACCUM AS HI-BYTE, ML STACK AS LO-BYTE *)  4 13
     LABEL PUT          ( REPLACE BOTTOM WITH ACCUM. AND ML STACK *)  6 13
     LABEL NEXT           ( EXECUTE NEXT FORTH ADDRESS, MOVING IP *)  8 13
     HERE  '  <CLIT>  !  HERE  2+  ,           ( MAKE SILENT WORD *)  1 14
     LABEL SETUP  ( MOVE # ITEMS FROM STACK TO 'N' AREA OF Z-PAGE *)  4 14
     CODE EXECUTE              ( EXECUTE A WORD BY ITS CODE FIELD *)  9 14
                                           ( ADDRESS ON THE STACK *) 10 14
     CODE BRANCH            ( ADJUST IP BY IN-LINE 16 BIT LITERAL *)  1 15
     CODE 0BRANCH           ( IF BOT IS ZERO, BRANCH FROM LITERAL *)  6 15
     CODE (LOOP)      ( INCREMENT LOOP INDEX, LOOP UNTIL => LIMIT *)  1 16
     CODE (+LOOP)            ( INCREMENT INDEX BY STACK VALUE +/- *)  8 16
     CODE (DO)             ( MOVE TWO STACK ITEMS TO RETURN STACK *)  2 17
     CODE I                    ( COPY CURRENT LOOP INDEX TO STACK *)  9 17
     CODE DIGIT     ( CONVERT ASCII CHAR-SECOND, WITH BASE-BOTTOM *)  1 18
                        ( IF OK RETURN DIGIT-SECOND, TRUE-BOTTOM; *)  2 18
                                        ( OTHERWISE FALSE-BOTTOM. *)  3 18
     CODE (FIND)  ( HERE, NFA ... PFA, LEN BYTE, TRUE; ELSE FALSE *)  1 19
     CODE ENCLOSE   ( ENTER WITH ADDRESS-2, DELIM-1.  RETURN WITH *)  1 20
        ( ADDR-4, AND OFFSET TO FIRST CH-3, END WORD-2, NEXT CH-1 *)  2 20
     CODE EMIT             ( PRINT ASCII VALUE ON BOTTOM OF STACK *)  5 21
     CODE KEY        ( ACCEPT ONE TERMINAL CHARACTER TO THE STACK *)  7 21
     CODE ?TERMINAL      ( 'BREAK' LEAVES 1 ON STACK; OTHERWISE 0 *)  9 21
     CODE CR         ( EXECUTE CAR. RETURN, LINE FEED ON TERMINAL *) 11 21
     CODE CMOVE   ( WITHIN MEMORY; ENTER W/  FROM-3, TO-2, QUAN-1 *)  1 22
     CODE U*        ( 16 BIT MULTIPLICAND-2,  16 BIT MULTIPLIER-1 *)  1 23
                  ( 32 BIT UNSIGNED PRODUCT: LO WORD-2, HI WORD-1 *)  2 23
     CODE U/          ( 31 BIT DIVIDEND-2, -3,  16 BIT DIVISOR-1  *)  1 24
                      ( 16 BIT REMAINDER-2,  16 BIT QUOTIENT-1    *)  2 24
     CODE AND           ( LOGICAL BITWISE AND OF BOTTOM TWO ITEMS *)  2 25
     CODE OR           ( LOGICAL BITWISE 'OR' OF BOTTOM TWO ITEMS *)  6 25
     CODE XOR        ( LOGICAL 'EXCLUSIVE-OR' OF BOTTOM TWO ITEMS *) 10 25
     CODE SP@                      ( FETCH STACK POINTER TO STACK *)  1 26
     CODE SP!                                 ( LOAD SP FROM 'S0' *)  5 26
     CODE RP!                                   ( LOAD RP FROM R0 *)  8 26
     CODE ;S              ( RESTORE IP REGISTER FROM RETURN STACK *) 12 26
     CODE LEAVE          ( FORCE EXIT OF DO-LOOP BY SETTING LIMIT *)  1 27
        XSAVE STX,  TSX,  R LDA,  R 2+ STA,            ( TO INDEX *)  2 27
     CODE >R              ( MOVE FROM COMP. STACK TO RETURN STACK *)  5 27
     CODE R>              ( MOVE FROM RETURN STACK TO COMP. STACK *)  8 27
     CODE R      ( COPY THE BOTTOM OF RETURN STACK TO COMP. STACK *) 11 27
     CODE 0=           ( REVERSE LOGICAL STATE OF BOTTOM OF STACK *)  2 28
     CODE 0<            ( LEAVE TRUE IF NEGATIVE; OTHERWISE FALSE *)  6 28
     CODE +         ( LEAVE THE SUM OF THE BOTTOM TWO STACK ITEMS *)  1 29
     CODE D+            ( ADD TWO DOUBLE INTEGERS, LEAVING DOUBLE *)  4 29
     CODE MINUS         ( TWOS COMPLEMENT OF BOTTOM SINGLE NUMBER *)  9 29
     CODE DMINUS        ( TWOS COMPLEMENT OF BOTTOM DOUBLE NUMBER *) 12 29
     CODE OVER              ( DUPLICATE SECOND ITEM AS NEW BOTTOM *)  1 30
     CODE DROP                           ( DROP BOTTOM STACK ITEM *)  4 30
     CODE SWAP        ( EXCHANGE BOTTOM AND SECOND ITEMS ON STACK *)  7 30
     CODE DUP                    ( DUPLICATE BOTTOM ITEM ON STACK *) 11 30
     CODE +!   ( ADD SECOND TO MEMORY 16 BITS ADDRESSED BY BOTTOM *)  2 31



                                     38








     CODE TOGGLE          ( BYTE AT ADDRESS-2, BIT PATTERN-1  ... *)  7 31
     CODE @                   ( REPLACE STACK ADDRESS WITH 16 BIT *)  1 32
         BOT X) LDA,  PHA,             ( CONTENTS OF THAT ADDRESS *)  2 32
     CODE C@      ( REPLACE STACK ADDRESS WITH POINTED 8 BIT BYTE *)  5 32
     CODE !         ( STORE SECOND AT 16 BITS ADDRESSED BY BOTTOM *)  8 32
     CODE C!           ( STORE SECOND AT BYTE ADDRESSED BY BOTTOM *) 12 32
     : :                  ( CREATE NEW COLON-DEFINITION UNTIL ';' *)  2 33
     : ;                             ( TERMINATE COLON-DEFINITION *)  9 33
     : CONSTANT              ( WORD WHICH LATER CREATES CONSTANTS *)  1 34
     : VARIABLE              ( WORD WHICH LATER CREATES VARIABLES *)  5 34
     : USER                                ( CREATE USER VARIABLE *) 10 34
     20 CONSTANT BL                             CR  ( ASCII BLANK *)  4 35
     40 CONSTANT C/L                   ( TEXT CHARACTERS PER LINE *)  5 35
     3BE0    CONSTANT   FIRST   ( FIRST BYTE RESERVED FOR BUFFERS *)  7 35
     4000    CONSTANT   LIMIT            ( JUST BEYOND TOP OF RAM *)  8 35
       80    CONSTANT   B/BUF            ( BYTES PER DISC BUFFER  *)  9 35
        8     CONSTANT  B/SCR  ( BLOCKS PER SCREEN = 1024 B/BUF / *) 10 35
     : +ORIGIN  LITERAL  +  ; ( LEAVES ADDRESS RELATIVE TO ORIGIN *) 13 35
     HEX              ( 0 THRU 5 RESERVED,    REFERENCED TO $00A0 *)  1 36
     ( 06 USER  S0 )             ( TOP OF EMPTY COMPUTATION STACK *)  2 36
     ( 08 USER  R0 )                  ( TOP OF EMPTY RETURN STACK *)  3 36
     0A   USER  TIB                       ( TERMINAL INPUT BUFFER *)  4 36
     0C   USER  WIDTH                  ( MAXIMUM NAME FIELD WIDTH *)  5 36
     0E   USER  WARNING                   ( CONTROL WARNING MODES *)  6 36
     10   USER  FENCE              CR    ( BARRIER FOR FORGETTING *)  7 36
     12   USER  DP                           ( DICTIONARY POINTER *)  8 36
     14   USER  VOC-LINK                   ( TO NEWEST VOCABULARY *)  9 36
     16   USER  BLK                        ( INTERPRETATION BLOCK *) 10 36
     18   USER  IN                      ( OFFSET INTO SOURCE TEXT *) 11 36
     1A   USER  OUT                     ( DISPLAY CURSOR POSITION *) 12 36
     1C   USER  SCR                              ( EDITING SCREEN *) 13 36
     1E   USER  OFFSET                 ( POSSIBLY TO OTHER DRIVES *)  1 37
     20   USER  CONTEXT               ( VOCABULARY FIRST SEARCHED *)  2 37
     22   USER  CURRENT          ( SEARCHED SECOND, COMPILED INTO *)  3 37
     24   USER  STATE                         ( COMPILATION STATE *)  4 37
     26   USER  BASE             CR    ( FOR NUMERIC INPUT-OUTPUT *)  5 37
     28   USER  DPL                      ( DECIMAL POINT LOCATION *)  6 37
     2A   USER  FLD                          ( OUTPUT FIELD WIDTH *)  7 37
     2C   USER  CSP                        ( CHECK STACK POSITION *)  8 37
     2E   USER  R#                     (  EDITING CURSOR POSITION *)  9 37
     30   USER  HLD        ( POINTS TO LAST CHARACTER HELD IN PAD *) 10 31
     : 1+      1   +  ;           ( INCREMENT STACK NUMBER BY ONE *)  1 38
     : 2+      2   +  ;           ( INCREMENT STACK NUMBER BY TWO *)  2 38
     : HERE    DP @ ;          ( FETCH NEXT FREE ADDRESS IN DICT. *)  3 38
     : ALLOT   DP +! ;                 ( MOVE DICT. POINTER AHEAD *)  4 38
     : ,   HERE  !  2  ALLOT  ;  CR ( ENTER STACK NUMBER TO DICT. *)  5 38
     : C,   HERE  C!  1   ALLOT  ;    ( ENTER STACK BYTE TO DICT. *)  6 38
     : -   MINUS  +  ;                 ( LEAVE DIFF. SEC - BOTTOM *)  7 38
     : =   -  0=  ;                   ( LEAVE BOOLEAN OF EQUALITY *)  8 38
     : <   -  0<  ;                  ( LEAVE BOOLEAN OF SEC < BOT *)  9 38
     : >   SWAP  < ;                 ( LEAVE BOOLEAN OF SEC > BOT *) 10 38
     : ROT   >R  SWAP  R>  SWAP  ;       ( ROTATE THIRD TO BOTTOM *) 11 38
     : SPACE     BL  EMIT  ;   CR       ( PRINT BLANK ON TERMINAL *) 12 38
     : -DUP     DUP  IF  DUP  ENDIF  ;       ( DUPLICATE NON-ZERO *) 13 38



                                     39








     : TRAVERSE                          ( MOVE ACROSS NAME FIELD *)  1 39
              ( ADDRESS-2, DIRECTION-1, I.E. -1=R TO L, +1=L TO R *)  2 39
     : LATEST       CURRENT  @  @  ;         ( NFA OF LATEST WORD *)  6 39
     : LFA    4  -  ;                ( CONVERT A WORDS PFA TO LFA *) 11 39
     : CFA    2  -  ;   CR           ( CONVERT A WORDS PFA TO CFA *) 12 39
     : NFA    5  -  -1  TRAVERSE  ;  ( CONVERT A WORDS PFA TO NFA *) 13 39
     : PFA     1  TRAVERSE  5  +  ;  ( CONVERT A WORDS NFA TO PFA *) 14 39
     : !CSP     SP@  CSP  !  ;     ( SAVE STACK POSITION IN 'CSP' *)  1 40
     : ?ERROR          ( BOOLEAN-2,  ERROR TYPE-1,  WARN FOR TRUE *)  3 40
     : ?COMP   STATE @  0= 11 ?ERROR ;   ( ERROR IF NOT COMPILING *)  6 40
     : ?EXEC   STATE  @  12  ?ERROR  ;   ( ERROR IF NOT EXECUTING *)  8 40
     : ?PAIRS  -  13  ?ERROR  ;  ( VERIFY STACK VALUES ARE PAIRED *) 10 40
     : ?CSP   SP@  CSP @ -  14  ?ERROR  ; ( VERIFY STACK POSITION *) 12 40
     : ?LOADING                        ( VERIFY LOADING FROM DISC *) 14 40
     : COMPILE          ( COMPILE THE EXECUTION ADDRESS FOLLOWING *)  2 41
     : [    0  STATE  !  ;  IMMEDIATE          ( STOP COMPILATION *)  5 41
     : ]    C0  STATE  !  ;             ( ENTER COMPILATION STATE *)  7 41
     : SMUDGE    LATEST  20  TOGGLE  ;   ( ALTER LATEST WORD NAME *)  9 41
     : HEX      10  BASE  !  ;         ( MAKE HEX THE IN-OUT BASE *) 11 41
     : DECIMAL  0A  BASE  !  ;     ( MAKE DECIMAL THE IN-OUT BASE *) 13 41
     : (;CODE)     ( WRITE CODE FIELD POINTING TO CALLING ADDRESS *)  2 42
     : ;CODE                      ( TERMINATE A NEW DEFINING WORD *)  6 42
     : <BUILDS   0  CONSTANT  ;  ( CREATE HEADER FOR 'DOES>' WORD *)  2 43
     : DOES>          ( REWRITE PFA WITH CALLING HI-LEVEL ADDRESS *)  4 43
                                  ( REWRITE CFA WITH 'DOES>' CODE *)  5 43
     : COUNT    DUP 1+ SWAP C@  ;  ( LEAVE TEXT ADDR. CHAR. COUNT *)  1 44
     : TYPE            ( TYPE STRING FROM ADDRESS-2, CHAR.COUNT-1 *)  2 44
     : -TRAILING     ( ADJUST CHAR. COUNT TO DROP TRAILING BLANKS *)  5 44
     : (.")               ( TYPE IN-LINE STRING, ADJUSTING RETURN *)  8 44
     : ."     22  STATE  @       ( COMPILE OR PRINT QUOTED STRING *) 12 44
     : EXPECT             ( TERMINAL INPUT MEMORY-2, CHAR LIMIT-1 *)  2 45
     : X   BLK @                            ( END-OF-TEXT IS NULL *) 11 45
     : FILL                 ( FILL MEMORY BEGIN-3, QUAN-2, BYTE-1 *)  1 46
     : ERASE             ( FILL MEMORY WITH ZEROS BEGIN-2, QUAN-1 *)  4 46
     : BLANKS                  ( FILL WITH BLANKS BEGIN-2, QUAN-1 *)  7 46
     : HOLD                               ( HOLD CHARACTER IN PAD *) 10 46
     : PAD        HERE  44  +  ;     ( PAD IS 68 BYTES ABOVE HERE *) 13 46
             ( DOWNWARD HAS NUMERIC OUTPUTS; UPWARD MAY HOLD TEXT *) 14 46
     : WORD         ( ENTER WITH DELIMITER, MOVE STRING TO 'HERE' *)  1 47
     : (NUMBER)    ( CONVERT DOUBLE NUMBER, LEAVING UNCONV. ADDR. *)  1 48
     : NUMBER         ( ENTER W/ STRING ADDR. LEAVE DOUBLE NUMBER *)  6 48
     : -FIND       ( RETURN PFA-3, LEN BYTE-2, TRUE-1; ELSE FALSE *) 12 48
     : (ABORT)    GAP  ( ABORT )  ;  ( USER ALTERABLE ERROR ABORT *)  2 49
     : ERROR               ( WARNING: -1=ABORT, 0=NO DISC, 1=DISC *)  4 49
         WARNING  @  0<           ( PRINT TEXT LINE REL TO SCR #4 *)  5 49
     : ID.             ( PRINT NAME FIELD FROM ITS HEADER ADDRESS *)  9 49
     : CREATE              ( A SMUDGED CODE HEADER TO PARAM FIELD *)  2 50
                          ( WARNING IF DUPLICATING A CURRENT NAME *)  3 50
     : [COMPILE]         ( FORCE COMPILATION OF AN IMMEDIATE WORD *)  2 51
     : LITERAL                     ( IF COMPILING, CREATE LITERAL *)  5 51
     : DLITERAL             ( IF COMPILING, CREATE DOUBLE LITERAL *)  8 51
     : ?STACK          ( QUESTION UPON OVER OR UNDERFLOW OF STACK *) 13 51
     : INTERPRET   ( INTERPRET OR COMPILE SOURCE TEXT INPUT WORDS *)  2 52
     : IMMEDIATE        ( TOGGLE PREC. BIT OF LATEST CURRENT WORD *)  1 53



                                     40








     : VOCABULARY  ( CREATE VOCAB WITH 'V-HEAD' AT VOC INTERSECT. *)  4 53
     VOCABULARY  FORTH     IMMEDIATE       ( THE TRUNK VOCABULARY *)  9 53
     : DEFINITIONS        ( SET THE CONTEXT ALSO AS CURRENT VOCAB *) 11 53
     : (                ( SKIP INPUT TEXT UNTIL RIGHT PARENTHESIS *) 14 53
     : QUIT                    ( RESTART, INTERPRET FROM TERMINAL *)  2 54
     : ABORT                  ( WARM RESTART, INCLUDING REGISTERS *)  7 54
     CODE COLD               ( COLD START, INITIALIZING USER AREA *)  1 55
     CODE S->D                  ( EXTEND SINGLE INTEGER TO DOUBLE *)  1 56
     : +-    0< IF MINUS ENDIF ;   ( APPLY SIGN TO NUMBER BENEATH *)  4 56
     : D+-                  ( APPLY SIGN TO DOUBLE NUMBER BENEATH *)  6 56
     : ABS     DUP  +-   ;                 ( LEAVE ABSOLUTE VALUE *)  9 56
     : DABS    DUP  D+-  ;        ( DOUBLE INTEGER ABSOLUTE VALUE *) 10 56
     : MIN                         ( LEAVE SMALLER OF TWO NUMBERS *) 12 56
     : MAX                          ( LEAVE LARGER OF TWO NUMBERS *) 14 56
     : M*     ( LEAVE SIGNED DOUBLE PRODUCT OF TWO SINGLE NUMBERS *)  1 57
     : M/              ( FROM SIGNED DOUBLE-3-2, SIGNED DIVISOR-1 *)  3 57
                    ( LEAVE SIGNED REMAINDER-2, SIGNED QUOTIENT-1 *)  4 57
     : *      U*  DROP  ;                        ( SIGNED PRODUCT *)  7 57
     : /MOD   >R  S->D  R>  M/  ;           ( LEAVE REM-2, QUOT-1 *)  8 57
     : /      /MOD  SWAP  DROP  ;                ( LEAVE QUOTIENT *)  9 57
     : MOD    /MOD  DROP  ;     CR              ( LEAVE REMAINDER *) 10 57
     : */MOD              ( TAKE RATION OF THREE NUMBERS, LEAVING *) 11 57
              >R  M*  R>  M/  ;               ( REM-2, QUOTIENT-1 *) 12 57
     : */     */MOD  SWAP  DROP ;    ( LEAVE RATIO OF THREE NUMBS *) 13 57
     : M/MOD      ( DOUBLE, SINGLE DIVISOR ...  REMAINDER, DOUBLE *) 14 57
     FIRST  VARIABLE  USE           ( NEXT BUFFER TO USE, STALEST *)  1 58
     FIRST  VARIABLE  PREV      ( MOST RECENTLY REFERENCED BUFFER *)  2 58
     : +BUF     ( ADVANCE ADDRESS-1 TO NEXT BUFFER. RETURNS FALSE *)  4 58
           84 ( I.E. B/BUF+4 )  +  DUP  LIMIT  =     ( IF AT PREV *)  5 58
     : UPDATE     ( MARK THE BUFFER POINTED TO BY PREV AS ALTERED *)  8 58
     : EMPTY-BUFFERS   ( CLEAR BLOCK BUFFERS; DON'T WRITE TO DISC *) 11 58
     : DR0      0  OFFSET  !  ;                 ( SELECT DRIVE #0 *) 14 58
     : DR1   07D0  OFFSET  !  ;                 ( SELECT DRIVE #1 *) 15 58
     : BUFFER                 ( CONVERT BLOCK# TO STORAGE ADDRESS *)  1 59
     : BLOCK         ( CONVERT BLOCK NUMBER TO ITS BUFFER ADDRESS *)  1 60
     : (LINE)        ( LINE#, SCR#, ...  BUFFER ADDRESS, 64 COUNT *)  2 61
     : .LINE                        ( LINE#,  SCR#,  ...  PRINTED *)  6 61
     : MESSAGE      ( PRINT LINE RELATIVE TO SCREEN #4 OF DRIVE 0 *)  9 61
     : LOAD                         ( INTERPRET SCREENS FROM DISC *)  2 62
     : -->               ( CONTINUE INTERPRETATION ON NEXT SCREEN *)  6 62
     6900    CONSTANT  DATA                     ( CONTROLLER PORT *)  1 65
     6901    CONSTANT  STATUS                   ( CONTROLLER PORT *)  2 65
     : #HL            ( CONVERT DECIMAL DIGIT FOR DISC CONTROLLER *)  5 65
     CODE D/CHAR      ( TEST CHAR-1. EXIT TEST BOOL-2, NEW CHAR-1 *)  1 66
     : ?DISC         ( UPON NAK SHOW ERR MSG, QUIT.  ABSORBS TILL *)  7 66
           1  D/CHAR  >R  0=                ( EOT, EXCEPT FOR SOH *)  8 66
     CODE BLOCK-WRITE     ( SEND TO DISC FROM ADDRESS-2,  COUNT-1 *)  1 67
           2 # LDA,  SETUP JSR,                 ( WITH EOT AT END *)  2 67
     CODE BLOCK-READ    ( BUF.ADDR-1. EXIT AT 128 CHAR OR CONTROL *)  2 68
                                      ( C = 1 TO READ, 0 TO WRITE *)  3 69
     : R/W                                ( READ/WRITE DISC BLOCK *)  4 69
                    ( BUFFER ADDRESS-3, BLOCK #-2, 1-READ 0-WRITE *)  5 69
     : '          ( FIND NEXT WORDS PFA; COMPILE IT, IF COMPILING *)  2 72
     : FORGET            ( FOLLOWING WORD FROM CURRENT VOCABULARY *)  6 72



                                     41








     : \           ( SKIP INTERPRETATION OF THE REMAINDER OF LINE *) 11 72
     : BACK     HERE  -  ,  ;           ( RESOLVE BACKWARD BRANCH *)  1 73
     : D.R        ( DOUBLE INTEGER OUTPUT, RIGHT ALIGNED IN FIELD *)  1 76
     : D.     0  D.R  SPACE  ;            ( DOUBLE INTEGER OUTPUT *)  5 76
     : .R     >R  S->D  R>  D.R  ;       ( ALIGNED SINGLE INTEGER *)  7 76
     : .      S->D  D.  ;                 ( SINGLE INTEGER OUTPUT *)  9 76
     : ?      @  .  ;                  ( PRINT CONTENTS OF MEMORY *) 11 76
     : LIST                      ( LIST SCREEN BY NUMBER ON STACK *)  2 77
     : INDEX       ( PRINT FIRST LINE OF EACH SCREEN FROM-2, TO-1 *)  7 77
     : TRIAD     ( PRINT 3 SCREENS ON PAGE, CONTAINING # ON STACK *) 12 77
     : VLIST                            ( LIST CONTEXT VOCABULARY *)  2 78
     CREATE MON          ( CALL MONITOR, SAVING RE-ENTRY TO FORTH *)  3 79













































                                     42









                          FORTH MODEL IMPLEMENTATION


     This model is presented for the serious student as both an example 
     of a large FORTH program and as a complete nucleus of FORTH.  That 
     is, it is sufficient to run and to continue to compile itself.

     When compiled, the model requires about 2800 bytes of memory.  An 
     expanded version with formatted output and compiling aids would 
     require about 4000 bytes.  A 'full' implementation usually requires 
     6000 to 7000 bytes (including editor, assembler, and disk 
     interface).

     The following information consists of word definitions you will find 
     in the CODE definitions.  These are dependent on the micro-computer 
     used, these being for the MOS Technology 6502.

     Note that the notation in the CODE definitions is 'reverse Polish' 
     as is all of FORTH.  This means that the operand comes before the 
     operator.  Each equivalent of a 'line' of assembly code has a 
     symbolic operand, then any address mode modifier, and finally the 
     op-code mnemonic.  (Note that words that generate actual machine 
     code end in a ',' ;   i.e.  LDA, ).  Therefore:

               BOT 1+ LDA,         in FORTH would be:

               LDA 1,X             in usual assembler.

     And also:

               POINTER  )Y  STA,   in FORTH would be:

               STA  (POINTER),Y    in usual assembler.

     It takes a bit of getting used to, but reverse Polish assembler 
     allows full use of FORTH in evaluation of expressions and the easy 
     generation of the equivalent of macros.


                           GLOSSARY OF FORTH MODEL


      IP       address of the Interpretive Pointer in zero-page.

      W        address of the code field pointer in zero-page.

      N        address of an 8 byte scratch area in zero-page.

      XSAVE    address of a temporary register for X in zero-page.

      UP       address of the User Pointer in zero-page.

      .A       specify accumulator address mode.



                                     43








      #        specify immediate mode for machine byte literals.

      ,X  ,Y   specify memory indexed address mode.

      X)  )Y   specify indirect memory reference by a zero-page register.

      BOT      address of low  byte of a 16-bit stack item with
                   ,X address mode.  X register locates computation
                   stack in zero-page, relative to address $0000.

      BOT 1+   address of the high byte of the bottom stack item
                   with ,X mode  preset.

      SEC and SEC 1+   address the second stack item as for BOT.

      TSX,     move the return stack pointer (which is located in
                   the CPU machine stack in page-one) to X register.

      R        address of low byte of return stack with ,X mode preset.

      R n +    address of the n-th byte of the return stack with ,X
                   mode preset.  Note that the low byte is at low
                   memory, so 1+ gets the high byte, and 3 + gets
                   the high byte of the second item of return stack.

      PUT      address of routine to replace the present computation
                   stack high byte from accumulator, and put from
                   the machine stack one byte which replaces the
                   present low stack byte; continue on to NEXT.

      PUSH     address of routine to repeat PUT but creating a new
                   bottom item on the computation stack.

      PUSH0A  PUT0A   address of routine to place the accumulator
                   at the low stack byte, with the high byte zero.
                   PUT0A over-writes, while PUSH0A creates new item.

      POP  POPTWO   address of routine to remove one or two 16-bit
                   items from computation stack.

      BINARY   address of routine to pop one item and PUT the accumulator
                   (high) and ML stack (low) over what was second.

      SETUP    address of a routine to move 16-bit items to zero-page.
                   Item quantity is in accumulator.

      NEXT     address of the inner-interpreter, to which all
                   code routines must return.  NEXT fetches
                   indirectly referred to IP the next compiled
                   FORTH word address.  It then jumps indirectly
                   to pointed machine code.






                                     44








     SCR # 6
       0 (  INPUT-OUTPUT,  TIM                              WFR-780519 )
       1 CODE EMIT   XSAVE STX,  BOT 1+ LDA,  7F # AND,
       2             72C6 JSR,  XSAVE LDX,  POP JMP,
       3 CODE KEY   XSAVE STX,  BEGIN,  BEGIN,  8 # LDX,
       4       BEGIN,  6E02 LDA,  .A LSR,  CS END,  7320 JSR,
       5       BEGIN,  731D JSR,  0 X) CMP,  0 X) CMP,  0 X) CMP,
       6       0 X) CMP,  0 X) CMP,  6E02 LDA,  .A LSR,  PHP,  TYA,
       7       .A LSR,  PLP,  CS IF,  80 # ORA,  THEN,  TAY,  DEX,
       8       0= END,  731D JSR,  FF # EOR,  7F # AND,  0= NOT END,
       9       7F # CMP,  0= NOT END,  XSAVE LDX,  PUSH0A JMP,
      10 CODE CR  XSAVE STX,  728A JSR,  XSAVE LDX, NEXT JMP,
      11
      12 CODE ?TERMINAL   1 # LDA,  6E02 BIT,  0= NOT IF,
      13      BEGIN,  731D JSR,  6E02 BIT,  0= END,  INY,  THEN,
      14      TYA,  PUSH0A  JMP,
      15 DECIMAL       ;S

     SCR # 7
       0 (  INPUT-OUTPUT,  APPLE                            WPR-780730 )
       1 CODE HOME   FC58 JSR,  NEXT JMP,
       2 CODE SCROLL   FC70 JSR,  NEXT JMP,
       3
       4 HERE  '  KEY  2  -  !    ( POINT KEY TO HERE )
       5    FD0C JSR,  7F # AND,  PUSH0A JMP,
       6 HERE  ' EMIT  2  -  !   (  POINT EMIT TO HERE  )
       7    BOT 1+ LDA,  80 # ORA,  FDED JSR,  POP JMP,
       8 HERE  '  CR  2  -  !      ( POINT CR TO HERE )
       9     FD8E JSR,  NEXT JMP,
      10 HERE  '  ?TERMINAL  2  -  !   ( POINT ?TERM TO HERE )
      11    C000 BIT,  0<
      12       IF,  BEGIN,  C010 BIT,  C000 BIT,  0< NOT END,  INY,
      13         THEN,  TYA,  PUSH0A JMP,
      14
      15 DECIMAL    ;S

     SCR # 8
       0 (  INPUT-OUTPUT,  SYM-1                            WFR-781015 )
       1 HEX
       2 CODE KEY    8A58 JSR,  7F # AND,  PUSH0A JMP,
       3
       4 CODE EMIT   BOT 1+ LDA,    8A47 JSR,  POP JMP,
       5
       6 CODE CR    834D JSR,  NEXT JMP,
       7
       8 CODE ?TERMINAL  ( BREAK TEST FOR ANY KEY )
       9     8B3C JSR,  CS
      10     IF,  BEGIN,  8B3C JSR,  CS NOT  END,  INY,  THEN,
      11            TYA,  PUSH0A  JMP,
      12
      13
      14
      15 DECIMAL    ;S

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     45








     SCR # 12
       0 (  COLD AND WARM ENTRY,  USER PARAMETERS          WFR-79APR29 )
       1 ASSEMBLER   OBJECT  MEM  HEX
       2 NOP,   HERE JMP,   ( WORD ALIGNED VECTOR TO COLD )
       3 NOP,   HERE JMP,   ( WORD ALIGNED VECTOR TO WARM )
       4 0000 ,   0001 ,  ( CPU, AND REVISION PARAMETERS )
       5 0000 ,          ( TOPMOST WORD IN FORTH VOCABULARY )
       6   7F ,          ( BACKSPACE CHARACTER )
       7 3BA0 ,          ( INITIAL USER AREA )
       8 009E ,          ( INITIAL TOP OF STACK )
       9 01FF ,          ( INITIAL TOP OF RETURN STACK )
      10 0100 ,          ( TERMINAL INPUT BUFFER )
      11 001F ,          ( INITIAL NAME FIELD WIDTH )
      12 0001 ,          ( INITIAL WARNING = 1 )
      13 0200 ,          ( INITIAL FENCE )
      14 0000 ,          ( COLD START VALUE FOR DP )
      15 0000 ,          ( COLD START VALUE FOR VOC-LINK )  -->

     SCR # 13
       0 (  START OF NUCLEUS,  LIT, PUSH, PUT, NEXT        WFR-78DEC26 )
       1 CODE LIT                   ( PUSH FOLLOWING LITERAL TO STACK *)
       2      IP )Y LDA,  PHA,  IP INC,  0= IF,  IP 1+ INC,  THEN,
       3      IP )Y LDA,        IP INC,  0= IF,  IP 1+ INC,  THEN,
       4 LABEL PUSH      ( PUSH ACCUM AS HI-BYTE, ML STACK AS LO-BYTE *)
       5      DEX,  DEX,
       6 LABEL PUT          ( REPLACE BOTTOM WITH ACCUM. AND ML STACK *)
       7      BOT 1+ STA,  PLA,  BOT STA,
       8 LABEL NEXT           ( EXECUTE NEXT FORTH ADDRESS, MOVING IP *)
       9      1 # LDY,  IP )Y LDA,  W 1+ STA,     ( FETCH CODE ADDRESS )
      10          DEY,  IP )Y LDA,  W    STA,
      11      CLC,  IP LDA,  2 # ADC,  IP STA,         ( MOVE IP AHEAD )
      12      CS IF,  IP 1+ INC,  THEN,
      13      W 1 - JMP,   ( JUMP INDIR. VIA W THRU CODE FIELD TO CODE )
      14
      15 -->

     SCR # 14
       0 (  SETUP                                           WFR-790225 )
       1                     HERE  2+  ,           ( MAKE SILENT WORD *)
       2      IP )Y LDA,  PHA,  TYA,  'T LIT 0B +  0=  NOT  END,
       3
       4 LABEL SETUP  ( MOVE # ITEMS FROM STACK TO 'N' AREA OF Z-PAGE *)
       5     .A ASL,  N 1 - STA,
       6     BEGIN,  BOT LDA,  N ,Y STA,  INX,  INY,
       7          N 1 - CPY,  0= END,  0 # LDY,  RTS,
       8
       9 CODE EXECUTE              ( EXECUTE A WORD BY ITS CODE FIELD *)
      10                                       ( ADDRESS ON THE STACK *)
      11    BOT LDA,  W STA,  BOT 1+ LDA,  W 1+ STA,
      12    INX,  INX,  W 1 - JMP,
      13
      14
      15 -->

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     46








     SCR # 15
       0 (  BRANCH, 0BRANCH     W/16-BIT OFFSET            WFR-79APR01 )
       1 CODE BRANCH            ( ADJUST IP BY IN-LINE 16 BIT LITERAL *)
       2    CLC,  IP )Y LDA,  IP    ADC,        PHA,
       3    INY,  IP )Y LDA,  IP 1+ ADC,  IP 1+ STA,
       4                            PLA,  IP    STA,  NEXT 2+ JMP,
       5
       6 CODE 0BRANCH           ( IF BOT IS ZERO, BRANCH FROM LITERAL *)
       7    INX,  INX,  FE ,X LDA,  FF ,X ORA,
       8    '  BRANCH  0= NOT END,  ( USE 'BRANCH' FOR FALSE )
       9  LABEL BUMP:                    ( TRUE JUST MOVES IP 2 BYTES *)
      10    CLC,  IP LDA,  2 # ADC,  IP STA,
      11    CS IF,  IP 1+ INC, THEN,  NEXT JMP,
      12
      13 -->
      14
      15

     SCR # 16
       0 (  LOOP CONTROL                                   WFR-79MAR20 )
       1 CODE (LOOP)      ( INCREMENT LOOP INDEX, LOOP UNTIL => LIMIT *)
       2     XSAVE STX,  TSX,  R INC,  0= IF,  R 1+ INC,  THEN,
       3   LABEL L1:  CLC,  R 2+ LDA,  R SBC,  R 3 + LDA,  R 1+ SBC,
       4   LABEL L2:    XSAVE LDX,      ( LIMIT-INDEX-1 )
       5     .A ASL, '  BRANCH  CS END, ( BRANCH UNTIL D7 SIGN=1 )
       6     PLA,  PLA,  PLA,  PLA,  BUMP: JMP,  ( ELSE EXIT LOOP )
       7
       8 CODE (+LOOP)          ( INCREMENT INDEX BY STACK VALUE +/-   *)
       9     INX,  INX,  XSAVE STX,  ( POP INCREMENT )
      10     FF ,X LDA,  PHA,  PHA,  FE ,X LDA,  TSX,  INX,  INX,
      11     CLC,  R ADC,  R STA,  PLA,  R 1 + ADC,  R 1 + STA,
      12     PLA,  L1:  0< END,     ( AS FOR POSITIVE INCREMENT )
      13     CLC,  R    LDA,  R 2+  SBC, ( INDEX-LIMIT-1 )
      14           R 1+ LDA,  R 3 + SBC,    L2: JMP,
      15 -->

     SCR # 17
       0 (  (DO-                                           WFR-79MAR30 )
       1
       2 CODE (DO)             ( MOVE TWO STACK ITEMS TO RETURN STACK *)
       3    SEC 1+ LDA,  PHA,  SEC LDA,  PHA,
       4    BOT 1+ LDA,  PHA,  BOT LDA,  PHA,
       5
       6 LABEL POPTWO    INX,  INX,
       7 LABEL POP       INX,  INX,  NEXT JMP,
       8
       9 CODE I                    ( COPY CURRENT LOOP INDEX TO STACK *)
      10                           ( THIS WILL LATER BE POINTED TO 'R' )
      11
      12 -->
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     47








     SCR # 18
       0 (  DIGIT                                           WFR-781202 )
       1 CODE DIGIT     ( CONVERT ASCII CHAR-SECOND, WITH BASE-BOTTOM *)
       2                    ( IF OK RETURN DIGIT-SECOND, TRUE-BOTTOM; *)
       3                                    ( OTHERWISE FALSE-BOTTOM. *)
       4   SEC,  SEC LDA,   30 # SBC,
       5   0< NOT IF,  0A # CMP, ( ADJUST FOR ASCII LETTER )
       6             0< NOT IF,  SEC,  07 # SBC,  0A # CMP,
       7                        0< NOT IF,
       8  SWAP ( AT COMPILE TIME )  THEN,  BOT CMP, ( TO BASE )
       9                       0< IF,  SEC STA,  1 # LDA,
      10                       PHA,  TYA,  PUT JMP,
      11                       ( STORE RESULT SECOND AND RETURN TRUE )
      12    THEN,  THEN,  THEN,   ( CONVERSION FAILED )
      13    TYA,  PHA,  INX,  INX,  PUT JMP,  ( LEAVE BOOLEAN FALSE )
      14
      15 -->

     SCR # 19
       0 (  FIND FOR VARIABLE LENGTH NAMES                  WFR-790225 )
       1 CODE (FIND)  ( HERE, NFA ... PFA, LEN BYTE, TRUE; ELSE FALSE *)
       2      2 # LDA,  SETUP JSR,  XSAVE STX,
       3 BEGIN,  0 # LDY,  N )Y LDA,  N 2+ )Y EOR,  3F # AND,  0=
       4    IF, ( GOOD ) BEGIN, INY, N )Y LDA,  N 2+ )Y EOR,  .A ASL,  0=
       5           IF, ( STILL GOOD ) SWAP  CS ( LOOP TILL D7 SET )
       6       END,    XSAVE LDX,  DEX,  DEX,  DEX,  DEX,  CLC,
       7               TYA,  5 # ADC,  N ADC,  SEC STA,  0 # LDY,
       8         TYA,   N 1+ ADC,  SEC 1+ STA,  BOT 1+ STY,
       9      N )Y LDA,  BOT STA,  1 # LDA,  PHA,  PUSH JMP, ( FALSE )
      10      THEN,  CS  NOT ( AT LAST CHAR? )  IF,  SWAP  THEN,
      11     BEGIN,  INY,  N )Y LDA,  0< END, ( TO LAST CHAR )
      12   THEN,  INY,  ( TO LINK )  N )Y LDA,  TAX,  INY,
      13          N )Y LDA,  N 1+ STA,  N STX,  N ORA, ( 0 LINK ? )
      14     0= END, ( LOOP FOR ANOTHER NAME )
      15     XSAVE LDX,  0 # LDA, PHA,  PUSH JMP, ( FALSE )   -->

     SCR # 20
       0 (  ENCLOSE                                         WFR-780926 )
       1 CODE ENCLOSE   ( ENTER WITH ADDRESS-2, DELIM-1.  RETURN WITH *)
       2    ( ADDR-4, AND OFFSET TO FIRST CH-3, END WORD-2, NEXT CH-1 *)
       3   2 # LDA,  SETUP JSR,  TXA,  SEC,  8 # SBC,  TAX,
       4   SEC 1+ STY,  BOT 1+ STY,  ( CLEAR HI BYTES )   DEY,
       5   BEGIN,  INY,  N 2+ )Y LDA,  ( FETCH CHAR )
       6      N CMP,  0=  NOT END,  ( STEP OVER LEADING DELIMITERS )
       7   BOT 4 + STY,  ( SAVE OFFSET TO FIRST CHAR )
       8   BEGIN,  N 2+ )Y LDA,  0=
       9       IF, ( NULL )  SEC STY, ( IN EW )  BOT STY,  ( IN NC )
      10             TYA,  BOT 4 + CMP,  0=
      11           IF, ( Y=FC )  SEC INC, ( BUMP EW )  THEN,  NEXT JMP,
      12        THEN,  SEC STY,  ( IN EW )  INY,  N CMP, ( DELIM ? )
      13      0= END,  ( IS DELIM )  BOT STY, ( IN NC )  NEXT JMP,
      14
      15 -->

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     48








     SCR # 21
       0 (  TERMINAL VECTORS                               WFR-79MAR30 )
       1 (  THESE WORDS ARE CREATED WITH NO EXECUTION CODE, YET.
       2 (  THEIR CODE FIELDS WILL BE FILLED WITH THE ADDRESS OF THEIR )
       3 (  INSTALLATION SPECIFIC CODE.
       4
       5 CODE EMIT             ( PRINT ASCII VALUE ON BOTTOM OF STACK *)
       6
       7 CODE KEY        ( ACCEPT ONE TERMINAL CHARACTER TO THE STACK *)
       8
       9 CODE ?TERMINAL      ( 'BREAK' LEAVES 1 ON STACK; OTHERWISE 0 *)
      10
      11 CODE CR         ( EXECUTE CAR. RETURN, LINE FEED ON TERMINAL *)
      12
      13 -->
      14
      15

     SCR # 22
       0 (  CMOVE,                                         WFR-79MAR20 )
       1 CODE CMOVE    ( WITHIN MEMORY; ENTER W/ FROM-3, TO-2, QUAN-1 *)
       2   3 # LDA,   SETUP JSR,        ( MOVE 3 ITEMS TO 'N' AREA )
       3   BEGIN,  BEGIN,  N CPY,  0=  ( DECREMENT BYTE COUNTER AT 'N' )
       4              IF,  N 1+ DEC,  0<         ( EXIT WHEN DONE )
       5                   IF,  NEXT JMP,  THEN,  THEN,
       6          N 4 + )Y LDA,  N 2+ )Y STA,  INY,  0=
       7       END,          ( LOOP TILL Y WRAPS, 22 CYCLES/BYTE  )
       8       N 5 + INC,  N 3 + INC,      ( BUMP HI BYTES OF POINTERS
       9     JMP, ( BACK TO FIRST 'BEGIN' )
      10
      11 -->
      12
      13
      14
      15

     SCR # 23
       0 (  U*,  UNSIGNED MULTIPLY FOR 16 BITS          RS-WFR-80AUG16 )
       1 CODE U*       ( 16 BIT MULTIPLICAND-2,   16 BIT MULTIPLIER-1 *)
       2              ( 32 BIT UNSIGNED PRODUCT: LO WORD-2, HI WORD-1 *)
       3    SEC    LDA,  N    STA,  SEC    STY,
       4    SEC 1+ LDA,  N 1+ STA,  SEC 1+ STY,  ( multiplicand to n )
       5    10 # LDY,
       6    BEGIN,  BOT 2+ ASL,  BOT 3 + ROL,  BOT ROL,  BOT 1+ ROL,
       7             ( double product while sampling D15 of multiplier )
       8          CS IF, ( set ) CLC,
       9             ( add multiplicant to partial product 32 bits )
      10                N    LDA,  BOT 2 + ADC,  BOT 2 + STA,
      11                N 1+ LDA,  BOT 3 + ADC,  BOT 3 + STA,
      12              CS IF,  BOT INC,  0= IF,  BOT 1+ INC, ENDIF, ENDIF,
      13            ENDIF,  DEY,  0=    ( corrected for carry bug )
      14       UNTIL,      NEXT JMP,   C;
      15 -->

     FORTH INTEREST GROUP                              Aug 23, 1980


                                     49








     SCR # 24
       0 (  U/,  UNSIGNED DIVIDE FOR 31 BITS               WFR-79APR29 )
       1 CODE  U/         ( 31 BIT DIVIDEND-2, -3,  16 BIT DIVISOR-1  *)
       2                  ( 16 BIT REMAINDER-2,  16 BIT QUOTIENT-1    *)
       3   SEC 2 + LDA,  SEC     LDY,  SEC 2 + STY,  .A ASL,  SEC    STA,
       4   SEC 3 + LDA,  SEC 1+  LDY,  SEC 3 + STY,  .A ROL,  SEC 1+ STA,
       5   10 # LDA,  N STA,
       6   BEGIN,  SEC 2 + ROL,  SEC 3 + ROL,  SEC,
       7           SEC 2 + LDA, BOT      SBC,  TAY,
       8           SEC 3 + LDA, BOT 1+   SBC,
       9           CS IF,  SEC 2+ STY,  SEC 3 + STA,  THEN,
      10           SEC ROL,  SEC 1+ ROL,
      11           N DEC,  0=
      12       END,    POP  JMP,
      13 -->
      14
      15

     SCR # 25
       0 (  LOGICALS                                       WFR-79APR20 )
       1
       2 CODE AND           ( LOGICAL BITWISE AND OF BOTTOM TWO ITEMS *)
       3    BOT    LDA,  SEC    AND,  PHA,
       4    BOT 1+ LDA,  SEC 1+ AND,  INX,  INX,  PUT JMP,
       5
       6 CODE OR           ( LOGICAL BITWISE 'OR' OF BOTTOM TWO ITEMS *)
       7    BOT    LDA,  SEC     ORA,  PHA,
       8    BOT 1+ LDA,  SEC 1 + ORA,  INX,  INX,  PUT JMP,
       9
       10 CODE XOR       ( LOGICAL 'EXCLUSIVE-OR' OF BOTTOM TWO ITEMS *)
       11    BOT    LDA,  SEC    EOR,  PHA,
       12    BOT 1+ LDA,  SEC 1+ EOR,  INX,  INX,  PUT JMP,
       13
       14 -->
       15

     SCR # 26
       0 (  STACK INITIALIZATION                           WFR-79MAR30 )
       1 CODE SP@                      ( FETCH STACK POINTER TO STACK *)
       2                TXA,
       3 LABEL PUSH0A   PHA,  0 # LDA,  PUSH JMP,
       4
       5 CODE SP!                                 ( LOAD SP FROM 'S0' *)
       6    06 # LDY,  UP )Y LDA,  TAX,  NEXT JMP,
       7
       8 CODE RP!                                   ( LOAD RP FROM R0 *)
       9    XSAVE STX,  08 # LDY,  UP )Y LDA,  TAX,  TXS,
      10               XSAVE LDX,  NEXT JMP,
      11
      12 CODE ;S              ( RESTORE IP REGISTER FROM RETURN STACK *)
      13    PLA,  IP STA,  PLA,  IP 1+ STA,  NEXT JMP,
      14
      15 -->

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     50








     SCR # 27
       0 (  RETURN STACK WORDS                             WFR-79MAR29 )
       1 CODE LEAVE          ( FORCE EXIT OF DO-LOOP BY SETTING LIMIT *)
       2    XSAVE STX,  TSX,  R LDA,  R 2+ STA,            ( TO INDEX *)
       3    R 1+ LDA,  R 3 + STA,  XSAVE LDX,  NEXT JMP,
       4
       5 CODE >R              ( MOVE FROM COMP. STACK TO RETURN STACK *)
       6    BOT 1+ LDA,  PHA,  BOT LDA,  PHA,  INX,  INX,  NEXT JMP,
       7
       8 CODE R>              ( MOVE FROM RETURN STACK TO COMP. STACK *)
       9    DEX,  DEX,  PLA,  BOT STA,  PLA,  BOT 1+ STA,  NEXT JMP,
      10
      11 CODE R      ( COPY THE BOTTOM OF RETURN STACK TO COMP. STACK *)
      12    XSAVE STX,  TSX,  R LDA,  PHA,  R 1+ LDA,
      13    XSAVE LDX,  PUSH JMP,
      14 '   R    -2  BYTE.IN  I  !
      15 -->

     SCR # 28
       0 (  TESTS AND LOGICALS                             WFR-79MAR19 )
       1
       2 CODE 0=           ( REVERSE LOGICAL STATE OF BOTTOM OF STACK *)
       3    BOT LDA,  BOT 1+ ORA,  BOT 1+ STY,
       4    0= IF,  INY,  THEN,  BOT STY,  NEXT JMP,
       5
       6 CODE 0<            ( LEAVE TRUE IF NEGATIVE; OTHERWISE FALSE *)
       7    BOT 1+ ASL,  TYA,  .A ROL,  BOT 1+ STY,  BOT STA,  NEXT JMP,
       8
       9
      10 -->
      11
      12
      13
      14
      15

     SCR # 29
       0 (  MATH                                           WFR-79MAR19 )
       1 CODE +         ( LEAVE THE SUM OF THE BOTTOM TWO STACK ITEMS *)
       2    CLC,  BOT LDA,  SEC ADC,  SEC STA,  BOT 1+ LDA,  SEC 1+ ADC,
       3          SEC 1+ STA,  INX,  INX,  NEXT JMP,
       4 CODE D+            ( ADD TWO DOUBLE INTEGERS, LEAVING DOUBLE *)
       5    CLC,  BOT 2 + LDA,  BOT 6 + ADC,  BOT 6 + STA,
       6          BOT 3 + LDA,  BOT 7 + ADC,  BOT 7 + STA,
       7          BOT     LDA,  BOT 4 + ADC,  BOT 4 + STA,
       8          BOT 1 + LDA,  BOT 5 + ADC,  BOT 5 + STA,  POPTWO JMP,
       9 CODE MINUS         ( TWOS COMPLEMENT OF BOTTOM SINGLE NUMBER *)
      10    SEC,  TYA,  BOT    SBC,  BOT    STA,
      11          TYA,  BOT 1+ SBC,  BOT 1+ STA,  NEXT JMP,
      12 CODE DMINUS        ( TWOS COMPLEMENT OF BOTTOM DOUBLE NUMBER *)
      13    SEC,  TYA,  BOT 2 + SBC,  BOT 2 + STA,
      14          TYA,  BOT 3 + SBC,  BOT 3 + STA,
      15       1 BYTE.IN   MINUS  JMP,               -->

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     51








     SCR # 30
       0 (  STACK MANIPULATION                             WFR-79MAR29 )
       1 CODE OVER              ( DUPLICATE SECOND ITEM AS NEW BOTTOM *)
       2    SEC LDA,  PHA,  SEC 1+ LDA,  PUSH JMP,
       3
       4 CODE DROP                           ( DROP BOTTOM STACK ITEM *)
       5    POP  -2  BYTE.IN  DROP  ! ( C.F. VECTORS DIRECTLY TO 'POP' )
       6
       7 CODE SWAP        ( EXCHANGE BOTTOM AND SECOND ITEMS ON STACK *)
       8    SEC LDA,  PHA,  BOT LDA,  SEC STA,
       9    SEC 1+ LDA,  BOT 1+ LDY,  SEC 1+ STY,  PUT JMP,
      10
      11 CODE DUP                    ( DUPLICATE BOTTOM ITEM ON STACK *)
      12    BOT LDA,  PHA,  BOT 1+ LDA,  PUSH JMP,
      13
      14 -->
      15

     SCR # 31
       0 (  MEMORY INCREMENT,                              WFR-79MAR30 )
       1
       2 CODE +!   ( ADD SECOND TO MEMORY 16 BITS ADDRESSED BY BOTTOM *)
       3    CLC,  BOT X) LDA,  SEC ADC,  BOT X) STA,
       4    BOT INC,  0= IF,  BOT 1+ INC,  THEN,
       5    BOT X) LDA,  SEC 1+ ADC,  BOT X) STA,  POPTWO JMP,
       6
       7 CODE TOGGLE          ( BYTE AT ADDRESS-2, BIT PATTERN-1  ... *)
       8        SEC X) LDA,  BOT EOR,  SEC X) STA,  POPTWO JMP,
       9
      10 -->
      11
      12
      13
      14
      15

     SCR # 32
       0 (  MEMORY FETCH AND STORE                          WFR-781202 )
       1 CODE @                   ( REPLACE STACK ADDRESS WITH 16 BIT *)
       2     BOT X) LDA,  PHA,             ( CONTENTS OF THAT ADDRESS *)
       3     BOT INC,  0= IF, BOT 1+ INC,  THEN,  BOT X) LDA,  PUT JMP,
       4
       5 CODE C@      ( REPLACE STACK ADDRESS WITH POINTED 8 BIT BYTE *)
       6     BOT X) LDA,  BOT STA,  BOT 1+ STY,  NEXT JMP,
       7
       8 CODE !         ( STORE SECOND AT 16 BITS ADDRESSED BY BOTTOM *)
       9     SEC LDA,  BOT X) STA,  BOT INC,  0= IF,  BOT 1+ INC,  THEN,
      10     SEC 1+ LDA,  BOT X) STA,  POPTWO JMP,
      11
      12 CODE C!           ( STORE SECOND AT BYTE ADDRESSED BY BOTTOM *)
      13     SEC LDA,  BOT X) STA,  POPTWO JMP,
      14
      15 DECIMAL     ;S

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     52








     SCR # 33
       0 (  :,  ;,                                         WFR-79MAR30 )
       1
       2 : :                 ( CREATE NEW COLON-DEFINITION UNTIL ';' *)
       3                    ?EXEC !CSP CURRENT   @         CONTEXT    !
       4                CREATE  ]     ;CODE   IMMEDIATE
       5      IP 1+ LDA,  PHA,  IP LDA,  PHA,  CLC,  W LDA,  2 # ADC,
       6      IP STA,  TYA,  W 1+ ADC,  IP 1+ STA,  NEXT JMP,
       7
       8
       9 : ;                             ( TERMINATE COLON-DEFINITION *)
      10                     ?CSP  COMPILE     ;S
      11                   SMUDGE  [    ;   IMMEDIATE
      12
      13
      14
      15 -->

     SCR # 34
       0 (  CONSTANT, VARIABLE, USER                       WFR-79MAR30 )
       1 : CONSTANT              ( WORD WHICH LATER CREATES CONSTANTS *)
       2                       CREATE  SMUDGE  ,     ;CODE
       3        2 # LDY,  W )Y LDA,  PHA,  INY,  W )Y LDA,  PUSH JMP,
       4
       5 : VARIABLE              ( WORD WHICH LATER CREATES VARIABLES *)
       6      CONSTANT  ;CODE
       7        CLC,  W LDA,  2 # ADC,  PHA,  TYA,  W 1+ ADC,  PUSH JMP,
       8
       9
      10 : USER                                ( CREATE USER VARIABLE *)
      11      CONSTANT  ;CODE
      12        2 # LDY,  CLC,  W )Y LDA,  UP ADC,  PHA,
      13        0 # LDA,  UP 1+ ADC,  PUSH JMP,
      14
      15 -->

     SCR # 35
       0 (  DEFINED CONSTANTS                              WFR-78MAR22 )
       1 HEX
       2 00  CONSTANT  0       01  CONSTANT  1
       3 02  CONSTANT  2       03  CONSTANT  3
       4 20  CONSTANT  BL                                ( ASCII BLANK *)
       5 40  CONSTANT  C/L                  ( TEXT CHARACTERS PER LINE *)
       6
       7 3BE0    CONSTANT   FIRST   ( FIRST BYTE RESERVED FOR BUFFERS *)
       8 4000    CONSTANT   LIMIT            ( JUST BEYOND TOP OF RAM *)
       9   80    CONSTANT   B/BUF             ( BYTES PER DISC BUFFER *)
      10    8     CONSTANT  B/SCR  ( BLOCKS PER SCREEN = 1024 B/BUF / *)
      11
      12            00  +ORIGIN
      13 : +ORIGIN  LITERAL  +  ; ( LEAVES ADDRESS RELATIVE TO ORIGIN *)
      14 -->
      15

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     53








     SCR # 36
       0 (  USER VARIABLES                                 WFR-78APR29 )
       1 HEX              ( 0 THRU 5 RESERVED,    REFERENCED TO $00A0 *)
       2 ( 06 USER S0 )              ( TOP OF EMPTY COMPUTATION STACK *)
       3 ( 08 USER R0 )                   ( TOP OF EMPTY RETURN STACK *)
       4 0A   USER TIB                        ( TERMINAL INPUT BUFFER *)
       5 0C   USER WIDTH                   ( MAXIMUM NAME FIELD WIDTH *)
       6 0E   USER WARNING                    ( CONTROL WARNING MODES *)
       7 10   USER FENCE                     ( BARRIER FOR FORGETTING *)
       8 12   USER DP                            ( DICTIONARY POINTER *)
       9 14   USER VOC-LINK                    ( TO NEWEST VOCABULARY *)
      10 16   USER BLK                         ( INTERPRETATION BLOCK *)
      11 18   USER IN                       ( OFFSET INTO SOURCE TEXT *)
      12 1A   USER OUT                      ( DISPLAY CURSOR POSITION *)
      13 1C   USER SCR                               ( EDITING SCREEN *)
      14 -->
      15

     SCR # 37
       0 (  USER VARIABLES, CONT.                          WFR-79APR29 )
       1 1E   USER OFFSET                  ( POSSIBLY TO OTHER DRIVES *)
       2 20   USER CONTEXT                ( VOCABULARY FIRST SEARCHED *)
       3 22   USER CURRENT           ( SEARCHED SECOND, COMPILED INTO *)
       4 24   USER STATE                          ( COMPILATION STATE *)
       5 26   USER BASE                    ( FOR NUMERIC INPUT-OUTPUT *)
       6 28   USER DPL                       ( DECIMAL POINT LOCATION *)
       7 2A   USER FLD                           ( OUTPUT FIELD WIDTH *)
       8 2C   USER CSP                         ( CHECK STACK POSITION *)
       9 2E   USER R#                       ( EDITING CURSOR POSITION *)
      10 30   USER HLD         ( POINTS TO LAST CHARACTER HELD IN PAD *)
      11 -->
      12
      13
      14
      15

     SCR # 38
       0 (  HI-LEVEL MISC.                                 WFR-79APR29 )
       1 : 1+      1   +  ;           ( INCREMENT STACK NUMBER BY ONE *)
       2 : 2+      2   +  ;           ( INCREMENT STACK NUMBER BY TWO *)
       3 : HERE    DP  @  ;        ( FETCH NEXT FREE ADDRESS IN DICT. *)
       4 : ALLOT   DP  +! ;                ( MOVE DICT. POINTER AHEAD *)
       5 : ,   HERE  !  2  ALLOT  ;     ( ENTER STACK NUMBER TO DICT. *)
       6 : C,   HERE  C!  1   ALLOT  ;    ( ENTER STACK BYTE TO DICT. *)
       7 : -   MINUS  +  ;                 ( LEAVE DIFF. SEC - BOTTOM *)
       8 : =   -  0=  ;                   ( LEAVE BOOLEAN OF EQUALITY *)
       9 : <   -  0<  ;                  ( LEAVE BOOLEAN OF SEC < BOT *)
      10 : >   SWAP  <  ;                ( LEAVE BOOLEAN OF SEC > BOT *)
      11 : ROT   >R  SWAP  R>  SWAP  ;       ( ROTATE THIRD TO BOTTOM *)
      12 : SPACE     BL  EMIT  ;            ( PRINT BLANK ON TERMINAL *)
      13 : -DUP     DUP  IF  DUP  ENDIF  ;       ( DUPLICATE NON-ZERO *)
      14 -->
      15

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     54








     SCR # 39
       0 (  VARIABLE LENGTH NAME SUPPORT                   WFR-79MAR30 )
       1 : TRAVERSE                          ( MOVE ACROSS NAME FIELD *)
       2          ( ADDRESS-2, DIRECTION-1, I.E. -1=R TO L, +1=L TO R *)
       3        SWAP
       4        BEGIN  OVER  +  7F  OVER  C@  <  UNTIL  SWAP  DROP  ;
       5
       6 : LATEST       CURRENT  @  @  ;         ( NFA OF LATEST WORD *)
       7
       8
       9 ( FOLLOWING HAVE LITERALS DEPENDENT ON COMPUTER WORD SIZE )
      10
      11 : LFA    4  -  ;                ( CONVERT A WORDS PFA TO LFA *)
      12 : CFA    2  -  ;                ( CONVERT A WORDS PFA TO CFA *)
      13 : NFA    5  -  -1  TRAVERSE  ;  ( CONVERT A WORDS PFA TO NFA *)
      14 : PFA     1  TRAVERSE  5  +  ;  ( CONVERT A WORDS NFA TO PFA *)
      15     -->

     SCR # 40
       0 (  ERROR PROCEDURES, PER SHIRA                    WFR-79MAR23 )
       1 : !CSP     SP@  CSP  !  ;     ( SAVE STACK POSITION IN 'CSP' *)
       2
       3 : ?ERROR          ( BOOLEAN-2,  ERROR TYPE-1,  WARN FOR TRUE *)
       4          SWAP  IF         ERROR    ELSE  DROP  ENDIF  ;
       5
       6 : ?COMP   STATE @  0= 11 ?ERROR ;   ( ERROR IF NOT COMPILING *) 
       7
       8 : ?EXEC   STATE  @  12  ?ERROR  ;   ( ERROR IF NOT EXECUTING *)
       9
      10 : ?PAIRS  -  13  ?ERROR  ;  ( VERIFY STACK VALUES ARE PAIRED *)
      11
      12 : ?CSP   SP@  CSP @ -  14  ?ERROR  ; ( VERIFY STACK POSITION *)
      13
      14 : ?LOADING                        ( VERIFY LOADING FROM DISC *)
      15          BLK  @  0=  16  ?ERROR  ;   -->

     SCR # 41
       0 (  COMPILE,  SMUDGE,  HEX, DECIMAL                WFR-79APR20 )
       1
       2 : COMPILE          ( COMPILE THE EXECUTION ADDRESS FOLLOWING *)
       3         ?COMP  R>  DUP  2+  >R  @  ,  ;
       4
       5 : [    0  STATE  !  ;  IMMEDIATE          ( STOP COMPILATION *)
       6
       7 : ]    C0  STATE  !  ;             ( ENTER COMPILATION STATE *)
       8
       9 : SMUDGE    LATEST  20  TOGGLE  ;   ( ALTER LATEST WORD NAME *)
      10
      11 : HEX      10  BASE  !  ;         ( MAKE HEX THE IN-OUT BASE *)
      12
      13 : DECIMAL  0A  BASE  !  ;     ( MAKE DECIMAL THE IN-OUT BASE *)
      14 -->
      15

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     55








     SCR # 42
       0 (  ;CODE                                          WFR-79APR20 )
       1
       2 : (;CODE)     ( WRITE CODE FIELD POINTING TO CALLING ADDRESS *)
       3         R>  LATEST  PFA  CFA  !  ;
       4
       5
       6 : ;CODE                      ( TERMINATE A NEW DEFINING WORD *)
       7       ?CSP  COMPILE  (;CODE)
       8       [COMPILE]  [  SMUDGE  ;   IMMEDIATE
       9 -->
      10
      11
      12
      13
      14
      15

     SCR # 43
       0 (  <BUILD,  DOES>                                 WFR-79MAR20 )
       1
       2 : <BUILDS   0  CONSTANT  ;  ( CREATE HEADER FOR 'DOES>' WORD *)
       3
       4 : DOES>          ( REWRITE PFA WITH CALLING HI-LEVEL ADDRESS *)
       5                              ( REWRITE CFA WITH 'DOES>' CODE *)
       6              R>  LATEST  PFA  !  ;CODE
       7         IP 1+ LDA,  PHA,  IP LDA,  PHA,   ( BEGIN FORTH NESTING )
       8         2 # LDY,  W )Y LDA,  IP STA,        ( FETCH FIRST PARAM )
       9         INY,  W )Y LDA,  IP 1+ STA,       ( AS NEXT INTERP. PTR )
      10         CLC,  W LDA,  4 # ADC,  PHA,   ( PUSH ADDRESS OF PARAMS )
      11         W 1+ LDA,  00 # ADC,  PUSH JMP,
      12
      13 -->
      14
      15

     SCR # 44
       0 (  TEXT OUTPUTS                                   WFR-79APR02 )
       1 : COUNT    DUP 1+ SWAP C@  ;  ( LEAVE TEXT ADDR. CHAR. COUNT *)
       2 : TYPE            ( TYPE STRING FROM ADDRESS-2, CHAR.COUNT-1 *)
       3         -DUP  IF OVER + SWAP
       4                  DO I C@ EMIT LOOP  ELSE DROP ENDIF ;
       5 : -TRAILING   ( ADJUST CHAR. COUNT TO DROP TRAILING BLANKS *)
       6         DUP  0  DO  OVER  OVER  +  1  -  C@
       7         BL  -  IF  LEAVE  ELSE  1  -  ENDIF  LOOP  ;
       8 : (.")             ( TYPE IN-LINE STRING, ADJUSTING RETURN *)
       9         R  COUNT  DUP  1+  R>  +  >R  TYPE  ;
      10
      11
      12 : ."     22  STATE  @      ( COMPILE OR PRINT QUOTED STRING *)
      13     IF  COMPILE  (.")       WORD    HERE  C@  1+  ALLOT
      14     ELSE            WORD   HERE   COUNT  TYPE  ENDIF  ;
      15                IMMEDIATE    -->

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     56








     SCR # 45
       0 (  TERMINAL INPUT                                 WFR-79APR29 )
       1
       2 : EXPECT            ( TERMINAL INPUT MEMORY-2,  CHAR LIMIT-1 *)
       3     OVER  +  OVER  DO  KEY  DUP  0E  +ORIGIN ( BS )  @  =
       4     IF  DROP  08  OVER  I  =  DUP  R>  2  -  +  >R  -
       5        ELSE ( NOT BS )  DUP  0D  =
       6            IF ( RET ) LEAVE  DROP  BL  0  ELSE  DUP  ENDIF
       7            I  C!  0  I  1+  !
       8        ENDIF EMIT  LOOP  DROP  ;
       9 : QUERY     TIB  @  50  EXPECT  0  IN  !  ;
      10 8081  HERE
      11 : X   BLK @                            ( END-OF-TEXT IS NULL *)
      12       IF ( DISC ) 1 BLK +!  0 IN !  BLK @  7  AND  0=
      13          IF ( SCR END )  ?EXEC  R>  DROP  ENDIF ( disc dependent )
      14        ELSE  ( TERMINAL )    R>  DROP
      15          ENDIF  ;   !   IMMEDIATE     -->

     SCR # 46
       0 (  FILL, ERASE, BLANKS, HOLD, PAD                 WFR-79APR02 )
       1 : FILL               ( FILL MEMORY BEGIN-3,  QUAN-2,  BYTE-1 *)
       2         SWAP  >R  OVER  C!  DUP  1+  R>  1  -  CMOVE  ;
       3
       4 : ERASE            ( FILL MEMORY WITH ZEROS  BEGIN-2, QUAN-1 *)
       5         0  FILL  ;
       6
       7 : BLANKS                  ( FILL WITH BLANKS BEGIN-2, QUAN-1 *)
       8         BL  FILL  ;
       9
      10 : HOLD                               ( HOLD CHARACTER IN PAD *)
      11         -1  HLD  +!   HLD  @  C!  ;
      12
      13 : PAD        HERE  44  +  ;     ( PAD IS 68 BYTES ABOVE HERE *)
      14         ( DOWNWARD HAS NUMERIC OUTPUTS; UPWARD MAY HOLD TEXT *)
      15 -->

     SCR # 47
       0 (  WORD,                                          WFR-79APR02 )
       1 : WORD         ( ENTER WITH DELIMITER, MOVE STRING TO 'HERE' *)
       2    BLK  @  IF  BLK  @        BLOCK    ELSE  TIB  @  ENDIF
       3    IN  @  +  SWAP    ( ADDRESS-2, DELIMITER-1 )
       4    ENCLOSE         ( ADDRESS-4, START-3, END-2, TOTAL COUNT-1 )
       5    HERE  22 BLANKS       ( PREPARE FIELD OF 34 BLANKS )
       6    IN  +!          ( STEP OVER THIS STRING )
       7    OVER  -  >R     ( SAVE CHAR COUNT )
       8    R  HERE  C!     ( LENGTH STORED FIRST )
       9    +  HERE  1+
      10    R>  CMOVE  ;    ( MOVE STRING FROM BUFFER TO HERE+1 )
      11
      12
      13
      14
      15 -->

     FORTH INTEREST GROUP                                  MAY 1, 1979


                                     57








     SCR # 48
       0 (  (NUMBER-,  NUMBER,  -FIND,                     WFR-79APR29 )
       1 : (NUMBER)    ( CONVERT DOUBLE NUMBER, LEAVING UNCONV. ADDR. *)
       2    BEGIN  1+  DUP  >R  C@  BASE  @  DIGIT
       3       WHILE  SWAP  BASE  @  U*  DROP  ROT  BASE  @  U*  D+
       4       DPL  @  1+  IF  1  DPL  +!  ENDIF  R>  REPEAT  R>  ;
       5
       6 : NUMBER   ( ENTER W/ STRING ADDR.  LEAVE DOUBLE NUMBER *)
       7       0  0  ROT  DUP  1+  C@  2D  =  DUP  >R  +  -1
       8    BEGIN  DPL  !  (NUMBER)  DUP  C@  BL  -
       9       WHILE  DUP  C@  2E  -  0  ?ERROR    0  REPEAT
      10       DROP  R>  IF  DMINUS  ENDIF  ;
      11
      12 : -FIND       ( RETURN PFA-3, LEN BYTE-2, TRUE-1; ELSE FALSE *)
      13       BL  WORD         HERE  CONTEXT  @  @  (FIND)
      14       DUP  0=  IF  DROP  HERE  LATEST  (FIND)  ENDIF  ;
      15 -->

     SCR # 49
       0 (  ERROR HANDLER                                  WFR-79APR20 )
       1
       2 : (ABORT)           ABORT    ;  ( USER ALTERABLE ERROR ABORT *)
       3
       4 : ERROR              ( WARNING:  -1=ABORT, 0=NO DISC, 1-DISC *)
       5     WARNING  @  0<           ( PRINT TEXT LINE REL TO SCR #4 *)
       6     IF  (ABORT)  ENDIF  HERE  COUNT  TYPE  ."   ? "
       7           MESSAGE    SP!  IN  @  BLK  @        QUIT    ;
       8
       9 : ID.   ( PRINT NAME FIELD FROM ITS HEADER ADDRESS *)
      10      PAD  020  5F  FILL  DUP  PFA  LFA  OVER  -
      11      PAD  SWAP  CMOVE  PAD  COUNT  01F  AND  TYPE  SPACE  ;
      12 -->
      13
      14
      15

     SCR # 50
       0 (  CREATE                                         WFR-79APR28 )
       1
       2 : CREATE              ( A SMUDGED CODE HEADER TO PARAM FIELD *)
       3                      ( WARNING IF DUPLICATING A CURRENT NAME *)
       4       TIB  HERE  0A0  +  <  2  ?ERROR  ( 6502 only )
       5       -FIND    ( CHECK IF UNIQUE IN CURRENT AND CONTEXT )
       6       IF ( WARN USER )  DROP  NFA  ID.
       7                         4         MESSAGE    SPACE  ENDIF
       8       HERE  DUP  C@  WIDTH  @        MIN    1+  ALLOT
       9       DP  C@  0FD  =  ALLOT   ( 6502 only )
      10       DUP  A0  TOGGLE  HERE  1  -  80  TOGGLE ( DELIMIT BITS )
      11       LATEST  ,  CURRENT  @  !
      12       HERE  2+  ,  ;
      13 -->
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     58








     SCR # 51
       0 (  LITERAL,  DLITERAL,  [COMPILE],  ?STACK        WFR-79APR29 )
       1
       2 : [COMPILE]         ( FORCE COMPILATION OF AN IMMEDIATE WORD *)
       3       -FIND  0=  0  ?ERROR  DROP  CFA  ,  ;  IMMEDIATE
       4
       5 : LITERAL                     ( IF COMPILING, CREATE LITERAL *)
       6       STATE  @  IF  COMPILE  LIT  ,  ENDIF  ;  IMMEDIATE
       7
       8 : DLITERAL             ( IF COMPILING, CREATE DOUBLE LITERAL *)
       9       STATE  @  IF  SWAP  [COMPILE]  LITERAL
      10                           [COMPILE]  LITERAL  ENDIF ; IMMEDIATE
      11
      12 (  FOLLOWING DEFINITION IS INSTALLATION DEPENDENT )
      13 : ?STACK    ( QUESTION UPON OVER OR UNDERFLOW OF STACK *)
      14       09E  SP@  <  1  ?ERROR   SP@  020  <  7  ?ERROR  ;
      15 -->

     SCR # 52
       0 (  INTERPRET,                                     WFR-79APR18 )
       1
       2 : INTERPRET   ( INTERPRET OR COMPILE SOURCE TEXT INPUT WORDS *)
       3       BEGIN  -FIND
       4          IF  ( FOUND )  STATE  @  <
       5                 IF  CFA  ,  ELSE  CFA  EXECUTE  ENDIF  ?STACK
       6             ELSE  HERE  NUMBER  DPL  @  1+
       7                 IF  [COMPILE]  DLITERAL
       8                   ELSE   DROP  [COMPILE]  LITERAL  ENDIF  ?STACK
       9           ENDIF  AGAIN  ;
      10 -->
      11
      12
      13
      14
      15

     SCR # 53
       0 (  IMMEDIATE,  VOCAB,  DEFIN,  FORTH,  (      DJK-WFR-79APR29 )
       1 : IMMEDIATE        ( TOGGLE PREC. BIT OF LATEST CURRENT WORD *)
       2          LATEST  40  TOGGLE  ;
       3
       4 : VOCABULARY  ( CREATE VOCAB WITH 'V-HEAD' AT VOC INTERSECT. *)
       5        <BUILDS  A081  ,  CURRENT  @  CFA  ,
       6        HERE  VOC-LINK  @  ,  VOC-LINK  !
       7        DOES>  2+  CONTEXT  !  ;
       8
       9 VOCABULARY  FORTH     IMMEDIATE       ( THE TRUNK VOCABULARY *)
      10
      11 : DEFINITIONS        ( SET THE CONTEXT ALSO AS CURRENT VOCAB *)
      12        CONTEXT  @  CURRENT  !  ;
      13
      14 : (              ( SKIP INPUT TEXT UNTIL RIGHT PARENTHESIS *)
      15        29  WORD  ;   IMMEDIATE   -->

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     59








     SCR # 54
       0 (  QUIT,  ABORT                                  WFR-79MAR30 )
       1
       2 : QUIT                   ( RESTART,  INTERPRET FROM TERMINAL *)
       3       0  BLK  !  [COMPILE]  [
       4       BEGIN  RP!  CR  QUERY  INTERPRET
       5              STATE  @  0=  IF  ."  OK"  ENDIF  AGAIN  ;
       6
       7 : ABORT                  ( WARM RESTART, INCLUDING REGISTERS *)
       8       SP!  DECIMAL            DR0
       9       CR  ." FORTH-65 V 4.0"
      10       [COMPILE]  FORTH  DEFINITIONS  QUIT  ;
      11
      12
      13 -->
      14
      15

     SCR # 55
       0 (  COLD START                                     WFR-79APR29 )
       1 CODE COLD               ( COLD START, INITIALIZING USER AREA *)
       2    HERE  02  +ORIGIN  !  ( POINT COLD ENTRY TO HERE )
       3          0C +ORIGIN LDA,  'T FORTH 4 + STA,  ( FORTH VOCAB. )
       4          0D +ORIGIN LDA,  'T FORTH 5 + STA,
       5          15 # LDY, ( INDEX TO VOC-LINK ) 0= IF, ( FORCED )
       6     HERE  06 +ORIGIN !   ( POINT RE-ENTRY TO HERE )
       7       0F # LDY,  ( INDEX TO WARNING )   THEN, ( FROM IF, )
       8       10 +ORIGIN LDA,   UP    STA,  ( LOAD UP )
       9       11 +ORIGIN LDA,   UP 1+ STA,
      10        BEGIN,  0C +ORIGIN ,Y LDA,  ( FROM LITERAL AREA )
      11                        UP )Y STA,  ( TO USER AREA )
      12             DEY,  0< END,
      13      'T ABORT  100  /MOD  # LDA,  IP 1+ STA,
      14                           # LDA,  IP    STA,
      15       6C # LDA,  W 1 - STA,    'T RP! JMP, ( RUN )  -->

     SCR # 56
       0 (  MATH UTILITY                               DJK-WFR-79APR29 )
       1 CODE S->D                  ( EXTEND SINGLE INTEGER TO DOUBLE *)
       2       BOT 1+ LDA,  0< IF, DEY, THEN,  TYA, PHA, PUSH JMP,
       3
       4 : +-    0< IF MINUS ENDIF ;   ( APPLY SIGN TO NUMBER BENEATH *)
       5
       6 : D+-                  ( APPLY SIGN TO DOUBLE NUMBER BENEATH *)
       7         0<  IF  DMINUS  ENDIF  ;
       8
       9 : ABS     DUP  +-   ;                 ( LEAVE ABSOLUTE VALUE *)
      10 : DABS    DUP  D+-  ;        ( DOUBLE INTEGER ABSOLUTE VALUE *)
      11     
      12 : MIN                         ( LEAVE SMALLER OF TWO NUMBERS *)
      13         OVER  OVER  >  IF  SWAP  ENDIF  DROP  ;
      14 : MAX                          ( LEAVE LARGER OF TWO NUMBERS *)
      15         OVER  OVER  <  IF  SWAP  ENDIF  DROP  ; -->

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     60








     SCR # 57
       0 (  MATH PACKAGE                               DJK-WFR-79APR29 )
       1 : M*     ( LEAVE SIGNED DOUBLE PRODUCT OF TWO SINGLE NUMBERS *)
       2         OVER  OVER  XOR  >R  ABS  SWAP  ABS  U*  R>  D+-  ;
       3 : M/              ( FROM SIGNED DOUBLE-3-2, SIGNED DIVISOR-1 *)
       4                ( LEAVE SIGNED REMAINDER-2, SIGNED QUOTIENT-1 *)
       5         OVER  >R  >R  DABS  R  ABS  U/
       6         R>  R  XOR  +-  SWAP  R>  +-  SWAP  ;
       7 : *      U*  DROP  ;                        ( SIGNED PRODUCT *)
       8 : /MOD   >R  S->D  R>  M/  ;           ( LEAVE REM-2, QUOT-1 *)
       9 : /      /MOD  SWAP  DROP  ;                ( LEAVE QUOTIENT *)
      10 : MOD    /MOD  DROP  ;                     ( LEAVE REMAINDER *)
      11 : */MOD              ( TAKE RATION OF THREE NUMBERS, LEAVING *)
      12          >R  M*  R>  M/  ;               ( REM-2, QUOTIENT-1 *)
      13 : */     */MOD  SWAP  DROP  ;   ( LEAVE RATIO OF THREE NUMBS *)
      14 : M/MOD   ( DOUBLE, SINGLE DIVISOR ...  REMAINDER, DOUBLE *)
      15           >R  0  R  U/  R>  SWAP  >R  U/  R>   ;   -->

     SCR # 58
       0 (  DISC UTILITY,  GENERAL USE                     WFR-79APR02 )
       1 FIRST  VARIABLE  USE           ( NEXT BUFFER TO USE, STALEST *)
       2 FIRST  VARIABLE  PREV      ( MOST RECENTLY REFERENCED BUFFER *)
       3
       4 : +BUF     ( ADVANCE ADDRESS-1 TO NEXT BUFFER. RETURNS FALSE *)
       5       84 ( I.E. B/BUF+4 )  +  DUP  LIMIT  =     ( IF AT PREV *)
       6       IF  DROP  FIRST  ENDIF  DUP  PREV  @  -  ;
       7
       8 : UPDATE     ( MARK THE BUFFER POINTED TO BY PREV AS ALTERED *)
       9       PREV  @  @  8000  OR  PREV  @  !  ;
      10
      11 : EMPTY-BUFFERS   ( CLEAR BLOCK BUFFERS; DON'T WRITE TO DISC *)
      12       FIRST  LIMIT  OVER  -  ERASE  ;
      13
      14 : DR0      0  OFFSET  !  ;                 ( SELECT DRIVE #0 *)
      15 : DR1   07D0  OFFSET  !  ;   -->           ( SELECT DRIVE #1 *)

     SCR # 59
       0 (  BUFFER                                         WFR-79APR02 )
       1 : BUFFER                 ( CONVERT BLOCK# TO STORAGE ADDRESS *)
       2     USE  @  DUP  >R   ( BUFFER ADDRESS TO BE ASSIGNED )
       3     BEGIN  +BUF  UNTIL ( AVOID PREV )  USE  !  ( FOR NEXT TIME )
       4     R  @  0<  ( TEST FOR UPDATE IN THIS BUFFER )
       5     IF ( UPDATED, FLUSH TO DISC )
       6        R  2+ ( STORAGE LOC. )
       7        R  @  7FFF  AND  ( ITS BLOCK # )
       8        0         R/W     ( WRITE SECTOR TO DISC )
       9       ENDIF
      10     R  !  ( WRITE NEW BLOCK # INTO THIS BUFFER )
      11     R  PREV  !  ( ASSIGN THIS BUFFER AS 'PREV' )
      12     R>  2+  ( MOVE TO STORAGE LOCATION )  ;
      13
      14 -->
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     61








     SCR # 60
       0 (  BLOCK                                          WFR-79APR02 )
       1 : BLOCK         ( CONVERT BLOCK NUMBER TO ITS BUFFER ADDRESS *)
       2    OFFSET  @  +  >R   ( RETAIN BLOCK # ON RETURN STACK )
       3    PREV  @  DUP  @  R  -  DUP  +  ( BLOCK = PREV ? )
       4    IF ( NOT PREV )
       5       BEGIN  +BUF  0=  ( TRUE UPON REACHING 'PREV' )
       6          IF ( WRAPPED )  DROP  R  BUFFER
       7              DUP  R  1         R/W    ( READ SECTOR FROM DISC )
       8              2  - ( BACKUP )
       9            ENDIF
      10            DUP  @  R  -  DUP  +  0=
      11         UNTIL  ( WITH BUFFER ADDRESS )
      12       DUP  PREV  !
      13      ENDIF
      14      R>  DROP    2+  ;
      15 -->

     SCR # 61
       0 (  TEXT OUTPUT FORMATTING                         WFR-79MAY03 )
       1
       2 : (LINE)         ( LINE#, SCR#, ... BUFFER ADDRESS, 64 COUNT *)
       3          >R  C/L  B/BUF  */MOD  R>  B/SCR  *  +
       4          BLOCK  +  C/L  ;
       5
       6 : .LINE   ( LINE#,  SCR#,  ...  PRINTED *)
       7          (LINE)  -TRAILING  TYPE  ;
       8
       9 : MESSAGE      ( PRINT LINE RELATIVE TO SCREEN #4 OF DRIVE 0 *)
      10     WARNING  @
      11     IF  ( DISC IS AVAILABLE )
      12         -DUP  IF  4  OFFSET  @  B/SCR  /  -  .LINE  ENDIF
      13         ELSE  ." MSG # "          .    ENDIF  ;
      14 -->
      15

     SCR # 62
       0 (  LOAD,  -->                                     WFR-79APR02 )
       1
       2 : LOAD                         ( INTERPRET SCREENS FROM DISC *)
       3     BLK  @  >R  IN  @  >R  0  IN  !  B/SCR  *  BLK !
       4     INTERPRET  R>  IN  !  R>  BLK  !  ;
       5
       6 : -->               ( CONTINUE INTERPRETATION ON NEXT SCREEN *)
       7      ?LOADING  0  IN  !  B/SCR  BLK  @  OVER
       8      MOD  -  BLK  +!  ;    IMMEDIATE
       9
      10 -->
      11
      12
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     62








     SCR # 63
       0 (  INSTALLATION DEPENDENT TERMINAL I-O,  TIM      WFR-79APR26 )
       1 ( EMIT )        ASSEMBLER
       2   HERE  -2  BYTE.IN  EMIT  !       ( VECTOR EMITS' CF TO HERE )
       3   XSAVE STX,  BOT LDA,  7F # AND, 72C6 JSR,  XSAVE LDX,
       4   CLC,  1A # LDY,  UP )Y LDA,  01 # ADC,  UP )Y STA,
       5              INY,  UP )Y LDA,  00 # ADC,  UP )Y STA,  POP JMP,
       6                                       ( AND INCREMENT 'OUT' )
       7 ( KEY )
       8       HERE  -2  BYTE.IN  KEY  !   ( VECTOR KEYS' CF TO HERE )
       9       XSAVE STX,  BEGIN,  8 # LDX,
      10       BEGIN,  6E02 LDA,  .A LSR,  CS END,  7320 JSR,
      11       BEGIN,  731D JSR,  0 X) CMP,  0 X) CMP,  0 X) CMP,
      12       0 X) CMP,  0 X) CMP,  6E02 LDA,  .A LSR,  PHP,  TYA,
      13       .A LSR,  PLP,  CS IF,  80 # ORA,  THEN,  TAY,  DEX,
      14       0= END,  731D JSR,  FF # EOR,  7F # AND,  0= NOT END,
      15       XSAVE LDX,   PUSH0A JMP,     -->

     SCR # 64
       0 (  INSTALLATION DEPENDENT TERMINAL I-O,  TIM      WFR-79APR02 )
       1
       2 ( ?TERMINAL )
       3      HERE  -2  BYTE.IN  ?TERMINAL  !    ( VECTOR LIKEWISE )
       4      1 # LDA, 6E02 BIT, 0= NOT  IF,
       5      BEGIN,  731D JSR,  6E02 BIT,  0= END,  INY,  THEN,
       6       TYA,    PUSH0A JMP,
       7
       8 ( CR )
       9     HERE  -2  BYTE.IN  CR  !  ( VECTOR CRS' CF TO HERE )
      10     XSAVE STX,  728A JSR,  XSAVE LDX, NEXT JMP,
      11
      12 -->
      13
      14
      15

     SCR # 65
       0 (  INSTALLATION DEPENDENT DISC                    WFR-79APR02 )
       1 6900    CONSTANT  DATA                     ( CONTROLLER PORT *)
       2 6901    CONSTANT  STATUS                   ( CONTROLLER PORT *)
       3
       4
       5 : #HL            ( CONVERT DECIMAL DIGIT FOR DISC CONTROLLER *)
       6       0  0A  U/  SWAP  30  +  HOLD  ;
       7
       8 -->
       9
      10
      11
      12
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     63








     SCR # 66
       0 (  D/CHAR,  ?DISC,                                WFR-79MAR23 )
       1 CODE D/CHAR    ( TEST CHAR-1. EXIT TEST BOOL-2, NEW CHAR-1 *)
       2       DEX,  DEX,  BOT 1+ STY,  C0 # LDA,
       3    BEGIN,  STATUS BIT,  0= NOT END,  ( TILL CONTROL READY )
       4       DATA LDA,  BOT STA,  ( SAVE CHAR )
       5       SEC CMP,  0= IF,  INY,  THEN,  SEC STY,  NEXT JMP,
       6
       7 : ?DISC         ( UPON NAK SHOW ERR MSG, QUIT.  ABSORBS TILL *)
       8       1  D/CHAR  >R  0=                ( EOT, EXCEPT FOR SOH *)
       9     IF  ( NOT SOH )  R  15  =
      10          IF ( NAK )  CR
      11              BEGIN  4  D/CHAR  EMIT
      12                 UNTIL ( PRINT ERR MSG TIL EOT )  QUIT
      13            ENDIF  ( FOR ENQ, ACK )
      14           BEGIN  4  D/CHAR  DROP  UNTIL  ( AT EOT )
      15      ENDIF  R>  DROP  ;   -->

     SCR # 67
       0 (  BLOCK-WRITE                                     WFR-790103 )
       1 CODE BLOCK-WRITE     ( SEND TO DISC FROM ADDRESS-2,  COUNT-1 *)
       2       2 # LDA,  SETUP JSR,                 ( WITH EOT AT END *)
       3    BEGIN,  02 # LDA,
       4       BEGIN,    STATUS BIT,  0= END,  ( TILL IDLE )
       5       N CPY, 0=
       6         IF, ( DONE )  04 # LDA,  STATUS STA,  DATA STA,
       7              NEXT JMP,
       8         THEN,
       9       N 2+ )Y LDA,  DATA STA,  INY,
      10       0=  END,   ( FORCED TO BEGIN )
      11
      12 -->
      13
      14
      15

     SCR # 68
       0 (  BLOCK-READ,                                     WFR-790103 )
       1
       2 CODE BLOCK-READ   ( BUF.ADDR-1. EXIT AT 128 CHAR OR CONTROL *)
       3     1 # LDA,  SETUP JSR,
       4    BEGIN,  C0 # LDA,
       5       BEGIN,   STATUS BIT,  0=  NOT END,  ( TILL FLAG )
       6       50 ( BVC, D6=DATA )
       7      IF,  DATA LDA,  N )Y STA,  INY,      SWAP
       8           0< END,  ( LOOP TILL 128 BYTES )
       9        THEN,   ( OR D6=0, SO D7=1, )
      10        NEXT JMP,
      11
      12 -->
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     64








     SCR # 69
       0 (  R/W   FOR PERSCI 1070 CONTROLLER               WFR-79MAY03 )
       1 0A  ALLOT  HERE      ( WORKSPACE TO PREPARE DISC CONTROL TEXT )
       2         ( IN FORM:  C TT SS /D,  TT=TRACK, SS=SECTOR, D=DRIVE )
       3                                  ( C = 1 TO READ, 0 TO WRITE *)
       4 : R/W                                ( READ/WRITE DISC BLOCK *)
       5                ( BUFFER ADDRESS-3, BLOCK #-2, 1=READ 0=WRITE *)
       6    LITERAL  HLD  ! ( JUST AFTER WORKSPACE )   SWAP
       7    0  OVER  >  OVER  0F9F  >  OR  6  ?ERROR
       8    07D0  ( 2000 SECT/DR )  /MOD  #HL  DROP  2F  HOLD  BL  HOLD
       9    1A  /MOD  SWAP 1+ #HL  #HL  DROP  BL  HOLD  ( SECTOR 01-26 )
      1O                      #HL  #HL  DROP  BL  HOLD  ( TRACK  00-76 )
      11    DUP
      12    IF  49 ( 1=READ)  ELSE 4F ( 0=WRITE )  ENDIF
      13    HOLD  HLD  @  0A  BLOCK-WRITE  ( SEND TEXT ) ?DISC
      14    IF  BLOCK-READ  ELSE  B/BUF  BLOCK-WRITE  ENDIF
      15    ?DISC  ;     -->

     SCR # 70
       0 (  FORWARD REFERENCES                             WFR-79MAR30 )
       1 00  BYTE.IN  :         REPLACED.BY  ?EXEC
       2 02  BYTE.IN  :         REPLACED.BY  !CSP
       3 04  BYTE.IN  :         REPLACED.BY  CURRENT
       4 08  BYTE.IN  :         REPLACED.BY  CONTEXT
       5 0C  BYTE.IN  :         REPLACED.BY  CREATE
       6 0E  BYTE.IN  :         REPLACED.BY  ]
       7 10  BYTE.IN  :         REPLACED.BY  (;CODE)
       8 00  BYTE.IN  ;         REPLACED.BY  ?CSP
       9 02  BYTE.IN  ;         REPLACED.BY  COMPILE
      10 06  BYTE.IN  ;         REPLACED.BY  SMUDGE
      11 08  BYTE.IN  ;         REPLACED.BY  [
      12 00  BYTE.IN  CONSTANT  REPLACED.BY  CREATE
      13 02  BYTE.IN  CONSTANT  REPLACED.BY  SMUDGE
      14 04  BYTE.IN  CONSTANT  REPLACED.BY  ,
      15 06  BYTE.IN  CONSTANT  REPLACED.BY  (;CODE)    -->

     SCR # 71
       0 (  FORWARD REFERENCES                             WFR-79APR29 )
       1 02  BYTE.IN VARIABLE   REPLACED.BY  (;CODE)
       2 02  BYTE.IN USER       REPLACED.BY  (;CODE)
       3 06  BYTE.IN ?ERROR     REPLACED.BY  ERROR
       4 0F  BYTE.IN ."         REPLACED.BY  WORD
       5 1D  BYTE.IN ."         REPLACED.BY  WORD
       6 00  BYTE.IN (ABORT)    REPLACED.BY  ABORT
       7 19  BYTE.IN ERROR      REPLACED.BY  MESSAGE
       8 25  BYTE.IN ERROR      REPLACED.BY  QUIT
       9 0C  BYTE.IN WORD       REPLACED.BY  BLOCK
      10 1E  BYTE.IN CREATE     REPLACED.BY  MESSAGE
      11 2C  BYTE.IN CREATE     REPLACED.BY  MIN
      12 04  BYTE.IN ABORT      REPLACED.BY  DR0
      13 2C  BYTE.IN BUFFER     REPLACED.BY  R/W
      14 30  BYTE.IN BLOCK      REPLACED.BY  R/W        DECIMAL  ;S
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     65








     SCR # 72
       0 (  ',  FORGET,  \                                 WFR-79APR28 )
       1 HEX    3   WIDTH
       2 : '          ( FIND NEXT WORDS PFA; COMPILE IT, IF COMPILING *)
       3     -FIND  0=  0  ?ERROR  DROP  [COMPILE]  LITERAL  ;
       4                                     IMMEDIATE
       5
       6 : FORGET            ( FOLLOWING WORD FROM CURRENT VOCABULARY *)
       7     CURRENT  @  CONTEXT  @  -  18  ?ERROR
       8     [COMPILE]  '  DUP  FENCE  @  <  15  ?ERROR
       9     DUP  NFA  DP  !  LFA  @  CURRENT  @  !  ;
      10
      11
      12
      13 -->
      14
      15

     SCR # 73
       0 (  CONDITIONAL COMPILER, PER SHIRA                WFR-79APR01 )
       1 : BACK     HERE  -  ,  ;           ( RESOLVE BACKWARD BRANCH *)
       2
       3 : BEGIN    ?COMP  HERE  1  ;                  IMMEDIATE
       4
       5 : ENDIF    ?COMP 2 ?PAIRS  HERE  OVER  -  SWAP  !  ;  IMMEDIATE
       6
       7 : THEN     [COMPILE]  ENDIF  ;    IMMEDIATE
       8
       9 : DO       COMPILE  (DO)  HERE  3  ;            IMMEDIATE
      10
      11 : LOOP     3  ?PAIRS  COMPILE  (LOOP)  BACK  ;  IMMEDIATE
      12
      13 : +LOOP    3  ?PAIRS  COMPILE  (+LOOP)  BACK  ;     IMMEDIATE
      14
      15 : UNTIL    1  ?PAIRS  COMPILE  0BRANCH  BACK  ; IMMEDIATE  -->

     SCR # 74
       0 (  CONDITIONAL COMPILER                           WFR-79APR01 )
       1 : END      [COMPILE]  UNTIL  ;  IMMEDIATE
       2
       3 : AGAIN    1  ?PAIRS  COMPILE  BRANCH   BACK  ;   IMMEDIATE
       4
       5 : REPEAT   >R  >R  [COMPILE]  AGAIN
       6               R>  R>  2  -  [COMPILE]  ENDIF  ;  IMMEDIATE
       7
       8 : IF       COMPILE  0BRANCH   HERE  0  ,  2  ;  IMMEDIATE
       9
      10 : ELSE     2  ?PAIRS  COMPILE  BRANCH  HERE  0  ,
      11            SWAP  2  [COMPILE]  ENDIF  2  ;      IMMEDIATE
      12
      13 : WHILE   [COMPILE]  IF  2+  ;    IMMEDIATE
      14
      15 -->

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     66








     SCR # 75
       0 (  NUMERIC PRIMITIVES                             WFR-79APR01 )
       1 : SPACES     0  MAX  -DUP  IF  0  DO  SPACE  LOOP  ENDIF  ;
       2
       3 : <#     PAD  HLD  !  ;
       4
       5 : #>     DROP  DROP  HLD  @  PAD  OVER  -  ;
       6
       7 : SIGN   ROT  0<  IF  2D  HOLD  ENDIF  ;
       8
       9 : #                     ( CONVERT ONE DIGIT, HOLDING IN PAD * )
      10          BASE @ M/MOD ROT 9 OVER < IF  7 + ENDIF 30  +  HOLD  ;
      11
      12 : #S     BEGIN  #  OVER  OVER  OR  0=  UNTIL  ;
      13 -->
      14
      15

     SCR # 76
       0 (  OUTPUT OPERATORS                               WFR-79APR20 )
       1 : D.R        ( DOUBLE INTEGER OUTPUT, RIGHT ALIGNED IN FIELD *)
       2        >R  SWAP  OVER  DABS  <#  #S  SIGN  #>
       3        R>  OVER  -  SPACES  TYPE  ;
       4
       5 : D.     0  D.R  SPACE  ;            ( DOUBLE INTEGER OUTPUT *)
       6
       7 : .R     >R  S->D  R>  D.R  ;       ( ALIGNED SINGLE INTEGER *)
       8
       9 : .      S->D  D.  ;                 ( SINGLE INTEGER OUTPUT *)
      10
      11 : ?      @  .  ;                  ( PRINT CONTENTS OF MEMORY *)
      12
      13    .  CFA       MESSAGE  2A  +  !  ( PRINT MESSAGE NUMBER )
      14 -->
      15

     SCR # 77
       0 (  PROGRAM DOCUMENTATION                          WFR-79APR20 )
       1 HEX
       2 : LIST                      ( LIST SCREEN BY NUMBER ON STACK *)
       3           DECIMAL   CR  DUP  SCR  !
       4          ." SCR # "   .  10  0  DO  CR  I  3  .R  SPACE
       5          I  SCR  @  .LINE  LOOP  CR  ;
       6
       7 : INDEX       ( PRINT FIRST LINE OF EACH SCREEN FROM-2, TO-1 *)
       8          0C  EMIT ( FORM FEED )  CR  1+  SWAP
       9          DO  CR  I  3  .R  SPACE
      10              0  I  .LINE
      11              ?TERMINAL  IF  LEAVE  ENDIF  LOOP  ;
      12 : TRIAD     ( PRINT 3 SCREENS ON PAGE, CONTAINING # ON STACK *)
      13          0C  EMIT ( FF )  3  /  3  *  3  OVER  +  SWAP
      14          DO  CR  I  LIST  LOOP  CR
      15          0F  MESSAGE  CR  ;     DECIMAL   -->

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     67








     SCR # 78
       0 (  TOOLS                                          WPR-79APR20 )
       1 HEX
       2 : VLIST                            ( LIST CONTEXT VOCABULARY *)
       3                80  OUT  !    CONTEXT  @  @
       4      BEGIN  OUT  @  C/L  >  IF  CR  0  OUT  !  ENDIF
       5             DUP  ID.  SPACE  SPACE    PFA  LFA  @
       6             DUP  0=  ?TERMINAL  OR  UNTIL  DROP  ;
       7 -->
       8
       9
      10
      11
      12
      13
      14
      15

     SCR # 79
       0 (  TOOLS                                          WFR-79MAY03 )
       1 HEX
       2
       3 CREATE  MON         ( CALL MONITOR, SAVING RE-ENTRY TO FORTH *)
       4         0  C,    4C C,   ' LIT 18 + ,    SMUDGE
       5
       6
       7
       8
       9
      10 DECIMAL
      11 HERE             FENCE  !
      12 HERE       28  +ORIGIN  !   ( COLD START FENCE )
      13 HERE       30  +ORIGIN  !   ( COLD START DP )
      14 LATEST     12  +ORIGIN  !   ( TOPMOST WORD )
      15 '  FORTH  6  +  32  +ORIGIN  !  ( COLD VOC-LINK )  ;S

     SCR # 80
       0 -->
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     68









                                  LINE EDITOR


     This is a sample editor, compatible with the fig-FORTH model and 
     simple terminal devices.  The line and screen editing functions are 
     portable.  The code definition for the string MATCH could be written 
     high level or translated.

















































                                     69

































































                                     70








     SCR # 87
       0 (  TEXT,  LINE                                    WFR-79MAY01 )
       1 FORTH  DEFINITIONS   HEX
       2 : TEXT                        ( ACCEPT FOLLOWING TEXT TO PAD *)
       3      HERE  C/L  1+   BLANKS  WORD  HERE  PAD  C/L  1+  CMOVE  ;
       4
       5 : LINE              ( RELATIVE TO SCR, LEAVE ADDRESS OF LINE *)
       6       DUP  FFF0  AND  17  ?ERROR   ( KEEP ON THIS SCREEN )
       7       SCR  @  (LINE)  DROP  ;
       8 -->
       9
      10
      11
      12
      13
      14
      15

     SCR # 88
       0 (  LINE EDITOR                                    WFR-79MAY03 )
       1 VOCABULARY  EDITOR  IMMEDIATE    HEX
       2 : WHERE                  ( PRINT SCREEN # AND IMAGE OF ERROR *)
       3     DUP  B/SCR  /  DUP  SCR  !  ." SCR # "  DECIMAL  .
       4     SWAP  C/L  /MOD  C/L  *  ROT  BLOCK  +  CR  C/L  TYPE
       5     CR  HERE  C@  -  SPACES  5E EMIT  [COMPILE] EDITOR  QUIT  ;
       6
       7 EDITOR  DEFINITIONS
       8 : #LOCATE                    ( LEAVE CURSOR OFFSET-2, LINE-1 *)
       9          R#  @  C/L  /MOD  ;
      10 : #LEAD                 ( LINE ADDRESS-2, OFFSET-1 TO CURSOR *)
      11          #LOCATE  LINE  SWAP  ;
      12 : #LAG              ( CURSOR ADDRESS-2, COUNT-1 AFTER CURSOR *)
      13          #LEAD  DUP  >R  +  C/L  R>  -  ;
      14 : -MOVE      ( MOVE IN BLOCK BUFFER ADDR FROM-2,  LINE TO-1 *)
      15          LINE  C/L  CMOVE  UPDATE  ;  -->

     SCR # 89
       0 (  LINE EDITING COMMANDS                          WFR-79MAY03 )
       1 : H                              ( HOLD NUMBERED LINE AT PAD *)
       2       LINE  PAD  1+  C/L  DUP  PAD  C!  CMOVE  ;
       3
       4 : E                               ( ERASE LINE-1 WITH BLANKS *)
       5       LINE  C/L  BLANKS  UPDATE  ;
       6
       7 : S                             ( SPREAD MAKING LINE # BLANK *)
       8       DUP  1  -  ( LIMIT )  0E ( FIRST TO MOVE )
       9       DO  I  LINE  I  1+  -MOVE  -1  +LOOP  E  ;
      10
      11 : D                         ( DELETE LINE-1, BUT HOLD IN PAD *)
      12       DUP  H  0F  DUP  ROT
      13       DO  I  1+  LINE  I  -MOVE  LOOP  E  ;
      14
      15 -->

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     71








     SCR # 90
       0 (  LINE EDITING COMMANDS                          WFR-79MAY03 )
       1
       2 : M    ( MOVE CURSOR BY SIGNED AMOUNT-1, PRINT ITS LINE *)
       3      R#  +!  CR  SPACE  #LEAD  TYPE  5F  EMIT
       4                         #LAG   TYPE  #LOCATE  .  DROP  ;
       5
       6 : T    ( TYPE LINE BY #-1,  SAVE ALSO IN PAD *)
       7      DUP  C/L  *  R#  !  DUP  H  0  M  ;
       8
       9 : L     ( RE-LIST SCREEN *)
      10         SCR  @  LIST  0  M  ;
      11 -->
      12
      13
      14
      15

     SCR # 91
       0 (  LINE EDITING COMMANDS                           WFR-790105 )
       1 : R                          ( REPLACE ON LINE #-1, FROM PAD *)
       2       PAD  1+  SWAP  -MOVE  ;
       3
       4 : P                           ( PUT FOLLOWING TEXT ON LINE-1 *)
       5       1  TEXT  R  ;
       6
       7 : I                       ( INSERT TEXT FROM PAD ONTO LINE # *)
       8       DUP  S  R  ;
       9                             CR
      10 : TOP                    ( HOME CURSOR TO TOP LEFT OF SCREEN *)
      11       0  R#  !  ;
      12 -->
      13
      14
      15

     SCR # 92
       0 (  SCREEN EDITING COMMANDS                        WFR-79APR27 )
       1 : CLEAR                           ( CLEAR SCREEN BY NUMBER-1 *)
       2       SCR  !  10  0  DO  FORTH  I  EDITOR  E  LOOP  ;
       3
       4 : FLUSH                   ( WRITE ALL UPDATED BLOCKS TO DISC *)
       5     [  LIMIT  FIRST  -  B/BUF  4  +  /  ]  ( NUMBER OF BUFFERS)
       6     LITERAL  0  DO  7FFF  BUFFER  DROP  LOOP  ;
       7
       8 : COPY                   ( DUPLICATE SCREEN-2, ONTO SCREEN-1 *)
       9    B/SCR  *  OFFSET  @  +  SWAP  B/SCR  *  B/SCR  OVER  +  SWAP
      10    DO  DUP  FORTH  I  BLOCK  2  -  !  1+   UPDATE  LOOP
      11    DROP  FLUSH  ;
      12 -->
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     72








     SCR # 93
       0 (  DOUBLE NUMBER SUPPORT                          WFR-80APR24 )
       1 (  OPERATES ON 32 BIT DOUBLE NUMBERS   OR TWO 16-BIT INTEGERS )
       2 FORTH DEFINITIONS
       3
       4 : 2DROP   DROP    DROP  ;  ( DROP DOUBLE NUMBER )
       5
       6 : 2DUP    OVER    OVER  ;  ( DUPLICATE A DOUBLE NUMBER )
       7
       8 : 2SWAP   ROT     >R    ROT   R>  ;
       9         ( BRING SECOND DOUBLE TO TOP OF STACK )
      10 EDITOR DEFINITIONS  -->
      11
      12
      13
      14
      15

     SCR # 94
       0 (  STRING MATCH FOR EDITOR                     PM-WFR-80APR25 )
       1 : -TEXT                   ( ADDRESS-3, COUNT-2, ADDRESS-1 --- )
       2  SWAP   -DUP  IF  ( LEAVE BOOLEAN MATCHED-NON-ZERO, NOPE-ZERO )
       3               OVER + SWAP       (NEITHER ADDRESS MAY BE ZERO! )
       4         DO  DUP  C@  FORTH  I  C@  -
       5             IF  0=  LEAVE  ELSE  1+  THEN    LOOP
       6         ELSE  DROP  0=  THEN
       7 : MATCH   ( CURSOR ADDRESS-4, BYTES LEFT-3, STRING ADDRESS-2, )
       8           ( STRING COUNT-1, ---  BOOLEAN-2, CURSOR MOVEMENT-1 )
       9   >R  >R  2DUP  R>  R>  2SWAP  OVER  +  SWAP
      10   ( CADDR-6, BLEFT-5, $ADDR-4, $LEN-3, CADDR+BLEFT-2, CADDR-1 )
      11   DO  2DUP  FORTH   I   -TEXT
      12     IF  >R  2DROP  R>  -  I  SWAP  -  0  SWAP  0  0  LEAVE
      13         (  CADDR BLEFT  $ADDR  $LEN  OR ELSE 0  OFFSET  0  0  )
      14       THEN  LOOP 2DROP   ( CADDR-2, BLEFT-1, OR 0-2, OFFSET-1 )
      15     SWAP  0=  SWAP  ;    -->

     SCR # 95
       0 (  STRING EDITING COMMANDS                        WFR-79MAR24 )
       1 : 1LINE       ( SCAN LINE WITH CURSOR FOR MATCH TO PAD TEXT, *)
       2                              ( UPDATE CURSOR, RETURN BOOLEAN *)
       3        #LAG  PAD  COUNT  MATCH  R#   +!   ;
       4
       5 :  FIND   ( STRING AT PAD OVER FULL SCREEN RANGE, ELSE ERROR *)
       6      BEGIN  3FF  R#  @  <
       7          IF  TOP  PAD  HERE  C/L  1+  CMOVE  0  ERROR  ENDIF
       8          1LINE   UNTIL   ;
       9
      10 : DELETE                    ( BACKWARDS AT CURSOR BY COUNT-1 *)
      11     >R  #LAG  +  FORTH  R  -  ( SAVE BLANK FILL LOCATION )
      12     #LAG  R MINUS  R#  +!     ( BACKUP CURSOR )
      13     #LEAD  +  SWAP  CMOVE
      14     R>  BLANKS  UPDATE  ;   ( FILL FROM END OF TEXT )
      15 -->

     FORTH INTEREST GROUP                                  NOVEMBER 1980


                                     73








     SCR # 96
       0 (  STRING EDITOR COMMANDS                         WFR-79MAR24 )
       1 : N     ( FIND NEXT OCCURANCE OF PREVIOUS TEXT *)
       2       FIND  0  M  ;
       3
       4 : F      ( FIND OCCURANCE OF FOLLOWING TEXT *)
       5       1  TEXT  N  ;
       6
       7 : B      ( BACKUP CURSOR BY TEXT IN PAD *)
       8       PAD  C@  MINUS  M  ;
       9
      10 : X     ( DELETE FOLLOWING TEXT *)
      11       1  TEXT  FIND  PAD  C@  DELETE  0  M  ;
      12
      13 : TILL      ( DELETE ON CURSOR LINE, FROM CURSOR TO TEXT END *)
      14       #LEAD  +  1  TEXT  1LINE  0=  0  ?ERROR
      15       #LEAD  +  SWAP  -  DELETE  0  M  ;     -->

     SCR # 97
       0 (  STRING EDITOR COMMANDS                         WFR-79MAR23 )
       1 : C        ( SPREAD AT CURSOR AND COPY IN THE FOLLOWING TEXT *)
       2     1  TEXT  PAD  COUNT
       3     #LAG  ROT  OVER  MIN  >R
       4     FORTH  R  R#  +!  ( BUMP CURSOR )
       5     R  -  >R          ( CHARS TO SAVE )
       6     DUP  HERE  R  CMOVE  ( FROM OLD CURSOR TO HERE )
       7     HERE  #LEAD  +  R>  CMOVE  ( HERE TO CURSOR LOCATION )
       8     R>  CMOVE  UPDATE   ( PAD TO OLD CURSOR )
       9     0  M  ( LOOK AT NEW LINE )  ;
      10 FORTH  DEFINITIONS   DECIMAL
      11 LATEST   12  +ORIGIN  !   ( TOP NFA )
      12 HERE     28  +ORIGIN  !   ( FENCE )
      13 HERE     30  +ORIGIN  !   ( DP )
      14 '  EDITOR  6  +   32  +ORIGIN  !  ( VOC-LINK )
      15 HERE  FENCE   !      ;S

     SCR # 98
       0
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15

     FORTH INTEREST GROUP                                 MAY 1, 1979


                                     74









                             EDITOR USER MANUAL

                              by Bill Stoddart
                           of FIG, United Kingdom


     FORTH organizes its mass storage into "screens" of 1024 characters.
     If, for example, a diskette of 250k byte capacity is used entirely
     for storing text, it will appear to the user as 250 screens
     numbered 0 to 249.

     Each screen is organized as 16 lines with 64 characters per line.
     The FORTH screens are merely an arrangement of virtual memory and
     need not correspond exactly with the screen format of a particular
     terminal.


                    Selecting a Screen and Input of Text

     To start an editing session the user types EDITOR to invoke the
     appropriate vocabulary.

     The screen to be edited is then selected, using either:

     n LIST  ( list screen n and select it for editing ) OR
     n CLEAR ( clear screen n and select for editing )

     To input new test to screen n after LIST or CLEAR the P (put)
     command is used.

     Example:

     0 P THIS IS HOW
     1 P TO INPUT TEXT
     2 P TO LINES 0, 1, AND 2 OF THE SELECTED SCREEN.





















                                     75









                                Line Editing

     During this description of the editor, reference is made to PAD.
     This is a text buffer which may hold a line of text used by or
     saved with a line editing command, or a text string to be found or
     deleted by a string editing command.

     PAD can be used to transfer a line from one screen to another, as
     well as to perform edit operations within a single screen.


                            Line Editor Commands

     n H     Hold line n at PAD (used by system more often than by user).

     n D     Delete line n but hold it in PAD.  Line 15 becomes blank
             as lines n+1 to 15 move up 1 line.

     n T     Type line n and save it in PAD.

     n R     Replace line n with the text in PAD.

     n I     Insert the text from PAD at line n, moving the old line n
             and following lines down.  Line 15 is lost.

     n E     Erase line n with blanks.

     n S     Spread at line n.  n and subsequent lines move down 1
             line.  Line n becomes blank.  Line 15 is lost.



























                                     76









                      Cursor Control and String Editing

     The screen of text being edited resides in a buffer area of
     storage.  The editing cursor is a variable holding an offset into
     this buffer area.  Commands are provided for the user to position
     the cursor, either directly or by searching for a string of buffer
     text, and to insert or delete text at the cursor position.


                       Commands to Position the Cursor

     TOP     Position the cursor at the start of the screen.

     n M     Move the cursor by a signed amount n and print the cursor
             line.  The position of the cursor on its line is shown by
             a __ (underline).


                           String Editing Commands

     F text      Search forward from the current cursor position until
                 string "text" is found. The cursor is left at the end
                 of the text string, and the cursor line is printed.
                 If the string is not found an error message is given
                 and the cursor is repositioned at the top of screen.

     B           Used after F to back up the cursor by the length of
                 the most recent text.

     N           Find the next occurrence of the string found by an F
                 command.

     X text      Find and delete the string "text."

     C text      Copy in text to the cursor line at the cursor position.

     TILL text   Delete on the cursor line from the cursor till the end
                 of the text string "text."

     NOTE:       Typing C with no text will copy a null into the text
                 at the cursor position.  This will abruptly stop later
                 compiling!  To delete this error type TOP X 'return'.














                                     77









                           Screen Editing Commands

     n LIST      List screen n and select it for editing

     n CLEAR     Clear screen n with blanks and select it for editing

     n1 n2 COPY  Copy screen n1 to screen n2.

     L           List the current screen. The cursor line is relisted
                 after the screen listing, to show the cursor position.

     FLUSH       Used at the end of an editing session to ensure that
                 all entries and updates of text have been transferred
                 to disc.










































                                     78









                               Editor Glossary

     TEXT     c ---
        Accept following text to pad.  c is text delimiter.

     LINE     n --- addr
        Leave address of line n of current screen.  This address will
        be in the disc buffer area.

     WHERE    n1 n2 ---
        n2 is the block no., n1 is offset into block.  If an error is
        found in the source when loading from disc, the recovery
        routine ERROR leaves these values on the stack to help the user
        locate the error.  WHERE uses these to print the screen and
        line nos. and a picture of where the error occurred.

     R#       --- addr
        A user variable which contains the offset of the editing cursor
        from the start of the screen.

     #LOCATE  --- n1 n2
        From the cursor position determine the line-no n2 and the
        offset into the line n1.

     #LEAD    --- line-address offset-to-cursor

     #LAG     --- cursor-address count-after-cursor-till-EOL

     -MOVE    addr line-no ---
        Move a line of text from addr to line of current screen.

     H        n ---
        Hold numbered line at PAD.

     E        n ---
        Erase line n with blanks.

     S        n ---
        Spread.  Lines n and following move down.  n becomes blank.

     D        n ---
        Delete line n, but hold in pad.

     M        n ---
        Move cursor by a signed amount and print its line.

     T        n ---
        Type line n and save in PAD.

     L        ---
        List the current screen.





                                     79








     R        n ---
        Replace line n with the text in PAD.

     P        n ---
        Put the following text on line n.

     I        n ---
        Spread at line n and insert text from PAD.

     TOP      ---
        Position editing cursor at top of screen.

     CLEAR    n ---
        Clear screen n, can be used to select screen n for editing.

     FLUSH    ---
        Write all updated buffers to disc.  This has been modified to
        cope with an error in the Micropolis CPM disc drivers.

     COPY     n1 n2 ---
        Copy screen n1 to screen n2.

     -TEXT    Addr 1 count Addr 2 -- boolean
        True if strings exactly match.

     MATCH    cursor-addr bytes-left-till-EOL str-addr str-count
       ---    tf cursor-advance-till-end-of-matching-text
       ---    ff bytes-left-till-EOL
        Match the string at str-addr with all strings on the cursor
        line forward from the cursor.  The arguments left allow the
        cursor R# to be updated either to the end of the matching text
        or to the start of the next line.

     1LINE    --- f
        Scan the cursor line for a match to PAD text.  Return flag and
        update the cursor R# to the end of matching text, or to the
        start of the next line if no match is found.

     FIND     ---
        Search for a match to the string at PAD, from the cursor
        position till the end of screen.  If no match found issue an
        error message and reposition the cursor at the top of screen.

     DELETE   n ---
        Delete n characters prior to the cursor.

     N        ---
        Find next occurrence of PAD text.

     F        ---
        Input following text to PAD and search for match from cursor
        position till end of screen.





                                     80








     B        ---
        Backup cursor by text in PAD.

     X        ---
        Delete next occurrence of following text.

     TILL     ---
        Delete on cursor line from cursor to end of the following text.

     C        ---
        Spread at cursor and copy the following text into the cursor
        line.













































                                     81