Hello, friends.
I'm working on a 6502 emulator as a hobby project. I've been making much use of the indispensable Visual6502 simulator in this endeavour, which has greatly aided me (along with many other resources including this forum). However, there is one behaviour of the simulator that I don't fully understand, and I was hoping someone here might be able to explain it.
In short, when executing an opcode that has multiple write cycles in succession, such as BRK or JSR pushing the PC (and processor flags, in BRKs case) to the stack, a previous value that was on the databus appears in the first half-cycle of the later write cycles.
As shown in this image, during cycles 9 and 10, the value 0x42 (the next byte after the BRK opcode) appears on the databus again. (If the image is hard to read, here's a link that should load the inputs on the simulator.)
As far as I can tell, no internal register or latch (at least, none that Visual6502 exposes as traceable) holds the 0x42 value during the half cycle the bus is being used for writing. The "idl" latch (which I think is the Visual6502 name for one of the latches used for ALU input and not the Input Data Latch from Hanson's diagram?) does hold this value, but that's several cycles too early.
What I suspect is happening is that the Internal Data Latch stores the last read value and it's put on the bus for that half-cycle once the write is finished? If that's the case, does this happen every time, even for read cycles (since I think the behaviour would match)? I can't seem to find any source that explicitly confirms that's what's happening though. The NESdev wiki does say that the DL is put on one of DB/ADH/ADL each Phi1, but the listed datapath node names make reference to the internal data bus instead and, in the simulator, aren't active on the cycles I'm confused about. The Breaking NES 6502 book also says that the "db" the DL/DB datapath node refers to is the internal bus.
I should also say that I'm very much approaching this from a "high-level (i.e. programmer) down" view, since I don't have a particularly strong grasp of electrical engineering (the Visual6502 diagram is very difficult for me to parse, for example), so if the answer would be obvious from a lower-level hardware perspective, I'll have to ask you to humour me.
Thanks in advance for any insight you might have.
Confused about Data Bus behaviour during write cycles
- GARTHWILSON
- Forum Moderator
- Posts: 8775
- Joined: 30 Aug 2002
- Location: Southern California
- Contact:
Re: Confused about Data Bus behaviour during write cycles
The processor is not putting data on the bus during those times, beyond just the tDHW time. The logic states are just being held by stray capacitance in the circuit. If all loads are CMOS, the state of a bus line that's no longer being driven may be held for milliseconds, not just microseconds or nanoseconds.
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?
- BigDumbDinosaur
- Posts: 9428
- Joined: 28 May 2009
- Location: Midwestern USA (JB Pritzker’s dystopia)
- Contact:
Re: Confused about Data Bus behaviour during write cycles
Anarcholepsy wrote:
In short, when executing an opcode that has multiple write cycles in succession, such as BRK or JSR pushing the PC (and processor flags, in BRKs case) to the stack, a previous value that was on the databus appears in the first half-cycle of the later write cycles.
An interesting problem arises if nothing drives the data bus during a read cycle when the clock goes high. Parasitic capacitance may cause the 65C02 to read what it thinks is an opcode but is actually just left-over state of an indeterminate value. There’s no telling what will happen in such a case.
BTW, the 65C02 MPU pushes SR (status register) during any interrupt, not just BRK. The b bit in the stack copy of SR only matters during an IRQ or BRK...it is always set if SR is examined via a PHP - PLA sequence.
x86? We ain't got no x86. We don't NEED no stinking x86!
Re: Confused about Data Bus behaviour during write cycles
Welcome!
Indeed, as noted, a real 6502 will be reading the bus in the first half cycle of the write, and most physical systems will do something predictable in that case, but what exactly they do depends on the system.
As for visual6502, reading the code will tell us what it does, but it's somewhat unimportant: the value printed for the first half of the cycle has no effect, and doesn't come from the 6502 internals. (I do agree that it is initially unexpected for the user!)
Indeed, as noted, a real 6502 will be reading the bus in the first half cycle of the write, and most physical systems will do something predictable in that case, but what exactly they do depends on the system.
As for visual6502, reading the code will tell us what it does, but it's somewhat unimportant: the value printed for the first half of the cycle has no effect, and doesn't come from the 6502 internals. (I do agree that it is initially unexpected for the user!)
Re: Confused about Data Bus behaviour during write cycles
Quote:
... there is one behaviour of the simulator that I don't fully understand, and I was hoping someone here might be able to explain it.
Code: Select all
function halfStep(){
var clk = isNodeHigh(nodenames['clk0']);
if (clk) {setLow('clk0'); handleBusRead(); }
else {setHigh('clk0'); handleBusWrite();}
eval(clockTriggers[cycle+1]); // pre-apply next tick's inputs now, so the updates are displayed
}
function handleBusRead(){
if(isNodeHigh(nodenames['rw'])){
var a = readAddressBus();
var d = eval(readTriggers[a]);
if(d == undefined)
d = mRead(readAddressBus());
if(isNodeHigh(nodenames['sync']))
eval(fetchTriggers[d]);
writeDataBus(d);
}
}
function handleBusWrite(){
if(!isNodeHigh(nodenames['rw'])){
var a = readAddressBus();
var d = readDataBus();
eval(writeTriggers[a]);
mWrite(a,d);
if(a<0x200) setCellValue(a,d);
}
}
function readAddressBus(){return readBits('ab', 16);}
function readDataBus(){return readBits('db', 8);}
Code: Select all
function setHigh(name){
var nn = nodenames[name];
nodes[nn].pullup = true;
nodes[nn].pulldown = false;
recalcNodeList([nn]);
}
function setLow(name){
var nn = nodenames[name];
nodes[nn].pullup = false;
nodes[nn].pulldown = true;
recalcNodeList([nn]);
}
Edit: the upstream sources are in this repo
-
Anarcholepsy
- Posts: 3
- Joined: 21 Feb 2026
Re: Confused about Data Bus behaviour during write cycles
Thanks everyone, I think I understand now.