fig-FORTH EXECUTE
fig-FORTH EXECUTE
Hi All,
With fig-FORTH 1.0, I've noticed that I may issue the following, which jumps to the reset vector as expected and starts my kernal.
HEX
FFFC
EXECUTE
The Kernal reset is at $8530. From Wozmon, a 8530R starts it, and from EHBASIC a CALL $8530 works as well.
From fig-FORTH however, though the above execute for address FFFC works, the following does not, fig-FORTH just hangs:
HEX
8530
EXECUTE
I have also tried creating short assembly things at various addresses which it does not seem to call either, again just hangs. Tali forth on the other hand works "as I expect" whereas execute calls, in my example, 8530, or my address to start wozmon, etc.
I'm left wondering, am I missing something, should I expect fig-FORTH to jump to and execute 8530 as in my example above, or do I have some sort of problem with my fig-FORTH source, etc.
Any insight is appreciated and thanks!
PS - I am new to forth, so although I have also been trying to use CODE in order to test if I could make the desired jumps via. a assembly using a CODE instruction, I'm unfortunately not up to speed with that yet, though I continue to dig. However, even if I get that to work, I still want to understand if EXECUTE should handle it as described above.
I placed the post here as I'm thinking this is a newbie question, but of course please move to the FORTH section if more appropriate.
Thanks
With fig-FORTH 1.0, I've noticed that I may issue the following, which jumps to the reset vector as expected and starts my kernal.
HEX
FFFC
EXECUTE
The Kernal reset is at $8530. From Wozmon, a 8530R starts it, and from EHBASIC a CALL $8530 works as well.
From fig-FORTH however, though the above execute for address FFFC works, the following does not, fig-FORTH just hangs:
HEX
8530
EXECUTE
I have also tried creating short assembly things at various addresses which it does not seem to call either, again just hangs. Tali forth on the other hand works "as I expect" whereas execute calls, in my example, 8530, or my address to start wozmon, etc.
I'm left wondering, am I missing something, should I expect fig-FORTH to jump to and execute 8530 as in my example above, or do I have some sort of problem with my fig-FORTH source, etc.
Any insight is appreciated and thanks!
PS - I am new to forth, so although I have also been trying to use CODE in order to test if I could make the desired jumps via. a assembly using a CODE instruction, I'm unfortunately not up to speed with that yet, though I continue to dig. However, even if I get that to work, I still want to understand if EXECUTE should handle it as described above.
I placed the post here as I'm thinking this is a newbie question, but of course please move to the FORTH section if more appropriate.
Thanks
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
Welcome. EXECUTE's input is the desired word's CFA (code-field address) on the stack. The CFA points to the code that is to be run. It is not the beginning address of the code itself. In the case of a primitive, ie, a code definition, ie, a word that is defined in assembly language (as opposed to being defined in terms of other Forth words), the CFA just points to the PFA (parameter-field address), which immediately follows the CFA. If you do HEX 8530 EXECUTE, it will pick up an address from $8530 and $8531, and jump to whatever that said. If those two bytes contained instructions rather than an address, then yes, you'll take a left turn into the weeds.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: fig-FORTH EXECUTE
Garth! Thank you so much, that cleared it up and I have it working already.
You are much appreciated!
For anyone that may also struggle with this below is an example:
fig-FORTH 1.0
HEX OK
: LOW 50 ; OK
: HIGH 51 ; OK
30 LOW C! OK
85 HIGH C! OK
LOW EXECUTE
Note that execute works differently in Taliforth2
You are much appreciated!
For anyone that may also struggle with this below is an example:
fig-FORTH 1.0
HEX OK
: LOW 50 ; OK
: HIGH 51 ; OK
30 LOW C! OK
85 HIGH C! OK
LOW EXECUTE
Note that execute works differently in Taliforth2
Last edited by noneya on Sun Mar 20, 2022 7:18 am, edited 2 times in total.
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
Here's a graphic of the ITC Forth header structure, plus some explanation which should help. I think the only difference between this and FIG is the comment here about the need for aligning 16-bit cells to even addresses. On the NMOS 6502, this had to be done because of the JMP(xxFF) bug (which was fixed in the CMOS 65c02).
Code: Select all
After the name, there will be a zero byte if necessary to have the link field
start on an even-numbered address. Making the dummy byte a zero makes it
easier to find the NFA given the LFA when we allow characters above 7F in
names. The name field can start on any addr. [Edit: It especially makes SEE,
the de-compiling word easier.]
LINK FIELD: A two-byte address (low byte first, as usual) of the name
field of the previous word in the vocabulary. Link field always
starts on an even address.
CODE FIELD A two-byte address of the code to execute for this word. For a:
primitive: it points to the parameter field (its own addr + 2).
secondary: it points to the CFA of nest.
constant: it points to the addr of const runtime routine.
variable when the word is in RAM: it points to the addr of
create (not CREATE ).
variable when the word is in ROM: it works the same as a
constant that gives the applicable RAM addr.
(etc. Also see explanations of DOES> does ;code etc.)
PARAMETER FIELD (body) This could be machine-language code (in the case of a
primitive), a string of two-byte Forth code field addresses (in
the case of a secondary), data (in the case of a constant,
array, etc) or combinations of these. Some words may not even
have a parameter field, as is the case with DROP for example,
whose code field points to the POP routine, which has no need to
look back at DROP's parameter field for any information.
If code is compiled without headers, the name field and link field will be
absent. This saves memory, and if all the code is compiled without headers, it
will be nearly impossible for someone else to look at your compiled program and
figure it out, ie, reverse-engineer it. Headerless code may be acceptable for
systems where further compilation (requiring searching the dictionary for names)
is not needed.
Note that a runtime routine (or runtime, for short) is not a Forth word per se,
and not only has no header, but no CFA either. Other words' CFAs will point to
the address where the runtime routine starts. An example would be const , the
runtime for constants. const knows how to get the next cell (the only cell in
the parameter field of a word created by CONSTANT ) and put it on the stack.
Code fragments like POP2 and PUSH_FALSE are not particularly runtime routines,
but can be used as such by being called by the CFA of other words. In this
particular case, the address of POP2 is pointed to by the CFA of 2DROP , and the
address of PUSH_FALSE is pointed to by DUMMYCELL and a couple others. Usually
primitives will end by jumping to these fragments to save some memory when doing
things that a lot of primitives do at the end.http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
BTW, note these bugs in fig-Forth, and their fixes:
- unsigned division of a 32-bit dividend by a 16-bit divisor, resulting in a 16-bit quotient and a 16-bit remainder. Presented for the 65C02 (with changes for use on 6502) and 65816, with notes of interest to Forth users (for UM/MOD).
- unsigned multiplication (on forum), with 16-bit factors and 32-bit result, correcting a bug in the public-domain 6502 Forth multiplication, as the division article above
- D< bug in common Forths, plus a fix (on forum)
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: fig-FORTH EXECUTE
Thank you again! I will defiantly dig in to this.
Re: fig-FORTH EXECUTE
GARTHWILSON wrote:
I think the only difference between this and FIG is the comment here about the need for aligning 16-bit cells to even addresses. On the NMOS 6502, this had to be done because of the JMP(xxFF) bug (which was fixed in the CMOS 65c02).
Code: Select all
After the name, there will be a zero byte if necessary to have the link field start on an even-numbered address.The extra byte is only inserted when CREATE is about to lay down a Link Field and Code Field and the low-byte of DP = $FD. If an extra byte is inserted it will, as a side effect, cause the Link Field to be even-aligned, but this is unimportant.
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
I'll take your word for it so I don't have to look into the details again (which I have not paid attention to in years); but do see my comment in the code section about keeping the alignment in my 65c02 and '816 Forths because it made it easier to find the NFA given the LFA when I frequently use the special characters above $7F in the DOS/ANSI [Edit: that should say IBM437 character set], so I can have names like ±½°C. [Edit, after further discussion below: I had forgotten it also makes SEE, the de-compiling word, easier.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: fig-FORTH EXECUTE
GARTHWILSON wrote:
[...] because it made it easier to find the NFA given the LFA when I frequently use the special characters above $7F
But did you gloss over some details when you mentioned "keeping the alignment" in your 65c02 and '816 Forths? Either I'm missing something or you've evolved the alignment byte into something new and different that isn't really alignment related at all. I say that because aligning to even addresses means the extra byte will be absent about 50% of the time, whereas your end-of-name location scheme will require the extra byte to always be there. (Maybe we don't need to fully resolve this -- I'm okay if we don't.)
Certainly all of this is a LOT more detail than you asked for, noneya!
-- Jeff
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html
https://laughtonelectronics.com/Arcana/ ... mmary.html
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
Dr Jefyll wrote:
GARTHWILSON wrote:
[...] because it made it easier to find the NFA given the LFA when I frequently use the special characters above $7F
But did you gloss over some details when you mentioned "keeping the alignment" in your 65c02 and '816 Forths? Either I'm missing something or you've evolved the alignment byte into something new and different that isn't really alignment related at all.
- Cells are aligned in this kernel. The ANS decompiling word SEE works out simpler when the first byte of a cell has an even-numbered address. This is the only real reason for the alignment. DOES> compiles a null alignment byte after the JSR _does in the parent word so the CFA following it will be aligned. Interestingly, this also makes _does simpler.
FWIW, I wrote my word SEE before I knew about ANS, or probably before it even came out in '94, but I had called mine VIEW. When I saw that ANS had the same thing but called it SEE, I renamed mine to the standard. SEE is a decompiling word which makes a nice printout of what's in a secondary (ie, colon definition), its NFA, LFA, and CFA, with each cell given the word name if there's a header, the cell number, signed and unsigned value in both hex and decimal in case it's a compiled number, and text if it's a pair of ASCII characters, information might help in certain debugging situations.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: fig-FORTH EXECUTE
GARTHWILSON wrote:
Welcome. EXECUTE's input is the desired word's CFA (code-field address) on the stack. The CFA points to the code that is to be run. It is not the beginning address of the code itself. In the case of a primitive, ie, a code definition, ie, a word that is defined in assembly language (as opposed to being defined in terms of other Forth words), the CFA just points to the PFA (parameter-field address), which immediately follows the CFA. If you do HEX 8530 EXECUTE, it will pick up an address from $8530 and $8531, and jump to whatever that said. If those two bytes contained instructions rather than an address, then yes, you'll take a left turn into the weeds.
Something I realized when tightening up some code. EXECUTE isn't needed in the definition of a colon definition if the address to execute is known ahead of time. I used to define BYE , the word Fleet Forth uses to reset the C64, like this:
Code: Select all
: BYE ( -- )
SAVE-BUFFERS ACLOSE
$FFFC EXECUTE ; -2 ALLOT
Which compiled to something like this:
Code: Select all
SEE BYE
BYE
4374 23F1 SAVE-BUFFERS
4376 D3C ACLOSE
4378 A3C LIT FFFC
437C 17F3 EXECUTE
A
OK
Now I define it like this:
Code: Select all
: BYE ( -- )
SAVE-BUFFERS ACLOSE
[ $FFFC , ] ; -2 ALLOT
Which compiles to this:
Code: Select all
SEE BYE
BYE
4374 23F1 SAVE-BUFFERS
4376 D3C ACLOSE
4378 FFFC
6
OK
Saving four bytes.
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
Off the top of my head, the number-one use of EXECUTE I can think of is if you pick up the address from a table, where the address you'll need is not known at compile time. It may even be a cell in a record in the table, where other bytes in the same record may be text or other parameters, rather than CFAs.
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
- GARTHWILSON
- Forum Moderator
- Posts: 8773
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: fig-FORTH EXECUTE
Ah, yes, calling either INTERPRETER or COMPILER:
Code: Select all
: INTERPRETER ( str_addr -- ) \ Common Forth FIG
FIND \ ^ addr f (f=0 if not found)
IF EXECUTE \ EXECUTE if word found.
ELSE #INT 0= \ Else, see if it's a valid number.
IF DROP THEN \ DROP the high cell if not double-precision.
THEN ?STACK ;
: COMPILER ( str_addr -- )
FIND ?DUP IF \ TOS<>0 if word was found.
0< IF , EXIT THEN \ -1 means not IMMEDIATE , so compile it.
EXECUTE EXIT THEN \ Else it's IMMEDIATE , so execute it.
\ If word was not found, see
#INT IF \ if string is a valid number. If a decimal
2LITERAL EXIT THEN \ point was found, make a double literal; else
DROP LITERAL ; \ drop the high cell and make a single literal.
: INTERPRET ( -- ) \ 18 CELLS SF283-286
BEGIN BL WORD \ ^ addr
DUP C@ 0<> \ ^ addr f
WHILE STATE @ \ ^ addr f
IF COMPILER ELSE INTERPRETER THEN \ ^ empty
REPEAT DROP ;http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: fig-FORTH EXECUTE
OOC, where else would either INTERPRETER or COMPILER be used outside of INTERPRET that would require them to have their own definitions?
Personally I like the all-in-one combination of all three in Fig Forth.
Personally I like the all-in-one combination of all three in Fig Forth.