OpenCores
URL https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [nvram.txt] - Rev 5

Compare with Previous | Blame | View Log

\ ==== Boot Block ==============================================
-1 loaded !














; ==== Short Help ==============================================
This is a subroutine threaded Forth, based on eForth. The
starting base in in hexadecimal. A tutorial, word glossary and
extra code is stored in block storage. A short list of commands
follows ('#' are numbers):

  words       list all Forth words
  see         decompile the next word in the input stream
  # #2 index  get descriptive titles for blocks from '#' to '#2'
  # list      list block number '#'
  # load      execute code in block '#'
  # #2 thru   execute code in blocks '#' to '#2'




; ==== Forth Error Messages: 1/4 ===============================
  -1 ABORT
  -2 ABORT"
  -3 stack overflow
  -4 stack underflow
  -5 return stack overflow
  -6 return stack underflow
  -7 do-loops nested too deeply during execution
  -8 dictionary overflow
  -9 invalid memory address
 -10 division by zero
 -11 result out of range
 -12 argument type mismatch
 -13 undefined word
 -14 interpreting a compile-only word
 -15 invalid FORGET
; ==== Forth Error Messages: 2/4 ===============================
 -16 attempt to use zero-length string as a name
 -17 pictured numeric output string overflow
 -18 parsed string overflow
 -19 definition name too long
 -20 write to a read-only location
 -21 unsupported operation
 -22 control structure mismatch
 -23 address alignment exception
 -24 invalid numeric argument
 -25 return stack imbalance
 -26 loop parameters unavailable
 -27 invalid recursion
 -28 user interrupt
 -29 compiler nesting
 -30 obsolescent feature
; ==== Forth Error Messages: 3/4 ===============================
 -31 >BODY used on non-CREATEd definition
 -32 invalid name argument (e.g., TO xxx)
 -33 block read exception
 -34 block write exception
 -35 invalid block number
 -36 invalid file position
 -37 file I/O exception
 -38 non-existent file
 -39 unexpected end of file
 -40 invalid BASE for floating point conversion
 -41 loss of precision
 -42 floating-point divide by zero
 -43 floating-point result out of range
 -44 floating-point stack overflow
 -45 floating-point stack underflow
; ==== Forth Error Messages: 4/4 ===============================
 -46 floating-point invalid argument
 -47 compilation word list deleted
 -48 invalid POSTPONE
 -49 search-order overflow
 -50 search-order underflow
 -51 compilation word list changed
 -52 control-flow stack overflow
 -53 exception stack overflow
 -54 floating-point underflow
 -55 floating-point unidentified fault
 -56 QUIT
 -57 exception in sending or receiving a character
 -58 [IF], [ELSE], or [THEN] exception


; ==== Description of this file ================================
The next screens contain extra code that can be loaded into the
interpreter if needed. Some of the standard Forth words are
placed here instead of in the image to save on space.

The blocks should be loaded in order unless otherwise stated.

This file is first converted by a utility into a fixed width
format, which can then be loaded onto the target board with
the same utility used to uploaded the bitfile to the FPGA.

Line lengths are limited to 64 characters wide, each block 
contains 16 lines. The first line should contain a 
description of the block so that when it is displayed with
'index' a glossary can be viewed, allowing quick navigation.

; ==== Scratch Block ===========================================















\ ==== Block Editor 1/2 ========================================
( Block Editor: There is a help section later on )
variable editor-voc 0 editor-voc ! forth
: editor decimal editor-voc 1 set-order ;
get-order editor-voc swap 1+ set-order
$40 constant c/l $10 constant l/b
: (block) blk @ block ;
: (check) dup b/buf c/l / u>= if -24 throw then ;
: (line) (check) c/l * (block) + ;
: b block drop ;
: l blk @ list ;
: n  1 +block b l ;
: p -1 +block b l ;
: d (line) c/l blank ;
: x (block) b/buf blank ;
: s update save-buffers ;
\ ==== Block Editor 2/2 ========================================
: q forth save-buffers ;
: e forth blk @ load editor ;
: ia c/l * + (block) + source drop >in @ +
  swap source nip >in @ - cmove [compile] \ ;
: i 0 swap ia ;
: u update ;
: w words ;
: yank pad c/l ;
: c (line) yank >r swap r> cmove ;
: y (line) yank cmove ;
: ct swap y c ;
: ea (line) c/l evaluate ;
: sw 2dup y (line) swap (line) swap c/l cmove c ;
forth

\ ==== Assembler word set ======================================
variable assembler-voc
bl parse rdrop pad pack$ find drop assembler-voc !
: assembler assembler-voc 1 set-order ;
: ;code assembler ; immediate
: code [compile] : assembler ;
get-order assembler-voc swap 1+ set-order
: end-code forth [compile] ; ; immediate
: words words ;
: forth forth ;
forth





\ ==== CORDIC 1/2 ==============================================
variable lookup -1 cells allot ( 16 values )
$3243 , $1DAC , $0FAD , $07F5 , $03FE , $01FF , $00FF , $007F ,
$003F , $001F , $000F , $0007 , $0003 , $0001 , $0000 , $0000 ,

: arshift ( n u -- n : arithmetic right shift )
  2dup rshift >r swap $8000 and
  if $10 swap - -1 swap lshift else drop 0 then r> or ;

$26DD constant cordic_1K $6487 constant pi/2

variable tx 0 tx ! variable ty 0 ty ! variable tz 0 tz !
variable x  0  x ! variable y  0  y ! variable z  0  z !
variable d  0  d ! variable k  0  k !


\ ==== CORDIC 2/2 ==============================================
( CORDIC: valid in range -pi/2 to pi/2, arguments are in fixed )
( point format with 1 = 16384, angle is given in radians.  )
: cordic ( angle -- sine cosine )
  z ! cordic_1K x ! 0 y ! 0 k !
  $10 begin ?dup while
    z @ 0< d !
    x @ y @ k @ arshift d @ xor d @ - - tx !
    y @ x @ k @ arshift d @ xor d @ - + ty !
    z @ k @ cells lookup + @ d @ xor d @ - - tz !
    tx @ x ! ty @ y ! tz @ z !
    k 1+!
    1-
  repeat y @ x @ ;
: sin cordic drop ;
: cos cordic nip ;
\ ==== Login Code 1/2 ==========================================
\ Login and user management system
: generate count dup >r crc r> ccitt ; ( b -- u )
: .user     ." user>" space ; ( -- )
: .password ." password>" space ; ( -- )
variable user0 0 user0 !
: mk.user ( --; <string1>, <string2> )
  here user0 @ , user0 ! here 0 , bl word count 1+ allot align
  drop bl word generate swap ! ;
: ls.user ( -- : list all users in user database )
  cr user0 @
  begin dup while dup 2 cells + space count type cr @ repeat
  drop cr ;
: find.user ( a -- u | 0 : find user in database, return hash )
  >r user0 @ begin dup while dup 2 cells + count r@ count
  =string if rdrop exit then @ repeat rdrop drop 0 ;
\ ==== Login Code 2/2 ==========================================
: (password) ( u --, <string> )
  >r begin .password query bl word cr generate
  r@ = until rdrop ;
: fake .password query bl word drop cr ;
: (user)
  begin .user query bl word cr find.user ?dup until ;
: retry ( xt -- : retry word until it succeeds )
  >r begin r@ catch 0= until rdrop ;
: user?     ' (user)     retry ;
: password? ' (password) retry ;
: hide-all 0 1 set-order ;
: login hide-all
  cr user? cell+ @ conceal password? interactive forth ;
mk.user guest guest     mk.user archer dangerzone
mk.user lana  sterling  mk.user cyril  figgis
\ ==== Extra Code 1/7 ==========================================
: 2+ 2 + ;                       ( n -- n )
: 2- 2 - ;                       ( n -- n )
: >= < invert ;                  ( n n -- f )
: simulation? cpu-id $0666 <> ; ( -- f : are we in the matrix? )
: 0<= 0> 0= ;                    ( n n -- f )
: 0>= 0< 0= ;                    ( n n -- f )
: not -1 xor ;                   ( n -- n )
: dabs dup 0< if dnegate then ;  ( d -- d )
: d+  >r swap >r um+ r> r> + + ; ( d d -- d )
: d=  >r swap r> = >r = r> and ; ( d d -- f )
: d<> d= 0= ;                    ( d d -- f )
: roll  dup 0> if swap >r 1- recurse r> swap else drop then ;
: ?exit if rdrop then ;          ( n --, R: n -- n | )
: 2rdrop r> rdrop rdrop >r ;     ( R n n -- )
: 2. swap . . ;                  ( n n -- )
\ ==== Extra Code 2/7 ==========================================
: m* 2dup xor 0< >r abs swap abs um* r> if dnegate then ;
: */mod  >r m* r> m/mod ;  ( n n n -- r q )
: */  */mod nip ;          ( n n n -- q )
: s>d dup 0< ;             ( n -- d : single to double )
: holds begin dup while 1- 2dup + c@ hold repeat 2drop ;
: binary  2 base ! ;                       ( -- )
: octal  8 base ! ;                        ( -- )
: .base base @ dup decimal base ! ; ( -- )
: only -1 set-order ;
: also get-order over swap 1+ set-order ;
: previous get-order swap drop 1- set-order ;
: buffer block ; ( k -- a )
: bye [ 0 , ] ;
: enum dup constant 1+ ; ( n --, <string> )
: logical 0= 0= ;     ( n -- f )
\ ==== Extra Code 3/7 ==========================================
: square dup * ;      ( n -- )
: limit rot min max ; ( n lo hi -- n )
: odd 1 and logical ; ( n -- )
: even odd invert ;   ( n -- )
: nor or invert ;     ( u u -- u )
: nand and invert ;   ( u u -- u )
: bell 7 emit ;       ( -- )
: under >r dup r> ;   ( n1 n2 -- n1 n1 n2 )
: 2nip >r >r 2drop r> r> ; ( n1 n2 n3 n4 -- n3 n4 )
( n1 n2 n3 n4 -- n1 n2 n3 n4 n1 n2 )
: 2over >r >r 2dup r> swap >r swap r> r> -rot ;
: 2swap >r -rot r> -rot ; ( n1 n2 n3 n4 -- n3 n4 n1 n2 )
: 2tuck 2swap 2over ; ( n1 n2 n3 n4 -- n3 n4 n1 n2 n3 n4 )
: 4drop 2drop 2drop ; ( n1 n2 n3 n4 -- )
: trip dup dup ; ( n -- n n n )
\ ==== Extra Code 4/7 ==========================================
: log  >r 0 swap ( u base -- u )
  begin swap 1+ swap r@ / dup 0= until
  drop 1- rdrop ;
: log2 0 swap ( u -- u )
  begin swap 1+ swap   2/ dup 0= until
  drop 1- ;
: average um+ 2 um/mod nip ; ( u u -- u )
: <=> 2dup > if 2drop -1 exit then < ;
: bounds over + swap ;
: 2, , , ; ( n n -- )
: tab 9 emit ; ( -- )
: drup drop dup ; ( n1 n2 -- n1 n1 )
: lsb $FF and ; ( u -- u )
: --> 1 +block load ;
: scr blk ;
\ ==== Extra Code 5/7 ==========================================
: signum ( n -- -1 | 0 | 1 : Signum function )
  dup 0> if drop  1 exit then
      0< if      -1 exit then
      0 ;
: >< dup 8 rshift swap 8 lshift or ; ( u -- u : swap bytes )
: #digits dup 0= if 1+ exit then base @ log 1+ ;
: ** ( n u -- n )
  ?dup if
    over >r
    begin
      dup 1 >
    while
      swap r@ * swap 1-
    repeat rdrop drop
  else logical 1 and then ;
\ ==== Extra Code 6/7 ==========================================
: b. base @ swap 2 base ! u. base ! ; ( u -- )
: h. base @ swap hex u. base ! ;      ( u -- )
: o. base @ swap 8 base ! u. base ! ; ( u -- )
: d. base @ swap decimal . base ! ;   ( n -- )
: @bits swap @ and ;                  ( a u -- u )
: ?\ if [compile] \ then ; immediate
: ?( if [compile] ( then ; immediate ( )
: defined? ( -- pwd -1 | 0, <string> : is word defined? )
  bl word find if -1 else drop 0 then ;
: ?if compile dup [compile] if ; immediate
: ?dup-if compile ?dup [compile] if ; immediate
: >body ( dup @ $4000 or <> if 31 -throw then ) cell+ ;



\ ==== Extra Code 7/7 ==========================================
: screens ( k1 k2 -- : list blocks k1 to k2 )
  over -
  for
    dup . dup list 1+ key $D = if rdrop drop exit then
  next drop ;










\ ==== Roulette ================================================
\ Russian Roulette: It would be interesting to do something
\ killed the computer when the player dies

: click ."  *click*" cr ;
: bang  ."  BANG!" cr ;
: roulette random 6 mod if click else bang then ; ( -- )









\ ==== Extended ANSI Escape Codes ==============================
0 constant black 1 constant red 2 constant green 4 constant blue
red green        + constant yellow
    green blue   + constant cyan
red       blue   + constant magenta
red green blue + + constant white
: background $A + ;
: color $1E + sgr ;
\ : hide-cursor CSI [char] ? emit $19 10u. [char] l emit ;
\ : show-cursor CSI [char] ? emit $19 10u. [char] h emit ;
: up    [char] A ansi ; ( n -- )
: down  [char] B ansi ; ( n -- )
: left  [char] C ansi ; ( n -- )
: right [char] D ansi ; ( n -- )


\ ==== Screen Saver ============================================
\ An incredibly simple screen saver using ANSI Escape codes
\ for placement and coloring of random characters
base @ decimal
: screen-saver ( -- )
  page
  begin
    random 79 mod
    random 38 mod at-xy
    random >char emit
    random 8  mod
    random 1 and if background then
    random 256 and ms color
  again ;
base !

; ==== Game: YOU ARE DEAD (HELP) ===============================
This is a clone of the one dimensional rogue like game
available at <https://github.com/rupa/YOU_ARE_DEAD>. The
object is to get to the other side of the screen.

Keys:
w  Turn into '.'
a  Turn into '~'
s  Turn into '>'
d  Move right
q  Quit

Block number 7 is used to store the game state.



\ ==== Game: YOU ARE DEAD 1/6 ==================================
forth variable yad-voc get-order yad-voc swap 1+ set-order
$40 constant c/l $10 constant l/b
: memory 7 block ;
: variables memory c/l + ;
: score    variables 0 cells + ;
: position variables 1 cells + ;
: level    variables 2 cells + ;
: form     variables 3 cells + ;
: continue variables 4 cells + ;
: end c/l 1- ;
: player form @ ;
: .player position @ 1+ 3 at-xy player emit ;
: .goal c/l 3 at-xy [char] # emit ;
: .score ." SCORE: " score @ 5 u.r ;
: .level ." LEVEL: " level @ 5 u.r ;
\ ==== Game: YOU ARE DEAD 2/6 ==================================
: show
  page cr cr space memory c/l type
  .player .goal
  cr .score space .level cr ;

: select ( n -- c )
  dup 0=  if drop [char] <  exit then
  dup 1 = if drop [char] ~  exit then
  dup 2 = if drop [char] .  exit then
  drop bl ;

: die ." YOU ARE DEAD" cr 0 continue ! -56 throw ;
: survived ." YOU SURVIVED" cr .score cr ;
: forms form c@ position @ memory + c@ ; ( -- c c )

\ ==== Game: YOU ARE DEAD 3/6 ==================================
: generate ( -- generate a level )
  c/l 1- for
    random 5 mod ( 3 = most difficult )
    select memory r@ + c!
  next
  bl memory c! bl memory end + c! ;
: normal [char] x ;
: setup ( -- )
  -1 continue !
  memory b/buf 0 fill
  normal form c!
  generate ;

: +score random 4 mod 1 min score +! ; ( -- )
: ?next <> if die else +score then ; ( c c -- )
\ ==== Game: YOU ARE DEAD 4/6 ==================================
: +level
  0 position ! level 1+!
  random 23 mod 5 min score +!
  generate ;

: monster swap >r forms r> = if ?next else 2drop then ;

: command ( -- f )
  dup [char] w = if drop [char] . form c! 0 exit then
  dup [char] a = if drop [char] ~ form c! 0 exit then
  dup [char] d = if drop -1 exit then
  dup [char] s = if drop [char] < form c! 0 exit then
  dup [char] q = if drop -56 throw then
  drop 0 ;

\ ==== Game: YOU ARE DEAD 5/6 ==================================
: rules
  position @ end = if +level exit then
  forms = if exit then
  [char] ~ [char] < monster
  [char] . [char] ~ monster
  [char] < [char] . monster
  normal form c!
  bl position @ memory + c!
  score 1+!
  position 1+! ;





\ ==== Game: YOU ARE DEAD 6/6 ==================================
: game
  begin
  show
  key command if rules then
  level @ 9 >
  until survived ;


: play setup ' game catch drop ;
get-order -rot swap rot set-order
: you-are-dead base @ decimal play base ! ;
forth
\ : resume memory drop ' game catch drop ;


; ==== Sokoban: Instructions ===================================
To run, load the next blocks 9 blocks, which contain the code
for the Sokoban game. The object of the game is to maneuver the
boulders (*) onto the pads (.) with the player character (@/~),
until all the bolders are on the pads. Sokoban levels are 
stored one per block. To play:

  $2A sokoban

Would load a game stored in block '$2A' and begin playing.
The WASD keys move the player around, 'h' is for help, and
'q' quits.




\ ==== Sokoban 1/9 =============================================
\ only forth definitions hex
\ variable sokoban-wordlist sokoban-wordlist +order definitions
blk @ 1- constant help-block
char X constant wall
char * constant boulder
char . constant off
char & constant on
char @ constant player
char ~ constant player+ ( player + off pad )
$10    constant l/b     ( lines   per block )
$40    constant c/b     ( columns per block )
     7 constant bell    ( bell character )
variable position  ( current player position )
variable moves     ( moves made by player )
create rule 3 c, 0 c, 0 c, 0 c, 
\ ==== Sokoban 2/9 =============================================
: n1+ swap 1+ swap ; ( n n -- n n )
: match              ( a a -- f )
  n1+ ( replace with umin of both counts? )
  count 
  for aft  
    count rot count rot <> if 2drop rdrop 0 exit then
  then next 2drop -1 ;

: beep bell emit ; ( -- )
: ?apply           ( a a a -- a, R: ? -- ?| )
  >r over swap match if drop r> rdrop exit then rdrop ;




\ ==== Sokoban 3/9 =============================================
: apply ( a -- a )
 $" @ "  $"  @"  ?apply 
 $" @."  $"  ~"  ?apply
 $" @* " $"  @*" ?apply
 $" @*." $"  @&" ?apply
 $" @&." $"  ~&" ?apply
 $" @& " $"  ~*" ?apply
 $" ~ "  $" .@"  ?apply
 $" ~."  $" .~"  ?apply
 $" ~* " $" .@*" ?apply
 $" ~*." $" .@&" ?apply
 $" ~&." $" .~&" ?apply
 $" ~& " $" .~*" ?apply beep ;


\ ==== Sokoban 4/9 =============================================
: pack ( c0...cn b n -- )
  2dup swap c! for aft 1+ tuck c! then next drop ; 

: locate ( b u c -- u f )
  >r
  begin
    ?dup
  while
    1- 2dup + c@ r@ = if nip rdrop -1 exit then
  repeat
  rdrop
  drop
  0 0 ; 


\ ==== Sokoban 5/9 =============================================
: 2* 1 lshift ; ( u -- )
: relative swap c/b * + + ( $3FF and ) ; ( +x +y pos -- pos )
: +position position @ relative ; ( +x +y -- pos )
: double 2* swap 2* swap ;  ( u u -- u u )
: arena blk @ block b/buf ; ( -- b u )
: >arena arena drop + ;     ( pos -- a )
: fetch                     ( +x +y -- a a a )
  2dup   +position >arena >r
  double +position >arena r> swap
  position @ >arena -rot ;
: rule@ fetch c@ rot c@ rot c@ rot ; ( +x +y -- c c c )
: 3reverse -rot swap ;               ( 1 2 3 -- 3 2 1 )
: rule! rule@ 3reverse rule 3 pack ; ( +x +y -- )
: think 2dup rule! rule apply >r fetch r> ; ( +x +y --a a a a )
: count! count rot c! ;              ( a a -- )
\ ==== Sokoban 6/9 =============================================
\ 'act' could be made to be more elegant, but it works, it 
\ handles rules of length 2 and length 3
: act ( a a a a -- )
  count swap >r 2 = 
  if 
     drop swap r> count! count! 
  else 
     3reverse r> count! count! count! 
  then drop ;
: #boulders ( -- n )
   0 arena 
   for aft 
     dup c@ boulder = if n1+ then 
     1+ 
   then next drop ; 
\ ==== Sokoban 7/9 =============================================
: .boulders  ." BOULDERS: " #boulders u. cr ; ( -- )
: .moves    ." MOVES: " moves    @ u. cr ; ( -- )
: .help     ." WASD - MOVEMENT" cr ." H    - HELP" cr ; ( -- )
: .maze blk @ list ;                  ( -- )
: show ( page cr ) .maze .boulders .moves .help ; ( -- )
: solved? #boulders 0= ;               ( -- )
: finished? solved? if 1 throw then ; ( -- )
: instructions blk @ help-block list block drop key drop ; 
: where >r arena r> locate ;          ( c -- u f )
: player? player where 0= if drop player+ where else -1 then ; 
: player! player? 0= throw position ! ; ( -- )
: start player! 0 moves ! ;           ( -- )
: .winner show cr ." SOLVED!" cr ;    ( -- )
: .quit cr ." Quitter!" cr ;          ( -- )
: finish 1 = if .winner exit then .quit ; ( n -- )
\ ==== Sokoban 8/9 =============================================
: rules think act player! ;           ( +x +y -- )
: +move 1 moves +! ;                  ( -- )
: ?ignore over <> if rdrop then ;     ( c1 c2 --, R: x -- | x )
: left  [char] a ?ignore -1  0 rules +move ; ( c -- c )
: right [char] d ?ignore  1  0 rules +move ; ( c -- c )
: up    [char] w ?ignore  0 -1 rules +move ; ( c -- c )
: down  [char] s ?ignore  0  1 rules +move ; ( c -- c )
: help  [char] h ?ignore instructions ; ( c -- c )
: end   [char] q ?ignore 2 throw ; ( c -- | c, R ? -- | ? )
: default drop ;  ( c -- )
: command up down left right help end default finished? ;
: maze! block drop ; ( k -- )
: input key ;        ( -- c )


\ ==== Sokoban 9/9 =============================================
\ sokoban-wordlist -order definitions
\ sokoban-wordlist +order

: sokoban ( k -- )
  maze! start 
  begin 
    show input ' command catch ?dup 
  until finish ;







; ==== Sokoban Map 1 ===========================================

                    XXXXX             
                    X   X             
                    X*  X             
                  XXX  *XXX           
                  X  *  * X           
                XXX X XXX X     XXXXXX
                X   X XXX XXXXXXX  ..X
                X *  *             ..X
                XXXXX XXXX X@XXXX  ..X
                    X      XXX  XXXXXX
                    XXXXXXXX          
                


; ==== Sokoban Map 2 ===========================================

               XXXXXXXXXXXX  
               X..  X     XXX
               X..  X *  *  X
               X..  X*XXXX  X
               X..    @ XX  X
               X..  X X  * XX
               XXXXXX XX* * X
                 X *  * * * X
                 X    X     X
                 XXXXXXXXXXXX
 


              
; ==== Sokoban Map 3 ===========================================

                       XXXXXXXX 
                       X     @X 
                       X *X* XX 
                       X *  *X  
                       XX* * X  
               XXXXXXXXX * X XXX
               X....  XX *  *  X
               XX...    *  *   X
               X....  XXXXXXXXXX
               XXXXXXXX         




; ==== Sokoban Map 4 ===========================================

                             XXXXXXXX
                             X  ....X
                  XXXXXXXXXXXX  ....X
                  X    X  * *   ....X
                  X ***X*  * X  ....X
                  X  *     * X  ....X
                  X ** X* * *XXXXXXXX
               XXXX  * X     X       
               X   X XXXXXXXXX       
               X    *  XX            
               X **X** @X            
               X   X   XX            
               XXXXXXXXX             

\ ==== Game of Life: 1/4 =======================================
\ This is a Game Of Life implementation, originally from 
\ <http://wiki.c2.com/?ForthBlocks>. It has been adapted so
\ instead of blocks it uses 1KiB buffers at arbitrary memory
\ locations.
   $40 constant c/b
   $10 constant l/b
c/b 1- constant c/b>
l/b 1- constant l/b>
    bl constant off
char * constant on
variable state1
variable state2
variable statep


\ ==== Game of Life: 2/4 =======================================
: wrapy dup 0< if drop l/b> then dup l/b> > if drop 0 then ;
: wrapx dup 0< if drop c/b> then dup c/b> > if drop 0 then ;
: wrap  wrapy swap wrapx swap ;
: row c/b * + ; ( a u -- a )
: deceased? wrap row state2 @ ( block ) + c@ on <> ;
: living?  deceased? 0= ;
: (-1,-1) 2dup 1- swap 1- swap living? 1 and ;
: (0,-1)  >r 2dup 1- living? 1 and r> + ;
: (1,-1)  >r 2dup 1- swap 1+ swap living? 1 and r> + ;
: (-1,0)  >r 2dup swap 1- swap living? 1 and r> + ;
: (1,0)   >r 2dup swap 1+ swap living? 1 and r> + ;
: (-1,1)  >r 2dup 1+ swap 1- swap living? 1 and r> + ;
: (0,1)   >r 2dup 1+ living? 1 and r> + ;
: (1,1)   >r 1+ swap 1+ swap living? 1 and r> + ;
: mates (-1,-1) (0,-1) (1,-1) (-1,0) (1,0) (-1,1) (0,1) (1,1) ;
\ ==== Game of Life: 3/4 =======================================
: born?  mates 3 = ;
: survives?  2dup living? -rot mates 2 = and ;
: lives?  2dup born? -rot survives? or ;        ( u u -- )
: newstate  state1 @ ( block update ) statep ! ; ( -- )
: state!  statep @ c! 1 statep +! ;             ( c -- )
: alive  on state! ;                            ( -- )
: dead  off state! ;                            ( -- )
: cell?  2dup swap lives? if alive else dead then ; ( u u -- )
: rows   0 begin dup c/b < while cell? 1+ repeat drop ;
: iterate-block 0 begin dup l/b < while rows 1+ repeat drop ;
: generation  state2 @ state1 @ state2 ! state1 ! ;
: iterate  newstate iterate-block generation ; ( -- )
: done?  key [char] q = ;                      ( -- f )
: prompt  cr ." q to quit" cr ;                ( -- )
: .line l/b> swap - row c/b type cr ;          ( b u -- )
\ ==== Game of Life: 4/4 =======================================
: view state2 @ l/b> for dup r@ .line next drop prompt ;
\ : view (  page ) state2 @ list prompt ;      ( -- )
: game  begin page view iterate done? until ;  ( -- )
: life state2 ! state1 ! game ;                ( a a -- )

cr .( Usage: $3000 $32 block life ) cr









; ==== Game of Life: Glider ====================================





              ***
              *
               *







; ==== Brain F*ck Compiler Help 1/2 ============================
Brainfuck is a simple esoteric language with only 8 commands, it
is Turing complete which means it can compute any function which
can be computed - although it is very difficult to do so. The
commands operate on a block of memory 1024 bytes long. A data
pointer indexes into the memory. The commands are:

  >  increment the data pointer
  <  decrement the data pointer
  +  increment value at data pointer
  -  decrement value at data pointer
  .  output byte at data pointer
  ,  accept one byte and store it at data pointer
  [  branch forward to ] if byte at data pointer is zero
  ]  branch back    to [ if byte at data pointer is non-zero
The compiler discards all other input.
; ==== Brain F*ck Compiler Help 2/2 ============================
The following blocks implement the compiler, it translates each
command in a given string into Forth code, compiling it into a
new word definition which can then be executed.

Needless to say, it is not a useful language, but it is fun!
Some example programs are given after the compiler block.

This Forth brain fuck compiler was derived from the one 
available Rosetta Code, and so is licensed under the
GNU Free Documentation License [v1.2]. See:
<https://rosettacode.org/wiki/Execute_Brain****/Forth>

And for more information see:
 <http://www.hevanet.com/cristofd/brainfuck/short.b>
 <https://en.wikipedia.org/wiki/Brainfuck>
\ ==== Brain F*ck Compiler 1/2 =================================
: left over c!  1- dup c@ ;
: right over c! 1+ dup c@ ;
: erase 0 fill ;
: initialize pad b/buf erase pad 0 ;
: bf-compile ( c -- )
  >r
  r@ [char] [ = if [compile] begin 
                   compile dup [compile] while then
  r@ [char] ] = if [compile] repeat            then
  r@ [char] + = if compile 1+                  then 
  r@ [char] - = if compile 1-                  then  
  r@ [char] < = if compile left                then 
  r@ [char] > = if compile right               then
  r@ [char] , = if compile drop compile key    then
  r@ [char] . = if compile dup  compile emit   then rdrop ; 
\ ==== Brain F*ck Compiler 2/2 =================================
: bf ( b u --,<string> : compile brainfuck program into a word )
  >r >r
  [compile] : 
  compile initialize
  r> r> for aft
    dup 1+ >r c@ bf-compile r>
  then next
  drop
  compile swap
  compile c@
  compile 2drop
  [compile] ; ;

\ Example, making a simple echo like program called 'cat':
\ : string $" +[,.]" count ; string bf cat
; ==== Brain F*ck Example Programs =============================
From: http://www.hevanet.com/cristofd/brainfuck/short.b
Hello World: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]
>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Clear Screen: ++++++++++[>++++++++++>+<<-]>[>.<-]
Beep: +++++++.
Copy Input to Output: ,[.[-],]
Reverse Input: >,[>,]<[.<]
Translate text to brain fuck that prints said Text:
+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]






; ==== eForth v6.66: Help and Tutorial =========================

This Forth is modeled after eForth, described in a book by
C.H. Ting called "eForth Overview", or "The Zen of eForth". It
implements most of the eForth model with some changes expected
from a more modern Forth system.

The processor targeted is called the H2, a rewrite of the
J1 processor (<http://www.excamera.com/sphinx/fpga-j1.html>).
It has been extended with a few more instructions and with
interrupts. The system resides on an FPGA Nexys 3 board from
Digilent, with words and peripherals designed for it.

For more see: <https://github.com/howerj/forth-cpu>


; ==== Help: Introduction ======================================

Forth is a simple, imperative, stack based language that mixes
elements of a high level language with a low level language. It
is possible to fit a small Forth system in a few kilobytes of
RAM complete with an interactive read-evaluate-print loop, an
editor, an assembler and a disassembler.

It is also a language that has fallen out of favor in recent
times (after the micro-computer era) as it is not a very safe
language, nor is it one that allows the programmer to easily
create reusable and maintainable software components.

However it is still suitable for a number of purposes; for
assemblers, to bring up hardware and test it, in memory
constrained systems, as a boot loader, and for fun.
; ==== Help: Philosophy of Forth ===============================
Forth itself has its own philosophy, one in which the programmer
should have a complete understanding of the system, from the
problem that needs to be solved, the algorithms needed to solve
it, the hardware and the software. As the latter two, the
hardware and software are usually very simple in Forth systems
it is possible to optimize the problem across multiple domains,
tailoring each to come up with a solution. Forth eschews
complexity, preferring one off, bespoke solutions. Another
reason it has not seen widespread use.

Advocates of the language are usually quite passionate about
it (as with Lisp, and other niche systems) so it is important
to be pragmatic about Forth. Forth is simply a tool and when
used correctly can be used productively.

; ==== Help: Basics 1/6 ========================================
A Forth system contains an interactive interpreter that parses
text and either compiles or executes functions, called 'words'
in Forth terminology. The system uses Reverse Polish Notation
(RPN) and provides the user with two stacks and a 'dictionary'
(a big block of memory containing 'words' and other data).

The interpreter reads from an input device, such as a keyboard
or a serial port, and writes output to the screen or back over
the serial port. Words and number input are space delimited and
are either compiled into the dictionary depending on the
interpreter mode and whether the word read in is 'immediate'
or not.

This tutorial will describe how to use Forth and how the
interpreter works internally.
; ==== Help: Basics 2/6 ========================================
To start with, simple expressions can be entered and the
results displayed. A line is evaluated after the carriage
return is entered, code will be indented, this can be typed in.

We will start off with a simple expression, adding two numbers
together and displaying the result:

  ( Comments appear within brackets )
  2 2 + .

This prints out '4' and 'ok'. 'ok' is printed out after every
line has been successfully compiled, unless we are in compile
mode. '+' obviously does the addition, and '.' pops a value
off the stack an prints it. Entering a number pushes it onto
the data stack.
; ==== Help: Basics 3/6 ========================================
The data, or variable, stack is a general purpose stack that
the programmer uses to pass data to functions, and to return
data from functions. The stacks are an important concept
within Forth and stack management will take up a lot of a Forth
programmers time.

Numbers are entered in Reverse Polish Notation, this allows
Forth interpreter to immediate process a word or a function as
it is encountered instead of building up a parse tree.

When '2' is encountered it is pushed onto the variable stack,
when the second '2' is input, it is also pushed onto the stack.
The Forth word '+' takes two arguments off the stack, adds them
together and pushes the result back onto the stack. The word
'.' pops a single number off the stack and prints it.
; ==== Help: Basics 4/6 ========================================
Manipulating the stack will be difficult at first, but gets
easier over time. There are standard words for stack
manipulation and a standard methodology for describing
stack effects called 'stack comments'.

A stack comment is a short comment describing the stack before
and after execution of the word, and the type of the arguments
it accepts and returns. For example the stack comment for '+'
is:

  + ( n n -- n : add two numbers together )

All text between '(' and the ')' is discarded by the Forth
system. This comment describes a word that accepts two
signed numbers "n n", and returns a signed number "n".
; ==== Help: Basics 5/6 ========================================
The "--" divides the comment into what the stack looks like
before execution of the word (to the left of "--") and what it
looks like after (to the right of "--"). A comment on the
behavior of the word comes after the semicolon.

Here is a list of some common Forth words and their stack
comments:

  dup  ( n -- n n : duplicate first item on the stack )
  swap ( n1 n2 -- n2 n1 : swap first two items on stack )
  drop ( n -- : drop a value from the stack )

Stack effects are sometimes numbered, which is used to
so the effects on specific arguments can be documented if
the order of arguments and return values matter.
; ==== Help: Basics 6/6 ========================================
Some more words with comments:

  @    ( a -- u : load value from memory address )
  !    ( u a -- : store 'u' at memory location 'a' )
  <    ( n1 n2 -- f : is n1 greater than n2, signed )
  u<   ( u1 u2 -- f : is u1 greater than n2, unsigned )

These words have stack comments, some with numbered arguments,
but they use different letters. The different letters are used
to describe the type of the arguments that the word accepts.

'@', also known as load, takes an address, and '!', takes
an address and a value. "<" takes two signed numbers, "u<"
takes two unsigned numbers and produces a flag. Type checking
is not performed by Forth and is up to the programmer.
; ==== Help: Stack Comments ====================================
Here is a list of stack type descriptions and what they mean:
| Comment  | Meaning                             |
|----------|-------------------------------------|
| a        | cell address                        |
| n        | signed number                       |
| u        | unsigned number                     |
| b        | string address                      |
| c        | single character                    |
| d        | double width number (2 Cells)       |
| f        | boolean flag (-1 = true, 0 = false) |
| k        | block number                        |
| cfa      | code field address of a word        |
| nfa      | name field address of a word        |
| pwd      | previous word address of a word     |
| <string> | a parsing word                      |
; ==== Help: Expressions =======================================
Let us continue on with some interactive examples before we
start to define new words. Before we saw a trivial example
of adding two numbers together, we will go over a few more
operators first.

  9 2 + . ( Displays 'B', the default base is hexadecimal )
  decimal ( Change the input and output base to decimal )
  9 2 + . ( Displays '11' )
  3 4 dup * swap dup * + . ( Displays 3^2 + 4^2 or 25 )

Negative numbers can be input by prefixing the number with
'-':

  -2 4 * . ( Display -8 )

; ==== Help: Numeric Output 1/2 ================================
The word '.' pops a value off the stack before displaying it,
if we want to examine the stack without popping the value we
can print out the entire contents of the stack with '.s':

  1 2 3 .s ( prints "1 2 3 <sp")
  .        ( prints "3" )
  .s       ( prints "1 2 <sp" )

"<sp" marks the element which is currently on the top of the
stack. Other useful words for debugging include '?' that
prints the contents at a memory address and 'dump', which
prints a memory dump of a region of memory.

  dump ( a u -- )
  ?    ( a -- )
; ==== Help: Numeric Output 2/2 ================================
Hexadecimal numbers can be entered if the base input and output
base is 16, or by prefixing the number with '$'.

  decimal  $AAA . ( Displays 2730 )
          -$AAA . ( Displays -2730 )

eForth starts up in base 16, valid bases range anywhere from
2 to 36. The base can be changed by either setting a variable
'base' to the desired base, or with the words 'hex' to change
the base back into hexadecimal, or 'decimal' to change the base
to '10'. Variables in Forth are words that leave an address on
the stack when they are called. They can be read or set with
'@' and '!'. For example, "$10 base !" and "hex" are
equivalent, as are "$A base !" and "decimal".

; ==== Help: Word Definitions 1/2 ==============================
For the moment we have not covered how words are defined and
is a good time to do so, the word ":" is used to create a new
word definition and the word ";" is used to terminate one.
Words once defined are added to the 'dictionary', which is
consists of a linked list of words, hence the name
'dictionary'. We can define new words interactively like we can
type expressions in, such as:

  : square dup * ; ( n -- n : square a number )

We can then use square like any other word:

  4 square .  ( prints 16 )
  -5 square . ( prints 25 )

; ==== Help: Word Definitions 2/2 ==============================
'hex' and 'decimal' are defined as:

  : hex $10 base ! ;
  : decimal $A base ! ;

And simple Forth words likewise defined:

  : 2- 2 - ;      ( u -- u : decrement a number by 2 )
  : 2+ 2 + ;      ( u -- u : increment a number by 2 )
  : 2* 1 lshift ; ( u -- u : multiply a number by 2 )
  : 1+ 1 + ;      ( u -- u : increment a number by 1 )
  : negate invert 1+ ; ( n -- n : negate, twos compliment )

It is best to keep all Forth words as short as possible and
reuse code as much as possible.
; ==== Help: Interpreter Loop 1/3 ==============================
All functions, control structures, defining words such as ":",
and simple functions like "square" or "hex" are simply Forth
words, which are either defined in terms of other Forth words
or in terms of primitive operations supported by the H2 CPU.

Currently this does not explain how compilation happens. When
the word ":" is encountered it does multiple things such as
compiling a word header into the dictionary, and it does one
more thing - it puts the Forth system into compile mode. The
system starts out in command mode, in this mode words are
executed, and numbers are pushed onto the stack. In compile
mode, a call to the word is compiled (or an assembly
instruction is inlined) and numbers of turned into literals
that push their value when run.

; ==== Help: Interpreter Loop 2/3 ==============================
There is a special class of words called "immediate" words, ";"
is an immediate word, when it is encountered instead of being
compiled into the dictionary it is executed, it compiles an
exit instruction to terminate the word definition and it puts
the Forth system back into command mode.

Not only are control structures sets of words, like "if",
"else", "then", "begin", "until", but so are words like "("
and "\" which are used to process comments. When executed
they read from the input stream until the they find a ")" or
end of line respectively.

Variables, strings, and defining words (defining words are
that create new words) are all simply Forth words that are
either compiling or immediate, their is no special syntax.
; ==== Help: Interpreter Loop 3/3 ==============================
The command loop goes like this:
Start) Fetch a space delimited word, find it in the dictionary
   Found) Is the system in compile mode?
          Yes) Is the word immediate?
               Yes) Execute It
               No)  Compile a call to it / In-line it
          No)  Execute the word
   Not Found) Is the word a number?
          Yes) Is the system in compile mode?
               Yes) Compile the number
               No)  Push the number onto the stack
          No)  Error!
This simple loop is invoked by the work 'quit' which uses
'query' to fetch and parse the input and 'interpreter' to
perform the state dependent action.
; ==== Help: Control Structures 1/10 ===========================
This will give you some idea what is going on when control
structures are covered in the following blocks. Control
structures can only be used within a word definition, that
is in compile mode, if used in command mode they simply throw
an error.

Some of the control structures available to Forth are:

  if ... then
  if ... else ... then
  for ... next
  for ... aft ... then ... next
  begin ... until
  begin ... again
  begin ... while ... repeat
; ==== Help: Control Structures 2/10 ===========================
Recursion is also available with the 'recurse' word. There
are more advance control flow methods available that will be
described later (such as 'catch', 'throw' and manipulating the
return stack).

"if...then" will be described first. First a simple example,
we will define a word called 'abs' that will return the
absolute value of a number, that is negative numbers will be
turned into positive numbers and positive numbers will stay
the same. This will require the word 'negate' which changes
the sign of a number and '0<' which tests if a number is
negative, their stack effect comments are:

  0<     ( n -- f )
  negate ( n -- n )
; ==== Help: Control Structures 3/10 ===========================
The word 'abs' is then defined as:

  : abs dup 0< if negate then ;

'if' takes an argument off the stack at run time and jumps to
after the 'then' if it is false (zero), if it is true (non-
zero) the negate is performed. From now if a word is shown in
a definition that has not been previously mentioned please
refer to the glossary. We can can use the definition of the
word 'abs' as soon as we terminate the definition with ";":

  -9 abs . ( displays 9 )
   4 abs . ( displays 4 )

This Forth uses two complements to represent negative numbers.
; ==== Help: Control Structures 4/10 ===========================
A number can be negated in twos compliment form by performing
a bitwise not on the number and adding one to it, this is what
the word 'negate' does.

"if...else...then" control structures can be created:

  : min 2dup < if drop else nip then ; ( n n -- n )
  : max 2dup > if drop else nip then ; ( n n -- n )

These words get the minimum (min) and the maximum (max) of
two numbers.

   4 3 min . ( prints 3 )
   4 3 max . ( prints 4 )

; ==== Help: Control Structures 5/10 ===========================
Whilst control structures can be nested very deeply it is
considered very bad practice to do, instead the definition
should be refactored so it consists of short (preferably one
line) word definitions.

There are two mains ways of looping, either by recursion or
with the several looping mechanisms. One of the simplest is
"begin...until". This continues looping until a variable popped
off the stack when the "until" word is reach is non-zero. Like
the "if" control structure this can only be used within a word
definition. An example is the definition of "key", which gets
a single character from the input device, it blocks until there
is input. It uses a word called "key?" which returns a variable
number of items on the stack depending on whether there is
new input from the user.
; ==== Help: Control Structures 6/10 ===========================
The stack comments for "key?" and "key" are:

  key? ( -- c -1 | 0 )
  key  ( -- c )

Key returns the new character and "-1" (in Forth -1 is true,
and 0 is false), or "0" if there is no new input. The pipe
system "|" is used to separate the possible return values in
the stack comment. We can use "begin...until" to define "key"
in terms of "key?" with:

  : key begin key? until ;

This simply loops until there is a new character of input.

; ==== Help: Control Structures 7/10 ===========================
Some contrived examples, using the standard metasyntactic
variable name "foo":

  : foo begin 1- dup . cr dup 0= until drop ; ( u -- )

  4 foo ( <-- type this ) 3 ( <-- prints '3' )
  2  ( <-- then '2' )
  1  ( ... )
  0  ( ... )
  ok ( then ok prompt )

If zero is given this will underflow and wrap around to $FFFF
and continue the loop 65536 times which is probably not
intended.

; ==== Help: Control Structures 8/10 ===========================
Indefinite loops can be made with "begin...again", the
following word "bar" simply repeatedly prints out "1":

  : bar begin 1 . cr again ;
  bar 1 1 1 1 1 1 ( ... ad infinitum ... )

A looping mechanism that is easier to use is the
"begin...while...repeat" loop, this continues an operation
until a variable is not true:

  : foo begin ?dup while dup . cr 1- repeat ;
  3 foo 3 ( <-- prints 3 )
  2       ( <-- then 2 )
  1       ( <-- then 1 )

; ==== Help: Control Structures 9/10 ===========================
eForth provides another control structure, the "for...next" loop
which allows the Forth programmer to create counted loops. The
"for" loop takes a single variable, it stores this variable on
the return stack (which will be covered next) and decrements the
variable, until it is zero, at which point it exits (but still
executes for the final zeroth case). The word 'r@' is used to
push a copy of the top of the return stack, where the for loop
keeps the conditional value.

  : foobar for r@ . cr next ;
  3 foobar 3 ( <-- prints 3 )
  2
  1
  0 ( <-- prints zero as well! )

; ==== Help: Control Structures 10/10 ==========================
The "for...next" construct can be modified with the "aft" and
"then" construct, which is not executed on the first run of the
loop.

  : quux for -9 . aft r@ . then -8 . cr then ;
  decimal 3 quux -9 -8 ( for...aft and then...next is run )
  2 -8 ( aft...then and then...next is run )
  1 -8 ( ... )
  0 -8 ( ... )

This concludes the control structure section, it should be
noted that the control structures are defined words themselves
again, it is possible to redefine and add your own control
structures. How this is done will be covered later.

; ==== Help: Return Stack ======================================
All Forth systems have at least two stacks along with main
memory, they can be implemented in hardware like with this Forth
or in software. One stack is used to pass data to functions and
to return their results, the data or variable stack, which we
have already dealt with. The other stack is used for control
flow and as a place for temporarily storing variables.

Data can be moved to and from the return stacks, but this must
be done very carefully and only within word definitions,
leaving values on the stack by accident can cause the
interpreter to crash.

Some looping constructs use the return stack as well to store
their loop index, and the 'throw/catch' mechanism manipulates
control flow a lot.
; ==== Help: Return Stack ======================================
Some words for manipulating the return stack are as follows,
notice the stack comments describe both stacks here:

  >r    ( u --, R: -- u : move variable to return stack )
  r>    ( -- u, R: u -- : move variable from return stack )
  rdrop ( R: u -- : remove topmost variable from return stack )
  r@    ( -- u, R: u -- u : copy topmost return stack item )








; ==== Help: Control Structures ================================















; ==== Help: TO DO =============================================

* Describe the system internals
* eForth primitives
* Make, Doer, Create, Does>
* Do word glossary, with one block per word
* Vocabularies
* Block Word set
* Peripheral access word set
* Throw/Catch
* How Forth is implemented
* Add appendixes for ASCII character set, ANSI terminal
codes supported, the Nexy3 board, twos compliment format,
list of characters supported, etcetera.
* A short dictionary of English words, or a short
encyclopedia could be made and stored in blocks
; ==== Block Editor Help 1/5 ===================================

The traditional way to store Forth source code and data is as
Forth blocks, a block is a contiguous array of 1024 characters,
which can be saved to non-volatile storage with the 'block'
word set. On more modern Forth systems, especially hosted ones,
the file access word set is used instead.

A Forth that does not have a file system, such as this one,
usually has a primitive block editor. An editor can be defined
in just a handful of (non-standard) words.

By default the editor words are not in the Forth search order,
the words in the editor vocabulary would conflict with Forth
words (and with hexadecimal numbers). To load the block editor
execute the 'editor' Forth word. Load initial block with '0 b'.
; ==== Block Editor Help 2/5 ===================================
The block editor is a prime example of Forth simplicity, it
both simplifies the problem of editing text and reuses the
Forth interpreter to define a new command language. Each command
in the block editor simply a Forth word which takes its
arguments off the stack, and a line is a fixed width 64
character array, a block can contain 16 lines of text. An empty
line consists entirely of spaces, which the interpreter will
ignore if it were to evaluate the block.

The 'editor' word replaces the current vocabulary with the
editor vocabulary and switches the number base for input and
output to decimal. The commands are terse words, only one or
two characters in length.


; ==== Block Editor Help 3/5 ===================================
The third element of the block editor is the elegant, if some-
what limited, block word set. It completely abstracts aways the
task of retrieving data from mass storage and saving modified
data back to it. The mass storage is divided into blocks which
can be loaded by their block number. Block numbers in this
system start at 0 and go to $FFFE, $FFFF is an invalid block
number.

The block word set is quite small, and the editor uses the
words; 'block', 'update', 'save-buffers', 'list', 'load',
and '+block'. The variable 'blk', which contains the last
block loaded (and listed) is also used. Most editor commands
are minor modifications on the behavior of these words.


; ==== Block Editor Help 4/5 ===================================
The workhorse of the word set is 'block', it takes a block
number and if that block number is not currently loaded into a
block buffer (this system only has one block buffer available)
it checks to see if the current block is marked as dirty (with
the 'update' word). If it has been it first flushes the dirty
block to mass storage, then loads the desired block from it. It
then returns a pointer to the beginning of the block buffer. It
also updates the 'blk' variable to contain the block number
just loaded.

The 'save-buffers' saves all buffers to disk and deallocates
any blocks (by storing $FFFF in 'blk'). 'list' displays the
contents of a block, 'load' evaluates a block and '+block'
moves to a block relative to the currently loaded one.

; ==== Block Editor Help 5/5 ===================================
A quick recap of the block words:

block        ( k -- u : load block into buffer )
blk          ( -- a : last loaded block )
+block       ( k -- : load block relative to 'blk' )
save-buffers ( -- : flush block to disk, put -1 in 'blk' )
list         ( k -- : display block )
load         ( k -- : evaluate a block )

These can be used to define simple editor commands, such as:

  : b block drop ;
  : n 1 +block b ;
  : u update ;

; ==== Block Editor Commands 1/2 ===============================

'#' indicates a numeric argument the command takes:
      n    move to next block
      p    move to previous block
    # d    delete line in current block
      x    erase current block (overwrite with spaces)
      e    evaluate current block
    # i    insert line
 # #2 ia   insert at line #2 at column #
      q    quit editor loop
    # b    load block number
      s    save block and write it out
      u    update block
      w    list editor commands
      q    back to Forth interpreter
; ==== Block Editor Commands 2/2 ===============================


      l    re-list current block
    # c    paste copy buffer to line #
    # y    yank line # into copy buffer
 # #2 ct   copy line # to line #2
    # ea   evaluate line #
 # #2 sw   swap lines # and #2

The editor is simple to use and understand, but for large
documents and programs can quite difficult to use. This block
editor was derived from the Retro Forth block editor, available
at: <http://retroforth.org/pages/?PortsOfRetroEditor>


; ==== TO DO ===================================================
* The eForth primitives should be described.
* Describe the Nexys 3 system, the system on a chip, etc.
* List the instruction set, registers, words defined, eForth
* Make words for databases using blocks
* Add source code for everything to this block file
* Add a program listing, perhaps in the first block, it could
set variables relating to this document
* If a metacompiler based on the embed project is used, it
might be possible to have a self hosting system by storing the
source code in blocks.





; ==== Empty Block =============================================















; ==== Glossary ================================================
The next section presents the glossary, which contains one
word per screen with examples. The glossary may not necessarily
reflect the exact contents of the dictionary as words are
removed, added and replaced to save space, but the majority
should be documented here.

Hexadecimal and decimal numbers are used, and which base is
in operation should be inferred from context.

The glossary shows how blocks can be used as a way to
organize information, a concise description (that if needs
be could span multiple blocks) describes each word. The first
line can be used to create a table of contents with 'index'.
This way of organizing blocks maps well onto dictionaries,
encyclopedias, and all alphabetically organizable information.
; ==== <  ( n1 n2 -- f : signed less than ) ====================
Signed less than.














; ==== <>  ( u1 u2 -- f : not equal ) ==========================
'<>' takes two values off of the values stack and returns
a boolean which is true (-1) if the two value are not equal
and false (0) if they are.












; ==== <#  ( -- : prepare numeric output ) =====================
This is part of the mechanism for pictured numeric output,
which should be used from within a word definition only.













; ==== =  ( u1 u2 -- f : equality of two numbers ) =============
This is an assembly instruction for testing whether two numbers
are equal.













; ==== >  ( n1 n2 -- f : signed greater than ) =================
Signed greater than, if 'n1' is greater than 'n2' true (-1) is
returned, else false (0) is returned. This operates on signed
numbers stored in twos compliment format.












; ==== -  ( n1 n2 -- n : subtraction ) =========================
This is word performs subtraction of 'n2' from 'n1'.














; ==== ,  ( u -- : compile value into dictionary ) =============
The word ',' compiles a value at the next available location
in the dictionary, updating the dictionary pointer by the size
of a cell.












; ==== ;  ( -- : terminate a word definition ) =================
This word terminates a word definition, linking the newly formed
word into the dictionary. It is an immediate word and performs
some basic checking to make sure control structures match up. It
writes an 'exit' into the word and switches the state back into
command mode. It has another minor usage, if called within
command it throws -56, for QUIT. This can be used within a block
to stop execution of it, if 'thru' is used to load block, this
error is ignored.

Example:

   : 2+ 2 + ;
   : count dup 1+ swap c@ ;
   :noname 9 . ; execute ( <-- prints 9 )

; ==== :  ( -- ; <string> : start a word definition ) ==========
':' is a complex word that does many things. It is not an
immediate word, but it is a parsing word that reads in the
next space delimited word and compiles a word header into the
dictionary. It also switches the interpreter state into compile
mode, until switched back non-immediate words will now be
compiled into this word definition and numbers compiled into
it as literals. ':' is how most new words (or functions) are
defined within Forth. The word ';' should also be consulted.

Usage

  : example 2 + . cr ; ( <- makes a new word called 'example' )
  2 example            ( <- the new word prints '4' )


; ==== !  ( u a -- : store 'u' at address 'a' ) ================
Store a value in at an address, this is also used to write to
the memory mapped peripheral registers.













; ==== ?  ( a -- : print value at address ) ====================
Print a value out from an address, this is effected by the
output radix stored in 'base'. This word uses the area between
PAD area and the end of the dictionary.












; ==== /  ( n1 n2 -- q: divide n1 by n2 ) ======================
Signed and floored division of the second value on the stack by
the first. This will throw and error if the divisor is zero.
This is a particularly slow operation, as the H2 CPU does not
a built in division operation.











; ==== .  ( n -- : print number out in current base ) ==========
Print a space, then a signed number (if the output radix is ten
then a '-' is printed before the number if it is less than zero,
if the output radix is not ten, then it is just printed out as
an unsigned number). This word uses the area after the
dictionary and before the start of the pad area, it is not a
reentrant function.









; ==== ."  ( -- ; <string> : compile string into word ) ========
This word is an immediate word that compiles a string into a
word definition (it should only be used from within a word
definition). When the word is run it will print out the string.

The string is terminated by a double quote. A version of this
word which does no printing but instead returns a pointer to
a counted string is available, and it is called '$"'.

Usage:

  : hello cr ." Hello, World! " cr ;
  hello
  Hello, World! ( <- 'Hello, World!' is printed )


; ==== .(  ( -- ; <string> : print out line until ')' ) ========
This word prints out a string until the matching ')' is
encountered. It is not an immediate word. It is a parsing
word.






Usage:

  .( Hello, World! ) cr
  Hello, World!  ( <- 'Hello, World!' is printed )


; ==== '  ( -- xt ; <string> : return a word execution token ) =
This word parses the next word in the input stream and returns
its execution token if the word is found. It is an immediate
word. If the word is not found it throws an exception.












; ==== (  ( -- ; <string> : comment until ')' ) ================
This is an immediate word used for comments, it discards all
input until the matching ')' is encountered. It can be used
within blocks. This word should not span multiple lines
however.

Usage:

  2 2 + ( This is a comment ) . ( <- this '.' prints '4' )







; ==== )  ( -- : do nothing ) ==================================
This is a word that does nothing. It is an immediate word. It
has no function.













; ==== [  ( -- : change compile state to command mode ) ========
An immediate word for changing the state of the interpreter loop
into the command state. It can be used within a word definition.













; ==== ]  ( -- : change compile state to compile mode ) ========
A normal, compiling word, which turns the interpreter state into
compile mode. Words and numbers after (apart from immediate
words) are compiled into the dictionary.












; ==== @  ( a -- u : load value from address ) =================
Retrieve a value from memory location 'a'. It can be used to
read from the memory mapped registers as well.













; ==== $"  ( -- ; <string> : compile string into word ) ========
This is an immediate word that can only be used in a word
definition, it compiles a string into the dictionary, when it
runs it pushes the address of the counted string compiled into
the word.











; ==== *  ( u1 u2 -- u3 : multiple two numbers ) ===============
Multiply two numbers and push the result onto the stack. This is
a slow operation, as there is not a built in multiply operation.













; ==== \  ( -- ; <string> : comment until end of line ) ========
Comment until end of input line, this word works within blocks
as well, where it is a comment until the end of the block line.
It is an immediate word.












; ==== #  ( u -- u : extract numeric character from u ) ========















; ==== #>  ( u -- b u : return converted number string ) =======















; ==== +  ( u1 u2 -- u3 : add two numbers together ) ===========















; ==== +!  ( u a -- : add 'u' to value 'a' ) ===================















; ==== 0<  ( n -- f : 'n' less than zero? ) ====================
'0<' is a test word that operates on a signed value and returns
a boolean value, it returns -1 for true if 'n' is less than
zero and 0 for false if 'n' is greater than zero.





Usage:

     0 0< . ( prints '0' )
     9 0< . ( prints '0' )
    -4 0< . ( prints '-1' or 'FFFF' )
  FFFE 0< . ( prints '-1' or 'FFFF', 'FFFE' = -2 )

; ==== 0<>  ( n -- f : 'n' not equal to zero? ) ================
This word tests if 'n' is not zero, returning true (-1) if it
is not zero, and false if it is (0).

Usage:

   0 0<> . ( prints '0' )
  -7 0<> . ( prints '-1' or 'FFFF' )
   5 0<> . ( prints '-1' or 'FFFF' )







; ==== 0=  ( n -- f : 'n' equal to zero? ) =====================
This word tests if 'n' is zero, returning true (-1) if it is,
and false if it is not (0).


Usage:

  : 0<> 0= 0= ;
   0 0= .        ( prints '-1', or 'FFFF' in hex mode )
   4 0= .        ( prints '0' )
  -5 0= .        ( also prints '0' )





; ==== 0>  ( n -- f : 'n' greater than zero? ) =================
'0>' performs a greater than zero test on a signed number, if
'n' is greater than zero it returns true (-1), otherwise it
returns false (0) if 'n' is equal to or less than zero.












; ==== 1-  ( u -- u : decrement u ) ============================
'1-' decrements the top most stack item.














; ==== 1+  ( u -- u : increment u ) ============================
This is a regular word that increments a value by one.














; ==== 1+!  ( a -- : increment value at 'a' by one ) ===========
'1+!' increments the value at an address, 'a', by one.














; ==== 2!  ( u1 u2 a -- : store u1 and u2 at two cells ) =======















; ==== 2/  ( u -- u : divide 'u' by two ) ======================
'2/' is a division by 2, it is implemented as a logical right
shift by one. 













; ==== 2@  ( a -- u1 u2 : retrieve two cells ) =================
'2@' retrieves two consecutive cells from an address 'a'. The
word forms a pair with '2!', which stores two cells at two
consecutive addresses.





Usage:

   1 2     ( -- 1 2 : input test values )
   pad 2!  ( 1 2 -- : store values in temporary storage )
   pad 2@  ( -- 1 2 : retrieve values )


; ==== 2*  ( u -- u : multiply 'u' by two ) ====================
'2*' is a multiply by two, it is implemented as a left shift
by one.













; ==== 2drop  ( u u -- : drop two values from the stack ) ======
A simple word, '2drop' behaves as its stack comment suggests,
it removes the top most two items from the variable stack.

Usage:

  1 2 3 drop . 1 ( '1' is printed )









; ==== 2dup  ( u1 u2 -- u1 u2 u1 u2 : duplicate two values ) ===
This manipulates two items on the stack, like most words with
a '2' in their name. The stack effect describes the word
perfectly. Words like these, which produce and manipulate lots
of stack items should be avoided if possible.

Usage:
         ( -- : empty stack )
   1 2   (  -- 1 2  )
   2dup  ( 1 2 -- 1 2 1 2 )






; ==== abs  ( n -- u : absolute value of a number ) ============
Returns the absolute value of a signed number, positive values
stay the same, negative values become positive. Signed numbers
are stored in twos compliment format, the function fails for
the number $8000, which is unaffected by abs.

Usage:

  -1 abs .  ( prints '1' )
   4 abs .  ( prints '4' )






; ==== accept  ( b u -- b u : accept a line ) ==================















; ==== aft  ( -- : part of for...aft...then...next ) ===========















; ==== again  ( -- : part of begin...again loop ) ==============
'again' should only be used as part of a 'begin...again' loop,
which is a compile time only wordset. Using an 'again' without
a 'begin' may also be met with an error, as this situtation
should be caught by the compiler security mechanisms. The
'begin...again' looping mechanism forms an indefinite or an
infinite loop, the Forth interpreter/CPU jumps back to the
corresponding 'begin' unconditionally, and excluding any
errors/exceptions will do so forever.

Usage:
  : invalid-1 again ; ( <- invalid use, no matching 'begin )
  again        ( <- invalid use, outside a word definition )
  : test begin 1 . cr again ; 
  test ( 'test' prints '1' forever )

; ==== align  ( -- : align dictionary pointer ) ================
'align' is a word that takes no arguments and returns nothing,
it acts on the dictionary pointer variable (the internal name
for which is usually 'cp', the variable is returned by the
word 'here'). It should be used after allocating a data
structure in the dictionary which is byte aligned and before
defining any new words, the word 'align' reserves space up to
the next cell aligned address by manipulating the dictionary
pointer variable.

Usage:

   create x 3 allot ( <- dictionary pointer is now unaligned )
   align            ( <- dictionary pointer is now aligned )


; ==== aligned  ( b -- a : align up an address ) ===============
'aligned' takes an address 'b', that is potentially unaligned
and returns an aligned address by rounding up to the nearest
cell boundary. This word is like 'align' but it works on any
pointer instead of the dictionary pointer only. As this is
a 16-bit Forth system this rounds up to the nearest 16-bit cell
boundary, or to next multiple of two (bytes).

Usage:

  0 aligned . ( prints '0' )
  1 aligned . ( prints '2' )
  2 aligned . ( prints '2' )
  3 aligned . ( prints '4' )
  4 aligned . ( prints '4' )

; ==== allot  ( n -- : allocate 'n' bytes ) ====================
Allocate 'n' bytes of space in the dictionary, 'n' can be
either positive, or negative, negative values deallocate space,
which may break things.












; ==== and  ( u1 u2 -- u3 : bitwise and of two numbers ) =======
This performs a bitwise and on two numbers.














; ==== ansi ( n c -- : emit an ANSI escape command ) ===========
'ansi' is used to help construct ANSI escape code sequences,
most sequences consist of a CSI escape code, a number in base
10, and a single character to indicate the command. The
character and the number change, and are given as arguments
to the word 'ansi'. Most terminal emulators can deal with these
sequences, and the hardware VT100 clone that controls the VGA
display can deal with most of the more important codes.

Usage:

  : sgr [char] m ansi ;
  $1f sgr ( turn foreground color red )
  $0  sgr ( reset color )
  2 char J ansi ( blank screen, set cursor position to 1,1 )

; ==== at-xy  ( x y -- : place cursor at column 'x', row 'y' ) =
'at-xy' emits the ANSI escape sequence which will place the
cursor at column 'x' and row 'y'. This should work with the
built in VT100 terminal emulator, and with any decent terminal
emulator used to talk to the device over UART. 'at-xy' can be
used to draw primitive graphics along with other escape codes.
Counting starts from one, not zero.

Usage:

  1 1 at-xy  ( set cursor to top left corned )
  5 10 at-xy ( cursor to column 5, row 10 )




; ==== base  ( -- a : address of base radix ) ==================
Pushes the address of the base variable onto the variable stack,
this can be used to change the input and output radix of numbers
to a base between 2 and 36 inclusive. Characters '0' to '9' are
used for numbers 0 through 9, and letters 'A' to 'Z' are used
for numbers 10 to 35, upper case and lower case letter can be
used, only upper case characters are output.

Setting the base to an invalid value can cause exceptions to
be thrown in other words.

Example usage:
   $2 base !
   base @
   $8 base !

; ==== b/buf  ( -- u : number of bytes in a block ) ============
This pushes the number of bytes in a block onto the stack, 
which is 1024 in most Forth implementations, including this
one.





Usage:

  blk @ block b/buf blank ( blank most recently loaded block )




; ==== begin  ( -- : start begin...until/again loop ) ==========
'begin' is used to start three looping mechanisms,
* 'begin...again'          ( infinite loop )
* 'begin...until'          ( loop until non-zero )
* 'begin...while...repeat' ( loop until zero )
Which are best explained in the entries for 'again', 'until'
and 'while'/'repeat' respectively. 'begin' is an immediate
word that should only be used within a word definition, and
should be used in conjunction with a valid looping mechanism
word set.

Usage:

 See 'again', 'repeat', 'while' and 'until' for examples.


; ==== bl  ( -- u : value for space character ) ================
This pushes the space character to the stack. This is the
ASCII character 32 (decimal), or $20 (hexadecimal). This is
a useful character for comparing character ranges (anything
of a lower numeric value than space is a control character in
ASCII) and because it is unobtainable by using the word 'char'
or '[char]', as they use space to delimited the character to be
read in.








; ==== blank  ( b u -- : fill array with blanks ) ==============
This word writes the space character to a byte array, one use
is to erase a block before it is displayed with 'list'.













; ==== blk  ( -- a : address of last loaded block ) ============
'blk' is a variable which contains the value of the last block
to be loaded. This value is updated by 'block' on a successful
operation, and is set to an invalid block number on a block
error, or when 'flush' is called.











; ==== block  ( k -- a : perform block operation ) =============
'block' is a complex word that abstracts away all the details
of mass storage, whilst at the same time being easy to use, it
forms the basis on which Forth Blocks are used to organize
code and data. 'block'  takes a block number and if it is
valid attempts to find a free buffer in which to load the
block into, it then returns a pointer to that buffer. If no
free buffers are available it saves a dirty buffer to disk
then deallocates it, or it overwrites a clean buffer (as it
can always be loaded from disk if needed again).

Usage:

   5 block 2 cells + 1234 swap ! update flush


; ==== +block ( n -- k : return block number relative to blk ) =
'+block' is a useful common operation which returns the block
number relative to the one currently loaded in 'blk', it can
be thus used to navigate relative to the most recently loaded
block. The number it accepts is signed, the next blocks being
specified with a positive number, the current with zero, and
negative being prior blocks.

Usage:

  : +block blk @ + ;      ( n -- k )
  : next 1 +block ;       ( 
  : previous -1 +block ;
  5 block drop next next previous


; ==== border  ( -- a : variable for list display control ) ====
'border' is a variable that controls the display of 'list', 
it turns the border on when it is set to true (-1), and off
when it is set to false (0).












; ==== c,  ( c -- : compile character into dictionary ) ========
This words takes a character and writes the character in the
next available location in the dictionary, and updates the
dictionary pointer. This word can cause the dictionary number
to be misaligned, 'align' can be used to remedy this.











; ==== c!  ( c b -- : store 'c' at 'b' ) =======================
'c!' is the byte oriented store word, it stores a byte 'c' at
a potentially unaligned address 'b'. This is not a primitive
operation provided by the processor as it can only do cell
sized loads and stores in a single instruction. The
corresponding word for load a byte is 'c@'. The cell load
and store words are '@' and '!' respectively.









; ==== c@  ( b -- c : retrieve 'c' from 'b' ) ==================
'c@' retrieves a single byte from the address 'b', this address
does not have to be an aligned address. For storing a byte, see
'c!'. This word is the byte oriented version of '@', '@'
operates on Forth cells. On this processor 'c@' is not a
primitive operation, for speed '@' should be used instead, as
loads (and stores) can only be done by cell and not by byte.









; ==== catch  ( xt -- n | 0 : catch possible exception ) =======
'catch' can catch exceptions thrown by 'throw', it is part of
a pair of words that work as a pair like many Forth words, one
cannot exist without the other. 'catch' takes an execution
token, executes it, and returns 0 if nothing was thrown, and
a non-zero value if something was. 'catch' is also used as part
of the interpreter loop as an exception handler of last resort.
The word 'throw' should also be consulted. 'throw' and 'catch'
manipulate the return stack a lot and are fairly complex words
that are hard to implement on a processor with hardware stacks.

Usage:

  : x 99 throw ;   : y x 66 ;
  ' x catch . ( prints '99' )

; ==== ccitt  ( crc c -- crc : compute CRC step ) ==============















; ==== cell-  ( a -- a : decrement address by single cell ) ====
'cell-' is the opposite of 'cell+', it decrements an address
value by a cell. On this 16-bit Forth a cell consists of two
bytes, but on a 32-bit one it would decrement by four. Note
that this word does not ensure the resulting address is
aligned, if an unaligned addressed was passed in and unaligned
address will pop out, and an aligned address will stay so. This
word is needed so Forth code can be written that is portable
across different word size computers.







; ==== cell+  ( a -- a : increment address by single cell ) ====
'cell+' increments an address by the size of a cell, see
'cell-' for further description on this.













; ==== cells  ( n -- n : convert cell to byte count ) ==========
'cells' is a word that takes a count of the number of cells and
returns the number of bytes that those cells would occupy, on
this 16-bit Forth 'cells' is essentially a multiply by two
operation, but on other Forths it could be a different value,
so this word is used for portability reasons.

Usage:

  0 cells . ( prints '0' )
  1 cells . ( prints '2' )
  2 cells . ( prints '4' )
  create x 4 cells allot ( 'x' created, space for 4 cells )



; ==== >char ( c -- c : convert unprintable character ) ========
'>char' converts a character so that it can be printed by
converting any characters which cannot be printed to the
underscore character ('_'). This is used within words like
'message' and 'list'. Tabs also get converted, as do control
characters, delete and any character outside of the ASCII
range.









; ==== char  ( -- c ; <string> : parse character ) =============
This word reads in a space delimited word from the input stream 
and pushes the first character of that word onto the stack. An
entire word is potentially read in, but only the first 
character is used.

Usage:

  char x .          ( prints '$78' )
  char xylophone .  ( prints '$78', also )
  char 0 .          ( prints '$30' )





; ==== [char]  ( -- ; <string> : compile character literal ) ===
This is an immediate word that compiles a character into the
dictionary as a literal value that will be pushed onto the
stack when the word is run. It parses a space delimited word
and compiles the first character of that word. It is a compile
only word. Although an entire word is parsed, only the first
character is used.

Usage:

  : print-c [char] c emit ;
  print-c c            ( 'c' is printed )
  : push-c [char] c ;
  push-c . 63          ( ASCII 'c' is $63 )


; ==== cmove  ( b b u -- : move block memory ) =================
'cmove' copies a block of characters from one location to
another.













; ==== compile ( -- : compile next word into dictionary ) ======















; ==== [compile]  ( -- xt : compile next immediate word ) ======















; ==== compile,  ( xt -- : compile execution token ) ===========
'compile,' compiles an execution token into the next available
location in the dictionary, taking up a cell of space. This
word must be used when compiling in an execution into a word,
the word ',' will compile an unconditional branch.











; ==== conceal  ( -- : emit stars instead of characters ) ======















; ==== console  ( -- : UART only mode ) ========================















; ==== constant  ( n -- ; <string> : create constant ) =========
'constant' is a defining word that creates a new constant, it
takes in a value from the stack, and parses the next word from
the input stream which will become the name of the new
constant. This word uses 'create' and 'does>' internally to
do the work, and is similar to the definition of 'variable'.
At run time the new word when called will leave a copy of
'n' on the stack.

Usage:

   : constant create , does> @ ;
   4 constant x
   3 constant y
   x y + . ( prints '7' )

; ==== count  ( b -- b c : retrieve next character in string ) =
'count' is a very useful word when dealing with strings,
especially counted strings. It retrieves a character from an
address and increments that address by one character. This can
be used to advance through a string, and with counted strings
it can be used to retrieve the string length which is stored
in the first byte of the string.









; ==== cpu-id  ( -- u : return CPU-ID ) ========================
This is an assembly instruction that pushes the CPU-ID of the
CPU onto the stack. It can be used to determine whether the
system is running in a simulation or on the hardware.












; ==== cr  ( -- : emit new line ) ==============================
'cr' emits a new line, which consists of a carriage return
character followed by a linefeed character. This format is used
as communication occurs over a UART (and the VGA output display
behaves like a VT100 video terminal).











; ==== crc  ( b u -- u : perform CRC over array ) ==============
'crc' performs a Cyclic Redundancy Check (CRC) over an array
specified by an address ('b') and length ('u') pair. It
returns the result in a single cell. There are many different
ways of computing a CRC which depending on starting value,
what operation to perform at the end of the calculation and
what polynomial is used. 'crc' used the word 'ccitt' to do
the actual calculation on each byte, using the CCITT 
polynomial, which is a standard polynomial. See 'ccitt' for
more information. CRCs can be used for error detection.

Usage:

  : s1 $" hello" count ;
  hex x crc . ( prints 'D26E' )

; ==== create  ( -- ; <string> : make 'created' word ) =========
'create' is a very useful word that allows the creation of
new words. It parses the next space delimited string from the
input stream and creates a word which when run returns a
pointer to its code field. It can be used to make words which
create new words, and 'does>' can be used to give those new
words different actions. The 'create'/'does>' combination is
a really important concept in Forth and has been called 'The
Pearl of Forth'.

Usage:

  create x 2 cells allot
  : constant create , does> @ ;
  4 constant y ( a new constant called 'y' has been made )

; ==== decimal  ( -- : switch radix to decimal ) ===============
'decimal' switches the current output radix into decimal as
the name suggests. This can be useful when you are lost and do
not know what the current output radix is, or for performing
calculations like a human instead of a machine! Hexadecimal
values can still be input by prefixing the number with '$'.
Negative numbers will be printed with a leading '-', unlike
in other output bases, when a '.' is used to print the number.








; ==== dm+  ( a u -- u : print out section of memory ) =========
'dm+' prints out a section of memory in numeric forth, it
prints out the contents starting from address 'a' and advancing
for 'u' bytes, rounded down to the nearest aligned cell
location. It is a factor of 'dump' and is useful as a debugging
tool in itself. It will print out the values in the current
output radix, as stored in the 'base' variable. A crude memory
dump can be performed with '0 here dm+'. No newlines are
printed, but spaces are printed between cell values.

Usage:

  $40 $200 dm+ ( print $200 bytes starting from address $40 )
  0 here dm+   ( crude dump of Forth core )


; ==== dnegate  ( d -- d : negate a double value ) =============
'dnegate' is the double cell number equivalent of 'negate', it
negates a double cell number. Positive numbers become negative
and vice versa. Double cell numbers take up two items on the
stack as the name suggests.











; ==== doer  ( -- ; <string> : create a 'doer' word ) ==========















; ==== does>  ( -- : start 'does' section of word ) ============















; ==== drop  ( u -- : drop a value ) ===========================
'drop' simply pops off and discards the topmost value on the 
variable stack.  'rdrop' is the return stack equivalent.













; ==== dump  ( a u -- : dump a section of memory ) =============
'dump' is a debugging tool that dumps a section of memory
starting at the address 'a' and proceeds for at least 'u'
characters. It dumps the memory contents in whatever the
current output base it, as well as displaying the memory
contents as characters when the characters are printable.

Example: 

   0 here dump ( <-- dumps out everything )
Example Output (condensed to fit on the screen):
 0:  104C 0 0 0 0 0 E9B 0                     L_______________
 10: 8000 6403 7075 6081 601C 8010 6F04 6576  ___dup_`_`___ove
 20: 72 6181 601C 801A 6906 766E 7265 74      r__a_`___invert_
 30: 6600 601C 8026 2B01 6203 601C 8034 7304  _f_`&__+_b_`4__s
 ( and so on...)
; ==== dup  ( n -- n n : duplicate a value ) ===================
The stack comment explains this word completely, it simply
duplicates the topmost item on the variable stack. This is a
common Forth word that should be memorized - you should not
need to look it up here! Other common stack manipulation words
include 'swap', 'over', 'nip', 'tuck', '2dup', 'drop', and
'2drop' amongst others. If you find keeping track of the stack
difficult, try to rethink and refactor your code, stack
juggling gets easier over time but nothing beats out removing
complex combinations of 'dup', 'swap', 'over' and the like.

Usage:

  5 dup ( 5 -- 5 5 )


; ==== ?dup  ( n -- n n | 0 : duplicate value if not zero ) ====
This word duplicates a number if that number is non zero, it
returns just a single zero if the input number was zero. It
finds a lot of use in 'begin...while...repeat' loop constructs,
as well as in other looping constructs.

Usage:

  : ?dup dup if dup then ;
  0 ?dup .s ( 0 -- 0 )
  3 ?dup .s ( 3 -- 3 3 )





; ==== else  ( -- : if...else...then ) =========================
'else' is a word which forms part of the 'if...else...then'
clause, it can only be used from within a Forth word
definition and should always be used with the matching 'if'
and 'then'. 

Usage:

  : example cr if ." Hello!" else ." Goodbye!" then cr ;
  1 example ( prints 'Hello!' )
  0 example ( prints 'Goodbye!' )





; ==== emit  ( c -- : emit a character ) =======================
'emit' emits a single character to the output device, this
device is by default both the UART and the VT100 terminal
emulator can be displayed on a VGA capable display. The board
used has VGA output. The output of this word can be redirected
by words like 'io!', 'stars', 'conceal', 'file', 'console' and
'interactive'.



Usage:

  $6b emit ( prints 'k' )



; ==== empty-buffers  ( -- : deallocate block buffer ) =========
'empty-buffers' deallocates any currently loaded block buffers,
and stores and invalid block number in 'blk'. It can be used
to discard any changes made to any currently loaded blocks.












; ==== evaluate  ( a u -- : evaluate block of memory ) =========
'evaluate' takes a string specified by an address 'a' and a
length 'u' and evaluates it as if it were typed in by the
user. 'source-id' is set to '-1' for the duration of this
so code can work out it is being evaluated and not typed in.

Usage:

  : s1 $" 2 2 + . cr " count ;
  s1 evaluate ( prints '4' )






; ==== execute  ( xt -- : execute an execution token ) =========
'execute' takes an execution token, which represents a callable
function, and it executes that function. Execution tokens are
returned by words like "'" (quote), or by ":noname".












; ==== @execute  ( a -- : execute token at 'a' if non-zero ) ===
'@execute' expects an address of a value containing an
execution token to execute, it retrieves this token from the
address and executes it if the token is a non-zero value. This
is primarily uses for vectored word execution.











; ==== exit  ( -- : exit from word ) ===========================
This word is an assembly instruction that will be inlined into
a word when it is executed, it will run but have no effect when
executed in command mode, when compiled into a word it will
exit that word definition when it is run by returning from that
word. It is compiled into the end of a word definition by
the ';' word, which terminates a word.




Example:
   : foo if $f00f . exit then $1337 . ;
   0 foo $F00F ( <-- prints only '$F00F', $1337 not printed )
   1 foo $1337 ( <-- prints $1337 only )

; ==== expect  ( b u -- : accept, but store 'u' in span ) ======















; ==== file  ( -- : file transfer mode ) =======================















; ==== fill  ( b u c -- : fill area of memory with 'c' ) =======















; ==== find  ( a -- pwd 1 | pwd -1 | a 0 : find word ) =========















; ==== flash  ( -- : add flash words to search order ) =========
The flash related word set requires its own glossary and
description. It is for manipulating the onboard memory, not
just the Flash chip on the Nexys3 but the SRAM as well (as
both devices share data, address and most control lines).

The startup sequences loads blocks from Flash to SRAM, the
SRAM can be modified freely, but committing data to Flash is
a manual process as erasing and writing to Flash too many times
can cause it to wear out.

The source code should be consulted for a list of the memory
related words, their usage and other such information.



; ==== flush  ( -- : write dirty blocks, empty-buffers also ) ==















; ==== for  ( -- : part of for...next loop ) ===================















; ==== forth  ( -- : set search order to the default ) =========















; ==== forth-wordlist  ( -- voc : return Forth vocabulary ) ====















; ==== get-order  ( -- vn...v0 u : get search order ) ==========
'get-order' is the counter part to 'set-order', it takes a
variable number of arguments off of the stack, denoted by 'u',
which each represent a word list. It used for inspecting the
current search order in use by the interpreter.











; ==== here  ( -- a : return dictionary address ) ==============
'here' returns the current address of where the dictionary
pointer is, new words will be compiled at this address. The
dictionary pointer is updated by compiling words and numbers
into the dictionary, words like ',' and 'compile,'.











; ==== hex  ( -- : set numeric radix to hexadecimal ) ==========
This sets the current input output radix to hexadecimal, which
is the default radix for numbers in this Forth. If operating
in other bases, or to make it clear which base you mean, a
number can be prefixed with '$' to force the input base to
hex for that number. This affects all number conversions
globally as it sets the 'base' variable to '$10'. It is
equivalent to '$10 base !'.

Usage:

  hex 9999 1111 + .     ( prints 'AAAA' )
  decimal 9999 1111 + . ( prints '11110' )



; ==== hi  ( -- : initialize and login to system ) =============
'hi' initializes the system and calls the routine that prints
the login prompt.













; ==== hld ( -- a : hold count for pictured numeric output ) ===
'hld' is a variable which contains the current hold count for
the pictured numeric output. As characters are added to the
output buffer with the word 'hold', this value is increment. It
is reset by '<#'. The value for 'hld' may actually be a count
or a pointer.










; ==== hold  ( c -- : put byte into numeric output string ) ====
'hold' puts a byte into the hold buffer, which is used by the
Pictured Numeric Output (PNO) routines as a temporary buffer to
create a string that represents the number to be output. The
PNO related routines include; 'hold', 'hld', '<#', '#', '#s',
and '#>'. They are used by words like '.' and 'u.'. The
hold buffer is not that large, at has a minimum size of eighty
characters, so should not be used for large strings.

Usage:

  : (u.u) <# # # [char] . hold # # #> ;
  : u.u base @ >r hex (u.u) type r> base ! ;
  $1234 u.u ( prints '12.34' )


; ==== ien  ( f -- f : set interrupt flag ) ====================















; ==== ien?  ( -- f : are interrupts enabled? ) ================















; ==== if  ( -- : part of if...then/if...else...then) ==========
'if' is an immediate word that should only be used within a
word definition. It is used to form 'if...then' and
'if...else...then' clauses for conditional execution of
words. The words 'else' and 'then' should also be consulted.
'if' has differing behavior at compile time and run time,
which is covered in the documentation for the system internals,
however 'if' is just an ordinary Forth word. When run, it
takes a value from the variable stack and jumps to the
corresponding 'else' or 'then' if it is zero, if it is non
zero it continues execution after the 'else'.

  : example cr if $" Hello" else $" Bye" then count type cr ;
  0 example ( prints 'Hello' )
  1 example ( prints 'Bye' )

; ==== immediate  ( -- : make last defined word immediate ) ====
'immediate' is an important word that makes the most recently
defined word 'immediate', that is it will be executed even
when in compile mode. All control structure words are 
immediate words such as 'if', and 'for'.











; ==== >in  ( -- a : index into parse input at address ) =======















; ==== index  ( k1 k2 -- : print first line of block range ) ===
'index' displays the first line in a range of blocks, if the
blocks are formatted correctly with the first line containing a
description of the block contents then this works to display an
index of the blocks.











; ==== interactive  ( -- : interactive I/O mode ) ==============















; ==== interpret  ( ??? a -- ??? : interpret word/number ) =====















; ==== invert  ( u -- u : bitwise invert ) =====================
'invert' performs a bitwise invert on a number. For a
twos compliment negation see 'negate'.


Usage:

  hex
     0 invert . ( prints 'FFFF' )
     4 invert . ( prints 'FFFB' )
  FFFF invert . ( prints '0' )
  AAAA invert . ( prints '5555' )




; ==== io!  ( -- : initialize IO channels ) ====================
'io!' initializes the I/O devices and sets the input and output
devices to their default values (read from UART and PS/2
keyboard, write to the VT100 display, and to UART - both at
the same time). It also disables the interrupts, and sets the
timer to a count but not generate interrupts.





Example usage:

   io! ( ...that's not a very good demonstration... )


; ==== key  ( -- c : block until character read in ) ===========
This word blocks until a character has been read in from the
current input device (or devices). The input devices can be
either be the UART or the PS/2 Keyboard. The input devices can
be changed with the 'io!', 'console', 'conceal', 'interactive'
and 'file' words.










; ==== key?  ( -- c -1 | 0 : non-blocking character read ) =====
This is a non-blocking version of 'key', it returns a
character and true (-1) if a new character has come through
from input devices, and only 0 if there is no new character.
The input devices can be either a UART or a PS/2 keyboard, and
this can be changed with the 'io!', 'console', 'conceal', 'file'
and 'interactive' words.









; ==== last  ( -- pwd : last defined word ) ====================















; ==== led!  ( u -- : write value to LEDs ) ====================
'led!' sets the LEDs on the board next to the switches. There
are eight switches, and the lowest eight bits of the input value
are used to set the switches, 1 is on, 0 is off.












; ==== list  ( k -- : list block ) =============================
The word list loads block 'k' from disk and display the contents
of this block on the screen. It displays the block as 16 lines
with a column width of 64. The display format is controlled by
the 'border' variable, if true it 'list' displays the line
number and a border around the block, if false, then it just
display the block line by line without formatting. It is true
by default. 'list' will also call 'page' before it displays
the block if 'border' contains a non-zero value.

Usage:

   1 list
   2 list
   ( ..ad infinitum )

; ==== literal  ( n -- : compile literal into dictionary ) =====
This is an immediate word that compiles a number into the
dictionary. A number takes up between one and two cells in the
dictionary (negative numbers take up two space, positive only
one). It is a compile only word.

Usage:

  : example [ 2 2 + ] literal ;
  example . ( prints '4' )






; ==== load  ( k -- : load and execute block ) =================
'load' retrieves a block using 'block', and evaluates that
block, executing whatever is in that block as Forth code,
'source-id' will return -1 for the duration of this evaluation,
the input source will be returned to whatever it was before
the evaluation took place, such as keyboard or UART input,
once the evaluation has finished. 'load' is used in the
word 'thru' to do the evaluation of successive blocks off
mass storage.







; ==== loaded  ( -- a : variable, true if boot block loaded ) ==
This is a variable which can be set by the user if the loading
of the boot block was successful, and if the error messages
exists on disk. The error handling words in QUIT inspect this
variable to work out if it can lookup error messages and print
them, or if it should just print out the error number.










; ==== lshift  ( u1 u2 -- u3: logical left shift u1 by u2 ) ====
This performs a logical left shift on 'u1' by 'u2'.














; ==== make  ( -- : make part of make/doer words ) =============
'make' is a state aware word that operates on words made with
'doer', it should not be used with other words.













; ==== max  ( n1 n2 -- n3: maximum of two numbers ) ============
This returns the maximum of two signed numbers. This is a
signed operation! Some Forths define an unsigned version
called 'umax'. See 'min' for the minimum of two signed
numbers.











; ==== message  ( u -- : type line from block ) ================
'message' prints a line from a block, a block is 1024 bytes
long, and there are 16 lines of 64 bytes per block. 'u'
specifies a line number, starting at block 0, which contains
lines 0-15, block 1 has lines 16-31 and so on. Lines are
printing omitting any trailing spaces and non-ASCII characters
are replaced with another character (an underscore, '_').

This word is useful in printing error messages, the interpreter
maps error codes into line numbers. The error messages start
in block 2 and end in block 5, with one message per line.

Usage:

  $21 message ( print line 33, or the second line in block 3 )

; ==== min  ( n1 n2 -- n3: minimum of two numbers ) ============
This returns the minimum of two signed numbers. 'umin' is not
defined but it is enough to create, it provides an analogue
for unsigned numbers. The word is simple enough to use. 

  :  min 2dup  < if drop else nip then ; ( n n -- n )
  : umin 2dup u< if drop else nip then ; ( n n -- n )

Usage:

   3 4 min .    ( prints 3 )
  -3 4 min .    ( prints -3 )
  65533 4 min . ( prints -3, 65533 is -3 on a 16-bit system )
  65533 4 umin . ( prints 4 )


; ==== m/mod  ( d n -- r q : signed divide / modulo ) ==========















; ==== mod  ( n1 n2 -- r : remainder of n1 divided by n2 ) =====















; ==== /mod  ( n1 n2 -- r q : remainder/quotient ) =============
'/mod' divides 'n1' by 'n2' and returns the remainder ('r') 
and the quotient ('q') of that operation. Given '/mod', the
definitions of 'mod' and '/' naturally follow. They are
actually all implemented in the far more useful 'um/mod' word.











; ==== ms  ( u -- : wait for 'u' milliseconds ) ================
'ms' waits for 'u' milliseconds with a busy loop. It is
predicated on the system running at 100MHz and will need to be
modified if the system frequency changes.






Usage:
   : 1s 1000 ms ; ( -- : wait for a second )
   : toggle-leds 0 begin invert dup led! 1s again ; ( -- )
   


; ==== negate  ( n -- n : negate a number ) ====================
'negate' performs the negation of a number into twos compliment
format, positive numbers become negative and negative numbers
become positive (with the exclusion of $8000, which stays the
same).



Usage:

  decimal
   1 negate . ( '-1' )
   0 negate . ( '0' )
  -4 negate . ( '4' )


; ==== next  ( -- : part of for...next loop ) ==================















; ==== nip  ( n1 n2 -- n1 : remove second value on stack ) =====
The stack comment describes this word perfectly, 'nip' removes
the secondmost item on the stack, leaving the topmost intact.













; ==== :noname  ( -- xt : start anonymous function ) ===========
The ':noname' word is an immediate word that allows the
creation of words that do not have names, or an anonymous
function. The word can be executed with the 'execute' function.



Usage:

  :noname 2 2 + ; execute . ( prints '4' )
  : (;) ' rdrop compile, 0 state ! ;
  : compose >r >r :noname r> compile, r> compile, (;) ;
  : x 2 2 ;
  : y + . ;
  ' x ' y compose execute ( prints '4' )

; ==== number?  ( b u -- n f : is string a number ) ============















; ==== .ok  ( -- : print okay prompt ) =========================
'.ok' prints out 'ok' after the successful execution of an
input line when the Forth interpreter is in the command mode,
the prompt is suppressed when in compile mode.












; ==== or  ( u1 u2 -- u3: bitwise or of two numbers ) ==========
'or' performs the bitwise 'or' of two numbers. 














; ==== over  ( n1 n2 -- n1 n2 n1 : duplicate over ) ============
'over' duplicates the second most item on the variable stack.
Its stack comment describes its workings completely.







Usage:

  1 2 over .s
  1 2 1


; ==== pack$  ( b u a -- a : pack string into address ) ========
'pack$' is a useful word when dealing with short Forth
strings, it is used by the interpreter for packing the word
name into the words header. It takes a string specified by
'b u', 'b' being an address of a string, and 'u' beings its
length, and copies the string starting at address 'a', the
first byte of the new string is the length of the string, so
it requires an extra byte be available at 'a'. It then returns
a pointer to this newly packed, counted string.







; ==== pad  ( -- a : return address into pad area ) ============
'pad' returns a pointer into the pad area, which begins at
least 80 bytes after the end of the dictionary. The 'pad'
pointer moves when the dictionary pointer moves. It is a useful
area for temporary storage, but should not be used too much.
Some words, such as the Pictured Numeric Output (PNO) words, 
use the area just before the pad area.

Usage:

  3 pad !
  4 pad cell+ !
  pad @ pad cell+ @ + . ( prints '7' )



; ==== page  ( -- : clear page ) ===============================
'page' clears the screen, it does this by emitting the ANSI
terminal escape sequence codes for erasing the display and
moving the cursor position to the top left most cell.






Usage:

  page ( <- That's about it, not much to see )



; ==== parse  ( b u c -- b u delta : parse string out ) ========















; ==== pick  ( un...u0 u -- un...u0 u : pick value ) ===========
'pick' selects an item on the stack at an arbitrary depth 'u'
and pushes a copy onto the variable stack. This word should be
used sparingly and it would be better if it was not used at
all due to the way it is implemented and the limited stack size
available to the H2 processor (32-64 cells deep on both stacks,
plus one for the variable stack). The implementation shuffles
data from the variable stack to the return stack, so it is
quite easy to overflow the return stack for valid but high
values of 'u'.

Usage:
  
  22 33 44 0 pick . ( prints '44' )
  22 33 44 1 pick . ( prints '33' )
  22 33 44 2 pick . ( prints '22' )
; ==== query  ( -- : get line of input ) =======================
'query' gets a new line of input from the current input device,
and places that line in the Terminal Input Buffer, which can
be accessed by 'source'.












; ==== quit  ( -- : interpreter loop ) =========================
For some reason the interpreter loop is evoked by the word
'quit', which is what it is traditionally called. This is not
a good name, but nonetheless is the standard name for it. The
interpreter loop fetches a line of input, parses a word, 
evaluates it, catches/displays any errors and flushes the
current line if there are any, and continues to do this until
the current line contains no new space delimited words/numbers,
whereupon it fetches a new line and repeats the process again.

Usage:

  quit ( <- invokes another interpreter loop... )



; ==== >r  ( u --, R: -- u : move value to return stack ) ======
'>r', also known as 'to r' moves a variable from the variable
stack to the return stack, its inverse is 'r>'. This word, 
along with all return stack words, should be used carefully as
it is possible to trash the return stack with incorrect use.
The word should also be used only from within a word 
definition. The stack comment describes the action of this
word completely.

Usage:

  : rot >r swap r> swap ;    ( n1 n2 n3 -- n2 n3 n1 )
  : -rot swap >r swap r> ;   ( n1 n2 n3 -- n3 n1 n2 )



; ==== r>  ( -- u, R: u --: move value from return stack ) =====
'r>' also known as 'from r', moves a cell sized value from the
return stack to the variable stack. It should only be used from
within a word definition, and only by those that know what they
are doing. It is possible to crash the interpreter by trashing
the return stack with this word. The stack comment for this
word perfectly describes this word.

Usage:

  : rot >r swap r> swap ;   ( n1 n2 n3 -- n2 n3 n1 )
  : -rot swap >r swap r> ;  ( n1 n2 n3 -- n3 n1 n2 )




; ==== r@  ( -- u : R: u -- u: copy top of return stack ) ======
'r@' is a useful word that copies the topmost value on the
return stack, leaving that value in place, and pushes it to
the variable stack.  This word is useful when juggling 
variables on the stack, it is also used to access the loop 
counter in a "for...next" or "for...aft...then...next" 
construct.









; ==== random  ( -- u : random number ) ========================
'random' returns a Pseudo Random Number, it uses a CRC algorithm
and the system timer to generate the value.













; ==== rdrop  ( --, R: u -- : drop a value from return stack ) =
'rdrop' is the return stack equivalent of 'drop', it discards
a single value from the return stack. 

Care should be taken when manipulating the return stack
as it can trash it rendering the system inoperable until it
is restarted.









; ==== recurse  ( -- : recursively call current word ) =========
'recurse' is a word that when used within a word definition it
will recursively call the current word. This is not a tail
call, if this word is used incorrectly it will blow up the
return stack. Some Forths use the construct 'recurse exit'
to implement tail calls, reliant on a peephole optimizer
built into 'exit' to change the call into a branch, this Forth
does not do this. This word is necessary as the word currently
being defined has not been linked into the dictionary yet, to
permit previous versions of the word to be used in the new
definition. This word is a compile only word.

Usage:

  : pick ?dup if swap >r 1- recurse r> swap exit then dup ; 

; ==== repeat  ( -- : part of begin...while...repeat ) =========
'repeat' terminates a 'begin...while...repeat' loop. It is a
word that should only be used as part of a 
'begin...while...repeat' clause, and should only be used
from within a word definition. It is an immediate word. The
words 'begin' and 'while' should also be consulted. 'repeat'
unconditionally jumps back to the 'begin', it is 'while' that
does the test and potentially jumps past this 'repeat' if the
value it pops from variable stack is zero.







; ==== rot  ( n1 n2 n3 -- n2 n3 n1 : rotate three items ) ======
Rotate the first three elements on the variable stack. The
stack comment describes the word completely. If you find your
self using this word too much, you need to rethink and refactor
your Forth. 'rot' is a useful word, but it should be used
sparingly. '-rot' reverses the 'rot' operation.










; ==== -rot  ( n1 n2 n3 -- n3 n1 n2 : rotate three items ) =====
Rotate the first three elements on the variable stack in the
opposite direction as 'rot'. If you find yourself using this
word too much it might be best to refactor your code.












; ==== rp@  ( -- u : return stack depth ) ======================
'rp@' push the return stack depth onto the variable stack, it
is an assembly instruction.













; ==== rpick  ( u -- u, R: un...u0 : pick return stack value ) =
'rpick' picks a value at an arbitrary depth on the return stack
based on the argument given.













; ==== rshift  ( u1 u2 -- u3 : logical right shift u1 by u2 ) ==
'rshift' performs a logical right shift of 'u1' by 'u2' places,
it is equivalent to unsigned division by 2 raised to the power
of 'u2'.












; ==== .s  ( -- : print out variable stack ) ===================
This word is used for debugging, it prints out the entire
variable stack up to the current variable stack depth. It uses
the area between the end of the dictionary and the start of the
PAD area. It is not a reentrant function.











; ==== #s  ( u -- 0 : repeat '#' until 0 ) =====================
This word repeatedly calls '#' on a number until it is zero, it
should only be used within a pictured numeric output construct
and uses the area between the end of the dictionary and the
beginning of the pad area. Characters are held starting from
the pad area working downwards towards the end of the dictionary
space.





Example:
  : print-number <# #s #> type ;
  1234 print-number ( <-- prints '1234' )

; ==== save-buffers  ( -- : save dirty blocks ) ================
'save-buffers' saves any dirty buffers, if there are any, to
disk and sets the block dirty bit to clean (so subsequent calls
to 'save-buffers' will not save blocks to mass storage unless
they have been 'update'd again). You can make a block dirty
by calling 'update' after the block has been loaded, and before
any other blocks have been loaded.

Usage:

  5 block drop      ( load block 5, do nothing with it )
  save-buffers      ( nothing happens, block 5 is not dirty )
  4 block 99 swap ! ( store '99' in first element of block 4 )
  update            ( mark block 4 as dirty )
  save-buffers      ( block 4 written back to disk )

; ==== see  ( -- ; <string> : decompile word ) =================
'see' is a complex word that can decompile a Forth word, it is
liable to be buggy. 'see' parses the next space delimited word
in the dictionary, and if found attempts to disassemble the
word into instructions and function calls. If not found 'see'
will throw an exception. The results of 'see' are 
implementation dependent. Given a very good implementation
of 'see' it would be possible to dispense with the source
code entirely in text form, the binary could be disassembled,
the code modified, and then it could be reintegrated into
dictionary - the idea is purely speculative, comments would
be missing and this version of 'see' is not good enough.
Not many languages have a disassembler built-in!
Usage:
   
  see word
; ==== segments!  ( u -- : display 'u' on LED displays ) =======
Segments writes a single 16-bit value to the four seven segment
displays on the board. This can be used to display a single
cell as a hexadecimal value.






Usage:

  $cafe segments!
  $d1ed segments!
  $0001 segments!

; ==== set-order  ( vn...v0 n -- : set search order ) ==========
This word sets the search order for the dictionary search. It
accepts a variable number of items off of the stack, 'n' is
the number of those item. A special case for the value of 'n'
exists, when it is '-1' it sets the order to the minimal
search order.










; ==== sgr  ( u -- : set ANSI terminal SGR attribute ) =========
'sgr' takes a number and emits it as a 'Select Graphic
Rendition' command, which is a standard ANSI Escape sequence
used for terminal control. SGR commands relate to colors and
how the text is presents, for example numbers $1E to $25 are
used to set the foreground color, $28 to $2F the background
color. $0 is used to reset all of the attributes, $8 is used
to conceal character output, $7 for reverse video. Not all
SGR commands are processed by the VT100 hardware, and if
talking to the device over the UART it depends on the terminal
emulator you are using.

Examples:
   0 sgr    ( reset terminal SGR attributes )
   $1f sgr  ( set foreground color to red )
   $2a sgr  ( set background color to green )
; ==== sign  ( n -- : hold '-' if n negative ) =================
'sign' is a word used in conjunction with the pictured numeric
output routines ('<#', '#s' and '#>'), it holds a '-' is the
signed number it is given is negative.












; ==== source  ( -- a u : get source string ) ==================
'source' retrieves the address and length of the current
Terminal Input Buffer (TIB). This contains the current line
that is being processed, this is the line that is retrieved
by the word 'query'.







Usage:

  source type ( a simple quine )

; ==== source-id  ( -- 0 | -1 : identify input source ) ========
'source-id' is used to identify the input source, whether
the interpreter is reading input from the user (0) or evaluating
text within a string (-1)

Example usage:

  : test $" source-id . cr " count evaluate ;
  test        ( prints FFFF or -1 )
  source-id . ( prints '0')

When a block is evaluated with 'load' -1 is returned by
'source-id' as it is evaluating the block as a string.



; ==== sp@  ( -- u : variable stack depth ) ====================
'sp@' is an assembly instruction which returns the current
depth of the variable stack. 













; ==== space  ( -- : emit space character ) ====================
'space' emits a single space character to the current output
device. That is all.













; ==== spaces  ( n -- : emit 'n' spaces ) ======================
'spaces' emits 'n' number of spaces, if 'n' is greater than 
zero. This is a useful word for formatting.




Usage:

  0 spaces ok
  1 spaces  ok
  2 spaces   ok
 -1 spaces ok



; ==== span  ( -- a : character count from expect, variable ) ==
'span' is a variable which contains the latest character count
from 'expect'. Consult 'expect' for more information.






Usage:

   4000 20 expect
   span @



; ==== state  ( -- a : state variable ) ========================
'state' is a variable that contains the global state of the
Forth interpreter loop, which can be in either compile or
command mode. 'state' contains -1 for command mode, 0 for
compile mode. It can be set directly to change the interpreter
state, or read to make words change their behavior based on
the state (which is generally not the best thing to do). The
words '[' and ']' can be used to switch the state as well.

Usage:

  : ] -1 state ! ;
  : [  0 state ! ; immediate
  : example [ 2 2 + ] literal ;
  example . ( prints '4' )

; ==== =string  ( b1 u1 b2 u2 -- f : string equality ) =========
This word implement a test for string equality, it compares
two strings specified by two address-length pairs and returns
a boolean that determined whether the strings are equal or
not (-1 for true/equal, 0 for false/not-equal). The word is
unusual as it accepts four parameters on the stack, which is
bad practice for Forth words which is most circumstances should
only accept three parameters. This word is used internally for
doing the dictionary search.

Usage:
  : s1 $" Hello " count ;
  : s2 $" Bye! " count ; 
  s1 s2 =string . ( prints '0' )
  s1 s1 =string . ( prints '-1', or 'FFFF' )

; ==== /string  ( b u1 u2 -- b u : advance string by u2 ) ======
'/string' advances a string 'b u1' by 'u2' characters, if there
are enough characters left to advance the string by. This is
obviously a word that is useful when dealing with strings,
strings in Forth commonly come in two type: counted strings
and address-length based strings. This word deals with the
latter type of string.









; ==== swap  ( u1 u2 -- u2 u1 : swap two variables ) ===========
It swaps two variables on the stack, its stack effect describes 
the word perfectly. This is a simple word that will be used
quite a lot, memorize it quickly!






Usage:
   1 2   (     -- 1 2 )
   swap  ( 1 2 -- 2 1 )



; ==== switches  ( -- u : get state of switches ) ==============
'switches' retrieves the state of the two state switches on
the board, the values are already debounced. There are eight
switches which each have a single LED next to them (which can
be controlled with 'led!'). The lowest eight bits are used
for the switch states, 1 for on, 0 for off.

Example usage:
   : select 1 swap lshift switches swap and 0= 0= ;
   : sw0 0 select ; : sw1 1 select ; : sw2 2 select ;
   : sw3 3 select ; : sw4 4 select ; : sw5 5 select ;
   : sw6 6 select ; : sw7 7 select ;
   : switches->leds switches led! ;



; ==== then  ( -- : part of if...then or if...else...then ) ====
'then' should only be used inside a word definition and as
part of an 'if...else...then' or 'if...then' sequence, it is
used to terminate both sequences with execution continuing 
after 'then'. The words 'if' and 'else' should also be
consulted. An exception may be thrown if this word is used
outside a word definition, or if there is not a corresponding
if. It is an immediate word.

Usage:
   : invalid then ; ( <- invalid usage, no matching 'if' )
   then      ( <- invalid usage, outside word definition )
   : example dup if 1+ then ; ( 0 | x -- 0 | x+1 )
   4 example . ( prints '5' )
   0 example . ( prints '0' )

; ==== throw  ( ? n -- ?, R: ? -- ? : throw exception ) ========
'throw' along with 'catch' are the Forth exception handling
routines, 'throw' throws an exception if the number provided to
it is non-zero. An exception unwinds the return stack until
a 'catch' is encountered, the word 'quit' contains the exception
handler of last resort. Numbers from -255 to 0 are reserved for
standard Forth errors.


Usage:

   : fail $1000 throw ;
   : partially-executed cr ." Hello " fail ." World!" cr ;
   : catches-throw ' partially-executed catch u. ;
   catches-throw ( prints only 'Hello' then '1000' )

; ==== thru  ( k1 k2 -- : load from k1 to k2 ) =================
'thru' calls 'load' on a range of blocks from 'k1' to 'k2'
inclusively. It is used to evaluate a range of blocks and as
a convenient way to load software off of mass storage.
Code and data is stored in Forth blocks, 'thru' is used to load
that data. The word 'index' can be used to give an overview
of blocks, as the convention is to have the first line of the
block as a description.




Usage:

   8 9 thru ( evaluate blocks 8 and 9 )

; ==== timer  ( -- u : get value of timer ) ====================
'timer' retrieves the current value of the hardware time in the
FPGA, this peripheral can be controlled with the 'timer!' word,
which is used to control the timer.












; ==== timer!  ( -- : set timer ) ==============================
'timer!' sets the hardware timer control register, allowing the
timer to be enabled/stopped/reset and setting up the value at
which the timer wraps around at (or triggers an interrupt). The
layout of the timer control register is as follows:

  BIT  - MEANING
  15   - Enable Timer (1 = enabled)
  14   - Reset Timer
  13   - Enable Interrupts
  12-0 - Timer Compare Value

The word 'timer' can be used to read in the current value of
the timer.


; ==== tuck  ( n1 n2 -- n2 n1 n2 : tuck value ) ================
'tuck' is a simple word that manipulates the stack, its stack
comment describes what it does. It tucks a variable behind
the second most item on the stack.






Usage:
   5 7  ( -- 5 7 : two example numbers are entered )
   tuck ( 5 7 -- 7 5 7 : tuck does its job )



; ==== type  ( b u -- : print out a string ) ===================
'type' prints out a string, specified by an address 'b' and
a length 'u'. The output goes to the same place as 'emit'
does, which is usually an output device viewable by the
programmer.

The examples use the words '$"' and 'count' which should be
consulted as well. '$"' compiles a string literal into the
dictionary as a counted string, 'count' converts this to
an Address-Length pair needed by type.

Usage:
   : hello cr $" Hello, World!" count type cr ;
   hello          ( execute newly defined word )
   Hello, World!  ( it prints 'Hello, World! )

; ==== u<  ( u1 u2 -- f: unsigned less than ) ==================
Unsigned less than of two numbers.














; ==== u>  ( u1 u2 -- f: unsigned greater than ) ===============
Unsigned greater than, this is not an assembly instruction.














; ==== u>=  ( u1 u2 -- f: unsigned greater or equal to ) =======
Is 'u1' greater than or equal to 'u2', this is an unsigned
operation.













; ==== u.  ( u -- : print out number in current base ) =========
'u.' prints out an unsigned number in the current output base,
this number uses the area at the end of the dictionary and
the beginning of the PAD area as temporary storage.












; ==== um*  ( u u -- ud : unsigned multiply ) ==================
Unsigned multiply, it takes two single cell numbers and returns
an unsigned double cell number.













; ==== um+  ( u u -- u carry : unsigned add with carry ) =======
Unsigned addition with carry, this word is used to implement
the some of the arithmetic operations, although it is not
very useful directly. 'um+' is used directly to implement 'um*'
which in turn is used to implement '*'.











; ==== um/mod  ( ud u -- ur uq : unsigned modulo divide ) ======
Unsigned division of an unsigned double cell number by a single
cell number and leaves the remainder, 'ur' and the quotient,
'uq'. This is a slow operation as it is not implemented as an
instruction within the H2 CPU. It will throw and exception if
the divisor is zero. The word is used to implement the other
division and modulus operations.









; ==== until  ( -- : begin...until loop ) ======================
'until' is a compile only word that should be used as part of
a 'begin...until' loop within a word definition. It is a
conditional looping mechanism that pops and tests a value at
run time, and jumps back to the corresponding 'begin' if the
value is zero, otherwise execution continues after the 'until'.

Usage:
  : invalid until ; ( <- invalid usage, no matching 'begin' )
  until  ( <- invalid usage, used outside a word definition )
  : test begin 1- dup . ?dup 0= until cr ." done " cr ;
  3 test 2 1 0 ( '3 test' prints '2 1 0' )
  done         ( and also prints 'done' )



; ==== update  ( -- : mark last loaded block as dirty ) ========
Marks the last loaded block as being dirty (the last loaded
block block number is stored in the variable 'blk'). A dirty
block will be written to disk on when 'flush', 'save-buffers',
or another block is loaded from disk.

Usage:
   5 block      ( block '5' loaded, block address returned )
   swap 99 !    ( store '99' in block buffer )
   update       ( mark block as dirty )
   save-buffers ( write out block buffer back to block '5' )
   ( block '5' now contains '99' in its first byte, which has )
   ( been saved to disk )



; ==== u.r  ( u +n -- : print u right justified by +n ) ========
'u.r' is a general purpose numeric formatting word, it prints
out the number 'u' as an unsigned number in the current output
radix, preceded by '+n' spaces, minus the number of spaces
needed to display 'u' in the current output radix, or right
aligned. This function uses the area between the end of the
dictionary and the beginning of the PAD area as temporary
storage.

Usage:

  Typed   | <- Result -> |
  4 6 u.r     4 ok
  99 6 u.r    99 ok
  99 5 u.r   99 ok

; ==== variable  ( -- ; <string> : create a new variable ) =====
'variable' parses the next space delimited string from the
input string and makes a new named variable. The variable will
be initialized with zero, although this is not guaranteed to be
the case with all Forths. Variables are just normal words that
push a location onto the dictionary of where the variable is
stored, it can be accessed with the '!' and '@' words, only
one cell of storage space is reserved. The created word is
not an immediate word.







; ==== ver  ( -- u : push version information ) ================
Pushes the version number of the eForth implementation. The
format of the version is the major version is stored in the
upper byte and the minor version information is stored in the
lower byte.

The minor version number changes on minor updates, the major
version changes when there are major updates in how the
interpreter works that could potentially break code.







; ==== while  ( -- : begin...while...repeat loop ) =============















; ==== within  ( u hi lo -- f : is u within a range? ) =========
'within' is used to test with a value is within a range
specified with a maximum and minimum value.













; ==== word  ( c -- a; <string> : parse a word ) ===============
'word' parses the next word in the input stream and returns an
address to a counted string. 'counted strings' have their first
byte as their string length, which can be extracted with the
word 'count'. The delimiter is given as 'c', a special case
exists when 'c' is a space, as all characters up to the ASCII
space are treated as delimiters.









; ==== words  ( -- : list all words in dictionary ) ============
This lists all of the words in the dictionary that are on the
current search order. Each vocabulary is listed with the address
of that vocabulary as a prefix.












; ==== xor  ( u1 u2 -- u : bit wise exclusive or ) =============
Bitwise exclusive or of two numbers, there is nothing more
to this function than that.













; ==============================================================















; ==== ASCII Character Table ===================================
The following section presents a database of all of the ASCII
characters, from 0 through to 127 inclusive. The format of the
database is; decimal, octal, hex then binary value, character
(or name) and finally a column with a short description.
Columns are separated by spaces. There is one entry per line,
with the first line of each block containing an index entry
instead of an ASCII character description.








; ==== ASCII: NUL (0) to SO (14) ===============================
  0 000 00 00000000 NUL    Null char
  1 001 01 00000001 SOH    Start of Heading
  2 002 02 00000010 STX    Start of Text
  3 003 03 00000011 ETX    End of Text
  4 004 04 00000100 EOT    End of Transmission
  5 005 05 00000101 ENQ    Enquiry
  6 006 06 00000110 ACK    Acknowledgment
  7 007 07 00000111 BEL    Bell
  8 010 08 00001000 BS     Back Space
  9 011 09 00001001 HT     Horizontal Tab
 10 012 0A 00001010 LF     Line Feed
 11 013 0B 00001011 VT     Vertical Tab
 12 014 0C 00001100 FF     Form Feed
 13 015 0D 00001101 CR     Carriage Return
 14 016 0E 00001110 SO     Shift Out / X-On
; ==== ASCII: SI (15) to GS (29) ===============================
 15 017 0F 00001111 SI     Shift In / X-Off
 16 020 10 00010000 DLE    Data Line Escape
 17 021 11 00010001 DC1    Device Control 1 (oft. XON)
 18 022 12 00010010 DC2    Device Control 2
 19 023 13 00010011 DC3    Device Control 3 (oft. XOFF)
 20 024 14 00010100 DC4    Device Control 4
 21 025 15 00010101 NAK    Negative Acknowledgement
 22 026 16 00010110 SYN    Synchronous Idle
 23 027 17 00010111 ETB    End of Transmit Block
 24 030 18 00011000 CAN    Cancel
 25 031 19 00011001 EM     End of Medium
 26 032 1A 00011010 SUB    Substitute
 27 033 1B 00011011 ESC    Escape
 28 034 1C 00011100 FS     File Separator
 29 035 1D 00011101 GS     Group Separator
; ==== ASCII: RS (30) to Comma (44) ============================
 30 036 1E 00011110 RS     Record Separator
 31 037 1F 00011111 US     Unit Separator
 32 040 20 00100000 SPACE  Space
 33 041 21 00100001 !      Exclamation mark
 34 042 22 00100010 "      Double quotes (or speech marks)
 35 043 23 00100011 #      Number
 36 044 24 00100100 $      Dollar
 37 045 25 00100101 %      Procenttecken
 38 046 26 00100110 &      Ampersand
 39 047 27 00100111 '      Single quote
 40 050 28 00101000 (      Open parenthesis (or open bracket)
 41 051 29 00101001 )      Close parenthesis (or close bracket)
 42 052 2A 00101010 *      Asterisk
 43 053 2B 00101011 +      Plus
 44 054 2C 00101100 ,      Comma
; ==== ASCII: Hyphen (45) to Semicolon (59) ====================
 45 055 2D 00101101 -      Hyphen
 46 056 2E 00101110 .      Period, dot or full stop
 47 057 2F 00101111 /      Slash or divide
 48 060 30 00110000 0      Zero
 49 061 31 00110001 1      One
 50 062 32 00110010 2      Two
 51 063 33 00110011 3      Three
 52 064 34 00110100 4      Four
 53 065 35 00110101 5      Five
 54 066 36 00110110 6      Six
 55 067 37 00110111 7      Seven
 56 070 38 00111000 8      Eight
 57 071 39 00111001 9      Nine
 58 072 3A 00111010 :      Colon
 59 073 3B 00111011 ;      Semicolon
; ==== ASCII: Less than (60) to Uppercase J (74) ===============
 60 074 3C 00111100 <      Less than
 61 075 3D 00111101 =      Equals
 62 076 3E 00111110 >      Greater than
 63 077 3F 00111111 ?      Question mark
 64 100 40 01000000 @      At symbol
 65 101 41 01000001 A      Uppercase A
 66 102 42 01000010 B      Uppercase B
 67 103 43 01000011 C      Uppercase C
 68 104 44 01000100 D      Uppercase D
 69 105 45 01000101 E      Uppercase E
 70 106 46 01000110 F      Uppercase F
 71 107 47 01000111 G      Uppercase G
 72 110 48 01001000 H      Uppercase H
 73 111 49 01001001 I      Uppercase I
 74 112 4A 01001010 J      Uppercase J
; ==== ASCII: Uppercase K (75) to Uppercase Y (89) =============
 75 113 4B 01001011 K      Uppercase K
 76 114 4C 01001100 L      Uppercase L
 77 115 4D 01001101 M      Uppercase M
 78 116 4E 01001110 N      Uppercase N
 79 117 4F 01001111 O      Uppercase O
 80 120 50 01010000 P      Uppercase P
 81 121 51 01010001 Q      Uppercase Q
 82 122 52 01010010 R      Uppercase R
 83 123 53 01010011 S      Uppercase S
 84 124 54 01010100 T      Uppercase T
 85 125 55 01010101 U      Uppercase U
 86 126 56 01010110 V      Uppercase V
 87 127 57 01010111 W      Uppercase W
 88 130 58 01011000 X      Uppercase X
 89 131 59 01011001 Y      Uppercase Y
; ==== ASCII: Uppercase Z (90) to Lowercase h (104) ============
 90 132 5A 01011010 Z      Uppercase Z
 91 133 5B 01011011 [      Opening bracket
 92 134 5C 01011100 \      Backslash
 93 135 5D 01011101 ]      Closing bracket
 94 136 5E 01011110 ^      Caret - circumflex
 95 137 5F 01011111 _      Underscore
 96 140 60 01100000 `      Grave accent
 97 141 61 01100001 a      Lowercase a
 98 142 62 01100010 b      Lowercase b
 99 143 63 01100011 c      Lowercase c
100 144 64 01100100 d      Lowercase d
101 145 65 01100101 e      Lowercase e
102 146 66 01100110 f      Lowercase f
103 147 67 01100111 g      Lowercase g
104 150 68 01101000 h      Lowercase h
; ==== ASCII: Lowercase i (105) to Lowercase w (119) ===========
105 151 69 01101001 i      Lowercase i
106 152 6A 01101010 j      Lowercase j
107 153 6B 01101011 k      Lowercase k
108 154 6C 01101100 l      Lowercase l
109 155 6D 01101101 m      Lowercase m
110 156 6E 01101110 n      Lowercase n
111 157 6F 01101111 o      Lowercase o
112 160 70 01110000 p      Lowercase p
113 161 71 01110001 q      Lowercase q
114 162 72 01110010 r      Lowercase r
115 163 73 01110011 s      Lowercase s
116 164 74 01110100 t      Lowercase t
117 165 75 01110101 u      Lowercase u
118 166 76 01110110 v      Lowercase v
119 167 77 01110111 w      Lowercase w
; ==== ASCII: Lowercase x (120) to DEL (127) ===================
120 170 78 01111000 x      Lowercase x
121 171 79 01111001 y      Lowercase y
122 172 7A 01111010 z      Lowercase z
123 173 7B 01111011 {      Opening brace
124 174 7C 01111100 |      Vertical bar
125 175 7D 01111101 }      Closing brace
126 176 7E 01111110 ~      Equivalency sign - tilde
127 177 7F 01111111 DEL    Delete








Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.