Forth

Keedon

New Member
Oct 20, 2019
4
0
1
Would forth be something people would be interested in? There’s a fig-forth for the 6502 which could be added as one of the spare ROM banks?
 

BruceMcF

Active Member
May 19, 2019
139
42
28
The Forth port I have been working on is Camel Forth for the Z80, but this would be a RAM based Forth, so loaded and run as a PRG.

The Camel model can be made ROMMable, but in my first iteration I am just trying to make the most straightforward port of a direct threaded Forth work. This is being done on on the VICE C64 emulator, so it is a slow but straightforward direct threaded model ... but I am restricting I/O to KERNAL calls, so once it is debugged, changing the zero page locations to the CX16 user page locations should be all that is required to move it to the CX16.

My direct threaded 65C02 model, based on a "INX; INX; JMP (addr,X)" routine sitting at $00, so the IP is at $03/$04 and NEXT is "JMP $0000", is waiting on getting the first port debugged.
 

mobluse

Member
Sep 20, 2019
35
15
8
Why are you developing a new Forth for VICE C64? There are already plenty of FORTHs for C64. X16 has a WDC 65C02 CPU and one could use the features of that to advantage. Still it might be useful to have CamelForth for C64. One could probably have the same source code but use a preprocessor to use different instructions for the two CPUs.
 

Keedon

New Member
Oct 20, 2019
4
0
1
I'm not - I was just asking if there was an interest in a forth system. It looks like there are a few in development already
 

BruceMcF

Active Member
May 19, 2019
139
42
28
Why are you developing a new Forth for VICE C64? There are already plenty of FORTHs for C64. X16 has a WDC 65C02 CPU and one could use the features of that to advantage. Still it might be useful to have CamelForth for C64. One could probably have the same source code but use a preprocessor to use different instructions for the two CPUs.
The port started a number of months before the emulator was available.

The whole idea was to "port" CAM64TH to CAMX16 by just renaming it, loading it and running it ... until recently, when they changed the zero page locations, at which point the idea became to port it by assembling it to the new zero page locations, rename it and run it.

And in large part, because of the Monitor in VICE. So far I've done a lot of single stepping through various operations to get it to the point where it correctly inputs a line ... I don't think I would be anywhere near as close to running without the VICE Monitor.

The Camel for the Z80 code is well divided between model primitives, high level model dependencies, and common high level forth, so if it gets up and running, it should be possible to port it to a 65C02 "INX: INX: JMP ($0000,X)" NEXT in Zero Page model without having to debug the common high level forth again. It would use the same model dependencies and high level forth file, and its own edited primitives file ... and since the primitives file has the includes for the other one, no preprocessor is needed, just assembling the primitive file for the model that you want.

Edit: Also, since CAM64TH uses X for the return stack index in a split pair of byte stacks in Golden RAM, while NEXT uses but does not return Y for the indirect fetch of the direct word address, and uses the hardware stack for the data stack, if I use X for NEXT and Y for the a split pair of byte stacks in the much more expansive CX16 zero page user locations ... and then save the RNDX in between uses, so Y is free ... I can keep on using the same operand definitions except for the R-stack users.

It's also a good set up for benchmarking different models, since the benchmarking code could get built into the high level forth file, but that is not as big an issue unless they release the board with the 65816.
 
Last edited:

BruceMcF

Active Member
May 19, 2019
139
42
28
Sketched in for later is to add Blocks, and a separated dictionary, and modules, all in High RAM.

The idea is that BLOCK files have always been accessed "as if" atomically, inside the BLOCK operation, so as long as the BLOCK operation is in Low RAM, it can fill a 1K Buffer from a High RAM segment when a different High RAM segment is in "regular" use.

Also, the dictionary search process is in Low RAM as well, so if the dictionary is shifted from an embedded dictionary to a separated dictionary (step one), then it can also be in a High RAM segment when a different High RAM segment is in "regular" use.

So finally, a "MODULE name" "PUBLIC" "PRIVATE" system can be used to define routines in an 8K module, which the "PUBLIC" having entry routines (maximum of 128, each one a jump vector allocated from $BFFE down), so the "call module entry routine" operation is the routine address followed by two bytes ... the High RAM segment and the index of the routine in the jump vector.

That means that an inter-module call between two public routines in different modules is done the same as a a module call from the main Forth wordset in Low RAM. An intra-module call is just a regular Forth word vector, where that address happens to be in the $A000 to $BFFF range that is the High RAM segment of the currently active module.

So there would be three different uses of High RAM ... 1K BLOCKs, the dictionary system, and loadable code modules ... but each would not step on the toes of the other.
 
Last edited:
  • Like
Reactions: Keedon