Tricky-to-emulate games: Difference between revisions
From NESdev Wiki
Jump to navigationJump to search
(See also lists of games by exploited quirk) |
(The Curse of Possum Hollow) |
||
Line 7: | Line 7: | ||
* ''Battletoads & Double Dragon'' crashes at the first boss if emulated with WRAM (memory in the $6000-$7FFF range) present and initialized to $FF. ($00 does not seem to cause problems, for some reason.) The real cart does not contain WRAM and produces open bus reads. This is caused by a usually inert bug in the game's code. | * ''Battletoads & Double Dragon'' crashes at the first boss if emulated with WRAM (memory in the $6000-$7FFF range) present and initialized to $FF. ($00 does not seem to cause problems, for some reason.) The real cart does not contain WRAM and produces open bus reads. This is caused by a usually inert bug in the game's code. | ||
* ''Bee 52'' needs accurate DMC timing and relies on [[PPUSTATUS]] bit 5 (sprite overflow) as well | * ''Bee 52'' needs accurate DMC timing and relies on [[PPUSTATUS]] bit 5 (sprite overflow) as well | ||
* ''Bill & Ted's Excellent Adventure'' and a few other [[MMC1]] games depend on the mapper ignoring successive writes; see [[iNES Mapper 001]] (the talk page for that page might be informative too). ''Bill & | * ''Bill & Ted's Excellent Adventure'' and a few other [[MMC1]] games depend on the mapper ignoring successive writes; see [[iNES Mapper 001]] (the talk page for that page might be informative too). ''Bill & Ted'' also turns off and re-enables rendering midframe to switch CHR banks (e.g. in the black border above dialog boxes). | ||
* ''Burai Fighter (U)'' accesses [[PPUDATA]] during rendering to draw the scorebar. Incorrect emulation clips the scorebar to half size. See the notes on accessing [[PPUDATA]] during rendering on the [[PPU scrolling]] page. | * ''Burai Fighter (U)'' accesses [[PPUDATA]] during rendering to draw the scorebar. Incorrect emulation clips the scorebar to half size. See the notes on accessing [[PPUDATA]] during rendering on the [[PPU scrolling]] page. | ||
* ''B-Wings'' writes to CHR ROM and expects the writes to have no effect. | * ''B-Wings'' writes to CHR ROM and expects the writes to have no effect. | ||
Line 17: | Line 17: | ||
* ''Huge Insect'' depends on obscure [[OAMADDR]] ($2003) behavior; see [[PPU registers]]. | * ''Huge Insect'' depends on obscure [[OAMADDR]] ($2003) behavior; see [[PPU registers]]. | ||
* ''The Magic of Scheherazade'' maps two non-contiguous PRG-ROM pages next to each other, then executes code across the page boundary. Emulators which use pointers to fetch sequential instruction bytes from ROM will fail when taking damage in the RPG-style battles. (Use password 5W to test this easily) | * ''The Magic of Scheherazade'' maps two non-contiguous PRG-ROM pages next to each other, then executes code across the page boundary. Emulators which use pointers to fetch sequential instruction bytes from ROM will fail when taking damage in the RPG-style battles. (Use password 5W to test this easily) | ||
* ''Marble Madness'' | * ''Marble Madness'' and ''Pirates'' switch CHR banks mid-scanline to draw text boxes (e.g. at the beginning of each level). Getting these to render correctly requires fairly precise timing. | ||
* ''Micro Machines'' requires correct values when reading [[OAMDATA]] ($2004) during rendering, and also relies on proper background color selection when rendering is disabled and the VRAM address points to the palette (see the "background palette hack" on [[PPU palettes|the PPU palettes page]]). | * ''Micro Machines'' requires correct values when reading [[OAMDATA]] ($2004) during rendering, and also relies on proper background color selection when rendering is disabled and the VRAM address points to the palette (see the "background palette hack" on [[PPU palettes|the PPU palettes page]]). | ||
* ''Paperboy'' relies on the open bus behavior of controller reads and expects them to return exactly 0x40 or 0x41; see [[Standard controller]]. | * ''Paperboy'' relies on the open bus behavior of controller reads and expects them to return exactly 0x40 or 0x41; see [[Standard controller]]. | ||
Line 24: | Line 24: | ||
* ''Slalom'' does a JSR while the stack pointer is 0, so that half of the return address ends up at $0100 and the other half at $01FF. | * ''Slalom'' does a JSR while the stack pointer is 0, so that half of the return address ends up at $0100 and the other half at $01FF. | ||
* ''Super Mario Bros.'' is [https://forums.nesdev.org/viewtopic.php?p=22022#22022 probably the hardest game to emulate] among the most popular [[NROM]] games, which are generally the first targets against which an emulator author tests his or her work. It relies on JMP indirect, correct palette mirroring (otherwise the sky will be black; see [[PPU palettes]]), sprite 0 detection (otherwise the game will freeze on the title screen), the 1-byte delay when reading from CHR ROM through [[PPUDATA]] (see [[PPU registers#The PPUDATA read buffer (post-fetch)|The PPUDATA read buffer]]), and proper behavior of the nametable selection bits of [[PPUSTATUS]] and [[PPUADDR]]. In addition, there are several bad dumps floating around, some of which were ripped from pirate multicarts whose cheat menus leave several key parameters in RAM. If you're looking for a good first game for your new emulator, try anything made in 1984 or earlier, such as ''Donkey Kong''. | * ''Super Mario Bros.'' is [https://forums.nesdev.org/viewtopic.php?p=22022#22022 probably the hardest game to emulate] among the most popular [[NROM]] games, which are generally the first targets against which an emulator author tests his or her work. It relies on JMP indirect, correct palette mirroring (otherwise the sky will be black; see [[PPU palettes]]), sprite 0 detection (otherwise the game will freeze on the title screen), the 1-byte delay when reading from CHR ROM through [[PPUDATA]] (see [[PPU registers#The PPUDATA read buffer (post-fetch)|The PPUDATA read buffer]]), and proper behavior of the nametable selection bits of [[PPUSTATUS]] and [[PPUADDR]]. In addition, there are several bad dumps floating around, some of which were ripped from pirate multicarts whose cheat menus leave several key parameters in RAM. If you're looking for a good first game for your new emulator, try anything made in 1984 or earlier, such as ''Donkey Kong''. | ||
* ''Super Mario Bros. 3'' | * ''Super Mario Bros. 3'', ''RHDE: Furniture Fight'', and ''Haunted: Halloween '86: The Curse of Possum Hollow'' rely on an interaction between the [[sprite priority]] bit and the OAM index to put sprites behind the background. ''SMB3'' uses it for powerups sprouting from blocks, ''RHDE'' uses it for characters behind furniture, and ''HH86'' uses it when Donny runs behind a foreground telephone pole or falls into slime. | ||
* ''Time Lord'' is sensitive to the power-on state of the NES. The Vblank flag in PPU Status must be set for the first time within 240 scanlines, otherwise there will be a frame IRQ which is never acknowledged, which will mess up the DMC IRQs used elsewhere and cause the game to crash. | * ''Time Lord'' is sensitive to the power-on state of the NES. The Vblank flag in PPU Status must be set for the first time within 240 scanlines, otherwise there will be a frame IRQ which is never acknowledged, which will mess up the DMC IRQs used elsewhere and cause the game to crash. | ||
* ''Wizards and Warriors 3'' writes new tile graphics for the sprites at the screen split after the sprites have been drawn, but before the frame has ended. Emulators which draw the sprites all at once using graphics data from the end of the frame will have glitches in the main character's sprite. | * ''Wizards and Warriors 3'' writes new tile graphics for the sprites at the screen split after the sprites have been drawn, but before the frame has ended. Emulators which draw the sprites all at once using graphics data from the end of the frame will have glitches in the main character's sprite. |
Revision as of 19:43, 29 December 2016
At the very least the following games depend on hard-to-emulate or just obscure behavior:
- Adventures of Lolo 2, Ms. Pac-Man (Tengen), and Spelunker rely on 1 cycle NMI delay when PPUSTATUS ($2002) bit 7 gets set inside vblank (if $2002 has not been read yet), in which PPUSTATUS bit 7 can be read as true.
- Balloon Fight relies on reading the nametables through PPUDATA ($2007) to twinkle the stars in the background. (The code is at $D603.) The scroll split in "Balloon Trip" also depends to an extent on the correct number of CPU cycles from the start of NMI to the start of display, but it's not particularly picky.
- Bases Loaded II glitches after a pitch is thrown (screenshot) if writing $00 then $80 to PPUCTRL during vertical blank does not cause an additional NMI.
- Battletoads requires fairly precise CPU and PPU timing (including the cycle penalty for crossing pages) and a fairly robust sprite zero implementation. It leaves rendering disabled for a number of scanlines into the visible frame to gain extra VRAM manipulation time and then enables it. If the timing is off so that the background image appears too high or too low at this point, a sprite zero hit will fail to trigger, hanging the game. This usually occurs immediately upon entering the first stage if the timing is off by enough, and might cause random hangs at other points otherwise.
- Battletoads & Double Dragon crashes at the first boss if emulated with WRAM (memory in the $6000-$7FFF range) present and initialized to $FF. ($00 does not seem to cause problems, for some reason.) The real cart does not contain WRAM and produces open bus reads. This is caused by a usually inert bug in the game's code.
- Bee 52 needs accurate DMC timing and relies on PPUSTATUS bit 5 (sprite overflow) as well
- Bill & Ted's Excellent Adventure and a few other MMC1 games depend on the mapper ignoring successive writes; see iNES Mapper 001 (the talk page for that page might be informative too). Bill & Ted also turns off and re-enables rendering midframe to switch CHR banks (e.g. in the black border above dialog boxes).
- Burai Fighter (U) accesses PPUDATA during rendering to draw the scorebar. Incorrect emulation clips the scorebar to half size. See the notes on accessing PPUDATA during rendering on the PPU scrolling page.
- B-Wings writes to CHR ROM and expects the writes to have no effect.
- Cobra Triangle and Ironsword: Wizards and Warriors II rely on the dummy read for the sta $4000,X instruction to acknowledge pending APU IRQs.
- Crystalis, Fantastic Adventures of Dizzy, Fire Hawk, and Super Off Road do mid-frame palette changes.
- Fire Hawk, Mig 29 Soviet Fighter, and Time Lord need accurate DMC timing because they abuse APU DMC IRQ to split the screen.
- Galaxian requires proper handling of bit 4 of the P register for /IRQ.
- G.I. Joe and Mickey in Letterland turn sprite display off and MMC3 mapper relies on sprites fetches to clock the scanline counter.[1]
- Huge Insect depends on obscure OAMADDR ($2003) behavior; see PPU registers.
- The Magic of Scheherazade maps two non-contiguous PRG-ROM pages next to each other, then executes code across the page boundary. Emulators which use pointers to fetch sequential instruction bytes from ROM will fail when taking damage in the RPG-style battles. (Use password 5W to test this easily)
- Marble Madness and Pirates switch CHR banks mid-scanline to draw text boxes (e.g. at the beginning of each level). Getting these to render correctly requires fairly precise timing.
- Micro Machines requires correct values when reading OAMDATA ($2004) during rendering, and also relies on proper background color selection when rendering is disabled and the VRAM address points to the palette (see the "background palette hack" on the PPU palettes page).
- Paperboy relies on the open bus behavior of controller reads and expects them to return exactly 0x40 or 0x41; see Standard controller.
- Punch-Out!! requires fetching the 34th tile; otherwise, the ring will be glitched.
- Puzznic and Reflect World (FDS) use unofficial opcode $89, which is a two-byte NOP on 6502 and BIT #imm on 65C02. (Puzznic tasvideos discussion) The instruction in Puzznic is 89 00; emulating $89 as a single-byte NOP will trigger a BRK that causes the screen to shake.
- Slalom does a JSR while the stack pointer is 0, so that half of the return address ends up at $0100 and the other half at $01FF.
- Super Mario Bros. is probably the hardest game to emulate among the most popular NROM games, which are generally the first targets against which an emulator author tests his or her work. It relies on JMP indirect, correct palette mirroring (otherwise the sky will be black; see PPU palettes), sprite 0 detection (otherwise the game will freeze on the title screen), the 1-byte delay when reading from CHR ROM through PPUDATA (see The PPUDATA read buffer), and proper behavior of the nametable selection bits of PPUSTATUS and PPUADDR. In addition, there are several bad dumps floating around, some of which were ripped from pirate multicarts whose cheat menus leave several key parameters in RAM. If you're looking for a good first game for your new emulator, try anything made in 1984 or earlier, such as Donkey Kong.
- Super Mario Bros. 3, RHDE: Furniture Fight, and Haunted: Halloween '86: The Curse of Possum Hollow rely on an interaction between the sprite priority bit and the OAM index to put sprites behind the background. SMB3 uses it for powerups sprouting from blocks, RHDE uses it for characters behind furniture, and HH86 uses it when Donny runs behind a foreground telephone pole or falls into slime.
- Time Lord is sensitive to the power-on state of the NES. The Vblank flag in PPU Status must be set for the first time within 240 scanlines, otherwise there will be a frame IRQ which is never acknowledged, which will mess up the DMC IRQs used elsewhere and cause the game to crash.
- Wizards and Warriors 3 writes new tile graphics for the sprites at the screen split after the sprites have been drawn, but before the frame has ended. Emulators which draw the sprites all at once using graphics data from the end of the frame will have glitches in the main character's sprite.
- The Young Indiana Jones Chronicles accesses PPUDATA during rendering to perform a glitchy y scroll (to make the screen shake when cannon balls hit the ground). See the notes on accessing PPUDATA during rendering on PPU scrolling page.
Troubleshooting games
If a scroll split doesn't work, and a garbage sprite shows up around the intended split point, then the game is probably trying to use a sprite 0 hit, but either the wrong tile data is loaded or the background is scrolled to a position that doesn't overlap correctly. This could be a problem with nametable mirroring, with CHR bankswitching in mappers that support it, or with the CPU and PPU timing of whatever happened above the split. Battletoads, for one, uses 1-screen mirroring and requires exact timing to get the background scroll position dead-on.
See also
- Game bugs: These games have glitches on NES hardware, so don't go "fixing" them while breaking your emulator.
- Sprite overflow games
- Unofficial opcode games