Internals of BRK/IRQ/NMI/RESET on a MOS 6502

After 35 years of measuring the behaviour of the MOS 6502 CPU to better understand what is going on, the Visual6502 simulator finally allows us insight into the chip, so we can understand what the CPU does internally. One interesting thing here is the question how the 6502 handles BRK, IRQ, NMI and RESET.

The Specification

Let’s revisit the documented part first. The 6502 knows three vectors at the top of its address space:

Signal Vector
NMI $FFFA/$FFFB
RESET $FFFC/$FFFD
IRQ/BRK $FFFE/$FFFF
  • On a RESET, the CPU loads the vector from $FFFC/$FFFD into the program counter and continues fetching instructions from there.
  • On an NMI, the CPU pushes the low byte and the high byte of the program counter as well as the processor status onto the stack, disables interrupts and loads the vector from $FFFA/$FFFB into the program counter and continues fetching instructions from there.
  • On an IRQ, the CPU does the same as in the NMI case, but uses the vector at $FFFE/$FFFF.
  • On a BRK instruction, the CPU does the same as in the IRQ case, but sets bit #4 (B flag) in the copy of the status register that is saved on the stack.

The four operations are very similar, they only differ in the location of the vector, whether they actually push data onto the stack, and whether they set the B flag.

Signal Vector Push PC and P Set B Flag
NMI $FFFA/$FFFB yes no
RESET $FFFC/$FFFD no no
IRQ $FFFE/$FFFF yes no
BRK $FFFE/$FFFF yes yes

BRK

Ignoring opcode fetches, the PLA ROM defines the following cycles of the BRK instruction (6502 Programming Manual, page 131):

  • store PC(hi)
  • store PC(lo)
  • store P
  • fetch PC(lo) from $FFFE
  • fetch PC(hi) from $FFFF

IRQ

An IRQ does basically the same thing as a BRK, but it clears the B flag in the pushed status byte. The CPU goes through the same sequence of cycles as in the BRK case, which is done like this:

If there is an IRQ pending and the current instruction has just finished, the interrupt logic in the 6502 forces the instruction register (“IR”) to “0”, so instead of executing the next instruction, the PLA will decode the instruction with the opcode 0x00 – which is BRK! Of course it has to kick in a few cycles later again to make sure a B value of 0 is pushed, but otherwise, it’s just the BRK instruction executing.

NMI

Not surprisingly, NMI is done the same way: “0” is injected into the instruction stream, but this time, some extra logic makes sure that the addresses $FFFA/$FFFB are put onto the address bus when fetching the vector.

RESET

RESET also runs through the same sequence, but it is the most different of the four cases, since it does not write the current PC and status onto the stack – but this was hacked trivially: The bus cycles exist, but the read/write line is not set to “write”, but “read” instead. The following trace was created with the transistor data from the Visual 6502 project and shows the first nine cycles after letting go of RESET:

#0 AB:00FF D:00 R/W:1 PC:00FF A:AA X:00 Y:00 SP:00 P:02 IR:00  READ $00FF = $00

Cycle 0: When a 6502 is turned on, the stack pointer is initialized with zero. The BRK/IRQ/NMI/RESET sequence pulls the instruction register (IR) to 0.

#1 AB:00FF D:00 R/W:1 PC:00FF A:AA X:00 Y:00 SP:00 P:02 IR:00  READ $00FF = $00
#2 AB:00FF D:00 R/W:1 PC:00FF A:AA X:00 Y:00 SP:00 P:02 IR:00  READ $00FF = $00
#3 AB:0100 D:00 R/W:1 PC:00FF A:AA X:00 Y:00 SP:00 P:02 IR:00  READ $0100 = $00

Cycle 3: The first stack access happens at address $0100 – a push first stores the value at $0100 + SP, then decrements SP. In the BRK/IRQ/NMI case, this would have stored the high-byte of the PC. But for RESET, it is a read cycle, not a write cycle, and the result is discarded.

#4 AB:01FF D:00 R/W:1 PC:00FF A:AA X:00 Y:00 SP:00 P:02 IR:00  READ $01FF = $00

Cycle 4: SP is now 0xFF (even if the internal state does not reflect that), so the second stack access (which would have been the low-byte of PC) targets 0x01FF. Again, the result is discarded, and SP decremented.

#5 AB:01FE D:00 R/W:1 PC:00FF A:AA X:00 Y:00 SP:00 P:02 IR:00  READ $01FE = $00

Cycle 5: SP is now 0xFE, and the third stack access, (the status register) happens at 0x01FE. SP is decremented again.

#6 AB:FFFC D:E2 R/W:1 PC:00FF A:AA X:00 Y:00 SP:FD P:06 IR:00  READ $FFFC = $E2

Cycle 6: The internal state of the CPU now shows that SP is 0xFD, because it got decremented 3 times for the three fake push operations. The low-byte of the vector is read.

#7 AB:FFFD D:FC R/W:1 PC:00FF A:AA X:00 Y:00 SP:FD P:16 IR:00  READ $FFFD = $FC

Cycle 7: The high-byte of the vector is read.

#8 AB:FCE2 D:A2 R/W:1 PC:FCE2 A:AA X:00 Y:00 SP:FD P:16 IR:00  READ $FCE2 = $A2

Cycle 8: The first actual instruction is fetched.

Since RESET is not timing critical, it doesn’t matter whether a few cycles are wasted by doing the fake stack cycles.

26 thoughts on “Internals of BRK/IRQ/NMI/RESET on a MOS 6502”

  1. Nice work analyzing the Visual6502 model. This is a common hardware design paradigm — instantiate all logic blocks of the most complex operation and then use flags to selectively disable them to implement the simpler operations. It gets much more complicated when you are gating clocks and powering down the unused logic blocks though.

    Reply
  2. Ever since I heard how the B bit works I’ve wondered it if really is stored on the chip. It is only visible to 6502 code on the stack so it doesn’t need to be on the chip. Is there a B bit on chip? Or is it just something set dynamically by the few instructions involved?

    Small typo in IRQ description – should say “B value of 0 is pushed”.

    Reply
  3. you mean to tell ‘ME’ that after 35 years…this is the best you can do…you
    get a grade of ‘F’ from me. why? nowhere in your technical article of this
    great cpu uprocessor do you use the terms ‘POWER-ON’ or ‘COLD-BOOT’.
    instead you barely use everything else. you get a grade of ‘F’. you might
    have an idea of how the 6502 works but when it comes to TECHNICAL
    WRITING…you suck to hell.

    Reply
    • its not an operating system its a cpu ffs. the only person who should be recieving an F is you, my ignorant friend.

      Reply
    • To: 6502 Engineer,
      You are obviously trying to be a Mr. Know-it-all, and coming across as a complete asshole because this article is freely written with all the good will that Michael Steil has to offer. If I grade your grammar, you will get an F, but that does not matter. What does matter is that Michael does explain the processor very accurately with the RESET functionality. The ‘POWER-ON’ function is a hardware thing that typically activates RESET for a number of cycles until Clock and Sync are correct (exact details are in the datasheet). But to the point, the CPU has no concept of ‘POWER-ON’, it simply responds to the RESET line. By the looks of things, I believe Michael has a better idea of how the 6502 works and you,despite your name, need to learn to be thankful that guys like Michael are here to set the record straight. Thank you to Michael and all the other interesting Q & A comments (but not to you Mr. 6502Engineer for wasting valuable computer bits with your nonsense).

      Reply
    • youre projecting again.. typical ignorant clown, comes in hurling insults thinking he’s the cheese when in fact , he’s just a smelly old lindburger… get a clue, einstein. 6502 engineer my ass.

      Reply
    • youre projecting again.. typical ignorant clown, comes in hurling insults thinking he’s the cheese when in fact , he’s just a smelly old lindburger… get a clue, einstein. 6502 engineer my ass.

      Reply
    • ya it is..this fool getting all bent out of shape over what.. and even more amusing, wanting to inject termonology that doesnt apply to a cpu.. first semester undergrad or grade 12 maybe? either way, with that attitude he will not go to far. he needs to stfu, listen and learn. i love interviewing these kinds of ignorants…

      Reply
  4. Why did they prevent it from writing pc and s to stack on reset? Of course these values as well as the stack pointer are not initialized when the power is switched on, so the 6502 would write 3 random bytes to some random location within the stack before jumping to the reset routine. What would be the problem?

    Reply
  5. Hello,

    You are right, it does not matter on power-up — but it could very much
    matter during debugging. The write cycles would corrupt the stack page
    (unless we also switch to a dedicated “scratch pad” memory bank when we
    pull the reset pin). Sometimes you really need to look at every single
    byte, even in the stack, in order to find a bug.

    For example, depacker routines actively use the stack page and possibly
    also the SP register as raw memory — and since they are executing with
    interrupts disabled, they are very likely not prepared to deal with any
    interference. (Under such circumstances, even an NMI can be fatal.)

    Jibaro

    Reply
  6. “Cold Boot / Bootup” are phrases more within OS terminology and from a CPU standpoint “Powerup” or “Hard Reset” are more appropriate.

    The other thing – a 6502 RESET doesn’t necessarily mean a Coldstart occurs at the OS level. Atari XL/later machines use hardware Reset for warmstart (magic numbers stored in RAM flag to the OS not to coldstart).
    Commodore Plus4 RESET button works in a similar way.

    Inadvertant writes to the stack – it’s a retrospective thing but some systems might break if that happened. Commodore OSes use lower parts of the stack as work area. Many small utilities do that on other machines.
    Of course if those writes did occur then people wouldn’t have been so eager to use the stack in that way.

    Reply
    • If you expected them to be random, then you would not have any problems. Such software would probably wipe RAM down there, anyways?

      Reply
  7. 6502Engineer, Please do yourself a favor and google “dunning kruger effect”. That’s one of the conditions you suffer from. There is help.

    Reply
    • Dunning Kruger? I was thinking “Dunno Clueless”. God, I can’t stand people that come out of nowhere just to post something mean. These articles (on average) are better than excellent. This is no exception.

      Reply
  8. What is still unclear for me whether the I flag is set during the RESET process. The 6502 datasheet states it is set but I have tested some FPGA implementations and they don’t set it during RESET. What can we see from Visual6502? Is the I flag set when RESET happens?

    Reply
    • Yes, the interrupt flag is set on RESET. Worth noting is that the other flags are not affected so they are in essence in an undefined state after RESET.

      Reply
  9. Very helpful post as I am currently debugging a 65c02/atmega frankenstein breadboard computer.

    Thanks for the info!

    Reply
  10. I don’t agree totally with the reset sequence…
    I guess your sequence is totally right at power up

    but when the reset line is pulled down for a reset without loss of power
    the content of the stack pointer was changing
    probably keeping the old value

    I discovered that while debugging a software on a replica 1 from Vince Briel
    sometimes the software was working sometimes it was crashing
    and it was crashing on sections of code previously working…

    I discovered that Wozniak monitor does not initialize the stack pointer…
    so I modified the rom to display the stack pointer after a reset and I saw the
    value of SP decreasing after each reset
    after having modified the monitor to initialize the stock my software never crashed randomly again…..

    I was using an NMOS version of the 6502 (I’ve not checked the 65c02 or 6502 from other brands)

    Reply
  11. I think you forgot to set the SP value on cycle4 and 5. They are 00, and should be FF and FE respectively.

    Reply
  12. Note that not all 6502s do the same weird stuff just before the stack accesses. The Synertek SY6502A chip I have here (date coded 8247) performs the following accesses straight after reset:

    #00: READ h9E FROM h0010
    #01: READ h9E FROM h9EFF
    #02: FETCH h9E FROM h9E9D
    #03: READ h9E FROM h9E9D

    It then gets on with the three stack operations:

    #04: READ hBE FROM h0100
    #05: READ h65 FROM h01FF
    #06: READ h9D FROM h01FE

    So a bit different at the very start.

    Reply
  13. I know this article is old, but the crap throwing is for both of you. The CPU does NOTHING until the reset line is asserted then released (won’t proceed until the reset is released).

    Have any of you seen the behavior of the original Apple ][? I have. It comes on and shows garbage on the screen (whatever was in text screen memory at the time). It then just sits there doing NOTHING. There was no POR (power on reset) on the original machine.

    In order to get anywhere, the reset key had to be pressed, then the code in the firmware would start execution once the key was released.

    SO, those making claims of “POWER-ON” and “COLD-BOOT”, those terms are bogus on the 6502. Cold boot is just the reset line being asserted and released, as is POR. It’s only when the code in the firmware is executed that any distinction is made. On the A2, the firmware checks $3F3 XORd with #$A5 and compared with $3F4. If they don’t match, the cold start firmware code is executed, if it does match, then the vector at $3F2/$3F3 is executed.

    So, as far as the processor itself is concerned, there’s no difference between a POR and Cold Boot. BOTH are NOTHING but RESET.

    Reply

Leave a Comment