SamForth documentation

Description of the page content

Edited documentation of SamForth, a Forth system for the SAM Coupé computer.

Tags:

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.

>

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.

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 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 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 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 from FORGET.

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-ordinates
  • DRAW TO: 2 followed by x,y co-ordinates
  • CIRCLE: 3 followed by x,y and the radius
  • OVER: 4 followed by 0-3
  • PEN: 5 followed by 0-17
  • CLS: 6 followed by 0-1
  • PAUSE: 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):

Related pages

SamForth disassembled
Disassembling of SamForth.