Detecting Free Bus Cycles
Detecting Free Bus Cycles
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?
Re: Detecting Free Bus Cycles
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.
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.
Re: Detecting Free Bus Cycles
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?
Re: Detecting Free Bus Cycles
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.
... Or someone could have a better idea. But this is the approach that I see that comes closest to actually working.
Re: Detecting Free Bus Cycles
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.
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.
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.
-- Jeff
Last edited by Dr Jefyll on Fri Jun 26, 2015 4:07 am, edited 1 time in total.
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: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Detecting Free Bus Cycles
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.
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?
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?
Re: Detecting Free Bus Cycles
Quote:
Agreed. Druzyek, how would you feel about simply making the stack an exception?
Quote:
Is this really necessary though? I don't recall ever in 30 years having had a bug due to an uninitialized variable.
I am leaning against storing info on all the opcodes and addressing modes on the microcontroller.
Re: Detecting Free Bus Cycles
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.
-
White Flame
- Posts: 704
- Joined: 24 Jul 2012
Re: Detecting Free Bus Cycles
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.
Re: Detecting Free Bus Cycles
Quote:
the cycle after a SYNC is always going to be a read
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.
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.
- GARTHWILSON
- Forum Moderator
- Posts: 8774
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Detecting Free Bus Cycles
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.
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: Detecting Free Bus Cycles
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.
Code: Select all
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
Re: Detecting Free Bus Cycles
Michael wrote:
Something like this?
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!
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
Last edited by Dr Jefyll on Sat Jun 27, 2015 11:47 pm, edited 1 time in total.
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: Detecting Free Bus Cycles
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.
Yikes, having to keep track of the D flag is a deal breaker
-
White Flame
- Posts: 704
- Joined: 24 Jul 2012
Re: Detecting Free Bus Cycles
I think what Michael posted is from 64doc.txt.