BruceRMcF wrote:
chitselb wrote:
my exit was "POP RS->IP; JMP NEXT"
now it is "POP RS->IP; JMP NEXTO"
Code:
next inc ip
inc ip
nexto jmp (ip)
Either are perfectly standard EXITs. There are processors that do one faster and processors that do the other faster, and on those processors, the model will follow suit. IIRC, the 68K has a very fast four byte NEXT based on an available JMP ++(...) operation.
Thank you for the validation. I had only dissected a few other Forths and they used a post-increment EXIT. My inner interpreter (ENTER, EXIT, (+LOOP), (LOOP), etc...) is rewritten now and works well with the pre-incrementing!
For my next trick, I'm revisiting SAVE-BUFFERS and LOAD-BUFFERS (also VERIFY-BUFFERS which is a minor variant). PETTIL stashes blocks of virtual memory in (what I am calling) "packets" in a structure that builds downward in upper RAM. A packet is either "data" or "screen" and is either "compressed" or "uncompressed". Those two bit flags and a "size" form the 16-bit packet header. For compression, I use run-length encoding, which works well for typical Forth source. A screen packet will have 24 bits of "linewrap" stored adjacent and below the packet header. Each bit indicates whether that physical line is the start of a logical line, or not. Only 24 bits per screen are required, because physical line 0 is always the start of a logical line.
When I started writing this, the scope was intended to be a nifty Forth for my hardware PET. Project scope has expanded to the rest of the Commodore 8-bit line, which means adding disk support. The virtual memory buffer (all those packets) will load to a different place every time. Since all navigation is relative (only sizes, no absolute addresses) this doesn't require any changes to the data after loading it in. However, loading a file to a different load address than the one stored in the first two bytes is problematic. Here's the layout.
Code:
immediately after LOAD:
0000-03FF |zeropage|stack|systemstuff|
0400-46B7 |core|startup|studio|symtab| all mooshed together
Code:
after running PETTIL initialization:
0000-008C |PETTIL zeropage|
008D-03FF |zeropage|stack|system|
0400-040C |10 sys1039
040D-040F |JMP(startup)|
0410-049C |the bottom half of zeropage that BASIC was using|
049F-066B |Sweet16|
066C-1A55 |PETTIL `core` dictionary, (just code)|
1A56-52FD |free, unused memory, filled with DE AD BE EF pattern|
52FE-52FF |an empty virtual memory buffer (VMBUF)| grows downward, ends at BLKBUF
5300-56FF |1K block buffer (BLKBUF)| 1K block, ends at SYMTAB
5700-66FF |symbol table (SYMTAB)| this grows upward. FORGET sorts and moves it
6700-7FFF |PETTIL `studio` dictionary (just code)|
so, here's how we get to VMBUF
: blkbuf symtab @ b/buf - ;
: vmbuf blkbuf 2- ;
PETTIL studio is the programmer environment, with every definition that touches the symbol table. When the compiling is done, all memory above 1A55 may be reclaimed and used for other purposes! Of course, you lose the editor, assembler, interpreter, compiler, find, the symbols, etc... but that's okay because your application code is built now and no longer needs those things. Storing the top word (e.g. STARTREK) into STARTUP will bring it up at launch, and SAVE-FORTH can store such an image on tape or disk like a turnkey application. BLKBUF will now be 7C00-7FFF and VMBUF still goes adjacent and just below that.
In no particular order, these are the design questions that I ponder today.
A VIC-20 is more useful for graphics when more of the $1000-1FFF region is available to the VIC chip. It'd be nice to move things around so `core` does not live there. What memory layouts might work better?
On the 80-column PET and the 128, a screen has 2000 characters (and no linewrap). It's workable if I make BLKBUF a 2K region and have screen packets be this size. The ewww factor is high.
Moving VMBUF at load is a pain. PETTIL has to look at the load address, subtract it from the end address, and subtract that number (packet file size) from BLKBUF. Then get the data. To make things more annoying, whenever the machine does tape or disk I/O, and the user hits the STOP key, or an I/O error occurs, the ROM drops to the BASIC `READY.`prompt. That code is chiseled into concrete, so all disk I/O for load, save and verify needs to be sandwiched between a pair of `aloha` calls to ensure that zero page is okay for running BASIC. Typing RUN resumes PETTIL with a warm start if this happens.
This (relocating loader that looks at the file load addres before calculating the effective load address) seems like it could be the sort of problem that someone else has already solved. All ideas are welcome.