Ok, yes I fiigured that out. I'am in no rush to get two cogs running at this stage, but I will port some of my stuff across to pfth, so that I can give it a real run.
Since I opened the thread by raining on your parade, I have to chip in to say the PASM version has gotten my attention. Now instead of looking like a boat anchor the C background functions look like powerful bootstrap supports for something that is fast and useful once started.
Long way to go from this point, but now I will be watching closely. As a developer I will eventually be needing tools to save and bootstrap an end-user non-development application. I think the C background stuff might be leveraged there. Of course, we also have to get things like SD access and other I/O stuff like keyboard and video accessible to Forth code...
@Ron, I ran into the "+!" bug last night in init.fth, and fixed it there. I'll make sure I fix it in ansi.fth and ansi3.fth before I post the next update.
@localroger, thanks for your comments. A C version of Forth may not make a lot of sense for most applications, but there are a few cases where it does work OK. It runs very slowly on the Prop, but it is quite useable on my PC. The C version can be built with just a small number of words, and you can use ansi3.fth to implement the rest of the words. Or you can build it will all of the C source files to implement more words as kernel words. The full C version uses ansi.fth to fill in the rest of the ANS core words.
I think the one of the most important uses of Forth is bootstrapping a development system on a bare processor that doesn't have existing tools. The PASM version would be a good starting point for other processors. You only need to implement 20 kernel words to get a simple kernel running. As far as supporting SD, keyboard and displays I plan on using the PASM portion of exisiting objects in the OBEX, and replacing the Spin portion with Forth.
It's possible that the compiled code is overwritting the source code. Try increasing the size of the padding space from 1000 longs to something larger. You do need to leave a few bytes free at the end of memory because I use this for temporary strings. 256 free bytes at the end will be more than enough.
EDIT: My previous comment is only relevant to PASM pfth. With the C version it's possible that mywords.fth is using a word that is not defined in ansi3.fth. Try "pfth ansi.fth mywords.fth" to see if it detects an undefined word.
pfth ansi.fth mywords.fth Reports error on hex val encounted. 0b? 0a? etc >>>>>>>>Solution set to "hex" at top of file. (I only use hex)
pfth ansi3.fth mywords.fth Hangs, but works OK if hex is set at top of myfwords.fth . Not sure whats going on at this stage. I need to load a bigger file with ansi3.fth
I have not checked it out with PASM pfth, I like it, there are lots of possiblities
The whole base thing in Forth generates some interesting problems. It's not straightforward to know what base you are in. A "base @ ." always prints "10" no matter what the base is. I usually do something like "base @ 2 / ." to see what the base is. A "5" implies base 10 and an "8" means it is in base 16. C pfth starts out in decimal. Both ansi.fth and ansi3.fth save the current base, change it to decimal, and then restore the base at the end. ansi3.fth uses 1's and 0's to set the base since the DECIMAL word isn't defined at the beginning, and the starting base could be binary.
ansi3.fth uses the d2a and a2d to convert a digit-to-ascii and ascii-to-digit. d2a will generate the ascii characters "0123456789abc...z". However, it looks like a2d only handles the decimal digits 0 through 9. You could copy the a2d word from init.fth. It will handle the characters "0123456789abc...z". I renamed this word to _a2d in init.fth because I realized that "a2d" is a valid hex number. I'll fix this in ansi3.fth in the next update, which should be coming out soon. I'll probably add support for the uppercase characters A through Z as well. It just that all the if-else-then words look very awkward in Forth.
BTW, PASM pfth does start out in hex because the number conversions are easier to do than in decimal. However, init.fth ends up in decimal when done.
I ran C pfth with ansi3.fth, and then switched to hex, and I didn't see a problem. It was able to convert hex numbers with both upper and lower case letters. The interpreter uses a C routine to do the conversion. a2d is only used by the >number word defined in ansi3.fth. I've mostly been working with PASM pfth lately, so I was thinking about the way it handles numbers versus C pfth.
Ron, why do you need to use ansi3.fth. ansi.fth should work fine, and use less hub memory, and be faster. Are you building pfth with only pfth.c and basicwords.c?
Why ansi3 ? Like Everest, it's there, so for what ever reason, some will want to climb it.
I built forth on this occasion using install.bat (ppusb) . I think most will use this, if they want to try pfth.
Hangs here, but I thinks its a word in mywords.fth " : digits dup 9 > if 0a /mod 30 + emit then 30 + emit ; "
It should be unsigned mod.
Also "digits" does not test for " f > " , but I can't see that this would affect the dictionary build.
H Dave,
Not sure how far along you are in to committing to a multi-cog solution, but if and when you write a serial interface to support more cogs, I would like to suggest a solution.
PropForth as a 1 cog to 1 serial port solution. I suspect that Tachyon did the same and can get its absurdly fast baud rate because it does do.
I suggest that your serial driver have multiple serial port ability - something like 4 serial i/o that are managed by one cog. This would be less wasteful. It may sacrifice all out speed, but more cogs would remain available to other things.
I am all for optimal utility, not extreme performance and limited utility. Of course, 8 serial ports on one cog would be even better, but I am not greedy.
@Ron, the DIGITS word looks fine to me. I don't see how that would cause a problem. You may want to add a "Type(inputptr, inputlen);" debug print to the Include routine in pfth.c. This way you can see which line causes it to hang. Or if you want to post myword.fth I can take a look at it.
@Loopy, my plan for device drivers is to port some of the Spin/PASM objects from the OBEX. I've never used the 4-port serial driver, but I can take a look at it. I need to implement the cogx word, which will allow me to execute any Prop instruction.
Whats more myword.fth works
I fixed the known problem with +! in init.fth and increased the 1000 long buffer to 1100 so that I could get mywords.fth to load.
Ron, I added the debug print to pfth.c and the program hangs when it executes "variable edbuf 50 allot". The problem is that pfth is out of memory. When pfth first starts up, an "unused ." command will show that it has 9364 bytes unused. After loading ansi3.fth it only has 192 bytes left. In test1.fth I do a "forget forget" before loading ansi3.fth. I grouped the dictionary so that all the words before "forget" make up a basic set of words. ansi3.fth implements the words that "forget forget" removes in addition to the ANS core words. I was able to get mywords.fth to load with the following commands.
pfth
forget forget
include ansi3.fth
include mywords.fth
An "unused ." command shows that there are 4E0 (or 1248 decimal) bytes left.
@Loopy, my plan for device drivers is to port some of the Spin/PASM objects from the OBEX. I've never used the 4-port serial driver, but I can take a look at it. I need to implement the cogx word, which will allow me to execute any Prop instruction.
Well, I was actually thinking the 4x serial would boot up the Forth console at startup and then leave 3 remaining channels to be available. That may be all the RS232 serial a user would ever need.
Ok Dave,
I'm with you.
Now I have ANS up on the PASMr version I can add the FAT16 SDcard assembler code from the OBEX and run it in another cog.
Then I just have to write a few forth words to talk to SDcard..
Can you see any problems ? Ttere' s pleny of room
Ron
@Loopy, that sounds like a good idea. I hope to look into it at some point.
@Ron, that's the approach that I'm planning on with SD. Once the PASM SD driver is loaded it pretty much comes down to communicating to it through a mailbox. Most of the complexity is handled by the PASM driver, and all the Forth code has to do is read and write 512-byte sectors.
Here's a new version of pfth. This version includes the fixes that have been discussed since the last update. It also includes the following new features.
- I replaced misc.fth with comus.fth. comus is a set of commonly used Forth words that aren't included in ANS Forth. See Leo Wong's webpage on comus Forth.
- I added an LMM word that allows defining words consisting of LMM PASM instructions. This feature still needs a bit of work.
- I added propwords.fth that defines the Prop-specific words. This file includes cognew and cogstop, which are implemented using LMM.
- I added a "verbose" flag to disable prints during boot-up.
- Added version.fth that turns on the verbose flag and prints a version message. This file should be include in pfth.spin after init.fth and propwords.fth
- I ported some of the methods and the cog code from the FullDuplexSerial object. This is currently included in pfth.spin. Run the TEST word to try it.
This will probably be the last release that includes the C version of pfth. The PASM version is much faster and provides more space for user code. I'm hoping to add SD support in the next version of PASM pfth.
David
Re the SD driver.I think the way I may do it, is to take the basic words from init.fth that I need to in a new sdboot.fth. The sdboot.fth wil build a few dictionay words to access the sdcard files. Then from the .fth files, build the rest of the dictionary.
Providing that a forth word does not span across a SD block, then much of the dictionary build could be done from SD card.
Only a small amount of padding will be required.(enough to handle sdboot.fth only ) The sdfiles.fth can be loaded block by block and only when the dictionary build from the current sdblock is completed will the next block be loaded at "here" + padding of 128 longs. The only file to form part of the Forth Pasm code will be sdboot.fth which will replace init.fth.
Downloaded the lastest version will look later.
Now we have a full sdcard file system I will finish my Text Editor under ANS forth. A Stand Alone Forth system for the Prop on ppusb is now a real probability..
I'm currently working on porting the basic_i2c_driver in the OBEX from Spin to Forth. I have the ReadPage function working, and I'm working on WritePage and other routines. I encountered problems with the R@ and INVERT words, and I also noticed that 2>R, 2R> and 2R@ are not correct. I've attached a new version of init.fth that fixes these words. I had to rename the file to init.txt so I could attach it, so you will need to change it back to init.fth to use it.
I'm currently working on porting the basic_i2c_driver in the OBEX from Spin to Forth. I have the ReadPage function working, and I'm working on WritePage and other routines. I encountered problems with the R@ and INVERT words, and I also noticed that 2>R, 2R> and 2R@ are not correct. I've attached a new version of init.fth that fixes these words. I had to rename the file to init.txt so I could attach it, so you will need to change it back to init.fth to use it.
@David
I spent yesterday going through "propwords". I need to start another forth cog, so I would have to include a second cog in the pfth pasm.spin (returning the cog ID). I am assuming that the second pfth.spin will not require the the files at infileptr other than the mandatory 0. Only then can i start the second cog from the primary forth cog, In other words the primary kernel and any secondary kernels will be different.
Is that correct or am I missing something ?
Example of my test code.
I am away from home ATM for the next couple of months so I can't even solder a led on to my prop board so test_cog will have to do.
Example dictionary words to test the theory.
: wait clkfreq@ swap / cnt@ + waitcnt ;
: test begin 1 col +! 4 wait 0 until ; \ counts forever
Now from the current pasm cog with modified bg_pasm cog
: test_cog ' test (cogid ) coginit \ start background cog
begin 8 wait col @ . space 0 until ; \ output col to console
My test works Ok. I added the test word to the only file in the bgground cog
col increments in background and can display it in the current console.
Now I can move on to the next gig. BTW why the LMM word?
All of a sudden I will realise I need it!
Ron, it's good to see you got a background forth cog running. The approach you took by having a separate cog image for the background cog sounds good. My plan is to patch the boot cog image after startup so it can be used for additional forth cogs -- I just haven't gotten around to it yet. Can you post your code here or in a PM so I can look at it?
The LMM word is a way to implement Prop-specific words without using up cog memory. I was also thinking that some words could be implemented more efficiently in LMM routines than in Forth. I may go back to my original of plan for implementing rarely used Prop-specific words by a word that gets the source, destination and instruction values from the stack and returns a result on the stack.
I'll look at the SPI code once I get the I2C code done. I'm planning on porting the low-level Spin routines from FSRW to get started. Once I can read and write SD sectors I'll implement some of the ANS Forth BLOCK and FILE words.
David
I did not produce code as such. I created an object from a cog image,
I was unable to replicate it after I came back to late yesterday. : It was not a good solution anyway.
I can't see how this can be done unless all cogs are pre loaded with the kernel at compile time. Then other cogs can then be started or stopped from forth, with coginit, cogstop
Maybe the kernel needs a hook to pass a param from coginit to change the infileptr so that it then looks for a "coms.fth",, or some such file which the user can change.to run a background routine (AKA SDdriver)
You could use par reg ( coginit param) and add it to infileptr so that you can access different files.fth for each coginit in pasm forth. If par is not 0 then i/o is turned off. There will have to be another way from forth to switch the cog i/o but that is not going too be difficult.
Compiling Forth code from different cogs gets a little complicated. A lock is needed so that only one cog is updating the dictionary at a time. Each cog also needs it's own copy of the data and return stacks. What I am thinking of doing for now is to only allow the first cog to access the console/files and to compile code. I can allow multiple cogs to print to the output, put they need to use a lock so they don't step on each other.
So my plan is to pass a pointer in the PAR register when starting up a Forth cog that points to a word that is executed, and also points to data and return stacks. The word that a new cog executes will normally loop forever, or it may run a short piece of code an then stop itself.
Comments
Long way to go from this point, but now I will be watching closely. As a developer I will eventually be needing tools to save and bootstrap an end-user non-development application. I think the C background stuff might be leveraged there. Of course, we also have to get things like SD access and other I/O stuff like keyboard and video accessible to Forth code...
RE ansi3.fth word +! I think you will find it should be
: +! dup @ rot + swap !
Ron
@localroger, thanks for your comments. A C version of Forth may not make a lot of sense for most applications, but there are a few cases where it does work OK. It runs very slowly on the Prop, but it is quite useable on my PC. The C version can be built with just a small number of words, and you can use ansi3.fth to implement the rest of the words. Or you can build it will all of the C source files to implement more words as kernel words. The full C version uses ansi.fth to fill in the rest of the ANS core words.
I think the one of the most important uses of Forth is bootstrapping a development system on a bare processor that doesn't have existing tools. The PASM version would be a good starting point for other processors. You only need to implement 20 kernel words to get a simple kernel running. As far as supporting SD, keyboard and displays I plan on using the PASM portion of exisiting objects in the OBEX, and replacing the Spin portion with Forth.
I wanted to load mywords.fth (words that I use frequently, a small file.)
pfth ansi3.fth mywords.fth from the shell.
I wonder if the dictionary build overuns the hub text, because it hangs ??
That' s a guess one my part, based of what I know about the pfth.spin file.
EDIT: My previous comment is only relevant to PASM pfth. With the C version it's possible that mywords.fth is using a word that is not defined in ansi3.fth. Try "pfth ansi.fth mywords.fth" to see if it detects an undefined word.
pfth ansi3.fth mywords.fth Hangs, but works OK if hex is set at top of myfwords.fth . Not sure whats going on at this stage. I need to load a bigger file with ansi3.fth
I have not checked it out with PASM pfth, I like it, there are lots of possiblities
.
.
ansi3.fth uses the d2a and a2d to convert a digit-to-ascii and ascii-to-digit. d2a will generate the ascii characters "0123456789abc...z". However, it looks like a2d only handles the decimal digits 0 through 9. You could copy the a2d word from init.fth. It will handle the characters "0123456789abc...z". I renamed this word to _a2d in init.fth because I realized that "a2d" is a valid hex number. I'll fix this in ansi3.fth in the next update, which should be coming out soon. I'll probably add support for the uppercase characters A through Z as well. It just that all the if-else-then words look very awkward in Forth.
BTW, PASM pfth does start out in hex because the number conversions are easier to do than in decimal. However, init.fth ends up in decimal when done.
Ron, why do you need to use ansi3.fth. ansi.fth should work fine, and use less hub memory, and be faster. Are you building pfth with only pfth.c and basicwords.c?
I built forth on this occasion using install.bat (ppusb) . I think most will use this, if they want to try pfth.
Hangs here, but I thinks its a word in mywords.fth " : digits dup 9 > if 0a /mod 30 + emit then 30 + emit ; "
It should be unsigned mod.
Also "digits" does not test for " f > " , but I can't see that this would affect the dictionary build.
Not sure how far along you are in to committing to a multi-cog solution, but if and when you write a serial interface to support more cogs, I would like to suggest a solution.
PropForth as a 1 cog to 1 serial port solution. I suspect that Tachyon did the same and can get its absurdly fast baud rate because it does do.
I suggest that your serial driver have multiple serial port ability - something like 4 serial i/o that are managed by one cog. This would be less wasteful. It may sacrifice all out speed, but more cogs would remain available to other things.
I am all for optimal utility, not extreme performance and limited utility. Of course, 8 serial ports on one cog would be even better, but I am not greedy.
http://obex.parallax.com/objects/340/
@Loopy, my plan for device drivers is to port some of the Spin/PASM objects from the OBEX. I've never used the 4-port serial driver, but I can take a look at it. I need to implement the cogx word, which will allow me to execute any Prop instruction.
Thers nothing to it. don't understand either.
BTW got ansi.fth up and running in pasm version.....................It flies
Ron
I fixed the known problem with +! in init.fth and increased the 1000 long buffer to 1100 so that I could get mywords.fth to load.
Ron
pfth
forget forget
include ansi3.fth
include mywords.fth
An "unused ." command shows that there are 4E0 (or 1248 decimal) bytes left.
Well, I was actually thinking the 4x serial would boot up the Forth console at startup and then leave 3 remaining channels to be available. That may be all the RS232 serial a user would ever need.
I'm with you.
Now I have ANS up on the PASMr version I can add the FAT16 SDcard assembler code from the OBEX and run it in another cog.
Then I just have to write a few forth words to talk to SDcard..
Can you see any problems ? Ttere' s pleny of room
Ron
@Ron, that's the approach that I'm planning on with SD. Once the PASM SD driver is loaded it pretty much comes down to communicating to it through a mailbox. Most of the complexity is handled by the PASM driver, and all the Forth code has to do is read and write 512-byte sectors.
Thanks Dave
- I replaced misc.fth with comus.fth. comus is a set of commonly used Forth words that aren't included in ANS Forth. See Leo Wong's webpage on comus Forth.
- I added an LMM word that allows defining words consisting of LMM PASM instructions. This feature still needs a bit of work.
- I added propwords.fth that defines the Prop-specific words. This file includes cognew and cogstop, which are implemented using LMM.
- I added a "verbose" flag to disable prints during boot-up.
- Added version.fth that turns on the verbose flag and prints a version message. This file should be include in pfth.spin after init.fth and propwords.fth
- I ported some of the methods and the cog code from the FullDuplexSerial object. This is currently included in pfth.spin. Run the TEST word to try it.
This will probably be the last release that includes the C version of pfth. The PASM version is much faster and provides more space for user code. I'm hoping to add SD support in the next version of PASM pfth.
Re the SD driver.I think the way I may do it, is to take the basic words from init.fth that I need to in a new sdboot.fth. The sdboot.fth wil build a few dictionay words to access the sdcard files. Then from the .fth files, build the rest of the dictionary.
Providing that a forth word does not span across a SD block, then much of the dictionary build could be done from SD card.
Only a small amount of padding will be required.(enough to handle sdboot.fth only ) The sdfiles.fth can be loaded block by block and only when the dictionary build from the current sdblock is completed will the next block be loaded at "here" + padding of 128 longs. The only file to form part of the Forth Pasm code will be sdboot.fth which will replace init.fth.
Downloaded the lastest version will look later.
Now we have a full sdcard file system I will finish my Text Editor under ANS forth. A Stand Alone Forth system for the Prop on ppusb is now a real probability..
Cheers...
Should be" when we have a full sdcard system "
@David
I spent yesterday going through "propwords". I need to start another forth cog, so I would have to include a second cog in the pfth pasm.spin (returning the cog ID). I am assuming that the second pfth.spin will not require the the files at infileptr other than the mandatory 0. Only then can i start the second cog from the primary forth cog, In other words the primary kernel and any secondary kernels will be different.
Is that correct or am I missing something ?
Example of my test code.
I am away from home ATM for the next couple of months so I can't even solder a led on to my prop board so test_cog will have to do.
Example dictionary words to test the theory.
: wait clkfreq@ swap / cnt@ + waitcnt ;
: test begin 1 col +! 4 wait 0 until ; \ counts forever
Now from the current pasm cog with modified bg_pasm cog
: test_cog ' test (cogid ) coginit \ start background cog
begin 8 wait col @ . space 0 until ; \ output col to console
At this point I will wait to see your SPI code.
col increments in background and can display it in the current console.
Now I can move on to the next gig. BTW why the LMM word?
All of a sudden I will realise I need it!
I feel a bit like Loopy
.
The LMM word is a way to implement Prop-specific words without using up cog memory. I was also thinking that some words could be implemented more efficiently in LMM routines than in Forth. I may go back to my original of plan for implementing rarely used Prop-specific words by a word that gets the source, destination and instruction values from the stack and returns a result on the stack.
I'll look at the SPI code once I get the I2C code done. I'm planning on porting the low-level Spin routines from FSRW to get started. Once I can read and write SD sectors I'll implement some of the ANS Forth BLOCK and FILE words.
I did not produce code as such. I created an object from a cog image,
I was unable to replicate it after I came back to late yesterday. : It was not a good solution anyway.
I can't see how this can be done unless all cogs are pre loaded with the kernel at compile time. Then other cogs can then be started or stopped from forth, with coginit, cogstop
Maybe the kernel needs a hook to pass a param from coginit to change the infileptr so that it then looks for a "coms.fth",, or some such file which the user can change.to run a background routine (AKA SDdriver)
Just my 2cents worth.
This should fix
if coginit.param = 0 leave I/O on infileptr long @infiles + 16 >>>> , 0
if coginit.param <> 0 turn off I/O infileptr long @cogidfiles + 16 >>>>.,0
init all cogs in pasm.spin.
So my plan is to pass a pointer in the PAR register when starting up a Forth cog that points to a word that is executed, and also points to data and return stacks. The word that a new cog executes will normally loop forever, or it may run a short piece of code an then stop itself.