Frequently Used Words in Forth
Operators
| Word | Description |
|---|---|
| 1+ 1- | increment, decrement |
| 2* 2/ | Double/ Divide by 2 |
| /MOD | Modulo operation |
| = < > <= >= <> | relational operators |
| ! +! -! | assignment operators |
| AND OR XOR | logical operators |
| << U>> | bit shift |
| MIN MAX | compares 2 values at the top of the stack and returns the smaller number (MIN)/larger number (MAX) |
| . | prints the top most value on the stack |
| .S | prints all values in stack |
| @ | the value on top of the stack points to a memory address which value is put on top of the current stack |
| + - * | plus, minus, multiply |
| SWAP | swap 2 values on top of stack with each other |
| DUP | duplicate the value at the top of stack and place it on stack |
| DROP | delete the value at top of stack |
| OVER | copy the 2nd most value on top of stack and overwrite the first value in the stack |
| ROT | rotate the top 3 values in stack |
| 2SWAP | Reverses the top two pairs of numbers. |
| 2DUP | Duplicates the top pair of numbers. |
| 2OVER | Makes a copy of the second pair of numbers and pushes it on top. |
| 2DROP | Discards the top pair of numbers. |
| MOD | push the remainder into the stack |
Variable Declarations
| Word | Description |
|---|---|
| VARIABLE {name} | Declare a variable. Using an variable will only return its memory address. use @ to return the value inside the address |
| {value} CONSTANT {name} | declare a constant value |
| : {name} {operation} ; | Declare a word. a new line can be started within operation. |
| ."hello world" | print out a string |
| CR | print out a carriage return |
| {conditional statement} IF {true operation} THEN | if statement. can only be used when declaring a word. Can be nested |
| {conditional statement} IF {true operation} ELSE {false operation} THEN | same as above, but with else |
| {loop num} {initial value} DO {operation} LOOP | loop statement. same rules as if statement apply. |
| BEGIN {conditional statement} WHILE {operation} REPEAT | indefinite loop. Can not use counters or UNLOOP |
| BEGIN {operation} AGAIN | Infinite loop, to branch out use EXIT |
| I J | counters for loop |
| UNLOOP | get out of loop |
| EXIT | branch out while executing a WORD |
| SPACE | print out a space character |
| {num} EMIT | print out a character with ASCII code |
| {num} SPACES | print out a space num times |
Redstone Input/Output
| WORD | DESCRIPTION |
|---|---|
| IOXADDR | set the bus ID of I/O Device you want to use |
| {value} IOX! | set the output of the I/O device |
| IOX@ | get the input value from the I/O device |
| {value} IOXSET | turn on the set value |
| {value} IOXRST | turn off the set value |
Other
| WORD | DESCRIPTION |
|---|---|
| PAGE | clear screen |
| SAVE" name" | name an empty floppy |
| {value} TICKS | sleep, 1 tick = 1/20 second |
| {num} TIMES {word} | execute a WORD num times |
| DISKID | print the disk ID of the disk currently in drive |
IO Expander Output Color Values
| Color | Value |
|---|---|
| White | 1 |
| Orange | 2 |
| Magenta | 4 |
| Light Blue | 8 |
| Yellow | 16 |
| Lime | 32 |
| Pink | 64 |
| Gray | 128 |
| Light Gray | 256 |
| Cyan | 512 |
| Purple | 1024 |
| Blue | 2048 |
| Brown | 4096 |
| Green | 8192 |
| Red | 16384 |
| Black | 32768 |
very very very very very very VERY VERY helpful thank you so much i can use the computer part now very useful info keep it up il def. tell my buds about this page
A useful shortcut: to check whether the redstone input at some colour value N is on, use “IOX@ N AND”. This can be handed straight to conditionals if N is a power of 2 (if value N is on, then true, else false). If N isn’t a power of 2 (i.e. multiple colour values), use “N IOX@ N AND =” instead, unless you want to effectively boolean OR all the summed-2^X-values-that-make-N together. If you’re checking that several are all on, I’d recommend just summing their colour values and using the second snippet.
If you want to wait for a input from the io expander you can do it like this.
(this code runs a loop for 600 ticks (30 seconds) while it waits for a signal from cable 16 (yellow)) Kudos to Nihiltres for helping out with the IOX@ 16 AND bit, as I had been struggeling with IOX @ = 16 for a while.
: TEST 600 0 DO IOX@ 16 AND IF .” TRUE” LEAVE ELSE .” FALSE THEN LOOP ;
Hope this helps anyone
: TEST 600 0 DO IOX@ 16 AND IF .” True” LEAVE ELSE .” False” DROP THEN LOOP ;
You need to add DROP to the false statement to not break the loop counter.
forth is designed to be far more “modular” than your using it there. i do a similar thing [i have a big "stop the machine" lever on the wall] but i do this
: IsReset IOX@ 16 AND 16 = ; (assuming a switch on yellow )
then main code:
: Something BEGIN Stuff IsReset UNTIL ;
you can then a) re-use IsReset in other words b) makes the mainline more sensible.
tip: make words for EVERYTHING
my main code for my door system is
BEGIN
200 TICKS
LightChanged IF DoDoors
THEN
IsReset UNTIL
the more you modularise the words themselves, the simpler it is to debug… e.g i can do
LightChanged .
or IsReset .
to test various aspects before i write the main code
hope that helps even more…
How do you print out text in a program Like how do you make the program put text on the screen
.”text is here” should work (don’t forget the dot).
So does your IsReset detect the lever if a lot of levers are on? I didn’t really understand what that 16 AND 16 = part does. I don’t fully understand how AND and = works.
This page didn’t really teach me a lot. There are very basic operations here but the description is not for programming beginners (for example carriage return). Also, I expected Forth to be fully stack based and {num} TIMES {word} doesn’t seem to be fully stack based. I will probably learn 6502 assembly to create my own language and it will be as much stacked based as it can.
P.S. I am only 13
Some extra commands I’ve found somewhat useful that aren’t listed here:
COLD is the startup message, as in “cold start”. While this isn’t very useful in and of itself, knowing the command name means that you can redefine it! I like to redefine the startup message before saving my computer’s state to a blank floppy. Alternatively, use “PAGE COLD” on the command line to get that “just-started-up” feeling.
FREE returns the number of free bytes of RAM, as in the default COLD. I usually only use it when redefining COLD, but I’m sure it can be otherwise useful.
RADIX is the variable for the system radix. Want all numbers to be input and output as binary? Just “2 RADIX !”. Remember, input is assumed to be in the radix you’ve chosen, so you’ll have to “1010 RADIX !” to get back from binary to decimal, and you can’t use digits higher than the ones that exist in your current radix. Existing words and variables don’t need to be changed, but beware radices high enough to cause numbers and words to conflict. I haven’t properly tested what oddities happen if you select a number less than 2, but it doesn’t seem like a good idea.
I forgot to mention something related to FREE: the system assumes that numbers are signed, so “32767 1 + .” prints “-32768″. To print FREE properly, use “FREE U.”; “U.” tells the system to interpret the number as unsigned when printing it, so “32767 1 + U.” returns “32768″. Unsigned numbers use the interval [0, 65535] instead of the signed number interval [-32768, 32767]. If your computer has 4 or more 8K RAM Modules, this is important, as you may have more than 32767 bytes of RAM free.
Thank you very much for your help. But I have still a problem.
Hm… could it be, there is no way to use this system like a PLC? If I’m right there is nor “real” infinite loop. Even if I use BEGIN and AGAIN the loop stop after 30 seconds or something like that. But for a use like a PLC it would be great if the system infinite process the programm. Is there a way? Or have I still use the “usual” redpower for these things?
I have the same problem, but you should be able to set up a loop with the words themselves.
: FIRST FIRST ;
If that doesn’t work, try calling in a cycle.
: FIRST SECOND;
: SECOND FIRST ;
the main issue is that leaves no way to exit so instead use
: FIRST SECOND;
: SECOND KEY? IF QUIT ELSE FIRST THEN ;
personally I put the KEY? as deep into my loop as I can (so it gets called often and I can stop a malfunctioning program as fast as possible). KEY? just checks the input buffer for a waiting keystroke, it doesn’t matter when the key was hit so there is no particular timing required between hitting the key and the check.
Odd. Tried to include “body of loop” in brackets (after the initial FIRST) but it never showed up. Unfortunately my proposals won’t work since they are referencing a word which doesn’t exist yet.
In testing I’ve noticed that executing things like
BEGIN (loop) AGAIN
from the interpreter only runs once but as part of an executed word they work correctly.
: QUARRY BEGIN (loop) AGAIN ;
BEGIN and AGAIN are compile time loops, you can’t use them in the interpreter. I think they also clobber up memory, so
Is there a way to make a word run in the background? My word is basically an infinite loop but if I use the exit command it stops the loop and when I run the loop I can’t do anything else. To get out of it I end up having to restart the computer. Is there a command that lets me continue to use the computer once an infinite loop is working?
>Is there a way to make a word run in the background?
You could use an IO Expander to hook multiple CPUs to a “master” CPU, where turning on or off a colored wires will run/stop “background” tasks on one or more sub-CPUs. It’s not like CPUs are very expensive in terms of resources (compared to whatever process you’d need multiple CPUs to run effectively).
Technically an IO Expander isn’t needed for inter-computer communication. The computers are capable of communicating directly to each other by reading and writing to the ‘redbus’ which is shared by all computers connected to the ribbon cable. Unfortunately I do not know enough on the subject to be able to explain it fully…
It’s so slow when it comes to compilation >.>
hi
I try to type in .”Hello World” into the FORTH prompt but it says Unknown Token: .”Hello
wait nevermind
you need to define it in a word to print:
: HELLOWORLD
.” Hello World!”
;
you don’t /have/ to define a word, you can print in immediate mode.
i think the error was more the missing space after the
[dot][quote]
words in forth are quite specifically a string of non space separated chars… the word which prints is in fact the .” part the space after the quote separates the .” word from the text you need to print.
so, in the above suggestion, you have actually shown it correctly, the questioner hadn’t tho – which is probably the problem
the way that a word can be defined as /any/ char can be confusing to even me
[ironic understatement
]
e.g. consider the difference between
3 IOX! ( sets the IO expander to 3 ) – the ! is part of the word
compared to
3 IOXADDR ! ( sets the current IOX address to 3 – the ! is a separate word in forth meaning “store the stack (3 here) in this variable (IOXADDR)”
.. apols, just noticed you were correcting y’self – but the reply is the same
Hi there, Have a question.. Im using Nihiltres method to check if an Cable is powered. but it has to count each time it is live. i’ve thought about just using a delay. but its not as.. perfect as i was hoping. 15 button presses count 16 times. i then thought of checking to see if a variable was false. if not, then dont increase the count. but if no then increase the count.
then after the increase count by one command, have it set variable to true. heres what i mean in just a simple basic.
if input 1 live then
if z is false then count ++ z set true
else
z set false
endif
if that makes sense.
BASICALLy, i wanted to know if there was a way easier way to do this. as im going to be using all 16 channels on the IOX and think 16 ?? or 15?? anyway 16 variable is a stupid idea. unless i use an array… does forth do arrays?
sCRAtch the old question. i think i came up with a way around it. but now i have a new question.
Variables and strings.. HOW? can you store a string into a variable?
I’m sorry to tell you this but creating strings is not a breeze. I think you might find the FORTH dictionary useful
*******integratedredstone.wikispaces.com/Forth+Dictionary
Go to the section on “Variables, constants and alike” and check out the word CREATE.
Remember that Strings are actually Arrays
… but I could be wrong
Does it just happen to me or is there a problem with the FORGET command
When a compilation fails because of a syntax error or when I define a word 2 times, FORGET will only delete the last defined (as intended) but cannot seem to find the second one when I reFORGET. The word still shows up when I use WORDS…
Whats up with that? /scratch head
Nope, your totally right, i get the same issue, it appears in words. but you can forget the word, nor can you execute the remaining word ” Unknown Token” error.
I ended up with 5 T1 ‘s once.. accidently.
Can somebody please help me with this code here:
: lights_f1_on
4 IOXADDR !
5 TICKS
1 IOXSET
2 IOXRST
5 TICKS
32 IOXADDR !
;
: lights_f1_off
4 IOXADDR !
5 TICKS
1 IOXRST
2 IOXSET
5 TICKS
32 IOXADDR !
;
: lights_f2_on
4 IOXADDR !
5 TICKS
4 IOXSET
8 IOXRST
5 TICKS
32 IOXADDR !
;
: lights_f2_off
4 IOXADDR !
5 TICKS
4 IOXRST
8 IOXSET
5 TICKS
32 IOXADDR !
;
: lights_office_on
4 IOXADDR !
5 TICKS
16 IOXSET
5 TICKS
32 IOXADDR !
;
: lights_office_off
4 IOXADDR !
5 TICKS
16 IOXRST
5 TICKS
32 IOXADDR !
;
: stair_on
4 IOXADDR !
5 TICKS
32 IOXSET
5 TICKS
32 IOXADDR !
;
: stair_off
4 IOXADDR !
5 TICKS
32 IOXRST
5 TICKS
32 IOXADDR !
;
: Server
32 IOXADDR !
CR .” Server application now running”
BEGIN
CR .” In loop”
THEN
1 IOX@ = IF
lights_f1_on
CR .” Floor 1 lights turned on”
32 IOXADDR !
10 TICKS
THEN
2 IOX@ = IF
lights_f1_off
CR .” Floor 1 lights turned off”
32 IOXADDR !
10 TICKS
THEN
3 IOX@ = IF
lights_f2_on
CR .” Floor 2 lights turned on”
32 IOXADDR !
10 TICKS
THEN
4 IOX@ = IF
lights_f2_off
CR .” Floor 2 lights turned off”
32 IOXADDR !
10 TICKS
THEN
5 IOX@ = IF
lights_office_on
CR .” Office lights turned on”
32 IOXADDR !
10 TICKS
THEN
6 IOX@ = IF
lights_office_off
CR .” Office lights turned off”
32 IOXADDR !
10 TICKS
7 IOX@ = IF
stair_on
CR .” Stair lights turned on”
32 IOXADDR !
10 TICKS
8 IOX@ = IF
stair_off
CR .” Stair lights turned off”
32 IOXADDR !
10 TICKS
THEN
512 IOX@ = IF
CR .” Server application exiting…”
32 IOXADDR !
40 TICKS
EXIT
THEN
0 IOX@ = IF
CR .” Zero”
EXIT
THEN
CR .” None”
EXIT
CR .” None2″
AGAIN
CR .” Left loop”
EXIT
;
It is supposed to act as a server to control lights and other funtions via signals from client computers but instead it randomly changes outputs on IOXADDR 4. Help would be appreciated. Thanks.
WHY DO YOU NEED A COMPUTER FOR THIS??? I was writing the text below and thought that. And i thought it’s very strange that you need it and your inputs are also strange because for most of the lights you need several inputs on. I assume you still need it so I wrote a bit about your program (I did it before writing the above).
There are a lot of problems in your Server program i recommend making a word for each input check. Your program also might not detect if several inputs are on if you are using levers and too slow for buttons.
This might work but please note that mistakes are a part of programming (usually):
: lights_template_on
4 IOXADDR !
5 TICKS
IOXSET
5 TICKS
32 IOXADDR !
;
: lights_template_off
4 IOXADDR !
5 TICKS
IOXRST
5 TICKS
32 IOXADDR !
;
These were from your lights_f1_on and _off just the number before IOXSET and IOXRST was deleted.These templates will make less writing and less memory usage.
: lights_f1_on
1 lights_template_on
2 lights_template_off
CR .” Floor 1 lights turned on”
;
: lights_f1_off
1 lights_template_off
2 lights_template_on
CR .” Floor 1 lights turned on”
;
Didn’t finish it but i might come back here later and write the rest. I am quite lazy and only 13 years old
.
Please write if you don’t need the rest of the code!!!
Like many others i used a personal system for my base and majority of the coding works so far for my purposes.
One of them is a remote activation of a machine by use of the Wireless Redstone Mod, which works for me both mechanical means and direct iox manipulation.The Idea i used, is to enter a customized code, 1234
I have got the majority down, but i hit a weird bug? or my coding is wrong
Following code works for me except for number 3 & 4, which both returns 128.
.
: !# DUP 0 = IF 512 THEN DUP
1 = IF 1 THEN DUP 2 = IF 2 THEN DUP 3 = IF 4 THEN DUP
4 = IF 8 THEN DUP 5 = IF 16 THEN DUP 6 = IF 32 THEN DUP
7 = IF 64 THEN DUP 8 = IF 128 THEN DUP 9 = IF 256 THEN DUP
10 = IF 1024 THEN DUP 11 = IF 2048 THEN DUP
12 = IF 4096 THEN DUP 13 = IF 8192 THEN DUP
14 = IF 16384 THEN DUP 15 = IF 32768 THEN ;
thx, helped me alot; You should definitly add COLD (notices new RAM without RESET and you won’t lose all your words
)
647 514069hey there i stumbled upon your internet site looking about the internet. I wanted to say I enjoy the appear of items about here. Maintain it up will save for confident. 754450
Thanks this was helpful. I have a question though. I have lights that were turned on with a computer and won’t turn off. I’ve tried 0 IOX! and that didn’t work. Is there a way to turn them off without completely replacing my wiring?
{num} IOXSET should work.
Hello, I need some help with FORTH.
I need a program that runs continuously, and if an input wire(white) goes on, a loop is started.
If the white turns off, a different loop is started.
My questions:
1. Is this possible?
2. If so, how would I do it? I don’t understand much of this language, I need some help on this.
Anyone happen to know how to do logarithmic operations in FORTH? Or do we have to specify it ourselves?
Does this work?
Im trying a simple infinite loop broken by Redstone input.
: master
Begin
1024 iox@ if
Exit
Else
chickenfarm
Then
Again
;
How do you print out text in a program Like how do you make the program put text on the screen?
In Forth, i want to load a program from a disk in the disk drive, how i can do it? if in forth it isn’t posible, how i can create a program that do it??
i mean if someelse can put a code like:
: LOAD (program to load, this need to be written only for load the com)
compile: and now the comands that will do to work
compile: ;
PD: com = the command to load from the disk in the disk drive
And now if i tipe LOAD (THE PROGRAM HERE) i can load a program from a disk. Very thanks if anyone do this and paste here the example complete.
and now i am searching to load the disk like a program, example:
: LOADDISK (name of disk) (program that will be created)
compile: here a command that get all the programs of the disk an get
all to a program
compile: ;
I tipe this because i want to have the bigfoot tetris in my disk without restarting the cpu, i mean when i create the program LOADDISK i write
LOADDISK TETRIS TETRISOFBIGFOOT, when LOADDISK is the program, TETRIS the disk and TETRISOFBIGFOOT the command that if i write i can play the tetris xd.
Thanks for anyone for any answer, it will be very good for all
Hello can someone tell me how to get a number via user input inside an infinite loop ?
I want to build an elevator where you have to type only the number of the floor you want to go, without typing words.