link: add "offset" argument to RLDICT
As long as our target was the first word of the "user" dict, using target's prev to compute offset was fine, but when the target is not the first word, this system breaks down. This is the case when, instead of including source code in our boot binary, we paste it in Collapse OS' prompt. Also, adjust RC2014 recipe to include stage 3 assembling instructions with the "paste into prompt" method.
This commit is contained in:
parent
29a6ee128d
commit
dfaa1dc101
@ -110,11 +110,11 @@
|
|||||||
( TODO implement RLCELL )
|
( TODO implement RLCELL )
|
||||||
|
|
||||||
( Copy dict from target wordref, including header, up to HERE.
|
( Copy dict from target wordref, including header, up to HERE.
|
||||||
We're going to compact the space between that word and its
|
We're going relocate those words by specified offset. To do
|
||||||
prev word. To do this, we're copying this whole memory area
|
this, we're copying this whole memory area in HERE and then
|
||||||
in HERE and then iterate through that copied area and call
|
iterate through that copied area and call RLWORD on each
|
||||||
RLWORD on each word. That results in a dict that can be
|
word. That results in a dict that can be concatenated to
|
||||||
concatenated to target's prev entry in a more compact way.
|
target's prev entry in a more compact way.
|
||||||
|
|
||||||
This copy of data doesn't allocate anything, so H@ doesn't
|
This copy of data doesn't allocate anything, so H@ doesn't
|
||||||
move. Moreover, we reserve 4 bytes at H@ to write our target
|
move. Moreover, we reserve 4 bytes at H@ to write our target
|
||||||
@ -129,19 +129,16 @@
|
|||||||
possible to reliably detect its end. If you need that last
|
possible to reliably detect its end. If you need that last
|
||||||
word, define a dummy word before calling RLDICT.
|
word, define a dummy word before calling RLDICT.
|
||||||
)
|
)
|
||||||
( target -- )
|
( target offset -- )
|
||||||
: RLDICT
|
: RLDICT
|
||||||
( First of all, let's get our offset. It's easy, it's
|
( First of all, let's get our offset. It's easy, it's
|
||||||
target's prev field, which is already an offset, minus
|
target's prev field, which is already an offset, minus
|
||||||
its name length. We expect, in RLDICT that a target's
|
its name length. We expect, in RLDICT that a target's
|
||||||
prev word is a "hook word", that is, an empty word. )
|
prev word is a "hook word", that is, an empty word. )
|
||||||
( H@ == target )
|
|
||||||
DUP H@ !
|
|
||||||
DUP 1- C@ 0x7f AND ( t namelen )
|
|
||||||
SWAP 3 - @ ( namelen po )
|
|
||||||
-^ ( o )
|
|
||||||
( H@+2 == offset )
|
( H@+2 == offset )
|
||||||
H@ 2+ ! ( )
|
H@ 2+ ! ( target )
|
||||||
|
( H@ == target )
|
||||||
|
H@ ! ( )
|
||||||
( We have our offset, now let's copy our memory chunk )
|
( We have our offset, now let's copy our memory chunk )
|
||||||
H@ @ WORD( ( src )
|
H@ @ WORD( ( src )
|
||||||
DUP H@ -^ ( src u )
|
DUP H@ -^ ( src u )
|
||||||
@ -180,5 +177,9 @@
|
|||||||
|
|
||||||
( Relink a regular Forth full interpreter. )
|
( Relink a regular Forth full interpreter. )
|
||||||
: RLCORE
|
: RLCORE
|
||||||
LIT< H@ (find) DROP RLDICT
|
LIT< H@ (find) DROP ( target )
|
||||||
|
DUP 3 - @ ( t prevoff )
|
||||||
|
( subtract H@ name length )
|
||||||
|
2- ( t o )
|
||||||
|
RLDICT
|
||||||
;
|
;
|
||||||
|
@ -210,22 +210,49 @@ That's it! our binary is ready to run!
|
|||||||
|
|
||||||
../../emul/hw/rc2014/classic stage2r.bin
|
../../emul/hw/rc2014/classic stage2r.bin
|
||||||
|
|
||||||
And there you have it, a stage2 binary that you've assembled yourself. Now,
|
And there you have it, a stage2 binary that you've assembled yourself.
|
||||||
here's for your homework: use the same technique to add the contents of
|
|
||||||
`readln.fs` and `adev.fs` to stage2 so that you have a full-featured
|
|
||||||
interpreter.
|
|
||||||
|
|
||||||
Name it `stage3.bin` (the version without any source code appended and no
|
### Assembling stage 3
|
||||||
`INIT` word defined), you'll need this binary for sub-recipes written for the
|
|
||||||
RC2014.
|
|
||||||
|
|
||||||
Here's a little cheatsheet, but seriously, you should figure most of it
|
Stage 2 gives you a useable prompt, but bare. Because 8K isn't a lot of space
|
||||||
yourself. Tough love they call it.
|
to cram source code, we're limited in what we can include for this stage.
|
||||||
|
|
||||||
* `cat stage2.bin ../../forth/readln.fs ../../forth/adev.fs run.fs > stage2r.bin`
|
However, now that we have a usable prompt, we can do a lot (be cautious though:
|
||||||
* Don't forget `RDLN$` and `ADEV$`.
|
there is no `readln` yet, so you have no backspace), for example, build a
|
||||||
* `RLDICT` is like `RLCORE` but with a chosen target.
|
stage 3 with `readln`.
|
||||||
* `stripfc` can help you deal with size constraints.
|
|
||||||
|
Copy the unit's source
|
||||||
|
|
||||||
|
cat ../../forth/readln.fs | ../../tools/stripfc | xclip
|
||||||
|
|
||||||
|
and just paste it in your terminal. If you're doing the real thing and not
|
||||||
|
using the emulator, pasting so much code at once might freeze up the RC2014, so
|
||||||
|
it is recommended that you use `/tools/exec` that let the other side enough
|
||||||
|
time to breathe.
|
||||||
|
|
||||||
|
After your pasting, you'll have a compiled dict of that code in memory. You'll
|
||||||
|
need to relocate it in the same way you did for stage 2, but instead of using
|
||||||
|
`RLCORE`, which is a convenience word hardcoded for stage 1, we'll parametrize
|
||||||
|
`RLDICT`, the word doing the real work.
|
||||||
|
|
||||||
|
`RLDICT` takes 2 arguments, `target` and `offset`. `target` is the first word
|
||||||
|
of your relocated dict. In our case, it's going to be `' INBUFSZ`. `offset` is
|
||||||
|
the offset we'll apply to every eligible word references in our dict. In our
|
||||||
|
case, that offset is the offset of the *beginning* of the `INBUFSZ` entry (that
|
||||||
|
is, `' INBUFSZ WORD(` minus the offset of the last word (which should be a hook
|
||||||
|
word) in the ROM binary.
|
||||||
|
|
||||||
|
That offset can be conveniently fetched from code because it is the value of
|
||||||
|
the `LATEST` constant in stable ABI, which is at offset `0x08`. Therefore, our
|
||||||
|
offset value is:
|
||||||
|
|
||||||
|
' INBUFSZ WORD( 0x08 @ -
|
||||||
|
|
||||||
|
You can now run `RLDICT` and proceed with concatenation (and manual adjustments
|
||||||
|
of course) as you did with stage 2. Don't forget to adjust `run.fs` so that it
|
||||||
|
initializes `RDLN$` instead of creating a minimal `(c<)`.
|
||||||
|
|
||||||
|
Keep that `stage3.bin` around, you will need it for further recipes.
|
||||||
|
|
||||||
[rc2014]: https://rc2014.co.uk
|
[rc2014]: https://rc2014.co.uk
|
||||||
[romwrite]: https://github.com/hsoft/romwrite
|
[romwrite]: https://github.com/hsoft/romwrite
|
||||||
|
Loading…
Reference in New Issue
Block a user