6502 Simulator and Excess Read/Writes

Programming the 6502 microprocessor and its relatives in assembly and other languages.
Post Reply
Magna
Posts: 3
Joined: 30 Aug 2002
Location: United States
Contact:

6502 Simulator and Excess Read/Writes

Post by Magna »

Hi, I've run up against another problem on which I'm having trouble finding information. I can't find out in detail how the NMOS works with respect to the "garbage" reads and writes it performs during certain instructions. The CMOS chips are predictable from the documentation I have, but I need to be able to simulate both chips.

Of particular interest, I'm told that sometimes the NMOS reads from a garbage address, or writes a garbage value. I'm wondering if there is any way to calculate these values, or if they are truly random. If no one knows how, I'd appreciate recommendations about how to handle this phenomena. I'm mainly interested because my simulator may have to handle memory-mapped devices.

Thanks in advance.
John West
Posts: 383
Joined: 03 Sep 2002

Re: 6502 Simulator and Excess Read/Writes

Post by John West »

>Of particular interest, I'm told that sometimes the NMOS reads from a
>garbage address, or writes a garbage value. I'm wondering if there is
>any way to calculate these values, or if they are truly random.

They're not truly random. Most of the time, instructions run at one cycle for each memory access they need. However, there are a few exceptions.

The one-byte two-cycle instructions fetch the next opcode during their second cycle.

Indexed reads that cross page boundaries read from the wrong address first. The low 8 bits of the address will be correct, but the high 8 bits have not been incremented.

Indexed writes always have the dead cycle. If a page boundary is crossed, they'll read from the wrong location (as above). If it is not crossed, the extra read is from the right location.

Read-modify-write instructions (like INC) read the original data, write it back, and then write the modified data.

Taken branches read the next opcode byte. Taken branches that cross a page boundary read the next opcode byte, then the wrong address (correct low 8 bits, current high 8 bits).

Some time ago I took traces of a few instructions with a logic analyser. These are from an NMOS 6510 in a C64. http://www.ucc.gu.uwa.edu.au/~john

64doc contains more information than you could ever want to know. http://www.atarihq.com/danb/files/64doc.txt
orac
Posts: 64
Joined: 31 Aug 2002
Location: USA

Post by orac »

Hi Everyone,

To avoid these garbage reads from I/O devices (like UART RCV) I believe
everyone puts their I/O devices in address range 0-255. This seems like
the work-around that everyone does.

Anyone agree?


Thanks,
Bye,

Orac
Magna
Posts: 3
Joined: 30 Aug 2002
Location: United States
Contact:

Post by Magna »

Thanks, that cleared up some things, especially with regard to the indexed addressing mode. My books finally came in so I think I'm set to start some serious work on my simulator.

On the suggestion to keep all your I/O ports on one page, that seems like the best way to avoid the indexed addressing mode reads. I don't know how many I/O ports are normally needed(I don't have much experience programming the 6502), but if you've got more than one page worth of ports, it might also be a good idea not to keep them on continuous pages. Either that, or simply put it in your documentation not to use indexed instructions on I/O ports.
Magna
Posts: 3
Joined: 30 Aug 2002
Location: United States
Contact:

Post by Magna »

While I've got everyone's attention, here's another question along the same vein.

I've read that the 6502 uses a sort of instruction pipelining, such that if a write isn't done on the last cycle of an instruction it pre-fetches the next opcode. My question is about the BRK, JSR, and JMP instructions. On their last cycle they modify the PC register. Some other instructions also seem to modify it on their last cycle by incrementing it. In these cases, is the next opcode still fetched? Is the wrong opcode fetched, followed by the right one?

Thanks in advance for your help.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8774
Joined: 30 Aug 2002
Location: Southern California
Contact:

Post by GARTHWILSON »

I was glad to see John West's answer on the invisible reads and writes. I have WDC's cycle-by-cycle info, but couldn't find the same info on the NMOS 6502. Unfortunately, like John alluded, the logic analyzer is about the only way to check for yourself since you can't otherwise just single-cycle the processor and look. The problem with single-cycling an NMOS 6502 is that the clock can't be held in either state long enough to take a look and the buses by hand (which I _have_ done with a CMOS 6502).

> To avoid these garbage reads from I/O devices (like UART RCV) I
> believe everyone puts their I/O devices in address range 0-255. This
> seems like the work-around that everyone does.

This would be nice for faster I/O access, but depending on how much I/O you have, this method could eat up too much of your ZP. You can also simplify (and speed up) your address-decoding logic if you don't put this kind of limitation on the circuit. With nothing but a quad NAND (74HC04), you can have 16K of RAM and 32K of ROM (or vice-versa) and ten I/O ICs with a CS and CS\.

If you use the CMOS 6502, you won't have the random read problem we're talking about avoiding here. 6502-based microcontrollers generally have a lot of I/O in ZP, but that does not seem to be common in boards using '02 microprocessors and individual I/O ICs.

Garth
cbmnut
Posts: 2
Joined: 03 Sep 2002
Location: america

west

Post by cbmnut »

Hey John,
What ever happened to Chris Jam? We had awesome 3 way programming challenges. His 38 cycles Julia plot is still a work of art...
c128,2xc64/64cycle/65cycleVIC,2x1541/8k,1571,1581
John West
Posts: 383
Joined: 03 Sep 2002

Re: west

Post by John West »

> What ever happened to Chris Jam? We had awesome 3 way
> programming challenges. His 38 cycles Julia plot is still a work of art...

If I was at work today, he'd be at the desk next to mine. We're both working on Playstation 2 games (all that C64 hacking had to be good for something). I think he's still dabbling in 6502, but the real world has a nasty habit of greatly reducing the time available for fun things.

I've never forgiven him for his 14 bit Mandelbrot iteration in less than twice the cycles of my fastest (at the time) 8 bit multiply :-)
Guest

Post by Guest »

Magna wrote:
While I've got everyone's attention, here's another question along the same vein.

I've read that the 6502 uses a sort of instruction pipelining, such that if a write isn't done on the last cycle of an instruction it pre-fetches the next opcode. My question is about the BRK, JSR, and JMP instructions. On their last cycle they modify the PC register. Some other instructions also seem to modify it on their last cycle by incrementing it. In these cases, is the next opcode still fetched? Is the wrong opcode fetched, followed by the right one?

Thanks in advance for your help.
I believe it does.

I've programmed on a Nintendo 8-bit game machine (6502 core w/o decimal mode) with a logic analyzer, and if you put a hardware breakpoint on the instruction after a conditional branch, it would always trigger. Was pretty confusing at first.

I never checked unconditional branches, but I'm guessing it probably happens there too.

Toshi
mdpenny
Posts: 50
Joined: 24 Sep 2002
Location: Essex, UK

Post by mdpenny »

WRT exactly how the 6502 executes instructions (on a cycle-by-cycle level), I have had to address (no pun intended :) ) a similar problem for an emulator I'm writing.

I ended up using a Synertek reference document - in PDF format, found on the 6502.org site - for details, as it had an appendix at the end, listing details of all the documented instructions

After this, I used Adam Vardy's and Freddy Offenga's "Undocumented Instructions" lists to fill in the unofficial instructions.

HTH,

--Martin
Post Reply