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

Subversion Repositories forth-cpu

[/] [forth-cpu/] [trunk/] [nvram.txt] - Diff between revs 3 and 5

Only display areas with differences | Details | Blame | View Log

Rev 3 Rev 5
\ ==== Boot Block ==============================================
\ ==== Boot Block ==============================================
-1 loaded !
-1 loaded !
; ==== Short Help ==============================================
; ==== Short Help ==============================================
This is a subroutine threaded Forth, based on eForth. The
This is a subroutine threaded Forth, based on eForth. The
starting base in in hexadecimal. A tutorial, word glossary and
starting base in in hexadecimal. A tutorial, word glossary and
extra code is stored in block storage. A short list of commands
extra code is stored in block storage. A short list of commands
follows ('#' are numbers):
follows ('#' are numbers):
  words       list all Forth words
  words       list all Forth words
  see         decompile the next word in the input stream
  see         decompile the next word in the input stream
  # #2 index  get descriptive titles for blocks from '#' to '#2'
  # #2 index  get descriptive titles for blocks from '#' to '#2'
  # list      list block number '#'
  # list      list block number '#'
  # load      execute code in block '#'
  # load      execute code in block '#'
  # #2 thru   execute code in blocks '#' to '#2'
  # #2 thru   execute code in blocks '#' to '#2'
; ==== Forth Error Messages: 1/4 ===============================
; ==== Forth Error Messages: 1/4 ===============================
  -1 ABORT
  -1 ABORT
  -2 ABORT"
  -2 ABORT"
  -3 stack overflow
  -3 stack overflow
  -4 stack underflow
  -4 stack underflow
  -5 return stack overflow
  -5 return stack overflow
  -6 return stack underflow
  -6 return stack underflow
  -7 do-loops nested too deeply during execution
  -7 do-loops nested too deeply during execution
  -8 dictionary overflow
  -8 dictionary overflow
  -9 invalid memory address
  -9 invalid memory address
 -10 division by zero
 -10 division by zero
 -11 result out of range
 -11 result out of range
 -12 argument type mismatch
 -12 argument type mismatch
 -13 undefined word
 -13 undefined word
 -14 interpreting a compile-only word
 -14 interpreting a compile-only word
 -15 invalid FORGET
 -15 invalid FORGET
; ==== Forth Error Messages: 2/4 ===============================
; ==== Forth Error Messages: 2/4 ===============================
 -16 attempt to use zero-length string as a name
 -16 attempt to use zero-length string as a name
 -17 pictured numeric output string overflow
 -17 pictured numeric output string overflow
 -18 parsed string overflow
 -18 parsed string overflow
 -19 definition name too long
 -19 definition name too long
 -20 write to a read-only location
 -20 write to a read-only location
 -21 unsupported operation
 -21 unsupported operation
 -22 control structure mismatch
 -22 control structure mismatch
 -23 address alignment exception
 -23 address alignment exception
 -24 invalid numeric argument
 -24 invalid numeric argument
 -25 return stack imbalance
 -25 return stack imbalance
 -26 loop parameters unavailable
 -26 loop parameters unavailable
 -27 invalid recursion
 -27 invalid recursion
 -28 user interrupt
 -28 user interrupt
 -29 compiler nesting
 -29 compiler nesting
 -30 obsolescent feature
 -30 obsolescent feature
; ==== Forth Error Messages: 3/4 ===============================
; ==== Forth Error Messages: 3/4 ===============================
 -31 >BODY used on non-CREATEd definition
 -31 >BODY used on non-CREATEd definition
 -32 invalid name argument (e.g., TO xxx)
 -32 invalid name argument (e.g., TO xxx)
 -33 block read exception
 -33 block read exception
 -34 block write exception
 -34 block write exception
 -35 invalid block number
 -35 invalid block number
 -36 invalid file position
 -36 invalid file position
 -37 file I/O exception
 -37 file I/O exception
 -38 non-existent file
 -38 non-existent file
 -39 unexpected end of file
 -39 unexpected end of file
 -40 invalid BASE for floating point conversion
 -40 invalid BASE for floating point conversion
 -41 loss of precision
 -41 loss of precision
 -42 floating-point divide by zero
 -42 floating-point divide by zero
 -43 floating-point result out of range
 -43 floating-point result out of range
 -44 floating-point stack overflow
 -44 floating-point stack overflow
 -45 floating-point stack underflow
 -45 floating-point stack underflow
; ==== Forth Error Messages: 4/4 ===============================
; ==== Forth Error Messages: 4/4 ===============================
 -46 floating-point invalid argument
 -46 floating-point invalid argument
 -47 compilation word list deleted
 -47 compilation word list deleted
 -48 invalid POSTPONE
 -48 invalid POSTPONE
 -49 search-order overflow
 -49 search-order overflow
 -50 search-order underflow
 -50 search-order underflow
 -51 compilation word list changed
 -51 compilation word list changed
 -52 control-flow stack overflow
 -52 control-flow stack overflow
 -53 exception stack overflow
 -53 exception stack overflow
 -54 floating-point underflow
 -54 floating-point underflow
 -55 floating-point unidentified fault
 -55 floating-point unidentified fault
 -56 QUIT
 -56 QUIT
 -57 exception in sending or receiving a character
 -57 exception in sending or receiving a character
 -58 [IF], [ELSE], or [THEN] exception
 -58 [IF], [ELSE], or [THEN] exception
; ==== Description of this file ================================
; ==== Description of this file ================================
The next screens contain extra code that can be loaded into the
The next screens contain extra code that can be loaded into the
interpreter if needed. Some of the standard Forth words are
interpreter if needed. Some of the standard Forth words are
placed here instead of in the image to save on space.
placed here instead of in the image to save on space.
The blocks should be loaded in order unless otherwise stated.
The blocks should be loaded in order unless otherwise stated.
This file is first converted by a utility into a fixed width
This file is first converted by a utility into a fixed width
format, which can then be loaded onto the target board with
format, which can then be loaded onto the target board with
the same utility used to uploaded the bitfile to the FPGA.
the same utility used to uploaded the bitfile to the FPGA.
Line lengths are limited to 64 characters wide, each block
Line lengths are limited to 64 characters wide, each block
contains 16 lines. The first line should contain a
contains 16 lines. The first line should contain a
description of the block so that when it is displayed with
description of the block so that when it is displayed with
'index' a glossary can be viewed, allowing quick navigation.
'index' a glossary can be viewed, allowing quick navigation.
; ==== Scratch Block ===========================================
; ==== Scratch Block ===========================================
\ ==== Block Editor 1/2 ========================================
\ ==== Block Editor 1/2 ========================================
( Block Editor: There is a help section later on )
( Block Editor: There is a help section later on )
variable editor-voc 0 editor-voc ! forth
variable editor-voc 0 editor-voc ! forth
: editor decimal editor-voc 1 set-order ;
: editor decimal editor-voc 1 set-order ;
get-order editor-voc swap 1+ set-order
get-order editor-voc swap 1+ set-order
$40 constant c/l $10 constant l/b
$40 constant c/l $10 constant l/b
: (block) blk @ block ;
: (block) blk @ block ;
: (check) dup b/buf c/l / u>= if -24 throw then ;
: (check) dup b/buf c/l / u>= if -24 throw then ;
: (line) (check) c/l * (block) + ;
: (line) (check) c/l * (block) + ;
: b block drop ;
: b block drop ;
: l blk @ list ;
: l blk @ list ;
: n  1 +block b l ;
: n  1 +block b l ;
: p -1 +block b l ;
: p -1 +block b l ;
: d (line) c/l blank ;
: d (line) c/l blank ;
: x (block) b/buf blank ;
: x (block) b/buf blank ;
: s update save-buffers ;
: s update save-buffers ;
\ ==== Block Editor 2/2 ========================================
\ ==== Block Editor 2/2 ========================================
: q forth save-buffers ;
: q forth save-buffers ;
: e forth blk @ load editor ;
: e forth blk @ load editor ;
: ia c/l * + (block) + source drop >in @ +
: ia c/l * + (block) + source drop >in @ +
  swap source nip >in @ - cmove [compile] \ ;
  swap source nip >in @ - cmove [compile] \ ;
: i 0 swap ia ;
: i 0 swap ia ;
: u update ;
: u update ;
: w words ;
: w words ;
: yank pad c/l ;
: yank pad c/l ;
: c (line) yank >r swap r> cmove ;
: c (line) yank >r swap r> cmove ;
: y (line) yank cmove ;
: y (line) yank cmove ;
: ct swap y c ;
: ct swap y c ;
: ea (line) c/l evaluate ;
: ea (line) c/l evaluate ;
: sw 2dup y (line) swap (line) swap c/l cmove c ;
: sw 2dup y (line) swap (line) swap c/l cmove c ;
forth
forth
\ ==== Assembler word set ======================================
\ ==== Assembler word set ======================================
variable assembler-voc
variable assembler-voc
bl parse rdrop pad pack$ find drop assembler-voc !
bl parse rdrop pad pack$ find drop assembler-voc !
: assembler assembler-voc 1 set-order ;
: assembler assembler-voc 1 set-order ;
: ;code assembler ; immediate
: ;code assembler ; immediate
: code [compile] : assembler ;
: code [compile] : assembler ;
get-order assembler-voc swap 1+ set-order
get-order assembler-voc swap 1+ set-order
: end-code forth [compile] ; ; immediate
: end-code forth [compile] ; ; immediate
: words words ;
: words words ;
: forth forth ;
: forth forth ;
forth
forth
\ ==== CORDIC 1/2 ==============================================
\ ==== CORDIC 1/2 ==============================================
variable lookup -1 cells allot ( 16 values )
variable lookup -1 cells allot ( 16 values )
$3243 , $1DAC , $0FAD , $07F5 , $03FE , $01FF , $00FF , $007F ,
$3243 , $1DAC , $0FAD , $07F5 , $03FE , $01FF , $00FF , $007F ,
$003F , $001F , $000F , $0007 , $0003 , $0001 , $0000 , $0000 ,
$003F , $001F , $000F , $0007 , $0003 , $0001 , $0000 , $0000 ,
: arshift ( n u -- n : arithmetic right shift )
: arshift ( n u -- n : arithmetic right shift )
  2dup rshift >r swap $8000 and
  2dup rshift >r swap $8000 and
  if $10 swap - -1 swap lshift else drop 0 then r> or ;
  if $10 swap - -1 swap lshift else drop 0 then r> or ;
$26DD constant cordic_1K $6487 constant pi/2
$26DD constant cordic_1K $6487 constant pi/2
variable tx 0 tx ! variable ty 0 ty ! variable tz 0 tz !
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 x  0  x ! variable y  0  y ! variable z  0  z !
variable d  0  d ! variable k  0  k !
variable d  0  d ! variable k  0  k !
\ ==== CORDIC 2/2 ==============================================
\ ==== CORDIC 2/2 ==============================================
( CORDIC: valid in range -pi/2 to pi/2, arguments are in fixed )
( CORDIC: valid in range -pi/2 to pi/2, arguments are in fixed )
( point format with 1 = 16384, angle is given in radians.  )
( point format with 1 = 16384, angle is given in radians.  )
: cordic ( angle -- sine cosine )
: cordic ( angle -- sine cosine )
  z ! cordic_1K x ! 0 y ! 0 k !
  z ! cordic_1K x ! 0 y ! 0 k !
  $10 begin ?dup while
  $10 begin ?dup while
    z @ 0< d !
    z @ 0< d !
    x @ y @ k @ arshift d @ xor d @ - - tx !
    x @ y @ k @ arshift d @ xor d @ - - tx !
    y @ x @ k @ arshift d @ xor d @ - + ty !
    y @ x @ k @ arshift d @ xor d @ - + ty !
    z @ k @ cells lookup + @ d @ xor d @ - - tz !
    z @ k @ cells lookup + @ d @ xor d @ - - tz !
    tx @ x ! ty @ y ! tz @ z !
    tx @ x ! ty @ y ! tz @ z !
    k 1+!
    k 1+!
    1-
    1-
  repeat y @ x @ ;
  repeat y @ x @ ;
: sin cordic drop ;
: sin cordic drop ;
: cos cordic nip ;
: cos cordic nip ;
\ ==== Login Code 1/2 ==========================================
\ ==== Login Code 1/2 ==========================================
\ Login and user management system: @todo clear up with vocabs
\ Login and user management system
: generate count dup >r crc r> ccitt ; ( b -- u )
: generate count dup >r crc r> ccitt ; ( b -- u )
: .user     ." user>" space ; ( -- )
: .user     ." user>" space ; ( -- )
: .password ." password>" space ; ( -- )
: .password ." password>" space ; ( -- )
variable user0 0 user0 !
variable user0 0 user0 !
: mk.user ( --; ,  )
: mk.user ( --; ,  )
  here user0 @ , user0 ! here 0 , bl word count 1+ allot align
  here user0 @ , user0 ! here 0 , bl word count 1+ allot align
  drop bl word generate swap ! ;
  drop bl word generate swap ! ;
: ls.user ( -- : list all users in user database )
: ls.user ( -- : list all users in user database )
  cr user0 @
  cr user0 @
  begin dup while dup 2 cells + space count type cr @ repeat
  begin dup while dup 2 cells + space count type cr @ repeat
  drop cr ;
  drop cr ;
: find.user ( a -- u | 0 : find user in database, return hash )
: find.user ( a -- u | 0 : find user in database, return hash )
  >r user0 @ begin dup while dup 2 cells + count r@ count
  >r user0 @ begin dup while dup 2 cells + count r@ count
  =string if rdrop exit then @ repeat rdrop drop 0 ;
  =string if rdrop exit then @ repeat rdrop drop 0 ;
\ ==== Login Code 2/2 ==========================================
\ ==== Login Code 2/2 ==========================================
: (password) ( u --,  )
: (password) ( u --,  )
  >r begin .password query bl word cr generate
  >r begin .password query bl word cr generate
  r@ = until rdrop ;
  r@ = until rdrop ;
: fake .password query bl word drop cr ;
: fake .password query bl word drop cr ;
: (user)
: (user)
  begin .user query bl word cr find.user ?dup until ;
  begin .user query bl word cr find.user ?dup until ;
: retry ( xt -- : retry word until it succeeds )
: retry ( xt -- : retry word until it succeeds )
  >r begin r@ catch 0= until rdrop ;
  >r begin r@ catch 0= until rdrop ;
: user?     ' (user)     retry ;
: user?     ' (user)     retry ;
: password? ' (password) retry ;
: password? ' (password) retry ;
: hide-all 0 1 set-order ;
: hide-all 0 1 set-order ;
: login hide-all
: login hide-all
  cr user? cell+ @ conceal password? interactive forth ;
  cr user? cell+ @ conceal password? interactive forth ;
mk.user guest guest     mk.user archer dangerzone
mk.user guest guest     mk.user archer dangerzone
mk.user lana  sterling  mk.user cyril  figgis
mk.user lana  sterling  mk.user cyril  figgis
\ ==== Extra Code 1/7 ==========================================
\ ==== Extra Code 1/7 ==========================================
: 2+ 2 + ;                       ( n -- n )
: 2+ 2 + ;                       ( n -- n )
: 2- 2 - ;                       ( n -- n )
: 2- 2 - ;                       ( n -- n )
: >= < invert ;                  ( n n -- f )
: >= < invert ;                  ( n n -- f )
: simulation? cpu-id $cafe <> ; ( -- f : are we in the matrix? )
: simulation? cpu-id $0666 <> ; ( -- f : are we in the matrix? )
: 0<= 0> 0= ;                    ( n n -- f )
: 0<= 0> 0= ;                    ( n n -- f )
: 0>= 0< 0= ;                    ( n n -- f )
: 0>= 0< 0= ;                    ( n n -- f )
: not -1 xor ;                   ( n -- n )
: not -1 xor ;                   ( n -- n )
: dabs dup 0< if dnegate then ;  ( d -- d )
: dabs dup 0< if dnegate then ;  ( d -- d )
: d+  >r swap >r um+ r> r> + + ; ( d d -- d )
: d+  >r swap >r um+ r> r> + + ; ( d d -- d )
: d=  >r swap r> = >r = r> and ; ( d d -- f )
: d=  >r swap r> = >r = r> and ; ( d d -- f )
: d<> d= 0= ;                    ( d d -- f )
: d<> d= 0= ;                    ( d d -- f )
: roll  dup 0> if swap >r 1- recurse r> swap else drop then ;
: roll  dup 0> if swap >r 1- recurse r> swap else drop then ;
: ?exit if rdrop then ;          ( n --, R: n -- n | )
: ?exit if rdrop then ;          ( n --, R: n -- n | )
: 2rdrop r> rdrop rdrop >r ;     ( R n n -- )
: 2rdrop r> rdrop rdrop >r ;     ( R n n -- )
: 2. swap . . ;                  ( n n -- )
: 2. swap . . ;                  ( n n -- )
\ ==== Extra Code 2/7 ==========================================
\ ==== Extra Code 2/7 ==========================================
: m* 2dup xor 0< >r abs swap abs um* r> if dnegate then ;
: 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  >r m* r> m/mod ;  ( n n n -- r q )
: */  */mod nip ;          ( n n n -- q )
: */  */mod nip ;          ( n n n -- q )
: s>d dup 0< ;             ( n -- d : single to double )
: s>d dup 0< ;             ( n -- d : single to double )
: holds begin dup while 1- 2dup + c@ hold repeat 2drop ;
: holds begin dup while 1- 2dup + c@ hold repeat 2drop ;
: binary  2 base ! ;                       ( -- )
: binary  2 base ! ;                       ( -- )
: octal  8 base ! ;                        ( -- )
: octal  8 base ! ;                        ( -- )
: .base base @ dup decimal base ! ; ( -- )
: .base base @ dup decimal base ! ; ( -- )
: only -1 set-order ;
: only -1 set-order ;
: also get-order over swap 1+ set-order ;
: also get-order over swap 1+ set-order ;
: previous get-order swap drop 1- set-order ;
: previous get-order swap drop 1- set-order ;
: buffer block ; ( k -- a )
: buffer block ; ( k -- a )
: bye [ 0 , ] ;
: bye [ 0 , ] ;
: enum dup constant 1+ ; ( n --,  )
: enum dup constant 1+ ; ( n --,  )
: logical 0= 0= ;     ( n -- f )
: logical 0= 0= ;     ( n -- f )
\ ==== Extra Code 3/7 ==========================================
\ ==== Extra Code 3/7 ==========================================
: square dup * ;      ( n -- )
: square dup * ;      ( n -- )
: limit rot min max ; ( n lo hi -- n )
: limit rot min max ; ( n lo hi -- n )
: odd 1 and logical ; ( n -- )
: odd 1 and logical ; ( n -- )
: even odd invert ;   ( n -- )
: even odd invert ;   ( n -- )
: nor or invert ;     ( u u -- u )
: nor or invert ;     ( u u -- u )
: nand and invert ;   ( u u -- u )
: nand and invert ;   ( u u -- u )
: bell 7 emit ;       ( -- )
: bell 7 emit ;       ( -- )
: under >r dup r> ;   ( n1 n2 -- n1 n1 n2 )
: under >r dup r> ;   ( n1 n2 -- n1 n1 n2 )
: 2nip >r >r 2drop r> r> ; ( n1 n2 n3 n4 -- n3 n4 )
: 2nip >r >r 2drop r> r> ; ( n1 n2 n3 n4 -- n3 n4 )
( n1 n2 n3 n4 -- n1 n2 n3 n4 n1 n2 )
( n1 n2 n3 n4 -- n1 n2 n3 n4 n1 n2 )
: 2over >r >r 2dup r> swap >r swap r> r> -rot ;
: 2over >r >r 2dup r> swap >r swap r> r> -rot ;
: 2swap >r -rot r> -rot ; ( n1 n2 n3 n4 -- n3 n4 n1 n2 )
: 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 )
: 2tuck 2swap 2over ; ( n1 n2 n3 n4 -- n3 n4 n1 n2 n3 n4 )
: 4drop 2drop 2drop ; ( n1 n2 n3 n4 -- )
: 4drop 2drop 2drop ; ( n1 n2 n3 n4 -- )
: trip dup dup ; ( n -- n n n )
: trip dup dup ; ( n -- n n n )
\ ==== Extra Code 4/7 ==========================================
\ ==== Extra Code 4/7 ==========================================
: log  >r 0 swap ( u base -- u )
: log  >r 0 swap ( u base -- u )
  begin swap 1+ swap r@ / dup 0= until
  begin swap 1+ swap r@ / dup 0= until
  drop 1- rdrop ;
  drop 1- rdrop ;
: log2 0 swap ( u -- u )
: log2 0 swap ( u -- u )
  begin swap 1+ swap   2/ dup 0= until
  begin swap 1+ swap   2/ dup 0= until
  drop 1- ;
  drop 1- ;
: average um+ 2 um/mod nip ; ( u u -- u )
: average um+ 2 um/mod nip ; ( u u -- u )
: <=> 2dup > if 2drop -1 exit then < ;
: <=> 2dup > if 2drop -1 exit then < ;
: bounds over + swap ;
: bounds over + swap ;
: 2, , , ; ( n n -- )
: 2, , , ; ( n n -- )
: tab 9 emit ; ( -- )
: tab 9 emit ; ( -- )
: drup drop dup ; ( n1 n2 -- n1 n1 )
: drup drop dup ; ( n1 n2 -- n1 n1 )
: lsb $ff and ; ( u -- u )
: lsb $FF and ; ( u -- u )
: --> 1 +block load ;
: --> 1 +block load ;
: scr blk ;
: scr blk ;
\ ==== Extra Code 5/7 ==========================================
\ ==== Extra Code 5/7 ==========================================
: signum ( n -- -1 | 0 | 1 : Signum function )
: signum ( n -- -1 | 0 | 1 : Signum function )
  dup 0> if drop  1 exit then
  dup 0> if drop  1 exit then
      0< if      -1 exit then
      0< if      -1 exit then
      0 ;
      0 ;
: >< dup 8 rshift swap 8 lshift or ; ( u -- u : swap bytes )
: >< dup 8 rshift swap 8 lshift or ; ( u -- u : swap bytes )
: #digits dup 0= if 1+ exit then base @ log 1+ ;
: #digits dup 0= if 1+ exit then base @ log 1+ ;
: ** ( n u -- n )
: ** ( n u -- n )
  ?dup if
  ?dup if
    over >r
    over >r
    begin
    begin
      dup 1 >
      dup 1 >
    while
    while
      swap r@ * swap 1-
      swap r@ * swap 1-
    repeat rdrop drop
    repeat rdrop drop
  else logical 1 and then ;
  else logical 1 and then ;
\ ==== Extra Code 6/7 ==========================================
\ ==== Extra Code 6/7 ==========================================
: b. base @ swap 2 base ! u. base ! ; ( u -- )
: b. base @ swap 2 base ! u. base ! ; ( u -- )
: h. base @ swap hex u. base ! ;      ( u -- )
: h. base @ swap hex u. base ! ;      ( u -- )
: o. base @ swap 8 base ! u. base ! ; ( u -- )
: o. base @ swap 8 base ! u. base ! ; ( u -- )
: d. base @ swap decimal . base ! ;   ( n -- )
: d. base @ swap decimal . base ! ;   ( n -- )
: @bits swap @ and ;                  ( a u -- u )
: @bits swap @ and ;                  ( a u -- u )
: ?\ if [compile] \ then ; immediate
: ?\ if [compile] \ then ; immediate
: ?( if [compile] ( then ; immediate ( )
: ?( if [compile] ( then ; immediate ( )
: defined? ( -- pwd -1 | 0,  : is word defined? )
: defined? ( -- pwd -1 | 0,  : is word defined? )
  bl word find if -1 else drop 0 then ;
  bl word find if -1 else drop 0 then ;
: ?if compile dup [compile] if ; immediate
: ?if compile dup [compile] if ; immediate
: ?dup-if compile ?dup [compile] if ; immediate
: ?dup-if compile ?dup [compile] if ; immediate
: >body ( dup @ $4000 or <> if 31 -throw then ) cell+ ;
: >body ( dup @ $4000 or <> if 31 -throw then ) cell+ ;
\ ==== Extra Code 7/7 ==========================================
\ ==== Extra Code 7/7 ==========================================
: screens ( k1 k2 -- : list blocks k1 to k2 )
: screens ( k1 k2 -- : list blocks k1 to k2 )
  over -
  over -
  for
  for
    dup . dup list 1+ nuf? if rdrop drop exit then
    dup . dup list 1+ key $D = if rdrop drop exit then
  next drop ;
  next drop ;
\ ==== Roulette ================================================
\ ==== Roulette ================================================
\ Russian Roulette: It would be interesting to do something
\ Russian Roulette: It would be interesting to do something
\ killed the computer when the player dies
\ killed the computer when the player dies
: click ."  *click*" cr ;
: click ."  *click*" cr ;
: bang  ."  BANG!" cr ;
: bang  ."  BANG!" cr ;
: roulette random 6 mod if click else bang then ; ( -- )
: roulette random 6 mod if click else bang then ; ( -- )
\ ==== Extended ANSI Escape Codes ==============================
\ ==== Extended ANSI Escape Codes ==============================
0 constant black 1 constant red 2 constant green 4 constant blue
0 constant black 1 constant red 2 constant green 4 constant blue
red green        + constant yellow
red green        + constant yellow
    green blue   + constant cyan
    green blue   + constant cyan
red       blue   + constant magenta
red       blue   + constant magenta
red green blue + + constant white
red green blue + + constant white
: background $a + ;
: background $A + ;
: color $1e + sgr ;
: color $1E + sgr ;
\ : hide-cursor CSI [char] ? emit $19 10u. [char] l emit ;
\ : hide-cursor CSI [char] ? emit $19 10u. [char] l emit ;
\ : show-cursor CSI [char] ? emit $19 10u. [char] h emit ;
\ : show-cursor CSI [char] ? emit $19 10u. [char] h emit ;
: up    [char] A ansi ; ( n -- )
: up    [char] A ansi ; ( n -- )
: down  [char] B ansi ; ( n -- )
: down  [char] B ansi ; ( n -- )
: left  [char] C ansi ; ( n -- )
: left  [char] C ansi ; ( n -- )
: right [char] D ansi ; ( n -- )
: right [char] D ansi ; ( n -- )
\ ==== Screen Saver ============================================
\ ==== Screen Saver ============================================
\ An incredibly simple screen saver using ANSI Escape codes
\ An incredibly simple screen saver using ANSI Escape codes
\ for placement and coloring of random characters
\ for placement and coloring of random characters
 
base @ decimal
: screen-saver ( -- )
: screen-saver ( -- )
  page
  page
  begin
  begin
    random 80 mod
    random 79 mod
    random 40 mod at-xy
    random 38 mod at-xy
    random >char emit
    random >char emit
    random 8  mod
    random 8  mod
    ( random 1 and if background then )
    random 1 and if background then
    color
    random 256 and ms color
  again ;
  again ;
 
base !
 
 
; ==== Game: YOU ARE DEAD (HELP) ===============================
; ==== Game: YOU ARE DEAD (HELP) ===============================
This is a clone of the one dimensional rogue like game
This is a clone of the one dimensional rogue like game
available at . The
available at . The
object is to get to the other side of the screen.
object is to get to the other side of the screen.
Keys:
Keys:
w  Turn into '.'
w  Turn into '.'
a  Turn into '~'
a  Turn into '~'
s  Turn into '>'
s  Turn into '>'
d  Move right
d  Move right
q  Quit
q  Quit
Block number 7 is used to store the game state.
Block number 7 is used to store the game state.
\ ==== Game: YOU ARE DEAD 1/6 ==================================
\ ==== Game: YOU ARE DEAD 1/6 ==================================
forth variable yad-voc get-order yad-voc swap 1+ set-order
forth variable yad-voc get-order yad-voc swap 1+ set-order
$40 constant c/l $10 constant l/b
$40 constant c/l $10 constant l/b
: memory 7 block ;
: memory 7 block ;
: variables memory c/l + ;
: variables memory c/l + ;
: score    variables 0 cells + ;
: score    variables 0 cells + ;
: position variables 1 cells + ;
: position variables 1 cells + ;
: level    variables 2 cells + ;
: level    variables 2 cells + ;
: form     variables 3 cells + ;
: form     variables 3 cells + ;
: continue variables 4 cells + ;
: continue variables 4 cells + ;
: end c/l 1- ;
: end c/l 1- ;
: player form @ ;
: player form @ ;
: .player position @ 1+ 3 at-xy player emit ;
: .player position @ 1+ 3 at-xy player emit ;
: .goal c/l 3 at-xy [char] # emit ;
: .goal c/l 3 at-xy [char] # emit ;
: .score ." SCORE: " score @ 5 u.r ;
: .score ." SCORE: " score @ 5 u.r ;
: .level ." LEVEL: " level @ 5 u.r ;
: .level ." LEVEL: " level @ 5 u.r ;
\ ==== Game: YOU ARE DEAD 2/6 ==================================
\ ==== Game: YOU ARE DEAD 2/6 ==================================
: show
: show
  page cr cr space memory c/l type
  page cr cr space memory c/l type
  .player .goal
  .player .goal
  cr .score space .level cr ;
  cr .score space .level cr ;
: select ( n -- c )
: select ( n -- c )
  dup 0=  if drop [char] <  exit then
  dup 0=  if drop [char] <  exit then
  dup 1 = if drop [char] ~  exit then
  dup 1 = if drop [char] ~  exit then
  dup 2 = if drop [char] .  exit then
  dup 2 = if drop [char] .  exit then
  drop bl ;
  drop bl ;
: die ." YOU ARE DEAD" cr 0 continue ! -56 throw ;
: die ." YOU ARE DEAD" cr 0 continue ! -56 throw ;
: survived ." YOU SURVIVED" cr .score cr ;
: survived ." YOU SURVIVED" cr .score cr ;
: forms form c@ position @ memory + c@ ; ( -- c c )
: forms form c@ position @ memory + c@ ; ( -- c c )
\ ==== Game: YOU ARE DEAD 3/6 ==================================
\ ==== Game: YOU ARE DEAD 3/6 ==================================
: generate ( -- generate a level )
: generate ( -- generate a level )
  c/l 1- for
  c/l 1- for
    random 5 mod ( 3 = most difficult )
    random 5 mod ( 3 = most difficult )
    select memory r@ + c!
    select memory r@ + c!
  next
  next
  bl memory c! bl memory end + c! ;
  bl memory c! bl memory end + c! ;
: normal [char] x ;
: normal [char] x ;
: setup ( -- )
: setup ( -- )
  -1 continue !
  -1 continue !
  memory b/buf 0 fill
  memory b/buf 0 fill
  normal form c!
  normal form c!
  generate ;
  generate ;
: +score random 4 mod 1 min score +! ; ( -- )
: +score random 4 mod 1 min score +! ; ( -- )
: ?next <> if die else +score then ; ( c c -- )
: ?next <> if die else +score then ; ( c c -- )
\ ==== Game: YOU ARE DEAD 4/6 ==================================
\ ==== Game: YOU ARE DEAD 4/6 ==================================
: +level
: +level
  0 position ! level 1+!
  0 position ! level 1+!
  random 23 mod 5 min score +!
  random 23 mod 5 min score +!
  generate ;
  generate ;
: monster swap >r forms r> = if ?next else 2drop then ;
: monster swap >r forms r> = if ?next else 2drop then ;
: command ( -- f )
: command ( -- f )
  dup [char] w = if drop [char] . form c! 0 exit then
  dup [char] w = if drop [char] . form c! 0 exit then
  dup [char] a = 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] d = if drop -1 exit then
  dup [char] s = if drop [char] < form c! 0 exit then
  dup [char] s = if drop [char] < form c! 0 exit then
  dup [char] q = if drop -56 throw then
  dup [char] q = if drop -56 throw then
  drop 0 ;
  drop 0 ;
\ ==== Game: YOU ARE DEAD 5/6 ==================================
\ ==== Game: YOU ARE DEAD 5/6 ==================================
: rules
: rules
  position @ end = if +level exit then
  position @ end = if +level exit then
  forms = if exit then
  forms = if exit then
  [char] ~ [char] < monster
  [char] ~ [char] < monster
  [char] . [char] ~ monster
  [char] . [char] ~ monster
  [char] < [char] . monster
  [char] < [char] . monster
  normal form c!
  normal form c!
  bl position @ memory + c!
  bl position @ memory + c!
  score 1+!
  score 1+!
  position 1+! ;
  position 1+! ;
\ ==== Game: YOU ARE DEAD 6/6 ==================================
\ ==== Game: YOU ARE DEAD 6/6 ==================================
: game
: game
  begin
  begin
  show
  show
  key command if rules then
  key command if rules then
  level @ 9 >
  level @ 9 >
  until survived ;
  until survived ;
: play setup ' game catch drop ;
: play setup ' game catch drop ;
get-order -rot swap rot set-order
get-order -rot swap rot set-order
: you-are-dead base @ decimal play base ! ;
: you-are-dead base @ decimal play base ! ;
forth
forth
\ : resume memory drop ' game catch drop ;
\ : 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
 
\ . 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 ============================
; ==== Brain F*ck Compiler Help 1/2 ============================
Brainfuck is a simple esoteric language with only 8 commands, it
Brainfuck is a simple esoteric language with only 8 commands, it
is Turing complete which means it can compute any function which
is Turing complete which means it can compute any function which
can be computed - although it is very difficult to do so. The
can be computed - although it is very difficult to do so. The
commands operate on a block of memory 1024 bytes long. A data
commands operate on a block of memory 1024 bytes long. A data
pointer indexes into the memory. The commands are:
pointer indexes into the memory. The commands are:
  >  increment the data pointer
  >  increment the data pointer
  <  decrement the data pointer
  <  decrement the data pointer
  +  increment value at data pointer
  +  increment value at data pointer
  -  decrement value at data pointer
  -  decrement value at data pointer
  .  output byte at data pointer
  .  output byte at data pointer
  ,  accept one byte and store it at data pointer
  ,  accept one byte and store it at data pointer
  [  branch forward to ] if byte at data pointer is zero
  [  branch forward to ] if byte at data pointer is zero
  ]  branch back    to [ if byte at data pointer is non-zero
  ]  branch back    to [ if byte at data pointer is non-zero
The compiler discards all other input.
The compiler discards all other input.
; ==== Brain F*ck Compiler Help 2/2 ============================
; ==== Brain F*ck Compiler Help 2/2 ============================
The following blocks implement the compiler, it translates each
The following blocks implement the compiler, it translates each
command in a given string into Forth code, compiling it into a
command in a given string into Forth code, compiling it into a
new word definition which can then be executed.
new word definition which can then be executed.
Needless to say, it is not a useful language, but it is fun!
Needless to say, it is not a useful language, but it is fun!
Some example programs are given after the compiler block.
Some example programs are given after the compiler block.
This Forth brain fuck compiler was derived from the one
This Forth brain fuck compiler was derived from the one
available Rosetta Code, and so is licensed under the
available Rosetta Code, and so is licensed under the
GNU Free Documentation License [v1.2]. See:
GNU Free Documentation License [v1.2]. See:
And for more information see:
And for more information see:
 
 
 
 
\ ==== Brain F*ck Compiler 1/2 =================================
\ ==== Brain F*ck Compiler 1/2 =================================
: left over c!  1- dup c@ ;
: left over c!  1- dup c@ ;
: right over c! 1+ dup c@ ;
: right over c! 1+ dup c@ ;
: erase 0 fill ;
: erase 0 fill ;
: initialize pad b/buf erase pad 0 ;
: initialize pad b/buf erase pad 0 ;
: bf-compile ( c -- )
: bf-compile ( c -- )
  >r
  >r
  r@ [char] [ = if [compile] begin
  r@ [char] [ = if [compile] begin
                   compile dup [compile] while then
                   compile dup [compile] while then
  r@ [char] ] = if [compile] repeat            then
  r@ [char] ] = if [compile] repeat            then
  r@ [char] + = if compile 1+                  then
  r@ [char] + = if compile 1+                  then
  r@ [char] - = if compile 1-                  then
  r@ [char] - = if compile 1-                  then
  r@ [char] < = if compile left                then
  r@ [char] < = if compile left                then
  r@ [char] > = if compile right               then
  r@ [char] > = if compile right               then
  r@ [char] , = if compile drop compile key    then
  r@ [char] , = if compile drop compile key    then
  r@ [char] . = if compile dup  compile emit   then rdrop ;
  r@ [char] . = if compile dup  compile emit   then rdrop ;
\ ==== Brain F*ck Compiler 2/2 =================================
\ ==== Brain F*ck Compiler 2/2 =================================
: bf ( b u --, : compile brainfuck program into a word )
: bf ( b u --, : compile brainfuck program into a word )
  >r >r
  >r >r
  [compile] :
  [compile] :
  compile initialize
  compile initialize
  r> r> for aft
  r> r> for aft
    dup 1+ >r c@ bf-compile r>
    dup 1+ >r c@ bf-compile r>
  then next
  then next
  drop
  drop
  compile swap
  compile swap
  compile c@
  compile c@
  compile 2drop
  compile 2drop
  [compile] ; ;
  [compile] ; ;
\ Example, making a simple echo like program called 'cat':
\ Example, making a simple echo like program called 'cat':
\ : string $" +[,.]" count ; string bf cat
\ : string $" +[,.]" count ; string bf cat
; ==== Brain F*ck Example Programs =============================
; ==== Brain F*ck Example Programs =============================
From: http://www.hevanet.com/cristofd/brainfuck/short.b
From: http://www.hevanet.com/cristofd/brainfuck/short.b
Hello World: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]
Hello World: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]
>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
Clear Screen: ++++++++++[>++++++++++>+<<-]>[>.<-]
Clear Screen: ++++++++++[>++++++++++>+<<-]>[>.<-]
Beep: +++++++.
Beep: +++++++.
Copy Input to Output: ,[.[-],]
Copy Input to Output: ,[.[-],]
Reverse Input: >,[>,]<[.<]
Reverse Input: >,[>,]<[.<]
Translate text to brain fuck that prints said Text:
Translate text to brain fuck that prints said Text:
+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]
+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]
; ==== eForth v6.66: Help and Tutorial =========================
; ==== eForth v6.66: Help and Tutorial =========================
This Forth is modeled after eForth, described in a book by
This Forth is modeled after eForth, described in a book by
C.H. Ting called "eForth Overview", or "The Zen of eForth". It
C.H. Ting called "eForth Overview", or "The Zen of eForth". It
implements most of the eForth model with some changes expected
implements most of the eForth model with some changes expected
from a more modern Forth system.
from a more modern Forth system.
The processor targeted is called the H2, a rewrite of the
The processor targeted is called the H2, a rewrite of the
J1 processor ().
J1 processor ().
It has been extended with a few more instructions and with
It has been extended with a few more instructions and with
interrupts. The system resides on an FPGA Nexys 3 board from
interrupts. The system resides on an FPGA Nexys 3 board from
Digilent, with words and peripherals designed for it.
Digilent, with words and peripherals designed for it.
For more see: 
For more see: 
; ==== Help: Introduction ======================================
; ==== Help: Introduction ======================================
Forth is a simple, imperative, stack based language that mixes
Forth is a simple, imperative, stack based language that mixes
elements of a high level language with a low level language. It
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
is possible to fit a small Forth system in a few kilobytes of
RAM complete with an interactive read-evaluate-print loop, an
RAM complete with an interactive read-evaluate-print loop, an
editor, an assembler and a disassembler.
editor, an assembler and a disassembler.
It is also a language that has fallen out of favor in recent
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
times (after the micro-computer era) as it is not a very safe
language, nor is it one that allows the programmer to easily
language, nor is it one that allows the programmer to easily
create reusable and maintainable software components.
create reusable and maintainable software components.
However it is still suitable for a number of purposes; for
However it is still suitable for a number of purposes; for
assemblers, to bring up hardware and test it, in memory
assemblers, to bring up hardware and test it, in memory
constrained systems, as a boot loader, and for fun.
constrained systems, as a boot loader, and for fun.
; ==== Help: Philosophy of Forth ===============================
; ==== Help: Philosophy of Forth ===============================
Forth itself has its own philosophy, one in which the programmer
Forth itself has its own philosophy, one in which the programmer
should have a complete understanding of the system, from the
should have a complete understanding of the system, from the
problem that needs to be solved, the algorithms needed to solve
problem that needs to be solved, the algorithms needed to solve
it, the hardware and the software. As the latter two, the
it, the hardware and the software. As the latter two, the
hardware and software are usually very simple in Forth systems
hardware and software are usually very simple in Forth systems
it is possible to optimize the problem across multiple domains,
it is possible to optimize the problem across multiple domains,
tailoring each to come up with a solution. Forth eschews
tailoring each to come up with a solution. Forth eschews
complexity, preferring one off, bespoke solutions. Another
complexity, preferring one off, bespoke solutions. Another
reason it has not seen widespread use.
reason it has not seen widespread use.
Advocates of the language are usually quite passionate about
Advocates of the language are usually quite passionate about
it (as with Lisp, and other niche systems) so it is important
it (as with Lisp, and other niche systems) so it is important
to be pragmatic about Forth. Forth is simply a tool and when
to be pragmatic about Forth. Forth is simply a tool and when
used correctly can be used productively.
used correctly can be used productively.
; ==== Help: Basics 1/6 ========================================
; ==== Help: Basics 1/6 ========================================
A Forth system contains an interactive interpreter that parses
A Forth system contains an interactive interpreter that parses
text and either compiles or executes functions, called 'words'
text and either compiles or executes functions, called 'words'
in Forth terminology. The system uses Reverse Polish Notation
in Forth terminology. The system uses Reverse Polish Notation
(RPN) and provides the user with two stacks and a 'dictionary'
(RPN) and provides the user with two stacks and a 'dictionary'
(a big block of memory containing 'words' and other data).
(a big block of memory containing 'words' and other data).
The interpreter reads from an input device, such as a keyboard
The interpreter reads from an input device, such as a keyboard
or a serial port, and writes output to the screen or back over
or a serial port, and writes output to the screen or back over
the serial port. Words and number input are space delimited and
the serial port. Words and number input are space delimited and
are either compiled into the dictionary depending on the
are either compiled into the dictionary depending on the
interpreter mode and whether the word read in is 'immediate'
interpreter mode and whether the word read in is 'immediate'
or not.
or not.
This tutorial will describe how to use Forth and how the
This tutorial will describe how to use Forth and how the
interpreter works internally.
interpreter works internally.
; ==== Help: Basics 2/6 ========================================
; ==== Help: Basics 2/6 ========================================
To start with, simple expressions can be entered and the
To start with, simple expressions can be entered and the
results displayed. A line is evaluated after the carriage
results displayed. A line is evaluated after the carriage
return is entered, code will be indented, this can be typed in.
return is entered, code will be indented, this can be typed in.
We will start off with a simple expression, adding two numbers
We will start off with a simple expression, adding two numbers
together and displaying the result:
together and displaying the result:
  ( Comments appear within brackets )
  ( Comments appear within brackets )
  2 2 + .
  2 2 + .
This prints out '4' and 'ok'. 'ok' is printed out after every
This prints out '4' and 'ok'. 'ok' is printed out after every
line has been successfully compiled, unless we are in compile
line has been successfully compiled, unless we are in compile
mode. '+' obviously does the addition, and '.' pops a value
mode. '+' obviously does the addition, and '.' pops a value
off the stack an prints it. Entering a number pushes it onto
off the stack an prints it. Entering a number pushes it onto
the data stack.
the data stack.
; ==== Help: Basics 3/6 ========================================
; ==== Help: Basics 3/6 ========================================
The data, or variable, stack is a general purpose stack that
The data, or variable, stack is a general purpose stack that
the programmer uses to pass data to functions, and to return
the programmer uses to pass data to functions, and to return
data from functions. The stacks are an important concept
data from functions. The stacks are an important concept
within Forth and stack management will take up a lot of a Forth
within Forth and stack management will take up a lot of a Forth
programmers time.
programmers time.
Numbers are entered in Reverse Polish Notation, this allows
Numbers are entered in Reverse Polish Notation, this allows
Forth interpreter to immediate process a word or a function as
Forth interpreter to immediate process a word or a function as
it is encountered instead of building up a parse tree.
it is encountered instead of building up a parse tree.
When '2' is encountered it is pushed onto the variable stack,
When '2' is encountered it is pushed onto the variable stack,
when the second '2' is input, it is also pushed onto the 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
The Forth word '+' takes two arguments off the stack, adds them
together and pushes the result back onto the stack. The word
together and pushes the result back onto the stack. The word
'.' pops a single number off the stack and prints it.
'.' pops a single number off the stack and prints it.
; ==== Help: Basics 4/6 ========================================
; ==== Help: Basics 4/6 ========================================
Manipulating the stack will be difficult at first, but gets
Manipulating the stack will be difficult at first, but gets
easier over time. There are standard words for stack
easier over time. There are standard words for stack
manipulation and a standard methodology for describing
manipulation and a standard methodology for describing
stack effects called 'stack comments'.
stack effects called 'stack comments'.
A stack comment is a short comment describing the stack before
A stack comment is a short comment describing the stack before
and after execution of the word, and the type of the arguments
and after execution of the word, and the type of the arguments
it accepts and returns. For example the stack comment for '+'
it accepts and returns. For example the stack comment for '+'
is:
is:
  + ( n n -- n : add two numbers together )
  + ( n n -- n : add two numbers together )
All text between '(' and the ')' is discarded by the Forth
All text between '(' and the ')' is discarded by the Forth
system. This comment describes a word that accepts two
system. This comment describes a word that accepts two
signed numbers "n n", and returns a signed number "n".
signed numbers "n n", and returns a signed number "n".
; ==== Help: Basics 5/6 ========================================
; ==== Help: Basics 5/6 ========================================
The "--" divides the comment into what the stack looks like
The "--" divides the comment into what the stack looks like
before execution of the word (to the left of "--") and what it
before execution of the word (to the left of "--") and what it
looks like after (to the right of "--"). A comment on the
looks like after (to the right of "--"). A comment on the
behavior of the word comes after the semicolon.
behavior of the word comes after the semicolon.
Here is a list of some common Forth words and their stack
Here is a list of some common Forth words and their stack
comments:
comments:
  dup  ( n -- n n : duplicate first item on the stack )
  dup  ( n -- n n : duplicate first item on the stack )
  swap ( n1 n2 -- n2 n1 : swap first two items on stack )
  swap ( n1 n2 -- n2 n1 : swap first two items on stack )
  drop ( n -- : drop a value from the stack )
  drop ( n -- : drop a value from the stack )
Stack effects are sometimes numbered, which is used to
Stack effects are sometimes numbered, which is used to
so the effects on specific arguments can be documented if
so the effects on specific arguments can be documented if
the order of arguments and return values matter.
the order of arguments and return values matter.
; ==== Help: Basics 6/6 ========================================
; ==== Help: Basics 6/6 ========================================
Some more words with comments:
Some more words with comments:
  @    ( a -- u : load value from memory address )
  @    ( a -- u : load value from memory address )
  !    ( u a -- : store 'u' at memory location 'a' )
  !    ( u a -- : store 'u' at memory location 'a' )
  <    ( n1 n2 -- f : is n1 greater than n2, signed )
  <    ( n1 n2 -- f : is n1 greater than n2, signed )
  u<   ( u1 u2 -- f : is u1 greater than n2, unsigned )
  u<   ( u1 u2 -- f : is u1 greater than n2, unsigned )
These words have stack comments, some with numbered arguments,
These words have stack comments, some with numbered arguments,
but they use different letters. The different letters are used
but they use different letters. The different letters are used
to describe the type of the arguments that the word accepts.
to describe the type of the arguments that the word accepts.
'@', also known as load, takes an address, and '!', takes
'@', also known as load, takes an address, and '!', takes
an address and a value. "<" takes two signed numbers, "u<"
an address and a value. "<" takes two signed numbers, "u<"
takes two unsigned numbers and produces a flag. Type checking
takes two unsigned numbers and produces a flag. Type checking
is not performed by Forth and is up to the programmer.
is not performed by Forth and is up to the programmer.
; ==== Help: Stack Comments ====================================
; ==== Help: Stack Comments ====================================
Here is a list of stack type descriptions and what they mean:
Here is a list of stack type descriptions and what they mean:
| Comment  | Meaning                             |
| Comment  | Meaning                             |
|----------|-------------------------------------|
|----------|-------------------------------------|
| a        | cell address                        |
| a        | cell address                        |
| n        | signed number                       |
| n        | signed number                       |
| u        | unsigned number                     |
| u        | unsigned number                     |
| b        | string address                      |
| b        | string address                      |
| c        | single character                    |
| c        | single character                    |
| d        | double width number (2 Cells)       |
| d        | double width number (2 Cells)       |
| f        | boolean flag (-1 = true, 0 = false) |
| f        | boolean flag (-1 = true, 0 = false) |
| k        | block number                        |
| k        | block number                        |
| cfa      | code field address of a word        |
| cfa      | code field address of a word        |
| nfa      | name field address of a word        |
| nfa      | name field address of a word        |
| pwd      | previous word address of a word     |
| pwd      | previous word address of a word     |
|  | a parsing word                      |
|  | a parsing word                      |
; ==== Help: Expressions =======================================
; ==== Help: Expressions =======================================
Let us continue on with some interactive examples before we
Let us continue on with some interactive examples before we
start to define new words. Before we saw a trivial example
start to define new words. Before we saw a trivial example
of adding two numbers together, we will go over a few more
of adding two numbers together, we will go over a few more
operators first.
operators first.
  9 2 + . ( Displays 'B', the default base is hexadecimal )
  9 2 + . ( Displays 'B', the default base is hexadecimal )
  decimal ( Change the input and output base to decimal )
  decimal ( Change the input and output base to decimal )
  9 2 + . ( Displays '11' )
  9 2 + . ( Displays '11' )
  3 4 dup * swap dup * + . ( Displays 3^2 + 4^2 or 25 )
  3 4 dup * swap dup * + . ( Displays 3^2 + 4^2 or 25 )
Negative numbers can be input by prefixing the number with
Negative numbers can be input by prefixing the number with
'-':
'-':
  -2 4 * . ( Display -8 )
  -2 4 * . ( Display -8 )
; ==== Help: Numeric Output 1/2 ================================
; ==== Help: Numeric Output 1/2 ================================
The word '.' pops a value off the stack before displaying it,
The word '.' pops a value off the stack before displaying it,
if we want to examine the stack without popping the value we
if we want to examine the stack without popping the value we
can print out the entire contents of the stack with '.s':
can print out the entire contents of the stack with '.s':
  1 2 3 .s ( prints "1 2 3 
  1 2 3 .s ( prints "1 2 3 
  .        ( prints "3" )
  .        ( prints "3" )
  .s       ( prints "1 2 
  .s       ( prints "1 2 
"
"
stack. Other useful words for debugging include '?' that
stack. Other useful words for debugging include '?' that
prints the contents at a memory address and 'dump', which
prints the contents at a memory address and 'dump', which
prints a memory dump of a region of memory.
prints a memory dump of a region of memory.
  dump ( a u -- )
  dump ( a u -- )
  ?    ( a -- )
  ?    ( a -- )
; ==== Help: Numeric Output 2/2 ================================
; ==== Help: Numeric Output 2/2 ================================
Hexadecimal numbers can be entered if the base input and output
Hexadecimal numbers can be entered if the base input and output
base is 16, or by prefixing the number with '$'.
base is 16, or by prefixing the number with '$'.
 
 
  decimal  $aaa . ( Displays 2730 )
  decimal  $AAA . ( Displays 2730 )
          -$aaa . ( Displays -2730 )
          -$AAA . ( Displays -2730 )
 
 
eForth starts up in base 16, valid bases range anywhere from
eForth starts up in base 16, valid bases range anywhere from
2 to 36. The base can be changed by either setting a variable
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
'base' to the desired base, or with the words 'hex' to change
the base back into hexadecimal, or 'decimal' to change the base
the base back into hexadecimal, or 'decimal' to change the base
to '10'. Variables in Forth are words that leave an address on
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
the stack when they are called. They can be read or set with
'@' and '!'. For example, "$10 base !" and "hex" are
'@' and '!'. For example, "$10 base !" and "hex" are
equivalent, as are "$a base !" and "decimal".
equivalent, as are "$A base !" and "decimal".
 
 
; ==== Help: Word Definitions 1/2 ==============================
; ==== Help: Word Definitions 1/2 ==============================
For the moment we have not covered how words are defined and
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
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.
word definition and the word ";" is used to terminate one.
Words once defined are added to the 'dictionary', which is
Words once defined are added to the 'dictionary', which is
consists of a linked list of words, hence the name
consists of a linked list of words, hence the name
'dictionary'. We can define new words interactively like we can
'dictionary'. We can define new words interactively like we can
type expressions in, such as:
type expressions in, such as:
  : square dup * ; ( n -- n : square a number )
  : square dup * ; ( n -- n : square a number )
We can then use square like any other word:
We can then use square like any other word:
  4 square .  ( prints 16 )
  4 square .  ( prints 16 )
  -5 square . ( prints 25 )
  -5 square . ( prints 25 )
; ==== Help: Word Definitions 2/2 ==============================
; ==== Help: Word Definitions 2/2 ==============================
'hex' and 'decimal' are defined as:
'hex' and 'decimal' are defined as:
  : hex $10 base ! ;
  : hex $10 base ! ;
  : decimal $a base ! ;
  : decimal $A base ! ;
 
 
And simple Forth words likewise defined:
And simple Forth words likewise defined:
  : 2- 2 - ;      ( u -- u : decrement a number by 2 )
  : 2- 2 - ;      ( u -- u : decrement a number by 2 )
  : 2+ 2 + ;      ( u -- u : increment a number by 2 )
  : 2+ 2 + ;      ( u -- u : increment a number by 2 )
  : 2* 1 lshift ; ( u -- u : multiply a number by 2 )
  : 2* 1 lshift ; ( u -- u : multiply a number by 2 )
  : 1+ 1 + ;      ( u -- u : increment a number by 1 )
  : 1+ 1 + ;      ( u -- u : increment a number by 1 )
  : negate invert 1+ ; ( n -- n : negate, twos compliment )
  : negate invert 1+ ; ( n -- n : negate, twos compliment )
It is best to keep all Forth words as short as possible and
It is best to keep all Forth words as short as possible and
reuse code as much as possible.
reuse code as much as possible.
; ==== Help: Interpreter Loop 1/3 ==============================
; ==== Help: Interpreter Loop 1/3 ==============================
All functions, control structures, defining words such as ":",
All functions, control structures, defining words such as ":",
and simple functions like "square" or "hex" are simply Forth
and simple functions like "square" or "hex" are simply Forth
words, which are either defined in terms of other Forth words
words, which are either defined in terms of other Forth words
or in terms of primitive operations supported by the H2 CPU.
or in terms of primitive operations supported by the H2 CPU.
Currently this does not explain how compilation happens. When
Currently this does not explain how compilation happens. When
the word ":" is encountered it does multiple things such as
the word ":" is encountered it does multiple things such as
compiling a word header into the dictionary, and it does one
compiling a word header into the dictionary, and it does one
more thing - it puts the Forth system into compile mode. The
more thing - it puts the Forth system into compile mode. The
system starts out in command mode, in this mode words are
system starts out in command mode, in this mode words are
executed, and numbers are pushed onto the stack. In compile
executed, and numbers are pushed onto the stack. In compile
mode, a call to the word is compiled (or an assembly
mode, a call to the word is compiled (or an assembly
instruction is inlined) and numbers of turned into literals
instruction is inlined) and numbers of turned into literals
that push their value when run.
that push their value when run.
; ==== Help: Interpreter Loop 2/3 ==============================
; ==== Help: Interpreter Loop 2/3 ==============================
There is a special class of words called "immediate" words, ";"
There is a special class of words called "immediate" words, ";"
is an immediate word, when it is encountered instead of being
is an immediate word, when it is encountered instead of being
compiled into the dictionary it is executed, it compiles an
compiled into the dictionary it is executed, it compiles an
exit instruction to terminate the word definition and it puts
exit instruction to terminate the word definition and it puts
the Forth system back into command mode.
the Forth system back into command mode.
Not only are control structures sets of words, like "if",
Not only are control structures sets of words, like "if",
"else", "then", "begin", "until", but so are words like "("
"else", "then", "begin", "until", but so are words like "("
and "\" which are used to process comments. When executed
and "\" which are used to process comments. When executed
they read from the input stream until the they find a ")" or
they read from the input stream until the they find a ")" or
end of line respectively.
end of line respectively.
Variables, strings, and defining words (defining words are
Variables, strings, and defining words (defining words are
that create new words) are all simply Forth words that are
that create new words) are all simply Forth words that are
either compiling or immediate, their is no special syntax.
either compiling or immediate, their is no special syntax.
; ==== Help: Interpreter Loop 3/3 ==============================
; ==== Help: Interpreter Loop 3/3 ==============================
The command loop goes like this:
The command loop goes like this:
Start) Fetch a space delimited word, find it in the dictionary
Start) Fetch a space delimited word, find it in the dictionary
   Found) Is the system in compile mode?
   Found) Is the system in compile mode?
          Yes) Is the word immediate?
          Yes) Is the word immediate?
               Yes) Execute It
               Yes) Execute It
               No)  Compile a call to it / In-line it
               No)  Compile a call to it / In-line it
          No)  Execute the word
          No)  Execute the word
   Not Found) Is the word a number?
   Not Found) Is the word a number?
          Yes) Is the system in compile mode?
          Yes) Is the system in compile mode?
               Yes) Compile the number
               Yes) Compile the number
               No)  Push the number onto the stack
               No)  Push the number onto the stack
          No)  Error!
          No)  Error!
This simple loop is invoked by the work 'quit' which uses
This simple loop is invoked by the work 'quit' which uses
'query' to fetch and parse the input and 'interpreter' to
'query' to fetch and parse the input and 'interpreter' to
perform the state dependent action.
perform the state dependent action.
; ==== Help: Control Structures 1/10 ===========================
; ==== Help: Control Structures 1/10 ===========================
This will give you some idea what is going on when control
This will give you some idea what is going on when control
structures are covered in the following blocks. Control
structures are covered in the following blocks. Control
structures can only be used within a word definition, that
structures can only be used within a word definition, that
is in compile mode, if used in command mode they simply throw
is in compile mode, if used in command mode they simply throw
an error.
an error.
Some of the control structures available to Forth are:
Some of the control structures available to Forth are:
  if ... then
  if ... then
  if ... else ... then
  if ... else ... then
  for ... next
  for ... next
  for ... aft ... then ... next
  for ... aft ... then ... next
  begin ... until
  begin ... until
  begin ... again
  begin ... again
  begin ... while ... repeat
  begin ... while ... repeat
; ==== Help: Control Structures 2/10 ===========================
; ==== Help: Control Structures 2/10 ===========================
Recursion is also available with the 'recurse' word. There
Recursion is also available with the 'recurse' word. There
are more advance control flow methods available that will be
are more advance control flow methods available that will be
described later (such as 'catch', 'throw' and manipulating the
described later (such as 'catch', 'throw' and manipulating the
return stack).
return stack).
"if...then" will be described first. First a simple example,
"if...then" will be described first. First a simple example,
we will define a word called 'abs' that will return the
we will define a word called 'abs' that will return the
absolute value of a number, that is negative numbers will be
absolute value of a number, that is negative numbers will be
turned into positive numbers and positive numbers will stay
turned into positive numbers and positive numbers will stay
the same. This will require the word 'negate' which changes
the same. This will require the word 'negate' which changes
the sign of a number and '0<' which tests if a number is
the sign of a number and '0<' which tests if a number is
negative, their stack effect comments are:
negative, their stack effect comments are:
  0<     ( n -- f )
  0<     ( n -- f )
  negate ( n -- n )
  negate ( n -- n )
; ==== Help: Control Structures 3/10 ===========================
; ==== Help: Control Structures 3/10 ===========================
The word 'abs' is then defined as:
The word 'abs' is then defined as:
  : abs dup 0< if negate then ;
  : abs dup 0< if negate then ;
'if' takes an argument off the stack at run time and jumps to
'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-
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
zero) the negate is performed. From now if a word is shown in
a definition that has not been previously mentioned please
a definition that has not been previously mentioned please
refer to the glossary. We can can use the definition of the
refer to the glossary. We can can use the definition of the
word 'abs' as soon as we terminate the definition with ";":
word 'abs' as soon as we terminate the definition with ";":
  -9 abs . ( displays 9 )
  -9 abs . ( displays 9 )
   4 abs . ( displays 4 )
   4 abs . ( displays 4 )
This Forth uses two complements to represent negative numbers.
This Forth uses two complements to represent negative numbers.
; ==== Help: Control Structures 4/10 ===========================
; ==== Help: Control Structures 4/10 ===========================
A number can be negated in twos compliment form by performing
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
a bitwise not on the number and adding one to it, this is what
the word 'negate' does.
the word 'negate' does.
"if...else...then" control structures can be created:
"if...else...then" control structures can be created:
  : min 2dup < if drop else nip then ; ( n n -- n )
  : min 2dup < if drop else nip then ; ( n n -- n )
  : max 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
These words get the minimum (min) and the maximum (max) of
two numbers.
two numbers.
   4 3 min . ( prints 3 )
   4 3 min . ( prints 3 )
   4 3 max . ( prints 4 )
   4 3 max . ( prints 4 )
; ==== Help: Control Structures 5/10 ===========================
; ==== Help: Control Structures 5/10 ===========================
Whilst control structures can be nested very deeply it is
Whilst control structures can be nested very deeply it is
considered very bad practice to do, instead the definition
considered very bad practice to do, instead the definition
should be refactored so it consists of short (preferably one
should be refactored so it consists of short (preferably one
line) word definitions.
line) word definitions.
There are two mains ways of looping, either by recursion or
There are two mains ways of looping, either by recursion or
with the several looping mechanisms. One of the simplest is
with the several looping mechanisms. One of the simplest is
"begin...until". This continues looping until a variable popped
"begin...until". This continues looping until a variable popped
off the stack when the "until" word is reach is non-zero. Like
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
the "if" control structure this can only be used within a word
definition. An example is the definition of "key", which gets
definition. An example is the definition of "key", which gets
a single character from the input device, it blocks until there
a single character from the input device, it blocks until there
is input. It uses a word called "key?" which returns a variable
is input. It uses a word called "key?" which returns a variable
number of items on the stack depending on whether there is
number of items on the stack depending on whether there is
new input from the user.
new input from the user.
; ==== Help: Control Structures 6/10 ===========================
; ==== Help: Control Structures 6/10 ===========================
The stack comments for "key?" and "key" are:
The stack comments for "key?" and "key" are:
  key? ( -- c -1 | 0 )
  key? ( -- c -1 | 0 )
  key  ( -- c )
  key  ( -- c )
Key returns the new character and "-1" (in Forth -1 is true,
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
and 0 is false), or "0" if there is no new input. The pipe
system "|" is used to separate the possible return values in
system "|" is used to separate the possible return values in
the stack comment. We can use "begin...until" to define "key"
the stack comment. We can use "begin...until" to define "key"
in terms of "key?" with:
in terms of "key?" with:
  : key begin key? until ;
  : key begin key? until ;
This simply loops until there is a new character of input.
This simply loops until there is a new character of input.
; ==== Help: Control Structures 7/10 ===========================
; ==== Help: Control Structures 7/10 ===========================
Some contrived examples, using the standard metasyntactic
Some contrived examples, using the standard metasyntactic
variable name "foo":
variable name "foo":
  : foo begin 1- dup . cr dup 0= until drop ; ( u -- )
  : foo begin 1- dup . cr dup 0= until drop ; ( u -- )
  4 foo ( <-- type this ) 3 ( <-- prints '3' )
  4 foo ( <-- type this ) 3 ( <-- prints '3' )
  2  ( <-- then '2' )
  2  ( <-- then '2' )
  1  ( ... )
  1  ( ... )
  0  ( ... )
  0  ( ... )
  ok ( then ok prompt )
  ok ( then ok prompt )
If zero is given this will underflow and wrap around to $FFFF
If zero is given this will underflow and wrap around to $FFFF
and continue the loop 65536 times which is probably not
and continue the loop 65536 times which is probably not
intended.
intended.
; ==== Help: Control Structures 8/10 ===========================
; ==== Help: Control Structures 8/10 ===========================
Indefinite loops can be made with "begin...again", the
Indefinite loops can be made with "begin...again", the
following word "bar" simply repeatedly prints out "1":
following word "bar" simply repeatedly prints out "1":
  : bar begin 1 . cr again ;
  : bar begin 1 . cr again ;
  bar 1 1 1 1 1 1 ( ... ad infinitum ... )
  bar 1 1 1 1 1 1 ( ... ad infinitum ... )
A looping mechanism that is easier to use is the
A looping mechanism that is easier to use is the
"begin...while...repeat" loop, this continues an operation
"begin...while...repeat" loop, this continues an operation
until a variable is not true:
until a variable is not true:
  : foo begin ?dup while dup . cr 1- repeat ;
  : foo begin ?dup while dup . cr 1- repeat ;
  3 foo 3 ( <-- prints 3 )
  3 foo 3 ( <-- prints 3 )
  2       ( <-- then 2 )
  2       ( <-- then 2 )
  1       ( <-- then 1 )
  1       ( <-- then 1 )
; ==== Help: Control Structures 9/10 ===========================
; ==== Help: Control Structures 9/10 ===========================
eForth provides another control structure, the "for...next" loop
eForth provides another control structure, the "for...next" loop
which allows the Forth programmer to create counted loops. The
which allows the Forth programmer to create counted loops. The
"for" loop takes a single variable, it stores this variable on
"for" loop takes a single variable, it stores this variable on
the return stack (which will be covered next) and decrements the
the return stack (which will be covered next) and decrements the
variable, until it is zero, at which point it exits (but still
variable, until it is zero, at which point it exits (but still
executes for the final zeroth case). The word 'r@' is used to
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
push a copy of the top of the return stack, where the for loop
keeps the conditional value.
keeps the conditional value.
  : foobar for r@ . cr next ;
  : foobar for r@ . cr next ;
  3 foobar 3 ( <-- prints 3 )
  3 foobar 3 ( <-- prints 3 )
  2
  2
  1
  1
  0 ( <-- prints zero as well! )
  0 ( <-- prints zero as well! )
; ==== Help: Control Structures 10/10 ==========================
; ==== Help: Control Structures 10/10 ==========================
The "for...next" construct can be modified with the "aft" and
The "for...next" construct can be modified with the "aft" and
"then" construct, which is not executed on the first run of the
"then" construct, which is not executed on the first run of the
loop.
loop.
  : quux for -9 . aft r@ . then -8 . cr then ;
  : quux for -9 . aft r@ . then -8 . cr then ;
  decimal 3 quux -9 -8 ( for...aft and then...next is run )
  decimal 3 quux -9 -8 ( for...aft and then...next is run )
  2 -8 ( aft...then and then...next is run )
  2 -8 ( aft...then and then...next is run )
  1 -8 ( ... )
  1 -8 ( ... )
  0 -8 ( ... )
  0 -8 ( ... )
This concludes the control structure section, it should be
This concludes the control structure section, it should be
noted that the control structures are defined words themselves
noted that the control structures are defined words themselves
again, it is possible to redefine and add your own control
again, it is possible to redefine and add your own control
structures. How this is done will be covered later.
structures. How this is done will be covered later.
; ==== Help: Return Stack ======================================
; ==== Help: Return Stack ======================================
All Forth systems have at least two stacks along with main
All Forth systems have at least two stacks along with main
memory, they can be implemented in hardware like with this Forth
memory, they can be implemented in hardware like with this Forth
or in software. One stack is used to pass data to functions and
or in software. One stack is used to pass data to functions and
to return their results, the data or variable stack, which we
to return their results, the data or variable stack, which we
have already dealt with. The other stack is used for control
have already dealt with. The other stack is used for control
flow and as a place for temporarily storing variables.
flow and as a place for temporarily storing variables.
Data can be moved to and from the return stacks, but this must
Data can be moved to and from the return stacks, but this must
be done very carefully and only within word definitions,
be done very carefully and only within word definitions,
leaving values on the stack by accident can cause the
leaving values on the stack by accident can cause the
interpreter to crash.
interpreter to crash.
Some looping constructs use the return stack as well to store
Some looping constructs use the return stack as well to store
their loop index, and the 'throw/catch' mechanism manipulates
their loop index, and the 'throw/catch' mechanism manipulates
control flow a lot.
control flow a lot.
; ==== Help: Return Stack ======================================
; ==== Help: Return Stack ======================================
Some words for manipulating the return stack are as follows,
Some words for manipulating the return stack are as follows,
notice the stack comments describe both stacks here:
notice the stack comments describe both stacks here:
  >r    ( u --, R: -- u : move variable to return stack )
  >r    ( u --, R: -- u : move variable to return stack )
  r>    ( -- u, R: u -- : move variable from return stack )
  r>    ( -- u, R: u -- : move variable from return stack )
  rdrop ( R: u -- : remove topmost variable from return stack )
  rdrop ( R: u -- : remove topmost variable from return stack )
  r@    ( -- u, R: u -- u : copy topmost return stack item )
  r@    ( -- u, R: u -- u : copy topmost return stack item )
; ==== Help: Control Structures ================================
; ==== Help: Control Structures ================================
; ==== Help: TO DO =============================================
; ==== Help: TO DO =============================================
* Describe the system internals
* Describe the system internals
* eForth primitives
* eForth primitives
* Make, Doer, Create, Does>
* Make, Doer, Create, Does>
* Do word glossary, with one block per word
* Do word glossary, with one block per word
* Vocabularies
* Vocabularies
* Block Word set
* Block Word set
* Peripheral access word set
* Peripheral access word set
* Throw/Catch
* Throw/Catch
* How Forth is implemented
* How Forth is implemented
* Add appendixes for ASCII character set, ANSI terminal
* Add appendixes for ASCII character set, ANSI terminal
codes supported, the Nexy3 board, twos compliment format,
codes supported, the Nexy3 board, twos compliment format,
list of characters supported, etcetera.
list of characters supported, etcetera.
* A short dictionary of English words, or a short
* A short dictionary of English words, or a short
encyclopedia could be made and stored in blocks
encyclopedia could be made and stored in blocks
; ==== Block Editor Help 1/5 ===================================
; ==== Block Editor Help 1/5 ===================================
The traditional way to store Forth source code and data is as
The traditional way to store Forth source code and data is as
Forth blocks, a block is a contiguous array of 1024 characters,
Forth blocks, a block is a contiguous array of 1024 characters,
which can be saved to non-volatile storage with the 'block'
which can be saved to non-volatile storage with the 'block'
word set. On more modern Forth systems, especially hosted ones,
word set. On more modern Forth systems, especially hosted ones,
the file access word set is used instead.
the file access word set is used instead.
A Forth that does not have a file system, such as this one,
A Forth that does not have a file system, such as this one,
usually has a primitive block editor. An editor can be defined
usually has a primitive block editor. An editor can be defined
in just a handful of (non-standard) words.
in just a handful of (non-standard) words.
By default the editor words are not in the Forth search order,
By default the editor words are not in the Forth search order,
the words in the editor vocabulary would conflict with Forth
the words in the editor vocabulary would conflict with Forth
words (and with hexadecimal numbers). To load the block editor
words (and with hexadecimal numbers). To load the block editor
execute the 'editor' Forth word. Load initial block with '0 b'.
execute the 'editor' Forth word. Load initial block with '0 b'.
; ==== Block Editor Help 2/5 ===================================
; ==== Block Editor Help 2/5 ===================================
The block editor is a prime example of Forth simplicity, it
The block editor is a prime example of Forth simplicity, it
both simplifies the problem of editing text and reuses the
both simplifies the problem of editing text and reuses the
Forth interpreter to define a new command language. Each command
Forth interpreter to define a new command language. Each command
in the block editor simply a Forth word which takes its
in the block editor simply a Forth word which takes its
arguments off the stack, and a line is a fixed width 64
arguments off the stack, and a line is a fixed width 64
character array, a block can contain 16 lines of text. An empty
character array, a block can contain 16 lines of text. An empty
line consists entirely of spaces, which the interpreter will
line consists entirely of spaces, which the interpreter will
ignore if it were to evaluate the block.
ignore if it were to evaluate the block.
The 'editor' word replaces the current vocabulary with the
The 'editor' word replaces the current vocabulary with the
editor vocabulary and switches the number base for input and
editor vocabulary and switches the number base for input and
output to decimal. The commands are terse words, only one or
output to decimal. The commands are terse words, only one or
two characters in length.
two characters in length.
; ==== Block Editor Help 3/5 ===================================
; ==== Block Editor Help 3/5 ===================================
The third element of the block editor is the elegant, if some-
The third element of the block editor is the elegant, if some-
what limited, block word set. It completely abstracts aways the
what limited, block word set. It completely abstracts aways the
task of retrieving data from mass storage and saving modified
task of retrieving data from mass storage and saving modified
data back to it. The mass storage is divided into blocks which
data back to it. The mass storage is divided into blocks which
can be loaded by their block number. Block numbers in this
can be loaded by their block number. Block numbers in this
system start at 0 and go to $FFFE, $FFFF is an invalid block
system start at 0 and go to $FFFE, $FFFF is an invalid block
number.
number.
The block word set is quite small, and the editor uses the
The block word set is quite small, and the editor uses the
words; 'block', 'update', 'save-buffers', 'list', 'load',
words; 'block', 'update', 'save-buffers', 'list', 'load',
and '+block'. The variable 'blk', which contains the last
and '+block'. The variable 'blk', which contains the last
block loaded (and listed) is also used. Most editor commands
block loaded (and listed) is also used. Most editor commands
are minor modifications on the behavior of these words.
are minor modifications on the behavior of these words.
; ==== Block Editor Help 4/5 ===================================
; ==== Block Editor Help 4/5 ===================================
The workhorse of the word set is 'block', it takes a block
The workhorse of the word set is 'block', it takes a block
number and if that block number is not currently loaded into a
number and if that block number is not currently loaded into a
block buffer (this system only has one block buffer available)
block buffer (this system only has one block buffer available)
it checks to see if the current block is marked as dirty (with
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
the 'update' word). If it has been it first flushes the dirty
block to mass storage, then loads the desired block from it. It
block to mass storage, then loads the desired block from it. It
then returns a pointer to the beginning of the block buffer. It
then returns a pointer to the beginning of the block buffer. It
also updates the 'blk' variable to contain the block number
also updates the 'blk' variable to contain the block number
just loaded.
just loaded.
The 'save-buffers' saves all buffers to disk and deallocates
The 'save-buffers' saves all buffers to disk and deallocates
any blocks (by storing $FFFF in 'blk'). 'list' displays the
any blocks (by storing $FFFF in 'blk'). 'list' displays the
contents of a block, 'load' evaluates a block and '+block'
contents of a block, 'load' evaluates a block and '+block'
moves to a block relative to the currently loaded one.
moves to a block relative to the currently loaded one.
; ==== Block Editor Help 5/5 ===================================
; ==== Block Editor Help 5/5 ===================================
A quick recap of the block words:
A quick recap of the block words:
block        ( k -- u : load block into buffer )
block        ( k -- u : load block into buffer )
blk          ( -- a : last loaded block )
blk          ( -- a : last loaded block )
+block       ( k -- : load block relative to 'blk' )
+block       ( k -- : load block relative to 'blk' )
save-buffers ( -- : flush block to disk, put -1 in 'blk' )
save-buffers ( -- : flush block to disk, put -1 in 'blk' )
list         ( k -- : display block )
list         ( k -- : display block )
load         ( k -- : evaluate a block )
load         ( k -- : evaluate a block )
These can be used to define simple editor commands, such as:
These can be used to define simple editor commands, such as:
  : b block drop ;
  : b block drop ;
  : n 1 +block b ;
  : n 1 +block b ;
  : u update ;
  : u update ;
; ==== Block Editor Commands 1/2 ===============================
; ==== Block Editor Commands 1/2 ===============================
'#' indicates a numeric argument the command takes:
'#' indicates a numeric argument the command takes:
      n    move to next block
      n    move to next block
      p    move to previous block
      p    move to previous block
    # d    delete line in current block
    # d    delete line in current block
      x    erase current block (overwrite with spaces)
      x    erase current block (overwrite with spaces)
      e    evaluate current block
      e    evaluate current block
    # i    insert line
    # i    insert line
 # #2 ia   insert at line #2 at column #
 # #2 ia   insert at line #2 at column #
      q    quit editor loop
      q    quit editor loop
    # b    load block number
    # b    load block number
      s    save block and write it out
      s    save block and write it out
      u    update block
      u    update block
      w    list editor commands
      w    list editor commands
      q    back to Forth interpreter
      q    back to Forth interpreter
; ==== Block Editor Commands 2/2 ===============================
; ==== Block Editor Commands 2/2 ===============================
      l    re-list current block
      l    re-list current block
    # c    paste copy buffer to line #
    # c    paste copy buffer to line #
    # y    yank line # into copy buffer
    # y    yank line # into copy buffer
 # #2 ct   copy line # to line #2
 # #2 ct   copy line # to line #2
    # ea   evaluate line #
    # ea   evaluate line #
 # #2 sw   swap lines # and #2
 # #2 sw   swap lines # and #2
The editor is simple to use and understand, but for large
The editor is simple to use and understand, but for large
documents and programs can quite difficult to use. This block
documents and programs can quite difficult to use. This block
editor was derived from the Retro Forth block editor, available
editor was derived from the Retro Forth block editor, available
at: 
at: 
; ==== TO DO ===================================================
; ==== TO DO ===================================================
* The eForth primitives should be described.
* The eForth primitives should be described.
* Describe the Nexys 3 system, the system on a chip, etc.
* Describe the Nexys 3 system, the system on a chip, etc.
* List the instruction set, registers, words defined, eForth
* List the instruction set, registers, words defined, eForth
* Make words for databases using blocks
* Make words for databases using blocks
* Add source code for everything to this block file
* Add source code for everything to this block file
* Add a program listing, perhaps in the first block, it could
* Add a program listing, perhaps in the first block, it could
set variables relating to this document
set variables relating to this document
* If a metacompiler based on the embed project is used, it
* If a metacompiler based on the embed project is used, it
might be possible to have a self hosting system by storing the
might be possible to have a self hosting system by storing the
source code in blocks.
source code in blocks.
; ==== Empty Block =============================================
; ==== Empty Block =============================================
; ==== Glossary ================================================
; ==== Glossary ================================================
The next section presents the glossary, which contains one
The next section presents the glossary, which contains one
word per screen with examples. The glossary may not necessarily
word per screen with examples. The glossary may not necessarily
reflect the exact contents of the dictionary as words are
reflect the exact contents of the dictionary as words are
removed, added and replaced to save space, but the majority
removed, added and replaced to save space, but the majority
should be documented here.
should be documented here.
Hexadecimal and decimal numbers are used, and which base is
Hexadecimal and decimal numbers are used, and which base is
in operation should be inferred from context.
in operation should be inferred from context.
The glossary shows how blocks can be used as a way to
The glossary shows how blocks can be used as a way to
organize information, a concise description (that if needs
organize information, a concise description (that if needs
be could span multiple blocks) describes each word. The first
be could span multiple blocks) describes each word. The first
line can be used to create a table of contents with 'index'.
line can be used to create a table of contents with 'index'.
This way of organizing blocks maps well onto dictionaries,
This way of organizing blocks maps well onto dictionaries,
encyclopedias, and all alphabetically organizable information.
encyclopedias, and all alphabetically organizable information.
; ==== <  ( n1 n2 -- f : signed less than ) ====================
; ==== <  ( n1 n2 -- f : signed less than ) ====================
Signed less than.
Signed less than.
; ==== <>  ( u1 u2 -- f : not equal ) ==========================
; ==== <>  ( u1 u2 -- f : not equal ) ==========================
'<>' takes two values off of the values stack and returns
'<>' takes two values off of the values stack and returns
a boolean which is true (-1) if the two value are not equal
a boolean which is true (-1) if the two value are not equal
and false (0) if they are.
and false (0) if they are.
; ==== <#  ( -- : prepare numeric output ) =====================
; ==== <#  ( -- : prepare numeric output ) =====================
This is part of the mechanism for pictured numeric output,
This is part of the mechanism for pictured numeric output,
which should be used from within a word definition only.
which should be used from within a word definition only.
; ==== =  ( u1 u2 -- f : equality of two numbers ) =============
; ==== =  ( u1 u2 -- f : equality of two numbers ) =============
This is an assembly instruction for testing whether two numbers
This is an assembly instruction for testing whether two numbers
are equal.
are equal.
; ==== >  ( n1 n2 -- f : signed greater than ) =================
; ==== >  ( n1 n2 -- f : signed greater than ) =================
Signed greater than, if 'n1' is greater than 'n2' true (-1) is
Signed greater than, if 'n1' is greater than 'n2' true (-1) is
returned, else false (0) is returned. This operates on signed
returned, else false (0) is returned. This operates on signed
numbers stored in twos compliment format.
numbers stored in twos compliment format.
; ==== -  ( n1 n2 -- n : subtraction ) =========================
; ==== -  ( n1 n2 -- n : subtraction ) =========================
This is word performs subtraction of 'n2' from 'n1'.
This is word performs subtraction of 'n2' from 'n1'.
; ==== ,  ( u -- : compile value into dictionary ) =============
; ==== ,  ( u -- : compile value into dictionary ) =============
The word ',' compiles a value at the next available location
The word ',' compiles a value at the next available location
in the dictionary, updating the dictionary pointer by the size
in the dictionary, updating the dictionary pointer by the size
of a cell.
of a cell.
; ==== ;  ( -- : terminate a word definition ) =================
; ==== ;  ( -- : terminate a word definition ) =================
This word terminates a word definition, linking the newly formed
This word terminates a word definition, linking the newly formed
word into the dictionary. It is an immediate word and performs
word into the dictionary. It is an immediate word and performs
some basic checking to make sure control structures match up. It
some basic checking to make sure control structures match up. It
writes an 'exit' into the word and switches the state back into
writes an 'exit' into the word and switches the state back into
command mode. It has another minor usage, if called within
command mode. It has another minor usage, if called within
command it throws -56, for QUIT. This can be used within a block
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
to stop execution of it, if 'thru' is used to load block, this
error is ignored.
error is ignored.
Example:
Example:
   : 2+ 2 + ;
   : 2+ 2 + ;
   : count dup 1+ swap c@ ;
   : count dup 1+ swap c@ ;
   :noname 9 . ; execute ( <-- prints 9 )
   :noname 9 . ; execute ( <-- prints 9 )
; ==== :  ( -- ;  : start a word definition ) ==========
; ==== :  ( -- ;  : start a word definition ) ==========
':' is a complex word that does many things. It is not an
':' is a complex word that does many things. It is not an
immediate word, but it is a parsing word that reads in the
immediate word, but it is a parsing word that reads in the
next space delimited word and compiles a word header into the
next space delimited word and compiles a word header into the
dictionary. It also switches the interpreter state into compile
dictionary. It also switches the interpreter state into compile
mode, until switched back non-immediate words will now be
mode, until switched back non-immediate words will now be
compiled into this word definition and numbers compiled into
compiled into this word definition and numbers compiled into
it as literals. ':' is how most new words (or functions) are
it as literals. ':' is how most new words (or functions) are
defined within Forth. The word ';' should also be consulted.
defined within Forth. The word ';' should also be consulted.
Usage
Usage
  : example 2 + . cr ; ( <- makes a new word called 'example' )
  : example 2 + . cr ; ( <- makes a new word called 'example' )
  2 example            ( <- the new word prints '4' )
  2 example            ( <- the new word prints '4' )
; ==== !  ( u a -- : store 'u' at address 'a' ) ================
; ==== !  ( u a -- : store 'u' at address 'a' ) ================
Store a value in at an address, this is also used to write to
Store a value in at an address, this is also used to write to
the memory mapped peripheral registers.
the memory mapped peripheral registers.
; ==== ?  ( a -- : print value at address ) ====================
; ==== ?  ( a -- : print value at address ) ====================
Print a value out from an address, this is effected by the
Print a value out from an address, this is effected by the
output radix stored in 'base'. This word uses the area between
output radix stored in 'base'. This word uses the area between
PAD area and the end of the dictionary.
PAD area and the end of the dictionary.
; ==== /  ( n1 n2 -- q: divide n1 by n2 ) ======================
; ==== /  ( n1 n2 -- q: divide n1 by n2 ) ======================
Signed and floored division of the second value on the stack by
Signed and floored division of the second value on the stack by
the first. This will throw and error if the divisor is zero.
the first. This will throw and error if the divisor is zero.
This is a particularly slow operation, as the H2 CPU does not
This is a particularly slow operation, as the H2 CPU does not
a built in division operation.
a built in division operation.
; ==== .  ( n -- : print number out in current base ) ==========
; ==== .  ( n -- : print number out in current base ) ==========
Print a space, then a signed number (if the output radix is ten
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,
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
if the output radix is not ten, then it is just printed out as
an unsigned number). This word uses the area after the
an unsigned number). This word uses the area after the
dictionary and before the start of the pad area, it is not a
dictionary and before the start of the pad area, it is not a
reentrant function.
reentrant function.
; ==== ."  ( -- ;  : compile string into word ) ========
; ==== ."  ( -- ;  : compile string into word ) ========
This word is an immediate word that compiles a string into a
This word is an immediate word that compiles a string into a
word definition (it should only be used from within a word
word definition (it should only be used from within a word
definition). When the word is run it will print out the string.
definition). When the word is run it will print out the string.
The string is terminated by a double quote. A version of this
The string is terminated by a double quote. A version of this
word which does no printing but instead returns a pointer to
word which does no printing but instead returns a pointer to
a counted string is available, and it is called '$"'.
a counted string is available, and it is called '$"'.
Usage:
Usage:
  : hello cr ." Hello, World! " cr ;
  : hello cr ." Hello, World! " cr ;
  hello
  hello
  Hello, World! ( <- 'Hello, World!' is printed )
  Hello, World! ( <- 'Hello, World!' is printed )
; ==== .(  ( -- ;  : print out line until ')' ) ========
; ==== .(  ( -- ;  : print out line until ')' ) ========
This word prints out a string until the matching ')' is
This word prints out a string until the matching ')' is
encountered. It is not an immediate word. It is a parsing
encountered. It is not an immediate word. It is a parsing
word.
word.
Usage:
Usage:
  .( Hello, World! ) cr
  .( Hello, World! ) cr
  Hello, World!  ( <- 'Hello, World!' is printed )
  Hello, World!  ( <- 'Hello, World!' is printed )
; ==== '  ( -- xt ;  : return a word execution token ) =
; ==== '  ( -- xt ;  : return a word execution token ) =
This word parses the next word in the input stream and returns
This word parses the next word in the input stream and returns
its execution token if the word is found. It is an immediate
its execution token if the word is found. It is an immediate
word. If the word is not found it throws an exception.
word. If the word is not found it throws an exception.
; ==== (  ( -- ;  : comment until ')' ) ================
; ==== (  ( -- ;  : comment until ')' ) ================
This is an immediate word used for comments, it discards all
This is an immediate word used for comments, it discards all
input until the matching ')' is encountered. It can be used
input until the matching ')' is encountered. It can be used
within blocks. This word should not span multiple lines
within blocks. This word should not span multiple lines
however.
however.
Usage:
Usage:
  2 2 + ( This is a comment ) . ( <- this '.' prints '4' )
  2 2 + ( This is a comment ) . ( <- this '.' prints '4' )
; ==== )  ( -- : do nothing ) ==================================
; ==== )  ( -- : do nothing ) ==================================
This is a word that does nothing. It is an immediate word. It
This is a word that does nothing. It is an immediate word. It
has no function.
has no function.
; ==== [  ( -- : change compile state to command mode ) ========
; ==== [  ( -- : change compile state to command mode ) ========
An immediate word for changing the state of the interpreter loop
An immediate word for changing the state of the interpreter loop
into the command state. It can be used within a word definition.
into the command state. It can be used within a word definition.
; ==== ]  ( -- : change compile state to compile mode ) ========
; ==== ]  ( -- : change compile state to compile mode ) ========
A normal, compiling word, which turns the interpreter state into
A normal, compiling word, which turns the interpreter state into
compile mode. Words and numbers after (apart from immediate
compile mode. Words and numbers after (apart from immediate
words) are compiled into the dictionary.
words) are compiled into the dictionary.
; ==== @  ( a -- u : load value from address ) =================
; ==== @  ( a -- u : load value from address ) =================
Retrieve a value from memory location 'a'. It can be used to
Retrieve a value from memory location 'a'. It can be used to
read from the memory mapped registers as well.
read from the memory mapped registers as well.
; ==== $"  ( -- ;  : compile string into word ) ========
; ==== $"  ( -- ;  : compile string into word ) ========
This is an immediate word that can only be used in a word
This is an immediate word that can only be used in a word
definition, it compiles a string into the dictionary, when it
definition, it compiles a string into the dictionary, when it
runs it pushes the address of the counted string compiled into
runs it pushes the address of the counted string compiled into
the word.
the word.
; ==== *  ( u1 u2 -- u3 : multiple two numbers ) ===============
; ==== *  ( u1 u2 -- u3 : multiple two numbers ) ===============
Multiply two numbers and push the result onto the stack. This is
Multiply two numbers and push the result onto the stack. This is
a slow operation, as there is not a built in multiply operation.
a slow operation, as there is not a built in multiply operation.
; ==== \  ( -- ;  : comment until end of line ) ========
; ==== \  ( -- ;  : comment until end of line ) ========
Comment until end of input line, this word works within blocks
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.
as well, where it is a comment until the end of the block line.
It is an immediate word.
It is an immediate word.
; ==== #  ( u -- u : extract numeric character from u ) ========
; ==== #  ( u -- u : extract numeric character from u ) ========
; ==== #>  ( u -- b u : return converted number string ) =======
; ==== #>  ( u -- b u : return converted number string ) =======
; ==== +  ( u1 u2 -- u3 : add two numbers together ) ===========
; ==== +  ( u1 u2 -- u3 : add two numbers together ) ===========
; ==== +!  ( u a -- : add 'u' to value 'a' ) ===================
; ==== +!  ( u a -- : add 'u' to value 'a' ) ===================
; ==== 0<  ( n -- f : 'n' less than zero? ) ====================
; ==== 0<  ( n -- f : 'n' less than zero? ) ====================
'0<' is a test word that operates on a signed value and returns
'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
a boolean value, it returns -1 for true if 'n' is less than
zero and 0 for false if 'n' is greater than zero.
zero and 0 for false if 'n' is greater than zero.
Usage:
Usage:
     0 0< . ( prints '0' )
     0 0< . ( prints '0' )
     9 0< . ( prints '0' )
     9 0< . ( prints '0' )
    -4 0< . ( prints '-1' or 'FFFF' )
    -4 0< . ( prints '-1' or 'FFFF' )
  FFFE 0< . ( prints '-1' or 'FFFF', 'FFFE' = -2 )
  FFFE 0< . ( prints '-1' or 'FFFF', 'FFFE' = -2 )
; ==== 0<>  ( n -- f : 'n' not equal to zero? ) ================
; ==== 0<>  ( n -- f : 'n' not equal to zero? ) ================
This word tests if 'n' is not zero, returning true (-1) if it
This word tests if 'n' is not zero, returning true (-1) if it
is not zero, and false if it is (0).
is not zero, and false if it is (0).
Usage:
Usage:
   0 0<> . ( prints '0' )
   0 0<> . ( prints '0' )
  -7 0<> . ( prints '-1' or 'FFFF' )
  -7 0<> . ( prints '-1' or 'FFFF' )
   5 0<> . ( prints '-1' or 'FFFF' )
   5 0<> . ( prints '-1' or 'FFFF' )
; ==== 0=  ( n -- f : 'n' equal to zero? ) =====================
; ==== 0=  ( n -- f : 'n' equal to zero? ) =====================
This word tests if 'n' is zero, returning true (-1) if it is,
This word tests if 'n' is zero, returning true (-1) if it is,
and false if it is not (0).
and false if it is not (0).
Usage:
Usage:
  : 0<> 0= 0= ;
  : 0<> 0= 0= ;
   0 0= .        ( prints '-1', or 'FFFF' in hex mode )
   0 0= .        ( prints '-1', or 'FFFF' in hex mode )
   4 0= .        ( prints '0' )
   4 0= .        ( prints '0' )
  -5 0= .        ( also prints '0' )
  -5 0= .        ( also prints '0' )
; ==== 0>  ( n -- f : 'n' greater than zero? ) =================
; ==== 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-  ( u -- u : decrement u ) ============================
'1-' decrements the top most stack item.
'1-' decrements the top most stack item.
; ==== 1+  ( u -- u : increment u ) ============================
; ==== 1+  ( u -- u : increment u ) ============================
This is a regular function that increments a value by one.
This is a regular word that increments a value by one.
 
 
; ==== 1+!  ( a -- : increment value at 'a' by one ) ===========
; ==== 1+!  ( a -- : increment value at 'a' by one ) ===========
'1+!' increments the value at an address, '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!  ( u1 u2 a -- : store u1 and u2 at two cells ) =======
; ==== 2/  ( u -- u : divide 'u' by two ) ======================
; ==== 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@  ( 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*  ( 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 ) ======
; ==== 2drop  ( u u -- : drop two values from the stack ) ======
A simple word, '2drop' behaves as its stack comment suggests,
A simple word, '2drop' behaves as its stack comment suggests,
it removes the top most two items from the variable stack.
it removes the top most two items from the variable stack.
Usage:
Usage:
  1 2 3 drop . 1 ( '1' is printed )
  1 2 3 drop . 1 ( '1' is printed )
; ==== 2dup  ( u1 u2 -- u1 u2 u1 u2 : duplicate two values ) ===
; ==== 2dup  ( u1 u2 -- u1 u2 u1 u2 : duplicate two values ) ===
This manipulates two items on the stack, like most words with
This manipulates two items on the stack, like most words with
a '2' in their name. The stack effect describes the word
a '2' in their name. The stack effect describes the word
perfectly. Words like these, which produce and manipulate lots
perfectly. Words like these, which produce and manipulate lots
of stack items should be avoided if possible.
of stack items should be avoided if possible.
Usage:
Usage:
         ( -- : empty stack )
         ( -- : empty stack )
   1 2   (  -- 1 2  )
   1 2   (  -- 1 2  )
   2dup  ( 1 2 -- 1 2 1 2 )
   2dup  ( 1 2 -- 1 2 1 2 )
; ==== abs  ( n -- u : absolute value of a number ) ============
; ==== abs  ( n -- u : absolute value of a number ) ============
Returns the absolute value of a signed number, positive values
Returns the absolute value of a signed number, positive values
stay the same, negative values become positive. Signed numbers
stay the same, negative values become positive. Signed numbers
are stored in twos compliment format, the function fails for
are stored in twos compliment format, the function fails for
the number $8000, which is unaffected by abs.
the number $8000, which is unaffected by abs.
Usage:
Usage:
  -1 abs .  ( prints '1' )
  -1 abs .  ( prints '1' )
   4 abs .  ( prints '4' )
   4 abs .  ( prints '4' )
; ==== accept  ( b u -- b u : accept a line ) ==================
; ==== accept  ( b u -- b u : accept a line ) ==================
; ==== aft  ( -- : part of for...aft...then...next ) ===========
; ==== aft  ( -- : part of for...aft...then...next ) ===========
; ==== again  ( -- : part of begin...again loop ) ==============
; ==== again  ( -- : part of begin...again loop ) ==============
'again' should only be used as part of a '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
which is a compile time only wordset. Using an 'again' without
a 'begin' may also be met with an error, as this situtation
a 'begin' may also be met with an error, as this situtation
should be caught by the compiler security mechanisms. The
should be caught by the compiler security mechanisms. The
'begin...again' looping mechanism forms an indefinite or an
'begin...again' looping mechanism forms an indefinite or an
infinite loop, the Forth interpreter/CPU jumps back to the
infinite loop, the Forth interpreter/CPU jumps back to the
corresponding 'begin' unconditionally, and excluding any
corresponding 'begin' unconditionally, and excluding any
errors/exceptions will do so forever.
errors/exceptions will do so forever.
Usage:
Usage:
  : invalid-1 again ; ( <- invalid use, no matching 'begin )
  : invalid-1 again ; ( <- invalid use, no matching 'begin )
  again        ( <- invalid use, outside a word definition )
  again        ( <- invalid use, outside a word definition )
  : test begin 1 . cr again ;
  : test begin 1 . cr again ;
  test ( 'test' prints '1' forever )
  test ( 'test' prints '1' forever )
; ==== align  ( -- : align dictionary pointer ) ================
; ==== align  ( -- : align dictionary pointer ) ================
'align' is a word that takes no arguments and returns nothing,
'align' is a word that takes no arguments and returns nothing,
it acts on the dictionary pointer variable (the internal name
it acts on the dictionary pointer variable (the internal name
for which is usually 'cp', the variable is returned by the
for which is usually 'cp', the variable is returned by the
word 'here'). It should be used after allocating a data
word 'here'). It should be used after allocating a data
structure in the dictionary which is byte aligned and before
structure in the dictionary which is byte aligned and before
defining any new words, the word 'align' reserves space up to
defining any new words, the word 'align' reserves space up to
the next cell aligned address by manipulating the dictionary
the next cell aligned address by manipulating the dictionary
pointer variable.
pointer variable.
Usage:
Usage:
   create x 3 allot ( <- dictionary pointer is now unaligned )
   create x 3 allot ( <- dictionary pointer is now unaligned )
   align            ( <- dictionary pointer is now aligned )
   align            ( <- dictionary pointer is now aligned )
; ==== aligned  ( b -- a : align up an address ) ===============
; ==== 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 ) ====================
; ==== allot  ( n -- : allocate 'n' bytes ) ====================
Allocate 'n' bytes of space in the dictionary, 'n' can be
Allocate 'n' bytes of space in the dictionary, 'n' can be
either positive, or negative, negative values deallocate space,
either positive, or negative, negative values deallocate space,
which may break things.
which may break things.
; ==== and  ( u1 u2 -- u3 : bitwise and of two numbers ) =======
; ==== and  ( u1 u2 -- u3 : bitwise and of two numbers ) =======
This performs a bitwise and on two numbers.
This performs a bitwise and on two numbers.
; ==== ansi ( n c -- : emit an ANSI escape command ) ===========
; ==== 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  ( 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 ) ==================
; ==== base  ( -- a : address of base radix ) ==================
Pushes the address of the base variable onto the variable stack,
Pushes the address of the base variable onto the variable stack,
this can be used to change the input and output radix of numbers
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
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
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
for numbers 10 to 35, upper case and lower case letter can be
used, only upper case characters are output.
used, only upper case characters are output.
Setting the base to an invalid value can cause exceptions to
Setting the base to an invalid value can cause exceptions to
be thrown in other words.
be thrown in other words.
Example usage:
Example usage:
   $2 base !
   $2 base !
   base @
   base @
   $8 base !
   $8 base !
; ==== b/buf  ( -- u : number of bytes in a block ) ============
; ==== b/buf  ( -- u : number of bytes in a block ) ============
This pushes the number of bytes in a block onto the stack, which
This pushes the number of bytes in a block onto the stack,
is 1024 in most Forth implementations, including this one.
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  ( -- : 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 ) ================
; ==== bl  ( -- u : value for space character ) ================
This pushes the space character to the stack.
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 ) ==============
; ==== blank  ( b u -- : fill array with blanks ) ==============
This word writes the space character to a byte array, one use
This word writes the space character to a byte array, one use
is to erase a block before it is displayed with 'list'.
is to erase a block before it is displayed with 'list'.
; ==== blk  ( -- a : address of last loaded block ) ============
; ==== 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  ( u -- a : perform block operation ) =============
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
; ==== +block ( n -- k : return block number relative to blk ) =
; ==== +block ( n -- k : return block number relative to blk ) =
'+block' is a useful common operation which returns the block
'+block' is a useful common operation which returns the block
number relative to the one currently loaded in 'blk', it can
number relative to the one currently loaded in 'blk', it can
be thus used to navigate relative to the most recently loaded
be thus used to navigate relative to the most recently loaded
block. The number it accepts is signed, the next blocks being
block. The number it accepts is signed, the next blocks being
specified with a positive number, the current with zero, and
specified with a positive number, the current with zero, and
negative being prior blocks.
negative being prior blocks.
Usage:
Usage:
  : +block blk @ + ;      ( n -- k )
  : +block blk @ + ;      ( n -- k )
  : next 1 +block ;       (
  : next 1 +block ;       (
  : previous -1 +block ;
  : previous -1 +block ;
  5 block drop next next previous
  5 block drop next next previous
; ==== border  ( -- a : variable for list display control ) ====
; ==== 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 ) ========
; ==== c,  ( c -- : compile character into dictionary ) ========
This words takes a character and writes the character in the
This words takes a character and writes the character in the
next available location in the dictionary, and updates the
next available location in the dictionary, and updates the
dictionary pointer. This word can cause the dictionary number
dictionary pointer. This word can cause the dictionary number
to be misaligned, 'align' can be used to remedy this.
to be misaligned, 'align' can be used to remedy this.
; ==== c!  ( c b -- : store 'c' at 'b' ) =======================
; ==== c!  ( c b -- : store 'c' at 'b' ) =======================
'c!' is the byte oriented store word, it stores a byte 'c' at
'c!' is the byte oriented store word, it stores a byte 'c' at
a potentially unaligned address 'b'. This is not a primitive
a potentially unaligned address 'b'. This is not a primitive
operation provided by the processor as it can only do cell
operation provided by the processor as it can only do cell
sized loads and stores in a single instruction. The
sized loads and stores in a single instruction. The
corresponding word for load a byte is 'c@'. The cell load
corresponding word for load a byte is 'c@'. The cell load
and store words are '@' and '!' respectively.
and store words are '@' and '!' respectively.
; ==== c@  ( b -- c : retrieve 'c' from 'b' ) ==================
; ==== c@  ( b -- c : retrieve 'c' from 'b' ) ==================
'c@' retrieves a single byte from the address 'b', this address
'c@' retrieves a single byte from the address 'b', this address
does not have to be an aligned address. For storing a byte, see
does not have to be an aligned address. For storing a byte, see
'c!'. This word is the byte oriented version of '@', '@'
'c!'. This word is the byte oriented version of '@', '@'
operates on Forth cells. On this processor 'c@' is not a
operates on Forth cells. On this processor 'c@' is not a
primitive operation, for speed '@' should be used instead, as
primitive operation, for speed '@' should be used instead, as
loads (and stores) can only be done by cell and not by byte.
loads (and stores) can only be done by cell and not by byte.
; ==== catch  ( xt -- n | 0 : catch possible exception ) =======
; ==== catch  ( xt -- n | 0 : catch possible exception ) =======
'catch' can catch exceptions thrown by 'throw', it is part of
'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
a pair of words that work as a pair like many Forth words, one
cannot exist without the other. 'catch' takes an execution
cannot exist without the other. 'catch' takes an execution
token, executes it, and returns 0 if nothing was thrown, and
token, executes it, and returns 0 if nothing was thrown, and
a non-zero value if something was. 'catch' is also used as part
a non-zero value if something was. 'catch' is also used as part
of the interpreter loop as an exception handler of last resort.
of the interpreter loop as an exception handler of last resort.
The word 'throw' should also be consulted. 'throw' and 'catch'
The word 'throw' should also be consulted. 'throw' and 'catch'
manipulate the return stack a lot and are fairly complex words
manipulate the return stack a lot and are fairly complex words
that are hard to implement on a processor with hardware stacks.
that are hard to implement on a processor with hardware stacks.
Usage:
Usage:
  : x 99 throw ;   : y x 66 ;
  : x 99 throw ;   : y x 66 ;
  ' x catch . ( prints '99' )
  ' x catch . ( prints '99' )
; ==== ccitt  ( crc c -- crc : compute CRC step ) ==============
; ==== ccitt  ( crc c -- crc : compute CRC step ) ==============
; ==== cell-  ( a -- a : decrement address by single cell ) ====
; ==== cell-  ( a -- a : decrement address by single cell ) ====
'cell-' is the opposite of 'cell+', it decrements an address
'cell-' is the opposite of 'cell+', it decrements an address
value by a cell. On this 16-bit Forth a cell consists of two
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
bytes, but on a 32-bit one it would decrement by four. Note
that this word does not ensure the resulting address is
that this word does not ensure the resulting address is
aligned, if an unaligned addressed was passed in and unaligned
aligned, if an unaligned addressed was passed in and unaligned
address will pop out, and an aligned address will stay so. This
address will pop out, and an aligned address will stay so. This
word is needed so Forth code can be written that is portable
word is needed so Forth code can be written that is portable
across different word size computers.
across different word size computers.
; ==== cell+  ( a -- a : increment address by single cell ) ====
; ==== cell+  ( a -- a : increment address by single cell ) ====
'cell+' increments an address by the size of a cell, see
'cell+' increments an address by the size of a cell, see
'cell-' for further description on this.
'cell-' for further description on this.
; ==== cells  ( n -- n : convert cell to byte count ) ==========
; ==== cells  ( n -- n : convert cell to byte count ) ==========
'cells' is a word that takes a count of the number of cells and
'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
returns the number of bytes that those cells would occupy, on
this 16-bit Forth 'cells' is essentially a multiply by two
this 16-bit Forth 'cells' is essentially a multiply by two
operation, but on other Forths it could be a different value,
operation, but on other Forths it could be a different value,
so this word is used for portability reasons.
so this word is used for portability reasons.
Usage:
Usage:
  0 cells . ( prints '0' )
  0 cells . ( prints '0' )
  1 cells . ( prints '2' )
  1 cells . ( prints '2' )
  2 cells . ( prints '4' )
  2 cells . ( prints '4' )
  create x 4 cells allot ( 'x' created, space for 4 cells )
  create x 4 cells allot ( 'x' created, space for 4 cells )
; ==== >char ( c -- c : convert unprintable character ) ========
; ==== >char ( c -- c : convert unprintable character ) ========
'>char' converts a character so that it can be printed by
'>char' converts a character so that it can be printed by
converting any characters which cannot be printed to the
converting any characters which cannot be printed to the
underscore character ('_'). This is used within words like
underscore character ('_'). This is used within words like
'message' and 'list'. Tabs also get converted, as do control
'message' and 'list'. Tabs also get converted, as do control
characters, delete and any character outside of the ASCII
characters, delete and any character outside of the ASCII
range.
range.
; ==== char  ( -- c ;  : parse character ) =============
; ==== char  ( -- c ;  : parse character ) =============
This word reads in a space delimited word from the input stream
This word reads in a space delimited word from the input stream
and pushes the first character of that word onto the stack. An
and pushes the first character of that word onto the stack. An
entire word is potentially read in, but only the first
entire word is potentially read in, but only the first
character is used.
character is used.
Usage:
Usage:
  char x .          ( prints '$78' )
  char x .          ( prints '$78' )
  char xylophone .  ( prints '$78', also )
  char xylophone .  ( prints '$78', also )
  char 0 .          ( prints '$30' )
  char 0 .          ( prints '$30' )
; ==== [char]  ( -- ;  : compile character literal ) ===
; ==== [char]  ( -- ;  : compile character literal ) ===
This is an immediate word that compiles a character into the
This is an immediate word that compiles a character into the
dictionary as a literal value that will be pushed onto the
dictionary as a literal value that will be pushed onto the
stack when the word is run. It parses a space delimited word
stack when the word is run. It parses a space delimited word
and compiles the first character of that word. It is a compile
and compiles the first character of that word. It is a compile
only word. Although an entire word is parsed, only the first
only word. Although an entire word is parsed, only the first
character is used.
character is used.
Usage:
Usage:
  : print-c [char] c emit ;
  : print-c [char] c emit ;
  print-c c            ( 'c' is printed )
  print-c c            ( 'c' is printed )
  : push-c [char] c ;
  : push-c [char] c ;
  push-c . 63          ( ASCII 'c' is $63 )
  push-c . 63          ( ASCII 'c' is $63 )
; ==== cmove  ( b b u -- : move block memory ) =================
; ==== cmove  ( b b u -- : move block memory ) =================
'cmove' copies a block of characters from one location to
'cmove' copies a block of characters from one location to
another.
another.
; ==== compile ( -- : compile next word into dictionary ) ======
; ==== compile ( -- : compile next word into dictionary ) ======
; ==== [compile]  ( -- xt : compile next immediate word ) ======
; ==== [compile]  ( -- xt : compile next immediate word ) ======
; ==== compile,  ( xt -- : compile execution token ) ===========
; ==== compile,  ( xt -- : compile execution token ) ===========
'compile,' compiles an execution token into the next available
'compile,' compiles an execution token into the next available
location in the dictionary, taking up a cell of space. This
location in the dictionary, taking up a cell of space. This
word must be used when compiling in an execution into a word,
word must be used when compiling in an execution into a word,
the word ',' will compile an unconditional branch.
the word ',' will compile an unconditional branch.
; ==== conceal  ( -- : emit stars instead of characters ) ======
; ==== conceal  ( -- : emit stars instead of characters ) ======
; ==== console  ( -- : UART only mode ) ========================
; ==== console  ( -- : UART only mode ) ========================
; ==== constant  ( n -- ;  : create constant ) =========
; ==== constant  ( n -- ;  : create constant ) =========
'constant' is a defining word that creates a new constant, it
'constant' is a defining word that creates a new constant, it
takes in a value from the stack, and parses the next word from
takes in a value from the stack, and parses the next word from
the input stream which will become the name of the new
the input stream which will become the name of the new
constant. This word uses 'create' and 'does>' internally to
constant. This word uses 'create' and 'does>' internally to
do the work, and is similar to the definition of 'variable'.
do the work, and is similar to the definition of 'variable'.
At run time the new word when called will leave a copy of
At run time the new word when called will leave a copy of
'n' on the stack.
'n' on the stack.
Usage:
Usage:
   : constant create , does> @ ;
   : constant create , does> @ ;
   4 constant x
   4 constant x
   3 constant y
   3 constant y
   x y + . ( prints '7' )
   x y + . ( prints '7' )
; ==== count  ( b -- b c : retrieve next character in string ) =
; ==== count  ( b -- b c : retrieve next character in string ) =
'count' is a very useful word when dealing with strings,
'count' is a very useful word when dealing with strings,
especially counted strings. It retrieves a character from an
especially counted strings. It retrieves a character from an
address and increments that address by one character. This can
address and increments that address by one character. This can
be used to advance through a string, and with counted strings
be used to advance through a string, and with counted strings
it can be used to retrieve the string length which is stored
it can be used to retrieve the string length which is stored
in the first byte of the string.
in the first byte of the string.
; ==== cpu-id  ( -- u : return CPU-ID ) ========================
; ==== cpu-id  ( -- u : return CPU-ID ) ========================
This is an assembly instruction that pushes the CPU-ID of the
This is an assembly instruction that pushes the CPU-ID of the
CPU onto the stack. It can be used to determine whether the
CPU onto the stack. It can be used to determine whether the
system is running in a simulation or on the hardware.
system is running in a simulation or on the hardware.
; ==== cr  ( -- : emit new line ) ==============================
; ==== cr  ( -- : emit new line ) ==============================
'cr' emits a new line, which consists of a carriage return
'cr' emits a new line, which consists of a carriage return
character followed by a linefeed character. This format is used
character followed by a linefeed character. This format is used
as communication occurs over a UART (and the VGA output display
as communication occurs over a UART (and the VGA output display
behaves like a VT100 video terminal).
behaves like a VT100 video terminal).
; ==== crc  ( b u -- u : perform CRC over array ) ==============
; ==== crc  ( b u -- u : perform CRC over array ) ==============
'crc' performs a Cyclic Redundancy Check (CRC) over an array
'crc' performs a Cyclic Redundancy Check (CRC) over an array
specified by an address ('b') and length ('u') pair. It
specified by an address ('b') and length ('u') pair. It
returns the result in a single cell. There are many different
returns the result in a single cell. There are many different
ways of computing a CRC which depending on starting value,
ways of computing a CRC which depending on starting value,
what operation to perform at the end of the calculation and
what operation to perform at the end of the calculation and
what polynomial is used. 'crc' used the word 'ccitt' to do
what polynomial is used. 'crc' used the word 'ccitt' to do
the actual calculation on each byte, using the CCITT
the actual calculation on each byte, using the CCITT
polynomial, which is a standard polynomial. See 'ccitt' for
polynomial, which is a standard polynomial. See 'ccitt' for
more information. CRCs can be used for error detection.
more information. CRCs can be used for error detection.
Usage:
Usage:
  : s1 $" hello" count ;
  : s1 $" hello" count ;
  hex x crc . ( prints 'D26E' )
  hex x crc . ( prints 'D26E' )
; ==== create  ( -- ;  : make 'created' word ) =========
; ==== create  ( -- ;  : make 'created' word ) =========
'create' is a very useful word that allows the creation of
'create' is a very useful word that allows the creation of
new words. It parses the next space delimited string from the
new words. It parses the next space delimited string from the
input stream and creates a word which when run returns a
input stream and creates a word which when run returns a
pointer to its code field. It can be used to make words which
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
create new words, and 'does>' can be used to give those new
words different actions. The 'create'/'does>' combination is
words different actions. The 'create'/'does>' combination is
a really important concept in Forth and has been called 'The
a really important concept in Forth and has been called 'The
Pearl of Forth'.
Pearl of Forth'.
Usage:
Usage:
  create x 2 cells allot
  create x 2 cells allot
  : constant create , does> @ ;
  : constant create , does> @ ;
  4 constant y ( a new constant called 'y' has been made )
  4 constant y ( a new constant called 'y' has been made )
; ==== decimal  ( -- : switch radix to decimal ) ===============
; ==== decimal  ( -- : switch radix to decimal ) ===============
'decimal' switches the current output radix into decimal as
'decimal' switches the current output radix into decimal as
the name suggests. This can be useful when you are lost and do
the name suggests. This can be useful when you are lost and do
not know what the current output radix is, or for performing
not know what the current output radix is, or for performing
calculations like a human instead of a machine! Hexadecimal
calculations like a human instead of a machine! Hexadecimal
values can still be input by prefixing the number with '$'.
values can still be input by prefixing the number with '$'.
Negative numbers will be printed with a leading '-', unlike
Negative numbers will be printed with a leading '-', unlike
in other output bases, when a '.' is used to print the number.
in other output bases, when a '.' is used to print the number.
; ==== dm+  ( a u -- u : print out section of memory ) =========
; ==== dm+  ( a u -- u : print out section of memory ) =========
'dm+' prints out a section of memory in numeric forth, it
'dm+' prints out a section of memory in numeric forth, it
prints out the contents starting from address 'a' and advancing
prints out the contents starting from address 'a' and advancing
for 'u' bytes, rounded down to the nearest aligned cell
for 'u' bytes, rounded down to the nearest aligned cell
location. It is a factor of 'dump' and is useful as a debugging
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
tool in itself. It will print out the values in the current
output radix, as stored in the 'base' variable. A crude memory
output radix, as stored in the 'base' variable. A crude memory
dump can be performed with '0 here dm+'. No newlines are
dump can be performed with '0 here dm+'. No newlines are
printed, but spaces are printed between cell values.
printed, but spaces are printed between cell values.
Usage:
Usage:
  $40 $200 dm+ ( print $200 bytes starting from address $40 )
  $40 $200 dm+ ( print $200 bytes starting from address $40 )
  0 here dm+   ( crude dump of Forth core )
  0 here dm+   ( crude dump of Forth core )
; ==== dnegate  ( d -- d : negate a double value ) =============
; ==== dnegate  ( d -- d : negate a double value ) =============
'dnegate' is the double cell number equivalent of 'negate', it
'dnegate' is the double cell number equivalent of 'negate', it
negates a double cell number. Positive numbers become negative
negates a double cell number. Positive numbers become negative
and vice versa. Double cell numbers take up two items on the
and vice versa. Double cell numbers take up two items on the
stack as the name suggests.
stack as the name suggests.
; ==== doer  ( -- ;  : create a 'doer' word ) ==========
; ==== doer  ( -- ;  : create a 'doer' word ) ==========
; ==== does>  ( -- : start 'does' section of word ) ============
; ==== does>  ( -- : start 'does' section of word ) ============
; ==== drop  ( u -- : drop a value ) ===========================
; ==== drop  ( u -- : drop a value ) ===========================
'drop' simply pops off and discards the topmost value on the
'drop' simply pops off and discards the topmost value on the
variable stack.  'rdrop' is the return stack equivalent.
variable stack.  'rdrop' is the return stack equivalent.
; ==== dump  ( a u -- : dump a section of memory ) =============
; ==== dump  ( a u -- : dump a section of memory ) =============
'dump' is a debugging tool that dumps 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'
starting at the address 'a' and proceeds for at least 'u'
characters. It dumps the memory contents in whatever the
characters. It dumps the memory contents in whatever the
current output base it, as well as displaying the memory
current output base it, as well as displaying the memory
contents as characters when the characters are printable.
contents as characters when the characters are printable.
Example:
Example:
   0 here dump ( <-- dumps out everything )
   0 here dump ( <-- dumps out everything )
Example Output (condensed to fit on the screen):
Example Output (condensed to fit on the screen):
 0:  104C 0 0 0 0 0 E9B 0                     L_______________
 0:  104C 0 0 0 0 0 E9B 0                     L_______________
 10: 8000 6403 7075 6081 601C 8010 6F04 6576  ___dup_`_`___ove
 10: 8000 6403 7075 6081 601C 8010 6F04 6576  ___dup_`_`___ove
 20: 72 6181 601C 801A 6906 766E 7265 74      r__a_`___invert_
 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
 30: 6600 601C 8026 2B01 6203 601C 8034 7304  _f_`&__+_b_`4__s
 ( and so on...)
 ( and so on...)
; ==== dup  ( n -- n n : duplicate a value ) ===================
; ==== dup  ( n -- n n : duplicate a value ) ===================
The stack comment explains this word completely, it simply
The stack comment explains this word completely, it simply
duplicates the topmost item on the variable stack. This is a
duplicates the topmost item on the variable stack. This is a
common Forth word that should be memorized - you should not
common Forth word that should be memorized - you should not
need to look it up here! Other common stack manipulation words
need to look it up here! Other common stack manipulation words
include 'swap', 'over', 'nip', 'tuck', '2dup', 'drop', and
include 'swap', 'over', 'nip', 'tuck', '2dup', 'drop', and
'2drop' amongst others. If you find keeping track of the stack
'2drop' amongst others. If you find keeping track of the stack
difficult, try to rethink and refactor your code, stack
difficult, try to rethink and refactor your code, stack
juggling gets easier over time but nothing beats out removing
juggling gets easier over time but nothing beats out removing
complex combinations of 'dup', 'swap', 'over' and the like.
complex combinations of 'dup', 'swap', 'over' and the like.
Usage:
Usage:
  5 dup ( 5 -- 5 5 )
  5 dup ( 5 -- 5 5 )
; ==== ?dup  ( n -- n n | 0 : duplicate value if not zero ) ====
; ==== ?dup  ( n -- n n | 0 : duplicate value if not zero ) ====
This word duplicates a number if that number is non zero, it
This word duplicates a number if that number is non zero, it
returns just a single zero if the input number was 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,
finds a lot of use in 'begin...while...repeat' loop constructs,
as well as in other looping constructs.
as well as in other looping constructs.
Usage:
Usage:
  : ?dup dup if dup then ;
  : ?dup dup if dup then ;
  0 ?dup .s ( 0 -- 0 )
  0 ?dup .s ( 0 -- 0 )
  3 ?dup .s ( 3 -- 3 3 )
  3 ?dup .s ( 3 -- 3 3 )
; ==== else  ( -- : if...else...then ) =========================
; ==== else  ( -- : if...else...then ) =========================
'else' is a word which forms part of the '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
clause, it can only be used from within a Forth word
definition and should always be used with the matching 'if'
definition and should always be used with the matching 'if'
and 'then'.
and 'then'.
Usage:
Usage:
  : example cr if ." Hello!" else ." Goodbye!" then cr ;
  : example cr if ." Hello!" else ." Goodbye!" then cr ;
  1 example ( prints 'Hello!' )
  1 example ( prints 'Hello!' )
  0 example ( prints 'Goodbye!' )
  0 example ( prints 'Goodbye!' )
; ==== emit  ( c -- : emit a character ) =======================
; ==== emit  ( c -- : emit a character ) =======================
'emit' emits a single character to the output device, this
'emit' emits a single character to the output device, this
device is by default both the UART and the VT100 terminal
device is by default both the UART and the VT100 terminal
emulator can be displayed on a VGA capable display. The board
emulator can be displayed on a VGA capable display. The board
used has VGA output. The output of this word can be redirected
used has VGA output. The output of this word can be redirected
by words like 'io!', 'stars', 'conceal', 'file', 'console' and
by words like 'io!', 'stars', 'conceal', 'file', 'console' and
'interactive'.
'interactive'.
Usage:
Usage:
  $6b emit ( prints 'k' )
  $6b emit ( prints 'k' )
; ==== empty-buffers  ( -- : deallocate block buffer ) =========
; ==== empty-buffers  ( -- : deallocate block buffer ) =========
'empty-buffers' deallocates any currently loaded block buffers,
'empty-buffers' deallocates any currently loaded block buffers,
and stores and invalid block number in 'blk'. It can be used
and stores and invalid block number in 'blk'. It can be used
to discard any changes made to any currently loaded blocks.
to discard any changes made to any currently loaded blocks.
; ==== evaluate  ( a u -- : evaluate block of memory ) =========
; ==== evaluate  ( a u -- : evaluate block of memory ) =========
'evaluate' takes a string specified by an address 'a' and a
'evaluate' takes a string specified by an address 'a' and a
length 'u' and evaluates it as if it were typed in by the
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
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.
so code can work out it is being evaluated and not typed in.
Usage:
Usage:
  : s1 $" 2 2 + . cr " count ;
  : s1 $" 2 2 + . cr " count ;
  s1 evaluate ( prints '4' )
  s1 evaluate ( prints '4' )
; ==== execute  ( xt -- : execute an execution token ) =========
; ==== execute  ( xt -- : execute an execution token ) =========
'execute' takes an execution token, which represents a callable
'execute' takes an execution token, which represents a callable
function, and it executes that function. Execution tokens are
function, and it executes that function. Execution tokens are
returned by words like "'" (quote), or by ":noname".
returned by words like "'" (quote), or by ":noname".
; ==== @execute  ( a -- : execute token at 'a' if non-zero ) ===
; ==== @execute  ( a -- : execute token at 'a' if non-zero ) ===
'@execute' expects an address of a value containing an
'@execute' expects an address of a value containing an
execution token to execute, it retrieves this token from the
execution token to execute, it retrieves this token from the
address and executes it if the token is a non-zero value. This
address and executes it if the token is a non-zero value. This
is primarily uses for vectored word execution.
is primarily uses for vectored word execution.
; ==== exit  ( -- : exit from word ) ===========================
; ==== exit  ( -- : exit from word ) ===========================
This word is an assembly instruction that will be inlined into
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
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
executed in command mode, when compiled into a word it will
exit that word definition when it is run by returning from that
exit that word definition when it is run by returning from that
word. It is compiled into the end of a word definition by
word. It is compiled into the end of a word definition by
the ';' word, which terminates a word.
the ';' word, which terminates a word.
Example:
Example:
   : foo if $f00f . exit then $1337 . ;
   : foo if $f00f . exit then $1337 . ;
   0 foo $F00F ( <-- prints only '$F00F', $1337 not printed )
   0 foo $F00F ( <-- prints only '$F00F', $1337 not printed )
   1 foo $1337 ( <-- prints $1337 only )
   1 foo $1337 ( <-- prints $1337 only )
; ==== expect  ( b u -- : accept, but store 'u' in span ) ======
; ==== expect  ( b u -- : accept, but store 'u' in span ) ======
; ==== file  ( -- : file transfer mode ) =======================
; ==== file  ( -- : file transfer mode ) =======================
; ==== fill  ( b u c -- : fill area of memory with 'c' ) =======
; ==== fill  ( b u c -- : fill area of memory with 'c' ) =======
; ==== find  ( a -- pwd 1 | pwd -1 | a 0 : find word ) =========
; ==== find  ( a -- pwd 1 | pwd -1 | a 0 : find word ) =========
; ==== flash  ( -- : add flash words to search order ) =========
; ==== flash  ( -- : add flash words to search order ) =========
The flash related word set requires its own glossary and
The flash related word set requires its own glossary and
description. It is for manipulating the onboard memory, not
description. It is for manipulating the onboard memory, not
just the Flash chip on the Nexys3 but the SRAM as well (as
just the Flash chip on the Nexys3 but the SRAM as well (as
both devices share data, address and most control lines).
both devices share data, address and most control lines).
The startup sequences loads blocks from Flash to SRAM, the
The startup sequences loads blocks from Flash to SRAM, the
SRAM can be modified freely, but committing data to Flash is
SRAM can be modified freely, but committing data to Flash is
a manual process as erasing and writing to Flash too many times
a manual process as erasing and writing to Flash too many times
can cause it to wear out.
can cause it to wear out.
The source code should be consulted for a list of the memory
The source code should be consulted for a list of the memory
related words, their usage and other such information.
related words, their usage and other such information.
; ==== flush  ( -- : write dirty blocks, empty-buffers also ) ==
; ==== flush  ( -- : write dirty blocks, empty-buffers also ) ==
; ==== for  ( -- : part of for...next loop ) ===================
; ==== for  ( -- : part of for...next loop ) ===================
; ==== forth  ( -- : set search order to the default ) =========
; ==== forth  ( -- : set search order to the default ) =========
; ==== forth-wordlist  ( -- voc : return Forth vocabulary ) ====
; ==== forth-wordlist  ( -- voc : return Forth vocabulary ) ====
; ==== get-order  ( -- vn...v0 u : get search order ) ==========
; ==== get-order  ( -- vn...v0 u : get search order ) ==========
'get-order' is the counter part to 'set-order', it takes a
'get-order' is the counter part to 'set-order', it takes a
variable number of arguments off of the stack, denoted by 'u',
variable number of arguments off of the stack, denoted by 'u',
which each represent a word list. It used for inspecting the
which each represent a word list. It used for inspecting the
current search order in use by the interpreter.
current search order in use by the interpreter.
; ==== here  ( -- a : return dictionary address ) ==============
; ==== here  ( -- a : return dictionary address ) ==============
'here' returns the current address of where the dictionary
'here' returns the current address of where the dictionary
pointer is, new words will be compiled at this address. The
pointer is, new words will be compiled at this address. The
dictionary pointer is updated by compiling words and numbers
dictionary pointer is updated by compiling words and numbers
into the dictionary, words like ',' and 'compile,'.
into the dictionary, words like ',' and 'compile,'.
; ==== hex  ( -- : set numeric radix to hexadecimal ) ==========
; ==== hex  ( -- : set numeric radix to hexadecimal ) ==========
This sets the current input output radix to hexadecimal, which
This sets the current input output radix to hexadecimal, which
is the default radix for numbers in this Forth. If operating
is the default radix for numbers in this Forth. If operating
in other bases, or to make it clear which base you mean, a
in other bases, or to make it clear which base you mean, a
number can be prefixed with '$' to force the input base to
number can be prefixed with '$' to force the input base to
hex for that number. This affects all number conversions
hex for that number. This affects all number conversions
globally as it sets the 'base' variable to '$10'. It is
globally as it sets the 'base' variable to '$10'. It is
equivalent to '$10 base !'.
equivalent to '$10 base !'.
Usage:
Usage:
  hex 9999 1111 + .     ( prints 'AAAA' )
  hex 9999 1111 + .     ( prints 'AAAA' )
  decimal 9999 1111 + . ( prints '11110' )
  decimal 9999 1111 + . ( prints '11110' )
; ==== hi  ( -- : initialize and login to system ) =============
; ==== hi  ( -- : initialize and login to system ) =============
'hi' initializes the system and calls the routine that prints
'hi' initializes the system and calls the routine that prints
the login prompt.
the login prompt.
; ==== hld ( -- a : hold count for pictured numeric output ) ===
; ==== hld ( -- a : hold count for pictured numeric output ) ===
'hld' is a variable which contains the current hold count for
'hld' is a variable which contains the current hold count for
the pictured numeric output. As characters are added to the
the pictured numeric output. As characters are added to the
output buffer with the word 'hold', this value is increment. It
output buffer with the word 'hold', this value is increment. It
is reset by '<#'. The value for 'hld' may actually be a count
is reset by '<#'. The value for 'hld' may actually be a count
or a pointer.
or a pointer.
; ==== hold  ( c -- : put byte into numeric output string ) ====
; ==== hold  ( c -- : put byte into numeric output string ) ====
'hold' puts a byte into the hold buffer, which is used by the
'hold' puts a byte into the hold buffer, which is used by the
Pictured Numeric Output (PNO) routines as a temporary buffer to
Pictured Numeric Output (PNO) routines as a temporary buffer to
create a string that represents the number to be output. The
create a string that represents the number to be output. The
PNO related routines include; 'hold', 'hld', '<#', '#', '#s',
PNO related routines include; 'hold', 'hld', '<#', '#', '#s',
and '#>'. They are used by words like '.' and 'u.'. The
and '#>'. They are used by words like '.' and 'u.'. The
hold buffer is not that large, at has a minimum size of eighty
hold buffer is not that large, at has a minimum size of eighty
characters, so should not be used for large strings.
characters, so should not be used for large strings.
Usage:
Usage:
  : (u.u) <# # # [char] . hold # # #> ;
  : (u.u) <# # # [char] . hold # # #> ;
  : u.u base @ >r hex (u.u) type r> base ! ;
  : u.u base @ >r hex (u.u) type r> base ! ;
  $1234 u.u ( prints '12.34' )
  $1234 u.u ( prints '12.34' )
; ==== ien  ( f -- f : set interrupt flag ) ====================
; ==== ien  ( f -- f : set interrupt flag ) ====================
; ==== ien?  ( -- f : are interrupts enabled? ) ================
; ==== ien?  ( -- f : are interrupts enabled? ) ================
; ==== if  ( -- : part of if...then/if...else...then) ==========
; ==== if  ( -- : part of if...then/if...else...then) ==========
'if' is an immediate word that should only be used within a
'if' is an immediate word that should only be used within a
word definition. It is used to form 'if...then' and
word definition. It is used to form 'if...then' and
'if...else...then' clauses for conditional execution of
'if...else...then' clauses for conditional execution of
words. The words 'else' and 'then' should also be consulted.
words. The words 'else' and 'then' should also be consulted.
'if' has differing behavior at compile time and run time,
'if' has differing behavior at compile time and run time,
which is covered in the documentation for the system internals,
which is covered in the documentation for the system internals,
however 'if' is just an ordinary Forth word. When run, it
however 'if' is just an ordinary Forth word. When run, it
takes a value from the variable stack and jumps to the
takes a value from the variable stack and jumps to the
corresponding 'else' or 'then' if it is zero, if it is non
corresponding 'else' or 'then' if it is zero, if it is non
zero it continues execution after the 'else'.
zero it continues execution after the 'else'.
  : example cr if $" Hello" else $" Bye" then count type cr ;
  : example cr if $" Hello" else $" Bye" then count type cr ;
  0 example ( prints 'Hello' )
  0 example ( prints 'Hello' )
  1 example ( prints 'Bye' )
  1 example ( prints 'Bye' )
; ==== immediate  ( -- : make last defined word immediate ) ====
; ==== immediate  ( -- : make last defined word immediate ) ====
'immediate' is an important word that makes the most recently
'immediate' is an important word that makes the most recently
defined word 'immediate', that is it will be executed even
defined word 'immediate', that is it will be executed even
when in compile mode. All control structure words are
when in compile mode. All control structure words are
immediate words such as 'if', and 'for'.
immediate words such as 'if', and 'for'.
; ==== >in  ( -- a : index into parse input at address ) =======
; ==== >in  ( -- a : index into parse input at address ) =======
; ==== index  ( k1 k2 -- : print first line of block range ) ===
; ==== index  ( k1 k2 -- : print first line of block range ) ===
'index' displays the first line in a range of blocks, if the
'index' displays the first line in a range of blocks, if the
blocks are formatted correctly with the first line containing a
blocks are formatted correctly with the first line containing a
description of the block contents then this works to display an
description of the block contents then this works to display an
index of the blocks.
index of the blocks.
; ==== interactive  ( -- : interactive I/O mode ) ==============
; ==== interactive  ( -- : interactive I/O mode ) ==============
; ==== interpret  ( ??? a -- ??? : interpret word/number ) =====
; ==== interpret  ( ??? a -- ??? : interpret word/number ) =====
; ==== invert  ( u -- u : bitwise invert ) =====================
; ==== invert  ( u -- u : bitwise invert ) =====================
'invert' performs a bitwise invert on a number. For a
'invert' performs a bitwise invert on a number. For a
twos compliment negation see 'negate'.
twos compliment negation see 'negate'.
Usage:
Usage:
  hex
  hex
     0 invert . ( prints 'FFFF' )
     0 invert . ( prints 'FFFF' )
     4 invert . ( prints 'FFFB' )
     4 invert . ( prints 'FFFB' )
  FFFF invert . ( prints '0' )
  FFFF invert . ( prints '0' )
  AAAA invert . ( prints '5555' )
  AAAA invert . ( prints '5555' )
; ==== io!  ( -- : initialize IO channels ) ====================
; ==== io!  ( -- : initialize IO channels ) ====================
'io!' initializes the I/O devices and sets the input and output
'io!' initializes the I/O devices and sets the input and output
devices to their default values (read from UART and PS/2
devices to their default values (read from UART and PS/2
keyboard, write to the VT100 display, and to UART - both at
keyboard, write to the VT100 display, and to UART - both at
the same time). It also disables the interrupts, and sets the
the same time). It also disables the interrupts, and sets the
timer to a count but not generate interrupts.
timer to a count but not generate interrupts.
Example usage:
Example usage:
   io! ( ...that's not a very good demonstration... )
   io! ( ...that's not a very good demonstration... )
; ==== key  ( -- c : block until character read in ) ===========
; ==== key  ( -- c : block until character read in ) ===========
This word blocks until a character has been read in from the
This word blocks until a character has been read in from the
current input device (or devices). The input devices can be
current input device (or devices). The input devices can be
either be the UART or the PS/2 Keyboard. The input devices can
either be the UART or the PS/2 Keyboard. The input devices can
be changed with the 'io!', 'console', 'conceal', 'interactive'
be changed with the 'io!', 'console', 'conceal', 'interactive'
and 'file' words.
and 'file' words.
; ==== key?  ( -- c -1 | 0 : non-blocking character read ) =====
; ==== key?  ( -- c -1 | 0 : non-blocking character read ) =====
This is a non-blocking version of 'key', it returns a
This is a non-blocking version of 'key', it returns a
character and true (-1) if a new character has come through
character and true (-1) if a new character has come through
from input devices, and only 0 if there is no new character.
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
The input devices can be either a UART or a PS/2 keyboard, and
this can be changed with the 'io!', 'console', 'conceal', 'file'
this can be changed with the 'io!', 'console', 'conceal', 'file'
and 'interactive' words.
and 'interactive' words.
; ==== last  ( -- pwd : last defined word ) ====================
; ==== last  ( -- pwd : last defined word ) ====================
; ==== led!  ( u -- : write value to LEDs ) ====================
; ==== led!  ( u -- : write value to LEDs ) ====================
'led!' sets the LEDs on the board next to the switches. There
'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 eight switches, and the lowest eight bits of the input value
are used to set the switches, 1 is on, 0 is off.
are used to set the switches, 1 is on, 0 is off.
; ==== list  ( k -- : list block ) =============================
; ==== list  ( k -- : list block ) =============================
The word list loads block 'k' from disk and display the contents
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
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
with a column width of 64. The display format is controlled by
the 'border' variable, if true it 'list' displays the line
the 'border' variable, if true it 'list' displays the line
number and a border around the block, if false, then it just
number and a border around the block, if false, then it just
display the block line by line without formatting. It is true
display the block line by line without formatting. It is true
by default. 'list' will also call 'page' before it displays
by default. 'list' will also call 'page' before it displays
the block if 'border' contains a non-zero value.
the block if 'border' contains a non-zero value.
Usage:
Usage:
   1 list
   1 list
   2 list
   2 list
   ( ..ad infinitum )
   ( ..ad infinitum )
; ==== literal  ( n -- : compile literal into dictionary ) =====
; ==== literal  ( n -- : compile literal into dictionary ) =====
This is an immediate word that compiles a number into the
This is an immediate word that compiles a number into the
dictionary. A number takes up between one and two cells in the
dictionary. A number takes up between one and two cells in the
dictionary (negative numbers take up two space, positive only
dictionary (negative numbers take up two space, positive only
one). It is a compile only word.
one). It is a compile only word.
Usage:
Usage:
  : example [ 2 2 + ] literal ;
  : example [ 2 2 + ] literal ;
  example . ( prints '4' )
  example . ( prints '4' )
; ==== load  ( k -- : load and execute block ) =================
; ==== load  ( k -- : load and execute block ) =================
'load' retrieves a block using 'block', and evaluates that
'load' retrieves a block using 'block', and evaluates that
block, executing whatever is in that block as Forth code,
block, executing whatever is in that block as Forth code,
'source-id' will return -1 for the duration of this evaluation,
'source-id' will return -1 for the duration of this evaluation,
the input source will be returned to whatever it was before
the input source will be returned to whatever it was before
the evaluation took place, such as keyboard or UART input,
the evaluation took place, such as keyboard or UART input,
once the evaluation has finished. 'load' is used in the
once the evaluation has finished. 'load' is used in the
word 'thru' to do the evaluation of successive blocks off
word 'thru' to do the evaluation of successive blocks off
mass storage.
mass storage.
; ==== loaded  ( -- a : variable, true if boot block loaded ) ==
; ==== loaded  ( -- a : variable, true if boot block loaded ) ==
This is a variable which can be set by the user if the loading
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
of the boot block was successful, and if the error messages
exists on disk. The error handling words in QUIT inspect this
exists on disk. The error handling words in QUIT inspect this
variable to work out if it can lookup error messages and print
variable to work out if it can lookup error messages and print
them, or if it should just print out the error number.
them, or if it should just print out the error number.
; ==== lshift  ( u1 u2 -- u3: logical left shift u1 by u2 ) ====
; ==== lshift  ( u1 u2 -- u3: logical left shift u1 by u2 ) ====
This performs a logical left shift on 'u1' by 'u2'.
This performs a logical left shift on 'u1' by 'u2'.
; ==== make  ( -- : make part of make/doer words ) =============
; ==== make  ( -- : make part of make/doer words ) =============
'make' is a state aware word that operates on words made with
'make' is a state aware word that operates on words made with
'doer', it should not be used with other words.
'doer', it should not be used with other words.
; ==== max  ( n1 n2 -- n3: maximum of two numbers ) ============
; ==== max  ( n1 n2 -- n3: maximum of two numbers ) ============
This returns the maximum of two signed numbers. This is a
This returns the maximum of two signed numbers. This is a
signed operation! Some Forths define an unsigned version
signed operation! Some Forths define an unsigned version
called 'umax'. See 'min' for the minimum of two signed
called 'umax'. See 'min' for the minimum of two signed
numbers.
numbers.
; ==== message  ( u -- : type line from block ) ================
; ==== message  ( u -- : type line from block ) ================
'message' prints a line from a block, a block is 1024 bytes
'message' prints a line from a block, a block is 1024 bytes
long, and there are 16 lines of 64 bytes per block. 'u'
long, and there are 16 lines of 64 bytes per block. 'u'
specifies a line number, starting at block 0, which contains
specifies a line number, starting at block 0, which contains
lines 0-15, block 1 has lines 16-31 and so on. Lines are
lines 0-15, block 1 has lines 16-31 and so on. Lines are
printing omitting any trailing spaces and non-ASCII characters
printing omitting any trailing spaces and non-ASCII characters
are replaced with another character (an underscore, '_').
are replaced with another character (an underscore, '_').
This word is useful in printing error messages, the interpreter
This word is useful in printing error messages, the interpreter
maps error codes into line numbers. The error messages start
maps error codes into line numbers. The error messages start
in block 2 and end in block 5, with one message per line.
in block 2 and end in block 5, with one message per line.
Usage:
Usage:
  $21 message ( print line 33, or the second line in block 3 )
  $21 message ( print line 33, or the second line in block 3 )
; ==== min  ( n1 n2 -- n3: minimum of two numbers ) ============
; ==== min  ( n1 n2 -- n3: minimum of two numbers ) ============
This returns the minimum of two signed numbers. 'umin' is not
This returns the minimum of two signed numbers. 'umin' is not
defined but it is enough to create, it provides an analogue
defined but it is enough to create, it provides an analogue
for unsigned numbers. The word is simple enough to use.
for unsigned numbers. The word is simple enough to use.
  :  min 2dup  < if drop else nip then ; ( n n -- n )
  :  min 2dup  < if drop else nip then ; ( n n -- n )
  : umin 2dup u< if drop else nip then ; ( n n -- n )
  : umin 2dup u< if drop else nip then ; ( n n -- n )
Usage:
Usage:
   3 4 min .    ( prints 3 )
   3 4 min .    ( prints 3 )
  -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 min . ( prints -3, 65533 is -3 on a 16-bit system )
  65533 4 umin . ( prints 4 )
  65533 4 umin . ( prints 4 )
; ==== m/mod  ( d n -- r q : signed divide / modulo ) ==========
; ==== m/mod  ( d n -- r q : signed divide / modulo ) ==========
; ==== mod  ( n1 n2 -- r : remainder of n1 divided by n2 ) =====
; ==== mod  ( n1 n2 -- r : remainder of n1 divided by n2 ) =====
; ==== /mod  ( n1 n2 -- r q : remainder/quotient ) =============
; ==== /mod  ( n1 n2 -- r q : remainder/quotient ) =============
'/mod' divides 'n1' by 'n2' and returns the remainder ('r')
'/mod' divides 'n1' by 'n2' and returns the remainder ('r')
and the quotient ('q') of that operation. Given '/mod', the
and the quotient ('q') of that operation. Given '/mod', the
definitions of 'mod' and '/' naturally follow. They are
definitions of 'mod' and '/' naturally follow. They are
actually all implemented in the far more useful 'um/mod' word.
actually all implemented in the far more useful 'um/mod' word.
; ==== ms  ( u -- : wait for 'u' milliseconds ) ================
; ==== ms  ( u -- : wait for 'u' milliseconds ) ================
'ms' waits for 'u' milliseconds with a busy loop. It is
'ms' waits for 'u' milliseconds with a busy loop. It is
predicated on the system running at 100MHz and will need to be
predicated on the system running at 100MHz and will need to be
modified if the system frequency changes.
modified if the system frequency changes.
Usage:
Usage:
   : 1s 1000 ms ; ( -- : wait for a second )
   : 1s 1000 ms ; ( -- : wait for a second )
   : toggle-leds 0 begin invert dup led! 1s again ; ( -- )
   : toggle-leds 0 begin invert dup led! 1s again ; ( -- )
; ==== negate  ( n -- n : negate a number ) ====================
; ==== negate  ( n -- n : negate a number ) ====================
'negate' performs the negation of a number into twos compliment
'negate' performs the negation of a number into twos compliment
format, positive numbers become negative and negative numbers
format, positive numbers become negative and negative numbers
become positive (with the exclusion of $8000, which stays the
become positive (with the exclusion of $8000, which stays the
same).
same).
Usage:
Usage:
  decimal
  decimal
   1 negate . ( '-1' )
   1 negate . ( '-1' )
   0 negate . ( '0' )
   0 negate . ( '0' )
  -4 negate . ( '4' )
  -4 negate . ( '4' )
; ==== next  ( -- : part of for...next loop ) ==================
; ==== next  ( -- : part of for...next loop ) ==================
; ==== nip  ( n1 n2 -- n1 : remove second value on stack ) =====
; ==== nip  ( n1 n2 -- n1 : remove second value on stack ) =====
The stack comment describes this word perfectly, 'nip' removes
The stack comment describes this word perfectly, 'nip' removes
the secondmost item on the stack, leaving the topmost intact.
the secondmost item on the stack, leaving the topmost intact.
; ==== :noname  ( -- xt : start anonymous function ) ===========
; ==== :noname  ( -- xt : start anonymous function ) ===========
The ':noname' word is an immediate word that allows the
The ':noname' word is an immediate word that allows the
creation of words that do not have names, or an anonymous
creation of words that do not have names, or an anonymous
function. The word can be executed with the 'execute' function.
function. The word can be executed with the 'execute' function.
Usage:
Usage:
  :noname 2 2 + ; execute . ( prints '4' )
  :noname 2 2 + ; execute . ( prints '4' )
  : (;) ' rdrop compile, 0 state ! ;
  : (;) ' rdrop compile, 0 state ! ;
  : compose >r >r :noname r> compile, r> compile, (;) ;
  : compose >r >r :noname r> compile, r> compile, (;) ;
  : x 2 2 ;
  : x 2 2 ;
  : y + . ;
  : y + . ;
  ' x ' y compose execute ( prints '4' )
  ' x ' y compose execute ( prints '4' )
 
 
; ==== nuf?  ( -- f : true if 'cr' character pressed ) =========
 
'nuf?' is a non blocking input word that returns true if a
 
carriage return was input. It can be used to determine if a
 
word should continue execution or not.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
; ==== number?  ( b u -- n f : is string a number ) ============
; ==== number?  ( b u -- n f : is string a number ) ============
; ==== .ok  ( -- : print okay prompt ) =========================
; ==== .ok  ( -- : print okay prompt ) =========================
'.ok' prints out 'ok' after the successful execution of an
'.ok' prints out 'ok' after the successful execution of an
input line when the Forth interpreter is in the command mode,
input line when the Forth interpreter is in the command mode,
the prompt is suppressed when in compile mode.
the prompt is suppressed when in compile mode.
; ==== or  ( u1 u2 -- u3: bitwise or of two numbers ) ==========
; ==== or  ( u1 u2 -- u3: bitwise or of two numbers ) ==========
'or' performs the bitwise 'or' of two numbers.
'or' performs the bitwise 'or' of two numbers.
; ==== over  ( n1 n2 -- n1 n2 n1 : duplicate over ) ============
; ==== over  ( n1 n2 -- n1 n2 n1 : duplicate over ) ============
'over' duplicates the second most item on the variable stack.
'over' duplicates the second most item on the variable stack.
Its stack comment describes its workings completely.
Its stack comment describes its workings completely.
Usage:
Usage:
  1 2 over .s
  1 2 over .s
  1 2 1
  1 2 1
; ==== pack$  ( b u a -- a : pack string into address ) ========
; ==== pack$  ( b u a -- a : pack string into address ) ========
'pack$' is a useful word when dealing with short Forth
'pack$' is a useful word when dealing with short Forth
strings, it is used by the interpreter for packing the word
strings, it is used by the interpreter for packing the word
name into the words header. It takes a string specified by
name into the words header. It takes a string specified by
'b u', 'b' being an address of a string, and 'u' beings its
'b u', 'b' being an address of a string, and 'u' beings its
length, and copies the string starting at address 'a', the
length, and copies the string starting at address 'a', the
first byte of the new string is the length of the string, so
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
it requires an extra byte be available at 'a'. It then returns
a pointer to this newly packed, counted string.
a pointer to this newly packed, counted string.
; ==== pad  ( -- a : return address into pad area ) ============
; ==== pad  ( -- a : return address into pad area ) ============
'pad' returns a pointer into the pad area, which begins at
'pad' returns a pointer into the pad area, which begins at
least 80 bytes after the end of the dictionary. The 'pad'
least 80 bytes after the end of the dictionary. The 'pad'
pointer moves when the dictionary pointer moves. It is a useful
pointer moves when the dictionary pointer moves. It is a useful
area for temporary storage, but should not be used too much.
area for temporary storage, but should not be used too much.
Some words, such as the Pictured Numeric Output (PNO) words,
Some words, such as the Pictured Numeric Output (PNO) words,
use the area just before the pad area.
use the area just before the pad area.
Usage:
Usage:
  3 pad !
  3 pad !
  4 pad cell+ !
  4 pad cell+ !
  pad @ pad cell+ @ + . ( prints '7' )
  pad @ pad cell+ @ + . ( prints '7' )
; ==== page  ( -- : clear page ) ===============================
; ==== page  ( -- : clear page ) ===============================
'page' clears the screen, it does this by emitting the ANSI
'page' clears the screen, it does this by emitting the ANSI
terminal escape sequence codes for erasing the display and
terminal escape sequence codes for erasing the display and
moving the cursor position to the top left most cell.
moving the cursor position to the top left most cell.
Usage:
Usage:
  page ( <- That's about it, not much to see )
  page ( <- That's about it, not much to see )
; ==== parse  ( b u c -- b u delta : parse string out ) ========
; ==== parse  ( b u c -- b u delta : parse string out ) ========
; ==== pick  ( un...u0 u -- un...u0 u : pick value ) ===========
; ==== pick  ( un...u0 u -- un...u0 u : pick value ) ===========
'pick' selects an item on the stack at an arbitrary depth 'u'
'pick' selects an item on the stack at an arbitrary depth 'u'
and pushes a copy onto the variable stack. This word should be
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
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
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,
available to the H2 processor (32-64 cells deep on both stacks,
plus one for the variable stack). The implementation shuffles
plus one for the variable stack). The implementation shuffles
data from the variable stack to the return stack, so it is
data from the variable stack to the return stack, so it is
quite easy to overflow the return stack for valid but high
quite easy to overflow the return stack for valid but high
values of 'u'.
values of 'u'.
Usage:
Usage:
  22 33 44 0 pick . ( prints '44' )
  22 33 44 0 pick . ( prints '44' )
  22 33 44 1 pick . ( prints '33' )
  22 33 44 1 pick . ( prints '33' )
  22 33 44 2 pick . ( prints '22' )
  22 33 44 2 pick . ( prints '22' )
; ==== query  ( -- : get line of input ) =======================
; ==== query  ( -- : get line of input ) =======================
'query' gets a new line of input from the current input device,
'query' gets a new line of input from the current input device,
and places that line in the Terminal Input Buffer, which can
and places that line in the Terminal Input Buffer, which can
be accessed by 'source'.
be accessed by 'source'.
; ==== quit  ( -- : interpreter loop ) =========================
; ==== quit  ( -- : interpreter loop ) =========================
For some reason the interpreter loop is evoked by the word
For some reason the interpreter loop is evoked by the word
'quit', which is what it is traditionally called. This is not
'quit', which is what it is traditionally called. This is not
a good name, but nonetheless is the standard name for it. The
a good name, but nonetheless is the standard name for it. The
interpreter loop fetches a line of input, parses a word,
interpreter loop fetches a line of input, parses a word,
evaluates it, catches/displays any errors and flushes the
evaluates it, catches/displays any errors and flushes the
current line if there are any, and continues to do this until
current line if there are any, and continues to do this until
the current line contains no new space delimited words/numbers,
the current line contains no new space delimited words/numbers,
whereupon it fetches a new line and repeats the process again.
whereupon it fetches a new line and repeats the process again.
Usage:
Usage:
  quit ( <- invokes another interpreter loop... )
  quit ( <- invokes another interpreter loop... )
; ==== >r  ( u --, R: -- u : move value to return stack ) ======
; ==== >r  ( u --, R: -- u : move value to return stack ) ======
'>r', also known as 'to r' moves a variable from the variable
'>r', also known as 'to r' moves a variable from the variable
stack to the return stack, its inverse is 'r>'. This word,
stack to the return stack, its inverse is 'r>'. This word,
along with all return stack words, should be used carefully as
along with all return stack words, should be used carefully as
it is possible to trash the return stack with incorrect use.
it is possible to trash the return stack with incorrect use.
The word should also be used only from within a word
The word should also be used only from within a word
definition. The stack comment describes the action of this
definition. The stack comment describes the action of this
word completely.
word completely.
Usage:
Usage:
  : rot >r swap r> swap ;    ( n1 n2 n3 -- n2 n3 n1 )
  : rot >r swap r> swap ;    ( n1 n2 n3 -- n2 n3 n1 )
  : -rot swap >r swap r> ;   ( n1 n2 n3 -- n3 n1 n2 )
  : -rot swap >r swap r> ;   ( n1 n2 n3 -- n3 n1 n2 )
; ==== r>  ( -- u, R: u --: move value from return stack ) =====
; ==== r>  ( -- u, R: u --: move value from return stack ) =====
'r>' also known as 'from r', moves a cell sized value from the
'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
return stack to the variable stack. It should only be used from
within a word definition, and only by those that know what they
within a word definition, and only by those that know what they
are doing. It is possible to crash the interpreter by trashing
are doing. It is possible to crash the interpreter by trashing
the return stack with this word. The stack comment for this
the return stack with this word. The stack comment for this
word perfectly describes this word.
word perfectly describes this word.
Usage:
Usage:
  : rot >r swap r> swap ;   ( n1 n2 n3 -- n2 n3 n1 )
  : rot >r swap r> swap ;   ( n1 n2 n3 -- n2 n3 n1 )
  : -rot swap >r swap r> ;  ( n1 n2 n3 -- n3 n1 n2 )
  : -rot swap >r swap r> ;  ( n1 n2 n3 -- n3 n1 n2 )
; ==== r@  ( -- u : R: u -- u: copy top of return stack ) ======
; ==== r@  ( -- u : R: u -- u: copy top of return stack ) ======
'r@' is a useful word that copies the topmost value on the
'r@' is a useful word that copies the topmost value on the
return stack, leaving that value in place, and pushes it to
return stack, leaving that value in place, and pushes it to
the variable stack.  This word is useful when juggling
the variable stack.  This word is useful when juggling
variables on the stack, it is also used to access the loop
variables on the stack, it is also used to access the loop
counter in a "for...next" or "for...aft...then...next"
counter in a "for...next" or "for...aft...then...next"
construct.
construct.
; ==== random  ( -- u : random number ) ========================
; ==== random  ( -- u : random number ) ========================
'random' returns a Pseudo Random Number, it uses a CRC algorithm
'random' returns a Pseudo Random Number, it uses a CRC algorithm
and the system timer to generate the value.
and the system timer to generate the value.
; ==== rdrop  ( --, R: u -- : drop a value from return stack ) =
; ==== rdrop  ( --, R: u -- : drop a value from return stack ) =
'rdrop' is the return stack equivalent of 'drop', it discards
'rdrop' is the return stack equivalent of 'drop', it discards
a single value from the return stack.
a single value from the return stack.
Care should be taken when manipulating the return stack
Care should be taken when manipulating the return stack
as it can trash it rendering the system inoperable until it
as it can trash it rendering the system inoperable until it
is restarted.
is restarted.
; ==== recurse  ( -- : recursively call current word ) =========
; ==== recurse  ( -- : recursively call current word ) =========
'recurse' is a word that when used within a word definition it
'recurse' is a word that when used within a word definition it
will recursively call the current word. This is not a tail
will recursively call the current word. This is not a tail
call, if this word is used incorrectly it will blow up the
call, if this word is used incorrectly it will blow up the
return stack. Some Forths use the construct 'recurse exit'
return stack. Some Forths use the construct 'recurse exit'
to implement tail calls, reliant on a peephole optimizer
to implement tail calls, reliant on a peephole optimizer
built into 'exit' to change the call into a branch, this Forth
built into 'exit' to change the call into a branch, this Forth
does not do this. This word is necessary as the word currently
does not do this. This word is necessary as the word currently
being defined has not been linked into the dictionary yet, to
being defined has not been linked into the dictionary yet, to
permit previous versions of the word to be used in the new
permit previous versions of the word to be used in the new
definition. This word is a compile only word.
definition. This word is a compile only word.
Usage:
Usage:
  : pick ?dup if swap >r 1- recurse r> swap exit then dup ;
  : pick ?dup if swap >r 1- recurse r> swap exit then dup ;
; ==== repeat  ( -- : part of begin...while...repeat ) =========
; ==== repeat  ( -- : part of begin...while...repeat ) =========
'repeat' terminates a 'begin...while...repeat' loop. It is a
'repeat' terminates a 'begin...while...repeat' loop. It is a
word that should only be used as part of a
word that should only be used as part of a
'begin...while...repeat' clause, and should only be used
'begin...while...repeat' clause, and should only be used
from within a word definition. It is an immediate word. The
from within a word definition. It is an immediate word. The
words 'begin' and 'while' should also be consulted. 'repeat'
words 'begin' and 'while' should also be consulted. 'repeat'
unconditionally jumps back to the 'begin', it is 'while' that
unconditionally jumps back to the 'begin', it is 'while' that
does the test and potentially jumps past this 'repeat' if the
does the test and potentially jumps past this 'repeat' if the
value it pops from variable stack is zero.
value it pops from variable stack is zero.
; ==== rot  ( n1 n2 n3 -- n2 n3 n1 : rotate three items ) ======
; ==== rot  ( n1 n2 n3 -- n2 n3 n1 : rotate three items ) ======
Rotate the first three elements on the variable stack. The
Rotate the first three elements on the variable stack. The
stack comment describes the word completely. If you find your
stack comment describes the word completely. If you find your
self using this word too much, you need to rethink and refactor
self using this word too much, you need to rethink and refactor
your Forth. 'rot' is a useful word, but it should be used
your Forth. 'rot' is a useful word, but it should be used
sparingly. '-rot' reverses the 'rot' operation.
sparingly. '-rot' reverses the 'rot' operation.
; ==== -rot  ( n1 n2 n3 -- n3 n1 n2 : rotate three items ) =====
; ==== -rot  ( n1 n2 n3 -- n3 n1 n2 : rotate three items ) =====
Rotate the first three elements on the variable stack in the
Rotate the first three elements on the variable stack in the
opposite direction as 'rot'. If you find yourself using this
opposite direction as 'rot'. If you find yourself using this
word too much it might be best to refactor your code.
word too much it might be best to refactor your code.
; ==== rp@  ( -- u : return stack depth ) ======================
; ==== rp@  ( -- u : return stack depth ) ======================
'rp@' push the return stack depth onto the variable stack, it
'rp@' push the return stack depth onto the variable stack, it
is an assembly instruction.
is an assembly instruction.
; ==== rpick  ( u -- u, R: un...u0 : pick return stack value ) =
; ==== rpick  ( u -- u, R: un...u0 : pick return stack value ) =
'rpick' picks a value at an arbitrary depth on the return stack
'rpick' picks a value at an arbitrary depth on the return stack
based on the argument given.
based on the argument given.
; ==== rshift  ( u1 u2 -- u3 : logical right shift u1 by u2 ) ==
; ==== rshift  ( u1 u2 -- u3 : logical right shift u1 by u2 ) ==
'rshift' performs a logical right shift of 'u1' by 'u2' places,
'rshift' performs a logical right shift of 'u1' by 'u2' places,
it is equivalent to unsigned division by 2 raised to the power
it is equivalent to unsigned division by 2 raised to the power
of 'u2'.
of 'u2'.
; ==== .s  ( -- : print out variable stack ) ===================
; ==== .s  ( -- : print out variable stack ) ===================
This word is used for debugging, it prints out the entire
This word is used for debugging, it prints out the entire
variable stack up to the current variable stack depth. It uses
variable stack up to the current variable stack depth. It uses
the area between the end of the dictionary and the start of the
the area between the end of the dictionary and the start of the
PAD area. It is not a reentrant function.
PAD area. It is not a reentrant function.
; ==== #s  ( u -- 0 : repeat '#' until 0 ) =====================
; ==== #s  ( u -- 0 : repeat '#' until 0 ) =====================
This word repeatedly calls '#' on a number until it is zero, it
This word repeatedly calls '#' on a number until it is zero, it
should only be used within a pictured numeric output construct
should only be used within a pictured numeric output construct
and uses the area between the end of the dictionary and the
and uses the area between the end of the dictionary and the
beginning of the pad area. Characters are held starting from
beginning of the pad area. Characters are held starting from
the pad area working downwards towards the end of the dictionary
the pad area working downwards towards the end of the dictionary
space.
space.
Example:
Example:
  : print-number <# #s #> type ;
  : print-number <# #s #> type ;
  1234 print-number ( <-- prints '1234' )
  1234 print-number ( <-- prints '1234' )
; ==== save-buffers  ( -- : save dirty blocks ) ================
; ==== save-buffers  ( -- : save dirty blocks ) ================
'save-buffers' saves any dirty buffers, if there are any, to
'save-buffers' saves any dirty buffers, if there are any, to
disk and sets the block dirty bit to clean (so subsequent calls
disk and sets the block dirty bit to clean (so subsequent calls
to 'save-buffers' will not save blocks to mass storage unless
to 'save-buffers' will not save blocks to mass storage unless
they have been 'update'd again). You can make a block dirty
they have been 'update'd again). You can make a block dirty
by calling 'update' after the block has been loaded, and before
by calling 'update' after the block has been loaded, and before
any other blocks have been loaded.
any other blocks have been loaded.
Usage:
Usage:
  5 block drop      ( load block 5, do nothing with it )
  5 block drop      ( load block 5, do nothing with it )
  save-buffers      ( nothing happens, block 5 is not dirty )
  save-buffers      ( nothing happens, block 5 is not dirty )
  4 block 99 swap ! ( store '99' in first element of block 4 )
  4 block 99 swap ! ( store '99' in first element of block 4 )
  update            ( mark block 4 as dirty )
  update            ( mark block 4 as dirty )
  save-buffers      ( block 4 written back to disk )
  save-buffers      ( block 4 written back to disk )
; ==== see  ( -- ;  : decompile word ) =================
; ==== see  ( -- ;  : decompile word ) =================
'see' is a complex word that can decompile a Forth word, it is
'see' is a complex word that can decompile a Forth word, it is
liable to be buggy. 'see' parses the next space delimited word
liable to be buggy. 'see' parses the next space delimited word
in the dictionary, and if found attempts to disassemble the
in the dictionary, and if found attempts to disassemble the
word into instructions and function calls. If not found 'see'
word into instructions and function calls. If not found 'see'
will throw an exception. The results of 'see' are
will throw an exception. The results of 'see' are
implementation dependent. Given a very good implementation
implementation dependent. Given a very good implementation
of 'see' it would be possible to dispense with the source
of 'see' it would be possible to dispense with the source
code entirely in text form, the binary could be disassembled,
code entirely in text form, the binary could be disassembled,
the code modified, and then it could be reintegrated into
the code modified, and then it could be reintegrated into
dictionary - the idea is purely speculative, comments would
dictionary - the idea is purely speculative, comments would
be missing and this version of 'see' is not good enough.
be missing and this version of 'see' is not good enough.
Not many languages have a disassembler built-in!
Not many languages have a disassembler built-in!
Usage:
Usage:
  see word
  see word
; ==== segments!  ( u -- : display 'u' on LED displays ) =======
; ==== segments!  ( u -- : display 'u' on LED displays ) =======
Segments writes a single 16-bit value to the four seven segment
Segments writes a single 16-bit value to the four seven segment
displays on the board. This can be used to display a single
displays on the board. This can be used to display a single
cell as a hexadecimal value.
cell as a hexadecimal value.
Usage:
Usage:
  $cafe segments!
  $cafe segments!
  $d1ed segments!
  $d1ed segments!
  $0001 segments!
  $0001 segments!
; ==== set-order  ( vn...v0 n -- : set search order ) ==========
; ==== set-order  ( vn...v0 n -- : set search order ) ==========
This word sets the search order for the dictionary search. It
This word sets the search order for the dictionary search. It
accepts a variable number of items off of the stack, 'n' is
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'
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
exists, when it is '-1' it sets the order to the minimal
search order.
search order.
; ==== sgr  ( u -- : set ANSI terminal SGR attribute ) =========
; ==== sgr  ( u -- : set ANSI terminal SGR attribute ) =========
'sgr' takes a number and emits it as a 'Select Graphic
'sgr' takes a number and emits it as a 'Select Graphic
Rendition' command, which is a standard ANSI Escape sequence
Rendition' command, which is a standard ANSI Escape sequence
used for terminal control. SGR commands relate to colors and
used for terminal control. SGR commands relate to colors and
how the text is presents, for example numbers $1E to $25 are
how the text is presents, for example numbers $1E to $25 are
used to set the foreground color, $28 to $2F the background
used to set the foreground color, $28 to $2F the background
color. $0 is used to reset all of the attributes, $8 is used
color. $0 is used to reset all of the attributes, $8 is used
to conceal character output, $7 for reverse video. Not all
to conceal character output, $7 for reverse video. Not all
SGR commands are processed by the VT100 hardware, and if
SGR commands are processed by the VT100 hardware, and if
talking to the device over the UART it depends on the terminal
talking to the device over the UART it depends on the terminal
emulator you are using.
emulator you are using.
Examples:
Examples:
   0 sgr    ( reset terminal SGR attributes )
   0 sgr    ( reset terminal SGR attributes )
   $1f sgr  ( set foreground color to red )
   $1f sgr  ( set foreground color to red )
   $2a sgr  ( set background color to green )
   $2a sgr  ( set background color to green )
; ==== sign  ( n -- : hold '-' if n negative ) =================
; ==== sign  ( n -- : hold '-' if n negative ) =================
'sign' is a word used in conjunction with the pictured numeric
'sign' is a word used in conjunction with the pictured numeric
output routines ('<#', '#s' and '#>'), it holds a '-' is the
output routines ('<#', '#s' and '#>'), it holds a '-' is the
signed number it is given is negative.
signed number it is given is negative.
; ==== source  ( -- a u : get source string ) ==================
; ==== source  ( -- a u : get source string ) ==================
'source' retrieves the address and length of the current
'source' retrieves the address and length of the current
Terminal Input Buffer (TIB). This contains the current line
Terminal Input Buffer (TIB). This contains the current line
that is being processed, this is the line that is retrieved
that is being processed, this is the line that is retrieved
by the word 'query'.
by the word 'query'.
Usage:
Usage:
  source type ( a simple quine )
  source type ( a simple quine )
; ==== source-id  ( -- 0 | -1 : identify input source ) ========
; ==== source-id  ( -- 0 | -1 : identify input source ) ========
'source-id' is used to identify the input source, whether
'source-id' is used to identify the input source, whether
the interpreter is reading input from the user (0) or evaluating
the interpreter is reading input from the user (0) or evaluating
text within a string (-1)
text within a string (-1)
Example usage:
Example usage:
  : test $" source-id . cr " count evaluate ;
  : test $" source-id . cr " count evaluate ;
  test        ( prints FFFF or -1 )
  test        ( prints FFFF or -1 )
  source-id . ( prints '0')
  source-id . ( prints '0')
When a block is evaluated with 'load' -1 is returned by
When a block is evaluated with 'load' -1 is returned by
'source-id' as it is evaluating the block as a string.
'source-id' as it is evaluating the block as a string.
; ==== sp@  ( -- u : variable stack depth ) ====================
; ==== sp@  ( -- u : variable stack depth ) ====================
'sp@' is an assembly instruction which returns the current
'sp@' is an assembly instruction which returns the current
depth of the variable stack.
depth of the variable stack.
; ==== space  ( -- : emit space character ) ====================
; ==== space  ( -- : emit space character ) ====================
'space' emits a single space character to the current output
'space' emits a single space character to the current output
device. That is all.
device. That is all.
; ==== spaces  ( n -- : emit 'n' spaces ) ======================
; ==== spaces  ( n -- : emit 'n' spaces ) ======================
'spaces' emits 'n' number of spaces, if 'n' is greater than
'spaces' emits 'n' number of spaces, if 'n' is greater than
zero. This is a useful word for formatting.
zero. This is a useful word for formatting.
Usage:
Usage:
  0 spaces ok
  0 spaces ok
  1 spaces  ok
  1 spaces  ok
  2 spaces   ok
  2 spaces   ok
 -1 spaces ok
 -1 spaces ok
; ==== span  ( -- a : character count from expect, variable ) ==
; ==== span  ( -- a : character count from expect, variable ) ==
'span' is a variable which contains the latest character count
'span' is a variable which contains the latest character count
from 'expect'. Consult 'expect' for more information.
from 'expect'. Consult 'expect' for more information.
Usage:
Usage:
   4000 20 expect
   4000 20 expect
   span @
   span @
; ==== state  ( -- a : state variable ) ========================
; ==== state  ( -- a : state variable ) ========================
'state' is a variable that contains the global state of the
'state' is a variable that contains the global state of the
Forth interpreter loop, which can be in either compile or
Forth interpreter loop, which can be in either compile or
command mode. 'state' contains -1 for command mode, 0 for
command mode. 'state' contains -1 for command mode, 0 for
compile mode. It can be set directly to change the interpreter
compile mode. It can be set directly to change the interpreter
state, or read to make words change their behavior based on
state, or read to make words change their behavior based on
the state (which is generally not the best thing to do). The
the state (which is generally not the best thing to do). The
words '[' and ']' can be used to switch the state as well.
words '[' and ']' can be used to switch the state as well.
Usage:
Usage:
  : ] -1 state ! ;
  : ] -1 state ! ;
  : [  0 state ! ; immediate
  : [  0 state ! ; immediate
  : example [ 2 2 + ] literal ;
  : example [ 2 2 + ] literal ;
  example . ( prints '4' )
  example . ( prints '4' )
; ==== =string  ( b1 u1 b2 u2 -- f : string equality ) =========
; ==== =string  ( b1 u1 b2 u2 -- f : string equality ) =========
This word implement a test for string equality, it compares
This word implement a test for string equality, it compares
two strings specified by two address-length pairs and returns
two strings specified by two address-length pairs and returns
a boolean that determined whether the strings are equal or
a boolean that determined whether the strings are equal or
not (-1 for true/equal, 0 for false/not-equal). The word is
not (-1 for true/equal, 0 for false/not-equal). The word is
unusual as it accepts four parameters on the stack, which is
unusual as it accepts four parameters on the stack, which is
bad practice for Forth words which is most circumstances should
bad practice for Forth words which is most circumstances should
only accept three parameters. This word is used internally for
only accept three parameters. This word is used internally for
doing the dictionary search.
doing the dictionary search.
Usage:
Usage:
  : s1 $" Hello " count ;
  : s1 $" Hello " count ;
  : s2 $" Bye! " count ;
  : s2 $" Bye! " count ;
  s1 s2 =string . ( prints '0' )
  s1 s2 =string . ( prints '0' )
  s1 s1 =string . ( prints '-1', or 'FFFF' )
  s1 s1 =string . ( prints '-1', or 'FFFF' )
; ==== /string  ( b u1 u2 -- b u : advance string by u2 ) ======
; ==== /string  ( b u1 u2 -- b u : advance string by u2 ) ======
'/string' advances a string 'b u1' by 'u2' characters, if there
'/string' advances a string 'b u1' by 'u2' characters, if there
are enough characters left to advance the string by. This is
are enough characters left to advance the string by. This is
obviously a word that is useful when dealing with strings,
obviously a word that is useful when dealing with strings,
strings in Forth commonly come in two type: counted strings
strings in Forth commonly come in two type: counted strings
and address-length based strings. This word deals with the
and address-length based strings. This word deals with the
latter type of string.
latter type of string.
; ==== swap  ( u1 u2 -- u2 u1 : swap two variables ) ===========
; ==== swap  ( u1 u2 -- u2 u1 : swap two variables ) ===========
It swaps two variables on the stack, its stack effect describes
It swaps two variables on the stack, its stack effect describes
the word perfectly. This is a simple word that will be used
the word perfectly. This is a simple word that will be used
quite a lot, memorize it quickly!
quite a lot, memorize it quickly!
Usage:
Usage:
   1 2   (     -- 1 2 )
   1 2   (     -- 1 2 )
   swap  ( 1 2 -- 2 1 )
   swap  ( 1 2 -- 2 1 )
; ==== switches  ( -- u : get state of switches ) ==============
; ==== switches  ( -- u : get state of switches ) ==============
'switches' retrieves the state of the two state switches on
'switches' retrieves the state of the two state switches on
the board, the values are already debounced. There are eight
the board, the values are already debounced. There are eight
switches which each have a single LED next to them (which can
switches which each have a single LED next to them (which can
be controlled with 'led!'). The lowest eight bits are used
be controlled with 'led!'). The lowest eight bits are used
for the switch states, 1 for on, 0 for off.
for the switch states, 1 for on, 0 for off.
Example usage:
Example usage:
   : select 1 swap lshift switches swap and 0= 0= ;
   : select 1 swap lshift switches swap and 0= 0= ;
   : sw0 0 select ; : sw1 1 select ; : sw2 2 select ;
   : sw0 0 select ; : sw1 1 select ; : sw2 2 select ;
   : sw3 3 select ; : sw4 4 select ; : sw5 5 select ;
   : sw3 3 select ; : sw4 4 select ; : sw5 5 select ;
   : sw6 6 select ; : sw7 7 select ;
   : sw6 6 select ; : sw7 7 select ;
   : switches->leds switches led! ;
   : switches->leds switches led! ;
; ==== then  ( -- : part of if...then or if...else...then ) ====
; ==== then  ( -- : part of if...then or if...else...then ) ====
'then' should only be used inside a word definition and as
'then' should only be used inside a word definition and as
part of an 'if...else...then' or 'if...then' sequence, it is
part of an 'if...else...then' or 'if...then' sequence, it is
used to terminate both sequences with execution continuing
used to terminate both sequences with execution continuing
after 'then'. The words 'if' and 'else' should also be
after 'then'. The words 'if' and 'else' should also be
consulted. An exception may be thrown if this word is used
consulted. An exception may be thrown if this word is used
outside a word definition, or if there is not a corresponding
outside a word definition, or if there is not a corresponding
if. It is an immediate word.
if. It is an immediate word.
Usage:
Usage:
   : invalid then ; ( <- invalid usage, no matching 'if' )
   : invalid then ; ( <- invalid usage, no matching 'if' )
   then      ( <- invalid usage, outside word definition )
   then      ( <- invalid usage, outside word definition )
   : example dup if 1+ then ; ( 0 | x -- 0 | x+1 )
   : example dup if 1+ then ; ( 0 | x -- 0 | x+1 )
   4 example . ( prints '5' )
   4 example . ( prints '5' )
   0 example . ( prints '0' )
   0 example . ( prints '0' )
; ==== throw  ( ? n -- ?, R: ? -- ? : throw exception ) ========
; ==== throw  ( ? n -- ?, R: ? -- ? : throw exception ) ========
'throw' along with 'catch' are the Forth exception handling
'throw' along with 'catch' are the Forth exception handling
routines, 'throw' throws an exception if the number provided to
routines, 'throw' throws an exception if the number provided to
it is non-zero. An exception unwinds the return stack until
it is non-zero. An exception unwinds the return stack until
a 'catch' is encountered, the word 'quit' contains the exception
a 'catch' is encountered, the word 'quit' contains the exception
handler of last resort. Numbers from -255 to 0 are reserved for
handler of last resort. Numbers from -255 to 0 are reserved for
standard Forth errors.
standard Forth errors.
Usage:
Usage:
   : fail $1000 throw ;
   : fail $1000 throw ;
   : partially-executed cr ." Hello " fail ." World!" cr ;
   : partially-executed cr ." Hello " fail ." World!" cr ;
   : catches-throw ' partially-executed catch u. ;
   : catches-throw ' partially-executed catch u. ;
   catches-throw ( prints only 'Hello' then '1000' )
   catches-throw ( prints only 'Hello' then '1000' )
; ==== thru  ( k1 k2 -- : load from k1 to k2 ) =================
; ==== thru  ( k1 k2 -- : load from k1 to k2 ) =================
'thru' calls 'load' on a range of blocks 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
inclusively. It is used to evaluate a range of blocks and as
a convenient way to load software off of mass storage.
a convenient way to load software off of mass storage.
Code and data is stored in Forth blocks, 'thru' is used to load
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
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
of blocks, as the convention is to have the first line of the
block as a description.
block as a description.
Usage:
Usage:
   8 9 thru ( evaluate blocks 8 and 9 )
   8 9 thru ( evaluate blocks 8 and 9 )
; ==== timer  ( -- u : get value of timer ) ====================
; ==== timer  ( -- u : get value of timer ) ====================
'timer' retrieves the current value of the hardware time in the
'timer' retrieves the current value of the hardware time in the
FPGA, this peripheral can be controlled with the 'timer!' word,
FPGA, this peripheral can be controlled with the 'timer!' word,
which is used to control the timer.
which is used to control the timer.
; ==== timer!  ( -- : set timer ) ==============================
; ==== timer!  ( -- : set timer ) ==============================
'timer!' sets the hardware timer control register, allowing the
'timer!' sets the hardware timer control register, allowing the
timer to be enabled/stopped/reset and setting up the value at
timer to be enabled/stopped/reset and setting up the value at
which the timer wraps around at (or triggers an interrupt). The
which the timer wraps around at (or triggers an interrupt). The
layout of the timer control register is as follows:
layout of the timer control register is as follows:
  BIT  - MEANING
  BIT  - MEANING
  15   - Enable Timer (1 = enabled)
  15   - Enable Timer (1 = enabled)
  14   - Reset Timer
  14   - Reset Timer
  13   - Enable Interrupts
  13   - Enable Interrupts
  12-0 - Timer Compare Value
  12-0 - Timer Compare Value
The word 'timer' can be used to read in the current value of
The word 'timer' can be used to read in the current value of
the timer.
the timer.
; ==== tuck  ( n1 n2 -- n2 n1 n2 : tuck value ) ================
; ==== tuck  ( n1 n2 -- n2 n1 n2 : tuck value ) ================
'tuck' is a simple word that manipulates the stack, its stack
'tuck' is a simple word that manipulates the stack, its stack
comment describes what it does. It tucks a variable behind
comment describes what it does. It tucks a variable behind
the second most item on the stack.
the second most item on the stack.
Usage:
Usage:
   5 7  ( -- 5 7 : two example numbers are entered )
   5 7  ( -- 5 7 : two example numbers are entered )
   tuck ( 5 7 -- 7 5 7 : tuck does its job )
   tuck ( 5 7 -- 7 5 7 : tuck does its job )
; ==== type  ( b u -- : print out a string ) ===================
; ==== type  ( b u -- : print out a string ) ===================
'type' prints out a string, specified by an address 'b' and
'type' prints out a string, specified by an address 'b' and
a length 'u'. The output goes to the same place as 'emit'
a length 'u'. The output goes to the same place as 'emit'
does, which is usually an output device viewable by the
does, which is usually an output device viewable by the
programmer.
programmer.
The examples use the words '$"' and 'count' which should be
The examples use the words '$"' and 'count' which should be
consulted as well. '$"' compiles a string literal into the
consulted as well. '$"' compiles a string literal into the
dictionary as a counted string, 'count' converts this to
dictionary as a counted string, 'count' converts this to
an Address-Length pair needed by type.
an Address-Length pair needed by type.
Usage:
Usage:
   : hello cr $" Hello, World!" count type cr ;
   : hello cr $" Hello, World!" count type cr ;
   hello          ( execute newly defined word )
   hello          ( execute newly defined word )
   Hello, World!  ( it prints 'Hello, World! )
   Hello, World!  ( it prints 'Hello, World! )
; ==== u<  ( u1 u2 -- f: unsigned less than ) ==================
; ==== u<  ( u1 u2 -- f: unsigned less than ) ==================
Unsigned less than of two numbers.
Unsigned less than of two numbers.
; ==== u>  ( u1 u2 -- f: unsigned greater than ) ===============
; ==== u>  ( u1 u2 -- f: unsigned greater than ) ===============
Unsigned greater than, this is not an assembly instruction.
Unsigned greater than, this is not an assembly instruction.
; ==== u>=  ( u1 u2 -- f: unsigned greater or equal to ) =======
; ==== u>=  ( u1 u2 -- f: unsigned greater or equal to ) =======
Is 'u1' greater than or equal to 'u2', this is an unsigned
Is 'u1' greater than or equal to 'u2', this is an unsigned
operation.
operation.
; ==== u.  ( u -- : print out number in current base ) =========
; ==== u.  ( u -- : print out number in current base ) =========
'u.' prints out an unsigned number in the current output base,
'u.' prints out an unsigned number in the current output base,
this number uses the area at the end of the dictionary and
this number uses the area at the end of the dictionary and
the beginning of the PAD area as temporary storage.
the beginning of the PAD area as temporary storage.
; ==== um*  ( u u -- ud : unsigned multiply ) ==================
; ==== um*  ( u u -- ud : unsigned multiply ) ==================
Unsigned multiply, it takes two single cell numbers and returns
Unsigned multiply, it takes two single cell numbers and returns
an unsigned double cell number.
an unsigned double cell number.
; ==== um+  ( u u -- u carry : unsigned add with carry ) =======
; ==== um+  ( u u -- u carry : unsigned add with carry ) =======
Unsigned addition with carry, this word is used to implement
Unsigned addition with carry, this word is used to implement
the some of the arithmetic operations, although it is not
the some of the arithmetic operations, although it is not
very useful directly. 'um+' is used directly to implement 'um*'
very useful directly. 'um+' is used directly to implement 'um*'
which in turn is used to implement '*'.
which in turn is used to implement '*'.
; ==== um/mod  ( ud u -- ur uq : unsigned modulo divide ) ======
; ==== um/mod  ( ud u -- ur uq : unsigned modulo divide ) ======
Unsigned division of an unsigned double cell number by a single
Unsigned division of an unsigned double cell number by a single
cell number and leaves the remainder, 'ur' and the quotient,
cell number and leaves the remainder, 'ur' and the quotient,
'uq'. This is a slow operation as it is not implemented as an
'uq'. This is a slow operation as it is not implemented as an
instruction within the H2 CPU. It will throw and exception if
instruction within the H2 CPU. It will throw and exception if
the divisor is zero. The word is used to implement the other
the divisor is zero. The word is used to implement the other
division and modulus operations.
division and modulus operations.
; ==== until  ( -- : begin...until loop ) ======================
; ==== until  ( -- : begin...until loop ) ======================
'until' is a compile only word that should be used as part of
'until' is a compile only word that should be used as part of
a 'begin...until' loop within a word definition. It is a
a 'begin...until' loop within a word definition. It is a
conditional looping mechanism that pops and tests a value at
conditional looping mechanism that pops and tests a value at
run time, and jumps back to the corresponding 'begin' if the
run time, and jumps back to the corresponding 'begin' if the
value is zero, otherwise execution continues after the 'until'.
value is zero, otherwise execution continues after the 'until'.
Usage:
Usage:
  : invalid until ; ( <- invalid usage, no matching 'begin' )
  : invalid until ; ( <- invalid usage, no matching 'begin' )
  until  ( <- invalid usage, used outside a word definition )
  until  ( <- invalid usage, used outside a word definition )
  : test begin 1- dup . ?dup 0= until cr ." done " cr ;
  : test begin 1- dup . ?dup 0= until cr ." done " cr ;
  3 test 2 1 0 ( '3 test' prints '2 1 0' )
  3 test 2 1 0 ( '3 test' prints '2 1 0' )
  done         ( and also prints 'done' )
  done         ( and also prints 'done' )
; ==== update  ( -- : mark last loaded block as dirty ) ========
; ==== update  ( -- : mark last loaded block as dirty ) ========
Marks the last loaded block as being dirty (the last loaded
Marks the last loaded block as being dirty (the last loaded
block block number is stored in the variable 'blk'). A dirty
block block number is stored in the variable 'blk'). A dirty
block will be written to disk on when 'flush', 'save-buffers',
block will be written to disk on when 'flush', 'save-buffers',
or another block is loaded from disk.
or another block is loaded from disk.
Usage:
Usage:
   5 block      ( block '5' loaded, block address returned )
   5 block      ( block '5' loaded, block address returned )
   swap 99 !    ( store '99' in block buffer )
   swap 99 !    ( store '99' in block buffer )
   update       ( mark block as dirty )
   update       ( mark block as dirty )
   save-buffers ( write out block buffer back to block '5' )
   save-buffers ( write out block buffer back to block '5' )
   ( block '5' now contains '99' in its first byte, which has )
   ( block '5' now contains '99' in its first byte, which has )
   ( been saved to disk )
   ( been saved to disk )
; ==== u.r  ( u +n -- : print u right justified by +n ) ========
; ==== u.r  ( u +n -- : print u right justified by +n ) ========
'u.r' is a general purpose numeric formatting word, it prints
'u.r' is a general purpose numeric formatting word, it prints
out the number 'u' as an unsigned number in the current output
out the number 'u' as an unsigned number in the current output
radix, preceded by '+n' spaces, minus the number of spaces
radix, preceded by '+n' spaces, minus the number of spaces
needed to display 'u' in the current output radix, or right
needed to display 'u' in the current output radix, or right
aligned. This function uses the area between the end of the
aligned. This function uses the area between the end of the
dictionary and the beginning of the PAD area as temporary
dictionary and the beginning of the PAD area as temporary
storage.
storage.
Usage:
Usage:
  Typed   | <- Result -> |
  Typed   | <- Result -> |
  4 6 u.r     4 ok
  4 6 u.r     4 ok
  99 6 u.r    99 ok
  99 6 u.r    99 ok
  99 5 u.r   99 ok
  99 5 u.r   99 ok
; ==== variable  ( -- ;  : create a new variable ) =====
; ==== variable  ( -- ;  : create a new variable ) =====
'variable' parses the next space delimited string from the
'variable' parses the next space delimited string from the
input string and makes a new named variable. The variable will
input string and makes a new named variable. The variable will
be initialized with zero, although this is not guaranteed to be
be initialized with zero, although this is not guaranteed to be
the case with all Forths. Variables are just normal words that
the case with all Forths. Variables are just normal words that
push a location onto the dictionary of where the variable is
push a location onto the dictionary of where the variable is
stored, it can be accessed with the '!' and '@' words, only
stored, it can be accessed with the '!' and '@' words, only
one cell of storage space is reserved. The created word is
one cell of storage space is reserved. The created word is
not an immediate word.
not an immediate word.
; ==== ver  ( -- u : push version information ) ================
; ==== ver  ( -- u : push version information ) ================
Pushes the version number of the eForth implementation. The
Pushes the version number of the eForth implementation. The
format of the version is the major version is stored in the
format of the version is the major version is stored in the
upper byte and the minor version information is stored in the
upper byte and the minor version information is stored in the
lower byte.
lower byte.
The minor version number changes on minor updates, the major
The minor version number changes on minor updates, the major
version changes when there are major updates in how the
version changes when there are major updates in how the
interpreter works that could potentially break code.
interpreter works that could potentially break code.
; ==== while  ( -- : begin...while...repeat loop ) =============
; ==== while  ( -- : begin...while...repeat loop ) =============
; ==== within  ( u hi lo -- f : is u within a range? ) =========
; ==== within  ( u hi lo -- f : is u within a range? ) =========
'within' is used to test with a value is within a range
'within' is used to test with a value is within a range
specified with a maximum and minimum value.
specified with a maximum and minimum value.
; ==== word  ( c -- a;  : parse a word ) ===============
; ==== word  ( c -- a;  : parse a word ) ===============
'word' parses the next word in the input stream and returns an
'word' parses the next word in the input stream and returns an
address to a counted string. 'counted strings' have their first
address to a counted string. 'counted strings' have their first
byte as their string length, which can be extracted with the
byte as their string length, which can be extracted with the
word 'count'. The delimiter is given as 'c', a special case
word 'count'. The delimiter is given as 'c', a special case
exists when 'c' is a space, as all characters up to the ASCII
exists when 'c' is a space, as all characters up to the ASCII
space are treated as delimiters.
space are treated as delimiters.
; ==== words  ( -- : list all words in dictionary ) ============
; ==== words  ( -- : list all words in dictionary ) ============
This lists all of the words in the dictionary that are on the
This lists all of the words in the dictionary that are on the
current search order. Each vocabulary is listed with the address
current search order. Each vocabulary is listed with the address
of that vocabulary as a prefix.
of that vocabulary as a prefix.
; ==== xor  ( u1 u2 -- u : bit wise exclusive or ) =============
; ==== xor  ( u1 u2 -- u : bit wise exclusive or ) =============
Bitwise exclusive or of two numbers, there is nothing more
Bitwise exclusive or of two numbers, there is nothing more
to this function than that.
to this function than that.
; ==============================================================
; ==============================================================
; ==== ASCII Character Table ===================================
; ==== ASCII Character Table ===================================
The following section presents a database of all of the ASCII
The following section presents a database of all of the ASCII
characters, from 0 through to 127 inclusive. The format of the
characters, from 0 through to 127 inclusive. The format of the
database is; decimal, octal, hex then binary value, character
database is; decimal, octal, hex then binary value, character
(or name) and finally a column with a short description.
(or name) and finally a column with a short description.
Columns are separated by spaces. There is one entry per line,
Columns are separated by spaces. There is one entry per line,
with the first line of each block containing an index entry
with the first line of each block containing an index entry
instead of an ASCII character description.
instead of an ASCII character description.
; ==== ASCII: NUL (0) to SO (14) ===============================
; ==== ASCII: NUL (0) to SO (14) ===============================
  0 000 00 00000000 NUL    Null char
  0 000 00 00000000 NUL    Null char
  1 001 01 00000001 SOH    Start of Heading
  1 001 01 00000001 SOH    Start of Heading
  2 002 02 00000010 STX    Start of Text
  2 002 02 00000010 STX    Start of Text
  3 003 03 00000011 ETX    End of Text
  3 003 03 00000011 ETX    End of Text
  4 004 04 00000100 EOT    End of Transmission
  4 004 04 00000100 EOT    End of Transmission
  5 005 05 00000101 ENQ    Enquiry
  5 005 05 00000101 ENQ    Enquiry
  6 006 06 00000110 ACK    Acknowledgment
  6 006 06 00000110 ACK    Acknowledgment
  7 007 07 00000111 BEL    Bell
  7 007 07 00000111 BEL    Bell
  8 010 08 00001000 BS     Back Space
  8 010 08 00001000 BS     Back Space
  9 011 09 00001001 HT     Horizontal Tab
  9 011 09 00001001 HT     Horizontal Tab
 10 012 0A 00001010 LF     Line Feed
 10 012 0A 00001010 LF     Line Feed
 11 013 0B 00001011 VT     Vertical Tab
 11 013 0B 00001011 VT     Vertical Tab
 12 014 0C 00001100 FF     Form Feed
 12 014 0C 00001100 FF     Form Feed
 13 015 0D 00001101 CR     Carriage Return
 13 015 0D 00001101 CR     Carriage Return
 14 016 0E 00001110 SO     Shift Out / X-On
 14 016 0E 00001110 SO     Shift Out / X-On
; ==== ASCII: SI (15) to GS (29) ===============================
; ==== ASCII: SI (15) to GS (29) ===============================
 15 017 0F 00001111 SI     Shift In / X-Off
 15 017 0F 00001111 SI     Shift In / X-Off
 16 020 10 00010000 DLE    Data Line Escape
 16 020 10 00010000 DLE    Data Line Escape
 17 021 11 00010001 DC1    Device Control 1 (oft. XON)
 17 021 11 00010001 DC1    Device Control 1 (oft. XON)
 18 022 12 00010010 DC2    Device Control 2
 18 022 12 00010010 DC2    Device Control 2
 19 023 13 00010011 DC3    Device Control 3 (oft. XOFF)
 19 023 13 00010011 DC3    Device Control 3 (oft. XOFF)
 20 024 14 00010100 DC4    Device Control 4
 20 024 14 00010100 DC4    Device Control 4
 21 025 15 00010101 NAK    Negative Acknowledgement
 21 025 15 00010101 NAK    Negative Acknowledgement
 22 026 16 00010110 SYN    Synchronous Idle
 22 026 16 00010110 SYN    Synchronous Idle
 23 027 17 00010111 ETB    End of Transmit Block
 23 027 17 00010111 ETB    End of Transmit Block
 24 030 18 00011000 CAN    Cancel
 24 030 18 00011000 CAN    Cancel
 25 031 19 00011001 EM     End of Medium
 25 031 19 00011001 EM     End of Medium
 26 032 1A 00011010 SUB    Substitute
 26 032 1A 00011010 SUB    Substitute
 27 033 1B 00011011 ESC    Escape
 27 033 1B 00011011 ESC    Escape
 28 034 1C 00011100 FS     File Separator
 28 034 1C 00011100 FS     File Separator
 29 035 1D 00011101 GS     Group Separator
 29 035 1D 00011101 GS     Group Separator
; ==== ASCII: RS (30) to Comma (44) ============================
; ==== ASCII: RS (30) to Comma (44) ============================
 30 036 1E 00011110 RS     Record Separator
 30 036 1E 00011110 RS     Record Separator
 31 037 1F 00011111 US     Unit Separator
 31 037 1F 00011111 US     Unit Separator
 32 040 20 00100000 SPACE  Space
 32 040 20 00100000 SPACE  Space
 33 041 21 00100001 !      Exclamation mark
 33 041 21 00100001 !      Exclamation mark
 34 042 22 00100010 "      Double quotes (or speech marks)
 34 042 22 00100010 "      Double quotes (or speech marks)
 35 043 23 00100011 #      Number
 35 043 23 00100011 #      Number
 36 044 24 00100100 $      Dollar
 36 044 24 00100100 $      Dollar
 37 045 25 00100101 %      Procenttecken
 37 045 25 00100101 %      Procenttecken
 38 046 26 00100110 &      Ampersand
 38 046 26 00100110 &      Ampersand
 39 047 27 00100111 '      Single quote
 39 047 27 00100111 '      Single quote
 40 050 28 00101000 (      Open parenthesis (or open bracket)
 40 050 28 00101000 (      Open parenthesis (or open bracket)
 41 051 29 00101001 )      Close parenthesis (or close bracket)
 41 051 29 00101001 )      Close parenthesis (or close bracket)
 42 052 2A 00101010 *      Asterisk
 42 052 2A 00101010 *      Asterisk
 43 053 2B 00101011 +      Plus
 43 053 2B 00101011 +      Plus
 44 054 2C 00101100 ,      Comma
 44 054 2C 00101100 ,      Comma
; ==== ASCII: Hyphen (45) to Semicolon (59) ====================
; ==== ASCII: Hyphen (45) to Semicolon (59) ====================
 45 055 2D 00101101 -      Hyphen
 45 055 2D 00101101 -      Hyphen
 46 056 2E 00101110 .      Period, dot or full stop
 46 056 2E 00101110 .      Period, dot or full stop
 47 057 2F 00101111 /      Slash or divide
 47 057 2F 00101111 /      Slash or divide
 48 060 30 00110000 0      Zero
 48 060 30 00110000 0      Zero
 49 061 31 00110001 1      One
 49 061 31 00110001 1      One
 50 062 32 00110010 2      Two
 50 062 32 00110010 2      Two
 51 063 33 00110011 3      Three
 51 063 33 00110011 3      Three
 52 064 34 00110100 4      Four
 52 064 34 00110100 4      Four
 53 065 35 00110101 5      Five
 53 065 35 00110101 5      Five
 54 066 36 00110110 6      Six
 54 066 36 00110110 6      Six
 55 067 37 00110111 7      Seven
 55 067 37 00110111 7      Seven
 56 070 38 00111000 8      Eight
 56 070 38 00111000 8      Eight
 57 071 39 00111001 9      Nine
 57 071 39 00111001 9      Nine
 58 072 3A 00111010 :      Colon
 58 072 3A 00111010 :      Colon
 59 073 3B 00111011 ;      Semicolon
 59 073 3B 00111011 ;      Semicolon
; ==== ASCII: Less than (60) to Uppercase J (74) ===============
; ==== ASCII: Less than (60) to Uppercase J (74) ===============
 60 074 3C 00111100 <      Less than
 60 074 3C 00111100 <      Less than
 61 075 3D 00111101 =      Equals
 61 075 3D 00111101 =      Equals
 62 076 3E 00111110 >      Greater than
 62 076 3E 00111110 >      Greater than
 63 077 3F 00111111 ?      Question mark
 63 077 3F 00111111 ?      Question mark
 64 100 40 01000000 @      At symbol
 64 100 40 01000000 @      At symbol
 65 101 41 01000001 A      Uppercase A
 65 101 41 01000001 A      Uppercase A
 66 102 42 01000010 B      Uppercase B
 66 102 42 01000010 B      Uppercase B
 67 103 43 01000011 C      Uppercase C
 67 103 43 01000011 C      Uppercase C
 68 104 44 01000100 D      Uppercase D
 68 104 44 01000100 D      Uppercase D
 69 105 45 01000101 E      Uppercase E
 69 105 45 01000101 E      Uppercase E
 70 106 46 01000110 F      Uppercase F
 70 106 46 01000110 F      Uppercase F
 71 107 47 01000111 G      Uppercase G
 71 107 47 01000111 G      Uppercase G
 72 110 48 01001000 H      Uppercase H
 72 110 48 01001000 H      Uppercase H
 73 111 49 01001001 I      Uppercase I
 73 111 49 01001001 I      Uppercase I
 74 112 4A 01001010 J      Uppercase J
 74 112 4A 01001010 J      Uppercase J
; ==== ASCII: Uppercase K (75) to Uppercase Y (89) =============
; ==== ASCII: Uppercase K (75) to Uppercase Y (89) =============
 75 113 4B 01001011 K      Uppercase K
 75 113 4B 01001011 K      Uppercase K
 76 114 4C 01001100 L      Uppercase L
 76 114 4C 01001100 L      Uppercase L
 77 115 4D 01001101 M      Uppercase M
 77 115 4D 01001101 M      Uppercase M
 78 116 4E 01001110 N      Uppercase N
 78 116 4E 01001110 N      Uppercase N
 79 117 4F 01001111 O      Uppercase O
 79 117 4F 01001111 O      Uppercase O
 80 120 50 01010000 P      Uppercase P
 80 120 50 01010000 P      Uppercase P
 81 121 51 01010001 Q      Uppercase Q
 81 121 51 01010001 Q      Uppercase Q
 82 122 52 01010010 R      Uppercase R
 82 122 52 01010010 R      Uppercase R
 83 123 53 01010011 S      Uppercase S
 83 123 53 01010011 S      Uppercase S
 84 124 54 01010100 T      Uppercase T
 84 124 54 01010100 T      Uppercase T
 85 125 55 01010101 U      Uppercase U
 85 125 55 01010101 U      Uppercase U
 86 126 56 01010110 V      Uppercase V
 86 126 56 01010110 V      Uppercase V
 87 127 57 01010111 W      Uppercase W
 87 127 57 01010111 W      Uppercase W
 88 130 58 01011000 X      Uppercase X
 88 130 58 01011000 X      Uppercase X
 89 131 59 01011001 Y      Uppercase Y
 89 131 59 01011001 Y      Uppercase Y
; ==== ASCII: Uppercase Z (90) to Lowercase h (104) ============
; ==== ASCII: Uppercase Z (90) to Lowercase h (104) ============
 90 132 5A 01011010 Z      Uppercase Z
 90 132 5A 01011010 Z      Uppercase Z
 91 133 5B 01011011 [      Opening bracket
 91 133 5B 01011011 [      Opening bracket
 92 134 5C 01011100 \      Backslash
 92 134 5C 01011100 \      Backslash
 93 135 5D 01011101 ]      Closing bracket
 93 135 5D 01011101 ]      Closing bracket
 94 136 5E 01011110 ^      Caret - circumflex
 94 136 5E 01011110 ^      Caret - circumflex
 95 137 5F 01011111 _      Underscore
 95 137 5F 01011111 _      Underscore
 96 140 60 01100000 `      Grave accent
 96 140 60 01100000 `      Grave accent
 97 141 61 01100001 a      Lowercase a
 97 141 61 01100001 a      Lowercase a
 98 142 62 01100010 b      Lowercase b
 98 142 62 01100010 b      Lowercase b
 99 143 63 01100011 c      Lowercase c
 99 143 63 01100011 c      Lowercase c
100 144 64 01100100 d      Lowercase d
100 144 64 01100100 d      Lowercase d
101 145 65 01100101 e      Lowercase e
101 145 65 01100101 e      Lowercase e
102 146 66 01100110 f      Lowercase f
102 146 66 01100110 f      Lowercase f
103 147 67 01100111 g      Lowercase g
103 147 67 01100111 g      Lowercase g
104 150 68 01101000 h      Lowercase h
104 150 68 01101000 h      Lowercase h
; ==== ASCII: Lowercase i (105) to Lowercase w (119) ===========
; ==== ASCII: Lowercase i (105) to Lowercase w (119) ===========
105 151 69 01101001 i      Lowercase i
105 151 69 01101001 i      Lowercase i
106 152 6A 01101010 j      Lowercase j
106 152 6A 01101010 j      Lowercase j
107 153 6B 01101011 k      Lowercase k
107 153 6B 01101011 k      Lowercase k
108 154 6C 01101100 l      Lowercase l
108 154 6C 01101100 l      Lowercase l
109 155 6D 01101101 m      Lowercase m
109 155 6D 01101101 m      Lowercase m
110 156 6E 01101110 n      Lowercase n
110 156 6E 01101110 n      Lowercase n
111 157 6F 01101111 o      Lowercase o
111 157 6F 01101111 o      Lowercase o
112 160 70 01110000 p      Lowercase p
112 160 70 01110000 p      Lowercase p
113 161 71 01110001 q      Lowercase q
113 161 71 01110001 q      Lowercase q
114 162 72 01110010 r      Lowercase r
114 162 72 01110010 r      Lowercase r
115 163 73 01110011 s      Lowercase s
115 163 73 01110011 s      Lowercase s
116 164 74 01110100 t      Lowercase t
116 164 74 01110100 t      Lowercase t
117 165 75 01110101 u      Lowercase u
117 165 75 01110101 u      Lowercase u
118 166 76 01110110 v      Lowercase v
118 166 76 01110110 v      Lowercase v
119 167 77 01110111 w      Lowercase w
119 167 77 01110111 w      Lowercase w
; ==== ASCII: Lowercase x (120) to DEL (127) ===================
; ==== ASCII: Lowercase x (120) to DEL (127) ===================
120 170 78 01111000 x      Lowercase x
120 170 78 01111000 x      Lowercase x
121 171 79 01111001 y      Lowercase y
121 171 79 01111001 y      Lowercase y
122 172 7A 01111010 z      Lowercase z
122 172 7A 01111010 z      Lowercase z
123 173 7B 01111011 {      Opening brace
123 173 7B 01111011 {      Opening brace
124 174 7C 01111100 |      Vertical bar
124 174 7C 01111100 |      Vertical bar
125 175 7D 01111101 }      Closing brace
125 175 7D 01111101 }      Closing brace
126 176 7E 01111110 ~      Equivalency sign - tilde
126 176 7E 01111110 ~      Equivalency sign - tilde
127 177 7F 01111111 DEL    Delete
127 177 7F 01111111 DEL    Delete
 
 
 
 
 
 
 
 
 
 
 
 
 
 
; ==============================================================
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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