Added back the stack underflow detection. It got lost when I updated the code from AVRASM2 to XC8 compiler.
ATMEGA: Add stack underflow check
PIC18: BLOCK EDIT CORE
Had to revert INTERPRET and re-introduce ABORT for unknown words. It did not work like I was thinking with blocks. Also blocks24.fs was updated to work. There is a new word EXECUTE? to prevent potentially unknown words from aborting the evaluation of a block. execute? -mark marker -mark
PIC24: Revert to use ABORT in INTERPRET. Fixed BLOCK words
PIC18: put back ABORT for unkown words
PIC18: BLOCK EDIT
PIC18: Remove DO LOOP
PIC18:Remove P from PAUSE
PIC18: move words to root vocabulary
PIC18: Remove flow control and cpuload
PIC18: Remove flow control and cpuload
PIC18: FORGET HUH? assembler
PIC18: MARKER TINIT
PIC18: H.N, tasks MARKER
PIC18: Dot words, remove P words
PIC18: first 'working' version
PIC18: Abandon buggy xtended instruction set
PIC24: H.N SPACES
PIC18: ff-pic18.S
PIC18: rename ff-pic18.S
PIC18: rename directory
PIC18: updates
PIC24: forth files
PIC24: config files
Did some updates to the PIC24 part. - Less writes to flash on chips that do not have eeprom (almost all chips). A smarter algorithm compares the highest written flash address with the xt to be executed. - DOES> fixed to work also with an empty DOES> part. - Unknown words do not cause INTERPRET to ABORT. This allows that unknown (marker words) words do not abort the loading from blocks or from Pere's file system. This was needed to let MARKER words to be used in those scenarios. - 64 by 64-bit unsigned...
PIC24:Less flash writes,UQ/,fix DOES>
PIC24: improved flash write algorithm
PIC24: PIC24F32KA302
PIC24: PIC24F32KA302
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
PIC24: dsPIC33FJ128GP802 alpha
FF6: PIC24 initial
thanks for the information. but yes, i'm using scamp words. but because i'm using the FSM with vocabularies, really is not necessary use the marker option. I keep the specific words in different vocabularies.and i load them only when necessary.
I actually found a simple solution to change INTERPRET to continue interpreting when a error is encountered. Not much tested, but it works with my block system. So now when a -marker word is encountered, interpret will continue with the next word. You can try and patch your FF with this, unless of course you are using Scamp words. IUNKNOWN: ; a f dec2 W14, W14 rcall CFETCHPP rcall TYPE rcall XSQUOTE .byte 2 .byte '\?',NAK_ .align 2 rcall TYPE ; rcall FALSE_ ; rcall QABORTQ bra INTER1 INTER6:
I quess the only solution for now is to use -marker from the command line and then load the file(s).
Yes. That's a problem with EVALUATE. A proper solution would be to implement CATCH/THROW in FF, so that EVALUATE could catch the error and continue. With a simple ABORT that is not possible.
when i have: -test marker -test ram create buf 20 allot ram create buf2 20 allot test2 buf c@+ evaluate buf2 c@+ evaluate ; s" : test 1 2" buf place s" + . ;" buf2 place test2 test 3 in a text file and I make copy and paste to the forth terminal, this works fine. but if I put this in a buffer and then I make evaluate, the system don't recognizes the -test word and give me aan error message and the evaluate stops. then i can not save files starting with -name marker -name. is there any way to solve...
I've finally managed to read an entire 4K text from external storage without worrying about truncated definitions or being stuck mid-word at the end of a 256-byte page of Scamp3e. I parse to the next CR (even if it's on the next page), save it in a 64-byte buffer, and then evaluate. It works perfectly even when a definition is evaluated in several parts, as you mentioned in your answer.
last : why buf c@+ evaluate buf2 c@+ evaluate doesn't work? and : test2 buf c@+ evaluate buf2 c@+ evaluate ; works.? It does not work because after the first evaluate the system is in compilation state so interpret will try to compile the phrase " buf2 c@+ evaluate" instead of executing it. The word test2 only executes so there is no dependence on state.
last : why buf c@+ evaluate buf2 c@+ evaluate doesn't work? and : test2 buf c@+ evaluate buf2 c@+ evaluate ; works.? It does not work because after the first evaluate the system is in compilation state so interpret will try to compile the phrase " buf2 c@+ evaluate" instead of interpreting it. The word test2 only executes so there is no dependence on state.
Using evaluate like this does not work. ram create buf 20 allot ram create buf2 20 allot s" : test 1 2" buf place s" + . ;" buf2 place buf c@+ evaluate buf2 c@+ evaluate
This works for me ram create buf 20 allot ram create buf2 20 allot : test2 buf c@+ evaluate buf2 c@+ evaluate ; s" : test 1 2" buf place s" + . ;" buf2 place test2 test 3
last : why buf c@+ evaluate buf2 c@+ evaluate doesn't work? and : test2 buf c@+ evaluate buf2 c@+ evaluate ; works.? It does not work because after the first evaluate the system is in compilation state so interpret will try to compile the phrase " buf2 c@+ evaluate" instead of interpreting it.
it works well. Good idea for some quick test.
Added words to temporarily compile code and execute it. Handy for timing tests or for compile-only words. Look in ARCH/forth/compile-execute.fs. [[ 10 for r@ . next ]] 9 8 7 6 5 4 3 2 1 0 ok<$,ram>
ALL: [[ ]]
thank you for the information. my idea was to have two buffer, a buffer 256 bytes and then a buffer of 64 bytes and a handle system. but now i'm thinking to have only one of 64 bytes and fill it reading the text until cr, evaluate and do the same until the end of file. i will check and try this idea and I will inform you. last : why buf c@+ evaluate buf2 c@+ evaluate doesn't work? and : test2 buf c@+ evaluate buf2 c@+ evaluate ; works.?
thank you for the information. my idea was to have two buffer, a buffer 256 bytes and then a buffer of 64 bytes and a handle system. but now i'm thinking to have only one of 64 bytes and fill it reading the text until cr, evaluate and do the same until the end of file. i will check and try this idea and I will inform you.
thank you for the information. my idea was to have two buffer, a buffer 256 bytes and then a buffer of 64 bytes and a handle system. but now i'm thinking to have only one of 64 bytes and fill it reading the text until cr, evaluate and do the same until the end of file. i will check and try this idea and I inform you.
When I was writing the block words I found that FF should be restructured to accept input from a large buffer using REFILL. But I never did that restructuring. Anyway it is easiest to have a line buffer that can accept a whole line, and evaluate one line at a time. If you take in only part of a line you may cut off some words in the middle which again a more difficult thing to handle. So LOAD has the restriction that one line is always 64 bytes and a word is not allowed to be split across a 64 byte...
When I was writing the block words I found that FF should be restructured to accept input from a large buffer using REFILL. But I never did that restructuring. Anyway it is easiest to have a line buffer that can accept a whole line, and evaluate one line at a time. If you take in only part of a line you may cut of some words in the middle which again a more difficult thing to handle. So LOAD has the restriction that one line is always 64 bytes and a word is not allowed to be split across a 64 byte...
what i really need: with loops and more accurate 1 ram create buf 20 allot 2 : test buf 20 evaluate ; 3 s" test3 1 2" buf swap cmove 4 test 5 buffer 20 erase 6 s" + . ;" buf swap cmove 7 test test3---->3 if this possible? my goal is evaluate a complet file of 4 K with a buffer of 256 bytes.
what i really need: with loops and more accurate ram create buf 20 allot test buf 20 evaluate ; s" test3 1 2" buf swap cmove test buffer 20 erase s" + . ;" buf swap cmove test test3---->3 if this possible? my goal is evaluate a complet file of 4 K with a buffer of 256 bytes.
what i really need: with loops and more accurate ram create buf 20 allot test buf 20 evaluate ; s" test3 1 2" buf swap cmove test buffer 20 erase s" + . ;" buf 8 + swap cmove test test3---->3 if this possible? my goal is evaluate a complet file of 4 K with a buffer of 256 bytes.
what i really need: with loops and more accurate ram create buf 20 allot test buf c@+ evaluate ; s" test3 1 2" buf swap cmove test buffer 20 erase s" + . ;" buf 8 + swap cmove test test3---->3 if this possible? my goal is evaluate a complet file of 4 K with a buffer of 256 bytes.
Using evaluate like this does not work. ram create buf 20 allot ram create buf2 20 allot s" test 1 2" buf place s" + . ;" buf2 place buf c@+ evaluate buf2 c@+ evaluate
Having CR LF inside the buffer also works. All control bytes ( <32) are interpreted as white space.
This works for me ram create buf 20 allot ram create buf2 20 allot : test2 buf c@+ evaluate buf2 c@+ evaluate ; s" test 1 2" buf place s" + . ;" buf2 place test2 test 3
Hello Mikael is there a way to use interpret in a buffer? i mean, i have a buffer with some forth words, and some definitions. if i need several buffers to interpret, i cannot use evaluate, because some of them finish in the midle of a definition, ande aluate doesnt work. but maybe if i change the source and use interpret i can use it and following reading the newbuffer until the end... exMple: create buffer 10 allot buffer ------> ( : test 1 cr 1 + . ; )definition in two lines. twice the buffer...
Hello Mikael is there a way to use interpret in a buffer? i mean, i have a buffer with some forth words, and some definitions. if i need several buffers to interpret, i cannot use evaluate, because some of them finish in the midle of a definition, ande aluate doesnt work. but maybe if i change the source and use interpret i can use it and following reading the newbuffer until the end... exMple: create buffer 10 allot buffer ------> ( : test 1 cr 1 + . ; )definition in two lines. buffer evaluate doesnt...
Hello Mikael is there a way to use interpret in a buffer? i mean, i have a buffer with some forth words, and some definitions. if i need several buffers to interpret, i cannot use evaluate, because some of them finish in the midle of a definition, ande aluate doesnt work. but maybe if i change the source and use interpret i can use it and following reasing the newbuffer until the end... exMple: create buffer 10 allot buffer ------> ( : test 1 cr 1 + . ; )definition in two lines. buffer evaluate doesnt...
WHAT ?
Well we'll wait and see :-) Thank you Mikael. You do a great job with FF!
Yes, no P register is FF6, but I don't know if it will ever go further than alpha state.
OK Mikael. Thank you for your explanation. Does your remark about FF6 mean that there will be no P register and associated words available for all of us?
OK Mikael. Thank you for your explanation. Your does your remark about FF6 mean that there will be no P register and associated words available for all of us?
The advantage comes from the associated words, and by having a kind of consistency. Advantages compared to a variable is that the P register is multitasking safe and also re-entrant, and the associated words are more efficient than if you define them yourself. Myself I have had very little use of those P words, so in FF6 I removed them. They are mostly cute and an attempt to mimic pointers in C.
What is the advantage of using the P register instead of using a variable I can define myself? Is it because of the P register associated words or are there other advantages?
I always thought that when there were two nested loops, the index value of each loop had to be requested using I and J. But in the last example, I see that I can get the value of each index (inner and outer) using only index I, without needing to use J. I suppose they should only be used if both indices are requested within the same loop. sorry for a lot of questions, but i'm beginner forth user....
Your code does not match the result in FF. Maybe in gforth ? This is correct. What do you think it was supposed to do ? : tt 10 for i . 10 for i . next cr next ; ok tt 9 9 8 7 6 5 4 3 2 1 0 8 9 8 7 6 5 4 3 2 1 0 7 9 8 7 6 5 4 3 2 1 0 6 9 8 7 6 5 4 3 2 1 0 5 9 8 7 6 5 4 3 2 1 0 4 9 8 7 6 5 4 3 2 1 0 3 9 8 7 6 5 4 3 2 1 0 2 9 8 7 6 5 4 3 2 1 0 1 9 8 7 6 5 4 3 2 1 0 0 9 8 7 6 5 4 3 2 1 0 ok
Your code does not match the result. This is correct. What do you think it was supposed to do ? : tt 10 for i . 10 for i . next cr next ; ok tt 9 9 8 7 6 5 4 3 2 1 0 8 9 8 7 6 5 4 3 2 1 0 7 9 8 7 6 5 4 3 2 1 0 6 9 8 7 6 5 4 3 2 1 0 5 9 8 7 6 5 4 3 2 1 0 4 9 8 7 6 5 4 3 2 1 0 3 9 8 7 6 5 4 3 2 1 0 2 9 8 7 6 5 4 3 2 1 0 1 9 8 7 6 5 4 3 2 1 0 0 9 8 7 6 5 4 3 2 1 0 ok
You need J when you in the inner loop want to use the index of the outer loop. : test3 10 0 do 10 0 do ." i" ii . ." j" j . loop cr loop ; ok test3 i0 j0 i1 j0 i2 j0 i3 j0 i4 j0 i5 j0 i6 j0 i7 j0 i8 j0 i9 j0 i0 j1 i1 j1 i2 j1 i3 j1 i4 j1 i5 j1 i6 j1 i7 j1 i8 j1 i9 j1 i0 j2 i1 j2 i2 j2 i3 j2 i4 j2 i5 j2 i6 j2 i7 j2 i8 j2 i9 j2 i0 j3 i1 j3 i2 j3 i3 j3 i4 j3 i5 j3 i6 j3 i7 j3 i8 j3 i9 j3 i0 j4 i1 j4 i2 j4 i3 j4 i4 j4 i5 j4 i6 j4 i7 j4 i8 j4 i9 j4 i0 j5 i1 j5 i2 j5 i3 j5 i4 j5 i5 j5 i6 j5 i7 j5 i8 j5...
also : tt 10 for i . 10 for i . next cr next ; ok tt 10 10 9 8 7 6 5 4 3 2 1 0 9 10 9 8 7 6 5 4 3 2 1 0 8 10 9 8 7 6 5 4 3 2 1 0 7 10 9 8 7 6 5 4 3 2 1 0 6 10 9 8 7 6 5 4 3 2 1 0 5 10 9 8 7 6 5 4 3 2 1 0 4 10 9 8 7 6 5 4 3 2 1 0 3 10 9 8 7 6 5 4 3 2 1 0 2 10 9 8 7 6 5 4 3 2 1 0 1 10 9 8 7 6 5 4 3 2 1 0 0 10 9 8 7 6 5 4 3 2 1 0 ok
yes but normally in nested loop i used: qq 10 0 do Jx . 10 0 do I x . loop cr loop ; that is working well but if i make ww 10 0 do Ix . 10 0 do Ix . loop cr loop ; also it works... then why you need Jx? qq 10 0 do i . 10 0 do i . loop cr loop ; \ tested on my ipad swiftforth \ but also checked in my scamp ok qq 0 0 1 2 3 4 5 6 7 8 9 1 0 1 2 3 4 5 6 7 8 9 2 0 1 2 3 4 5 6 7 8 9 3 0 1 2 3 4 5 6 7 8 9 4 0 1 2 3 4 5 6 7 8 9 5 0 1 2 3 4 5 6 7 8 9 6 0 1 2 3 4 5 6 7 8 9 7 0 1 2 3 4 5 6 7 8 9 8 0 1 2 3 4...
yes but normally in nested loop i used: qq 10 0 do Jx . 10 0 do I x . loop cr loop ; that is working well but if i make ww 10 0 do Ix . 10 0 do Ix . loop cr loop ; also it works... then why you need Jx? qq 10 0 do i . 10 0 do i . loop cr loop ; \ tested on my ipad swiftforth \ but also checked in my scamp ok qq 0 0 1 2 3 4 5 6 7 8 9 1 0 1 2 3 4 5 6 7 8 9 2 0 1 2 3 4 5 6 7 8 9 3 0 1 2 3 4 5 6 7 8 9 4 0 1 2 3 4 5 6 7 8 9 5 0 1 2 3 4 5 6 7 8 9 6 0 1 2 3 4 5 6 7 8 9 7 0 1 2 3 4 5 6 7 8 9 8 0 1 2 3 4...
yes but normally in nested loop i used: qq 10 0 do Jx . 10 0 do I x . loop cr loop ; that is working well but if i make ww 10 0 do Ix . 10 0 do Ix . loop cr loop ; also it works... then why you need Jx? qq 10 0 do i . 10 0 do i . loop cr loop ; ok qq 0 0 1 2 3 4 5 6 7 8 9 1 0 1 2 3 4 5 6 7 8 9 2 0 1 2 3 4 5 6 7 8 9 3 0 1 2 3 4 5 6 7 8 9 4 0 1 2 3 4 5 6 7 8 9 5 0 1 2 3 4 5 6 7 8 9 6 0 1 2 3 4 5 6 7 8 9 7 0 1 2 3 4 5 6 7 8 9 8 0 1 2 3 4 5 6 7 8 9 9 0 1 2 3 4 5 6 7 8 9 ok
curiously if i use only i . the nested loop runs ok........ Why ? That is normal. I accesses the current loop index, J the outer loop index, K 2 levels up.
curiously if i use only i . the nested loop runs ok........
oh oh totally true, i had a wrong idea. really i is inner loop and j is outer loop. thank you again.....
gforth Gforth 0.7.9_20250321 Authors: Anton Ertl, Bernd Paysan, Jens Wilke et al., for more type `authors' Copyright © 2025 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html> Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license' Type `help' for basic help : test1 10 0 do ." i" i . 10 0 do ." j" j . loop cr loop ; ok test1 i0 j0 j0 j0 j0 j0 j0 j0 j0 j0 j0 i1 j1 j1 j1 j1 j1 j1 j1 j1 j1 j1 i2 j2 j2 j2 j2 j2 j2 j2 j2 j2 j2 i3 j3...
(a) is correct. You need to think about what the function of the word J is. J gets you the value of the index of the outer loop.
hello , i use i and jin the for next loop and ix and jx in the do loop: I checked these words: test1 10 0 do ." i " ix . 10 0 do ."j" jx . loop loop ; and doesnt work but (a) test1 10 0 do ." i" ix . 10 0 do ." j" ix. loop loop ; it works! (b) (a) : i0 j0 j0 j0 j0 j0 j0 j0 j0 j0 j0 i1 j1 j1 j1 j1 j1 j1 j1 j1 j1 j1 i2 j2 j2 j2 j2 j2 j2 j2 j2 j2 j2 i3 j3 j3 j3 j3 j3 j3 j3 j3 j3 j3 i4 j4 j4 j4 j4 j4 j4 j4 j4 j4 j4 i5 j5 j5 j5 j5 j5 j5 j5 j5 j5 j5 i6 j6 j6 j6 j6 j6 j6 j6 j6 j6 j6 i7 j7 j7 j7 j7 j7 j7...
hello , i use i and jin the for next loop and ix and jx in the do loop: I checked these words: test1 10 0 do ." i " ix . 10 0 do ."j" jx . loop loop ; and doesnt work but (a) test1 10 0 do ." i" ix . 10 0 do ." j" ix. loop loop ; it works! (b) (a) : i0 j0 j0 j0 j0 j0 j0 j0 j0 j0 j0 i1 j1 j1 j1 j1 j1 j1 j1 j1 j1 j1 i2 j2 j2 j2 j2 j2 j2 j2 j2 j2 j2 i3 j3 j3 j3 j3 j3 j3 j3 j3 j3 j3 i4 j4 j4 j4 j4 j4 j4 j4 j4 j4 j4 i5 j5 j5 j5 j5 j5 j5 j5 j5 j5 j5 i6 j6 j6 j6 j6 j6 j6 j6 j6 j6 j6 i7 j7 j7 j7 j7 j7 j7...
How did you define J for the FOR NEXT? You cannot use J defined for DO LOOP in the FOR NEXT LOOP.
It is difficult to answer a question if you do not show the real code that you are using. If you use Ix then write it in the code. For me the do loop works just fine on the scamp 3e. : test1 10 0 do ." i" ii . 10 0 do ." j" j . loop cr loop ; ok i0 j0 j0 j0 j0 j0 j0 j0 j0 j0 j0 i1 j1 j1 j1 j1 j1 j1 j1 j1 j1 j1 i2 j2 j2 j2 j2 j2 j2 j2 j2 j2 j2 i3 j3 j3 j3 j3 j3 j3 j3 j3 j3 j3 i4 j4 j4 j4 j4 j4 j4 j4 j4 j4 j4 i5 j5 j5 j5 j5 j5 j5 j5 j5 j5 j5 i6 j6 j6 j6 j6 j6 j6 j6 j6 j6 j6 i7 j7 j7 j7 j7 j7 j7 j7...
in the rest of forths the firts way is the correct, using i and j, not using always i. the question is why when i use i and j, the double loop doesnt work well?