\ ==== 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ==============================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|