1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# jewelforth
its a forth for linux x86\_64. mostly made for personal stuff.
if you use it and it breaks, too bad
public domain
the plan right now is that this will be an STC forth.
if this proves Too Complicated To Deal With the plan may be changed
to a DTC forth instead.
## dictionary
the dictionary follows a fairly standard format.
| field | size | forth name |
| :---- | :--- | :--------- |
| link to previous | 8 bytes | LFA (link field address) |
| flag | 1 byte | FFA (flag field address) |
| string length | 2 bytes | NFA (name field address) |
| string | variable length | still NFA |
| code | variable length | CFA (code field address) |
probably, some bitmask antics could be done to store the string length
and flags together. but alternatively: no.
## forth registers
- the working stack pointer, is `r14`.
- `r11`, `r12`, `r13`, and occcasionally `r10` and `r9` are general purpose working registers.
## miscellaneous notes and stuff
### COMPILE,
this is an STC forth so when we compile a call we have to
write the bytes of a `call` in manually.
x86\_64 does not allow absolute jumps from an immediate address,
so a wonky but hopefully not too slow solution is to compile
`literal address → W` and then `call W`. It'll Be Fine?
- `mov r11, [cfa]` = `94 BB [CFA]`
- `call r11` = `41 FF D3`
### words to bootstrap from
i want to make the kernel reasonably small,
especially if i add an assembler.
but obviously we need *something* to bootstrap from.
(this list is Inspired by [miniforth](https://github.com/meithecatte/miniforth)'s builtins)
- `!` (`val addr -- `): store a 64 bit word
- `@` (`addr -- val`): fetch a 64 bit word
- `c!` (`byte addr -- `): store a byte
- `c@` (`addr -- byte`): fetch a byte
- `:` (` -- `): compile a word from the current input source
- `;` (` -- `): stop compiling the current word
- `parse` (` -- c-addr u`): parse a word from the *forth init* (see footnote)
- `find` (`c-addr u -- ?lfa flag`)
- `interpret`: the stage 1 interpreter
- `latest`: a variable, the latest defined word
- `state`: a variable, determines current mode (interp./compiling)
- `>in`: a variable, offset from start of forth init
on `parse`: i don't want to deal with file access and stuff from the kernel.
so this word will be Upgraded in the forth init to read from a file.
### Some Links
- starting forth part 1: http://www.bradrodriguez.com/papers/moving1.htm
- a forum thread about determining empty stack with TOS register: http://forum.6502.org/viewtopic.php?t=8424
## silly little plans
### in-forth assembler
this would reap the most benefits from STC.
probably look at dusk's assemblers for how it should look like
or liek something liek dusk's lib/bm?
idk something to do stuff Fast if u need. would be fun
|