6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 9:15 am

All times are UTC




Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sat Feb 24, 2024 5:36 am 
Offline

Joined: Tue Sep 26, 2023 11:09 am
Posts: 109
started looking at running taliforth2 on my ben-eater-like 65c02 project.

I would love to get a small (8K??) kernel that I could link with other assembly I've been building with ca65 toolchain.

I was able to get a 16K taliforth2 image running by removing all the optional words other than block,
(including disassembler which I made optional), and then changing to org $c100 and removing the pymon I/O gap.
I moved pymon I/O to $c001/4. So this seems to make and run OK (below), and even leaves a couple kb free at top:

Code:
Output file:       taliforth-py65mon.bin
Data:      14088   $c100-$f807   $3708
Gap:        2034   $f808-$fff9   $07f2
Data:          6   $fffa-$ffff   $0006

py65mon -m 65c02 -r taliforth-py65mon.bin -i c004 -o c001

Wrote +16128 bytes from $c100 to $ffff
Tali Forth 2 default kernel for py65mon (04. Dec 2022)


Tali Forth 2 for the 65c02
Version 1.0 04. Dec 2022
Copyright 2014-2022 Scot W. Stevenson, Sam Colwell
Tali Forth 2 comes with absolutely NO WARRANTY
Type 'bye' to exit


But that's still almost all of the 16K rom I was planning.

If I want to get smaller, is there any other obvious stuff I could remove to minimize the image size? I'm happy to trade slower for smaller if that helps.

I also use the ca65 tool chain for all the other stuff I've been building, so it would be nice if there was a way to either compile TaliForth2 with ca65 (I saw there'd been some discussion/experimentation on github), or at least generate an object file/symbol table that I could link with ld65. Anyone have any tips there?

Thanks!


Top
 Profile  
Reply with quote  
PostPosted: Tue Feb 27, 2024 2:15 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
Hi pdragon,
Tali Forth 2 is a rather large Forth. While it is possible to fit it in 16K, I don't think it would be a great experience to get it down to 8K. Tali Forth 2 is designed for systems with 32K ROM (or RAM if loading it into RAM) where Tali takes up 24K (if you include everything) leaving 8K for your code. 8K is a lot of space for a BOIS or monitor program.

Tali can be assembled with ca65, but you'll have to replace the pieces that are specific to 64tass. Off the top of my head, that's going to be the conditional compilation and you may need to rework the anonymous labels used for short jumps. Search for + or - on a line by itself to find the anonymous labels. I don't remember if ca65 accepted the syntax currently in use.

I did a quick port a while back when we were testing new assemblers to allow for conditional assembly, so I don't think it's too much work. We ultimately did not pick ca65 because having users set up a correct custom target system file was more complex, but if you're already using it then you should know how to do that. If you decide to go down this path, I can certainly help if you get stuck.


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 03, 2024 12:12 am 
Offline

Joined: Tue Sep 26, 2023 11:09 am
Posts: 109
hi - thanks for the reply. so far I'm doing fine with at just under 14K which works for my 16K rom with a bit of extra kernel code.

I've got a simple block device working so with a tiny user_words prologue I can bootstrap from a block of forth code, and also have a minimal C simulator set up that runs like pymon but much faster (and supports block read/write). so my dev cycle is just edit normal forth files; re-make block image; run sim pointing at block image; which is pretty sweet. happy to make a PR if that's useful for others.

one thing I haven't figured out is if I can easily dump and reload compiled words. my source (even via ophisbin-like squashing) is probably going to end up too big alongside the data files I need, so would be cool to pre-compile in the simulator and just load a pre-built dictionary. any ideas about that?

overall taliforth has been excellent; solid docs and no bugs (tho /mod with signed results confused me for a while) with nicely documented source.

the only real stumbling points i've had are (a) it seems like `evaluate` doesn't play nice with backslash comments plus new-lines (the first backslash seems to swallow the rest of the source) and (b) would love a little more in the "getting started" docs to illustrate a simple pymon dev cycle for newbies. e.g. super simple like how to use load in pymon to import a source file to memory and jump into forth with evaluate to execute it. I got there eventually but felt I was floundering for a while. the current html doc also seems to have some semi-duplication of sections but understand if none of that is a priority right now.

thanks again for sharing all this!


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 04, 2024 9:39 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
Hi pdragon,
I'm happy you were able to get things working.

Your setup sounds pretty neat. If you have a repository or web page that explains your setup, I'd be happy to include a link to that in the docs/ch_installing.adoc file and you are welcome to make a Pull Request for that.

Can you dump and reload compiled words? It's Forth, so the answer is "of course you can" - the real question is how difficult it is. Tali has no in-built facilities to do this itself, so you will have to write it yourself, and some of the things you will need to touch are currently not exposed to Forth. You might write it entirely in assembly and then you'd create Forth words for performing the dump or restore, or you could create some Forth words to allow access to the data structures used under the hood in Tali and then you can do it all in higher level Forth.

--------------- BEGIN Long-winded description of what might be involved

There are "user variables" in both zero page and in regular RAM. You'll need to touch both. A few have Forth words to give you their address, but many are just defined as an offset from the beginning of the set. By default, the zero page user variables start at address 0 and go up from there (unless you moved the label "user0" in your platform file). You can see their offsets in definitions.asm. You are going to be interested in cp (the Compiler Pointer), dp (the Dictionary Pointer), and up (User Pointer - holds the address of the user variables in RAM) in zero page.

You'll also need to access some in-ram user variables. These use the address in up (which you can get using the word USERADDR in Forth) as a base address and then the offsets are listed further down in definitions.asm. You might be interested in
current_offset (determines which wordlist is being compiled into - be careful as this is a single byte and is an index into the list of wordlists),
num_wordlists_offset (also a single byte - it's the number of wordlists that currently exist - default is 4 (FORTH, ASSEMBLER, EDITOR, and ROOT),
wordlists_offset (an array of 16-bit addresses to the name token (address of a dictionary entry) for the latest word in each wordlist - there are the base 4 plus 8 more slots the user can use),
num_order_offset (single byte - number of wordlists in the search order), and finally
search_order_offset (an array of 9 bytes with each holding an index into the wordlists_table to indicate the order the wordlists should be searched during dictionary lookup).

If you aren't familiar with wordlists, I recommend reading https://forth-standard.org/standard/search - it's a bit obtuse, as it's trying hard not to specify how a Forth might implement these things. This is one of the more complicated pieces of Tali Forth, and I can see why people like the older VOCABULARY method of dealing with multiple dictionaries.

By default, when you first start Tali, all new words are compiled into the FORTH wordlist. In order to "save" your compiled words, you'll want to dump the memory between where CP was BEFORE you started (you can use the Forth word HERE to get that) and where it points to after you have compiled your application. Assuming you don't want to create a separate wordlist and just use the Forth wordlist, you'd just need to save and restore that block or memory along with the pointers in CP (in zero page), DP (in zero page), and the address in the FORTH wordlist (which is wordlist #0) in main memory. Note that this will restore the dictionary AND the compiled words, as Tali currently compiles the dictionary entry and body of the words together. If you want to be able to remove the names of the words, you could modify Tali to compile the names somewhere else.

If you are going to create your own wordlists, you really need to save/restore all of the wordlist items.

--------------- END Long-winded description of what might be involved

I agree that evaluate does not handle \ comments properly when they are embedded in strings - that's because ACCEPT gets one line at a time and does not include the line ending, so Tali simply jumps to the end of the input buffer when it sees \. On the other hand, ( and ) type comments should work. If you want to try fixing this (or want me to fix it), you are welcome to open an issue, but I will warn you that it should probably fix the behavior in BLOCKs as well, which have no line endings and simply have lines at fixed offsets.

In terms of a development cycle, what you describe for loading source into memory and then EVALUATE-ing in the simulator is the "hard way". Most people just edit the source on their PC and then copy/paste into the window running the simulator. I do that for developing on my real hardware as well, but it's a terminal window instead of a simulator window. It lets you use your fancy editor on your PC while seeing (almost instantly) the results from Forth. It's also super handy to copy/paste line by line when you are trying to debug something. I'm on Linux, so it's just highlight with regular mouse button and then middle click in the terminal to paste. On windows you can use the usual copy/paste commands. Once I have working code that I will want to use later, I copy it to compact flash or SD card, for which I have only implemented read-only support.

I like to work with what I call "reproducible state". I start with a cold booted Tali (you can always use the word COLD to get back to the cold boot state) and paste in my code to get to a particular state. If I'm troubleshooting, it will be the point just before the bad things happen. If I'm writing new words, it will be just after the new words have been defined so I can poke and prod them. Then I'll type manually at the Forth prompt to explore. I might paste in some problem code line by line or create a test word to try small pieces of it. If things break again, I can always "rewind" by resetting my board or simulator and pasting up to just before that point.


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 05, 2024 2:22 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
pdragon wrote:
The current html doc also seems to have some semi-duplication of sections but understand if none of that is a priority right now.
I am actually quite interested in this. You currently have a superpower that I do not have, and that is reading the docs when you have never read them before - you will see things that I am simply unable to see. I am aware of some duplication - in some cases this is intentional so that people who only read a subset of the manual will get the important info, but in other cases it's a result of the documentation being rearranged and it may be unintentional. I'm getting ready to do some fixes to the documentation, so now is a great time to just open an issue and tell me what you see that you think could be better.


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 05, 2024 4:46 pm 
Offline

Joined: Tue Sep 26, 2023 11:09 am
Posts: 109
thanks for the pointers, i've already been digging in to the developer docs to understand how word compilation works and doing some source browsing (nicely documented!) to look at cold, init and quit. so with your advice i'm quite optimistic i'll be able to figure out how to dump and recover the compiled word state.

in terms of dev cycle, i do lots of cut and paste from the editor into the sim, but I have a large and growing baseline of working words since I'm learning forth by porting a reasonably
hefty chunk of C code. so I normally want to have all that loaded and compiled in the sim as i experiment with new words or other changes. the stripped forth source is about 18K atm, so is painful to try to paste the whole thing at once. i use a block device hook to read the source a few K above 'here' and then evaluate all of it, which compiles down much smaller.

once things are more or less working i'd like to be able to distribute a simple 64K memory image with the pre-compiled dictionary and other data which would just reset into the starting word. i found some other forths implement 'turnkey' for that (e.g. https://udamonic.com/starting-up-with-turnkey.html), so I'll probably try to replicate something along those lines.

good point on the documentation, i'll make an issue with some notes of my experience reading it


Top
 Profile  
Reply with quote  
PostPosted: Thu Mar 21, 2024 1:40 pm 
Offline

Joined: Tue Sep 26, 2023 11:09 am
Posts: 109
for future reference there's now an illustrative minimal config in the taliforth repo https://github.com/SamCoVT/TaliForth2/b ... inimal.asm which pares down to about 12K


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: