6502 TaliForth2 Implementation Questions

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

6502 TaliForth2 Implementation Questions

Post by SparkyNZ »

After watching some Youtube videos on C64 White Lightning.. I have a new itch..

I have a virtual 6502 machine that I've played around with on Windows. I've made a simple Vic 20 emulator, BBC BASIC emulator and other things.. Now I'm thinking about building a copy of fig-Forth and creating some graphics extensions like you would find in White Lighting (e.g. functions/words that drive the Commodore 64's graphics or call kernel routines).

I've only just downloaded the fig-Forth assembly source. Just wondering if anybody had any hints or pointers on where to start - maybe somewhere there's some notes on how to implement the fig-Forth I/O routines which I need to start with first?

But let's say I get a simple Forth environment working - how would I go about adding a new word/token such as DRAW ? I'm not asking how to implement the specifics of DRAW -just how/where I would add support for the DRAW keyword, how many parameters it would expect to take, what it should return (if anything) and the likes.
Last edited by SparkyNZ on Mon Feb 24, 2025 9:42 pm, edited 1 time in total.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 fig-Forth Extensions

Post by SamCoVT »

Fig-Forth requires you to write:
cin - read in one ASCII character from keyboard (expects to block until key available - put char in A register)
cout - write one ASCII character (from A register) to terminal. Note, high bit (bit 7) may be set - best to clear that bit before outputting.
crout - move down to beginning of next line (eg. print linefeed or carriage return/linefeed if using a terminal)

Once you have those three working, you should be able to get an interactive forth prompt. If you hit enter and get OK back then everything is likely working.

I'd recommend starting by writing your words in Forth before you try writing them in assembly. You'll need to know how to access your video hardware. If you want to use C64 hardware (emulated or real) and you are familiar with POKE in basic, you can do that in Forth using the C! word. You also have the equivalent of PEEK with C@Here's an example:

Code: Select all

BASIC:
POKE 53281,1 : REM Set background to WHITE
PEEK(53281) : REM Get the current background color

Forth:
1 53281 C!   ( Set background to WHITE )
53281 C@     ( Equivalent of PEEK to get background color - value left on stack )
If you are targeting C64, I'd recommend getting a copy of Forth already assembled for that platform (the I/O will be done for you, and you can still POKE (C!) around - it may also have file I/O words available or be able to use blocks on a disk)

Once you get your word (written in Forth) working, then you can add it to the assembly source. You'll need to learn how to access the Forth data stack from assembly, and you'll need to add your word to the vocabulary linked list. When you get that far, let us know and we can help.
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: 6502 fig-Forth Extensions

Post by SparkyNZ »

SamCoVT wrote:
Once you get your word (written in Forth) working, then you can add it to the assembly source. You'll need to learn how to access the Forth data stack from assembly, and you'll need to add your word to the vocabulary linked list. When you get that far, let us know and we can help.
Yeah that's the part I'll be interested in. I'll get the Forth environment working first and then come back. I'm not targeting the C64 but it's good to talk about the C64 or Vic for examples. It will ultimately be for my homebrew 6502 system. Thanks
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 fig-Forth Extensions

Post by SamCoVT »

If your homebrew system has a 65C02 in it, I'll also put in a shameless plug for Tali Forth 2:
https://github.com/SamCoVT/TaliForth2
It's a significantly faster forth than FIG and is generally easy to port to new hardware (see the manual in the docs folder). It does require a 65C02 (won't run on an older 6502).
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: 6502 fig-Forth Extensions

Post by SparkyNZ »

SamCoVT wrote:
If your homebrew system has a 65C02 in it, I'll also put in a shameless plug for Tali Forth 2:
https://github.com/SamCoVT/TaliForth2
It's a significantly faster forth than FIG and is generally easy to port to new hardware (see the manual in the docs folder). It does require a 65C02 (won't run on an older 6502).
Thanks very much - I'll give Tali a shot first - no worries there. I'll be assembling it and loading it into my Windows 6502 emulator first. The homebrew machine has a WDC 6502 so it should be fine. I have far too many projects on the go so it will be a while before it runs on actual hardware but it would be good to get it up and running on my Windows app.

I'll go clone now and probably have a go at assembling it when I need a break from work next week :-)
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 fig-Forth Extensions

Post by SamCoVT »

If you need any help, there's a Tali-specific thread here you can ask questions in:
viewtopic.php?f=9&t=2926
Note that the thread has been running for 10 years and I'm not the original Tali Forth author, but I am the current maintainer.
You can also create a new thread for your questions if you want. The Forth folks here are helpful and are interested in hearing about whatever you find interesting in your Forthing adventures (even if it's simple).

Tali's build system requires GNU Make and 64tass, with gcc required if you also want to build the simulator it comes with (optional). On Windows, you can use WSL, Cygwin, or MinGW to get Gnu Make and gcc. You could also just download GNU Make for Windows and put it in your path.

Extending Tali Forth is similar to extending FIG Forth, and I'll recommend the same general sequence of writing your words in Forth first, and then translating them to assembly if it makes sense to do that. I think you'll find the source code for Tali is better documented than FIG, which makes that process much easier when it's time.

What Windows app do you use for simulation?
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: 6502 fig-Forth Extensions

Post by SparkyNZ »

SamCoVT wrote:
If you need any help, there's a Tali-specific thread here you can ask questions in:
viewtopic.php?f=9&t=2926
..
What Windows app do you use for simulation?
I installed MinGW and build the C65 version to try it out over the weekend (I admit I have been busy with other projects).

My Windows app is my own creation - it uses the same 6502 CPU source as C65 does so I'm on the same page there. I got as far as loading the tali-blah.bin file into my memory at $8000, setting FFFC and FFFD to point to $8000 and watched it fall over :-)

My app does log disassembly as it executes.. but to be fair, when I saw a load of BRK instructions being executed I figured I must be doing something stupid so I'll come back to it and possibly compare against the C65 app. I had a quick look at the first .asm file I could find but to be fair, I haven't spent enough time with it yet so I couldn't even confirm where the origin is yet.

I can jump across to the other thread if you prefer. I wondered about emailing you because I may have some really silly questions - but happy to use whichever channel is more appropriate.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 fig-Forth Extensions

Post by SamCoVT »

Silly questions are 100% allowed here, as they often help others who are experiencing the same silly problems. The Tali thread or this thread would be fine for that.

Just FYI, if you want to use this thread, you can rename the entire thread by editing the subject of the very first post. It's not uncommon for threads to longer match their initial title, so that's a good trick to know to make it easier for others to find information.

Starting at $8000 should work as long as your I/O doesn't need any initialization - that's where the word COLD is by default, and that word does a cold start. The expected starting address would be at the label kernel_init, found in your platform file (found in platform/simulator.asm if you are using the platform-py65mon.asm or platform-c65.asm platform files, as they share I/O routines).

There are no BRK instructions in Tali itself except for one in the word BYE, but I believe the unused areas in the bin file are zero filled so those will show up as BRK if you accidentally try to run code there.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 fig-Forth Extensions

Post by SamCoVT »

SamCoVT wrote:
There are no BRK instructions in Tali itself except for one in the word BYE, but I believe the unused areas in the bin file are zero filled so those will show up as BRK if you accidentally try to run code there.
That reminds me - I believe you end up in a series of BRK instructions if the CPU is a 6502 instead of a 65C02. I've run into that when I forget to change the cpu on py65mon because it defaults to 6502. Not sure if that helps with your situation, but I figured it was worth mentioning.
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: 6502 fig-Forth Extensions

Post by SparkyNZ »

SamCoVT wrote:
SamCoVT wrote:
There are no BRK instructions in Tali itself except for one in the word BYE, but I believe the unused areas in the bin file are zero filled so those will show up as BRK if you accidentally try to run code there.
That reminds me - I believe you end up in a series of BRK instructions if the CPU is a 6502 instead of a 65C02. I've run into that when I forget to change the cpu on py65mon because it defaults to 6502. Not sure if that helps with your situation, but I figured it was worth mentioning.
Thanks - I got it sitting on my machine at the moment.. hoping I can have a look during my lunchbreak :) I'm using fake6502. It looks as though I compiled with CMOS6502=1 .. but I'm not sure if that means its build for 65C02 or not. The fake6502 comments do say that "CMOS adds bugfixes and several instructions" so hopefully it is.
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: 6502 fig-Forth Extensions

Post by SparkyNZ »

SamCoVT wrote:
SamCoVT wrote:
There are no BRK instructions in Tali itself
My disassembler text was wrong. Instead of looking up opcode names at the PC, it was just using a bogus pointer. Now I have the code executing from $8000. I can see the CLD followed by the LDA/STA pair that store the address of kernel_putc. Because I'm loading the taliforth-py65mon.bin code, it's storing what appears to be $f022 as the address for kernel_putc (if I'm correct).

When I implemented my BBC BASIC emulator, I did some horrible things such as watching for jumps to various routines (think they were called OSBYTE and OSWORD if I recall). I'd then call some code in C to massage my ram byte array as necessary, tweak registers etc and return as required. This is more or less the direction I'll be taking with kernel_putc so I can write out provided characters to my screen. So this is totally a dirty hack (for now) but I'll be pretending to be py65mon as far as the code is concerned. Being able to run 6502 code within fake6502 on a Windows machine opens up so much when it comes to watching code. I even went through adding my own comments when I played with BBC BASIC so I could see my comments alongside the executed disassembly with optional registers and memory buffers. I think I added memory labels from .lst files too so I might do the same thing again - ie - assemble the py65mon, import the .lst labels etc.. That's if I really need to - I found py65mon-labelmap.txt which will be of good use. Interesting that it claims kernel_putc starts at $F027.. so maybe I should reassemble given that the .bin file I'm using looks a bit different.

I'll have to read the docs and do my research on how kernel_putc works. I'm guessing that the cold_zp_table contains vectors such as kernel_putc and that's what the rest of the code will use whenever kernel_putc is required. I just need to look through the code and find an example of where output is first done - where the Tali Forth 2 and version date are printed.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 TaliForth2 Implementation Questions

Post by SamCoVT »

The listing for taliforth-py65mon will end up in the file docs/py65mon-listing.txt and there is a labelmap there too if that's helpful.
The source code for kernel_putc, if you are using the py65mon based binary, will be in platform/simulator.asm

kernel_putc is expecting the character in the A register, and it just writes it to $f001 for the py65mon simulator.
kernel_getc just keeps reading from $f004 until a character arrives, and then returns that in A. It's a blocking routine.

The py65mon simulator will print any character written to $f001 and you can read from $f004 to get a char from the keyboard (the read from $f004 is non-blocking and returns 0 if no character is available).

The c65 simulator works mostly the same with addresses $f001 for printing and $f004 for reading, but reading characters is a bit different between them, so the code for kernel_getc is in the platform file itself (either platform/platform-py65mon.asm or platform/platform-c65.asm). If I recall, the main difference is that the c65 version has code for for the forth word KEY? which can detect if there is a key pressed or not. This is done by implementing (the entirely optional) kernel_kbhit, which returns 0 if no key is pressed and any other value when a key is pressed (it doesn't actually use up the keypress, though). The py65mon cheats a bit for kernel_kbhit by trying to read from $f004 and using a one byte buffer if it accidentally reads a character, and kernel_getc knows to check the buffer first.

The IO routines are placed just a little above that I/O section for those simulators, so I'm not surprised you are seeing addresses like $f022. You are indeed correct that the COLD routine is saving the address of kernel_putc (Tali uses vectored input and output so the user can replace the I/O routines while it is running). Only the vector for output is initialized at first, so that error messages can be printed if something goes wrong. The other vectors are copied in from a table a little later. If you want to see the source code for COLD, it's right at the top of words/all.asm

You're welcome to take a look at the modifications that Patrick put into c65 and yoink any you find useful - the code for Tali and c65 is public domain. I think the only modifications we made to fake65c02.h had to do with unused opcodes using up the correct number of bytes, and that did not affect the running of Tali at all because Tali doesn't have those opcodes and never generates those opcodes. I don't know if those changes made it upstream.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 fig-Forth Extensions

Post by SamCoVT »

SparkyNZ wrote:
When I implemented my BBC BASIC emulator, I did some horrible things such as watching for jumps to various routines (think they were called OSBYTE and OSWORD if I recall). I'd then call some code in C to massage my ram byte array as necessary, tweak registers etc and return as required.
You may want to take a quick look at platform/platform-neo6502 as it had I/O routines that were directly compatible with Tali (accepting or returning the character in A, with blocking reading (which Tali expects)), so I just assigned the labels kernel_putc and kernel_getc to those addresses. You could pick some unused addresses and do the same thing for your routines, seeing as you're going to write them in your simulator anyway.

That platform loads programs at $a000, so the assembly origin starts there, and there are no vectors at the end because that platform already has them loaded before Tali is loaded.
SparkyNZ
Posts: 30
Joined: 11 Mar 2022

Re: 6502 TaliForth2 Implementation Questions

Post by SparkyNZ »

SamCoVT wrote:
The listing for taliforth-py65mon will end up in the file docs/py65mon-listing.txt and there is a labelmap there too if that's helpful.
Well I seem to be getting somewhere.. My "screen" was actually an editor similar to the C64 but I've been changing it to do the simple PUTCH/GETCH behaviour. My brain too tired to do any more at the moment but at least I'm getting somewhere..

https://imgur.com/XSlZA53

I'm not sure how to upload images on this forum but hopefully you can see something. I'm not sure whether I should be handling line feed/CR myself or not but I'll come back to that tomorrow or the next day :-)
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: 6502 TaliForth2 Implementation Questions

Post by SamCoVT »

That looks great. The default behavior of BYE is to run a BRK instruction, and the default ISR vector for BRK instructions (or any interrupts, really) is kernel_init, so the fact it starts over again is expected behavior. You can write a new kernel_bye if you have an OS or monitor you would like to return to, but lots of Tali users just use Tali as their OS. It has an interactive shell, a built in assembler (hidden by default - see the docs for how to enable it), and direct access to the hardware.

How familiar with Forth are you? We handle questions and thoughts from people just getting started all the way through some members that are currently documenting their progress with metacompiling (where you use Forth to compile another Forth). Regardless of your skill level, you will want to check out the Glossary at the back of the manual to see all the words that Tali comes with. Tali is an ANS 2012 forth and you can also check the standard for more information on words at https://forth-standard.org/ (I use the Standard button and the Search function the most, at the top of that site, to find words).

It's best to add images to the forum, when possible, as the external links tend to disappear over time. To add images, make sure you are on the "full editor". The Quick Reply area at the bottom of the thread has a button to launch the full editor. Then, below the editor is an "Upload attachment" area. Choose your file, provide a text description (handy for people who may not be able to see the image), and click "Add the file".
How to add images to a post.
How to add images to a post.
This doesn't actually put the image in the post yet, it just uploads it to the server. After you've uploaded at least one image, there will be a new "Attachments" section with a dropdown that lets you pick the image you want and a "Place inline" button to add it to the post. It's handy to upload all of your images one at a time and then add them to your post where you want them.
How to place images in the thread post.
How to place images in the thread post.
6502_org_placing_images.png (31.8 KiB) Viewed 5542 times
You can click the "Preview" button to see how it's going to look.
Just FYI: There is an occasional issue where sometimes image previews get rotated that I don't have a solution for and most users will understand if that happens. I don't believe it rotates the original image, only the thumbnail preview, and it only happens occasionally.
Last edited by SamCoVT on Tue Feb 25, 2025 4:38 pm, edited 1 time in total.
Post Reply