Signature byte: Difference between revisions

From SNESdev Wiki
Jump to navigationJump to search
(some people think BRK is a one-byte instruction)
(revising: trying not to privilege "two-byte instruction" as many (not some) assemblers do make BRK 1 byte, make it clear that COP as "co-processor" is not SNES-relevant, explain more about how BRK/COP interrupts may be handled)
Line 1: Line 1:
In 65x parlance, a '''signature byte''' is the second byte of certain two-byte instructions, including:
In 65x parlance, a '''signature byte''' is the second byte that follows certain instructions, including:


* BRK
* <tt>BRK</tt>
* COP
* <tt>COP</tt>
* WDM
* <tt>WDM</tt>


When a programmer has sprinkled many BRKs throughout a large codebase, it can be difficult to tell which BRK breakpoint has been tripped.  That is why it can be useful to specify a unique signature byte after BRK, allowing up to 256 unique breakpoints.
Each of these instructions will normally advance the PC by two bytes, even though the hardware does not make any direct use of the second "operand" byte.


For co-processor empowerment, the signature byte can be used to specify which command the co-processor should run.
For this reason, these instructions have been treated both as one-byte<ref>Eyes & Lichty</ref> and two-byte instructions in various reference documents and assemblers.


The signature byte following WDM was originally intended to extend the 65c816's opcode space and allow for up to 256 more unique instructions, but this was never implemented. As of 2023 when using Mesen for SNES homebrew, WDM can be used as an even simpler (because it does not need a handler routine) breakpoint by checking the "Break on.." WDM checkbox in the debugger.
A software response to <tt>BRK</tt> or <tt>COP</tt> may use the return address on the stack to deduce the location of the operand byte and inspect it.
* <tt>BRK</tt> with an explicit operand can be used for error codes, or as a compact system call dispatch, handled by the [[CPU vectors|BRK vector]] at $FFF6.
* <tt>COP</tt> can be used in the same way as BRK, but it is handled by the [[CPU vectors|COP vector]] at $FFF4 instead.


Some literature (such as the Eyes & Lichty manual) describes BRK as a one-byte instruction because some assemblers do not require the programmer to specify the signature byte. This way of thinking about BRK has the disadvantage of needing to pad the following byte with a dummy value, or remember that the program counter was incremented by two before returning from an interrupt.
Alternatively, if the signature byte is not needed, a BRK or COP handler may wish to decrement the return address on the stack before <tt>RTI</tt>, returning as if it were a one-byte instruction.
 
The <tt>COP</tt> instruction was intended for use with a co-processor, for which the signature byte could indicate a command to send to the co-processor. However, there is no hardware to support this usage on the SNES, and it is simply a second software interrupt, equivalent to BRK.
 
The <tt>WDM</tt> instruction was reserved for future use, but was never actually used. It is simply a 2-byte alternative to <tt>NOP</tt>. Mesen's debugger provides a break-on-WDM instruction which can make it convenient as an emulator-only breakpoint.
 
There is no standard for how assemblers treat BRK or COP. If BRK emits only 1 byte, a signature byte can be added manually with a data byte following.
* ca65 in .p816 mode has an optional signature for BRK, allowing either 1 or 2 bytes. COP and WDM always require the signature byte.
 
Though the 65C816 has no unused opcodes, on the 6502 many were left open with unspecified behaviour. This allowed the use of "unofficial" illegal opcodes, including several <tt>NOP</tt> variants with an unused signature byte. See: [//www.nesdev.org/wiki/CPU_unofficial_opcodes NESDev: CPU unofficial opcodes]
 
== References ==
<References/>

Revision as of 21:48, 24 February 2023

In 65x parlance, a signature byte is the second byte that follows certain instructions, including:

  • BRK
  • COP
  • WDM

Each of these instructions will normally advance the PC by two bytes, even though the hardware does not make any direct use of the second "operand" byte.

For this reason, these instructions have been treated both as one-byte[1] and two-byte instructions in various reference documents and assemblers.

A software response to BRK or COP may use the return address on the stack to deduce the location of the operand byte and inspect it.

  • BRK with an explicit operand can be used for error codes, or as a compact system call dispatch, handled by the BRK vector at $FFF6.
  • COP can be used in the same way as BRK, but it is handled by the COP vector at $FFF4 instead.

Alternatively, if the signature byte is not needed, a BRK or COP handler may wish to decrement the return address on the stack before RTI, returning as if it were a one-byte instruction.

The COP instruction was intended for use with a co-processor, for which the signature byte could indicate a command to send to the co-processor. However, there is no hardware to support this usage on the SNES, and it is simply a second software interrupt, equivalent to BRK.

The WDM instruction was reserved for future use, but was never actually used. It is simply a 2-byte alternative to NOP. Mesen's debugger provides a break-on-WDM instruction which can make it convenient as an emulator-only breakpoint.

There is no standard for how assemblers treat BRK or COP. If BRK emits only 1 byte, a signature byte can be added manually with a data byte following.

  • ca65 in .p816 mode has an optional signature for BRK, allowing either 1 or 2 bytes. COP and WDM always require the signature byte.

Though the 65C816 has no unused opcodes, on the 6502 many were left open with unspecified behaviour. This allowed the use of "unofficial" illegal opcodes, including several NOP variants with an unused signature byte. See: NESDev: CPU unofficial opcodes

References

  1. Eyes & Lichty