URL
https://opencores.org/ocsvn/forth-cpu/forth-cpu/trunk
Subversion Repositories forth-cpu
[/] [forth-cpu/] [trunk/] [nvram.txt] - Rev 5
Compare with Previous | Blame | View Log
\ ==== Boot Block ==============================================-1 loaded !; ==== Short Help ==============================================This is a subroutine threaded Forth, based on eForth. Thestarting base in in hexadecimal. A tutorial, word glossary andextra code is stored in block storage. A short list of commandsfollows ('#' are numbers):words list all Forth wordssee decompile the next word in the input stream# #2 index get descriptive titles for blocks from '#' to '#2'# list list block number '#'# load execute code in block '#'# #2 thru execute code in blocks '#' to '#2'; ==== Forth Error Messages: 1/4 ===============================-1 ABORT-2 ABORT"-3 stack overflow-4 stack underflow-5 return stack overflow-6 return stack underflow-7 do-loops nested too deeply during execution-8 dictionary overflow-9 invalid memory address-10 division by zero-11 result out of range-12 argument type mismatch-13 undefined word-14 interpreting a compile-only word-15 invalid FORGET; ==== Forth Error Messages: 2/4 ===============================-16 attempt to use zero-length string as a name-17 pictured numeric output string overflow-18 parsed string overflow-19 definition name too long-20 write to a read-only location-21 unsupported operation-22 control structure mismatch-23 address alignment exception-24 invalid numeric argument-25 return stack imbalance-26 loop parameters unavailable-27 invalid recursion-28 user interrupt-29 compiler nesting-30 obsolescent feature; ==== Forth Error Messages: 3/4 ===============================-31 >BODY used on non-CREATEd definition-32 invalid name argument (e.g., TO xxx)-33 block read exception-34 block write exception-35 invalid block number-36 invalid file position-37 file I/O exception-38 non-existent file-39 unexpected end of file-40 invalid BASE for floating point conversion-41 loss of precision-42 floating-point divide by zero-43 floating-point result out of range-44 floating-point stack overflow-45 floating-point stack underflow; ==== Forth Error Messages: 4/4 ===============================-46 floating-point invalid argument-47 compilation word list deleted-48 invalid POSTPONE-49 search-order overflow-50 search-order underflow-51 compilation word list changed-52 control-flow stack overflow-53 exception stack overflow-54 floating-point underflow-55 floating-point unidentified fault-56 QUIT-57 exception in sending or receiving a character-58 [IF], [ELSE], or [THEN] exception; ==== Description of this file ================================The next screens contain extra code that can be loaded into theinterpreter if needed. Some of the standard Forth words areplaced here instead of in the image to save on space.The blocks should be loaded in order unless otherwise stated.This file is first converted by a utility into a fixed widthformat, which can then be loaded onto the target board withthe same utility used to uploaded the bitfile to the FPGA.Line lengths are limited to 64 characters wide, each blockcontains 16 lines. The first line should contain adescription of the block so that when it is displayed with'index' a glossary can be viewed, allowing quick navigation.; ==== Scratch Block ===========================================\ ==== Block Editor 1/2 ========================================( Block Editor: There is a help section later on )variable editor-voc 0 editor-voc ! forth: editor decimal editor-voc 1 set-order ;get-order editor-voc swap 1+ set-order$40 constant c/l $10 constant l/b: (block) blk @ block ;: (check) dup b/buf c/l / u>= if -24 throw then ;: (line) (check) c/l * (block) + ;: b block drop ;: l blk @ list ;: n 1 +block b l ;: p -1 +block b l ;: d (line) c/l blank ;: x (block) b/buf blank ;: s update save-buffers ;\ ==== Block Editor 2/2 ========================================: q forth save-buffers ;: e forth blk @ load editor ;: ia c/l * + (block) + source drop >in @ +swap source nip >in @ - cmove [compile] \ ;: i 0 swap ia ;: u update ;: w words ;: yank pad c/l ;: c (line) yank >r swap r> cmove ;: y (line) yank cmove ;: ct swap y c ;: ea (line) c/l evaluate ;: sw 2dup y (line) swap (line) swap c/l cmove c ;forth\ ==== Assembler word set ======================================variable assembler-vocbl parse rdrop pad pack$ find drop assembler-voc !: assembler assembler-voc 1 set-order ;: ;code assembler ; immediate: code [compile] : assembler ;get-order assembler-voc swap 1+ set-order: end-code forth [compile] ; ; immediate: words words ;: forth forth ;forth\ ==== CORDIC 1/2 ==============================================variable lookup -1 cells allot ( 16 values )$3243 , $1DAC , $0FAD , $07F5 , $03FE , $01FF , $00FF , $007F ,$003F , $001F , $000F , $0007 , $0003 , $0001 , $0000 , $0000 ,: arshift ( n u -- n : arithmetic right shift )2dup rshift >r swap $8000 andif $10 swap - -1 swap lshift else drop 0 then r> or ;$26DD constant cordic_1K $6487 constant pi/2variable tx 0 tx ! variable ty 0 ty ! variable tz 0 tz !variable x 0 x ! variable y 0 y ! variable z 0 z !variable d 0 d ! variable k 0 k !\ ==== CORDIC 2/2 ==============================================( CORDIC: valid in range -pi/2 to pi/2, arguments are in fixed )( point format with 1 = 16384, angle is given in radians. ): cordic ( angle -- sine cosine )z ! cordic_1K x ! 0 y ! 0 k !$10 begin ?dup whilez @ 0< d !x @ y @ k @ arshift d @ xor d @ - - tx !y @ x @ k @ arshift d @ xor d @ - + ty !z @ k @ cells lookup + @ d @ xor d @ - - tz !tx @ x ! ty @ y ! tz @ z !k 1+!1-repeat y @ x @ ;: sin cordic drop ;: cos cordic nip ;\ ==== Login Code 1/2 ==========================================\ Login and user management system: generate count dup >r crc r> ccitt ; ( b -- u ): .user ." user>" space ; ( -- ): .password ." password>" space ; ( -- )variable user0 0 user0 !: mk.user ( --; <string1>, <string2> )here user0 @ , user0 ! here 0 , bl word count 1+ allot aligndrop bl word generate swap ! ;: ls.user ( -- : list all users in user database )cr user0 @begin dup while dup 2 cells + space count type cr @ repeatdrop cr ;: find.user ( a -- u | 0 : find user in database, return hash )>r user0 @ begin dup while dup 2 cells + count r@ count=string if rdrop exit then @ repeat rdrop drop 0 ;\ ==== Login Code 2/2 ==========================================: (password) ( u --, <string> )>r begin .password query bl word cr generater@ = until rdrop ;: fake .password query bl word drop cr ;: (user)begin .user query bl word cr find.user ?dup until ;: retry ( xt -- : retry word until it succeeds )>r begin r@ catch 0= until rdrop ;: user? ' (user) retry ;: password? ' (password) retry ;: hide-all 0 1 set-order ;: login hide-allcr user? cell+ @ conceal password? interactive forth ;mk.user guest guest mk.user archer dangerzonemk.user lana sterling mk.user cyril figgis\ ==== Extra Code 1/7 ==========================================: 2+ 2 + ; ( n -- n ): 2- 2 - ; ( n -- n ): >= < invert ; ( n n -- f ): simulation? cpu-id $0666 <> ; ( -- f : are we in the matrix? ): 0<= 0> 0= ; ( n n -- f ): 0>= 0< 0= ; ( n n -- f ): not -1 xor ; ( n -- n ): dabs dup 0< if dnegate then ; ( d -- d ): d+ >r swap >r um+ r> r> + + ; ( d d -- d ): d= >r swap r> = >r = r> and ; ( d d -- f ): d<> d= 0= ; ( d d -- f ): roll dup 0> if swap >r 1- recurse r> swap else drop then ;: ?exit if rdrop then ; ( n --, R: n -- n | ): 2rdrop r> rdrop rdrop >r ; ( R n n -- ): 2. swap . . ; ( n n -- )\ ==== Extra Code 2/7 ==========================================: m* 2dup xor 0< >r abs swap abs um* r> if dnegate then ;: */mod >r m* r> m/mod ; ( n n n -- r q ): */ */mod nip ; ( n n n -- q ): s>d dup 0< ; ( n -- d : single to double ): holds begin dup while 1- 2dup + c@ hold repeat 2drop ;: binary 2 base ! ; ( -- ): octal 8 base ! ; ( -- ): .base base @ dup decimal base ! ; ( -- ): only -1 set-order ;: also get-order over swap 1+ set-order ;: previous get-order swap drop 1- set-order ;: buffer block ; ( k -- a ): bye [ 0 , ] ;: enum dup constant 1+ ; ( n --, <string> ): logical 0= 0= ; ( n -- f )\ ==== Extra Code 3/7 ==========================================: square dup * ; ( n -- ): limit rot min max ; ( n lo hi -- n ): odd 1 and logical ; ( n -- ): even odd invert ; ( n -- ): nor or invert ; ( u u -- u ): nand and invert ; ( u u -- u ): bell 7 emit ; ( -- ): under >r dup r> ; ( n1 n2 -- n1 n1 n2 ): 2nip >r >r 2drop r> r> ; ( n1 n2 n3 n4 -- n3 n4 )( n1 n2 n3 n4 -- n1 n2 n3 n4 n1 n2 ): 2over >r >r 2dup r> swap >r swap r> r> -rot ;: 2swap >r -rot r> -rot ; ( n1 n2 n3 n4 -- n3 n4 n1 n2 ): 2tuck 2swap 2over ; ( n1 n2 n3 n4 -- n3 n4 n1 n2 n3 n4 ): 4drop 2drop 2drop ; ( n1 n2 n3 n4 -- ): trip dup dup ; ( n -- n n n )\ ==== Extra Code 4/7 ==========================================: log >r 0 swap ( u base -- u )begin swap 1+ swap r@ / dup 0= untildrop 1- rdrop ;: log2 0 swap ( u -- u )begin swap 1+ swap 2/ dup 0= untildrop 1- ;: average um+ 2 um/mod nip ; ( u u -- u ): <=> 2dup > if 2drop -1 exit then < ;: bounds over + swap ;: 2, , , ; ( n n -- ): tab 9 emit ; ( -- ): drup drop dup ; ( n1 n2 -- n1 n1 ): lsb $FF and ; ( u -- u ): --> 1 +block load ;: scr blk ;\ ==== Extra Code 5/7 ==========================================: signum ( n -- -1 | 0 | 1 : Signum function )dup 0> if drop 1 exit then0< if -1 exit then0 ;: >< dup 8 rshift swap 8 lshift or ; ( u -- u : swap bytes ): #digits dup 0= if 1+ exit then base @ log 1+ ;: ** ( n u -- n )?dup ifover >rbegindup 1 >whileswap r@ * swap 1-repeat rdrop dropelse logical 1 and then ;\ ==== Extra Code 6/7 ==========================================: b. base @ swap 2 base ! u. base ! ; ( u -- ): h. base @ swap hex u. base ! ; ( u -- ): o. base @ swap 8 base ! u. base ! ; ( u -- ): d. base @ swap decimal . base ! ; ( n -- ): @bits swap @ and ; ( a u -- u ): ?\ if [compile] \ then ; immediate: ?( if [compile] ( then ; immediate ( ): defined? ( -- pwd -1 | 0, <string> : is word defined? )bl word find if -1 else drop 0 then ;: ?if compile dup [compile] if ; immediate: ?dup-if compile ?dup [compile] if ; immediate: >body ( dup @ $4000 or <> if 31 -throw then ) cell+ ;\ ==== Extra Code 7/7 ==========================================: screens ( k1 k2 -- : list blocks k1 to k2 )over -fordup . dup list 1+ key $D = if rdrop drop exit thennext drop ;\ ==== Roulette ================================================\ Russian Roulette: It would be interesting to do something\ killed the computer when the player dies: click ." *click*" cr ;: bang ." BANG!" cr ;: roulette random 6 mod if click else bang then ; ( -- )\ ==== Extended ANSI Escape Codes ==============================0 constant black 1 constant red 2 constant green 4 constant bluered green + constant yellowgreen blue + constant cyanred blue + constant magentared green blue + + constant white: background $A + ;: color $1E + sgr ;\ : hide-cursor CSI [char] ? emit $19 10u. [char] l emit ;\ : show-cursor CSI [char] ? emit $19 10u. [char] h emit ;: up [char] A ansi ; ( n -- ): down [char] B ansi ; ( n -- ): left [char] C ansi ; ( n -- ): right [char] D ansi ; ( n -- )\ ==== Screen Saver ============================================\ An incredibly simple screen saver using ANSI Escape codes\ for placement and coloring of random charactersbase @ decimal: screen-saver ( -- )pagebeginrandom 79 modrandom 38 mod at-xyrandom >char emitrandom 8 modrandom 1 and if background thenrandom 256 and ms coloragain ;base !; ==== Game: YOU ARE DEAD (HELP) ===============================This is a clone of the one dimensional rogue like gameavailable at <https://github.com/rupa/YOU_ARE_DEAD>. Theobject is to get to the other side of the screen.Keys:w Turn into '.'a Turn into '~'s Turn into '>'d Move rightq QuitBlock number 7 is used to store the game state.\ ==== Game: YOU ARE DEAD 1/6 ==================================forth variable yad-voc get-order yad-voc swap 1+ set-order$40 constant c/l $10 constant l/b: memory 7 block ;: variables memory c/l + ;: score variables 0 cells + ;: position variables 1 cells + ;: level variables 2 cells + ;: form variables 3 cells + ;: continue variables 4 cells + ;: end c/l 1- ;: player form @ ;: .player position @ 1+ 3 at-xy player emit ;: .goal c/l 3 at-xy [char] # emit ;: .score ." SCORE: " score @ 5 u.r ;: .level ." LEVEL: " level @ 5 u.r ;\ ==== Game: YOU ARE DEAD 2/6 ==================================: showpage cr cr space memory c/l type.player .goalcr .score space .level cr ;: select ( n -- c )dup 0= if drop [char] < exit thendup 1 = if drop [char] ~ exit thendup 2 = if drop [char] . exit thendrop bl ;: die ." YOU ARE DEAD" cr 0 continue ! -56 throw ;: survived ." YOU SURVIVED" cr .score cr ;: forms form c@ position @ memory + c@ ; ( -- c c )\ ==== Game: YOU ARE DEAD 3/6 ==================================: generate ( -- generate a level )c/l 1- forrandom 5 mod ( 3 = most difficult )select memory r@ + c!nextbl memory c! bl memory end + c! ;: normal [char] x ;: setup ( -- )-1 continue !memory b/buf 0 fillnormal form c!generate ;: +score random 4 mod 1 min score +! ; ( -- ): ?next <> if die else +score then ; ( c c -- )\ ==== Game: YOU ARE DEAD 4/6 ==================================: +level0 position ! level 1+!random 23 mod 5 min score +!generate ;: monster swap >r forms r> = if ?next else 2drop then ;: command ( -- f )dup [char] w = if drop [char] . form c! 0 exit thendup [char] a = if drop [char] ~ form c! 0 exit thendup [char] d = if drop -1 exit thendup [char] s = if drop [char] < form c! 0 exit thendup [char] q = if drop -56 throw thendrop 0 ;\ ==== Game: YOU ARE DEAD 5/6 ==================================: rulesposition @ end = if +level exit thenforms = if exit then[char] ~ [char] < monster[char] . [char] ~ monster[char] < [char] . monsternormal form c!bl position @ memory + c!score 1+!position 1+! ;\ ==== Game: YOU ARE DEAD 6/6 ==================================: gamebeginshowkey command if rules thenlevel @ 9 >until survived ;: play setup ' game catch drop ;get-order -rot swap rot set-order: you-are-dead base @ decimal play base ! ;forth\ : resume memory drop ' game catch drop ;; ==== Sokoban: Instructions ===================================To run, load the next blocks 9 blocks, which contain the codefor the Sokoban game. The object of the game is to maneuver theboulders (*) onto the pads (.) with the player character (@/~),until all the bolders are on the pads. Sokoban levels arestored one per block. To play:$2A sokobanWould 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 definitionsblk @ 1- constant help-blockchar X constant wallchar * constant boulderchar . constant offchar & constant onchar @ constant playerchar ~ 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? )countfor aftcount rot count rot <> if 2drop rdrop 0 exit thenthen 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 )>rbegin?dupwhile1- 2dup + c@ r@ = if nip rdrop -1 exit thenrepeatrdropdrop0 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 >rdouble +position >arena r> swapposition @ >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 =ifdrop swap r> count! count!else3reverse r> count! count! count!then drop ;: #boulders ( -- n )0 arenafor aftdup c@ boulder = if n1+ then1+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! startbeginshow input ' command catch ?dupuntil finish ;; ==== Sokoban Map 1 ===========================================XXXXXX XX* XXXX *XXXX * * XXXX X XXX X XXXXXXX X XXX XXXXXXX ..XX * * ..XXXXXX XXXX X@XXXX ..XX XXX XXXXXXXXXXXXXX; ==== Sokoban Map 2 ===========================================XXXXXXXXXXXXX.. X XXXX.. X * * XX.. X*XXXX XX.. @ XX XX.. X X * XXXXXXXX XX* * XX * * * * XX X XXXXXXXXXXXXX; ==== Sokoban Map 3 ===========================================XXXXXXXXX @XX *X* XXX * *XXX* * XXXXXXXXXX * X XXXX.... XX * * XXX... * * XX.... XXXXXXXXXXXXXXXXXX; ==== Sokoban Map 4 ===========================================XXXXXXXXX ....XXXXXXXXXXXXX ....XX X * * ....XX ***X* * X ....XX * * X ....XX ** X* * *XXXXXXXXXXXX * X XX X XXXXXXXXXX * XXX **X** @XX X XXXXXXXXXXX\ ==== Game of Life: 1/4 =======================================\ This is a Game Of Life implementation, originally from\ <http://wiki.c2.com/?ForthBlocks>. It has been adapted so\ instead of blocks it uses 1KiB buffers at arbitrary memory\ locations.$40 constant c/b$10 constant l/bc/b 1- constant c/b>l/b 1- constant l/b>bl constant offchar * constant onvariable state1variable state2variable statep\ ==== Game of Life: 2/4 =======================================: wrapy dup 0< if drop l/b> then dup l/b> > if drop 0 then ;: wrapx dup 0< if drop c/b> then dup c/b> > if drop 0 then ;: wrap wrapy swap wrapx swap ;: row c/b * + ; ( a u -- a ): deceased? wrap row state2 @ ( block ) + c@ on <> ;: living? deceased? 0= ;: (-1,-1) 2dup 1- swap 1- swap living? 1 and ;: (0,-1) >r 2dup 1- living? 1 and r> + ;: (1,-1) >r 2dup 1- swap 1+ swap living? 1 and r> + ;: (-1,0) >r 2dup swap 1- swap living? 1 and r> + ;: (1,0) >r 2dup swap 1+ swap living? 1 and r> + ;: (-1,1) >r 2dup 1+ swap 1- swap living? 1 and r> + ;: (0,1) >r 2dup 1+ living? 1 and r> + ;: (1,1) >r 1+ swap 1+ swap living? 1 and r> + ;: mates (-1,-1) (0,-1) (1,-1) (-1,0) (1,0) (-1,1) (0,1) (1,1) ;\ ==== Game of Life: 3/4 =======================================: born? mates 3 = ;: survives? 2dup living? -rot mates 2 = and ;: lives? 2dup born? -rot survives? or ; ( u u -- ): newstate state1 @ ( block update ) statep ! ; ( -- ): state! statep @ c! 1 statep +! ; ( c -- ): alive on state! ; ( -- ): dead off state! ; ( -- ): cell? 2dup swap lives? if alive else dead then ; ( u u -- ): rows 0 begin dup c/b < while cell? 1+ repeat drop ;: iterate-block 0 begin dup l/b < while rows 1+ repeat drop ;: generation state2 @ state1 @ state2 ! state1 ! ;: iterate newstate iterate-block generation ; ( -- ): done? key [char] q = ; ( -- f ): prompt cr ." q to quit" cr ; ( -- ): .line l/b> swap - row c/b type cr ; ( b u -- )\ ==== Game of Life: 4/4 =======================================: view state2 @ l/b> for dup r@ .line next drop prompt ;\ : view ( page ) state2 @ list prompt ; ( -- ): game begin page view iterate done? until ; ( -- ): life state2 ! state1 ! game ; ( a a -- )cr .( Usage: $3000 $32 block life ) cr; ==== Game of Life: Glider ====================================*****; ==== Brain F*ck Compiler Help 1/2 ============================Brainfuck is a simple esoteric language with only 8 commands, itis Turing complete which means it can compute any function whichcan be computed - although it is very difficult to do so. Thecommands operate on a block of memory 1024 bytes long. A datapointer indexes into the memory. The commands are:> increment the data pointer< decrement the data pointer+ increment value at data pointer- decrement value at data pointer. output byte at data pointer, accept one byte and store it at data pointer[ branch forward to ] if byte at data pointer is zero] branch back to [ if byte at data pointer is non-zeroThe compiler discards all other input.; ==== Brain F*ck Compiler Help 2/2 ============================The following blocks implement the compiler, it translates eachcommand in a given string into Forth code, compiling it into anew word definition which can then be executed.Needless to say, it is not a useful language, but it is fun!Some example programs are given after the compiler block.This Forth brain fuck compiler was derived from the oneavailable Rosetta Code, and so is licensed under theGNU Free Documentation License [v1.2]. See:<https://rosettacode.org/wiki/Execute_Brain****/Forth>And for more information see:<http://www.hevanet.com/cristofd/brainfuck/short.b><https://en.wikipedia.org/wiki/Brainfuck>\ ==== Brain F*ck Compiler 1/2 =================================: left over c! 1- dup c@ ;: right over c! 1+ dup c@ ;: erase 0 fill ;: initialize pad b/buf erase pad 0 ;: bf-compile ( c -- )>rr@ [char] [ = if [compile] begincompile dup [compile] while thenr@ [char] ] = if [compile] repeat thenr@ [char] + = if compile 1+ thenr@ [char] - = if compile 1- thenr@ [char] < = if compile left thenr@ [char] > = if compile right thenr@ [char] , = if compile drop compile key thenr@ [char] . = if compile dup compile emit then rdrop ;\ ==== Brain F*ck Compiler 2/2 =================================: bf ( b u --,<string> : compile brainfuck program into a word )>r >r[compile] :compile initializer> r> for aftdup 1+ >r c@ bf-compile r>then nextdropcompile swapcompile c@compile 2drop[compile] ; ;\ Example, making a simple echo like program called 'cat':\ : string $" +[,.]" count ; string bf cat; ==== Brain F*ck Example Programs =============================From: http://www.hevanet.com/cristofd/brainfuck/short.bHello World: ++++++++[>++++[>++>+++>+++>+<<<<-]>+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.Clear Screen: ++++++++++[>++++++++++>+<<-]>[>.<-]Beep: +++++++.Copy Input to Output: ,[.[-],]Reverse Input: >,[>,]<[.<]Translate text to brain fuck that prints said Text:+++++[>+++++++++<-],[[>--.++>+<<-]>+.->[<.>-]<<,]; ==== eForth v6.66: Help and Tutorial =========================This Forth is modeled after eForth, described in a book byC.H. Ting called "eForth Overview", or "The Zen of eForth". Itimplements most of the eForth model with some changes expectedfrom a more modern Forth system.The processor targeted is called the H2, a rewrite of theJ1 processor (<http://www.excamera.com/sphinx/fpga-j1.html>).It has been extended with a few more instructions and withinterrupts. The system resides on an FPGA Nexys 3 board fromDigilent, with words and peripherals designed for it.For more see: <https://github.com/howerj/forth-cpu>; ==== Help: Introduction ======================================Forth is a simple, imperative, stack based language that mixeselements of a high level language with a low level language. Itis possible to fit a small Forth system in a few kilobytes ofRAM complete with an interactive read-evaluate-print loop, aneditor, an assembler and a disassembler.It is also a language that has fallen out of favor in recenttimes (after the micro-computer era) as it is not a very safelanguage, nor is it one that allows the programmer to easilycreate reusable and maintainable software components.However it is still suitable for a number of purposes; forassemblers, to bring up hardware and test it, in memoryconstrained systems, as a boot loader, and for fun.; ==== Help: Philosophy of Forth ===============================Forth itself has its own philosophy, one in which the programmershould have a complete understanding of the system, from theproblem that needs to be solved, the algorithms needed to solveit, the hardware and the software. As the latter two, thehardware and software are usually very simple in Forth systemsit is possible to optimize the problem across multiple domains,tailoring each to come up with a solution. Forth eschewscomplexity, preferring one off, bespoke solutions. Anotherreason it has not seen widespread use.Advocates of the language are usually quite passionate aboutit (as with Lisp, and other niche systems) so it is importantto be pragmatic about Forth. Forth is simply a tool and whenused correctly can be used productively.; ==== Help: Basics 1/6 ========================================A Forth system contains an interactive interpreter that parsestext and either compiles or executes functions, called 'words'in Forth terminology. The system uses Reverse Polish Notation(RPN) and provides the user with two stacks and a 'dictionary'(a big block of memory containing 'words' and other data).The interpreter reads from an input device, such as a keyboardor a serial port, and writes output to the screen or back overthe serial port. Words and number input are space delimited andare either compiled into the dictionary depending on theinterpreter mode and whether the word read in is 'immediate'or not.This tutorial will describe how to use Forth and how theinterpreter works internally.; ==== Help: Basics 2/6 ========================================To start with, simple expressions can be entered and theresults displayed. A line is evaluated after the carriagereturn is entered, code will be indented, this can be typed in.We will start off with a simple expression, adding two numberstogether and displaying the result:( Comments appear within brackets )2 2 + .This prints out '4' and 'ok'. 'ok' is printed out after everyline has been successfully compiled, unless we are in compilemode. '+' obviously does the addition, and '.' pops a valueoff the stack an prints it. Entering a number pushes it ontothe data stack.; ==== Help: Basics 3/6 ========================================The data, or variable, stack is a general purpose stack thatthe programmer uses to pass data to functions, and to returndata from functions. The stacks are an important conceptwithin Forth and stack management will take up a lot of a Forthprogrammers time.Numbers are entered in Reverse Polish Notation, this allowsForth interpreter to immediate process a word or a function asit is encountered instead of building up a parse tree.When '2' is encountered it is pushed onto the variable stack,when the second '2' is input, it is also pushed onto the stack.The Forth word '+' takes two arguments off the stack, adds themtogether and pushes the result back onto the stack. The word'.' pops a single number off the stack and prints it.; ==== Help: Basics 4/6 ========================================Manipulating the stack will be difficult at first, but getseasier over time. There are standard words for stackmanipulation and a standard methodology for describingstack effects called 'stack comments'.A stack comment is a short comment describing the stack beforeand after execution of the word, and the type of the argumentsit accepts and returns. For example the stack comment for '+'is:+ ( n n -- n : add two numbers together )All text between '(' and the ')' is discarded by the Forthsystem. This comment describes a word that accepts twosigned numbers "n n", and returns a signed number "n".; ==== Help: Basics 5/6 ========================================The "--" divides the comment into what the stack looks likebefore execution of the word (to the left of "--") and what itlooks like after (to the right of "--"). A comment on thebehavior of the word comes after the semicolon.Here is a list of some common Forth words and their stackcomments:dup ( n -- n n : duplicate first item on the stack )swap ( n1 n2 -- n2 n1 : swap first two items on stack )drop ( n -- : drop a value from the stack )Stack effects are sometimes numbered, which is used toso the effects on specific arguments can be documented ifthe order of arguments and return values matter.; ==== Help: Basics 6/6 ========================================Some more words with comments:@ ( a -- u : load value from memory address )! ( u a -- : store 'u' at memory location 'a' )< ( n1 n2 -- f : is n1 greater than n2, signed )u< ( u1 u2 -- f : is u1 greater than n2, unsigned )These words have stack comments, some with numbered arguments,but they use different letters. The different letters are usedto describe the type of the arguments that the word accepts.'@', also known as load, takes an address, and '!', takesan address and a value. "<" takes two signed numbers, "u<"takes two unsigned numbers and produces a flag. Type checkingis not performed by Forth and is up to the programmer.; ==== Help: Stack Comments ====================================Here is a list of stack type descriptions and what they mean:| Comment | Meaning ||----------|-------------------------------------|| a | cell address || n | signed number || u | unsigned number || b | string address || c | single character || d | double width number (2 Cells) || f | boolean flag (-1 = true, 0 = false) || k | block number || cfa | code field address of a word || nfa | name field address of a word || pwd | previous word address of a word || <string> | a parsing word |; ==== Help: Expressions =======================================Let us continue on with some interactive examples before westart to define new words. Before we saw a trivial exampleof adding two numbers together, we will go over a few moreoperators first.9 2 + . ( Displays 'B', the default base is hexadecimal )decimal ( Change the input and output base to decimal )9 2 + . ( Displays '11' )3 4 dup * swap dup * + . ( Displays 3^2 + 4^2 or 25 )Negative numbers can be input by prefixing the number with'-':-2 4 * . ( Display -8 ); ==== Help: Numeric Output 1/2 ================================The word '.' pops a value off the stack before displaying it,if we want to examine the stack without popping the value wecan print out the entire contents of the stack with '.s':1 2 3 .s ( prints "1 2 3 <sp"). ( prints "3" ).s ( prints "1 2 <sp" )"<sp" marks the element which is currently on the top of thestack. Other useful words for debugging include '?' thatprints the contents at a memory address and 'dump', whichprints a memory dump of a region of memory.dump ( a u -- )? ( a -- ); ==== Help: Numeric Output 2/2 ================================Hexadecimal numbers can be entered if the base input and outputbase is 16, or by prefixing the number with '$'.decimal $AAA . ( Displays 2730 )-$AAA . ( Displays -2730 )eForth starts up in base 16, valid bases range anywhere from2 to 36. The base can be changed by either setting a variable'base' to the desired base, or with the words 'hex' to changethe base back into hexadecimal, or 'decimal' to change the baseto '10'. Variables in Forth are words that leave an address onthe stack when they are called. They can be read or set with'@' and '!'. For example, "$10 base !" and "hex" areequivalent, as are "$A base !" and "decimal".; ==== Help: Word Definitions 1/2 ==============================For the moment we have not covered how words are defined andis a good time to do so, the word ":" is used to create a newword definition and the word ";" is used to terminate one.Words once defined are added to the 'dictionary', which isconsists of a linked list of words, hence the name'dictionary'. We can define new words interactively like we cantype expressions in, such as:: square dup * ; ( n -- n : square a number )We can then use square like any other word:4 square . ( prints 16 )-5 square . ( prints 25 ); ==== Help: Word Definitions 2/2 =============================='hex' and 'decimal' are defined as:: hex $10 base ! ;: decimal $A base ! ;And simple Forth words likewise defined:: 2- 2 - ; ( u -- u : decrement a number by 2 ): 2+ 2 + ; ( u -- u : increment a number by 2 ): 2* 1 lshift ; ( u -- u : multiply a number by 2 ): 1+ 1 + ; ( u -- u : increment a number by 1 ): negate invert 1+ ; ( n -- n : negate, twos compliment )It is best to keep all Forth words as short as possible andreuse code as much as possible.; ==== Help: Interpreter Loop 1/3 ==============================All functions, control structures, defining words such as ":",and simple functions like "square" or "hex" are simply Forthwords, which are either defined in terms of other Forth wordsor in terms of primitive operations supported by the H2 CPU.Currently this does not explain how compilation happens. Whenthe word ":" is encountered it does multiple things such ascompiling a word header into the dictionary, and it does onemore thing - it puts the Forth system into compile mode. Thesystem starts out in command mode, in this mode words areexecuted, and numbers are pushed onto the stack. In compilemode, a call to the word is compiled (or an assemblyinstruction is inlined) and numbers of turned into literalsthat push their value when run.; ==== Help: Interpreter Loop 2/3 ==============================There is a special class of words called "immediate" words, ";"is an immediate word, when it is encountered instead of beingcompiled into the dictionary it is executed, it compiles anexit instruction to terminate the word definition and it putsthe Forth system back into command mode.Not only are control structures sets of words, like "if","else", "then", "begin", "until", but so are words like "("and "\" which are used to process comments. When executedthey read from the input stream until the they find a ")" orend of line respectively.Variables, strings, and defining words (defining words arethat create new words) are all simply Forth words that areeither compiling or immediate, their is no special syntax.; ==== Help: Interpreter Loop 3/3 ==============================The command loop goes like this:Start) Fetch a space delimited word, find it in the dictionaryFound) Is the system in compile mode?Yes) Is the word immediate?Yes) Execute ItNo) Compile a call to it / In-line itNo) Execute the wordNot Found) Is the word a number?Yes) Is the system in compile mode?Yes) Compile the numberNo) Push the number onto the stackNo) Error!This simple loop is invoked by the work 'quit' which uses'query' to fetch and parse the input and 'interpreter' toperform the state dependent action.; ==== Help: Control Structures 1/10 ===========================This will give you some idea what is going on when controlstructures are covered in the following blocks. Controlstructures can only be used within a word definition, thatis in compile mode, if used in command mode they simply throwan error.Some of the control structures available to Forth are:if ... thenif ... else ... thenfor ... nextfor ... aft ... then ... nextbegin ... untilbegin ... againbegin ... while ... repeat; ==== Help: Control Structures 2/10 ===========================Recursion is also available with the 'recurse' word. Thereare more advance control flow methods available that will bedescribed later (such as 'catch', 'throw' and manipulating thereturn stack)."if...then" will be described first. First a simple example,we will define a word called 'abs' that will return theabsolute value of a number, that is negative numbers will beturned into positive numbers and positive numbers will staythe same. This will require the word 'negate' which changesthe sign of a number and '0<' which tests if a number isnegative, their stack effect comments are:0< ( n -- f )negate ( n -- n ); ==== Help: Control Structures 3/10 ===========================The word 'abs' is then defined as:: abs dup 0< if negate then ;'if' takes an argument off the stack at run time and jumps toafter the 'then' if it is false (zero), if it is true (non-zero) the negate is performed. From now if a word is shown ina definition that has not been previously mentioned pleaserefer to the glossary. We can can use the definition of theword 'abs' as soon as we terminate the definition with ";":-9 abs . ( displays 9 )4 abs . ( displays 4 )This Forth uses two complements to represent negative numbers.; ==== Help: Control Structures 4/10 ===========================A number can be negated in twos compliment form by performinga bitwise not on the number and adding one to it, this is whatthe word 'negate' does."if...else...then" control structures can be created:: min 2dup < if drop else nip then ; ( n n -- n ): max 2dup > if drop else nip then ; ( n n -- n )These words get the minimum (min) and the maximum (max) oftwo numbers.4 3 min . ( prints 3 )4 3 max . ( prints 4 ); ==== Help: Control Structures 5/10 ===========================Whilst control structures can be nested very deeply it isconsidered very bad practice to do, instead the definitionshould be refactored so it consists of short (preferably oneline) word definitions.There are two mains ways of looping, either by recursion orwith the several looping mechanisms. One of the simplest is"begin...until". This continues looping until a variable poppedoff the stack when the "until" word is reach is non-zero. Likethe "if" control structure this can only be used within a worddefinition. An example is the definition of "key", which getsa single character from the input device, it blocks until thereis input. It uses a word called "key?" which returns a variablenumber of items on the stack depending on whether there isnew input from the user.; ==== Help: Control Structures 6/10 ===========================The stack comments for "key?" and "key" are:key? ( -- c -1 | 0 )key ( -- c )Key returns the new character and "-1" (in Forth -1 is true,and 0 is false), or "0" if there is no new input. The pipesystem "|" is used to separate the possible return values inthe stack comment. We can use "begin...until" to define "key"in terms of "key?" with:: key begin key? until ;This simply loops until there is a new character of input.; ==== Help: Control Structures 7/10 ===========================Some contrived examples, using the standard metasyntacticvariable name "foo":: foo begin 1- dup . cr dup 0= until drop ; ( u -- )4 foo ( <-- type this ) 3 ( <-- prints '3' )2 ( <-- then '2' )1 ( ... )0 ( ... )ok ( then ok prompt )If zero is given this will underflow and wrap around to $FFFFand continue the loop 65536 times which is probably notintended.; ==== Help: Control Structures 8/10 ===========================Indefinite loops can be made with "begin...again", thefollowing word "bar" simply repeatedly prints out "1":: bar begin 1 . cr again ;bar 1 1 1 1 1 1 ( ... ad infinitum ... )A looping mechanism that is easier to use is the"begin...while...repeat" loop, this continues an operationuntil a variable is not true:: foo begin ?dup while dup . cr 1- repeat ;3 foo 3 ( <-- prints 3 )2 ( <-- then 2 )1 ( <-- then 1 ); ==== Help: Control Structures 9/10 ===========================eForth provides another control structure, the "for...next" loopwhich allows the Forth programmer to create counted loops. The"for" loop takes a single variable, it stores this variable onthe return stack (which will be covered next) and decrements thevariable, until it is zero, at which point it exits (but stillexecutes for the final zeroth case). The word 'r@' is used topush a copy of the top of the return stack, where the for loopkeeps the conditional value.: foobar for r@ . cr next ;3 foobar 3 ( <-- prints 3 )210 ( <-- prints zero as well! ); ==== Help: Control Structures 10/10 ==========================The "for...next" construct can be modified with the "aft" and"then" construct, which is not executed on the first run of theloop.: quux for -9 . aft r@ . then -8 . cr then ;decimal 3 quux -9 -8 ( for...aft and then...next is run )2 -8 ( aft...then and then...next is run )1 -8 ( ... )0 -8 ( ... )This concludes the control structure section, it should benoted that the control structures are defined words themselvesagain, it is possible to redefine and add your own controlstructures. How this is done will be covered later.; ==== Help: Return Stack ======================================All Forth systems have at least two stacks along with mainmemory, they can be implemented in hardware like with this Forthor in software. One stack is used to pass data to functions andto return their results, the data or variable stack, which wehave already dealt with. The other stack is used for controlflow and as a place for temporarily storing variables.Data can be moved to and from the return stacks, but this mustbe done very carefully and only within word definitions,leaving values on the stack by accident can cause theinterpreter to crash.Some looping constructs use the return stack as well to storetheir loop index, and the 'throw/catch' mechanism manipulatescontrol flow a lot.; ==== Help: Return Stack ======================================Some words for manipulating the return stack are as follows,notice the stack comments describe both stacks here:>r ( u --, R: -- u : move variable to return stack )r> ( -- u, R: u -- : move variable from return stack )rdrop ( R: u -- : remove topmost variable from return stack )r@ ( -- u, R: u -- u : copy topmost return stack item ); ==== Help: Control Structures ================================; ==== Help: TO DO =============================================* Describe the system internals* eForth primitives* Make, Doer, Create, Does>* Do word glossary, with one block per word* Vocabularies* Block Word set* Peripheral access word set* Throw/Catch* How Forth is implemented* Add appendixes for ASCII character set, ANSI terminalcodes supported, the Nexy3 board, twos compliment format,list of characters supported, etcetera.* A short dictionary of English words, or a shortencyclopedia could be made and stored in blocks; ==== Block Editor Help 1/5 ===================================The traditional way to store Forth source code and data is asForth blocks, a block is a contiguous array of 1024 characters,which can be saved to non-volatile storage with the 'block'word set. On more modern Forth systems, especially hosted ones,the file access word set is used instead.A Forth that does not have a file system, such as this one,usually has a primitive block editor. An editor can be definedin just a handful of (non-standard) words.By default the editor words are not in the Forth search order,the words in the editor vocabulary would conflict with Forthwords (and with hexadecimal numbers). To load the block editorexecute the 'editor' Forth word. Load initial block with '0 b'.; ==== Block Editor Help 2/5 ===================================The block editor is a prime example of Forth simplicity, itboth simplifies the problem of editing text and reuses theForth interpreter to define a new command language. Each commandin the block editor simply a Forth word which takes itsarguments off the stack, and a line is a fixed width 64character array, a block can contain 16 lines of text. An emptyline consists entirely of spaces, which the interpreter willignore if it were to evaluate the block.The 'editor' word replaces the current vocabulary with theeditor vocabulary and switches the number base for input andoutput to decimal. The commands are terse words, only one ortwo characters in length.; ==== Block Editor Help 3/5 ===================================The third element of the block editor is the elegant, if some-what limited, block word set. It completely abstracts aways thetask of retrieving data from mass storage and saving modifieddata back to it. The mass storage is divided into blocks whichcan be loaded by their block number. Block numbers in thissystem start at 0 and go to $FFFE, $FFFF is an invalid blocknumber.The block word set is quite small, and the editor uses thewords; 'block', 'update', 'save-buffers', 'list', 'load',and '+block'. The variable 'blk', which contains the lastblock loaded (and listed) is also used. Most editor commandsare minor modifications on the behavior of these words.; ==== Block Editor Help 4/5 ===================================The workhorse of the word set is 'block', it takes a blocknumber and if that block number is not currently loaded into ablock buffer (this system only has one block buffer available)it checks to see if the current block is marked as dirty (withthe 'update' word). If it has been it first flushes the dirtyblock to mass storage, then loads the desired block from it. Itthen returns a pointer to the beginning of the block buffer. Italso updates the 'blk' variable to contain the block numberjust loaded.The 'save-buffers' saves all buffers to disk and deallocatesany blocks (by storing $FFFF in 'blk'). 'list' displays thecontents of a block, 'load' evaluates a block and '+block'moves to a block relative to the currently loaded one.; ==== Block Editor Help 5/5 ===================================A quick recap of the block words:block ( k -- u : load block into buffer )blk ( -- a : last loaded block )+block ( k -- : load block relative to 'blk' )save-buffers ( -- : flush block to disk, put -1 in 'blk' )list ( k -- : display block )load ( k -- : evaluate a block )These can be used to define simple editor commands, such as:: b block drop ;: n 1 +block b ;: u update ;; ==== Block Editor Commands 1/2 ==============================='#' indicates a numeric argument the command takes:n move to next blockp move to previous block# d delete line in current blockx erase current block (overwrite with spaces)e evaluate current block# i insert line# #2 ia insert at line #2 at column #q quit editor loop# b load block numbers save block and write it outu update blockw list editor commandsq back to Forth interpreter; ==== Block Editor Commands 2/2 ===============================l re-list current block# c paste copy buffer to line ## y yank line # into copy buffer# #2 ct copy line # to line #2# ea evaluate line ## #2 sw swap lines # and #2The editor is simple to use and understand, but for largedocuments and programs can quite difficult to use. This blockeditor was derived from the Retro Forth block editor, availableat: <http://retroforth.org/pages/?PortsOfRetroEditor>; ==== TO DO ===================================================* The eForth primitives should be described.* Describe the Nexys 3 system, the system on a chip, etc.* List the instruction set, registers, words defined, eForth* Make words for databases using blocks* Add source code for everything to this block file* Add a program listing, perhaps in the first block, it couldset variables relating to this document* If a metacompiler based on the embed project is used, itmight be possible to have a self hosting system by storing thesource code in blocks.; ==== Empty Block =============================================; ==== Glossary ================================================The next section presents the glossary, which contains oneword per screen with examples. The glossary may not necessarilyreflect the exact contents of the dictionary as words areremoved, added and replaced to save space, but the majorityshould be documented here.Hexadecimal and decimal numbers are used, and which base isin operation should be inferred from context.The glossary shows how blocks can be used as a way toorganize information, a concise description (that if needsbe could span multiple blocks) describes each word. The firstline can be used to create a table of contents with 'index'.This way of organizing blocks maps well onto dictionaries,encyclopedias, and all alphabetically organizable information.; ==== < ( n1 n2 -- f : signed less than ) ====================Signed less than.; ==== <> ( u1 u2 -- f : not equal ) =========================='<>' takes two values off of the values stack and returnsa boolean which is true (-1) if the two value are not equaland false (0) if they are.; ==== <# ( -- : prepare numeric output ) =====================This is part of the mechanism for pictured numeric output,which should be used from within a word definition only.; ==== = ( u1 u2 -- f : equality of two numbers ) =============This is an assembly instruction for testing whether two numbersare equal.; ==== > ( n1 n2 -- f : signed greater than ) =================Signed greater than, if 'n1' is greater than 'n2' true (-1) isreturned, else false (0) is returned. This operates on signednumbers stored in twos compliment format.; ==== - ( n1 n2 -- n : subtraction ) =========================This is word performs subtraction of 'n2' from 'n1'.; ==== , ( u -- : compile value into dictionary ) =============The word ',' compiles a value at the next available locationin the dictionary, updating the dictionary pointer by the sizeof a cell.; ==== ; ( -- : terminate a word definition ) =================This word terminates a word definition, linking the newly formedword into the dictionary. It is an immediate word and performssome basic checking to make sure control structures match up. Itwrites an 'exit' into the word and switches the state back intocommand mode. It has another minor usage, if called withincommand it throws -56, for QUIT. This can be used within a blockto stop execution of it, if 'thru' is used to load block, thiserror is ignored.Example:: 2+ 2 + ;: count dup 1+ swap c@ ;:noname 9 . ; execute ( <-- prints 9 ); ==== : ( -- ; <string> : start a word definition ) ==========':' is a complex word that does many things. It is not animmediate word, but it is a parsing word that reads in thenext space delimited word and compiles a word header into thedictionary. It also switches the interpreter state into compilemode, until switched back non-immediate words will now becompiled into this word definition and numbers compiled intoit as literals. ':' is how most new words (or functions) aredefined within Forth. The word ';' should also be consulted.Usage: example 2 + . cr ; ( <- makes a new word called 'example' )2 example ( <- the new word prints '4' ); ==== ! ( u a -- : store 'u' at address 'a' ) ================Store a value in at an address, this is also used to write tothe memory mapped peripheral registers.; ==== ? ( a -- : print value at address ) ====================Print a value out from an address, this is effected by theoutput radix stored in 'base'. This word uses the area betweenPAD area and the end of the dictionary.; ==== / ( n1 n2 -- q: divide n1 by n2 ) ======================Signed and floored division of the second value on the stack bythe first. This will throw and error if the divisor is zero.This is a particularly slow operation, as the H2 CPU does nota built in division operation.; ==== . ( n -- : print number out in current base ) ==========Print a space, then a signed number (if the output radix is tenthen 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 asan unsigned number). This word uses the area after thedictionary and before the start of the pad area, it is not areentrant function.; ==== ." ( -- ; <string> : compile string into word ) ========This word is an immediate word that compiles a string into aword definition (it should only be used from within a worddefinition). When the word is run it will print out the string.The string is terminated by a double quote. A version of thisword which does no printing but instead returns a pointer toa counted string is available, and it is called '$"'.Usage:: hello cr ." Hello, World! " cr ;helloHello, World! ( <- 'Hello, World!' is printed ); ==== .( ( -- ; <string> : print out line until ')' ) ========This word prints out a string until the matching ')' isencountered. It is not an immediate word. It is a parsingword.Usage:.( Hello, World! ) crHello, World! ( <- 'Hello, World!' is printed ); ==== ' ( -- xt ; <string> : return a word execution token ) =This word parses the next word in the input stream and returnsits execution token if the word is found. It is an immediateword. If the word is not found it throws an exception.; ==== ( ( -- ; <string> : comment until ')' ) ================This is an immediate word used for comments, it discards allinput until the matching ')' is encountered. It can be usedwithin blocks. This word should not span multiple lineshowever.Usage:2 2 + ( This is a comment ) . ( <- this '.' prints '4' ); ==== ) ( -- : do nothing ) ==================================This is a word that does nothing. It is an immediate word. Ithas no function.; ==== [ ( -- : change compile state to command mode ) ========An immediate word for changing the state of the interpreter loopinto the command state. It can be used within a word definition.; ==== ] ( -- : change compile state to compile mode ) ========A normal, compiling word, which turns the interpreter state intocompile mode. Words and numbers after (apart from immediatewords) are compiled into the dictionary.; ==== @ ( a -- u : load value from address ) =================Retrieve a value from memory location 'a'. It can be used toread from the memory mapped registers as well.; ==== $" ( -- ; <string> : compile string into word ) ========This is an immediate word that can only be used in a worddefinition, it compiles a string into the dictionary, when itruns it pushes the address of the counted string compiled intothe word.; ==== * ( u1 u2 -- u3 : multiple two numbers ) ===============Multiply two numbers and push the result onto the stack. This isa slow operation, as there is not a built in multiply operation.; ==== \ ( -- ; <string> : comment until end of line ) ========Comment until end of input line, this word works within blocksas well, where it is a comment until the end of the block line.It is an immediate word.; ==== # ( u -- u : extract numeric character from u ) ========; ==== #> ( u -- b u : return converted number string ) =======; ==== + ( u1 u2 -- u3 : add two numbers together ) ===========; ==== +! ( u a -- : add 'u' to value 'a' ) ===================; ==== 0< ( n -- f : 'n' less than zero? ) ===================='0<' is a test word that operates on a signed value and returnsa boolean value, it returns -1 for true if 'n' is less thanzero and 0 for false if 'n' is greater than zero.Usage:0 0< . ( prints '0' )9 0< . ( prints '0' )-4 0< . ( prints '-1' or 'FFFF' )FFFE 0< . ( prints '-1' or 'FFFF', 'FFFE' = -2 ); ==== 0<> ( n -- f : 'n' not equal to zero? ) ================This word tests if 'n' is not zero, returning true (-1) if itis not zero, and false if it is (0).Usage:0 0<> . ( prints '0' )-7 0<> . ( prints '-1' or 'FFFF' )5 0<> . ( prints '-1' or 'FFFF' ); ==== 0= ( n -- f : 'n' equal to zero? ) =====================This word tests if 'n' is zero, returning true (-1) if it is,and false if it is not (0).Usage:: 0<> 0= 0= ;0 0= . ( prints '-1', or 'FFFF' in hex mode )4 0= . ( prints '0' )-5 0= . ( also prints '0' ); ==== 0> ( n -- f : 'n' greater than zero? ) ================='0>' performs a greater than zero test on a signed number, if'n' is greater than zero it returns true (-1), otherwise itreturns false (0) if 'n' is equal to or less than zero.; ==== 1- ( u -- u : decrement u ) ============================'1-' decrements the top most stack item.; ==== 1+ ( u -- u : increment u ) ============================This is a regular word that increments a value by one.; ==== 1+! ( a -- : increment value at 'a' by one ) ==========='1+!' increments the value at an address, 'a', by one.; ==== 2! ( u1 u2 a -- : store u1 and u2 at two cells ) =======; ==== 2/ ( u -- u : divide 'u' by two ) ======================'2/' is a division by 2, it is implemented as a logical rightshift by one.; ==== 2@ ( a -- u1 u2 : retrieve two cells ) ================='2@' retrieves two consecutive cells from an address 'a'. Theword forms a pair with '2!', which stores two cells at twoconsecutive addresses.Usage:1 2 ( -- 1 2 : input test values )pad 2! ( 1 2 -- : store values in temporary storage )pad 2@ ( -- 1 2 : retrieve values ); ==== 2* ( u -- u : multiply 'u' by two ) ===================='2*' is a multiply by two, it is implemented as a left shiftby one.; ==== 2drop ( u u -- : drop two values from the stack ) ======A simple word, '2drop' behaves as its stack comment suggests,it removes the top most two items from the variable stack.Usage:1 2 3 drop . 1 ( '1' is printed ); ==== 2dup ( u1 u2 -- u1 u2 u1 u2 : duplicate two values ) ===This manipulates two items on the stack, like most words witha '2' in their name. The stack effect describes the wordperfectly. Words like these, which produce and manipulate lotsof stack items should be avoided if possible.Usage:( -- : empty stack )1 2 ( -- 1 2 )2dup ( 1 2 -- 1 2 1 2 ); ==== abs ( n -- u : absolute value of a number ) ============Returns the absolute value of a signed number, positive valuesstay the same, negative values become positive. Signed numbersare stored in twos compliment format, the function fails forthe number $8000, which is unaffected by abs.Usage:-1 abs . ( prints '1' )4 abs . ( prints '4' ); ==== accept ( b u -- b u : accept a line ) ==================; ==== aft ( -- : part of for...aft...then...next ) ===========; ==== again ( -- : part of begin...again loop ) =============='again' should only be used as part of a 'begin...again' loop,which is a compile time only wordset. Using an 'again' withouta 'begin' may also be met with an error, as this situtationshould be caught by the compiler security mechanisms. The'begin...again' looping mechanism forms an indefinite or aninfinite loop, the Forth interpreter/CPU jumps back to thecorresponding 'begin' unconditionally, and excluding anyerrors/exceptions will do so forever.Usage:: invalid-1 again ; ( <- invalid use, no matching 'begin )again ( <- invalid use, outside a word definition ): test begin 1 . cr again ;test ( 'test' prints '1' forever ); ==== align ( -- : align dictionary pointer ) ================'align' is a word that takes no arguments and returns nothing,it acts on the dictionary pointer variable (the internal namefor which is usually 'cp', the variable is returned by theword 'here'). It should be used after allocating a datastructure in the dictionary which is byte aligned and beforedefining any new words, the word 'align' reserves space up tothe next cell aligned address by manipulating the dictionarypointer variable.Usage:create x 3 allot ( <- dictionary pointer is now unaligned )align ( <- dictionary pointer is now aligned ); ==== aligned ( b -- a : align up an address ) ==============='aligned' takes an address 'b', that is potentially unalignedand returns an aligned address by rounding up to the nearestcell boundary. This word is like 'align' but it works on anypointer instead of the dictionary pointer only. As this isa 16-bit Forth system this rounds up to the nearest 16-bit cellboundary, or to next multiple of two (bytes).Usage:0 aligned . ( prints '0' )1 aligned . ( prints '2' )2 aligned . ( prints '2' )3 aligned . ( prints '4' )4 aligned . ( prints '4' ); ==== allot ( n -- : allocate 'n' bytes ) ====================Allocate 'n' bytes of space in the dictionary, 'n' can beeither positive, or negative, negative values deallocate space,which may break things.; ==== and ( u1 u2 -- u3 : bitwise and of two numbers ) =======This performs a bitwise and on two numbers.; ==== ansi ( n c -- : emit an ANSI escape command ) ==========='ansi' is used to help construct ANSI escape code sequences,most sequences consist of a CSI escape code, a number in base10, and a single character to indicate the command. Thecharacter and the number change, and are given as argumentsto the word 'ansi'. Most terminal emulators can deal with thesesequences, and the hardware VT100 clone that controls the VGAdisplay can deal with most of the more important codes.Usage:: sgr [char] m ansi ;$1f sgr ( turn foreground color red )$0 sgr ( reset color )2 char J ansi ( blank screen, set cursor position to 1,1 ); ==== at-xy ( x y -- : place cursor at column 'x', row 'y' ) ='at-xy' emits the ANSI escape sequence which will place thecursor at column 'x' and row 'y'. This should work with thebuilt in VT100 terminal emulator, and with any decent terminalemulator used to talk to the device over UART. 'at-xy' can beused to draw primitive graphics along with other escape codes.Counting starts from one, not zero.Usage:1 1 at-xy ( set cursor to top left corned )5 10 at-xy ( cursor to column 5, row 10 ); ==== base ( -- a : address of base radix ) ==================Pushes the address of the base variable onto the variable stack,this can be used to change the input and output radix of numbersto a base between 2 and 36 inclusive. Characters '0' to '9' areused for numbers 0 through 9, and letters 'A' to 'Z' are usedfor numbers 10 to 35, upper case and lower case letter can beused, only upper case characters are output.Setting the base to an invalid value can cause exceptions tobe thrown in other words.Example usage:$2 base !base @$8 base !; ==== b/buf ( -- u : number of bytes in a block ) ============This pushes the number of bytes in a block onto the stack,which is 1024 in most Forth implementations, including thisone.Usage:blk @ block b/buf blank ( blank most recently loaded block ); ==== begin ( -- : start begin...until/again loop ) =========='begin' is used to start three looping mechanisms,* 'begin...again' ( infinite loop )* 'begin...until' ( loop until non-zero )* 'begin...while...repeat' ( loop until zero )Which are best explained in the entries for 'again', 'until'and 'while'/'repeat' respectively. 'begin' is an immediateword that should only be used within a word definition, andshould be used in conjunction with a valid looping mechanismword set.Usage:See 'again', 'repeat', 'while' and 'until' for examples.; ==== bl ( -- u : value for space character ) ================This pushes the space character to the stack. This is theASCII character 32 (decimal), or $20 (hexadecimal). This isa useful character for comparing character ranges (anythingof a lower numeric value than space is a control character inASCII) and because it is unobtainable by using the word 'char'or '[char]', as they use space to delimited the character to beread in.; ==== blank ( b u -- : fill array with blanks ) ==============This word writes the space character to a byte array, one useis to erase a block before it is displayed with 'list'.; ==== blk ( -- a : address of last loaded block ) ============'blk' is a variable which contains the value of the last blockto be loaded. This value is updated by 'block' on a successfuloperation, and is set to an invalid block number on a blockerror, or when 'flush' is called.; ==== block ( k -- a : perform block operation ) ============='block' is a complex word that abstracts away all the detailsof mass storage, whilst at the same time being easy to use, itforms the basis on which Forth Blocks are used to organizecode and data. 'block' takes a block number and if it isvalid attempts to find a free buffer in which to load theblock into, it then returns a pointer to that buffer. If nofree buffers are available it saves a dirty buffer to diskthen deallocates it, or it overwrites a clean buffer (as itcan always be loaded from disk if needed again).Usage:5 block 2 cells + 1234 swap ! update flush; ==== +block ( n -- k : return block number relative to blk ) ='+block' is a useful common operation which returns the blocknumber relative to the one currently loaded in 'blk', it canbe thus used to navigate relative to the most recently loadedblock. The number it accepts is signed, the next blocks beingspecified with a positive number, the current with zero, andnegative being prior blocks.Usage:: +block blk @ + ; ( n -- k ): next 1 +block ; (: previous -1 +block ;5 block drop next next previous; ==== border ( -- a : variable for list display control ) ===='border' is a variable that controls the display of 'list',it turns the border on when it is set to true (-1), and offwhen it is set to false (0).; ==== c, ( c -- : compile character into dictionary ) ========This words takes a character and writes the character in thenext available location in the dictionary, and updates thedictionary pointer. This word can cause the dictionary numberto be misaligned, 'align' can be used to remedy this.; ==== c! ( c b -- : store 'c' at 'b' ) ======================='c!' is the byte oriented store word, it stores a byte 'c' ata potentially unaligned address 'b'. This is not a primitiveoperation provided by the processor as it can only do cellsized loads and stores in a single instruction. Thecorresponding word for load a byte is 'c@'. The cell loadand store words are '@' and '!' respectively.; ==== c@ ( b -- c : retrieve 'c' from 'b' ) =================='c@' retrieves a single byte from the address 'b', this addressdoes not have to be an aligned address. For storing a byte, see'c!'. This word is the byte oriented version of '@', '@'operates on Forth cells. On this processor 'c@' is not aprimitive operation, for speed '@' should be used instead, asloads (and stores) can only be done by cell and not by byte.; ==== catch ( xt -- n | 0 : catch possible exception ) ======='catch' can catch exceptions thrown by 'throw', it is part ofa pair of words that work as a pair like many Forth words, onecannot exist without the other. 'catch' takes an executiontoken, executes it, and returns 0 if nothing was thrown, anda non-zero value if something was. 'catch' is also used as partof the interpreter loop as an exception handler of last resort.The word 'throw' should also be consulted. 'throw' and 'catch'manipulate the return stack a lot and are fairly complex wordsthat are hard to implement on a processor with hardware stacks.Usage:: x 99 throw ; : y x 66 ;' x catch . ( prints '99' ); ==== ccitt ( crc c -- crc : compute CRC step ) ==============; ==== cell- ( a -- a : decrement address by single cell ) ===='cell-' is the opposite of 'cell+', it decrements an addressvalue by a cell. On this 16-bit Forth a cell consists of twobytes, but on a 32-bit one it would decrement by four. Notethat this word does not ensure the resulting address isaligned, if an unaligned addressed was passed in and unalignedaddress will pop out, and an aligned address will stay so. Thisword is needed so Forth code can be written that is portableacross different word size computers.; ==== cell+ ( a -- a : increment address by single cell ) ===='cell+' increments an address by the size of a cell, see'cell-' for further description on this.; ==== cells ( n -- n : convert cell to byte count ) =========='cells' is a word that takes a count of the number of cells andreturns the number of bytes that those cells would occupy, onthis 16-bit Forth 'cells' is essentially a multiply by twooperation, but on other Forths it could be a different value,so this word is used for portability reasons.Usage:0 cells . ( prints '0' )1 cells . ( prints '2' )2 cells . ( prints '4' )create x 4 cells allot ( 'x' created, space for 4 cells ); ==== >char ( c -- c : convert unprintable character ) ========'>char' converts a character so that it can be printed byconverting any characters which cannot be printed to theunderscore character ('_'). This is used within words like'message' and 'list'. Tabs also get converted, as do controlcharacters, delete and any character outside of the ASCIIrange.; ==== char ( -- c ; <string> : parse character ) =============This word reads in a space delimited word from the input streamand pushes the first character of that word onto the stack. Anentire word is potentially read in, but only the firstcharacter is used.Usage:char x . ( prints '$78' )char xylophone . ( prints '$78', also )char 0 . ( prints '$30' ); ==== [char] ( -- ; <string> : compile character literal ) ===This is an immediate word that compiles a character into thedictionary as a literal value that will be pushed onto thestack when the word is run. It parses a space delimited wordand compiles the first character of that word. It is a compileonly word. Although an entire word is parsed, only the firstcharacter is used.Usage:: print-c [char] c emit ;print-c c ( 'c' is printed ): push-c [char] c ;push-c . 63 ( ASCII 'c' is $63 ); ==== cmove ( b b u -- : move block memory ) ================='cmove' copies a block of characters from one location toanother.; ==== compile ( -- : compile next word into dictionary ) ======; ==== [compile] ( -- xt : compile next immediate word ) ======; ==== compile, ( xt -- : compile execution token ) ==========='compile,' compiles an execution token into the next availablelocation in the dictionary, taking up a cell of space. Thisword must be used when compiling in an execution into a word,the word ',' will compile an unconditional branch.; ==== conceal ( -- : emit stars instead of characters ) ======; ==== console ( -- : UART only mode ) ========================; ==== constant ( n -- ; <string> : create constant ) ========='constant' is a defining word that creates a new constant, ittakes in a value from the stack, and parses the next word fromthe input stream which will become the name of the newconstant. This word uses 'create' and 'does>' internally todo the work, and is similar to the definition of 'variable'.At run time the new word when called will leave a copy of'n' on the stack.Usage:: constant create , does> @ ;4 constant x3 constant yx y + . ( prints '7' ); ==== count ( b -- b c : retrieve next character in string ) ='count' is a very useful word when dealing with strings,especially counted strings. It retrieves a character from anaddress and increments that address by one character. This canbe used to advance through a string, and with counted stringsit can be used to retrieve the string length which is storedin the first byte of the string.; ==== cpu-id ( -- u : return CPU-ID ) ========================This is an assembly instruction that pushes the CPU-ID of theCPU onto the stack. It can be used to determine whether thesystem is running in a simulation or on the hardware.; ==== cr ( -- : emit new line ) =============================='cr' emits a new line, which consists of a carriage returncharacter followed by a linefeed character. This format is usedas communication occurs over a UART (and the VGA output displaybehaves like a VT100 video terminal).; ==== crc ( b u -- u : perform CRC over array ) =============='crc' performs a Cyclic Redundancy Check (CRC) over an arrayspecified by an address ('b') and length ('u') pair. Itreturns the result in a single cell. There are many differentways of computing a CRC which depending on starting value,what operation to perform at the end of the calculation andwhat polynomial is used. 'crc' used the word 'ccitt' to dothe actual calculation on each byte, using the CCITTpolynomial, which is a standard polynomial. See 'ccitt' formore information. CRCs can be used for error detection.Usage:: s1 $" hello" count ;hex x crc . ( prints 'D26E' ); ==== create ( -- ; <string> : make 'created' word ) ========='create' is a very useful word that allows the creation ofnew words. It parses the next space delimited string from theinput stream and creates a word which when run returns apointer to its code field. It can be used to make words whichcreate new words, and 'does>' can be used to give those newwords different actions. The 'create'/'does>' combination isa really important concept in Forth and has been called 'ThePearl of Forth'.Usage:create x 2 cells allot: constant create , does> @ ;4 constant y ( a new constant called 'y' has been made ); ==== decimal ( -- : switch radix to decimal ) ==============='decimal' switches the current output radix into decimal asthe name suggests. This can be useful when you are lost and donot know what the current output radix is, or for performingcalculations like a human instead of a machine! Hexadecimalvalues can still be input by prefixing the number with '$'.Negative numbers will be printed with a leading '-', unlikein other output bases, when a '.' is used to print the number.; ==== dm+ ( a u -- u : print out section of memory ) ========='dm+' prints out a section of memory in numeric forth, itprints out the contents starting from address 'a' and advancingfor 'u' bytes, rounded down to the nearest aligned celllocation. It is a factor of 'dump' and is useful as a debuggingtool in itself. It will print out the values in the currentoutput radix, as stored in the 'base' variable. A crude memorydump can be performed with '0 here dm+'. No newlines areprinted, but spaces are printed between cell values.Usage:$40 $200 dm+ ( print $200 bytes starting from address $40 )0 here dm+ ( crude dump of Forth core ); ==== dnegate ( d -- d : negate a double value ) ============='dnegate' is the double cell number equivalent of 'negate', itnegates a double cell number. Positive numbers become negativeand vice versa. Double cell numbers take up two items on thestack as the name suggests.; ==== doer ( -- ; <string> : create a 'doer' word ) ==========; ==== does> ( -- : start 'does' section of word ) ============; ==== drop ( u -- : drop a value ) ==========================='drop' simply pops off and discards the topmost value on thevariable stack. 'rdrop' is the return stack equivalent.; ==== dump ( a u -- : dump a section of memory ) ============='dump' is a debugging tool that dumps a section of memorystarting at the address 'a' and proceeds for at least 'u'characters. It dumps the memory contents in whatever thecurrent output base it, as well as displaying the memorycontents as characters when the characters are printable.Example:0 here dump ( <-- dumps out everything )Example Output (condensed to fit on the screen):0: 104C 0 0 0 0 0 E9B 0 L_______________10: 8000 6403 7075 6081 601C 8010 6F04 6576 ___dup_`_`___ove20: 72 6181 601C 801A 6906 766E 7265 74 r__a_`___invert_30: 6600 601C 8026 2B01 6203 601C 8034 7304 _f_`&__+_b_`4__s( and so on...); ==== dup ( n -- n n : duplicate a value ) ===================The stack comment explains this word completely, it simplyduplicates the topmost item on the variable stack. This is acommon Forth word that should be memorized - you should notneed to look it up here! Other common stack manipulation wordsinclude 'swap', 'over', 'nip', 'tuck', '2dup', 'drop', and'2drop' amongst others. If you find keeping track of the stackdifficult, try to rethink and refactor your code, stackjuggling gets easier over time but nothing beats out removingcomplex combinations of 'dup', 'swap', 'over' and the like.Usage:5 dup ( 5 -- 5 5 ); ==== ?dup ( n -- n n | 0 : duplicate value if not zero ) ====This word duplicates a number if that number is non zero, itreturns just a single zero if the input number was zero. Itfinds a lot of use in 'begin...while...repeat' loop constructs,as well as in other looping constructs.Usage:: ?dup dup if dup then ;0 ?dup .s ( 0 -- 0 )3 ?dup .s ( 3 -- 3 3 ); ==== else ( -- : if...else...then ) ========================='else' is a word which forms part of the 'if...else...then'clause, it can only be used from within a Forth worddefinition and should always be used with the matching 'if'and 'then'.Usage:: example cr if ." Hello!" else ." Goodbye!" then cr ;1 example ( prints 'Hello!' )0 example ( prints 'Goodbye!' ); ==== emit ( c -- : emit a character ) ======================='emit' emits a single character to the output device, thisdevice is by default both the UART and the VT100 terminalemulator can be displayed on a VGA capable display. The boardused has VGA output. The output of this word can be redirectedby words like 'io!', 'stars', 'conceal', 'file', 'console' and'interactive'.Usage:$6b emit ( prints 'k' ); ==== empty-buffers ( -- : deallocate block buffer ) ========='empty-buffers' deallocates any currently loaded block buffers,and stores and invalid block number in 'blk'. It can be usedto discard any changes made to any currently loaded blocks.; ==== evaluate ( a u -- : evaluate block of memory ) ========='evaluate' takes a string specified by an address 'a' and alength 'u' and evaluates it as if it were typed in by theuser. 'source-id' is set to '-1' for the duration of thisso code can work out it is being evaluated and not typed in.Usage:: s1 $" 2 2 + . cr " count ;s1 evaluate ( prints '4' ); ==== execute ( xt -- : execute an execution token ) ========='execute' takes an execution token, which represents a callablefunction, and it executes that function. Execution tokens arereturned by words like "'" (quote), or by ":noname".; ==== @execute ( a -- : execute token at 'a' if non-zero ) ==='@execute' expects an address of a value containing anexecution token to execute, it retrieves this token from theaddress and executes it if the token is a non-zero value. Thisis primarily uses for vectored word execution.; ==== exit ( -- : exit from word ) ===========================This word is an assembly instruction that will be inlined intoa word when it is executed, it will run but have no effect whenexecuted in command mode, when compiled into a word it willexit that word definition when it is run by returning from thatword. It is compiled into the end of a word definition bythe ';' word, which terminates a word.Example:: foo if $f00f . exit then $1337 . ;0 foo $F00F ( <-- prints only '$F00F', $1337 not printed )1 foo $1337 ( <-- prints $1337 only ); ==== expect ( b u -- : accept, but store 'u' in span ) ======; ==== file ( -- : file transfer mode ) =======================; ==== fill ( b u c -- : fill area of memory with 'c' ) =======; ==== find ( a -- pwd 1 | pwd -1 | a 0 : find word ) =========; ==== flash ( -- : add flash words to search order ) =========The flash related word set requires its own glossary anddescription. It is for manipulating the onboard memory, notjust the Flash chip on the Nexys3 but the SRAM as well (asboth devices share data, address and most control lines).The startup sequences loads blocks from Flash to SRAM, theSRAM can be modified freely, but committing data to Flash isa manual process as erasing and writing to Flash too many timescan cause it to wear out.The source code should be consulted for a list of the memoryrelated words, their usage and other such information.; ==== flush ( -- : write dirty blocks, empty-buffers also ) ==; ==== for ( -- : part of for...next loop ) ===================; ==== forth ( -- : set search order to the default ) =========; ==== forth-wordlist ( -- voc : return Forth vocabulary ) ====; ==== get-order ( -- vn...v0 u : get search order ) =========='get-order' is the counter part to 'set-order', it takes avariable number of arguments off of the stack, denoted by 'u',which each represent a word list. It used for inspecting thecurrent search order in use by the interpreter.; ==== here ( -- a : return dictionary address ) =============='here' returns the current address of where the dictionarypointer is, new words will be compiled at this address. Thedictionary pointer is updated by compiling words and numbersinto the dictionary, words like ',' and 'compile,'.; ==== hex ( -- : set numeric radix to hexadecimal ) ==========This sets the current input output radix to hexadecimal, whichis the default radix for numbers in this Forth. If operatingin other bases, or to make it clear which base you mean, anumber can be prefixed with '$' to force the input base tohex for that number. This affects all number conversionsglobally as it sets the 'base' variable to '$10'. It isequivalent to '$10 base !'.Usage:hex 9999 1111 + . ( prints 'AAAA' )decimal 9999 1111 + . ( prints '11110' ); ==== hi ( -- : initialize and login to system ) ============='hi' initializes the system and calls the routine that printsthe login prompt.; ==== hld ( -- a : hold count for pictured numeric output ) ==='hld' is a variable which contains the current hold count forthe pictured numeric output. As characters are added to theoutput buffer with the word 'hold', this value is increment. Itis reset by '<#'. The value for 'hld' may actually be a countor a pointer.; ==== hold ( c -- : put byte into numeric output string ) ===='hold' puts a byte into the hold buffer, which is used by thePictured Numeric Output (PNO) routines as a temporary buffer tocreate a string that represents the number to be output. ThePNO related routines include; 'hold', 'hld', '<#', '#', '#s',and '#>'. They are used by words like '.' and 'u.'. Thehold buffer is not that large, at has a minimum size of eightycharacters, so should not be used for large strings.Usage:: (u.u) <# # # [char] . hold # # #> ;: u.u base @ >r hex (u.u) type r> base ! ;$1234 u.u ( prints '12.34' ); ==== ien ( f -- f : set interrupt flag ) ====================; ==== ien? ( -- f : are interrupts enabled? ) ================; ==== if ( -- : part of if...then/if...else...then) =========='if' is an immediate word that should only be used within aword definition. It is used to form 'if...then' and'if...else...then' clauses for conditional execution ofwords. The words 'else' and 'then' should also be consulted.'if' has differing behavior at compile time and run time,which is covered in the documentation for the system internals,however 'if' is just an ordinary Forth word. When run, ittakes a value from the variable stack and jumps to thecorresponding 'else' or 'then' if it is zero, if it is nonzero it continues execution after the 'else'.: example cr if $" Hello" else $" Bye" then count type cr ;0 example ( prints 'Hello' )1 example ( prints 'Bye' ); ==== immediate ( -- : make last defined word immediate ) ===='immediate' is an important word that makes the most recentlydefined word 'immediate', that is it will be executed evenwhen in compile mode. All control structure words areimmediate words such as 'if', and 'for'.; ==== >in ( -- a : index into parse input at address ) =======; ==== index ( k1 k2 -- : print first line of block range ) ==='index' displays the first line in a range of blocks, if theblocks are formatted correctly with the first line containing adescription of the block contents then this works to display anindex of the blocks.; ==== interactive ( -- : interactive I/O mode ) ==============; ==== interpret ( ??? a -- ??? : interpret word/number ) =====; ==== invert ( u -- u : bitwise invert ) ====================='invert' performs a bitwise invert on a number. For atwos compliment negation see 'negate'.Usage:hex0 invert . ( prints 'FFFF' )4 invert . ( prints 'FFFB' )FFFF invert . ( prints '0' )AAAA invert . ( prints '5555' ); ==== io! ( -- : initialize IO channels ) ===================='io!' initializes the I/O devices and sets the input and outputdevices to their default values (read from UART and PS/2keyboard, write to the VT100 display, and to UART - both atthe same time). It also disables the interrupts, and sets thetimer to a count but not generate interrupts.Example usage:io! ( ...that's not a very good demonstration... ); ==== key ( -- c : block until character read in ) ===========This word blocks until a character has been read in from thecurrent input device (or devices). The input devices can beeither be the UART or the PS/2 Keyboard. The input devices canbe changed with the 'io!', 'console', 'conceal', 'interactive'and 'file' words.; ==== key? ( -- c -1 | 0 : non-blocking character read ) =====This is a non-blocking version of 'key', it returns acharacter and true (-1) if a new character has come throughfrom input devices, and only 0 if there is no new character.The input devices can be either a UART or a PS/2 keyboard, andthis can be changed with the 'io!', 'console', 'conceal', 'file'and 'interactive' words.; ==== last ( -- pwd : last defined word ) ====================; ==== led! ( u -- : write value to LEDs ) ===================='led!' sets the LEDs on the board next to the switches. Thereare eight switches, and the lowest eight bits of the input valueare used to set the switches, 1 is on, 0 is off.; ==== list ( k -- : list block ) =============================The word list loads block 'k' from disk and display the contentsof this block on the screen. It displays the block as 16 lineswith a column width of 64. The display format is controlled bythe 'border' variable, if true it 'list' displays the linenumber and a border around the block, if false, then it justdisplay the block line by line without formatting. It is trueby default. 'list' will also call 'page' before it displaysthe block if 'border' contains a non-zero value.Usage:1 list2 list( ..ad infinitum ); ==== literal ( n -- : compile literal into dictionary ) =====This is an immediate word that compiles a number into thedictionary. A number takes up between one and two cells in thedictionary (negative numbers take up two space, positive onlyone). It is a compile only word.Usage:: example [ 2 2 + ] literal ;example . ( prints '4' ); ==== load ( k -- : load and execute block ) ================='load' retrieves a block using 'block', and evaluates thatblock, executing whatever is in that block as Forth code,'source-id' will return -1 for the duration of this evaluation,the input source will be returned to whatever it was beforethe evaluation took place, such as keyboard or UART input,once the evaluation has finished. 'load' is used in theword 'thru' to do the evaluation of successive blocks offmass storage.; ==== loaded ( -- a : variable, true if boot block loaded ) ==This is a variable which can be set by the user if the loadingof the boot block was successful, and if the error messagesexists on disk. The error handling words in QUIT inspect thisvariable to work out if it can lookup error messages and printthem, or if it should just print out the error number.; ==== lshift ( u1 u2 -- u3: logical left shift u1 by u2 ) ====This performs a logical left shift on 'u1' by 'u2'.; ==== make ( -- : make part of make/doer words ) ============='make' is a state aware word that operates on words made with'doer', it should not be used with other words.; ==== max ( n1 n2 -- n3: maximum of two numbers ) ============This returns the maximum of two signed numbers. This is asigned operation! Some Forths define an unsigned versioncalled 'umax'. See 'min' for the minimum of two signednumbers.; ==== message ( u -- : type line from block ) ================'message' prints a line from a block, a block is 1024 byteslong, and there are 16 lines of 64 bytes per block. 'u'specifies a line number, starting at block 0, which containslines 0-15, block 1 has lines 16-31 and so on. Lines areprinting omitting any trailing spaces and non-ASCII charactersare replaced with another character (an underscore, '_').This word is useful in printing error messages, the interpretermaps error codes into line numbers. The error messages startin block 2 and end in block 5, with one message per line.Usage:$21 message ( print line 33, or the second line in block 3 ); ==== min ( n1 n2 -- n3: minimum of two numbers ) ============This returns the minimum of two signed numbers. 'umin' is notdefined but it is enough to create, it provides an analoguefor unsigned numbers. The word is simple enough to use.: min 2dup < if drop else nip then ; ( n n -- n ): umin 2dup u< if drop else nip then ; ( n n -- n )Usage:3 4 min . ( prints 3 )-3 4 min . ( prints -3 )65533 4 min . ( prints -3, 65533 is -3 on a 16-bit system )65533 4 umin . ( prints 4 ); ==== m/mod ( d n -- r q : signed divide / modulo ) ==========; ==== mod ( n1 n2 -- r : remainder of n1 divided by n2 ) =====; ==== /mod ( n1 n2 -- r q : remainder/quotient ) ============='/mod' divides 'n1' by 'n2' and returns the remainder ('r')and the quotient ('q') of that operation. Given '/mod', thedefinitions of 'mod' and '/' naturally follow. They areactually all implemented in the far more useful 'um/mod' word.; ==== ms ( u -- : wait for 'u' milliseconds ) ================'ms' waits for 'u' milliseconds with a busy loop. It ispredicated on the system running at 100MHz and will need to bemodified if the system frequency changes.Usage:: 1s 1000 ms ; ( -- : wait for a second ): toggle-leds 0 begin invert dup led! 1s again ; ( -- ); ==== negate ( n -- n : negate a number ) ===================='negate' performs the negation of a number into twos complimentformat, positive numbers become negative and negative numbersbecome positive (with the exclusion of $8000, which stays thesame).Usage:decimal1 negate . ( '-1' )0 negate . ( '0' )-4 negate . ( '4' ); ==== next ( -- : part of for...next loop ) ==================; ==== nip ( n1 n2 -- n1 : remove second value on stack ) =====The stack comment describes this word perfectly, 'nip' removesthe secondmost item on the stack, leaving the topmost intact.; ==== :noname ( -- xt : start anonymous function ) ===========The ':noname' word is an immediate word that allows thecreation of words that do not have names, or an anonymousfunction. The word can be executed with the 'execute' function.Usage::noname 2 2 + ; execute . ( prints '4' ): (;) ' rdrop compile, 0 state ! ;: compose >r >r :noname r> compile, r> compile, (;) ;: x 2 2 ;: y + . ;' x ' y compose execute ( prints '4' ); ==== number? ( b u -- n f : is string a number ) ============; ==== .ok ( -- : print okay prompt ) ========================='.ok' prints out 'ok' after the successful execution of aninput line when the Forth interpreter is in the command mode,the prompt is suppressed when in compile mode.; ==== or ( u1 u2 -- u3: bitwise or of two numbers ) =========='or' performs the bitwise 'or' of two numbers.; ==== over ( n1 n2 -- n1 n2 n1 : duplicate over ) ============'over' duplicates the second most item on the variable stack.Its stack comment describes its workings completely.Usage:1 2 over .s1 2 1; ==== pack$ ( b u a -- a : pack string into address ) ========'pack$' is a useful word when dealing with short Forthstrings, it is used by the interpreter for packing the wordname into the words header. It takes a string specified by'b u', 'b' being an address of a string, and 'u' beings itslength, and copies the string starting at address 'a', thefirst byte of the new string is the length of the string, soit requires an extra byte be available at 'a'. It then returnsa pointer to this newly packed, counted string.; ==== pad ( -- a : return address into pad area ) ============'pad' returns a pointer into the pad area, which begins atleast 80 bytes after the end of the dictionary. The 'pad'pointer moves when the dictionary pointer moves. It is a usefularea for temporary storage, but should not be used too much.Some words, such as the Pictured Numeric Output (PNO) words,use the area just before the pad area.Usage:3 pad !4 pad cell+ !pad @ pad cell+ @ + . ( prints '7' ); ==== page ( -- : clear page ) ==============================='page' clears the screen, it does this by emitting the ANSIterminal escape sequence codes for erasing the display andmoving the cursor position to the top left most cell.Usage:page ( <- That's about it, not much to see ); ==== parse ( b u c -- b u delta : parse string out ) ========; ==== pick ( un...u0 u -- un...u0 u : pick value ) ==========='pick' selects an item on the stack at an arbitrary depth 'u'and pushes a copy onto the variable stack. This word should beused sparingly and it would be better if it was not used atall due to the way it is implemented and the limited stack sizeavailable to the H2 processor (32-64 cells deep on both stacks,plus one for the variable stack). The implementation shufflesdata from the variable stack to the return stack, so it isquite easy to overflow the return stack for valid but highvalues of 'u'.Usage:22 33 44 0 pick . ( prints '44' )22 33 44 1 pick . ( prints '33' )22 33 44 2 pick . ( prints '22' ); ==== query ( -- : get line of input ) ======================='query' gets a new line of input from the current input device,and places that line in the Terminal Input Buffer, which canbe accessed by 'source'.; ==== quit ( -- : interpreter loop ) =========================For some reason the interpreter loop is evoked by the word'quit', which is what it is traditionally called. This is nota good name, but nonetheless is the standard name for it. Theinterpreter loop fetches a line of input, parses a word,evaluates it, catches/displays any errors and flushes thecurrent line if there are any, and continues to do this untilthe current line contains no new space delimited words/numbers,whereupon it fetches a new line and repeats the process again.Usage:quit ( <- invokes another interpreter loop... ); ==== >r ( u --, R: -- u : move value to return stack ) ======'>r', also known as 'to r' moves a variable from the variablestack to the return stack, its inverse is 'r>'. This word,along with all return stack words, should be used carefully asit is possible to trash the return stack with incorrect use.The word should also be used only from within a worddefinition. The stack comment describes the action of thisword completely.Usage:: rot >r swap r> swap ; ( n1 n2 n3 -- n2 n3 n1 ): -rot swap >r swap r> ; ( n1 n2 n3 -- n3 n1 n2 ); ==== r> ( -- u, R: u --: move value from return stack ) ====='r>' also known as 'from r', moves a cell sized value from thereturn stack to the variable stack. It should only be used fromwithin a word definition, and only by those that know what theyare doing. It is possible to crash the interpreter by trashingthe return stack with this word. The stack comment for thisword perfectly describes this word.Usage:: rot >r swap r> swap ; ( n1 n2 n3 -- n2 n3 n1 ): -rot swap >r swap r> ; ( n1 n2 n3 -- n3 n1 n2 ); ==== r@ ( -- u : R: u -- u: copy top of return stack ) ======'r@' is a useful word that copies the topmost value on thereturn stack, leaving that value in place, and pushes it tothe variable stack. This word is useful when jugglingvariables on the stack, it is also used to access the loopcounter in a "for...next" or "for...aft...then...next"construct.; ==== random ( -- u : random number ) ========================'random' returns a Pseudo Random Number, it uses a CRC algorithmand the system timer to generate the value.; ==== rdrop ( --, R: u -- : drop a value from return stack ) ='rdrop' is the return stack equivalent of 'drop', it discardsa single value from the return stack.Care should be taken when manipulating the return stackas it can trash it rendering the system inoperable until itis restarted.; ==== recurse ( -- : recursively call current word ) ========='recurse' is a word that when used within a word definition itwill recursively call the current word. This is not a tailcall, if this word is used incorrectly it will blow up thereturn stack. Some Forths use the construct 'recurse exit'to implement tail calls, reliant on a peephole optimizerbuilt into 'exit' to change the call into a branch, this Forthdoes not do this. This word is necessary as the word currentlybeing defined has not been linked into the dictionary yet, topermit previous versions of the word to be used in the newdefinition. This word is a compile only word.Usage:: pick ?dup if swap >r 1- recurse r> swap exit then dup ;; ==== repeat ( -- : part of begin...while...repeat ) ========='repeat' terminates a 'begin...while...repeat' loop. It is aword that should only be used as part of a'begin...while...repeat' clause, and should only be usedfrom within a word definition. It is an immediate word. Thewords 'begin' and 'while' should also be consulted. 'repeat'unconditionally jumps back to the 'begin', it is 'while' thatdoes the test and potentially jumps past this 'repeat' if thevalue it pops from variable stack is zero.; ==== rot ( n1 n2 n3 -- n2 n3 n1 : rotate three items ) ======Rotate the first three elements on the variable stack. Thestack comment describes the word completely. If you find yourself using this word too much, you need to rethink and refactoryour Forth. 'rot' is a useful word, but it should be usedsparingly. '-rot' reverses the 'rot' operation.; ==== -rot ( n1 n2 n3 -- n3 n1 n2 : rotate three items ) =====Rotate the first three elements on the variable stack in theopposite direction as 'rot'. If you find yourself using thisword too much it might be best to refactor your code.; ==== rp@ ( -- u : return stack depth ) ======================'rp@' push the return stack depth onto the variable stack, itis an assembly instruction.; ==== rpick ( u -- u, R: un...u0 : pick return stack value ) ='rpick' picks a value at an arbitrary depth on the return stackbased on the argument given.; ==== rshift ( u1 u2 -- u3 : logical right shift u1 by u2 ) =='rshift' performs a logical right shift of 'u1' by 'u2' places,it is equivalent to unsigned division by 2 raised to the powerof 'u2'.; ==== .s ( -- : print out variable stack ) ===================This word is used for debugging, it prints out the entirevariable stack up to the current variable stack depth. It usesthe area between the end of the dictionary and the start of thePAD area. It is not a reentrant function.; ==== #s ( u -- 0 : repeat '#' until 0 ) =====================This word repeatedly calls '#' on a number until it is zero, itshould only be used within a pictured numeric output constructand uses the area between the end of the dictionary and thebeginning of the pad area. Characters are held starting fromthe pad area working downwards towards the end of the dictionaryspace.Example:: print-number <# #s #> type ;1234 print-number ( <-- prints '1234' ); ==== save-buffers ( -- : save dirty blocks ) ================'save-buffers' saves any dirty buffers, if there are any, todisk and sets the block dirty bit to clean (so subsequent callsto 'save-buffers' will not save blocks to mass storage unlessthey have been 'update'd again). You can make a block dirtyby calling 'update' after the block has been loaded, and beforeany other blocks have been loaded.Usage:5 block drop ( load block 5, do nothing with it )save-buffers ( nothing happens, block 5 is not dirty )4 block 99 swap ! ( store '99' in first element of block 4 )update ( mark block 4 as dirty )save-buffers ( block 4 written back to disk ); ==== see ( -- ; <string> : decompile word ) ================='see' is a complex word that can decompile a Forth word, it isliable to be buggy. 'see' parses the next space delimited wordin the dictionary, and if found attempts to disassemble theword into instructions and function calls. If not found 'see'will throw an exception. The results of 'see' areimplementation dependent. Given a very good implementationof 'see' it would be possible to dispense with the sourcecode entirely in text form, the binary could be disassembled,the code modified, and then it could be reintegrated intodictionary - the idea is purely speculative, comments wouldbe missing and this version of 'see' is not good enough.Not many languages have a disassembler built-in!Usage:see word; ==== segments! ( u -- : display 'u' on LED displays ) =======Segments writes a single 16-bit value to the four seven segmentdisplays on the board. This can be used to display a singlecell as a hexadecimal value.Usage:$cafe segments!$d1ed segments!$0001 segments!; ==== set-order ( vn...v0 n -- : set search order ) ==========This word sets the search order for the dictionary search. Itaccepts a variable number of items off of the stack, 'n' isthe number of those item. A special case for the value of 'n'exists, when it is '-1' it sets the order to the minimalsearch order.; ==== sgr ( u -- : set ANSI terminal SGR attribute ) ========='sgr' takes a number and emits it as a 'Select GraphicRendition' command, which is a standard ANSI Escape sequenceused for terminal control. SGR commands relate to colors andhow the text is presents, for example numbers $1E to $25 areused to set the foreground color, $28 to $2F the backgroundcolor. $0 is used to reset all of the attributes, $8 is usedto conceal character output, $7 for reverse video. Not allSGR commands are processed by the VT100 hardware, and iftalking to the device over the UART it depends on the terminalemulator you are using.Examples:0 sgr ( reset terminal SGR attributes )$1f sgr ( set foreground color to red )$2a sgr ( set background color to green ); ==== sign ( n -- : hold '-' if n negative ) ================='sign' is a word used in conjunction with the pictured numericoutput routines ('<#', '#s' and '#>'), it holds a '-' is thesigned number it is given is negative.; ==== source ( -- a u : get source string ) =================='source' retrieves the address and length of the currentTerminal Input Buffer (TIB). This contains the current linethat is being processed, this is the line that is retrievedby the word 'query'.Usage:source type ( a simple quine ); ==== source-id ( -- 0 | -1 : identify input source ) ========'source-id' is used to identify the input source, whetherthe interpreter is reading input from the user (0) or evaluatingtext within a string (-1)Example usage:: test $" source-id . cr " count evaluate ;test ( prints FFFF or -1 )source-id . ( prints '0')When a block is evaluated with 'load' -1 is returned by'source-id' as it is evaluating the block as a string.; ==== sp@ ( -- u : variable stack depth ) ===================='sp@' is an assembly instruction which returns the currentdepth of the variable stack.; ==== space ( -- : emit space character ) ===================='space' emits a single space character to the current outputdevice. That is all.; ==== spaces ( n -- : emit 'n' spaces ) ======================'spaces' emits 'n' number of spaces, if 'n' is greater thanzero. This is a useful word for formatting.Usage:0 spaces ok1 spaces ok2 spaces ok-1 spaces ok; ==== span ( -- a : character count from expect, variable ) =='span' is a variable which contains the latest character countfrom 'expect'. Consult 'expect' for more information.Usage:4000 20 expectspan @; ==== state ( -- a : state variable ) ========================'state' is a variable that contains the global state of theForth interpreter loop, which can be in either compile orcommand mode. 'state' contains -1 for command mode, 0 forcompile mode. It can be set directly to change the interpreterstate, or read to make words change their behavior based onthe state (which is generally not the best thing to do). Thewords '[' and ']' can be used to switch the state as well.Usage:: ] -1 state ! ;: [ 0 state ! ; immediate: example [ 2 2 + ] literal ;example . ( prints '4' ); ==== =string ( b1 u1 b2 u2 -- f : string equality ) =========This word implement a test for string equality, it comparestwo strings specified by two address-length pairs and returnsa boolean that determined whether the strings are equal ornot (-1 for true/equal, 0 for false/not-equal). The word isunusual as it accepts four parameters on the stack, which isbad practice for Forth words which is most circumstances shouldonly accept three parameters. This word is used internally fordoing the dictionary search.Usage:: s1 $" Hello " count ;: s2 $" Bye! " count ;s1 s2 =string . ( prints '0' )s1 s1 =string . ( prints '-1', or 'FFFF' ); ==== /string ( b u1 u2 -- b u : advance string by u2 ) ======'/string' advances a string 'b u1' by 'u2' characters, if thereare enough characters left to advance the string by. This isobviously a word that is useful when dealing with strings,strings in Forth commonly come in two type: counted stringsand address-length based strings. This word deals with thelatter type of string.; ==== swap ( u1 u2 -- u2 u1 : swap two variables ) ===========It swaps two variables on the stack, its stack effect describesthe word perfectly. This is a simple word that will be usedquite a lot, memorize it quickly!Usage:1 2 ( -- 1 2 )swap ( 1 2 -- 2 1 ); ==== switches ( -- u : get state of switches ) =============='switches' retrieves the state of the two state switches onthe board, the values are already debounced. There are eightswitches which each have a single LED next to them (which canbe controlled with 'led!'). The lowest eight bits are usedfor the switch states, 1 for on, 0 for off.Example usage:: select 1 swap lshift switches swap and 0= 0= ;: sw0 0 select ; : sw1 1 select ; : sw2 2 select ;: sw3 3 select ; : sw4 4 select ; : sw5 5 select ;: sw6 6 select ; : sw7 7 select ;: switches->leds switches led! ;; ==== then ( -- : part of if...then or if...else...then ) ===='then' should only be used inside a word definition and aspart of an 'if...else...then' or 'if...then' sequence, it isused to terminate both sequences with execution continuingafter 'then'. The words 'if' and 'else' should also beconsulted. An exception may be thrown if this word is usedoutside a word definition, or if there is not a correspondingif. It is an immediate word.Usage:: invalid then ; ( <- invalid usage, no matching 'if' )then ( <- invalid usage, outside word definition ): example dup if 1+ then ; ( 0 | x -- 0 | x+1 )4 example . ( prints '5' )0 example . ( prints '0' ); ==== throw ( ? n -- ?, R: ? -- ? : throw exception ) ========'throw' along with 'catch' are the Forth exception handlingroutines, 'throw' throws an exception if the number provided toit is non-zero. An exception unwinds the return stack untila 'catch' is encountered, the word 'quit' contains the exceptionhandler of last resort. Numbers from -255 to 0 are reserved forstandard Forth errors.Usage:: fail $1000 throw ;: partially-executed cr ." Hello " fail ." World!" cr ;: catches-throw ' partially-executed catch u. ;catches-throw ( prints only 'Hello' then '1000' ); ==== thru ( k1 k2 -- : load from k1 to k2 ) ================='thru' calls 'load' on a range of blocks from 'k1' to 'k2'inclusively. It is used to evaluate a range of blocks and asa convenient way to load software off of mass storage.Code and data is stored in Forth blocks, 'thru' is used to loadthat data. The word 'index' can be used to give an overviewof blocks, as the convention is to have the first line of theblock as a description.Usage:8 9 thru ( evaluate blocks 8 and 9 ); ==== timer ( -- u : get value of timer ) ===================='timer' retrieves the current value of the hardware time in theFPGA, this peripheral can be controlled with the 'timer!' word,which is used to control the timer.; ==== timer! ( -- : set timer ) =============================='timer!' sets the hardware timer control register, allowing thetimer to be enabled/stopped/reset and setting up the value atwhich the timer wraps around at (or triggers an interrupt). Thelayout of the timer control register is as follows:BIT - MEANING15 - Enable Timer (1 = enabled)14 - Reset Timer13 - Enable Interrupts12-0 - Timer Compare ValueThe word 'timer' can be used to read in the current value ofthe timer.; ==== tuck ( n1 n2 -- n2 n1 n2 : tuck value ) ================'tuck' is a simple word that manipulates the stack, its stackcomment describes what it does. It tucks a variable behindthe second most item on the stack.Usage:5 7 ( -- 5 7 : two example numbers are entered )tuck ( 5 7 -- 7 5 7 : tuck does its job ); ==== type ( b u -- : print out a string ) ==================='type' prints out a string, specified by an address 'b' anda length 'u'. The output goes to the same place as 'emit'does, which is usually an output device viewable by theprogrammer.The examples use the words '$"' and 'count' which should beconsulted as well. '$"' compiles a string literal into thedictionary as a counted string, 'count' converts this toan Address-Length pair needed by type.Usage:: hello cr $" Hello, World!" count type cr ;hello ( execute newly defined word )Hello, World! ( it prints 'Hello, World! ); ==== u< ( u1 u2 -- f: unsigned less than ) ==================Unsigned less than of two numbers.; ==== u> ( u1 u2 -- f: unsigned greater than ) ===============Unsigned greater than, this is not an assembly instruction.; ==== u>= ( u1 u2 -- f: unsigned greater or equal to ) =======Is 'u1' greater than or equal to 'u2', this is an unsignedoperation.; ==== u. ( u -- : print out number in current base ) ========='u.' prints out an unsigned number in the current output base,this number uses the area at the end of the dictionary andthe beginning of the PAD area as temporary storage.; ==== um* ( u u -- ud : unsigned multiply ) ==================Unsigned multiply, it takes two single cell numbers and returnsan unsigned double cell number.; ==== um+ ( u u -- u carry : unsigned add with carry ) =======Unsigned addition with carry, this word is used to implementthe some of the arithmetic operations, although it is notvery useful directly. 'um+' is used directly to implement 'um*'which in turn is used to implement '*'.; ==== um/mod ( ud u -- ur uq : unsigned modulo divide ) ======Unsigned division of an unsigned double cell number by a singlecell number and leaves the remainder, 'ur' and the quotient,'uq'. This is a slow operation as it is not implemented as aninstruction within the H2 CPU. It will throw and exception ifthe divisor is zero. The word is used to implement the otherdivision and modulus operations.; ==== until ( -- : begin...until loop ) ======================'until' is a compile only word that should be used as part ofa 'begin...until' loop within a word definition. It is aconditional looping mechanism that pops and tests a value atrun time, and jumps back to the corresponding 'begin' if thevalue is zero, otherwise execution continues after the 'until'.Usage:: invalid until ; ( <- invalid usage, no matching 'begin' )until ( <- invalid usage, used outside a word definition ): test begin 1- dup . ?dup 0= until cr ." done " cr ;3 test 2 1 0 ( '3 test' prints '2 1 0' )done ( and also prints 'done' ); ==== update ( -- : mark last loaded block as dirty ) ========Marks the last loaded block as being dirty (the last loadedblock block number is stored in the variable 'blk'). A dirtyblock will be written to disk on when 'flush', 'save-buffers',or another block is loaded from disk.Usage:5 block ( block '5' loaded, block address returned )swap 99 ! ( store '99' in block buffer )update ( mark block as dirty )save-buffers ( write out block buffer back to block '5' )( block '5' now contains '99' in its first byte, which has )( been saved to disk ); ==== u.r ( u +n -- : print u right justified by +n ) ========'u.r' is a general purpose numeric formatting word, it printsout the number 'u' as an unsigned number in the current outputradix, preceded by '+n' spaces, minus the number of spacesneeded to display 'u' in the current output radix, or rightaligned. This function uses the area between the end of thedictionary and the beginning of the PAD area as temporarystorage.Usage:Typed | <- Result -> |4 6 u.r 4 ok99 6 u.r 99 ok99 5 u.r 99 ok; ==== variable ( -- ; <string> : create a new variable ) ====='variable' parses the next space delimited string from theinput string and makes a new named variable. The variable willbe initialized with zero, although this is not guaranteed to bethe case with all Forths. Variables are just normal words thatpush a location onto the dictionary of where the variable isstored, it can be accessed with the '!' and '@' words, onlyone cell of storage space is reserved. The created word isnot an immediate word.; ==== ver ( -- u : push version information ) ================Pushes the version number of the eForth implementation. Theformat of the version is the major version is stored in theupper byte and the minor version information is stored in thelower byte.The minor version number changes on minor updates, the majorversion changes when there are major updates in how theinterpreter works that could potentially break code.; ==== while ( -- : begin...while...repeat loop ) =============; ==== within ( u hi lo -- f : is u within a range? ) ========='within' is used to test with a value is within a rangespecified with a maximum and minimum value.; ==== word ( c -- a; <string> : parse a word ) ==============='word' parses the next word in the input stream and returns anaddress to a counted string. 'counted strings' have their firstbyte as their string length, which can be extracted with theword 'count'. The delimiter is given as 'c', a special caseexists when 'c' is a space, as all characters up to the ASCIIspace are treated as delimiters.; ==== words ( -- : list all words in dictionary ) ============This lists all of the words in the dictionary that are on thecurrent search order. Each vocabulary is listed with the addressof that vocabulary as a prefix.; ==== xor ( u1 u2 -- u : bit wise exclusive or ) =============Bitwise exclusive or of two numbers, there is nothing moreto this function than that.; ==============================================================; ==== ASCII Character Table ===================================The following section presents a database of all of the ASCIIcharacters, from 0 through to 127 inclusive. The format of thedatabase is; decimal, octal, hex then binary value, character(or name) and finally a column with a short description.Columns are separated by spaces. There is one entry per line,with the first line of each block containing an index entryinstead of an ASCII character description.; ==== ASCII: NUL (0) to SO (14) ===============================0 000 00 00000000 NUL Null char1 001 01 00000001 SOH Start of Heading2 002 02 00000010 STX Start of Text3 003 03 00000011 ETX End of Text4 004 04 00000100 EOT End of Transmission5 005 05 00000101 ENQ Enquiry6 006 06 00000110 ACK Acknowledgment7 007 07 00000111 BEL Bell8 010 08 00001000 BS Back Space9 011 09 00001001 HT Horizontal Tab10 012 0A 00001010 LF Line Feed11 013 0B 00001011 VT Vertical Tab12 014 0C 00001100 FF Form Feed13 015 0D 00001101 CR Carriage Return14 016 0E 00001110 SO Shift Out / X-On; ==== ASCII: SI (15) to GS (29) ===============================15 017 0F 00001111 SI Shift In / X-Off16 020 10 00010000 DLE Data Line Escape17 021 11 00010001 DC1 Device Control 1 (oft. XON)18 022 12 00010010 DC2 Device Control 219 023 13 00010011 DC3 Device Control 3 (oft. XOFF)20 024 14 00010100 DC4 Device Control 421 025 15 00010101 NAK Negative Acknowledgement22 026 16 00010110 SYN Synchronous Idle23 027 17 00010111 ETB End of Transmit Block24 030 18 00011000 CAN Cancel25 031 19 00011001 EM End of Medium26 032 1A 00011010 SUB Substitute27 033 1B 00011011 ESC Escape28 034 1C 00011100 FS File Separator29 035 1D 00011101 GS Group Separator; ==== ASCII: RS (30) to Comma (44) ============================30 036 1E 00011110 RS Record Separator31 037 1F 00011111 US Unit Separator32 040 20 00100000 SPACE Space33 041 21 00100001 ! Exclamation mark34 042 22 00100010 " Double quotes (or speech marks)35 043 23 00100011 # Number36 044 24 00100100 $ Dollar37 045 25 00100101 % Procenttecken38 046 26 00100110 & Ampersand39 047 27 00100111 ' Single quote40 050 28 00101000 ( Open parenthesis (or open bracket)41 051 29 00101001 ) Close parenthesis (or close bracket)42 052 2A 00101010 * Asterisk43 053 2B 00101011 + Plus44 054 2C 00101100 , Comma; ==== ASCII: Hyphen (45) to Semicolon (59) ====================45 055 2D 00101101 - Hyphen46 056 2E 00101110 . Period, dot or full stop47 057 2F 00101111 / Slash or divide48 060 30 00110000 0 Zero49 061 31 00110001 1 One50 062 32 00110010 2 Two51 063 33 00110011 3 Three52 064 34 00110100 4 Four53 065 35 00110101 5 Five54 066 36 00110110 6 Six55 067 37 00110111 7 Seven56 070 38 00111000 8 Eight57 071 39 00111001 9 Nine58 072 3A 00111010 : Colon59 073 3B 00111011 ; Semicolon; ==== ASCII: Less than (60) to Uppercase J (74) ===============60 074 3C 00111100 < Less than61 075 3D 00111101 = Equals62 076 3E 00111110 > Greater than63 077 3F 00111111 ? Question mark64 100 40 01000000 @ At symbol65 101 41 01000001 A Uppercase A66 102 42 01000010 B Uppercase B67 103 43 01000011 C Uppercase C68 104 44 01000100 D Uppercase D69 105 45 01000101 E Uppercase E70 106 46 01000110 F Uppercase F71 107 47 01000111 G Uppercase G72 110 48 01001000 H Uppercase H73 111 49 01001001 I Uppercase I74 112 4A 01001010 J Uppercase J; ==== ASCII: Uppercase K (75) to Uppercase Y (89) =============75 113 4B 01001011 K Uppercase K76 114 4C 01001100 L Uppercase L77 115 4D 01001101 M Uppercase M78 116 4E 01001110 N Uppercase N79 117 4F 01001111 O Uppercase O80 120 50 01010000 P Uppercase P81 121 51 01010001 Q Uppercase Q82 122 52 01010010 R Uppercase R83 123 53 01010011 S Uppercase S84 124 54 01010100 T Uppercase T85 125 55 01010101 U Uppercase U86 126 56 01010110 V Uppercase V87 127 57 01010111 W Uppercase W88 130 58 01011000 X Uppercase X89 131 59 01011001 Y Uppercase Y; ==== ASCII: Uppercase Z (90) to Lowercase h (104) ============90 132 5A 01011010 Z Uppercase Z91 133 5B 01011011 [ Opening bracket92 134 5C 01011100 \ Backslash93 135 5D 01011101 ] Closing bracket94 136 5E 01011110 ^ Caret - circumflex95 137 5F 01011111 _ Underscore96 140 60 01100000 ` Grave accent97 141 61 01100001 a Lowercase a98 142 62 01100010 b Lowercase b99 143 63 01100011 c Lowercase c100 144 64 01100100 d Lowercase d101 145 65 01100101 e Lowercase e102 146 66 01100110 f Lowercase f103 147 67 01100111 g Lowercase g104 150 68 01101000 h Lowercase h; ==== ASCII: Lowercase i (105) to Lowercase w (119) ===========105 151 69 01101001 i Lowercase i106 152 6A 01101010 j Lowercase j107 153 6B 01101011 k Lowercase k108 154 6C 01101100 l Lowercase l109 155 6D 01101101 m Lowercase m110 156 6E 01101110 n Lowercase n111 157 6F 01101111 o Lowercase o112 160 70 01110000 p Lowercase p113 161 71 01110001 q Lowercase q114 162 72 01110010 r Lowercase r115 163 73 01110011 s Lowercase s116 164 74 01110100 t Lowercase t117 165 75 01110101 u Lowercase u118 166 76 01110110 v Lowercase v119 167 77 01110111 w Lowercase w; ==== ASCII: Lowercase x (120) to DEL (127) ===================120 170 78 01111000 x Lowercase x121 171 79 01111001 y Lowercase y122 172 7A 01111010 z Lowercase z123 173 7B 01111011 { Opening brace124 174 7C 01111100 | Vertical bar125 175 7D 01111101 } Closing brace126 176 7E 01111110 ~ Equivalency sign - tilde127 177 7F 01111111 DEL Delete
