A mistake?
The instruction $89
on the 6502 is a two-byte NOP. Based on adjacent instructions in the opcode matrix, especially LDA #ii
($A9 ii
), it would have been STA #ii
, a store to an immediate value, which makes no sense. On the 65C02, this instruction is changed to BIT #ii
, which almost behaves as a two-byte NOP
. One hypothesis is that a programmer working on both NES projects and projects for some 65C02-based system forgot that the original 6502 lacked BIT #ii
, but because the instruction does so little anyway, the programmer didn't notice any difference.
Clockslide
A clockslide is a is a sequence of instructions that wastes a small constant amount of cycles plus one cycle per executed byte, no matter whether it's entered on an odd or even address.
With official instructions, one can construct a clockslide from CMP instructions: ... C9 C9 C9 C9 C5 EA
:
- Disassemble from the start and you get
CMP #$C9 CMP #$C9 CMP $00EA
(6 bytes, 7 cycles).
- Disassemble one byte in and you get
CMP #$C9 CMP #$C5 NOP
(5 bytes, 6 cycles).
A calculated start address into a clockslide can be used with indirect jumps (JMP (aaaa)
or LDA highbyte PHA LDA lowbyte PHA RTS
) to precisely control timing, such as when playing PCM audio or sending video register changes to the PPU in a raster effect.
It's even more important on the Atari 2600, where the whole screen is a raster effect.
CMP
has a side effect of destroying most of the processor status flags, but unofficial instructions that skip one byte can be used to preserve them.
For example, replace $C9
(CMP
) with $89
or $80
, which skips one immediate byte, and replace $C5
with $04
, $44
, or $64
, which reads a byte from zero page and ignores it.
Watermarking
As LOIS 16192 mentioned, the official NOP instruction ($EA
) can be inserted at random places in a particular subroutine that isn't an inner loop. This can identify authorship of a piece of code in a way similar to trap streets. But it adds even more entropy to use unofficial NOPs ($1A
, $3A
, $5A
, $7A
, $DA
, or $FA
), two-byte NOPs ($80 ii
, $82 ii
, $89 ii
, $C2 ii
, $E2 ii
), or two-byte NOPs that read the zero page ($04 dd
, $44 dd
, or $64 dd
). And now that NES games are manufactured with flash memory instead of mask ROM, each cartridge can have a slightly different pattern of NOPs. This can help identify exactly which copy of a game was leaked to the warez scene.
As with clockslide, watermarking can also be done without unofficial instructions. But because of the cost of copying a mask ROM, this sort of watermarking wasn't actually used in games during the original commercial era of the Famicom and NES (1983 to 1996). It may be in use in homebrew-era games (2010 and later).
Sources