Firing up a FIG-Forth

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

cjb wrote:
Dr Jefyll wrote:
cjb wrote:
MEM can't be greater than $7F00. The words that scan and add to the dictionary do signed comparisons with pointers.
Hi, cjb. MEM is not listed in my (6502) edition of the Fig glossary
I was referring to the parameter set in the fig-forth assembler source:

Code: Select all

MEM       = $6E00               ;top of assigned memory+1 byte.
UAREA     = MEM-128             ;128 bytes of user area
DAREA     = UAREA-BMAG          ;disk buffer space.
I was seeing the same problem as the OP when I had MEM much higher in memory, something that I'd been tracing the problems it caused for 2 straight days-- but then it struck me, and seconds later, everything worked! :D
I looked around and found MEM, it's set to $4000.

It's clearly my U* routine.

You can see from this trace:

Code: Select all

0F15             BASE 0976 98 01F4  S:0001 0000 0002 
0F17             @ 0785 96 01F4  S:3FA6 0001 0000 0002 
0F19             U* 052F 96 01F4  S:000A 0001 0000 0002 
0F1B             D+ 06BE 96 01F4  S:0000 0000 0000 0002 
0F1D             DPL 097F 9A 01F4  S:0000 0002 
The trace output is the IP, the name of the word, the CFA, the stack pointer, and the return stack. After the S: is the contents of the current stack. The gap is spaces in the front represents nesting (in truth this is just a space per byte on the return stack - not a perfect representation of nesting since some words >R and <R, but close enough).

It's just started to convert "123". You can see if found the "1", and converted it to 1 via DIGIT. I'm not sure what the double 0000 0002 is at this point. Then it fetches the BASE (10 is this case) and calls U*. But 0A * 01 is not 00. I guess U* takes two singles, and multiplies then unsigned in to an unsigned double. So, in theory the result should be 0000 000A, but instead it's zero.

However, note right after that D+ appears to work in this case.

So, it's certainly in U* at this point. Unfortunately, binary multiplication is not my strong suit. I haven't sussed out the issue here yet. ROL looks good, unless the flags are wrong. The rest are reasonably proven instructions. All of the work is in memory, rather than in registers, that makes it a little more difficult to trace.

Anyway, more digging.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Firing up a FIG-Forth

Post by Dr Jefyll »

whartung wrote:
It's clearly my U* routine.

You can see from this trace [...] After the S: is the contents of the current stack.
It took me a moment to get used to how your stack dump is formatted. Usually when the contents of a Forth stack are portrayed in text, the top-of-stack item shows on the right, not the left. But you're right -- U* is clearly not working, since it multiplied 0Ah by 1 and returned 0 (in double precision).

This wouldn't be caused by the bug Garth mentioned. Most likely it's another artifact of your simulator... probably in the 6502's shift/rotate instructions and their flags settings -- stuff that Forth hardly uses except in math routines. Fun!

Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

Hazah! Success.

Precedence hates me.

Code: Select all

result = result << 1 + carry;
is actually

Code: Select all

result = result << (1 + carry);
So, when ROL hits with Carry set, we end up with a 2 for 1 deal -- not good.

Quick fix and 123 123 + . gets me 246 like Chuck intended!

Now, VLIST appears to not be clearing the high bit on the last character... *sigh*...so, more digging.

But progress every day! I love the little errors I stumble upon. The mind -- it's a terrible thing.
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

whartung wrote:
Now, VLIST appears to not be clearing the high bit on the last character... *sigh*...so, more digging.
So I dug a little more. VLIST is pure Forth, and relies on TYPE, but I don't think TYPE does anything about the high bit on the final letter. TYPE itself looks pretty basic. So I guess it's working as designed, but this doesn't seem right to me.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Firing up a FIG-Forth

Post by Dr Jefyll »

whartung wrote:
The mind -- it's a terrible thing.
You're a funny guy. Congratulations on your success with Forth and your emulator!
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
BigDumbDinosaur
Posts: 9428
Joined: 28 May 2009
Location: Midwestern USA (JB Pritzker’s dystopia)
Contact:

Re: Firing up a FIG-Forth

Post by BigDumbDinosaur »

whartung wrote:
But progress every day! I love the little errors I stumble upon. The mind -- it's a terrible thing.
Tell me about it! Each day before I built POC V1.0 I'd review the design, only to find another little goof. Then I finally went ahead and built the thing, only to find yet another gotcha. <Sigh> At least V1.1 worked without the need for blue wire. :P
x86?  We ain't got no x86.  We don't NEED no stinking x86!
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

Dabbling some more, I have a couple of other new issues to tackle.

I can't seem to redefine a word.

I can create an initial word:

Code: Select all

: hello ." Hello world!" ;
but if I do it again, I get a ? MSG # 4. I need to dig up what that message means.

Also, apparently my DO - LOOP structures are not working, at least from the compiler since (DO) and (LOOP) work fine from the internal definitions.

I tried adding 3 words in the assembly. 1 took, one or both of the other two sent something in to a spin to where I would get the version message, but that was it -- after that it was stuck.

The word I added was a new USER variable to handle a TRACE flag, and I wrapped the JSR TRACE with some simply logic to check that flag.

Funny thing, when I enabled the trace the output was WILDLY different from when I simply had JSR TRACE hard coded.

So, I'm still in the "simplest things flummox me" stage. Guess I have more gremlins in the core to hunt down, but I think I'm running out of rare instructions to test.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Firing up a FIG-Forth

Post by Dr Jefyll »

Quote:
I can't seem to redefine a word.
I can create an initial word:

Code: Select all

: hello ." Hello world!" ;
but if I do it again, I get a ? MSG # 4.
It's a warning, not an error. Your new definition was successfully created. MSG#4 means "Not unique" Forth will warn you that the name already exists but it won't stop you from creating a new word by the same name.

Try creating another new word

Code: Select all

: hello ." Hello world, VERSION TWO" ;
Then type "hello" and you'll see the new word is found -- not the old word.

-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

Dr Jefyll wrote:
It's a warning, not an error. Your new definition was successfully created. MSG#4 means "Not unique" Forth will warn you that the name already exists but it won't stop you from creating a new word by the same name.
Yea, I finally tracked down the text of the 2 screens with the FIG error messages on it. Kind of annoying they're not in the original FIG listings. I stumbled upon a listing for an old Atari Forth that had them. After poking around, I see they're also in the Users Guide for the PDP-11 Forth (I remember when my friend keyed that in to our PDP-11 at school).

Thanks for the info though.

But, in other news, HAZAH! I found my FORGET bug. It wasn't my CPU at all!

If anything, it was my assembler.

In the FIG listing, all of the ZBRANCH and BRANCH offsets are hard coded constants ("hand crafted"), save for 1, in the core of FORGET.

There's this code:

Code: Select all

L3220     .WORD R,OVER,ULESS
          .WORD ZBRAN,L3225-*
          .WORD FORTH,DEFIN,AT,DUP
          .WORD VOCL,STORE
          .WORD BRAN,$FFFF-24+1 ; L3220-*
L3225     .WORD DUP,CLIT
The culprit is that "L3225-*".

In MY assembler, I get a value of 20 ($14), but if you use the eenie-meenie-minie-moe method of counting bytes using the Mark 1 Eyeball and Digitus Indexitus, I count that it should be 18 ($12). So, I guess I'm not advancing the '*' PC at the right point in my assembler. I can honestly say I haven't put any thought whatsoever in to how '*' is handled, specifically in this kind of situation. Arguably I'm doing it "wrong" since here's evidence of "wrongness", but I don't really know. (Does any one know how '*' should behave? Comments welcome...)

For the moment, I worked around it by simply changing it to "L3225-*-2", and HAZAH!, success. Now my FORTH can be as forgetful and I am.

So, that's good. One less thing.

While I'm not willing to stick this thing on a rocket to mars, I'm getting more confident that this beast is actually working. I can start adding mass storage to the emulator and implementing the disk primitives in the Forth. Then I can hunt down the awful Forth line editor to see if I can get that working. Next would be adding, perhaps, ANSI-ish escape handling and keyboard arrows (Forget arrows, WordStar diamond yo!) and such so I can hack out a Forth screen editor for my "smart" terminal.

And then...then...uh...I don't know then. Don't have a then set up for, um, then.

Debugging going back and forth from machine code to high level Forth is a bit of a pain. I added memory read/write breakpoints to the emulator, that helped a lot. Updated my memory dump display, that was handy too. Highlighting differences between display updates was helpful as well.

With the memory read breakpoints, I was able to "single step" high level Forth words by putting a BP on each word in the Parameter Field. I can safely say I'm glad I'm not debugging this on hardware with a 80x25 terminal staring at hex dumps from a machine monitor. (Though I was thinking about adding SuperMon to this...) Mind, if I was doing that I'd likely have a CPU that worked along with an Assembler that worked, but what fun is that?

Anyway, onward...Zoiks, and away!
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

whartung wrote:
So, I guess I'm not advancing the '*' PC at the right point in my assembler. I can honestly say I haven't put any thought whatsoever in to how '*' is handled, specifically in this kind of situation. Arguably I'm doing it "wrong" since here's evidence of "wrongness", but I don't really know. (Does any one know how '*' should behave? Comments welcome...)
I figured this out, it's not that mysterious as I thought. The problem is that in my assembler, I'm not incrementing my "current address" internal variable for each element of the .WORD and .BYTE instructions, I simply accumulate the delta and realize it at the end. '*' doesn't really need that much deep thought. Mind, I haven't fixed it, but just figured out what it is.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Firing up a FIG-Forth

Post by Dr Jefyll »

Looking back a ways...
whartung wrote:
My current problem is basically it's printing "? Msg #0" for pretty much anything I type after I hit enter. Whether its a blank line, a number or a forth word -- always that same thing.
cjb wrote:
MEM can't be greater than $7F00. The words that scan and add to the dictionary do signed comparisons with pointers.
I wrote:
somehow I'm still drawing a blank [...] I searched the assembly source to find code that uses < > and 0< (which do signed comparisons) and once again noticed nothing suspicious. What am I missing?
This story has an odd outcome. If you search the Fig Forth assembly source code as I did, looking for < (the signed less-than test), you'll see it's never used for testing dictionary addresses. And if you look at the code that does test dictionary addresses you'll see it uses U< (the unsigned version). This is as you would expect, since addresses are unsigned values.

However, Fig Forth U< turns out to be buggy. Apparently a hasty, last-minute addition to the code (it's unlisted in the glossary), U< is defined as

Code: Select all

: U< - 0< ;
This is incorrect, as explained here. With whartung's assistance a revised version of U< has now been successfully tested, and the original complaint is resolved -- MEM can be set as high as you like.

:oops: Ironically, the U< bug is clearly documented in notes I pencilled into my copy of the Fig source listing a couple of decades ago. As whartung said,
Quote:
The mind -- it's a terrible thing.
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

Still working getting I/O going. Nothing too exciting going on there, had to deal with simulator GUI stuff and the internal I/O routines are next, and finally the "hardware".

I added ".S" to print the stack, that was some fun spelunking, and I also added that to the assembly listing -- which was fraught with more danger, but seems to be working now as well.

I am curious about VLIST however, because it relies on "ID.", and I see that routine copy the text of the word out in to PAD, clean up the count and then call TYPE. But there's no consideration for clearing the top bit of the last byte. It's simply not there. It's not in the FIG model at all as far as I can tell. I've looked at several FIG listings, and they all do it the same way.

So, I'm wonder if there's an assumption that the ASCII I/O device is simply implicitly stripping the top bit, since ASCII is only a 7-Bit set. Historical software, historical assumptions.

I looked over at eForth, but it doesn't seem to have (easily findable I should say) either VLIST or ID., so I can't compare what they are doing. I did a little work trying to fix mine, but it just makes me want to get the I/O working some more -- would be nice to have error messages :).

Just curious if anyone else saw similar issues with ID. and VLIST.
User avatar
Dr Jefyll
Posts: 3526
Joined: 11 Dec 2009
Location: Ontario, Canada
Contact:

Re: Firing up a FIG-Forth

Post by Dr Jefyll »

Quote:
Just curious if anyone else saw similar issues with ID. and VLIST.
Yes, I seem to recall seeing the VLIST output on screen, with the last character of every word aliased to something other than normal ASCII. I never considered it enough of a problem to dig in and change the behavior, though.

Sorry for not speaking up sooner, since you did mention this in a previous post.

-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
User avatar
dclxvi
Posts: 362
Joined: 11 Mar 2004

Re: Firing up a FIG-Forth

Post by dclxvi »

whartung wrote:
But there's no consideration for clearing the top bit of the last byte.
In the 6502 implementation shown in the FIG-Forth installation manual, masking is done in EMIT (line 3042 of FIGINST.TXT)

ftp://ftp.taygeta.com/pub/Forth/Archive ... IGINST.ZIP

In 8086 FIG-Forth, masking is done in POUT (line 2501 of FORTH.ASM -- same in either archive, hooray for ancient archive formats :))

ftp://ftp.taygeta.com/pub/Forth/Archive/ibm/fig86.lzh
http://www.umich.edu/~archive/msdos/pro ... /fig86.arc

In 8088 FIG-Forth, masking is done in TYPE (line 1907 of FORTH)

ftp://ftp.taygeta.com/pub/Forth/Compile ... th8088.zip
whartung wrote:
I looked over at eForth, but it doesn't seem to have (easily findable I should say) either VLIST or ID., so I can't compare what they are doing.
Not sure which implementation of eForth you were looking at, but the last byte of a word name doesn't have bit 7 flipped in any of the eForths implementations I've dealt with or looked at over the years, so they could just use plain old TYPE for that sort of thing.
whartung
Posts: 1004
Joined: 13 Dec 2003

Re: Firing up a FIG-Forth

Post by whartung »

dclxvi wrote:
In the 6502 implementation shown in the FIG-Forth installation manual, masking is done in EMIT (line 3042 of FIGINST.TXT)

ftp://ftp.taygeta.com/pub/Forth/Archive ... IGINST.ZIP
Thanks for this, now that all makes sense. And this is the "elusive" FIG installation manual with these mythical screens the source code references. There's all these comments in the FIG assembly source to screens and words, and I had no idea what they were referring to. The Fig doc I have doesn't have those screens. This doc is much better.
Quote:
Not sure which implementation of eForth you were looking at, but the last byte of a word name doesn't have bit 7 flipped in any of the eForths implementations I've dealt with or looked at over the years, so they could just use plain old TYPE for that sort of thing.
Yea I was just looking at source from the web pages, I didn't know if they did the 7th bit thing or not. But it was a readily available, "look I don't have download more junk to my hard drive", view it on the web kind of spelunking.
Post Reply