2014-07-19 13:40:30 +00:00
|
|
|
foco65
|
|
|
|
======
|
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
Forth cross-compiler targeting 6502 processors. Outputs [xasm](https://github.com/pfusik/xasm)
|
|
|
|
compatible assembly source code containing Forth runtime and compiled user
|
|
|
|
program.
|
|
|
|
|
|
|
|
Runtime
|
|
|
|
-------
|
|
|
|
|
|
|
|
Generated Forth runtime is 16-bit indirect-threaded.
|
|
|
|
|
|
|
|
Parameter stack is full-descending and addressed by `X` register. Address and
|
|
|
|
size of the parameter stack are by default $600 and 256 respectively and are
|
|
|
|
user-configurable.
|
|
|
|
|
|
|
|
Hardware stack is used as return stack.
|
|
|
|
|
|
|
|
The runtime uses 12 bytes on zero page: 2-byte instruction pointer `ip` and
|
|
|
|
5 2-byte work registers: `w`, `z`, `cntr`, `tmp`, `tmp2` which may be used
|
|
|
|
in user-defined words (note than on every word entry these registers' contents
|
|
|
|
are undefined).
|
|
|
|
|
|
|
|
On entry runtime initializes instruction pointer and enters user-defined word
|
|
|
|
`main` which is supposed to never exit (i.e. contain an infinite loop).
|
|
|
|
|
|
|
|
Generated Source Code
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
Generated assembly source code for words/data/code blocks is logically grouped
|
|
|
|
into _sections_. Default order of sections is: `init`, `boot`, `data`, `text`.
|
|
|
|
|
|
|
|
Sections:
|
|
|
|
* `init` - top of the output, typically contains user-provided assembly code
|
|
|
|
block with `org` directive
|
|
|
|
* `boot` - forth runtime
|
|
|
|
* `data` - user data
|
|
|
|
* `text` - core words and user program
|
|
|
|
|
|
|
|
User-defined data is output into the most recently declared data section (with
|
|
|
|
`[data-section]` word), everything else is output into the most recently
|
|
|
|
declared text section (with `[text-section]` word).
|
|
|
|
|
|
|
|
Syntax
|
|
|
|
------
|
|
|
|
|
|
|
|
### Identifiers
|
|
|
|
|
|
|
|
Identifiers are case sensitive.
|
|
|
|
|
|
|
|
Constant and data identifiers consist of alphanumeric characters, '\_'s, '-'s
|
|
|
|
and '?'s and must start with a letter, '\_', '-' or '?'. In generated assembly
|
|
|
|
labels every '-' is replaced by '\_' and every '?' is replaced by '\_is\_'.
|
|
|
|
|
|
|
|
Word identifiers consist of printable ASCII characters. Word identifiers
|
|
|
|
consisting only of alphanumeric characters, '\_'s, '-'s, '?'s and starting with
|
|
|
|
a letter, '\_', '-' or a '?' are translated automatically to valid assembly
|
|
|
|
labels. Other word identifiers require user-defined label specification (see
|
|
|
|
below).
|
|
|
|
|
|
|
|
Section identifiers consist of printable ASCII characters.
|
|
|
|
|
|
|
|
### Comments
|
|
|
|
|
|
|
|
Syntax:
|
|
|
|
<pre><code>
|
|
|
|
\ this is a one-line comment
|
|
|
|
( this is a multi-line
|
|
|
|
comment)
|
|
|
|
</code></pre>
|
|
|
|
|
|
|
|
### Numbers
|
|
|
|
|
|
|
|
Syntax:
|
|
|
|
<pre><code>
|
|
|
|
123 \ decimal number
|
|
|
|
$BA98 \ hexadecimal number
|
|
|
|
</code></pre>
|
|
|
|
|
|
|
|
### Word definitions
|
|
|
|
|
|
|
|
Syntax:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`:` _name_ *[* `[label]` _asm-label_ *]* _words_ `;`
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
or:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`:` _name_
|
|
|
|
*[* `[label]` _asm-label_ *]*
|
|
|
|
`[code]`
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
; inline-assembly
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`[end-code]` `;`
|
|
|
|
|
|
|
|
Examples:
|
|
|
|
<pre><code>
|
|
|
|
: foo begin end-flag until ;
|
|
|
|
</code></pre>
|
|
|
|
<pre><code>
|
|
|
|
: bar
|
|
|
|
[code]
|
|
|
|
lda #1
|
|
|
|
sta $D5E8
|
|
|
|
jmp next
|
|
|
|
[end-code] ;
|
|
|
|
</code></pre>
|
|
|
|
<pre><code>
|
|
|
|
: +7 ( n1 -- n2 )
|
|
|
|
[label] plus_7
|
|
|
|
7 + ;
|
|
|
|
</code></pre>
|
|
|
|
|
|
|
|
### Data declarations
|
|
|
|
|
|
|
|
One-cell variable:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`variable` _name_
|
|
|
|
|
|
|
|
Two-cell variable:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`2variable` _name_
|
|
|
|
|
|
|
|
Assembly label at current program counter:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`create` _name_
|
|
|
|
|
|
|
|
Compile a one-cell value:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
_value_ `,`
|
|
|
|
|
|
|
|
Compile a one-byte value:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
_value_ `c,`
|
|
|
|
|
|
|
|
Allocate a byte-array:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
_length_ `allot`
|
|
|
|
|
|
|
|
Allocate Atari XL/XE Antic counted string:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`,'` _text_`'`
|
|
|
|
|
|
|
|
Allocate ASCII counted string:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`,"` _text_`"`
|
|
|
|
|
|
|
|
Allocate Atari XL/XE Antic string:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`'` _text_`'`
|
|
|
|
|
2014-09-20 20:18:22 +00:00
|
|
|
Allocate ASCII string:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`"` _text_`"`
|
|
|
|
|
|
|
|
### Constants
|
|
|
|
|
|
|
|
Syntax:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
_value_ `constant` _name_
|
|
|
|
|
|
|
|
Example:
|
|
|
|
<pre><code>
|
|
|
|
$230 constant dladr
|
|
|
|
</code></pre>
|
|
|
|
|
|
|
|
### Inline assembly blocks
|
|
|
|
|
|
|
|
Syntax:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`[code]`
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
_; assembly code_
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`[end-code]`
|
|
|
|
|
|
|
|
### Compiler directives
|
|
|
|
|
|
|
|
Syntax:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`[text-section]` _name_
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
or:
|
2014-07-27 14:37:52 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
`[data-section]` _name_
|
|
|
|
|
|
|
|
Words
|
|
|
|
-----
|
|
|
|
|
|
|
|
`:` `@` `0=` `1-` `1+` `2/` `2*` `2@` `2!` `and` `c!` `c@` `cmove` `count` `d-` `d+` `d=` `do` `drop` `dup` `i` `j` `loop`
|
|
|
|
`+loop` `lshift` `<=` `<` `>=` `>` `-` `+` `or` `over` `rshift` `rsp` `sp` `swap` `unloop` `u<` `u>` `while` `<>`
|
|
|
|
`=` `!` `[` `]` `[code]` `[end-code]` `cell` `cells` `not` `[text-section]` `[data-section]`
|
|
|
|
`variable` `2variable` `constant` `create` `,` `c,` `,'` `'` `,"` `"` `allot`
|
2016-06-29 20:10:46 +00:00
|
|
|
`lit` `\` `(` `recursive` `[label]` `*` `/` `m*`
|
2014-07-19 13:43:00 +00:00
|
|
|
|
|
|
|
Usage
|
|
|
|
-----
|
|
|
|
|
2014-07-20 19:25:47 +00:00
|
|
|
```sh
|
2014-07-19 13:43:00 +00:00
|
|
|
foco65 [OPTIONS] INPUT-FILE
|
2014-07-20 19:25:47 +00:00
|
|
|
```
|
2014-07-19 13:43:00 +00:00
|
|
|
|
|
|
|
OPTIONS:
|
|
|
|
|
2014-07-20 08:27:15 +00:00
|
|
|
-h display help
|
|
|
|
-p ADDR,--pstack-bottom=ADDR parameter stack bottom address
|
|
|
|
-s SECTS,--sections=SECTS specify comma separated list of sections
|
2014-07-27 14:20:57 +00:00
|
|
|
default: init,boot,data,text
|
2014-07-20 08:27:15 +00:00
|
|
|
-S INT,--pstack-SIZE=INT parameter stack size
|
2014-07-20 08:21:18 +00:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
2014-07-20 08:27:15 +00:00
|
|
|
```sh
|
|
|
|
$ foco65 foo.forth > foo.asx
|
|
|
|
```
|
2014-07-19 13:43:00 +00:00
|
|
|
|
2014-07-19 13:47:55 +00:00
|
|
|
Examples
|
|
|
|
--------
|
2014-07-19 13:43:00 +00:00
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
Typical Atari XL/XE executable program structure.
|
2014-07-21 19:07:33 +00:00
|
|
|
|
|
|
|
<pre><code>
|
2014-07-27 14:20:57 +00:00
|
|
|
[text-section] init
|
2014-07-21 19:07:33 +00:00
|
|
|
|
|
|
|
[code]
|
|
|
|
org $2000
|
|
|
|
[end-code]
|
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
\ constant definitions
|
|
|
|
\ data declarations
|
|
|
|
\ word definitions
|
|
|
|
|
|
|
|
[text-section] text
|
2014-07-21 19:25:25 +00:00
|
|
|
|
2014-07-21 19:07:33 +00:00
|
|
|
: main
|
2014-07-27 14:20:57 +00:00
|
|
|
\ user program initialization
|
2014-07-21 19:07:33 +00:00
|
|
|
begin
|
2014-07-27 14:20:57 +00:00
|
|
|
\ user program main loop
|
2014-07-21 19:07:33 +00:00
|
|
|
again ;
|
|
|
|
|
|
|
|
[code]
|
|
|
|
run boot
|
|
|
|
[end-code]
|
|
|
|
</code></pre>
|
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
Atari XL/XE example: display character table.
|
2014-07-19 13:43:00 +00:00
|
|
|
|
|
|
|
<pre><code>
|
2014-07-27 14:20:57 +00:00
|
|
|
[text-section] init
|
2014-07-19 13:43:00 +00:00
|
|
|
|
|
|
|
[code]
|
|
|
|
org $3000
|
|
|
|
[end-code]
|
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
[text-section] text
|
2014-07-19 13:43:00 +00:00
|
|
|
|
|
|
|
$230 constant dladr
|
|
|
|
|
|
|
|
variable screen
|
|
|
|
variable cursor
|
|
|
|
variable line
|
|
|
|
|
|
|
|
: cursor-next ( -- u )
|
|
|
|
cursor @ dup 1+ cursor ! ;
|
|
|
|
|
|
|
|
: put-char ( c -- )
|
|
|
|
cursor-next c! ;
|
|
|
|
|
|
|
|
: set-cursor ( u -- )
|
|
|
|
screen @ + cursor ! ;
|
|
|
|
|
|
|
|
: main
|
|
|
|
dladr @ 4 + @ screen !
|
|
|
|
|
|
|
|
0 line !
|
|
|
|
16 0 do
|
|
|
|
line @ set-cursor
|
|
|
|
line @ 40 + line !
|
|
|
|
16 0 do
|
|
|
|
i j 4 lshift or put-char
|
|
|
|
loop
|
|
|
|
loop
|
|
|
|
|
|
|
|
begin again ;
|
|
|
|
|
|
|
|
[code]
|
|
|
|
run boot
|
|
|
|
[end-code]
|
|
|
|
</code></pre>
|
|
|
|
|
|
|
|
Atari XL/XE example of defining word in assembly:
|
|
|
|
wait for keypress and push the pressed key's code
|
|
|
|
on the parameter stack.
|
|
|
|
|
|
|
|
<pre><code>
|
|
|
|
: get-char ( -- c )
|
|
|
|
[code]
|
|
|
|
lda #0
|
|
|
|
dex
|
|
|
|
sta pstack,x
|
|
|
|
stx w
|
|
|
|
jsr do_gc
|
|
|
|
ldx w
|
|
|
|
dex
|
|
|
|
sta pstack,x
|
|
|
|
jmp next
|
2014-07-27 14:20:57 +00:00
|
|
|
|
2014-07-19 13:43:00 +00:00
|
|
|
do_gc
|
|
|
|
lda $E425
|
|
|
|
pha
|
|
|
|
lda $E424
|
|
|
|
pha
|
|
|
|
rts
|
|
|
|
[end-code] ;
|
|
|
|
</code></pre>
|
|
|
|
|
|
|
|
Increase cell at the given address. Shows defining words not
|
|
|
|
being a valid assembler label.
|
|
|
|
|
|
|
|
<pre><code>
|
|
|
|
create array 16 cells allot
|
|
|
|
|
2014-07-27 14:20:57 +00:00
|
|
|
\ increase cell at given address
|
2014-07-19 13:43:00 +00:00
|
|
|
: ++ ( addr -- )
|
|
|
|
[label] plus_plus
|
|
|
|
dup @ 1+ swap ! ;
|
|
|
|
</code></pre>
|