6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 06, 2024 9:03 am

All times are UTC




Post new topic Reply to topic  [ 16 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Jun 26, 2015 12:46 am 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
I'm running a 65C02 from a microcontroller and feeding it data from the microcontroller's memory. If the processor tries to read an address that the microcontroller has marked uninitialized, the microcontroller stops execution. This is really handy for debugging. The problem is detecting the difference between when the processor is reading from an address or just pointing to that address but not reading or writing anything. For example, I noticed on JSR the address bus first jumps to the top of the stack for one cycle then writes data there on the next cycle. If this address is uninitialized, it won't matter since it's just going to write there on the second cycle but I need a way to know that it isn't doing anything on the first cycle. When I did this on a 65C816 I just had to check that both VPA and VDA were zero to know it was an internal operation. Any suggestions on how to find the same thing out on a 65C02?


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 2:18 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
Assuming a WDC 'c02, and checking the data sheet for pinout information and the like, I find SYNC and VPB outputs that give the opportunity for an external state machine to "lock on" to the CPU state. You can then keep track of where the CPU is in terms of handling each opcode.

The problem comes with your page-boundary penalty for indexing across a page boundary. In these cases, there doesn't appear to be a way to know that a "free" cycle is being emitted until the start of the following cycle. The WDC 'c02 is at least specified to have the invalid address be the last instruction byte fetched, but that's no guarantee: If the last instruction byte is actually the given target then it isn't dead. This may not matter for your use-case, however.

The same cycle for a "taken" branch is easy to detect: If the second cycle after a branch opcode is fetched does not involve SYNC, then you have a "free" cycle.

I guess what I'm saying is "not for the general case, here's an 80% solution, how to drive it to 90%, and when it's not going to work". If it's a "good enough" solution for your project is a judgment call that only you are qualified to make.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 2:27 am 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Thanks for your reply nyef. It seems like I would need to include a description of the bus for every op code on every cycle, which does not seem like much fun. Does that seem like the only way to accomplish this?


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 2:33 am 
Offline

Joined: Sun Jul 28, 2013 12:59 am
Posts: 235
There are only so many instructions, and far, far fewer addressing modes, which are the primary determiner of behavior in this respect. It may or may not be fun. It may even be yet another tedious thing that needs to be dealt with in order to achieve your goals. But it is unlikely to take very long to determine if it would work for you, nor is it likely to take very long to implement.

... Or someone could have a better idea. But this is the approach that I see that comes closest to actually working.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 2:35 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3353
Location: Ontario, Canada
nyef wrote:
SYNC and VPB outputs that give the opportunity for an external state machine to "lock on" to the CPU state. You can then keep track of where the CPU is in terms of handling each opcode.
Yup.

nyef wrote:
The WDC 'c02 [ Rockwell, too - JL ] is at least specified to have the invalid address be the last instruction byte fetched, but that's no guarantee: If the last instruction byte is actually the given target then it isn't dead.
Interesting; you're right. But occasions where the last instruction byte is actually the given target are hardly the norm. </droll understatement> :D I think the external state machine idea is highly feasible -- but (and you make this point yourself) perhaps more effort than is justified.


nyef wrote:
I guess what I'm saying is "not for the general case, here's an 80% solution, how to drive it to 90%, and when it's not going to work". If it's a "good enough" solution for your project is a judgment call that only you are qualified to make.
Agreed. Druzyek, how would you feel about simply making the stack an exception? Ie; don't check for uninitialized accesses if the address is in Page 1. It seems to me the utility of your debugging feature would be largely unaffected.

-- Jeff

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


Last edited by Dr Jefyll on Fri Jun 26, 2015 4:07 am, edited 1 time in total.

Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 2:36 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
We've talked about something like this before, but I can't remember what search terms might find it. One thing that came up was that the microcontroller watching it would have to keep track of whether the 6502 is in decimal mode or not, because it affects what you should expect in the various cycles of some instructions.

Is this really necessary though? I don't recall ever in 30 years having had a bug due to an uninitialized variable. Ever. It's because with good programming habits, you initialize what you need to when you write the reset routine and other routines that initialize programs.

_________________
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: Fri Jun 26, 2015 3:39 pm 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Quote:
Agreed. Druzyek, how would you feel about simply making the stack an exception?
That is a really good idea. Can you think of any other op codes that I might need to watch out for outside the stack? For example, I know RTS points to the next byte even though its not used, although this wouldn't be a problem unless its the very last opcode in my program.

Quote:
Is this really necessary though? I don't recall ever in 30 years having had a bug due to an uninitialized variable.
YES! I started this project because I didn't know how the processor worked or how to use assembly. So far the majority of mistakes I have made learning assembly have been pointing the processor to the wrong place such as writing LDA $40 when I really meant LDA #$40.

I am leaning against storing info on all the opcodes and addressing modes on the microcontroller.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 3:55 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10799
Location: England
RTS reads the next byte because every instruction reads the next byte - the CPU has no choice because it doesn't yet know what the opcode is. So, the cycle after a SYNC is always going to be a read, and can't (practically) be a case of reading uninit data.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 7:25 pm 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 672
It's also hard to know what on the stack is truly initialized vs uninitialized just by looking at reads and writes. If the stack pointer is incremented for popping things off, those locations should ideally become uninitialized again, but you can't really know that just by basic r/w bus sniffing.

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 8:53 pm 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Quote:
the cycle after a SYNC is always going to be a read
That makes sense. I should do some testing and see exactly what cycles VDA and VPA were marking as internal.

By the way, is there a reference anywhere that would show what op codes are doing internal operations when? If it is not that many, maybe I can have the microcontroller look out for them.

Quote:
It's also hard to know what on the stack is truly initialized vs uninitialized just by looking at reads and writes.
In a way, yes. The whole stack gets marked uninitialized between runs for one and I find that mismatched JSR and RTS pairs (again easy to do for a beginner like me) can lead to reading uninitialized stack memory pretty quickly.

I don't mean to make a big deal about detecting the uninitialized reads but it has been by far the handiest debug feature. It also breaks on trying to execute any addresses marked as data or trying to load data that is marked as code (unless you want it to be self modifying) but this practically never happens. Looking out for uninitialized reads can save you from all sorts of things like even doing an indirect jump to the wrong address since most of the address space is empty.


Top
 Profile  
Reply with quote  
PostPosted: Fri Jun 26, 2015 9:50 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8432
Location: Southern California
Quote:
By the way, is there a reference anywhere that would show what op codes are doing internal operations when? If it is not that many, maybe I can have the microcontroller look out for them.

That used to be in the data sheet, but I see the newer revisions don't have it. And again, the microcontroller would have to know if the processor's D flag is set, because that affects some of the instructions' bus cycles and internal-operations cycles.

_________________
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 Jun 27, 2015 12:23 am 
Offline
User avatar

Joined: Wed Feb 13, 2013 1:38 pm
Posts: 586
Location: Michigan, USA
Druzyek wrote:
... By the way, is there a reference anywhere that would show what op codes are doing internal operations when? If it is not that many, maybe I can have the microcontroller look out for them.

Do you mean a document that shows what's going on during each cycle? Something like this?

Code:
  Instructions accessing the stack

     BRK

        #  address R/W description
       --- ------- --- -----------------------------------------------
        1    PC     R  fetch opcode, increment PC
        2    PC     R  read next instruction byte (and throw it away),
                       increment PC
        3  $0100,S  W  push PCH on stack, decrement S
        4  $0100,S  W  push PCL on stack, decrement S
        5  $0100,S  W  push P on stack (with B flag set), decrement S
        6   $FFFE   R  fetch PCL
        7   $FFFF   R  fetch PCH


     RTI

        #  address R/W description
       --- ------- --- -----------------------------------------------
        1    PC     R  fetch opcode, increment PC
        2    PC     R  read next instruction byte (and throw it away)
        3  $0100,S  R  increment S
        4  $0100,S  R  pull P from stack, increment S
        5  $0100,S  R  pull PCL from stack, increment S
        6  $0100,S  R  pull PCH from stack


     RTS

        #  address R/W description
       --- ------- --- -----------------------------------------------
        1    PC     R  fetch opcode, increment PC
        2    PC     R  read next instruction byte (and throw it away)
        3  $0100,S  R  increment S
        4  $0100,S  R  pull PCL from stack, increment S
        5  $0100,S  R  pull PCH from stack
        6    PC     R  increment PC



Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 27, 2015 1:21 am 
Offline
User avatar

Joined: Fri Dec 11, 2009 3:50 pm
Posts: 3353
Location: Ontario, Canada
Michael wrote:
Something like this?
That's good info, Michael -- clear and easy to read. Where did it come from? Unfortunately it's not arranged in a way that lets you quickly notice all the dummy bus cycles. Table 5-7 of WDC's '816 datasheet is NOT easy to read, but at least it makes dummy bus cycles obvious; you can just scan down the columns for VPA & VDA and look for cases where they're both zero. But Table 5-7 is seven pages long!

Here, then, is my edited version of Table 5-7 -- sorted and highlighted to show every case where dummy bus cycles occur. Despite being part of an '816 datasheet, Table 5-7 apparently applies to WDC's current 'C02 as well (the W65C02S).

As you can see below, I rearranged and condensed the seven-page table into two tall, skinny gif files. Although I was reasonably careful, it's possible I accidentally introduced some errors, so check the WDC original if you prefer to see their errors only! :wink:

Edit: I will be adding detail and revising these gif diagrams, so I suggest you do NOT download them. Here is rev1 of the first table. Matters related to indexed addressing I moved up near the top, for easier reference to the notes. IMO indexed addressing is by far the most confusing cause of dummy bus cycles!

cheers,
Jeff


Attachments:
'02 and '816 dummy cycles due to misc causes rev1.gif
'02 and '816 dummy cycles due to misc causes rev1.gif [ 164.26 KiB | Viewed 1150 times ]
'02 and '816 dummy cycles due to extra read at PC.gif
'02 and '816 dummy cycles due to extra read at PC.gif [ 203.93 KiB | Viewed 1150 times ]

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


Last edited by Dr Jefyll on Sat Jun 27, 2015 11:47 pm, edited 1 time in total.
Top
 Profile  
Reply with quote  
PostPosted: Sat Jun 27, 2015 1:50 pm 
Offline
User avatar

Joined: Mon May 12, 2014 6:18 pm
Posts: 365
Dr Jefyll, thanks! That is exactly what I was hoping to find.

Yikes, having to keep track of the D flag is a deal breaker :( I do plan to use a lot of BCD arithmetic. Thanks for the ideas but I think I will have to leave this feature out. In the future I think I will also only buy 65C816s even when I really want a 6502.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jun 28, 2015 11:24 pm 
Offline

Joined: Tue Jul 24, 2012 2:27 am
Posts: 672
I think what Michael posted is from 64doc.txt.

_________________
WFDis Interactive 6502 Disassembler
AcheronVM: A Reconfigurable 16-bit Virtual CPU for the 6502 Microprocessor


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

All times are UTC


Who is online

Users browsing this forum: No registered users and 13 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: