SamForth documentation
Description of the page content
Edited documentation of SamForth, a Forth system for the SAM Coupé computer.
SamForth, is a Forth for the SAM Coupé, written by John A. Avis in 1991. SamForth is freeware. Unfortunately, its author lost the original source code.
I publish this documentation in order to make it easier to use and preserve it for the future. Also the original SamForth disks can be downloaded.
The original documentation files of SamForth have 64-character lines without line endings (the Tasword Two format, that also Outwrite can use). I extracted them from the MGT disk images, with the help of Edwin Blink's SAM Diskimage manager. (it's written for Windows 95/98 but works fine on Debian with the help of Wine). Then I joined the files and converted them to plain text with the help of dd
and cat
:
mv BDOC DOCB
cat DOC* | dd cbs=64 conv=unblock > samforth_doc.txt
Finally I included the code examples (that were provided in their own files) and edited the result with Vim. I also corrected all typos I found.
The structure and order of the contents has not been changed, excepting: data lists have been converted to tables; the two variables lists have been combined to a single table.
SamForth is a version of the Forth language designed for the SAM computer. It is not Fig-Forth, Forth-79, or Forth-83, but anyone who has knowledge of these versions should be able to cope with SamForth.
If you already know Forth you can turn to the section of these notes entitled Non-standard words and special SAM words.
SamForth normally uses pages 3-6 of SAM's memory as its program area, and pages 7 & 8 to store source. The SAM ROM is paged in as required.
Sometimes if you use the PALETTE
command to obtain a multi-coloured screen, flickering can occur as the SAM ROM is paged in and out. This can be rectified by using version B in which the SAM ROM remains paged in all the time, but the downside is we lose 16 KiB of working RAM.
As it stands SamForth will load automatically. You just insert the Forth disc and press F9.
Inevitably, you will not find every command here that you may want. But one of the beauties of Forth is that you can define your own commands, and if you wish to save them in a customised version, you can do so.
Details of Forth words
LIT
This word is mainly used internally by SamForth. It takes a number and places it on the Forth stack. It could be used in machine code as follows:
HEX CD C, FIND LIT , 4000 ,
This routine, if executed, would place the number 16384 (4000 in Hex) on the Forth stack.
EXECUTE
This word is also used internally by SamForth to execute Forth words, but it could be used to call a block of machine code.
20000 EXECUTE
The above sequence would execute machine code starting at address 20000.
BRANCH
Used internally by SamForth in words such as ELSE
. As the name BRANCH
suggests it is used to force the program to branch to a particular address. It could be useful if you wished to design you own control commands.
HEX CD C, FIND BRANCH , MY-CODE ,
This would make a branch to MY-CODE.
0BRANCH
Similar to BRANCH
, but it will only branch if the Forth stack contains a zero. The zero could be the result of a condition test which returns false or zero.
HEX CD C, FIND 0BRANCH , MY-CODE , FREDS-CODE ,
A branch will be made to MY-CODE if the Forth stack contains a zero, otherwise it will continue with FREDS-CODE.
SWAP
Exchanges the top two entries on the Forth stack. Top of stack becomes 2nd on stack, and second on stack becomes top of stack.
2 3 SWAP . .
will print 2 3. If there were no SWAP
, 2 3 . .
would print 3 2.
DUP
Duplicates top entry on the Forth stack.
2 DUP . .
will print 2 2.
DROP
Removes the top entry from the Forth stack and discards it.
INTERPRET
Is used internally by Forth interpreter to interpret source code in the input buffer, or in the source code area.
(FIND)
Another internal word. Used by the Forth interpreter to find the execution address of a Forth word. It returns a zero if the word cannot be found. Used by the Forth word FIND
.
U*
Multiplies the top two unsigned numbers on the Forth stack and places their product on top of the stack as an unsigned double precision number.
4 16384 U* D.
will print 65536.
+
Adds the top two single precision numbers on the stack and places their sum as a single precision number on top of the stack.
2 2 + .
will print 4.
D+
Adds the top two double precision numbers on the stack and places their sum as a double precision number at the top of the stack.
65536 65536 D+ D.
will give 131072.
D.
Prints an unsigned double number.
-
Subtracts the top number on the stack from the second number on the stack and leaves the answer on top of the stack.
44 33 - .
will print 11.
MINUS
Negates single precision number at the top of the stack.
2 MINUS .
will produce -2.
DMINUS
Negates the double precision number at the top of the stack. We can use it to make the following definition:
: D-
DMINUS D+
;
131072 65536 D- D.
will show 65536.
NUMBER
This word is used by Forth to convert ASCII characters in the input buffer or source code area into double precision numbers. If the number is below 65536 the forth interpreter will convert it into a single precision number.
We can use NUMBER
to define a word that will input numbers during a program.
: INPUT
QUERY 13 WORD
DUP 1 + DUP DUP 1-
C@ 13 SWAP C!
NUMBER DROP
;
INPUT
will take number characters from the input buffer and convert them into a double precision number which is placed on the stack. If a single precision number is required the word DROP should be included, with no brackets around it. If you want double precision numbers omit the word DROP
.
EMIT
Will output an ASCII character to the screen, printer or other output device.
65 EMIT
will output an "A" to the screen.
U.
Will output the unsigned single precision number on the top of the stack to the current output device. The numbers are in the range 0 - 65535.
/MOD
Will divide the second single precision number on the stack by the top single precision number and leave the modulus (remainder) as second on the stack and the quotient on the top of the stack.
10 3 /MOD . .
will show 3 1.
CLS
Clears the screen.
CREATE
Used by :
, VARIABLE
, CONSTANT
, etc., to create new Forth words.
On its own, CREATE NEWWORD
will create a Forth word with no parameter field. It can be used to make a machine code definition. See also ;CODE
.
CR
Causes a "carriage return". Printing will re-commence at the left-most column one line down.
VLIST
List all the words currently in the Forth dictionary.
DECIMAL
Selects number base 10.
HEX
Selects number base 16.
When working in number bases other than 10 or 16 the above two words allow an easy return to a more normal way of working.
C,
Places a number in the range 0 - 255 into the next vacant address in the Forth dictionary. Can be used to make machine code definitions.
,
Places a number in the range 0 - 65535 into the next two vacant addresses in the Forth dictionary.
ALLOT
Reserves addresses in the Forth dictionary.
10 ALLOT
reserves 10 addresses. These can be reclaimed with -10 ALLOT
.
Use negative numbers with care as you could overwrite your Forth definitions.
!
Place the number 0 - 65535 held second on the stack into the address held on top of the stack.
20000 50000 !
is the Forth equivalent to the BASIC DPOKE 50000,20000
.
C!
Similar to !
but places numbers in the range 0 - 255 held second on the stack in the address held o n top of the stack.
12 16384 C!
is the Forth equivalent to the BASIC POKE 16384,12
.
@
Take a number in the range 0 - 65535 from the address held on the top of the stack, and place that number on the top of the stack.
16384 @ U.
equals the BASIC PRINT DPEEK 16384
.
C@
Similar to @
but takes a number in the range 0 - 255 from the address at the top of the stack and places that number at the top of the stack.
16384 C@ U.
equals the BASIC PRINT PEEK 16384
.
HERE
Places the number of the next vacant address in the Forth dictionary on the Forth stack.
LATEST
Places the address of the name field of the last Forth word in the dictionary on the stack.
:;
The colon indicates that the first word folowing it is the name of a new word to be created, and the Forth words following it are to be compiled as its definition and not executed immediately. The semi-colon marks the end of the compilation.
: FOUR 4 . ;
The example definition will print the number "4" whenever FOUR is entered.
DO LOOP DO +LOOP I
The Forth DO
- LOOP
loop is similar to the BASIC FOR
- NEXT
loop.
: TESTLOOP
30 0 DO
I . LOOP
;
The definition TESTLOOP will print out the numbers from 0 - 29. Note that 30 is not printed.
I
places the index number in the DO
- LOOP
on the Forth stack.
DO
- +LOOP
is similar to a BASIC FOR
- NEXT
loop using STEP
.
: TESTLOOP2
30 0 DO
I . 2 +LOOP
;
This definition will print out the numbers 0 - 28 in steps of 2. Steps can be negative.
-
Multiplies two single precision integers at the top of the stack and places their product on the stack as a single precision number.
2 2 * .
will give the answer 4.
TYPE
Prints a string of characters to the screen or other output device. It takes two parameters, the start address of the characters and the number of characters.
16384 10 TYPE
will print the 10 characters occupying memory locations 16384 to 16393.
=
If the entry on the top of the stack is equal to the entry second on the stack they are replaced with "1" on the top of the stack. If they are not equal a "0" replaces them on the stack.
/
Will divide the second entry on the stack by the top entry and replace them with the quotient on the top of the stack.
10 5 / .
will give the answer 2.
If you try and divide by zero you will get the error message "Division by zero".
MOD
Divides the second entry on the stack by the top entry and replaces them with the modulus (remainder) on the top of the stack.
11 5 MOD .
will give the remainder 1.
BEGIN UNTIL
A control loop. The code between BEGIN
and UNTIL
will be repeatedly executed until UNTIL
finds a non-zero at the top of the stack.
: 30TIMES
0 BEGIN
DUP . 1 + DUP
30 = UNTIL DROP
;
Will print the numbers 0 - 29. The loop keeps executing until the count reaches 30 when =
(see above) will place a "1" on the Forth stack. If you end the loop with 0 UNTIL
the loop will repeat forever, or until you press SHIFT+F1 to force a break.
BEGIN WHILE REPEAT
Another control loop. The code between BEGIN
and REPEAT
is repeatedly executed while the condition before WHILE
remains true. When it becomes false a jump is made to the code after REPEAT
.
: 50TIMES
0 BEGIN
DUP . 1 + DUP 50 <
WHILE
." and "
REPEAT DROP
;
This definition will print the numbers 0 to 49 with an "and" in between. When the count reaches 50 the condition becomes false and a jump is made to the word DROP
.
<
When the second on the stack is less than the top of the stack a true flag (1) replaces them on the top of the stack. When the second on the stack is greater than the top of the stack a false flag (0) replaces them on the top of the stack.
1 3 <
will give a true flag (1).3 1 <
will give a false flag (0).1 1 <
will give a false flag (0).
>
When the second on the stack is greater than the top of the stack a true flag (1) replaces them on the stack. When the second on the stack is less than the top of the stack a false flag (0) replaces them on the stack.
1 3 >
will give a false flag (0).3 1 >
will give a true flag (1).1 1 >
will give a false flag (0).
R>
Transfers the 2nd entry on the Z80 stack to the top of the Forth stack. Use with care. Note that the 2nd entry is transfered because the top entry on the Z80 stack is the return address for the command R>
.
>R
Is the reverse of R>
. The top entry on the Forth stack is transferred to the second entry on the Z80 stack.
KEY
Waits for a keypress and places the ASCII code of the key on the top of the Forth stack.
OVER
A stack command, not the same as the BASIC OVER
. The second entry on the stack is copied to the top of the stack.
4 5 OVER . . .
will produce 4 5 4.
ROT
A stack command. The third entry on the stack is moved up to become the top entry on the stack.
4 5 6 ROT . . .
will produce 4 6 5.
2DUP
A stack command. The top 2 entries on the stack are duplicated.
4 5 DUP . . .
will give 5 4 5 4.
It is the equivalent of using OVER OVER
.
PAD
Places the address of the pad on the top of the stack. See the definition of INPUT under NUMBER
.
IF ELSE THEN ENDIF
If the condition before the IF
is true the code between IF
and ELSE
is executed and a jump is made to the code after THEN
. If the condition is false the code after the ELSE
is executed.
When there is no ELSE
, the code between IF
and THEN
is executed, otherwise a jump is made to the code after THEN
. ENDIF
is just a different name for THEN
.
: ?ONE
1 = IF ." One "
ELSE ."Not One"
THEN
;
: RIGHT
2 = IF 33 3 1 BEEP
THEN
;
In the above examples, if "1" is on the stack "One" is written; if any other number is on the stack "Not One" is printed. In the second example if "2" is on the stack a beep is sounded, otherwise nothing happens.
<BUILDS DOES>
Used to define new defining words, that is, words that define other words.
: ARRAY
<BUILDS
2 * ALLOT ( defining action)
DOES>
SWAP 2 * + ( runtime action)
;
10 ARRAY INDEX
25 8 INDEX !
8 INDEX @ . ( will give 25)
The example defines a defining word ARRAY, which in turn defines an array called INDEX with 10 slots. The code between <BUILDS
and DOES>
is what ARRAY will use when it defines the required word. In defining INDEX it takes the parameter 10 and multiplies it by two to ALLOT
20 addresses, two for each number to be placed in the array.
The code after DOES>
is the runtime action. The parameters 25 (the number to be stored) and 8 (the slot into which the number is to be stored) are on the stack when INDEX is called. DOES>
places the start address of the array on the stack. This is SWAPped so that 8 is on the top of the stack. The 8 is multiplied by 2 and added to the start address to give the address where 25 is to be stored. The store address is on top of the stack and the 25 to be stored second on the stack. The word "!" stores 25 in the store address. The final example reads the contents of the 8th store address and places them on the stack.
VARIABLE
Is a defining word already in the vocabulary. It is used to define variables.
VARIABLE SUM
will define a variable called SUM. !
is used to write to a variable, and @
is used to read a variable.
4 SUM ! SUM @ .
will print 4.
We could have defined VARIABLE
using <BUILDS
and DOES>
.
: MYVAR
<BUILDS
2 ALLOT
DOES>
;
CONSTANT
Is a defining word used to define constants.
4 CONSTANT FOUR
creates a constant called FOUR. Whenever FOUR is executed the number 4 is placed on the stack. Again we could have defined it using <BUILDS
and DOES>
:
: MYCONS
<BUILDS
2 ALLOT
DOES>
@
;
CMOVE
Moves blocks of code from one memory location to another.
It takes 3 parameters: source address, destination address, length of code.
16384 32768 10 CMOVE
will move the 10 bytes of code at 16384 to 32768.
A length of zero will do nothing.
Boolean Operators
AND
Operates on the bits of the top two numbers on the stack, removes them and leaves the result:
- 1 and 1 give 1
- 1 and 0 give 0
- 0 and 0 give 0
OR
Operates on the bits of the top two numbers on the stack, removes them and leaves the result:
- 1 and 1 give 1
- 1 and 0 give 1
- 0 and 0 give 0
XOR
Operates on the bits of the top two numbers on the stack, removes them and leaves the result:
- 1 and 1 give 0
- 1 and 0 give 1
- 0 and 0 give 0
NOT
Operates on the top number on the stack. If it is 1 NOT
replaces it with a 0, and if it is a zero NOT
replaces it with a 1.
0=
Is the same as NOT
.
Example
: TEST
DUP 11 < SWAP 0 > AND
IF ." YES"
ELSE ." NO"
THEN
;
The above example tests numbers to see if they are in the range 1 - 10.
Although testing multiple conditions is a common use of these operators in Forth, they can be useful in other ways, which is why a good book on Forth would be an asset.
FORGET
FORGET FRED
will clear the user dictionary from and including FRED and all words following FRED to the end of the dictionary.
FENCE
The original documentation reads:
Protects words in the dictionary fromFORGET
.
FIND FRED FENCE
will protect all words up to and including FRED.If you now try to do
FORGET FRED
you will get the error message "Inside Fence".
But actually FENCE
is a variable that holds the limit address, so the example code should be FIND FRED FENCE !
. Beside, the said error is not implemented— "Break" is shown instead. This have been finished in ForthCoupe.
U/MOD
Divides unsigned double precision number second on stack by unsigned single precsion number at the top of the stack. It leaves two single precision numbers, the modulus or remainder at second on stack and the quotient at the top of the stack.
Number Formatting
Numbers are already formatted by the word NUMBER, but if you want some special format with - signs, commas, or decimal points you must use the words below. They operate on a double precision number.
<#
Initiates number formatting.
#>
Finishes formatted output and leaves the address of the string at second on stack and the length on top of the stack ready for TYPE to print it out.
#
Generates an ASCII character for each digit in formatted output.
#S
Applies # above until the number is formatted.
HOLD
Used in formatted output to hold a character such as a decimal point or currency sign in the pad.
SIGN
Used in formatted output to hold a "-" sign if the number is negative.
: LP
<# # # ( two characters for pence)
ASCII . HOLD ( insert decimal point)
#S ( now the rest of the number as pounds)
ASCII L HOLD ( now the pound sign is printed)
#> TYPE
;
Note that the number is formatted backwards. "L" has been used for a pounds sign which my printer doesn't want to print.
0<
If the number on the top of the stack is negative it is replaced by a true flag (1), otherwise a false flag (0).
PICK
Stack control. n PICK
copies the nth entry on the stack to the top of the stack.
ROLL
Stack control. n ROLL
moves the nth entry on the stack to the top of the stack.
Non-standard words and special SAM words
DLOAD DSAVE
These words save and load a compiled dictionary. Their parameter is the name of the file.
DSAVE FILE
will save a compiled dictionary called FILE.FD and DLOAD FILE
will reload it, overwriting any dictionary already in memory.
BLOAD BSAVE
These load and save blocks of memory.
32768 80 BSAVE DATA
will save to the file DATA.FC the 80 bytes of memory starting from address 32768, but 50000 BLOAD DATA
will reload the file to address 50000.
See also under PAGE
.
INVERSE BRIGHT CSIZE SOUND FLASH BRIGHT PEN PAPER MODE CLS
These are the Forth equivalents of the BASIC commands, but remember that the parameters precede the command.
2 PAPER 15 PEN
OVERP
This is the Forth version of the BASIC command OVER
, but it is written OVERP
to avoid confusion with the Forth stack command OVER
.
TAB
This tabulates printed output across the screen.
9 TAB 18 TAB 27 TAB
will move the print position to columns 9, 18 and 27 respectively.
BLITZ
This command calls the SAM ROM routine. (see the technical manual).
32768 3 BLITZ
will execute the 3 commands starting at address 32768.
BLITZ$
Is a defining word which defines an array to hold your BLITZ
commands.
3 100 100 10 3 100 100 20 8 BLITZ$ CIRCLES
The first 8 numbers are the paramenters needed by the BLITZ
command. The last parameter "8" is the number of BLITZ
parameters and is used to set up the array.
Now by using the command CIRCLES
you can draw two circles one 10 pixels in diameter, and the other 20 pixels in diameter, around the co-ordinates 100,100.
The BLITZ
parameters reproduced from SAM's Technical Manual are:
PLOT
: 1 followed by x,y co-ordinatesDRAW TO
: 2 followed by x,y co-ordinatesCIRCLE
: 3 followed by x,y and the radiusOVER
: 4 followed by 0-3PEN
: 5 followed by 0-17CLS
: 6 followed by 0-1PAUSE
: 7 followed by 0-255
SCREEN
The Forth equivalent of the BASIC SCREEN$
command.
15 15 SCREEN
will return the code of the ASCII character or UDG at print position 15 row 15 column.
UDGDEF
Creates a user defined character replacing any of the existing characters from code 32 to 255.
It takes 9 parameters. The first 8 represent the dot patterns and the 9th is the character code.
24 24 255 60 60 36 36 144 UDGDEF
converts character 144 into a silly little figure of a man.
ROLS
This is the SAM ROM routine JROLS (see Technical Manual). The parameters are:
- Wrap: 0 for no wrap, -1 for wrap.
- Number of pixels to move by.
- Direction to move: 1=left, 2=up, 3=right, 4=down.
- Length of block in pixels.
- Width of block in pixels.
- X plot position.
- Y plot position.
This routine can be used to define Forth equivalents of the BASIC commands SCROLL
and ROLL
.
SOFF
This command has no parameters but "switches off" the sound chip.
SVC@ SVC! SV@ SV!
These are similar to the standard Forth words C@
, C!
, @
, and !
, but they operate on the SAM system variables in page 0. The address of the system variable as shown in the Technical Manual should be used.
HEX 5A40 SVC@ . DECIMAL
will read the SAM system variable "MODE". Although Forth uses the SAM ROM it is paged out much of the time. The above commands will also access page 1 with addresses within the range 32768 - 49151.
DRIVE
This command changes the default disc drive.
3 DRIVE
will change to Master DOS RAM disc (if you are using that system - Forth will also run under SAM DOS) and 1 DRIVE
will revert to the floppy drive 1.
PLOT DRAW DRAWBY
These are similar to their BASIC equivalents except that DRAW
is the equivalent of DRAW TO
and uses ab solute co-ordinates, and plot position 0 0 is at the top left of the screen. DRAWBY
uses relative co-ordinates like the BASIC DRAW
.
0 0 PLOT 255 0 DRAW 255 170 DRAW 0 170 DRAW 0 0 DRAW
will draw a line around the screen, using relative co-ordinates.
0 0 PLOT 255 0 DRAWBY 0 170 DRAWBY -255 0 DRAWBY 0 -170 DRAWBY
will draw a line around the screen using absolute co-ordinates.
COLOUR
Sets the permanent screen colours. The parameters are paper code and pen code.
9 15 COLOUR
produces blue paper and bright white pen, provided the PALETTE
has been left in its default state.
ASCII
Puts the character code of the character following the command on the stack.
ASCII A
puts the number 65 on the stack which is the character code for a capital A.
ERROR
Will print out a Forth error message.
1 ERROR
will print "Stack empty".
INKEY
Is similar to the standard Forth word KEY
but it does not wait for a key to be pressed.
COLD
Resets the system but does not clear the source code area.
FIND
Finds the execution address of the word which follows it.
FIND VLIST EXECUTE
would do the same as writing VLIST
.
WORD
Accepts input text as far as a delimiter and puts it into PAD
. It puts the start address of the text on the stack and the length of the text into the first address of the PAD
.
42 WORD
will accept text until a "*" is encountered,
Define the following word:
: COUNT DUP 1 + SWAP C@ ;
Now type QUERY 42 WORD
and enter "1234*56".
Follow this immediately by COUNT TYPE
.
The following will be printed: "1234". If you enter the command PAD C@ .
there will be a "4" printed on the screen. The "4" represents the number of characters entered before the delimiter.
If, however, you type in PAD 1 + 7 TYPE
you will find your your original entry of "1234*56" is printed. The whole entry is transfered to the PAD
, but the number of characters WORD has accepted is indicated by the number in the first address of PAD
and can be used by words such as COUNT
.
QUERY
Clears input buffer and accepts character input until RETURN
is pressed. It can be edited in the normal way. A word to accept string input could be defined as follows:
: INPUT$
QUERY 13 WORD
1 + SWAP PAD C@
CMOVE
;
The parameter is the address of the area of memory or string variable in which you wish to hold the inputs.
VARIABLE HOLDATA 8 ALLOT
defines an area of memory 10 bytes long in which you can hold your input.
Type HOLDATA INPUT$
and type in "DOG & CAT". Now type HOLDATA 10 TYPE
and you will print out "DOG & CAT", which is now held in HOLDATA.
RETYPE
This is similar to QUERY
but does not clear the input buffer enabling the text to be edited. Move the text into PAD
starting at the second address of PAD
before calling RETYPE
.
PAD
Puts the address of PAD
on the stack.
DIR
Prints to screen the directory of the current drive.
SAM
Returns to SAM BASIC. Come back to Forth by typing GOTO WARM
or by typing SHIFT+F7.
SC! SC@
Similar to C!
and C@
but they address the screen. Address 0 is at the top left hand corner.
."
Prints a string. It can only be used in compile mode.
: EXAMPLE
." This is an EXAMPLE"
;
BEEP
Uses the SAM's sound chip. It takes 3 parameters: note, octave, length.
Notes:
- B: 5
- C: 33
- C#: 60
- D: 85
- D#: 109
- E: 132
- F: 153
- F#: 173
- G: 192
- G#: 210
- A: 227
- A#: 293
Middle "C" is in the third octave so 33 3 1 BEEP
will produce middle "C".
More details are to be found in the Technical Manual.
AT
Similar to the BASIC AT
.
15 0 AT
(the equivalent to the BASIC AT 15,0
) will move the print position on the screen to row 15 column 0.
LINK
Changes print output.
1 LINK
will print to the bottom of the screen.2 LINK
will print to the normal screen.3 LINK
will redirect ouput to the printer.251 LINK
will allow control codes to be sent to the printer.
When Forth returns to input mode it will return you automatically to its normal mode of printing. Thus to print a VLIST
on the printer all you need input is 3 LINK VLIST
.
PAGE
Forth normally operates using pages 3, 4, 5 and 6. It pages in the SAM ROM as required.
10 PAGE
will page in pages 10 & 11 at address 32768. Pages 10 & 11 will remain paged in until the next PAGE
command. The PAGE
command gives you considerable control over your computer, but it also give you a greater opportunity to crash. If your Forth dictionary extends beyond 32768, be very careful how you use this command. You can page out the code you are executing. Make sure that all definitions that use PAGE are situated below 32768, and it is a good habit to restore page 5 as soon as you can in a definition.
10 PAGE 50000 C@ 5 PAGE
The PAGE
command affects the use of BLOAD
and BSAVE
. When a page other than page 5 is paged in at address 32768, files with a start address of less than 32768 will be loaded into, or saved from, pages 3, 4, 5, or 6 as usual. Where the file has a start address of 32768 or above, it will be loaded into, or saved from, the page that is currently paged in at 32768.
IN OUT
These are similar to @
and !
, but operate on ports rather than memory.
252 IN
will print the number of the page paged in at 32768.
;CODE
Terminates a colon definition without inserting an assembler command RET
(code 201, C9 in hex) allowing the user to continue the definition in machine code. Terminate the definition with either 201 C,
or use the word CODE:
.
CODE:
Resumes a colon definition terminated by ;CODE
allowing the user to continue in Forth after the machine code sequence.
BASE
Requires the numer base as a parameter.
2 BASE
will select binary. It is advisable to return to normal by using the words HEX
or DECIMAL
.
Notes on numbers
If a number which is input is less than 65536 Forth treat it as a single precision number, if it is greater than 65535 it is treated as a double precision number. If you wish to have a double precision number which is less than 65536 you must enter it as 65535 0
or 4 0
.
GRAB
Grabs an area of the screen and places it in the buffer area of screen memory starting at address 57345 with the screen paged into areas C & D. the parameters are x-co-ordinate, y-co-ordinate, length, width. It may be easier to use GRAB$
.
GRAB$
Defines a special Forth word to hold your GRAB
bed data. The parameters are x-co-ordinate, y-co-ordinate, length, width.
Example:
10 20 50 40 GRAB$ FORTHWORD
You can call your FORTHWORD whatever you wish.
PUT
In the screen modes 3 & 4 will put a block of data on the screen at the given co-ordinates. The data can be a block that has been grabbed using GRAB
or GRAB$
.
The parameters are x-co-ord, y-co-ord, data address, method of placing.
The method of placing is as follows:
- 0= overwrite with
INVERSE
option - 1= XOR with existing data.
- 2= OR with existing data.
- 3= AND with existing data.
- 4= overwrite with no
INVERSE
(faster than 0).
If you use PUT
after GRAB
the address of data will be 57345. It is difficult to use other addresses as GRAB
will look for them on pages 0 - 2 which are paged in as the command operates.
PUT$
Is designed to operate on the data you have stored as a Forth word using GRAB$
. The parameters are x-co-ord, y-co-ord, method of placing.
Example:
30 3 1 FORTHWORD PUT$
FILL
Will fill the area of memory containing the co-ordinates with the 16*16 pixel pattern at the given address.
The parameters are address, x-co-ord, y-co-ord.
If the address is zero the area will be filled with the current PEN
colour.
4 PEN 0 100 100 FILL
will fill the are enclosing co-ordinates 100,100 with PEN
colour 4.
We can define a word to fill in with the pen colour (the parameters are x-coord, y-coord, pen colour):
: PFILL
PEN 0 ROT ROT
FILL
;
?SCROLL
Switches the scroll message at the bottom of the screen on or off.
1 ?SCROLL
enables the message and is the equivalent of the BASIC SCROLL RESTORE
.
0 ?SCROLL
disables the message and is the equivalent of the BASIC SCROLL CLEAR
.
PALETTE
This command takes four parameters: colour, colour, palette entry and y-coordinate.
The colour parameters must be within the range 0 - 127. If the two colours are different you will get a flashing effect, if they are the same you get no flashing.
If the y-coordinate is non-zero it is the y-coordinate to alter the palette at.
The simple PALETTE
command to alter the paint pots can be defined as follows:
: SIMPAL
SWAP DUP ROT 0
PALETTE
;
That word takes two parameters: colour, palette entry.
EXPAND
Expands the Forth core dictionary to include user definitions allowing you to customize the Forth. Having called the command EXPAND
, typing HERE U.
will give you the length of code to save.
Type SAM and return to basic mode. Then save your expanded Forth with SAVE "MY FORTH" CODE 65536,length
, where length is the length given by HERE U.
.
Then alter line 20 of the BASIC interface program to load "MY FORTH" instead of "CODE". Save the BASIC interface under another name.
SAVE "ANOTHERNAME" LINE 1
If you save to another disc, remember to copy the small code file called "PAGE" to the new disc.
SamForth editor
The Forth editor stores source code as a continuous block usually in page 7 of SAM's memory. The address of the start of the block, usually 32768, is to be found in system variable "ST" (source top) at address 437. The end address of the source can be found in system variable "SE" (source end) at address 482.
Each line of source ends with code 13. This code is ignored by the interpreter.
A 15-line window is provided into the continuous block of code similar to a standard Forth screen. This window is used to create, edit and delete source code.
The start address of the current window is to be found in the system variable "LISTS" at address 506, and the end of the current window can be found in system variable "ELIST" at address 508.
Before entering any source we need to clear the source memory. We do this by using the command T CLEAR
.
T
makes the current window start at the start of source.
CLEAR
clears the source area from the top of the current window to the end of the source code block. In practice it makes the end address of the source code equal to the start address of the current window. We can now begin to enter our source code. We do this with the command NEWL
.
NEWL
creates 15 blank lines numbered 1-15. We enter the source code by typing the required line number and pressing the EDIT key - not the return key. If we type in "1" and press EDIT the words "1 EDIT" will appear on the screen. We can then enter our source code into the input line. Press RETURN and our source code appears in line 1 of the window. To enter source in line 2 type "2" and press the EDIT key and so on for each of the lines.
If we have made an error, say in line 4, we type in "4" and press EDIT and our line of source appears in the input line at the bottom of the screen where we can amend it as desired.
Input Line Keys
- DELETE deletes the characters to the left of the cursor.
- SHIFT+DELETE deletes the character to the right of the cursor.
- The left and right arrow keys move the cursor to the left and right in the input line.
- The up cursor key move the cursor to the start of the input line.
- The down cursor key moves the cursor to the end of the input line.
- F2 blanks the input line.
- F0 toggles insert mode on or off. When SamForth is first entered the insert mode defaults to "ON".
- F3 blanks the input line from the cursor to the end of the line.
- SHIFT+F1 will force a break in the Forth program.
When we have filled the current window we can enter the command NEWL
once more and we have the next window of blank lines.
More Editor Commands
D
D
takes as its parameter a line number. 2 D
will delete line 2. Line 3 will become the new line 2, line 4 the new line 3 and so on. The new line 15 will be the former first line of the next window if there is one. If there is not the current window will end at line 14.
S
S
also takes a line number as its parameter. 2 S
will insert a new line after line 2. This new blank line will be line 3, the old line 3 will become line 4 and line 15 will become the first line of the next window.
DEL
2 3 DEL
will delete line 2 and the 2 following lines. Line 5 will become line 2.
INS
2 3 INS
will insert 3 lines after line 2. Line 2 will become line 5.
E
3 E
will erase the source in line 3 but not delete the line.
C
1 2 C
will copy line 1 to line 2 and also into the PAD.
R
3 R
will replace line 3 with the text held in the PAD.
H
3 H
will hold line 3 in the PAD
for future use.
P
P
is used interally by other editor commands, but if you enter P
followed at once by a line of source, e.g. P THIS IS A LINE OF SOURCE
, that line will be entered as a new source line at the end of the source block.
Listing Commands
L
L
lists the current window on the screen or to the printer.
N
N
will list the next 15-line window (if there is one).
B
B
will list the previous 15-line window (if there is one).
UP
3 UP
will move the source up 3 lines. 3 lines will be lost from the top and 3 gained at the bottom.
DN
3 DN
will move the source down 3 lines. 3 lines will be gained at the top, and 3 lines lost at the bottom.
FROM
FROM
will move the start of the list. If you have defined a word called FRED, the command FROM FRED L
will list the current window from the word FRED
. It actually lists from the first occurence of !#FRED!#, which will normally be its definition.
F
F
is a shorter version of FROM
, but unlike FROM
does not justify the line in which the required word was found. You can do this with the command 1 DN
.
LIST
LIST
will list source, one definition at a time, pausing at the end of each definition. Pressing any key except SPACE will continue the listing. Pressing SPACE will terminate the listing.
LIST
does not list using the 15-line window and does not display any line numbers. It is preferable to use LIST
when printing source. When printing, LIST does not pause after each definition.
TO
Just as FROM
indicates the start of a current window or list, TO
indicates the end of a listing. FROM FRED TO FREDA LIST
will run a list from FRED up to but not including FREDA.
ES
This word makes the end of source the end of the current list. 3 LINK T ES LIST
will list the whole of your source to the printer.
SAVE
SAVE
will save source to disc. T ES SAVE PROG
will save the whole of your source to disc with the name PROG. The program will save the file to disc as PROG.FS. ("FS" means "Forth Source") Get into the habit of using the commands T ES
before you save a whole source program. If you just do a SAVE PROG
you may be saving only the current window. This may seem like a bind but it does enable you to save parts of your sour code. See below.
Always remember this is Forth. If a command is not there then define it yourself. If you use it often, use EXPAND
to include it in your customized version.
A command to save the whole of source:
: TSAVE
T ES SAVE
;
A command to clear the whole source area and load in new source:
: TCLOAD
T CLEAR LOAD
;
LOAD
LOAD
has two functions.
It is used first to load source code from disc. T LOAD PROG
will load the source to the beginning of the source area. If the command T
is not used it will load to the end of the current list.
It is used secondly to compile the source code into Forth. T ES LOAD
will compile the whole of your source.
It is possible to compile, list or save a part of your source. FROM FRED TO FREDA LOAD
will only compile the source from the word FRED up to but not including FREDA. FROM FRED TO FREDA SAVE PART
will save the same part of source to disc under the name PART.FS.
WHERE
If the compilation of your source ends with an error message using WHERE
will list your source from where the error occurred using a graphics character to flag up the offending word.
Note
It is possible to give the editor impossible commands, and when this happens it will make nonsense of the listing. Regain control by entering the commands T L
.
SamForth error report
1 - Stack empty
This message appears when you have insufficient data on the stack for the application you are running. Possibly the most common error.Example:
KEY 65 = IF EMIT THEN
What happens here is that having tested your input to see whether it is "A" (ASCII code 65), you no longer have 65 on the stack to EMIT
.
You should write it as
KEY DUP 65 = IF EMIT ELSE DROP THEN
You input your data, duplicate it, test the entry on the top of the stack. If it is 65 you print it, otherwise you discard it.
2 - Stack full
Your application generates too many unused parameters.
Example:
256 32 DO
I LOOP
The word I
is placing the index number of the loop on the stack and doing nothing with it.
256 32 DO
I EMIT LOOP
Will print the character set and leave the stack as it found it.
3 - Undefined word
You are trying to use a word you have not yet defined, or you have mistyped a word.
4 - Colon definitions only
Some words such as DO
, LOOP
, +LOOP
, BEGIN
, UNTIL
, WHILE#!, #!REPEAT
and ."
can only be used within colon definitions, and not in immediate mode.
5 - Division by zero
Division by zero does not seem to be allowed on any computer. It usually arises in a calculation. Use IF
to make sure it does not happen.
DUP 0 = IF DROP ELSE / THEN
6 - Return stack full
You have put too many parameters on the Return or Z80 stack. Unlikely to occur unless you make excessive use of ">R"
7 - Inside fence
You have attempted to FORGET
a word in the core dictionary, or one you have protected using the command FENCE
.
8 - Break
You have pressed the break keys (SHIFT+F1). Handy if your Forth program has gone into an indefinite loop, or is awaiting an impossible result from a calculation.
9 - Incomplete form
You have used a command like DO
without a LOOP
or a +LOOP
, or a BEGIN
without an UNTIL
etc.
10 - Not found
Occurs when you have used the editor commands F
, FROM
, or TO
followed by a word that cannot be found in the source.
11 - Editor error
You have tried to edit a line that does not exist.
Every time there is an error report, a warm restart occurs, and the Forth stack is cleared.
Machine Code Notes
Each SamForth definition is called using the assembler instruction CALL
(code 205, or CD in hex). Each definition must end in a RET
(code 201 or C9 in hex).
The Forth interpreter does this for you in the normal definitions, but if you want to write definitions in machine code the following notes will be useful.
The Forth words ;CODE
and CODE:
and ,
and CREATE
can be used for machine code definitions.
CREATE STARS1
6 C, 10 C, 197 C, 62 C, 42 C,
207 C, 193 C, 16 C, -7 C, 201 C,
This definition will print 10 stars.
In Z80 mnenomics:
LD B,10 ; Number of stars to print
LOOP PUSH BC ; Preserve B register
LD A, 42 ; ASCII code for asterisk
RST 8 ; Print asterisk
POP BC ; Restore B register
DJNZ LOOP ; Decrement B register
; If <>0 jump back to "LOOP"
RET
We can use ;CODE
in a similar way. The definition STARS2 does the same as STARS1.
: STARS2
;CODE
6 C, 10 C, 197 C, 62 C, 42 C,
207 C, 193 C, 16 C, -7 C,
201 C,
When we use CREATE
and ;CODE
in this way the definition must end with a RET
(code 201, C9 in hex).
We can also use ;CODE
with CODE:
to include machine code within a normal definition. STARS3 does the same as STARS1 and STARS2.
: STARS3
10 0 DO
;CODE
62 C, 42 C, 207 C,
CODE:
LOOP
;
In the last example the final RET
is inserted by the Forth interpreter in the normal way by executing the word ;
.
Useful calls
Address | Description |
---|---|
RST 8 | Output to screen, or printer, the character whose ASCII code is in the A register. |
RST 16 (10h) | Push the HL register on the Forth stack. |
RST 24 (18h) | Pop from the Forth stack into the HL register. |
RST 32 (20h) | Put the HL & DE registers on the Forth stack. HL will be top of stack, DE second on stack. |
RST 40 (28h) | Place top of Forth stack in HL register and second on the stack into DE register. |
RST 48 (30h) | Cause warm restart with error report. Error number in the A register. |
1805 (070Dh) | Call a routine in the SAM ROM. The address of the SAM routine must be in the IY register. The other registers must hold the parameters required by SAM.
|
Useful Calls in SamForth-B
The Forth words below provide the execution address of the Forth stack routines.
Enter them into machine code this way: 205 C, PUSH-HL ,
.
Forth word | Description |
---|---|
PUSH-HL |
Push the HL register onto the Forth stack. |
POP-HL |
Pop from the Forth stack into the HL register. |
PUSH-DE |
Put the HL & DE registers on the Forth stack. HL will be top of the stack, DE second on the stack. |
POP-DE |
Place top of Forth stack in HL register and second on stack into DE register.
|
The stack routines only affect the HL
and DE
registers.
To call a SAM routine we use the indirect call using JSVIN
at address 259 (103h).
It is used in the examples above to call the SAM print routine at address 16.
205 C, 259 , SAM-ADDRESS-TO-CALL ,
The parameters in the other registers are those required by the SAM routine.
System Variables
SamForth variables start at 400 (190h). SamForth-B variables start at 16692 (4134h). The list is identical for both versions, excepting two variables not used by SamForth-B.
Name | SamForth address | SamForth-B address | Description |
---|---|---|---|
FLAGS | 400 (190h) | 16692 (4134h) | Various flags to control the system. |
LASTK | 401 (191h) | 16693 (4135h) | ASCII code of last key pressed. |
BORD | 402 (192h) | 16694 (4136h) | Current border colour. |
FRAMES1 | 403 (193h) | 16695 (4137h) | Counts television picture frames into a double number. |
FRAMES2 | 405 (195h) | 16697 (4139h) | Counts television picture frames into a double number. |
YCORD | 407 (197h) | 16699 (413bh) | Last Y position plotted or drawn. |
XCORD | 408 (198h) | 16700 (413ch) | Last X position plotted or drawn. |
RSTACK | 410 (19ah) | 16702 (413eh) | Address of return stack (Z80 stack). |
STP | 412 (19ch) | 16704 (4140h) | Stack pointer to Forth stack. |
STACK | 414 (19eh) | 16706 (4142h) | Start of Forth stack. |
STKEND | 416 (1a0h) | 16708 (4144h) | End of Forth stack. |
SAMERR | 418 (1a2h) | 16710 (4146h) | Holds SAM error number. Not used by SamForth-B, but used by the error trapping code of its BASIC loader. |
NMI | 419 (1a3h) | |Address to jump to when NMI button pressed. Not used by SamForth-B. | |
CLATE | 421 (1a5h) | 16713 (4149h) | Address of last Forth word in dictionary at cold start. |
CHERE | 423 (1a7h) | 16715 (414bh) | Next vacant address in dictionary at cold start. |
LATEST | 425 (1a9h) | 16717 (414dh) | Address of last Forth word in dictionary. |
HERE | 427 (1abh) | 16719 (414fh) | Next vacant address in dictionary. |
BASE | 429 (1adh) | 16721 (4151h) | Current number base. |
FENCE | 431 (1afh) | 16723 (4153h) | Address below which FORGET will not operate. It can be changed with the command FENCE . |
TIB | 433 (1b1h) | 16725 (4155h) | Start address of the Terminal Input Buffer. |
PAD | 435 (1b3h) | 16727 (4157h) | Start address of the temporary data holding area. |
ST | 437 (1b5h) | 16729 (4159h) | Start address of source, usually 32768. The page holding the source file is paged in at C & D. |
TEMPSTK | 439 (1b7h) | |Used as temporary stack store. | |
RAMPAGE | 441 (1b9h) | 16733 (415dh) | Page number where source file will be held. Defaults to page 7. |
ERRSP | 442 (1bah) | 16734 (415eh) | Address at which return stack is set upon an error. |
CORESTORE | 444 (1bch) | 16736 (4160h) | Next vacant address in dictionary at cold start. [Not used. CHERE does the same function.] |
STATE | 446 (1beh) | 16738 (4162h) | Flag showing compile or immediate mode. |
LENGTH | 447 (1bfh) | 16739 (4163h) | Used to test for the length of a word being looked for in the dictionary. |
LENG | 448 (1c0h) | 16740 (4164h) | Used to test for the length of a word being looked for in the dictionary. |
IP | 449 (1c1h) | 16741 (4165h) | Address of interpreter pointer within source being compiled. |
DUBFLAG | 451 (1c3h) | 16743 (4167h) | Flag indicating double number. |
BASTACK | 452 (1c4h) | 16744 (4168h) | Holds stack pointer from SAM BASIC. |
EDITS | 454 (1c6h) | 16746 (416ah) | Start address of source to be edited. |
NUMBIT | 456 (1c8h) | 16748 (416ch) | Temporary store used during number output. |
PART1 | 458 (1cah) | 16750 (416eh) | Temporary addresses used during number input. |
PART2 | 460 (1cch) | 16752 (4170h) | Temporary addresses used during number input. |
ENDF | 462 (1ceh) | 16754 (4172h) | Temporary store used during number output. |
NEGA | 464 (1d0h) | 16756 (4174h) | Flag for negative number during number output. |
TEMP1 | 466 (1d2h) | 16758 (4176h) | Temporary store for HERE during compiling. |
TEMP2 | 468 (1d4h) | 16760 (4178h) | Temporary store for LATEST during compiling. |
IL1 | 470 (1d6h) | 16762 (417ah) | Length of input line before cursor. |
IL2 | 471 (1d7h) | 16763 (417bh) | Length of input line after cursor. |
ETIB | 472 (1d8h) | 16764 (417ch) | End address of Terminal Input Buffer. |
IFLAG | 474 (1dah) | 16766 (417eh) | Flag indicating that characters may be inserted into the input line and existing input is not over written. |
LDFLG | 475 (1dbh) | 16767 (417fh) | Flag showing that source is being compiled. |
ERRHLD | 476 (1dch) | 16768 (4180h) | Address of interpreter pointer position when an error occurred during source compilation. |
SVBLK | 478 (1deh) | 16770 (4182h) | Flag used during LOAD , SAVE and DIR commands. |
SLEN | 480 (1e0h) | 16772 (4184h) | Length of source to be saved. |
SE | 482 (1e2h) | 16774 (4186h) | End address of source. |
SADD | 484 (1e4h) | 16776 (4188h) | Address from where source will be LOAD ed or SAVE d. |
HLDS | 486 (1e6h) | 16778 (418ah) | Temporary store during number formatting. |
PAIRS | 488 (1e8h) | 16780 (418ch) | Flags to indicate whether pairs such as DO - LOOP match up during compilation. |
PAGENO | 490 (1eah) | 16782 (418eh) | Holds number of page paged in at 32768 in sections C & D. |
CUR | 492 (1ech) | 16784 (4190h) | Address of cursor in input buffer. |
SMODE | 494 (1eeh) | 16786 (4192h) | Indicates SAM screen mode 1, 2, 3 or 4. |
|496 (1f0h) | 16788 (4194h) | Not used. | |
|498 (1f2h) | 16790 (4196h) | Not used. | |
|500 (1f4h) | 16792 (4198h) | Not used. | |
LEN2 | 502 (1f6h) | 16794 (419ah) | Used to increase or decrease length of source during editing. |
LEN1 | 504 (1f8h) | 16796 (419ch) | Used to increase or decrease length of source during editing. |
LISTS | 506 (1fah) | 16798 (419eh) | Start address of source list on screen, or of source to be SAVE d. Changed with T , N , FROM . |
ELIST | 508 (1fch) | 16800 (41a0h) | End address of source list on screen or source to be SAVE d. Changed with N or ES . |
BLONG | 510 (1feh) | 16802 (41a2h) | Used during source editing. |
ENDLINE | 512 (200h) | 16804 (41a4h) | Used during source editing. |
Downloads
SamForth by John Avis (1991):