AVR chips often run at less than z80's system clock. This means that
our SPI relay needs to have its own clock to properly communicate
with it. This means that the delay between OUT and IN can't be
hardcoded to 2 NOPs anymore. It needs to be configurable.
Although the SPI Relay driver is RC2014-specific, the SD Card driver
is generic enough to be a subsystem. That's the second subsystem we
add and this warrants, I think, the formalization of a new concept:
protocols.
Among random "better safe than sorry" changes, the real fix is in
changing "4" for "5" above _find declaration. This off-by-one error
had that word, which is the root word in z80, have a 0x01 prev field
instead of a 0x00 one.
When all memory was initialized to zero, it didn't matter, we ended
up hitting 0 prev and considered ourselves properly at the end of
dict.
When memory wasn't initialized, however, we would end up jumping at
all kinds of places, leading to random behavior.
The previous approach of maintaining R> and W> pointers was
conceptually simple, but made INT handler code actually quite
complex.
Now, we maintain indexes instead. It's much easier to perform
bounds checks and to compare for equality, something we have to
do quick in the INT handler.
it seems I left my asm argument harmonization half done here.
Instructions list at B208 doesn't correspond to many actual
mnemonics. This mnemonic here was the worst offender.
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.