Compiling TaliForth2 on Windows
Compiling TaliForth2 on Windows
I'd like to get TaliForth running on my emulator, but I'm having some trouble getting it to compile. I installed GnuWin32 make and ophis, then changed the makefile to add the full path for ophis. make responds with "Nothing to be done for `all'." I tried adding a comment to taliforth.asm to get make to see the file was updated and changed the boot string in platform\platform-py65mon.asm, but make responds the same. Deleting taliforth-py65mon.bin first then running make results in "*** No rule to make target `taliforth-py65mon.bin', needed by `all'. Stop." Assembling directly with "ophis -c taliforth.c" gives about 20 errors "Undefined or circular dependency for label 'cp'" (also, dp, workword, insrc, cib, ciblen, etc)
Would it be possible to just tell me what python scripts and programs I need to run and in what order to get an updated bin with the code to work on my emulator? Make files have always seemed a bit cryptic to me...
Would it be possible to just tell me what python scripts and programs I need to run and in what order to get an updated bin with the code to work on my emulator? Make files have always seemed a bit cryptic to me...
Re: Compiling TaliForth2 on Windows
It might be that the makefile isn't as it should be, or doesn't match the environment, and I can't help with that, but for reference:
will do all the work which might possibly be needed, as if all sources had recently been touched
will do no work but will tell you the commands it would have run
So, I think,might well give you all the commands you might need, in a useful order.
Quote:
make -B
Quote:
make -n
So, I think,
Quote:
make -B -n
Re: Compiling TaliForth2 on Windows
Druzyek wrote:
Would it be possible to just tell me what python scripts and programs I need to run and in what order to get an updated bin with the code to work on my emulator? Make files have always seemed a bit cryptic to me...
Code: Select all
ophis -l docs/py65mon-listing.txt -m docs/py65mon-labelmap.txt -o taliforth-py65mon.bin -c platform/platform-py65mon.asmYou can probably omit the -l and -m options if you don't need the listing and labelmap. That shortens it down to:
Code: Select all
ophis -o taliforth-py65mon.bin -c platform/platform-py65mon.asmCode: Select all
python3 forth_code/forth_to_ophisbin.py -i forth_code/forth_words.fs > forth_words.asc
python3 forth_code/forth_to_ophisbin.py -i forth_code/user_words.fs > user_words.asc
ophis -l docs/py65mon-listing.txt -m docs/py65mon-labelmap.txt -o taliforth-py65mon.bin -c platform/platform-py65mon.asm ;
python3 tools/generate_wordlist.py > docs/WORDLIST.mdRe: Compiling TaliForth2 on Windows
I can verify that Tali2 does not build on Windows using GnuWin32 make. I usually use cygwin on windows, so that probably broke a while ago and I didn't notice. I've put in an issue ticket on Tali2's github page, and it looks like it's pretty easy to fix so I'll probably do it myself if I have time this weekend. The issue appears to be a semicolon on the end of lines 18 and 24 (just remove it - it's not needed on Linux and just confuses Windows). I also had to change all references of "python3" to "python" as 3.8.1 did not appear to install a "python3.exe".
The above commands should get you going in the meantime. If you don't have a python3.exe executable (it brought up the windows store when I installed 3.8.1 and tried running "python3" on a fresh copy of windows 10), you can change those to just "python" in the above commands.
The above commands should get you going in the meantime. If you don't have a python3.exe executable (it brought up the windows store when I installed 3.8.1 and tried running "python3" on a fresh copy of windows 10), you can change those to just "python" in the above commands.
Re: Compiling TaliForth2 on Windows
Thanks for looking into it. I was able to get it to compile with ophis like you showed above.
Would it be possible to comment out some of the words I don't need and recompile to make the binary smaller? Would I need to edit the word lists too to get that to work? The closest I can get to a rommable version might be a cut down version of the runtime and having my emulator supply bytes from a file every time TaliForth requests a key press. Maybe it would make sense to keep the full version to develop interactively and have a reduced version to switch to that just reads from a file and executes.
In case it's useful, make is 3.81. I tried running make -B and it shows the line "python3 tools/generate_wordlist.py > docs/WORDLIST.md" with error 9009. Typing python gets me a python prompt but python3 opens a browser window to install Python from the Windows store but doesn't print anything to the console.
Would it be possible to comment out some of the words I don't need and recompile to make the binary smaller? Would I need to edit the word lists too to get that to work? The closest I can get to a rommable version might be a cut down version of the runtime and having my emulator supply bytes from a file every time TaliForth requests a key press. Maybe it would make sense to keep the full version to develop interactively and have a reduced version to switch to that just reads from a file and executes.
In case it's useful, make is 3.81. I tried running make -B and it shows the line "python3 tools/generate_wordlist.py > docs/WORDLIST.md" with error 9009. Typing python gets me a python prompt but python3 opens a browser window to install Python from the Windows store but doesn't print anything to the console.
Re: Compiling TaliForth2 on Windows
Druzyek wrote:
Would it be possible to comment out some of the words I don't need and recompile to make the binary smaller? Would I need to edit the word lists too to get that to work? The closest I can get to a rommable version might be a cut down version of the runtime and having my emulator supply bytes from a file every time TaliForth requests a key press. Maybe it would make sense to keep the full version to develop interactively and have a reduced version to switch to that just reads from a file and executes.
To make things smaller, you should be able to remove the assembler, disassembler, and "ed" editor (not to be confused with the "editor" for working with blocks). I'll have to try doing that to see what the instructions are. Those three things live in separate asm files (bought in from the taliforth.asm file), but you will need to remove the headers for all of those words in headers.asm (this is a singly linked list where each "nt" (name token) links to the next word in the list). There are actually four wordlists - a root wordlist, the main forth wordlist, an editor wordlist (for the block editor), and an assembler wordlist.
To remove the assembler, for example, you would comment out the .require "assembler.asm" in taliforth.asm, then go into headers.asm and search for ASSEMBLER-WORDLIST. You should leave the "assembler_dictionary_start:" so it resolves somewhere else in the code, but you don't care what it resolves to as it won't be used anymore. You can then comment out from nt_asm_adc_h: through the end of the file.
You should also remove the forth word that invokes this wordlist (only needed because you've eliminated an entire wordlist. Search for "nt_assembler_wordlist:". You'll actually be editing nt_root_wordlist so it doesn't link to nt_assembler_wordlist anymore. In the "nt_root_wordlist:" header, change the very first item after .word from "nt_assembler_wordlist" to "nt_editor_wordlist".
You should now be able to reassemble without the assembler being installed.
If you want to remove further words, you can pick and choose from the words in native_words.asm and then "unlink" their header entry by making the previous entry skip over them. Then you can comment out their header as well.
I'll give this a try and make sure it works as I explained it, but feel free to give a holler if you get stuck or break something.
Druzyek wrote:
In case it's useful, make is 3.81. I tried running make -B and it shows the line "python3 tools/generate_wordlist.py > docs/WORDLIST.md" with error 9009. Typing python gets me a python prompt but python3 opens a browser window to install Python from the Windows store but doesn't print anything to the console.
I've updated the Makefile and issued a pull request to the Tali2 project, but it might be a bit before scotws can take a look at it. You can snag just the Makefile from https://github.com/SamCoVT/TaliForth2/t ... m/Makefile if you'd like to use make.
Re: Compiling TaliForth2 on Windows
(As of very recently, python2 is no longer maintained, so it's become reasonable for 'python' to mean 'python3' - which is not to say that everything everywhere will still work. We've had a long time to make the adjustment, but many of us haven't.)
Re: Compiling TaliForth2 on Windows
I've made a quick attempt to "smallerize" Tali2 by removing the assembler, disassembler, wordlist support, and the editor "ed". It drops from around 22K to less than 10K in size. I made a branch in my repository if you want to check it out: https://github.com/SamCoVT/TaliForth2/t ... smalltali2
Please note that the binary is still 32K because the platform/platform-py65mon.asm file still has an ".org $8000" at the beginning, and at the end it advances to $fffa to place the reset/interrupt vectors. Also beware that there are a couple of ".advance" directives in the middle of the code (to $e000 for platform_bye: and to $f010 for the IO routines. You can adjust these for wherever you want the code to live.
The expectation is that you will make a new platform-xxxx.asm file in the platform folder for your specific hardware or simulator and put your initialization and I/O routines there. You can take a look at the existing files there for examples.
If you can provide some more details on what you're interested in doing and what hardware/simulator you are working with, I can probably provide more specific help.
Please note that the binary is still 32K because the platform/platform-py65mon.asm file still has an ".org $8000" at the beginning, and at the end it advances to $fffa to place the reset/interrupt vectors. Also beware that there are a couple of ".advance" directives in the middle of the code (to $e000 for platform_bye: and to $f010 for the IO routines. You can adjust these for wherever you want the code to live.
The expectation is that you will make a new platform-xxxx.asm file in the platform folder for your specific hardware or simulator and put your initialization and I/O routines there. You can take a look at the existing files there for examples.
If you can provide some more details on what you're interested in doing and what hardware/simulator you are working with, I can probably provide more specific help.
Re: Compiling TaliForth2 on Windows
Quote:
I've made a quick attempt to "smallerize" Tali2
I'm trying to get it running on my JavaScript emulator in order to port a simple game I made to see how Forth compares to CC65 and writing assembly with macros. The setup is four 16k banks with the lowest one mapped to ram, the middle two normally mapped to screen memory and code in the top 16k. The CC65 version came out to 27k, so some graphics and other stuff are in a second bank which gets copied to RAM at startup before the screen is needed then banked out so the address space can be used for the screen. Hopefully I can devise something similar for Forth.
Re: Compiling TaliForth2 on Windows
Druzyek wrote:
Awesome! Thanks a lot for doing this. I think this will be a big help. Is there a good place in ram or zero page where I can steal a few bytes to keep track of the cursor position?
Quote:
I'm trying to get it running on my JavaScript emulator in order to port a simple game I made to see how Forth compares to CC65 and writing assembly with macros.
Just FYI, you *might* want the assembler (you can easily mix assembly and forth words in Tali2) and remove some of the other words instead. If that ends up being the case, let me know.
Quote:
The setup is four 16k banks with the lowest one mapped to ram, the middle two normally mapped to screen memory and code in the top 16k. The CC65 version came out to 27k, so some graphics and other stuff are in a second bank which gets copied to RAM at startup before the screen is needed then banked out so the address space can be used for the screen. Hopefully I can devise something similar for Forth.
Re: Compiling TaliForth2 on Windows
Great. I got everything working. The character data and drawing code is about 1k. It fits into 16k with your cut down version with about 700 bytes to spare. Is the extra 5k of data in addition to the 9k or so of code word lists and stuff?
The extra code space might be more valuable for this project. Seems like I could cross assemble instead and store the entry points in a table then use Forth to jump into assembly, but I haven't tried yet.
Hopefully the code and graphics data will both fit. Hmm, could I change the dictionary pointer to compile some words to a different 16k bank and run the code from there that doesn't access the screen which uses the same 16k bank? That worked really well in CC65.
Quote:
Just FYI, you *might* want the assembler (you can easily mix assembly and forth words in Tali2) and remove some of the other words instead.
Quote:
16K of RAM should be way more than enough for Forth, as most of the dictionary and starting words live in ROM
Re: Compiling TaliForth2 on Windows
Druzyek wrote:
Great. I got everything working. The character data and drawing code is about 1k. It fits into 16k with your cut down version with about 700 bytes to spare. Is the extra 5k of data in addition to the 9k or so of code word lists and stuff?
Quote:
Seems like I could cross assemble instead and store the entry points in a table then use Forth to jump into assembly, but I haven't tried yet.
Quote:
Quote:
16K of RAM should be way more than enough for Forth, as most of the dictionary and starting words live in ROM
When Tali compiles, it places the header and code together in the dictionary, which grows up from the bottom of RAM. The headers don't have to be with the code, through, and indeed they are not in the words in ROM. I suspect you'd have to rewrite : to make that work, but it's a possibility.
Another possibility would be to use wordlists (might need to put back a few select words that I removed - Tali still has the functionality but not the words to control wordlists). You could create a new wordlist, make it the current wordlist (the one new words will go into), save the current value of CP (the compiler pointer) into a variable that lives in the bottom 16K, map the page you want to use into one of your upper 16K blocks, move CP point into that page, and then start defining new words. Once all of the words you want have been compiled, you can put CP back where it used to live, make the "Forth" wordlist the current wordlist again, and then you just need to make sure you remove the new wordlist out of the search order before you unmap that page (so that Forth doesn't go looking for any headers in that page). You could technically make a new wordlist for every 16K page you wanted to compile new words into.
Are you familiar with CREATE and DOES> in Forth? You could certainly make a new defining word that will do all of this switching around when compiling the words and can also switch things around when running them. I'll have to think on it a while to see if I can see exactly how that would work. Making new defining words is still a bit mind-bending for me.
Re: Compiling TaliForth2 on Windows
The 5K was indeed wordlist headers and strings. If you want to pull my recent commits to the example/smalltali2 branch, I've removed the second editor, the environment? word which used a lot of strings, and all of the block words. It's now about 14K combined code+data.
I also put back just enough wordlist words and tested moving the compiler pointer around - it seems to work. You have "wordlist" which creates a new wordlist and gives you the number (make sure you save this immediately - using the word again will reserve ANOTHER wordlist). I normally put it in a constant like so:
The compiler pointer is in zero page address 0. You can "move" it by just storing into location zero:
I recommend saving the original value of cp (the word "here" puts the current value on the stack) into a variable kept in the unpaged low RAM so that you can put it back when you are done.
Here is my sample run in the simulator.
Once the words have been compiled into memory, you only need to use the "set-order" word to change the search order. Make sure the correct memory page is there before adjusting the search order, and put it back to just the forth-wordlist before changing it to another page. You can check out https://forth-standard.org/standard/search for info on these words. I didn't put back words like get-current and order that let you see what's currently set for values, but you can uncomment them (in native_words.asm and headers.asm) if you want them.
I also put back just enough wordlist words and tested moving the compiler pointer around - it seems to work. You have "wordlist" which creates a new wordlist and gives you the number (make sure you save this immediately - using the word again will reserve ANOTHER wordlist). I normally put it in a constant like so:
Code: Select all
wordlist constant mywordlistCode: Select all
hex 4000 0 ! ( move compiler pointer to $4000 )Here is my sample run in the simulator.
Code: Select all
wordlist constant mywordlist \ Make a new wordlist ok
mywordlist forth-wordlist 2 set-order \ Add the new wordlist to the search order ok
mywordlist set-current \ Make the new wordlist the one words compile into ok
here . 1047 \ See where CP is now. ok
4000 0 ! \ Change it to $4000 ok
here . 4000 \ Check that it changed OK. ok
: new-word ." This word lives higher in memory" ; ok
\ Once you are done defining words:
1047 0 ! \ Put the original CP value back ok
forth-wordlist set-current \ Make the Forth wordlist the compiling wordlist ok
forth-wordlist 1 set-order \ Remove the new wordlist from the search order ok
\ Now it's OK to swap that memory out.
\ The words in that wordlist are "hidden" and will not be
\ searched or used until you put mywordlist back in the search order.Re: Compiling TaliForth2 on Windows
After a lot of fiddling, I got it to work. Thanks for the even smaller version. The extra 1.6k in ROM is VERY useful.
One thing that threw me was that the Undefined word error only shows part of the word. If you enter "bar" for example and it's not defined it shows ">r< Undefined word" instead of >bar<. I thought maybe the pointer to the input buffer was getting scrambled somehow switching between the banks.
ram_end had to be moved from $4000-1 to $C000-1 since otherwise moving the cp to $4000 would give an out of memory error. cp_end is now also $C000-1. hist_buff changed from ram_end-$03ff to $4000-$03ff so it won't point to the banked memory (I recognized the problem when I got lots of colored dots on the screen
) Hmm, how exactly does hist_buff work? Do I need all 8 buffers?
Here's what I have so far. Please let me know what I can improve.
One thing that threw me was that the Undefined word error only shows part of the word. If you enter "bar" for example and it's not defined it shows ">r< Undefined word" instead of >bar<. I thought maybe the pointer to the input buffer was getting scrambled somehow switching between the banks.
ram_end had to be moved from $4000-1 to $C000-1 since otherwise moving the cp to $4000 would give an out of memory error. cp_end is now also $C000-1. hist_buff changed from ram_end-$03ff to $4000-$03ff so it won't point to the banked memory (I recognized the problem when I got lots of colored dots on the screen
Here's what I have so far. Please let me know what I can improve.
Code: Select all
hex
\ Variables stored in zero page
0 constant cp
86 constant bank_mode \ whether bank 2 points to code or screen memory
88 constant cp_save \ copy of normal cp
8A constant cp_banked \ copy of second cp in bank 2
\ Hardware specific
FFE1 constant bank2_register \ 0x4000-0x7FFF
1 constant bank_gen_ram2 \ banked code goes here (bank 2)
4 constant bank_gfx_ram1 \ upper half of screen (bank 2)
: bank2 bank2_register c! ;
wordlist constant mywordlist
: setup 4000 cp_banked ! \ cp for banked code ;
: startup decimal CR CR CR 4000 here - u. hex ." bytes RAM left" ;
: EnableBankROM
bank_mode @ 0= if
mywordlist forth-wordlist 2 set-order
mywordlist set-current
here cp_save !
cp_banked @ cp !
bank_gen_ram2 bank2
1 bank_mode !
then
;
: EnableGfxRAM
bank_mode @ 0<> if
here cp_banked !
cp_save @ cp !
forth-wordlist set-current
forth-wordlist 1 set-order
bank_gfx_ram1 bank2
0 bank_mode !
then
;
setup
startup
: foo ." foo!" ;
foo \ Success
EnableBankROM
: bar ." bar!" ;
foo bar \ Success
EnableGfxRAM
foo bar \ bar not found as expected
EnableBankROM
foo bar \ Success
Re: Compiling TaliForth2 on Windows
I think mod may be wrong. Here is some test output:
It should be this (confirmed in Gforth):
-x/y = -(x/y) but -x mod y != -(x mod y)
Code: Select all
13 5 mod . 3 ok
-13 5 mod . -3 ok
13 -5 mod . 3 ok
-13 -5 mod . -3 okCode: Select all
13 5 mod . 3 ok
-13 5 mod . 2 ok
13 -5 mod . -2 ok
-13 -5 mod . -3 ok