It's a bit more inconvenient in terms of register protection (BC
is much more generally useful than IY), but it makes tight spots
such as next and execute much faster, so I think it's worth it.
The 1 byte limitation has been effective for a while now, but I
hadn't made the move yet, I wanted to see if the limitation would
cause me problems. It doesn't.
Doing this now slightly facilitates the IY->BC move in z80.
Bootstrapping: if you try to recreate the CVM binary from the
previous commit with this code, you'll have bootstrapping problems.
The first bootstrap will compile a binary with 2-bytes wide cells
but branching conditionals that yields 1-byte cells. That's bad.
I got around the issue by temporarily inserting a "397 399 LOADR"
instruction in cvm/xcomp.fs, right before the xcomp overrides. This
way, I force 1-byte cells everywhere on the first compiliation,
which then allows me to apply the logic change in cvm/vm.c and have
a properly running binary.
There is now no more actual code in stable ABI, only references.
This makes refactoring of this code much easier. For example,
changing IY to BC as the IP register.
Only its jump at 0x33 remains.
I've also fixed a strange offset oddity in 8086's (n) placement.
It was off by 2, but strangely, it ran properly. Anyway, now it's
fixed.
Previously, it was impossible to cross-compile Collapse OS from a
binary-offsetted Collapse OS because stable ABI wordrefs would have
a wrongly offsetted address.
This solves the problem by replacing those wordrefs by direct,
hardcoded stable ABI offset references.
Driver configuration don't need their own words at runtime, we only
need to compile them as literals when compiling words.
Now that we have this "declaration blocks" pattern emerging, it
seems like a good idea to take advantage of this in drivers, both
for simplifying the xcomp unit and to make final binary slimmer.
Initially, I used the same letters as those used in the z80 ref
docs, but it makes the different assemblers harder to use than they
should. Having consistent "argtype" rules across assemblers should
help.
Previously, recipes that began spitting binary contents before
loading block 282 would end up with VARIABLE code in their binary,
thus breaking them. We fix this by making this loading process
2-part.
Shadowing core "I" is too messy. As soon as ed is loaded in memory,
nothing else that isn't "i-aware" can be loaded anymore.
I guess that's why "contexts" exist in Starting Forth, but adding
this concept just for allowing the shadowing of core words seems
overkill to me. Renaming I to i in ed seems better.
This commit adds ?DUP IF guards to MOVE and MOVE- that make them exit
when u is 0. Without these guards a DO loop was executed 65535 times
instead of 0.
In particular, this fixes a crash when "105 LOAD I " is executed
immediately after boot. Block editor word "I" passes IBUF length (0)
to MOVE- and MOVE in this case, causing a crash.
(well, not PC@ and PC!, but I'm not even sure what would be the role
of these in a PC/AT. they're only used in drivers on the z80 front,
so they will not be immediately needed. todo... )
Now comes the fitting part.
Instead of having wordref point to core word routines, I made them
into word 4 word types. It liberates space into the stable ABI and
should make porting to other arches easier.
I'm also thinking of combining word type with the namelen field
for precious bytes saving, but not now...
It was useful when we still had the relinker, but now it has no use.
I was waiting a bit to see if the distinction would be useful again,
but it seems like it won't.
Documentation in block 100 says a number followed by a space or return
lists the contents of the block. However, typing any other character
does this too, because _pdacc returns -1 in this case.
This is annoying because typing "n" instead of "N" immediately after
jumping to some block was bringing you to block 0. Now "n" is ignored
instead.
This commit changes the condition for printing to explicitly check for
the value of 1, which means whitespace according to _pdacc documentation
in block 355.
I'm not sure yet where I'm going, but I'm not going to build the
8086 port from the ground up like I did with the z80, that is,
making is sustain itself and eventually merge its forth code with
core words. That would be too much work which would then be thrown
out (all those words I'll initially have to implement in asm which
are already implemented in Forth).
What I *think* I can do is build a mirror version of z80 boot code
and cross-compile it from the z80. This means it has to follow z80
stable ABI.
Nope, I'm not sure where I'm going...