home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / CLIPPER / MISC / FFB.ZIP / FFHLP.ARC / KERNEL1.HLP < prev    next >
Encoding:
Text File  |  1987-12-23  |  13.2 KB  |  353 lines

  1.  
  2.  
  3. The first 8 bytes in the system are vectors to the Cold and Warm
  4. start entries.  You can freely jump to them in code anytime.
  5. The DPUSH and HPUSH labels are space savers.  We jump to them
  6. in several CODE words when we want to push their contents on the
  7. Parameter Stack.
  8. >NEXT is where all the action is.  It is the guts of the Forth
  9. Virtual Machine.  It must advance the interpretive pointer held
  10. in the IP register pair and jump indirect to what it points to.
  11.  
  12. We define a few macros here to make our life a little easier
  13. later.  Using NEXT as a macro allows us to put it inline later.
  14.  
  15. RP    Used to hold the depth of the return stack
  16. NEST  The runtime code for :  It pushs the current IP onto
  17.    the return stack and sets the IP to point to the parameter
  18.    field of the word being executed.
  19. EXIT
  20.      Pop an entry off the return stack and place it into the
  21.      Interpretive Pointer.  Terminates a Hi Level definition.
  22. UNNEST   Same as exit.  Compiled by ; to help decompiling.
  23. DODOES
  24.    The runtime portion of defining words.  First it pushes the
  25.    IP onto the return stack and then it pushes the BODY address
  26.    of the word being executed onto the parameter stack.
  27. DOCREATE   Leave a pointer to its own parameter field on the
  28.    stack.  This is also the runtime for variable.
  29.  
  30. UP   Holds a pointer to the current USER area. ( multitasking )
  31. @USER    A subroutine called from code level words that returns
  32.    the contents of a particular user variable.
  33. !USER    A subroutine called from code level words that sets
  34.    the contents of a particular user variable.
  35.  
  36. DOCONSTANT   The run time code for CONSTANT.  It takes the
  37.    contents of the parameter field and pushes it onto the stack.
  38. DOUSER       The run time code for USER variables.  Places a
  39.    pointer to the current version of this variable on the stack.
  40.    Needed for multitasking.
  41. (LIT)     The runtime code for literals.  Pushes the following
  42.    two bytes onto the parameter stack and moves the IP over
  43.    them.  It is compiled by the word LITERAL.
  44.  
  45.  
  46. BRANCH    Performs an unconditional branch.  Notice that we
  47.    are using absolute addresses insead of relative ones. (fast)
  48. ?BRANCH   Performs a conditional branch.  If the top of the
  49.    parameter stack in True, take the branch.  If not, skip
  50.    over the branch address which is inline.
  51.  
  52. LOOP-EXIT   is a common routine used by (LOOP) and (+LOOP)
  53.    It is called when the loop has terminated and is exited
  54.    normally.
  55. (LOOP)      the runtime procedure for LOOP.  Branches back to
  56.    the beginning of the loop if there are more iterations to
  57.    do.  Otherwise it exits.  The loop counter is incremented.
  58. LOOP-BRANCH   A common routine needed twice in the 8080
  59.    implementation of (+LOOP).
  60. (+LOOP)
  61.    Increment the loop counter by the value on the stack and
  62.    decide whether or not to loop again.  Due to the wierdness
  63.    of the 8080, you have to stand on your head to determine
  64.    the conditions under which you loop or exit.
  65.  
  66. (DO)  The runtime code compiled by DO. Pushes the inline address
  67.    onto the return stack along with values needed by (LOOP).
  68. (?DO)
  69.    The runtime code compiled by ?DO.  The difference between
  70.    ?DO and DO is that ?DO will not perform any iterations if
  71.    the initial index is equal to the final index.
  72. BOUNDS
  73.    Given address and length, make it ok for DO ... LOOP.
  74.  
  75. These are again the TRANSITION versions of the immediate words
  76. for looping.  They compile the correct run time code and then
  77. Mark and Resolve the various branches.
  78.  
  79. >NEXT     The address of the inner interpreter.
  80. EXECUTE   the word whose code field is on the stack.  Very
  81.    useful for passing executable routines to procedures!!!
  82. PERFORM   the word whose code field is stored at the address
  83.    pointed to by the number on the stack.  Same as @ EXECUTE
  84. DO-DEFER  The runtime code for deferred words.  Fetches the
  85.    code field and executes it.
  86. DOUSER-DEFER   The runtime code for User deferred words.  These
  87.    are identical to regular deferred words except that each
  88.    task has its own version.
  89. GO
  90.      Execute code at the given address.
  91. NOOP      One of the most useful words in Forth.  Does nothing.
  92. PAUSE     Used by the Multitasker to switch tasks.
  93.  
  94. I           returns the current loop index.  It now requires
  95.    a little more calculation to compute it than in FIG Forth
  96.    but the tradeoff is a much faster (LOOP).  The loop index
  97.    is stored on the Return Stack.
  98. J           returns the loop index of the inner loop in
  99.    nested DO .. LOOPs.
  100. (LEAVE)
  101.    Does an immediate exit of a DO ... LOOP structure.  Unlike
  102.    FIG Forth which waits until the next LOOP is executed.
  103. (?LEAVE)
  104.    Leaves if the flag on the stack is true.  Continues if not.
  105. LEAVE   I have to do this to be 83-Standard.
  106.  
  107. @
  108.    Fetch a 16 bit value from addr.
  109. !
  110.   Store a 16 bit value at addr.
  111. C@
  112.    Fetch an 8 bit value from addr.
  113. C!
  114.    Store an 8 bit value at addr.
  115.  
  116. CMOVE
  117.    Move a set of bytes from the from address to the to address.
  118.    The number of bytes to be moved is count.  The bytes are
  119.    moved from low address to high address, so overlap is
  120.    possible and in fact sometimes desired.
  121. CMOVE>
  122.    The same as CMOVE above except that bytes are moved in the
  123.    opposite direction, ie from high addresses to low addresses.
  124.  
  125. SP@
  126.      Return the address of the next entry on the parameter stack
  127. SP!  ( Warning, this is different from FIG Forth )
  128.      Sets the parameter stack pointer to the specified value.
  129. RP@
  130.      Return the address of the next entry on the return stack.
  131. RP!  ( Warning, this is different from FIG Forth )
  132.      Sets the return stack pointer to the specified value.
  133.  
  134. DROP
  135.      Throw away the top element of the stack.
  136. DUP
  137.      Duplicate the top element of the stack.
  138. SWAP
  139.      Exchange the top two elements on the stack.
  140. OVER
  141.    Copy the second element to the top.
  142.  
  143. TUCK
  144.    Tuck the first element under the second one.
  145. NIP
  146.    Drop the second element from the stack.
  147. ROT
  148.    Rotate the top three element, bringing the third to the top.
  149. -ROT
  150.    The inverse of ROT.  Rotates the top element to third place.
  151. FLIP
  152.    Exhange the hi and low halves of a word.
  153. ?DUP
  154.    Duplicate the top of the stack if it is non-zero.
  155.  
  156. R>
  157.    Pops a value off of the return stack and pushes it onto the
  158.    parameter stack.  It is dangerous to use this randomly!
  159. >R
  160.    Pops a value off of the parameter stack and pushes it onto
  161.    return stack.  It is dangerous to use this randomly!
  162. R@
  163.    Copies the value on the return stack to the parameter stack.
  164. PICK   Reaches into the stack and grabs an element, copying it
  165.    to the top of the stack.  For example, if the stack has 1 2 3
  166.    Then 0 PICK is 3, 1 PICK is 2, and 2 PICK is 1.
  167. ROLL
  168.    Similar to SHAKE and RATTLE.  Should be avoided.
  169.    1 ROLL is SWAP, 2 ROLL is ROT, etc.
  170.    ROLL can be useful, but it is slow.
  171. AND
  172.    Returns the bitwise AND of n1 and n2 on the stack.
  173.  
  174. OR
  175.    Returns the bitwise OR of n1 and n2 on the stack.
  176.  
  177. XOR
  178.    Returns the bitwise Exclusive Or of n1 and n2 on the stack.
  179.  
  180. NOT
  181.   Does a ones complement of the top.  Equivalent to -1 XOR.
  182.  
  183. TRUE FALSE     Constants for clarity.
  184. YES            Push a true flag on the stack and jump to next
  185. NO             Push a false flag on the stack and jump to next
  186. CSET  Set the contents of addr so that the bits that are 1 in n
  187.       are also 1 in addr.  Equivalent to DUP C@ ROT OR SWAP C!
  188. CRESET
  189.    Set the contents of addr so the the bits that are 1 in n
  190.    are zero in addr.  Equivalent to DUP C@ ROT NOT AND SWAP C!
  191. CTOGGLE   Flip the bits in addr by the value n.  Equivalent to
  192.          DUP C@ ROT XOR SWAP C!
  193. ON
  194.    Set the contents of addr to TRUE
  195. OFF
  196.    Set the contents of addr to FALSE
  197.  
  198. +
  199.    Add the top two numbers on the stack and return the result.
  200. NEGATE
  201.    Turn the number into its negative.  A twos complement op.
  202. -
  203.    Subtracts n2 from n1 leaving the result on the stack.
  204.  
  205. ABS
  206.    Return the absolute value of the 16 bit integer on the stack
  207. +!
  208.    Increment the value at addr by n.  This is equivalent to
  209.    the following:   DUP @ ROT + SWAP ! but much faster.
  210. 0 1    Frequently used constants
  211. 2 3    Are faster and more code efficient.
  212.  
  213. 2*
  214.    Double the number on the Stack.
  215. 2/
  216.    Shift the number on the stack right one bit.  Equivalent to
  217.    division by 2 for positive numbers.
  218. U2/
  219.    16 bit logical right shift.
  220.  
  221. 8*
  222.    Multiply the top of the stack by 8.
  223.  
  224. 1+    Increment the top of the stack by one.
  225. 2+    Increment the top of the stack by two.
  226. 1-    Decrement the top of the stack by one.
  227. 2-    Decrement the top of the stack by two.
  228. You could write a whole book about multiplication and division,
  229. and in fact Knuth did.  Suffice it to say that UM* is the basic
  230. multiplication primitive in Forth.  It takes two unsigned 16 bit
  231. integers and returns an unsigned 32 bit result.  All other
  232. multiplication functions are derived from this primitive one.
  233.  
  234. It probably isn't particularly fast or elegant, but that is
  235. because I never liked arithmetic and I stole this implementation
  236. from FIG Forth anyway.
  237.  
  238. U*D is a synonym for UM*
  239.  
  240.  
  241. These are various subroutines used by the division primitive in
  242. Forth, namely U/.  Again I must give credit for them to FIG
  243. Forth, since if I can't even understand multiply,
  244. divide would be completely hopeless.
  245.  
  246. UM/MOD
  247.    This is the division primitive in Forth.  All other division
  248.    operations are derived from it.  It takes a double number,
  249.    d1, and divides by by a single number n1.  It leaves a
  250.    remainder and a quotient on the stack.  For a clearer
  251.    understanding of arithmetic consult Knuth Volume 2 on
  252.    Seminumerical Algorithms.
  253.  
  254. 0=
  255.   Returns True if top is zero, False otherwise.
  256. 0<
  257.   Returns true if top is negative, ie sign bit is on.
  258. 0>
  259.   Returns true if top is positive.
  260. 0<>
  261.   Returns true if the top is non-zero, False otherwise.
  262. =
  263.    Returns true if the two elements on the stack are equal,
  264.    False otherwise.
  265. <>   Returns true if the two element are not equal, else false.
  266. ?NEGATE   Negate the second element if the top is negative.
  267.  
  268. U< Compare the top two elements on the stack as unsigned
  269.    integers and return true if the second is less than the
  270.    first.  Be sure to use U< whenever comparing addresses, or
  271.    else strange things will happen beyond 32K.
  272. U> Compare the top two elements on the stack as unsigned
  273.    integers.  True if n1 > n2 unsigned.
  274. <  Compare the top two elements on the stack as signed
  275.    integers and return true if n1 < n2.
  276. >  Compare the top two elements on the stack as signed
  277.    integers and return true if n1 > n2.
  278.  
  279. MIN     Return the minimum of n1 and n2
  280. MAX     Return the maximum of n1 and n2
  281. BETWEEN  Return true if min <= n1 <= max, otherwise false.
  282. WITHIN   Return true if min <= n1 < max, otherwise false.
  283. 2@
  284.    Fetch a 32 bit value from addr.
  285.  
  286. 2!
  287.    Store a 32 bit value at addr.
  288.  
  289. 2DROP
  290.    Drop the top two elements of the stack.
  291. 2DUP
  292.    Duplicate the top two elements of the stack.
  293. 2SWAP
  294.    Swap the top two pairs of numbers on the stack.  You can use
  295.    this operator to swap two 32 bit integers and preserve
  296.    their meaning as double numbers.
  297. 2OVER
  298.    Copy the second pair of numbers over the top pair.  Behaves
  299.    like 2SWAP for 32 bit integers.
  300. 3DUP    Duplicate the top three elements of the stack.
  301. 4DUP    Duplicate the top four elements of the stack.
  302. 2ROT    rotates top three double numbers.
  303.  
  304. D+
  305.    Add the two double precision numbers on the stack and
  306.    return the result as a double precision number.
  307.  
  308. DNEGATE
  309.    Same as NEGATE except for double precision numbers.
  310.  
  311. S>D
  312.    Take a single precision number and make it double precision
  313.    by extending the sign bit to the upper half.
  314. DABS
  315.    Return the absolute value of the 32 bit integer on the stack
  316.  
  317. D2*
  318.    32 bit left shift.
  319. D2/
  320.    32 bit arithmetic right shift. Equivalent to divide by 2.
  321.  
  322. D-   Subtract the two double precision numbers.
  323. ?DNEGATE    Negate the double number if the top is negative.
  324.  
  325. D0=     Compare the top double number to zero.  True if d = 0
  326. D=      Compare the top two double numbers.  True if d1 = d2
  327. DU<     Performs unsigned comparison of two double numbers.
  328. D<      Compare the top two double numbers.  True if d1 < d2
  329. D>      Compare the top two double numbers.  True if d1 > d2
  330. DMIN    Return the lesser of the top two double numbers.
  331. DMAX    Return the greater of the the top two double numbers.
  332.  
  333. This does all the arithmetic you could possibly want and even
  334. more.  I can never remember exactly what the order of the
  335. arguments is for any of these, except maybe * / and MOD, so I
  336. suggest you just try it when you are in doubt.  That is one
  337. of the nice things about having an interpreter around, you can
  338. ask it questions anytime and it will tell you the answer.
  339.  
  340. *D  multiplys two singles and leaves a double.
  341. M/MOD  divides a double by a single, leaving a single quotient
  342.    and a single remainder. Division is floored.
  343. MU/MOD  divides a double by a single, leaving a double quotient
  344.    and a single remainder. Division is floored.
  345.  
  346.  
  347. */ is a particularly useful operator, as it allows you to
  348. do accurate arithmetic on fractional quantities.  Think of
  349. it as multiplying n1 by the fraction n2/n3.  The intermediate
  350. result is kept to full accuracy.  Notice that this is not the
  351. same as * followed by /.  See Starting Forth for more examples.
  352.  
  353.