Durexforth-V2 0 0
Durexforth-V2 0 0
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
2
Contents
1 Introduction 5
1.1 Forth, the Language . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.1 Why Forth? . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.1.2 Comparing to other Forths . . . . . . . . . . . . . . . . . 5
1.2 Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3 Appetizers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.1 Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.2 Fractals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.3 Music . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3.4 Sprites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2 Tutorial 7
2.1 Interpreter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.2 Editor . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
2.3 Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.4 Console I/O Example . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5 Avoiding Stack Crashes . . . . . . . . . . . . . . . . . . . . . . . 8
2.5.1 Commenting . . . . . . . . . . . . . . . . . . . . . . . . . 8
2.5.2 Stack Checks . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.6 Configuring durexForth . . . . . . . . . . . . . . . . . . . . . . . 9
2.6.1 Stripping Modules . . . . . . . . . . . . . . . . . . . . . . 9
2.6.2 Custom Start-Up . . . . . . . . . . . . . . . . . . . . . . . 10
2.7 How to Learn More . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.7.1 Internet Resources . . . . . . . . . . . . . . . . . . . . . . 10
2.7.2 Other . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
3 Editor 11
3.1 Key Presses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1.1 Inserting Text . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1.2 Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . 11
3.1.3 Saving & Quitting . . . . . . . . . . . . . . . . . . . . . . 12
3.1.4 Text Manipulation . . . . . . . . . . . . . . . . . . . . . . 12
4 Forth Words 13
4.1 Stack Manipulation . . . . . . . . . . . . . . . . . . . . . . . . . . 13
4.2 Utility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.3 Mathematics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4.4 Double . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
3
4.5 Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.6 Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.7 Compiling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
4.8 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.8.1 Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.8.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4.9 Control Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
4.10 Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.11 Editing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
4.12 Strings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.13 Number Formatting . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.14 Vectored Execution . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4.15 Debugging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.16 System State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.17 Disk I/O . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
4.18 Compatibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
4.19 Kernel Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
5 Graphics 23
5.1 Turtle Graphics . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
5.2 High-Resolution Graphics . . . . . . . . . . . . . . . . . . . . . . 23
6 SID 25
6.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.1.1 Voice Control . . . . . . . . . . . . . . . . . . . . . . . . . 25
6.1.2 SID Control . . . . . . . . . . . . . . . . . . . . . . . . . . 25
7 Music 26
7.1 Music Macro Language . . . . . . . . . . . . . . . . . . . . . . . . 26
7.2 Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
8 Assembler 27
8.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
8.2 Variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
8.3 Branches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
8.4 Labels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
A Assembler Mnemonics 29
B Memory Map 30
C Word Anatomy 31
C.1 Inspecting a Word . . . . . . . . . . . . . . . . . . . . . . . . . . 31
C.2 Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
C.3 Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
4
Chapter 1
Introduction
5
1.2 Contents
durexForth is packaged as a 16-kByte cartridge file and a system disk image.
Using the cartridge is equivalent to loading durexForth from disk, but of course
the cartridge boots a lot faster. The disk image also contains optional Forth
modules that can be loaded at will.
1.3 Appetizers
Some demonstration files are included on the disk as appetizers.
1.3.1 Graphics
The gfxdemo package demonstrates the high-resolution graphics, with some
examples adapted from the book ”Step-By-Step Programming C64 Graphics”
by Phil Cornes. Show the demos by entering:
include gfxdemo
When a demo has finished drawing, press any key to continue.
1.3.2 Fractals
The fractals package demonstrates turtle graphics by generating fractal images.
Run it by entering:
include fractals
When an image has finished drawing, press any key to continue.
1.3.3 Music
The mmldemo package demonstrates the MML music capabilities. To play some
music:
include mmldemo
1.3.4 Sprites
The sprite package adds functionality for defining and displaying sprites. To run
the demo:
include spritedemo
Exit the demo by pressing any key.
6
Chapter 2
Tutorial
2.1 Interpreter
Start up durexForth. When loaded, it will greet you with a blinking yellow
cursor, waiting for your input. You have landed in the interpreter!
Let’s warm it up a little. Enter 1 (followed by return). You have now put a
digit on the stack. This can be verified by the command .s, which will print the
stack contents without modifying it. Now enter . to pop the digit and print it
to screen, followed by .s to verify that the stack is empty.
Let’s define a word bg! for setting the border color. . .
: bg! $d020 c! ;
Now try entering 1 bg! to change the border color to white. Then, try changing
it back again with 0 bg!.
2.2 Editor
The editor (fully described in chapter 3) is convenient for editing larger pieces
of code. With it, you keep an entire source file loaded in RAM, and you can
recompile and test it easily.
Start the editor by typing v. You will enter the red editor screen. To enter text,
first press i to enter insert mode. This mode allows you to insert text into the
buffer. You can see that it’s active on the I that appears in the lower left corner.
This is a good start for creating a program!
Now, enter the following lines. . .
. . . and then press ← to leave insert mode. Press F7 to compile and run. If
everything is entered right, you will be facing a wonderful color cycle.
When you finished watching, press RESTORE to quit your program, then enter
v to reopen the editor.
7
2.3 Assembler
If you want to color cycle as fast as possible, it is possible to use the durexForth
assembler to generate machine code. code and ;code define a code word, just
like : and ; define Forth words. Within a code word, you can use assembler
mnemonics.
code flash
here ( push current addr )
$d020 inc,
jmp, ( jump to pushed addr )
;code
flash
Note: As the x register contains the parameter stack depth, it is important that
your assembly code leaves it unchanged.
2.5.1 Commenting
One helpful technique to avoid stack crashes is to add comments about stack
usage. In this example, we imagine a graphics word ”drawbox” that draws a
black box. ( color -- ) indicates that it takes one argument on stack, and
on exit it should leave nothing on the stack. The comments inside the word
(starting with £) indicate what the stack looks like after the line has executed.
: drawbox ( color -- )
10 begin dup 20 < while £ color x
10 begin dup 20 < while £ color x y
2dup £ color x y x y
8
4 pick £ color x y x y color
blkcol £ color x y
1+ repeat drop £ color x
1+ repeat 2drop ;
Once the word is working as supposed, it may be nice to again remove the
comments, as they are no longer very interesting to read.
: mainloop begin
( do stuff here... )
depth abort" depth not 0"
again ;
9
2.6.2 Custom Start-Up
You may launch a word automatically at start-up by setting the variable start
to the execution token of the word. Example: ’ megademo start ! To save
the new configuration to disk, type e.g. save-forth megademo.
When writing a new program using a PC text editor, it is practical to configure
durexForth to compile and execute the program at startup. That can be set up
using the following snippet:
Other Forths
• colorForth
• JONESFORTH
• colorForthRay.info — How to: with Ray St. Marie
2.7.2 Other
• durexForth source code
10
Chapter 3
Editor
3.1.2 Navigation
hjkl Cursor left, down, up, right.
Cursor Keys ...also work fine.
Ctrl+u Half page up.
Ctrl+d Half page down.
b Go to previous word.
w Go to next word.
0 Go to line start.
11
$ Go to line end.
g Go to start of file.
G Go to end of file.
/{string} Search forward for the next occurrence of the string.
* Search forward for the next occurrence of the word under the cursor.
:q Exit.
:w Save. (Must be followed by return.)
:w!filename Save as.
F7 Compile and run editor contents. Press Restore key to return to editor.
X Backspace-delete character.
dw Delete word.
dd Cut line.
12
Chapter 4
Forth Words
13
4.2 Utility
. ( n – ) Prints top value of stack as signed number.
u. ( u – ) Prints top value of stack as unsigned number.
4.3 Mathematics
1+ ( a – b ) Increase top of stack value by 1.
1- ( a – b ) Decrease top of stack value by 1.
* ( a b – c ) Multiply a with b.
/ ( a b – q ) Divide a with b using floored division.
/mod ( a b – r q ) Divide a with b, giving remainder r and quotient q.
mod ( a b – r ) Remainder of a divided by b.
14
*/mod ( a b c – r q ) Like */, but also keeping remainder r.
0< ( a – b ) Is a negative?
negate ( a – b ) Negates a.
abs ( a – b ) Gives absolute value of a.
min ( a b – c ) Gives the lesser of a and b.
base (variable) Points to the cell that holds the numerical base.
decimal Sets the numerical base to 10.
hex Sets the numerical base to 16.
4.4 Double
The following words use double-cell integers. On the stack, the cell containing
the most significant part of a double-cell integer is above the cell containing the
least significant part.
15
4.5 Logic
0= ( a – flag) Is a equal to zero?
0<> ( a – flag ) Is a not equal to 0?
= ( a b – flag ) Is a equal to b?
<> ( a b – flag ) Does a differ from b?
and ( a b – c ) Binary and.
or ( a b – c ) Binary or.
xor ( a b – c ) Binary exclusive or.
invert ( a – b ) Flip all bits of a.
4.6 Memory
! ( value address – ) Store 16-bit value at address.
@ ( address – value ) Fetch 16-bit value from address.
c! ( value address – ) Store 8-bit value at address.
c@ ( address – value ) Fetch 8-bit value from address.
fill ( addr len char – ) Fill range [addr, len + addr) with char.
move ( src dst len – ) Copies a region of memory len bytes long, starting at
src, to emory beginning at dst.
4.7 Compiling
: (C: ”<spaces>name” – colon-sys ) Define the word with the given name
and enter compilation state.
:noname ( – xt colon-sys ) Create an execution token and enter compilation
state.
; ( colon-sys – ) End the current definition, allow it to be found in the dic-
tionary and go back to interpretation state.
code ( ”<spaces>name” – ) Start assembling a new word.
;code End assembler.
, ( n – ) Write word on stack to here position and increase here by 2.
c, ( n – ) Write byte on stack to here position and increase here by 1.
allot ( n – ) Add n bytes to the body of the most recently defined word.
literal ( n – ) Compile a value from the stack as a literal value. Typical use: :
x ... [ a b * ] literal ... ;
16
[char] c Compile character c as a literal value.
[ ( – ) Leave compile mode. Execute the following words immediately instead
of compiling them.
] ( – ) Return to compile mode.
immediate Mark the most recently defined word as immediate (i.e. inside
colon definitions, it will be executed immediately instead of compiled).
[’] name ( – xt ) Place name’s execution token xt on the stack. The execution
token returned by the compiled phrase [’] x is the same value returned
by ’ x outside of compilation state. Typical use: : x ... [’] name
... ;
compile, ( xt – ) Append jsr xt to the word being compiled. Typical use: :
recurse immed latest @ >xt compile, ;
postpone xxx Compile the compilation semantics (instead of interpretation
semantics) of xxx. Typical use:
4.8 Variables
4.8.1 Values
Values are fast to read, slow to write. Use values for variables that are rarely
changed.
4.8.2 Variables
Variables are faster to write to than values.
17
4.9 Control Flow
Control functions only work in compile mode, not in interpreter.
: print0to7 8 0 do i . loop ;
unloop Discards the loop-control parameters. Allows clean exit from within a
loop.
: tellno ( n -- )
case
1 of ." one" endof
2 of ." two" endof
3 of ." three" endof
." other"
endcase
18
4.10 Input
key ( – c ) Gets one character from the keyboard.
key? ( – flag ) Returns true if a character is available for key.
getc ( – c ) Consumes the next character from the input buffer and increases
>in by one. If no characters are available, the input buffer is refilled as
needed.
char ( – c ) Parses the next word, delimited by a space, and puts its first
character on the stack.
>in ( – addr) Gives the address of a cell containing the offset in characters
from the start of the input buffer to the start of the parse area.
refill ( – ) Attempts to fill the input buffer from the input source.
source ( – caddr u) Gives the address of, and number of characters in, the
input buffer.
source-id ( – n ) Returns 0 if current input is keyboard, -1 if it is a string
from evaluate, or the current file id.
word ( delim – addr ) Reads a word from input, using delimiter delim, and
puts the string address on the stack. If the delimiter is the space character,
non-breaking space (hex a0) will also be treated as a delimiter.
parse-name ( name – caddr u ) Reads a word from input, delimited by
whitespace. Skips leading spaces.
interpret ( – value ) Interprets a word from input and puts it on the stack.
4.11 Editing
v filename Opens text editor and starts editing the file named ”filename”. If
filename is empty and a buffer is already open, editor will pick up where it
left. Otherwise, an untitled buffer will be created.
19
4.12 Strings
.( Print a string. Example: .( foo)
.” Compile-time version of ”.(”. Example: : foo ." bar" ;
20
4.15 Debugging
words List all defined words.
size size foo prints size of foo.
marker name ( – ) Creates a word that when called, forgets itself and all
words that were defined after it. Example:
marker forget
: x ;
forget
21
4.18 Compatibility
The compat module contains various words that are not deemed necessary for
enjoyable DurexForth operation, but still must be provided to comply with the
Forth 2012 core standard.
cells ( n – n*2 ) 2*
char+ ( n – n+1 ) 1+
align ( – ) No-op
aligned ( – ) No-op
chars ( – ) No-op
2@ ( address – x1 x2 ) Fetch 32-bit value from address. x2 is stored at
address, and x1 is stored at address + 2.
22
Chapter 5
Graphics
23
plot ( x y – ) Sets the pixel at x, y.
peek ( x y – p ) Gets the pixel at x, y.
24
Chapter 6
SID
6.1 Introduction
The sid module contains low-level words for controlling the SID chip. To load
it, type include sid. To test that it works, run sid-demo.
note! ( n – ) Plays note in range [0, 94], where 0 equals C-0. The tuning is
correct for PAL.
25
Chapter 7
Music
: frere-jaques
s" o3l4fgaffgafab->c&c<ab->c&cl8cdc<b-l4af>l8cdc<b-l4affcf&ffcf&f"
s" r1o3l4fgaffgafab->c&c<ab->c&cl8cdc<b-l4af>l8cdc<b-l4affcf&ffcf&f"
s" " play-mml ;
7.2 Commands
cdefgab The letters c to b represent musical notes. Sharp notes are produced
by appending a +, flat notes are produced by appending a -. The length
of a note is specified by appending a number representing its length as a
fraction of a whole note – for example, c8 represents a C eight note, and
f+2 an F# half note. Valid note lengths are 1, 2, 3, 4, 6, 8, 16, 24 and 32.
Appending a . increases the duration of the note by half of its value.
o Followed by a number, o selects the octave the instrument will play in.
r A rest. The length of the rest is specified in the same manner as the length of
a note.
<,> Used to step down or up one octave.
l Followed by a number, specifies the default length used by notes or rests which
do not explicitly specify one.
26
Chapter 8
Assembler
8.1 Introduction
DurexForth features a simple but useful 6510 assembler with support for branches
and labels. Assembly code is typically used within a code word, as in the tutorial
example:
code flash
here ( push current addr )
$d020 inc, ( inc $d020 )
jmp, ( jump to pushed addr )
;code
It is also possible to inline assembly code into a regular Forth word, as seen in
the tutorial:
8.2 Variables
DurexForth has a few variables that are specifically meant to be used within
code words.
lsb ( – addr ) Points to the top of the LSB parameter stack. Together with
the x register, it can be used to access stack contents.
msb ( – addr ) Points to the top of the MSB parameter stack. Together with
the x register, it can be used to access stack contents.
w ( – addr ) A zero-page cell that code words may use freely as work area.
w2 ( – addr ) Second zero-page work area cell.
w3 ( – addr ) Third zero-page work area cell.
27
code + ( n1 n2 -- sum )
clc, ( clear carry )
lsb 1+ lda,x ( load n1 lsb )
lsb adc,x ( add n2 lsb )
lsb 1+ sta,x ( store to n1 lsb )
msb 1+ lda,x ( load n1 msb )
msb adc,x ( add n2 msb )
msb 1+ sta,x ( store to n2 msb )
inx, ( drop n2; n1 = sum )
;code
8.3 Branches
The assembler supports forward and backward branches. These branches cannot
overlap each other, so their usage is limited to simple cases.
foo lda,
+branch beq,
bar inc, :+
8.4 Labels
The labels module adds support for more complicated flows where branches
can overlap freely. These branches are resolved by the ;code word, so it is not
possible to branch past it.
Example:
code checkers
$7f lda,# 0 ldy,# ’l’ @:
$400 sta,y $500 sta,y
$600 sta,y $700 sta,y
dey, ’l’ @@ bne, ;code
28
Appendix A
Assembler Mnemonics
29
Appendix B
Memory Map
bufstart - eof Editor text buffer. Grows upwards as needed. Default bufstart
is $7000.
...
$a000 - $cbff Free RAM.
30
Appendix C
Word Anatomy
: bg $d020 c! ;
After the word is defined, you can get its start address by latest @, and the
contents of bg can be dumped using latest @ dump. Try it, and you will get
output like the following:
4c38 ed 4b 02 42 47 20 cf 0e .k.bg ..
4c40 20 d0 4c 49 0a ff ff ff .li....
4c48 ff ff ff ff ff ff ff ff ........
4c50 ...
Here, we can see that the ”bg” word is 14 bytes long and starts at address $4c38.
It contains two parts: Header and code.
C.2 Header
4c38 ed 4b 02 42 47 20 cf 0e .k.bg ..
4c40 20 d0 4c 49 0a ff ff ff .li....
The first two bytes contain a back-pointer to the previous word, starting at
$4bed. The next byte, ”02”, is the length of ”bg” name string. After that, the
string ”bg” follows. (42 = ’b’, 47 = ’g’)
The name length byte is also used to store special attributes of the word. Bit
7 is ”immediate” flag, which means that the word should execute immediately
instead of being compiled into word definitions. (”(” is such an example of an
immediate word that does not get compiled.) Bit 6 is ”hidden” flag, which makes
a word unfindable. Bit 5 is the ”no-tail-call-elimination” flag, which makes
sure that tail call elimination (the practice of replacing jsr/rts with jmp) is not
performed if this word is the jsr target. Since bg does not have these flags set,
bits 7-5 are all clear.
31
C.3 Code
4c38 ed 4b 02 42 47 20 cf 0e .k.bg ..
4c40 20 d0 4c 49 0a ff ff ff .li....
20 cf 0e ( jsr $ecf ) $ecf is the adress of the lit code. lit copies the two
following bytes to parameter stack.
20 d0 ( $d020 ) The parameter to the lit word. When executed, lit will
add $d020 to the parameter stack.
32