6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun May 05, 2024 12:58 pm

All times are UTC




Post new topic Reply to topic  [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next
Author Message
PostPosted: Sat Dec 20, 2014 7:50 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
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?


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 20, 2014 4:55 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3352
Location: Ontario, Canada
barrym95838 wrote:
is there a risk of another IRQ hitting between the PLP and SEI, mucking up the works?
A more extensive answer to your question is, "we don't know." That's because there's no spec that details how long it takes for PLP to take effect on interrupts. We know the PLP instruction adds 4 cycles to overall program execution time, but to suppose "4 cycles" explains everything would be an unsupported assumption. It's possible (IMO probable) the interrupt logic has significant latency of its own in accepting the signal from the already-"completed" PLP instruction. That latency plays out during execution of the instruction(s) following PLP.

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


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 20, 2014 6:34 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 20, 2014 7:12 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10797
Location: England
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


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 21, 2014 8:21 am 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10797
Location: England
... 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.]


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 21, 2014 4:13 pm 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3352
Location: Ontario, Canada
Thanks, Michael & Ed, for supplying the two data points. The 'c02 experiment is one I can run myself, time permitting.

Code:
     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
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.

BigEd wrote:
because the SEI does have effect just prior to the second interrupt being taken, it would be possible to detect that.
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

_________________
In 1988 my 65C02 got six new registers and 44 new full-speed instructions!
https://laughtonelectronics.com/Arcana/ ... mmary.html


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 21, 2014 4:52 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10797
Location: England
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...

I don't think this is quite right: the first part is right, in that \IRQ is still low, so the PLP will in the first case clear the I flag, and a second interrupt handling sequence will be started. But, because the SEI had effect, the second time around the PLP will not clear the I flag, and the SEI and PHP will both proceed as expected. The end result is that this little routine will be run twice, without any noticeable effect except the time taken.

But as Jeff notes, the idea was to minimise the time taken! So this tweak isn't an optimisation.

Cheers
Ed


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 21, 2014 7:50 pm 
Offline
User avatar

Joined: Sun Jun 30, 2013 10:26 pm
Posts: 1928
Location: Sacramento, CA, USA
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.

Nah, just stirrin' the pot, Dr. J!!

Thanks to you and to the others for politely putting up with my off-topic antics.

Mike


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 29, 2014 2:59 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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).
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

The following is the new BRANCH routine:
Code:
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.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 18, 2019 8:14 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 18, 2019 9:51 pm 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
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.

Those are odd problems.

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


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 18, 2019 10:11 pm 
Offline

Joined: Sat Jun 04, 2016 10:22 pm
Posts: 483
Location: Australia
If you're on linux, srec_cat can turn transfer between any number of formats, including srec and binary.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 18, 2019 10:34 pm 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.

_________________
Michael A.


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 19, 2019 12:04 am 
Offline

Joined: Sat Dec 13, 2003 3:37 pm
Posts: 1004
DerTrueForce wrote:
If you're on linux, srec_cat can turn transfer between any number of formats, including srec and binary.

Ah, this helped.

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:
$ 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:
File comment: Forth Source, Assembled Forth Source, Forth Binary load at $0000, start at $0200
forth.zip [67.65 KiB]
Downloaded 60 times
Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 19, 2019 12:37 am 
Offline
User avatar

Joined: Mon Apr 23, 2012 12:28 am
Posts: 760
Location: Huntsville, AL
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.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 66 posts ]  Go to page Previous  1, 2, 3, 4, 5  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 4 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: