Line 205... |
Line 205... |
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 ( --; , )
|
Line 240... |
Line 240... |
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 )
|
Line 297... |
Line 297... |
: <=> 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
|
Line 336... |
Line 336... |
|
|
\ ==== 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 ;
|
|
|
|
|
|
|
|
|
Line 370... |
Line 370... |
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 -- )
|
Line 383... |
Line 383... |
|
|
|
|
\ ==== 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.
|
Line 508... |
Line 508... |
: 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
|
Line 784... |
Line 1088... |
? ( 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.
|
Line 816... |
Line 1120... |
|
|
; ==== 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 )
|
Line 1757... |
Line 2061... |
|
|
|
|
|
|
|
|
; ==== 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.
|
|
|
|
|
|
|
|
|
|
|
Line 1789... |
Line 2093... |
|
|
|
|
|
|
|
|
; ==== 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.
|
|
|
|
|
|
|
|
|
|
|
Line 1837... |
Line 2141... |
|
|
|
|
|
|
|
|
; ==== 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.
|
|
|
|
|
|
|
|
|
|
|
Line 1853... |
Line 2157... |
|
|
|
|
|
|
|
|
; ==== 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.
|
|
|
|
|
|
|
|
|
|
|
Line 1997... |
Line 2301... |
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.
|
Line 2045... |
Line 2349... |
|
|
|
|
|
|
|
|
; ==== 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 ) ==================
|
Line 2093... |
Line 2397... |
$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.
|
|
|
|
|
|
|
|
|
|
|
Line 2157... |
Line 2461... |
|
|
|
|
|
|
|
|
; ==== 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.
|
|
|
|
|
|
|
|
|
|
|
Line 2168... |
Line 2476... |
|
|
|
|
|
|
|
|
|
|
|
; ==== 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
|
Line 2205... |
Line 2509... |
: 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).
|
|
|
|
|
|
|
|
|
|
|
Line 3580... |
Line 3884... |
: 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 ) ============
|
|
|
|
|
|
|
|
|
Line 4826... |
Line 5114... |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
; ==============================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|