Errata: Difference between revisions
From SNESdev Wiki
Jump to navigationJump to search
NovaSquirrel (talk | contribs) (→Video) |
NovaSquirrel (talk | contribs) No edit summary |
||
Line 3: | Line 3: | ||
== Video == | == Video == | ||
* [[Offset-per-tile]] never affects the first (leftmost) tile. | * [[Offset-per-tile]] never affects the first (leftmost) tile. | ||
* If NMI is enabled during vblank, NMI will trigger immediately. | |||
* When there are too many sprite tiles on a scanline, the SNES will drop the <em>highest priority sprites</em> instead of the lowest priority ones. | * When there are too many sprite tiles on a scanline, the SNES will drop the <em>highest priority sprites</em> instead of the lowest priority ones. | ||
* The SNES programming manual describes a situation where the Time Over flag is erroneously set when the first hardware sprite is 16x16, 32x32, or 64x64, has a horizontal position of 0-255, and other hardware sprites have negative horizontal positions. | * The SNES programming manual describes a situation where the Time Over flag is erroneously set when the first hardware sprite is 16x16, 32x32, or 64x64, has a horizontal position of 0-255, and other hardware sprites have negative horizontal positions. | ||
Line 14: | Line 15: | ||
== Audio == | == Audio == | ||
* The gauss interpolation table has some mistakes in it - see [https://problemkaputt.de/fullsnes.htm#snesapudspbrrpitch fullsnes] | * The gauss interpolation table has some mistakes in it - see [https://problemkaputt.de/fullsnes.htm#snesapudspbrrpitch fullsnes] | ||
* Writing to the first two SPC700 communication registers ($2140 and $2141) with a 16-bit write can corrupt the last two - see [https://wiki.superfamicom.org/spc700-reference#communication-ports-74] | |||
* Writing to SPC700 communication registers ($2140, $2141, $2142, $2143) at the same time the other processor reads it can result in incorrect data being read. | |||
** A SPC700 program may want to read twice and only proceed when two subsequent reads have the same value. | |||
== DMA == | == DMA == | ||
Line 23: | Line 27: | ||
== References == | == References == | ||
* https://undisbeliever.net/snesdev/registers/inidisp.html#glitches-and-hardware-bugs | |||
* [[SNES Development Manual]] Book 1, section 2-25-1: Documented Problems | * [[SNES Development Manual]] Book 1, section 2-25-1: Documented Problems |
Revision as of 06:11, 21 May 2022
This page describes quirks in the SNES hardware that programmers need to be aware of. They could be mistakes in the hardware's implementation, or just unintuitive behavior.
Video
- Offset-per-tile never affects the first (leftmost) tile.
- If NMI is enabled during vblank, NMI will trigger immediately.
- When there are too many sprite tiles on a scanline, the SNES will drop the highest priority sprites instead of the lowest priority ones.
- The SNES programming manual describes a situation where the Time Over flag is erroneously set when the first hardware sprite is 16x16, 32x32, or 64x64, has a horizontal position of 0-255, and other hardware sprites have negative horizontal positions.
- The SNES programming manual says that a hardware sprite should not have its horizontal position set to $100.
- INIDISP (register $2100) problems
- Changing the brightness is not instant. On a 3-chip SNES, it may only take a few pixels to change the brightness, but on a 1-chip SNES it may be a gradual fade that takes 72 pixels or more.
- This can be a problem for games that extend vblank by disabling rendering and enabling it several scanlines into the frame. For this use-case, it's recommended to disable rendering by writing
$8F
(or $80 ORed with whatever the desired brightness is) to INIDISP instead of$80
, so that the brightness is not changed as rendering is enabled.
- This can be a problem for games that extend vblank by disabling rendering and enabling it several scanlines into the frame. For this use-case, it's recommended to disable rendering by writing
- INIDISP early read bug: When INIDISP is written to, the PPU doesn't wait for the value to be put on the bus before attempting to read it. This means that the SNES will end up rendering about one pixel where INIDISP has been set to whatever was on the data bus before the correct value. For instructions that don't use indirect addressing, this will likely be the last byte of the instruction.
- Workaround: Use long addressing to write to INIDISP during rendering, and take advantage of how PPU registers are available in many different banks.
STA $8F2100
will put $8f on the bus before the written value, andSTA $0F2100
will put $0f on the bus before the written value, and so on.
- Workaround: Use long addressing to write to INIDISP during rendering, and take advantage of how PPU registers are available in many different banks.
- Changing the brightness is not instant. On a 3-chip SNES, it may only take a few pixels to change the brightness, but on a 1-chip SNES it may be a gradual fade that takes 72 pixels or more.
Audio
- The gauss interpolation table has some mistakes in it - see fullsnes
- Writing to the first two SPC700 communication registers ($2140 and $2141) with a 16-bit write can corrupt the last two - see [1]
- Writing to SPC700 communication registers ($2140, $2141, $2142, $2143) at the same time the other processor reads it can result in incorrect data being read.
- A SPC700 program may want to read twice and only proceed when two subsequent reads have the same value.
DMA
- On version 1 of the 5A22 chip ("S-CPU"), the chip can crash if DMA finishes right before HDMA happens. This is generally only a problem for games that want to use DMA to clear RAM, as that's the main reason to use DMA during rendering.
- On version 2 of the 5A22 chip ("S-CPU-A"), a recent HDMA transfer to/from INIDISP (Meaning that BBADn is set to zero $00) can make a DMA transfer fail. Nothing will happen and the DMA size registers (DASnL, DASnH) will be unchanged, instead of zero like they normally are after a DMA has been completed.
- Workaround: Set BBADn to $ff instead, and set the transfer pattern to 1. This will cause HDMA to write to $21ff (nothing) and then $2100 (INIDISP). Both bytes should be set to the same value to prevent the INIDISP early read bug.
- S-CPU (the first version), S-CPU-B and the 1-CHIP SNES are not affected by this bug.
- DMA cannot be used to copy from one section of the SNES's RAM to another.
References
- https://undisbeliever.net/snesdev/registers/inidisp.html#glitches-and-hardware-bugs
- SNES Development Manual Book 1, section 2-25-1: Documented Problems