foco65/README.md

328 lines
5.8 KiB
Markdown
Raw Permalink Normal View History

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` `fill` `i` `j` `loop`
2018-09-22 21:44:13 +00:00
`+loop` `lshift` `<=` `<` `>=` `>` `-` `+` `or` `over` `rshift` `rsp` `sp` `swap` `unloop` `u<` `u>` `while` `<>` `>r` `r>`
2014-07-27 14:20:57 +00:00
`=` `!` `[` `]` `[code]` `[end-code]` `cell` `cells` `not` `[text-section]` `[data-section]`
`variable` `2variable` `constant` `create` `,` `c,` `,'` `'` `,"` `"` `allot`
`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>