Errata: Difference between revisions
From NESdev Wiki
Jump to navigationJump to search
(a bit of clarification about the ($xx),y's wrapping behavior, lest people get misled.) |
mNo edit summary |
||
Line 26: | Line 26: | ||
* ''JMP ($xxyy)'', or JMP indirect, does not advance pages if the lower eight bits of the specified address is $FF; the upper eight bits are fetched from ''$xx00'', 255 bytes earlier, instead of the expected following byte. | * ''JMP ($xxyy)'', or JMP indirect, does not advance pages if the lower eight bits of the specified address is $FF; the upper eight bits are fetched from ''$xx00'', 255 bytes earlier, instead of the expected following byte. | ||
* All of the zero page addressing modes wrap within the zero page. The ''$xx,x'' , ''$xx,y'', and ''($xx,x)'' addressing modes all count 254,255,0,1…; none advance 254,255,256,257… | * All of the zero page addressing modes wrap within the zero page. The ''$xx,x'' , ''$xx,y'', and ''($xx,x)'' addressing modes all count 254,255,0,1…; none advance 254,255,256,257… | ||
* The ''($xx),y'' addressing mode wraps when fetching the indirect address if the lower eight bits are stored at $FF (the upper eight bits are fetched from $0000, not $0100) | * The ''($xx),y'' addressing mode wraps when fetching the indirect address if the lower eight bits are stored at $FF (the upper eight bits are fetched from $0000, not $0100). | ||
* BRK, IRQ, or NMI can mask each other under certain conditions. (see Visual6502 wiki [http://visual6502.org/wiki/index.php?title=6502_BRK_and_B_bit] and [http://visual6502.org/wiki/index.php?title=6502_Timing_of_Interrupt_Handling] ) Not all can happen on the NES. | * BRK, IRQ, or NMI can mask each other under certain conditions. (see Visual6502 wiki [http://visual6502.org/wiki/index.php?title=6502_BRK_and_B_bit] and [http://visual6502.org/wiki/index.php?title=6502_Timing_of_Interrupt_Handling] ) Not all can happen on the NES. | ||
* Decimal mode was disconnected from the ALU in the NES's second-source 6502 to save on patent royalties. Some famiclones, however, use an authentic 6502 with a working decimal mode. (Workaround: Don't SED, and convert binary numbers to decimal when displaying them.) | * Decimal mode was disconnected from the ALU in the NES's second-source 6502 to save on patent royalties. Some famiclones, however, use an authentic 6502 with a working decimal mode. (Workaround: Don't SED, and convert binary numbers to decimal when displaying them.) |
Revision as of 17:54, 29 October 2013
The developer manuals for the Sega CD, Sega 32X, 3DO, and Atari Jaguar consoles reportedly have about five pages of hardware errata, or things in the silicon that don't work right. The NES, a third-generation console, has far less silicon than these four-and-a-half-generation consoles; therefore, it has far less space for bugs.
Video
- Reading $2002 at the exact same time that $2002.D7 goes high at the start of vertical blanking keeps $2002.D7 from going high at all that frame. (Workaround: Use NMI to wait for vertical blanking.)
- In horizontal or 4-screen mirroring, writing $2000 at the exact start of horizontal blanking may cause the PPU to start reading from the first pattern table instead of the second. (Workaround: Don't disable NMI during active picture. Instead, use a variable to lock out reentrant NMI.)
- Sprite 0 hit does not trigger at x=255.
- Filling secondary OAM causes a diagonal fetch pattern, causing both false positives and false negatives in the sprite overflow bit. (Workaround: Make sure the ninth sprite immediately follows the eighth, and use sprite overflow only to time the top of the screen, not the bottom.)
- Writes to $2003 corrupt OAM. (Workaround: Rewrite entire OAM before rendering starts, possibly using DMA initiated by writes to $4014, or rely on $2003 being 0 at end of rendering)
- Leaving the value in $2003 (either written or by autoincrement) at a value of eight or greater before rendering starts causes minor OAM corruption, copying the eight bytes at OAMADDR&~7 to the beginning of OAM.
- After reset ends (by CIC or reset button), the PPU refuses to accept data written to the registers at $2000, $2001, $2005, and $2006 for just a little more than one whole field of video.
- The VBlank flag in $2002.D7 is not cleared on reset, only power-up.
- One cannot use any read-modify-write instructions on the PPU registers (although it would only be useful on $2004 and $2007) because the 2A03 will write two different values faster than the PPU can respond.
Input
- DMC DMA during a controller read ($4016/$4017) causes double clocking, which causes bits of the report to be skipped. A common symptom is spurious presses of Right. The arcade version of Donkey Kong 3 was created before this behavior was fully characterized; it plays samples on a separate 2A03. (Workaround: If playing samples, reread the controller and make sure the reads match. If using DMC as a scanline counter, read the controller in a DMC IRQ handler.)
Audio
- APU Pulse: In sweep decrease mode, the carry input differs between the two channels.
- APU Pulse: The bottom octave doesn't work, even if sweep is turned off, unless the sweep is set to decrease mode. A lot of commercial games that use all software sweeps don't even try to fix this. (Workaround: Write $08 to $4001 and $4005.)
- APU Pulse: Writing to $4003 or $4007 to change the high byte of the period while a note is playing causes a click as the phase resets. (Workaround: Write $4003 and $4007 only when they have changed, and use sweep and $4017 writes to change the high bit.)
CPU
The 6502 has several hardware gotchas: (adapted from this 6502 forum discussion and Wikipedia's article on the 6502 ). However, it should be safer to rely on the page wrapping than on the NES-specific gotchas above because 6502 variants with different wrapping behavior also have the CPU unofficial opcodes removed, and a few licensed games rely on unofficial opcodes.
- JMP ($xxyy), or JMP indirect, does not advance pages if the lower eight bits of the specified address is $FF; the upper eight bits are fetched from $xx00, 255 bytes earlier, instead of the expected following byte.
- All of the zero page addressing modes wrap within the zero page. The $xx,x , $xx,y, and ($xx,x) addressing modes all count 254,255,0,1…; none advance 254,255,256,257…
- The ($xx),y addressing mode wraps when fetching the indirect address if the lower eight bits are stored at $FF (the upper eight bits are fetched from $0000, not $0100).
- BRK, IRQ, or NMI can mask each other under certain conditions. (see Visual6502 wiki [1] and [2] ) Not all can happen on the NES.
- Decimal mode was disconnected from the ALU in the NES's second-source 6502 to save on patent royalties. Some famiclones, however, use an authentic 6502 with a working decimal mode. (Workaround: Don't SED, and convert binary numbers to decimal when displaying them.)