Embedded system Fun Blog
























































Find out all the best information, libraries and circuit about the latest Embedded systems.

Saturday 7 January 2012

The famous 6502 'B' flag and BRK opcode

.from: http://nesdev.parodius.com/the%20%27B%27%20flag%20&%20BRK%20instruction.txt

6502 'B' flag & BRK opcode
Brad Taylor


The B flag
----------
No actual "B" flag exists inside the 6502's processor status register. The B 
flag only exists in the status flag byte pushed to the stack. Naturally, 
when the flags are restored (via PLP or RTI), the B bit is discarded.

Depending on the means, the B status flag will be pushed to the stack as 
either 0 or 1.

software instructions BRK & PHP will push the B flag as being 1.
hardware interrupts IRQ & NMI will push the B flag as being 0.


A note on the BRK opcode
------------------------
Regardless of what ANY 6502 documentation says, BRK is a 2 byte opcode. The 
first is #$00, and the second is a padding byte. This explains why interrupt 
routines called by BRK always return 2 bytes after the actual BRK opcode, 
and not just 1.

6502 coded breakpoint handlers that treat BRK as a 1-byte opcode have to 
manually decrement the return address stored on the stack before executing a 
RTI:

 tsx; get stack pointer into index register
 sec; ensure carry is set before subtracting

;decrement low byte of rtn address
 lda $0102,x
 sbc #$01
 sta $0102,x

;decrement high byte of rtn address (if no carry)
 lda $0103,x
 sbc #$00
 sta $0103,x

 rti; return to byte after BRK opcode

Of course, none of this code (except "rti") is neccessary if BRK is 
assembled as a 2-byte opcode.


BRK in detail
-------------
In the 7 clock cycles it takes BRK to execute, the padding byte is actually 
fetched, but the CPU does nothing with it. The diagram below will show the 
bus operations that take place during the execution of BRK:

cc addr data
-- ---- ----
1 PC 00 ;BRK opcode
2 PC+1 ?? ;the padding byte, ignored by the CPU
3 S PCH ;high byte of PC
4 S-1 PCL ;low byte of PC
5 S-2 P ;status flags with B flag set
6 FFFE ?? ;low byte of target address
7 FFFF ?? ;high byte of target address


making use of the padding byte
------------------------------
With some external hardware, it is possible to take advantage of the padding 
byte. For example, a good use for this byte would be to index an interrupt 
vector to swap into addresses $FFFE & $FFFF, so that a 256 software 
interrupt scheme could be implemented.

On regular 6502's, BRK could be detected with an 8-input "OR" gate (tied to 
the data bus), gated with "SYNC". The padding byte would then appear on the 
data bus one clock cycle after detecting BRK.

There is no SYNC signal available on the NES's 2A03, so obtaining the 
padding byte is a little trickier, but still possible. The first step is to 
have an 8-bit latch that is loaded with the contents of the data bus on 
every clock cycle _except_ during write cycles. Next, hardware must be 
implemented to detect 3 consecutive write cycles to the stack (only 
interrupts can do 3 writes in a row), plus make sure that bit 4 during the 
3rd stack write is set (1) (this 3rd write contains the B flag, which will 
be set if the interrupt was caused by BRK). Finally, if all these tests 
pass, this means the BRK instruction is in progress, and the latch register 
contains the valid padding byte. The latched value can now be used to swap 
in the values to use for the next 2 clock cycles (the BRK vector fetch). 
Note that since all of this won't happen unless BRK is executed, IRQ & BRK 
routines will effectively be seperate from each other (i.e., IRQ will still 
use the vector at $FFFE, but BRK will now use a 512-byte jump table at e.g., 
$8000).

EOF





No comments:

Post a Comment