VolksForth

pzembrod
Posts: 93
Joined: Sat Aug 29, 2020 9:21 pm

General - CX16 VolksForth

Post by pzembrod »

VolksForth is available for the latest X16 version again; VolksForth version 3.9.5 contains adaptions for the R46 Kernal.

VolksForth is a 16-bit ITC (Indirect Threaded Code) Forth system produced by the German Forth Gesellschaft e.V. that I am in the process of renovating. It so far follows the Forth-83 standard. Adaption to the ANS Forth standard is planned for the future, but first we want to merge the 4 platforms (6502, 68k, 8080, 8086) that were forked off one another in the 80s back into a shared code base. VolksForth is built from Forth sources with a metacompiler or targetcompiler.

This release includes a binary
v4th-x16e.prg
(13.84 KiB) Downloaded 442 times
that, added to the Forth kernel, contains direct invocation of the ROM version of Stefan's excellent X16Edit via the word XED, as well as the words DIR, CAT and DOS for disk handling.

The full release can be found at github.com/forth-ev/VolksForth/releases/tag/v3.9.5-6502-C64.

An update of my cc64 Small C compiler which is built using VolksForth will soon follow, too.
Stefan
Posts: 448
Joined: Thu Aug 20, 2020 8:59 am

Re: VolksForth

Post by Stefan »

That is great news!
voidstar
Posts: 445
Joined: Thu Apr 15, 2021 8:05 am

Re: VolksForth

Post by voidstar »

Ok, I gave this a try. I know nothing about Forth.

I understood translation, like
: TEST ." HALLO ;

But, where is the STACK?

I tried an old C64 example, which had this:

: 2SORT STACK: n1 n2

And it didn't seem to recongize STACK. I tried doing "words" and didn't see STACK listed in there - but it scrolls off the screen and not sure if it was all sorted/in-order. So I tried to do -echo in the emulator and capture all the words, but they all come out as \X codes and not readily searchable.

Looks neat, just I need a bit of an orientation here :)


One reference in German: https://www.lyonlabs.org/commodore/onrequest/UF.pdf

Another C64 reference: https://www.lyonlabs.org/commodore/onre ... he_C64.pdf
MarkTheStrange
Posts: 18
Joined: Sat Nov 26, 2022 6:24 pm

Re: VolksForth

Post by MarkTheStrange »

Cool to see Forth on the X16! Some initial thoughts:

It seems odd not to take advantage of the screen editor – by which I just mean the one that BASIC uses, not X16Edit, i.e. reading input using BASIN/CHRIN instead of rolling your own cursor and using GETIN. You lose the ability to cursor around the screen and hit enter on previously-entered lines and so on; the one-line input interface feels a little extra-retro even for retrocomputing. Especially with no PETSCII control code support; you can't even clear the screen with 147 emit.

Is there a vocabulary for low-level access? It going to be hard to write useful programs without a way to call into ML routines. Tom Zimmer's 64FORTH for the C64 had a SYSTEM vocabulary which included a SYS word, for instance. (It pulled register values from the stack on entry and pushed them on return; I might prefer some standard variables that you can C! before the call and C@ afterward instead, analogous to the way SYS works from BASIC, just so you don't have to push or pop a bunch of dummy values when you're not using them.) I don't think there's a standard for this, but some type of access is needed to open up the capabilities of the system beyond what's built into the dictionary that comes with.

A few bugs I noticed:

1. Doubles are backwards on the stack; the MSW should be on top. (FORTH83 section 5: "Double numbers are represented on the stack with the most-significant 16 bits (with sign) most accessible." Both 64FORTH and GNU Forth match the spec.)

2. An unrecognized word should clear the stack; guides like Starting Forth recommend using intentionally-bogus words as a way to clear a cluttered stack quickly.

3. The cursor seems to get stuck on the screen when backspacing.

I look forward to seeing more from this project!
MarkTheStrange
Posts: 18
Joined: Sat Nov 26, 2022 6:24 pm

Re: VolksForth

Post by MarkTheStrange »

@voidstar There are standards for FORTH (FORTH-83, ANS FORTH), but no two are quite alike anyway.

I'm not familiar with any that have a word named STACK, though. The stack (well, the data stack; there's also a return stack) is where operands live, but is itself unnamed. The nondestructive way to look at what's on it is .S. You can also use . to remove the top of the stack and print it (as a signed single-cell decimal number), but then it's gone. Though you can use DUP to make a copy first so there's still one left after the printing.

Note that Forth's output primitives do not as a rule append (or prepend, for that matter) newlines. You can use CR to print one.
pzembrod
Posts: 93
Joined: Sat Aug 29, 2020 9:21 pm

Re: VolksForth

Post by pzembrod »

Hi voidstar,

some answers you already got from MarkTheStrange, like .s for viewing the stack.
voidstar wrote: Tue Dec 05, 2023 12:52 am Ok, I gave this a try. I know nothing about Forth.
In that case I would recommend Leo Brodie's excellent book Starting Forth.
It's really the canonical introduction to the language.

And to add motivation to learn forth: Leo's Thinking Forth is really a masterpiece,
I think one of the best books on software design I have ever read. Though long ago, I must admit.
voidstar wrote: Tue Dec 05, 2023 12:52 am One reference in German: https://www.lyonlabs.org/commodore/onrequest/UF.pdf
Yes, that's the right one. The current canonical source would be here on forth-ev.de.
We should probably put it into the GitHub repo, too. A reference in German is okay for you?
Alas, we don't have an English one, at least as yet.
pzembrod
Posts: 93
Joined: Sat Aug 29, 2020 9:21 pm

Re: VolksForth

Post by pzembrod »

Hi Mark!
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm Cool to see Forth on the X16! Some initial thoughts:

It seems odd not to take advantage of the screen editor – by which I just mean the one that BASIC uses, not X16Edit, i.e. reading input using BASIN/CHRIN instead of rolling your own cursor and using GETIN. You lose the ability to cursor around the screen and hit enter on previously-entered lines and so on; the one-line input interface feels a little extra-retro even for retrocomputing. Especially with no PETSCII control code support; you can't even clear the screen with 147 emit.
I think there's two reasons for this. For one, I guess it's hard to implement the Forth-83 standard words KEY, EXPECT and QUIT with the CBM BASIC screen editor. And two, the first VolksForth, on the C64, offers to use up to 50k of RAM ($0800-$CFFF) and thus didn't have the BASIC ROM enabled.
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm Is there a vocabulary for low-level access? It going to be hard to write useful programs without a way to call into ML routines. Tom Zimmer's 64FORTH for the C64 had a SYSTEM vocabulary which included a SYS word, for instance. (It pulled register values from the stack on entry and pushed them on return; I might prefer some standard variables that you can C! before the call and C@ afterward instead, analogous to the way SYS works from BASIC, just so you don't have to push or pop a bunch of dummy values when you're not using them.) I don't think there's a standard for this, but some type of access is needed to open up the capabilities of the system beyond what's built into the dictionary that comes with.
The usual way to access the system at low-level would be through CODE words using the 6502 assembler that comes with VolksForth. Way back, I implemented a pretty nifty 1351 mouse driver and input support; you could double-click on any word on the screen, and it would be fed into the keyboard buffer. I'll have to dig that out again some day.

That said, the idea with a SYS word is also kinda nice. Easy to write, too. Though I would definitely feed that through the stack, not through variables.
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm A few bugs I noticed:

1. Doubles are backwards on the stack; the MSW should be on top. (FORTH83 section 5: "Double numbers are represented on the stack with the most-significant 16 bits (with sign) most accessible." Both 64FORTH and GNU Forth match the spec.)
I think that is so with VolksForth, too:

Code: Select all

 ok
12.  ok
.s 0 12  ok
. 0  ok
. 12  ok
Turns out VolksForth's .s prints the stack TOS to the left whereas e.g. GForth prints TOS to the right. Maybe that caused confusion?
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm 2. An unrecognized word should clear the stack; guides like Starting Forth recommend using intentionally-bogus words as a way to clear a cluttered stack quickly.
I can't find anything in the Forth-83 standard wrt this.
The ANS standard says in 3.4 d. that then an ambiguous condition exists. I.e. the standard doesn't prescribe anything.
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm 3. The cursor seems to get stuck on the screen when backspacing.
Yes, that's a catch that I wasn't able to iron out yet. Last time I visited that piece of code,
I felt I need some additional Kernal API call. I should bring it up with Michael Steil again.
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm I look forward to seeing more from this project!
Thanks! I'm about to release the adapted version of cc64 (written in VolksForth), probably today on GitHub, possibly here tomorrow.
And what I would love to see is people doing stuff, writing things, with either of the two, for the X16.
Wanna take a stab at it?
MarkTheStrange
Posts: 18
Joined: Sat Nov 26, 2022 6:24 pm

Re: VolksForth

Post by MarkTheStrange »

pzembrod wrote: Tue Dec 05, 2023 8:51 pm I think there's two reasons for this. For one, I guess it's hard to implement the Forth-83 standard words KEY, EXPECT and QUIT with the CBM BASIC screen editor. And two, the first VolksForth, on the C64, offers to use up to 50k of RAM ($0800-$CFFF) and thus didn't have the BASIC ROM enabled.
Fair, although I don't think you need BASIC for the screen editor, just the KERNAL. And the standard IRQ routine has to be enabled. In which case it should be as simple as replacing JSR GETIN with JSR CHRIN, and getting rid of your custom cursor handling stuff. In 64FORTH, based on behavior (I haven't disassembled it), KEY seems to use GETIN, while the normal QUIT REPL doesn't, so I'm guessing the definition of QUIT is CODE that doesn't involve KEY.
pzembrod wrote: Tue Dec 05, 2023 8:51 pm The usual way to access the system at low-level would be through CODE words using the 6502 assembler that comes with VolksForth.
Great! I found the German Handbuch; is there any English doc? I wonder if it's the assembler syntax is the same as the one in 64FORTH.
pzembrod wrote: Tue Dec 05, 2023 8:51 pm That said, the idea with a SYS word is also kinda nice. Easy to write, too. Though I would definitely feed that through the stack, not through variables.
I brought up the variables approach because to properly set up an ML call in 64FORTH you have to push four things on the stack in addition to the address of the subroutine – A, X, Y, and the processor status register, since many routines change their behavior based on whether the carry flag is set or not – and a routine that expects five arguments and leaves four is rapidly moving away from Moore-friendly. :) When calling routines via SYS from BASIC, there are four memory locations from which the registers are loaded, and the values in the registers are stored back there when the called routine returns to the BASIC interpreter. So the access is there if you need it, but you can ignore it if you don't, on both sides of the call. I thought some well-known variables could work the same way in Forth, too. I think something like this:

Code: Select all

: MEMTOP 1 FLAGS C! -103 SYS Y C@ 256 * X C@ + ;
is a little clearer than this:

Code: Select all

: MEMTOP 1 0 0 0 -103 SYS 256 * + SWAP DROP SWAP DROP ;

pzembrod wrote: Tue Dec 05, 2023 8:51 pm Turns out VolksForth's .s prints the stack TOS to the left whereas e.g. GForth prints TOS to the right. Maybe that caused confusion?
Indeed that was it. I guess the order of .S is not specified by the standard, but I'd not previously encountered a Forth which printed the TOS to the left. After all, the standard stack diagrams used in word documentation place the TOS on the right - on both sides of the dashes, even. Anyway, sorry for the false accusation!
pzembrod wrote: Tue Dec 05, 2023 8:51 pm
MarkTheStrange wrote: Tue Dec 05, 2023 12:50 pm 2. An unrecognized word should clear the stack
I can't find anything in the Forth-83 standard wrt this.
The ANS standard says an ambiguous condition exists. I.e. the standard doesn't prescribe anything.
Yup, that's why I mentioned Starting Forth rather than the standards. I was just surprised; I've encountered the advice more than once. But I see Volksforth has the standard word CLEARSTACK, so it's hardly necessary functionality. For interactive use ABORT works, too...
pzembrod wrote: Tue Dec 05, 2023 8:51 pm Thanks! I'm about to release the adapted version of cc64 (written in VolksForth), probably today on GitHub, possibly here tomorrow. And what I would love to see is people doing stuff, writing things, with either of the two, for the X16.
Wanna take a stab at it?
I'll give it a shot. I was writing a Forth implementation from scratch for the X16, but while that's fun, it's probably more productive to build on the one we already have. :)
pzembrod
Posts: 93
Joined: Sat Aug 29, 2020 9:21 pm

Re: VolksForth

Post by pzembrod »

MarkTheStrange wrote: Wed Dec 06, 2023 2:57 am Fair, although I don't think you need BASIC for the screen editor, just the KERNAL.
Ah, that might be the case. I'll have to try that out. There's one other reason, though, why buffered input is coded by VolksForth itself instead of using Kernal's CHRIN, and that's the Forth tasker. Here's what C64KEY (also used for C16 and X16) looks like:

Code: Select all

: c64key  ( -- 8b)
 curon BEGIN pause c64key?  UNTIL
 curoff getkey ;
The PAUSE in the loop keeps the cooperative multitasking alive even during keyboard input. And there we also have the reason for the hanging cursor on delete: I couldn't implement CUROFF reliably, IIRC because I would have to duplicate significant parts of Kernal code, I think it would have been from cbm/editor.s, to do so.
MarkTheStrange wrote: Wed Dec 06, 2023 2:57 am
pzembrod wrote: Tue Dec 05, 2023 8:51 pm The usual way to access the system at low-level would be through CODE words using the 6502 assembler that comes with VolksForth.
Great! I found the German Handbuch; is there any English doc? I wonder if it's the assembler syntax is the same as the one in 64FORTH.
Unfortunately we don't have an English manual. 64FORTH has the canonical 6502 figForth assembler by Bill Ragsdale from which also VolksForth's assembler is derived; there's just a small change in syntax, afaik, the VolksForth assembler dropped the trailing comma of Bill Ragsdale's mnemonics. atariwiki.org offers a convenient comparison of the assemblers of VolksForth and figForth.
MarkTheStrange wrote: Wed Dec 06, 2023 2:57 am I think something like this:

Code: Select all

: MEMTOP 1 FLAGS C! -103 SYS Y C@ 256 * X C@ + ;
is a little clearer than this:

Code: Select all

: MEMTOP 1 0 0 0 -103 SYS 256 * + SWAP DROP SWAP DROP ;
Ah yes, I see your point.
MarkTheStrange wrote: Wed Dec 06, 2023 2:57 am I'll give it a shot. I was writing a Forth implementation from scratch for the X16, but while that's fun, it's probably more productive to build on the one we already have. :)
Hehe; I have a 3/4 done STC 6502 Forth implementation from my university days myself somewhere in my drawer. That's one of the things about Forth, it's so easy, and fun, to implement. Implementation-wise, I find the interesting thing about VolksForth to be that it is metacompiled; understanding its metacompiler (or targetcompiler in VolksForth's lingo) is one of the near things on my todo list.

Looking forward to anything in Forth you're going to produce!
MarkTheStrange
Posts: 18
Joined: Sat Nov 26, 2022 6:24 pm

Re: VolksForth

Post by MarkTheStrange »

I'm afraid I don't think you can do much on the X16 with VolksForth in this form (i.e. no access to the kernel or even PETSCII control codes in its stock configuration). You can do a lot in plain text mode on the X16 - display text in multiple colors anywhere on the screen, for instance. In VolksForth it's like the machine is emulating a generic ASCII line terminal that doesn't even support ANSI escape sequences. And I don't see any way to fix it, other than rewriting QUIT, KEY, etc. to use KERNAL routines instead of doing everything from scratch.

How do you write code words? It doesn't understand CODE, even in ASSEMBLER context, so it doesn't seem to work like other Forths in that respect. The manual references one that shows examples using CODE, so I'm a bit confused. However you write it, I think there will have to be a lot of assembly to do something interesting on the X16 platform from VolksForth.

But I suspect we need to work toward an X16-specific build that doesn't swap ROM out to get more RAM: the X16 isn't as constrained as the C64. Also, its KERNAL does a lot more than the C64 one; there are routines for bitmap graphics, fast copies between memory locations or with the disk drive, etc. A lot of the new stuff in X16 BASIC is not really part of BASIC, but just a BASIC interface to functionality actually provided by the KERNAL, and VolksForth boots up with none of that stuff available to it.
Post Reply