Among ZX Spectrum Next new features is the huge amount of RAM. The question is how to leverage all that memory in Forth.
Looking to how Forth’s system areas are sorted out, the first challenge is to move them down to free the top 8K CPU’s addressable memory between 0E000h and 0FFFFh allowing MMU7 to map to any physical 8K RAM page. There are some peculiar addresses that identify the following Forth system areas:
- 0F840h : Calculator Stack (SP) grows downward, Text Input Buffer (TIB) upward.,
- 0F8E0h : Return Stack (RP) grows downward, User Variables Area upward.
- 0F94Ch : the FIRST disk buffer starts here and buffers area ends just before LIMIT 0FF58h.
I coded this “move” in a few words (available in Screens #220-#223) summarized in the definition DOWN that moves these pointers “down” as follow:
0FF58h → 0E000h : LIMIT
0F9C4h → 0D9F4h : FIRST
0F8E0h → 0D9A0h : Return Stack and User Variables Area
0F840h → 0D900h : Stack Pointer and TIB
The second question is how to encode both page number and address offset in a normal Z80 16-bits pointer variable. Since an 8K offset requires 13 bits, the remaining 3 bits can be used to encode, say, from page 64 to page 71.
16 bit pointer | pppb bbbb | bbbb bbbb | | Page | Offset | | 0100 0ppp | | 111b bbbb | bbbb bbbb |
This solution opens to 64K of physical RAM that can store large amount of data, a so called heap. Long strings are dictionary expensive, so it would be useful storing them in heap as constant-strings and fetch them at need. More, 8K of room is a good place to store an array of strings, or even numeric array and implement some matrices algebra…
The third and final question is how to conceive a “store and retrieve” on heap so that it can keep track of room and a way to let a page to stay in place across I/O to disk operations, that it is known they use addresses C000-FFFF for their purposes. Maybe, this is the tricky part, avoid that my string is “paged away” in the middle of processing.
What I am working on these days are a few new definitions such as a POINTER to create a pointer word, to be seen as a constant that holds an encoded far-address, a HEAP-ALLOT word to require space on the heap, and a FAR word to prefix any ! (store), @ (fetch), or TYPE to turn a pointer into a physical address and perform the paging handling under the hood just before using it. Things are not complete yet, but I hope to share soon some result on github. Maybe, this is enough for a while…