Help on fig-FORTH 1.0 Bring Up
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Help on fig-FORTH 1.0 Bring Up
Yes, that would be a problem. Keep in mind that the interrupt has not been serviced yet, so IRQ\ will still be low. It will be the same interrupt that makes it loop and loop, continually calling setirq, and overrun the return stack, which at this point won't matter anyway because you're crashed.
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: Help on fig-FORTH 1.0 Bring Up
barrym95838 wrote:
is there a risk of another IRQ hitting between the PLP and SEI, mucking up the works?
It's fair to ask whether I'm supposing the interrupt logic to be more complex than it is. However, the fact remains there is no spec. And the following topic illustrates that the interrupt logic does have some non-obvious behaviors: A taken branch delays interrupt handling by one instruction
Because there's no spec which verifies your shortened code sequence is alright, it's best to play it safe as Garth suggests. Unfortunately that precludes your imaginative speed-up. If the issue means a lot to you, an experiment is required. And of course the experiment would need to be repeated for every processor variant ('02, 'c02, 816, emulator, soft core, etc) of interest.
cheers,
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
Re: Help on fig-FORTH 1.0 Bring Up
I think that I can help with this study with respect to the M65C02/M65C02A cores.
The effect of the I bit change introduced by SEI/CLI is immediate. Because of the pipelining implemented in these two soft-cores, interrupts are not taken at the completion of either instruction. SEI inhibits maskable interrupts even if simultaneously asserted with the fetch of the SEI opcode, and CLI delays the acceptance of maskable interrupts until the completion of the following instruction.
That being the case, I fall into DrJefyll's camp on this issue. I've not read any specification regarding the timing of the effects of SEI/CLI as I defined above for the M65C02/M65C02A cores for any other member of the 6502 processor family. It is safer to take the Garth's approach for modifying the I flag in a PSW on the stack.
The effect of the I bit change introduced by SEI/CLI is immediate. Because of the pipelining implemented in these two soft-cores, interrupts are not taken at the completion of either instruction. SEI inhibits maskable interrupts even if simultaneously asserted with the fetch of the SEI opcode, and CLI delays the acceptance of maskable interrupts until the completion of the following instruction.
That being the case, I fall into DrJefyll's camp on this issue. I've not read any specification regarding the timing of the effects of SEI/CLI as I defined above for the M65C02/M65C02A cores for any other member of the 6502 processor family. It is safer to take the Garth's approach for modifying the I flag in a PSW on the stack.
Michael A.
Re: Help on fig-FORTH 1.0 Bring Up
For the NMOS 6502, you can see the effect is as Garth describes - the pending interrupt is taken as a result of the PLP clearing the I flag, although the SEI instruction is already in flight at the point this happens and indeed succeeds in setting the I flag. The subsequent instruction - in this case a PHP - is subsumed by a BRK-like action which stacks the machine state and fetches from the appropriate vector. See
http://visual6502.org/JSSim/expert.html ... ogmore=irq
Cheers
Ed
http://visual6502.org/JSSim/expert.html ... ogmore=irq
Cheers
Ed
Re: Help on fig-FORTH 1.0 Bring Up
... and note, because the SEI does have effect just prior to the second interrupt being taken, it would be possible to detect that. If the interrupt mask is set on entry to the interrupt routine, we're in a nested call, so just RTI. The original outer call will then resume, having patched the P byte it will now continue by pushing it.
[Thanks to Dr Jefyll for prompting me to think about that.]
[Thanks to Dr Jefyll for prompting me to think about that.]
Re: Help on fig-FORTH 1.0 Bring Up
Thanks, Michael & Ed, for supplying the two data points. The 'c02 experiment is one I can run myself, time permitting.
This reinforces the premise that you can't predict interrupt behavior merely by glancing at the source code. Taken at face value, the code in this case seems to indicate that the SEI will not execute.
Ed has taken the matter in a direction I didn't anticipate. He notes that, because on NMOS '02 the SEI does execute, the state pushed by the interrupt has the I bit set -- a novel circumstance, given that the ISR is about to be entered! I wonder if that could prove useful in some other context -- knowing whether an SEI had just executed, I mean. (In Mike's case the extra ISR code to detect the condition would dilute the speedup he was trying to achieve.)
-- Jeff
Code: Select all
PLP ;enables interrupts
SEI ;disables interrupts
BigEd wrote:
the pending interrupt is taken as a result of the PLP clearing the I flag, although the SEI instruction is already in flight
BigEd wrote:
because the SEI does have effect just prior to the second interrupt being taken, it would be possible to detect that.
-- 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
Re: Help on fig-FORTH 1.0 Bring Up
GARTHWILSON wrote:
Keep in mind that the interrupt has not been serviced yet, so IRQ\ will still be low. It will be the same interrupt that makes it loop and loop, continually calling setirq...
But as Jeff notes, the idea was to minimise the time taken! So this tweak isn't an optimisation.
Cheers
Ed
- barrym95838
- Posts: 2056
- Joined: 30 Jun 2013
- Location: Sacramento, CA, USA
Re: Help on fig-FORTH 1.0 Bring Up
Dr Jefyll wrote:
... If the issue means a lot to you, an experiment is required. And of course the experiment would need to be repeated for every processor variant ('02, 'c02, 816, emulator, soft core, etc) of interest.
Thanks to you and to the others for politely putting up with my off-topic antics.
Mike
Re: Help on fig-FORTH 1.0 Bring Up
Just wanted to make two comments about my recent experience porting the fig-FORTH NEXT routine to the M65C02A instruction set.
First, on exit from NEXT, Y must be 0 or CFA will drive the train off the rails. In CFA there's a code snippet that adjusts W by 2. As written it saves 1 cycle by using a TYA instruction to add the carry out of the low byte of IP into the high. This is done instead of using the same technique used in other parts of the kernel for incrementing W/IP by 2. (Whoop dee do, this is a prime example of optimization at its absolute worst. CFA is a very low frequency word/operation in the grand scheme of things. It would have been much more effective to optimize the number of STX XSAVE and LDX XSAVE operations scattered throughout the code than to assume Y is zero in this particular routine.)
Second, BRANCH jumps into NEXT at NEXT+2. This avoids the LDY #1 instruction at NEXT. BRANCH is a frequently used fig-FORTH word, but it's probably not necessary to optimize out that 2 cycle instruction.
Thus, to use 65C02 and M65C02A instructions, the jmp NEXT+2 in BRANCH must be replaced with a jmp NEXT, and a LDY #0 must be included in NEXT. With those stumbling blocks avoided, I replaced the fig-FORTH NEXT with a version implemented using 65C02 and M65C02A instructions. It saves 8 bytes and 6 cycles from the 6502 version. Below is the M65C02A NEXT (without using the FORTH VM instruction sequence IND NXT).
The following is the new BRANCH routine:
First, on exit from NEXT, Y must be 0 or CFA will drive the train off the rails. In CFA there's a code snippet that adjusts W by 2. As written it saves 1 cycle by using a TYA instruction to add the carry out of the low byte of IP into the high. This is done instead of using the same technique used in other parts of the kernel for incrementing W/IP by 2. (Whoop dee do, this is a prime example of optimization at its absolute worst. CFA is a very low frequency word/operation in the grand scheme of things. It would have been much more effective to optimize the number of STX XSAVE and LDX XSAVE operations scattered throughout the code than to assume Y is zero in this particular routine.)
Second, BRANCH jumps into NEXT at NEXT+2. This avoids the LDY #1 instruction at NEXT. BRANCH is a frequently used fig-FORTH word, but it's probably not necessary to optimize out that 2 cycle instruction.
Thus, to use 65C02 and M65C02A instructions, the jmp NEXT+2 in BRANCH must be replaced with a jmp NEXT, and a LDY #0 must be included in NEXT. With those stumbling blocks avoided, I replaced the fig-FORTH NEXT with a version implemented using 65C02 and M65C02A instructions. It saves 8 bytes and 6 cycles from the 6502 version. Below is the M65C02A NEXT (without using the FORTH VM instruction sequence IND NXT).
Code: Select all
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NEXT db SIZ ;; Fetch code field address pointed
lda (IP) ;; to by IP
db SIZ ;; Store in W
sta W
db SIZ ;; Increment IP by 2
inc IP
db SIZ
inc IP
ldy #$00 ;; clear Y before exit
jmp W-1 ;; Jump to an indirect jump (W) which
ds 8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Code: Select all
L89 db $86,"BRANC",$C8
dw L75 ;link to EXCECUTE
BRAN dw *+2
clc
lda (IP),y
adc IP
pha
iny
lda (IP),y
adc IP+1
sta IP+1
pla
sta IP
;; jmp NEXT+2
jmp NEXT
Michael A.
Re: Help on fig-FORTH 1.0 Bring Up
I've converted / ported figForth 1.0 to support my M65C02A processor model. I've succeeded in getting the sign-on message displayed within the py65 environment. Beyond that I had a lot of trouble figuring out why the interpreter terminated and fell out to the py65 command line.
Therefore, yesterday I began rehosting what I considered my golden version of the figForth 1.0 source code; code that I had posted on github along with my M65C02 core and transferred into the M65C02A project repository when I released that project again on github.
Well that turned out to have some issues. First, my M65C02A, PyAsm65, assembler was not correctly supporting some of the addressing modes of the basic 6502/65C02, and it was defaulting some of the pre-indexed (by X) addressing modes to zp rather than abs for certain instructions like the sty abs,X instruction. Once I resolved those I could get the sign-on message that I expected: "fig-FORTH 1.0a".
After adding some mods to my py65 M65C02A processor model to allow me to trace the Forth words, I finally isolated a problem that prevented my figForth from traversing the vocabulary. (In the process, I found problems with the names of several of the words, such that the words were padded with a large number of leading spaces / blanks. Removing those blanks did not correct the problem with traversing the vocabulary.) I finally isolated the problem in TRAVERSE to the way the word's name string end was being determined. The implementation was using a modified LESS word to compare the character read from memory to a character literal of 0x7F.
Since figForth sets the msb of the name field's count and the last character in the name field, I changed the character literal to 0x80, and changed the operation from LESS to ANDD. With that change, TRAVERSE now works, and typing in VLIST at the prompt results in the listing of all of the elements of the figForth vocabulary. (Making the same changes to the M65C02A version, did not change that versions behavior: it stil outputs the sign-on message, but nothing else is working as expected. So something else is wrong with my port to the M65C02A extended instruction set.)
I can't seem to get any other vocabulary word, other than VLIST, to work as expected. It appears to interpret the entering of VLIST correctly, and it appears to enter new COLON definitions into the dictionary. If I use VLIST after an attempt to create a new word, the name of the new word appear in the vocabulary listing.
For example, if I type in the following a new word: : star 42 emit ; . I get " 42 ? " as the response, and star shows up in the vocabulary.
Debugging Forth (or for that matter someone else's code) is a bit outside of my experience. Much of the code is working as advertised, but the amount of time I spent finding the issue with TRAVERSE was mostly due to my unfamiliarity with figForth, or any Forth.
Since that simple program had an issue with the number, I will probably try to figure out if here is a problem with the number conversion routine first. However, any other suggestions would also be welcomed.
Therefore, yesterday I began rehosting what I considered my golden version of the figForth 1.0 source code; code that I had posted on github along with my M65C02 core and transferred into the M65C02A project repository when I released that project again on github.
Well that turned out to have some issues. First, my M65C02A, PyAsm65, assembler was not correctly supporting some of the addressing modes of the basic 6502/65C02, and it was defaulting some of the pre-indexed (by X) addressing modes to zp rather than abs for certain instructions like the sty abs,X instruction. Once I resolved those I could get the sign-on message that I expected: "fig-FORTH 1.0a".
After adding some mods to my py65 M65C02A processor model to allow me to trace the Forth words, I finally isolated a problem that prevented my figForth from traversing the vocabulary. (In the process, I found problems with the names of several of the words, such that the words were padded with a large number of leading spaces / blanks. Removing those blanks did not correct the problem with traversing the vocabulary.) I finally isolated the problem in TRAVERSE to the way the word's name string end was being determined. The implementation was using a modified LESS word to compare the character read from memory to a character literal of 0x7F.
Since figForth sets the msb of the name field's count and the last character in the name field, I changed the character literal to 0x80, and changed the operation from LESS to ANDD. With that change, TRAVERSE now works, and typing in VLIST at the prompt results in the listing of all of the elements of the figForth vocabulary. (Making the same changes to the M65C02A version, did not change that versions behavior: it stil outputs the sign-on message, but nothing else is working as expected. So something else is wrong with my port to the M65C02A extended instruction set.)
I can't seem to get any other vocabulary word, other than VLIST, to work as expected. It appears to interpret the entering of VLIST correctly, and it appears to enter new COLON definitions into the dictionary. If I use VLIST after an attempt to create a new word, the name of the new word appear in the vocabulary listing.
For example, if I type in the following a new word: : star 42 emit ; . I get " 42 ? " as the response, and star shows up in the vocabulary.
Debugging Forth (or for that matter someone else's code) is a bit outside of my experience. Much of the code is working as advertised, but the amount of time I spent finding the issue with TRAVERSE was mostly due to my unfamiliarity with figForth, or any Forth.
Since that simple program had an issue with the number, I will probably try to figure out if here is a problem with the number conversion routine first. However, any other suggestions would also be welcomed.
Michael A.
Re: Help on fig-FORTH 1.0 Bring Up
MichaelM wrote:
Debugging Forth (or for that matter someone else's code) is a bit outside of my experience. Much of the code is working as advertised, but the amount of time I spent finding the issue with TRAVERSE was mostly due to my unfamiliarity with figForth, or any Forth.
I would check to make sure the basics work, notably entering numbers, "." to print the top of stack, things like that.
Debugging Forth can be quite challenging if the fundamentals don't work, as you're in the mix of high level and low level code.
I would not blithely be changing constants in the code as is without a firm foundation as to why they are the way they are. There are a lot of assumptions in the raw FIG source code. The code DOES work. The bugs that are in the original FIG source are edge cases, rather than with the fundamental model.
Ideally, Forth is debugged with Forth. My FIG forth works. I have not tried it on py65 (I never found in the documentation how to read and write a character in py65 -- note, I see it now, it's just not obvious when the primary documentation is the monitor.)
My assembler produces S Records, not binaries. So I can't trivially load it in to py65 at the moment.
You can re-live some of my bootstrapping fun for Fig-Forth in this thread: viewtopic.php?f=9&t=2187
-
DerTrueForce
- Posts: 483
- Joined: 04 Jun 2016
- Location: Australia
Re: Help on fig-FORTH 1.0 Bring Up
If you're on linux, srec_cat can turn transfer between any number of formats, including srec and binary.
Re: Help on fig-FORTH 1.0 Bring Up
whartung:
Thanks very much. I'll read your thread / topic and look for inspiration for debugging my implementation.
I think part of the problem with TRAVERSE is due to the annotation in the LESS module that says it is altered from the model. Perhaps the 16-bit less than operation it attempts to perform does not apply well when both quantities are zero padded 8-bit quantities.
I've tested the DIGIT module for the decimal mode. Since that is working, I'll try to catch the error with the conversion of "42" that seems to be tripping up the compilation of the little COLON definition that I was using for testing.
Thanks very much. I'll read your thread / topic and look for inspiration for debugging my implementation.
I think part of the problem with TRAVERSE is due to the annotation in the LESS module that says it is altered from the model. Perhaps the 16-bit less than operation it attempts to perform does not apply well when both quantities are zero padded 8-bit quantities.
I've tested the DIGIT module for the decimal mode. Since that is working, I'll try to catch the error with the conversion of "42" that seems to be tripping up the compilation of the little COLON definition that I was using for testing.
Michael A.
Re: Help on fig-FORTH 1.0 Bring Up
DerTrueForce wrote:
If you're on linux, srec_cat can turn transfer between any number of formats, including srec and binary.
Turns out, I write Intel hex, not S Records. Doh! No matter, that utility helped.
Ok, I managed to get it to work.
Attached is a zip file with the FIG source I used, tweaked to work with py65. It also includes the assembler listing (with addresses and such), as well as the binary. I could not figure out how to check for a key to be hit (vs read), so ?TERMINAL likely does not work.
But, you can define words, and VLIST works. It expects DEL for back space, and ^M ($0D) for end of line. This is what worked on my mac shell, I hope that works for you.
But at a minimum, here you have one that works (with "works" meaning I typed 3 lines in to the prompt, and they worked). So, if nothing else, maybe you can contrast what you have to what I have.
Example session:
Code: Select all
$ py65mon
Py65 Monitor
PC AC XR YR SP NV-BDIZC
6502: 0000 00 00 00 ff 00110000
.load /tmp/forth.bin
Wrote +7063 bytes from $0000 to $1b96
PC AC XR YR SP NV-BDIZC
6502: 0000 00 00 00 ff 00110000
.g 0200
fig-FORTH 1.0
10 10 + OK
. 20 OK
: hello ." Hello!" CR ; OK
hello Hello!
OK
vlist
HELLO MON J* .S VLIST TRIAD INDEX LIST ? . .R
D. D.R #S # SIGN #> <# SPACES WHILE ELSE IF
REPEAT AGAIN END UNTIL +LOOP LOOP DO THEN ENDIF
BEGIN BACK FORGET ' R/W -BCD -DISC --> LOAD MESSAGE
.LINE (LINE) BLOCK BUFFER DR1 DR0 EMPTY-BUFFERS FLUSH
UPDATE +BUF PREV USE M/MOD */ */MOD MOD / /MOD
* M/ M* MAX MIN DABS ABS D+- +- S->D COLD ABORT
QUIT ( DEFINITIONS FORTH VOCABULARY IMMEDIATE INTERPRET
?STACK DLITERAL LITERAL [COMPILE] CREATE ID. ERROR
(ABORT) -FIND NUMBER (NUMBER) UPPER WORD PAD HOLD
BLANKS ERASE FILL QUERY EXPECT ." (.") -TRAILING
TYPE COUNT DOES> <BUILDS ;CODE (;CODE) DECIMAL HEX
SMUDGE ] [ COMPILE ?LOADING ?CSP ?PAIRS ?EXEC ?COMP
?ERROR !CSP PFA NFA CFA LFA LATEST TRAVERSE -DUP
SPACE ROT > < U< = - C, , ALLOT HERE 2+ 1+
TRFLAG HLD R# CSP FLD DPL BASE STATE CURRENT CONTEXT
OFFSET SCR OUT IN BLK VOC-LINK DP FENCE WARNING
WIDTH TIB +ORIGIN B/SCR B/BUF LIMIT FIRST C/L BL
3 2 1 0 USER VARIABLE CONSTANT ; : C! ! C@
@ T +! DUP SWAP DROP OVER DMINUS MINUS D+ +
0< 0= R R> >R LEAVE ;S RP! SP! SP@ XOR OR
AND U/ U* CMOVE CR ?TERMINAL KEY EMIT ENCLOSE (FIND)
DIGIT I (DO) (+LOOP) (LOOP) 0BRANCH BRANCH EXECUTE
CLIT LIT OK
Interrupt
PC AC XR YR SP NV-BDIZC
6502: 0310 00 9c 00 f5 00110010
.^D
$
- Attachments
-
- forth.zip
- Forth Source, Assembled Forth Source, Forth Binary load at $0000, start at $0200
- (67.65 KiB) Downloaded 99 times
Re: Help on fig-FORTH 1.0 Bring Up
Thanks very much. Will load and run the binary and see if I can get the same result. My processor model may have an error, and your file may help me isolate that as an issue.
Michael A.