I figured I should document the discoveries I made while hacking Tetris (Nintendo) & Dr. Mario (not to be confused with the SNES combo cart). They ought to be accessible outside of Discord ramblings...
These two games are compared to each other quite often, and it's valid for more reasons than one would expect. It turns out that these two games use an identical codebase based on the FDS BIOS, down to the general-purpose routines and zeropage/stack variables. It was for this reason that I was able to create disk ports so easily: TetrisFDS, dr-mario-fds
The shared codebase contributes to the following quirks:
The polling loop no longer crosses a page boundary in Tetris & Dr. Mario, throwing off the parity and causing false reads. It's very likely that the developers noticed this issue during testing and implemented the AND workaround as a "quick fix" without fully testing it. The other controller reading routines from the FDS BIOS are left intact in both games, so it's possible to use Game Genie codes to "select" an alternate routine.
I wonder what the development process was like for these games. Were these developed on the FDS to begin with, or were they developed on MMC1 with a reused codebase? FDS units are visibly being used in documentary footage taken around/during SMB3's development period, so targeting the FDS first might not have been that unusual within Nintendo.
These two games are compared to each other quite often, and it's valid for more reasons than one would expect. It turns out that these two games use an identical codebase based on the FDS BIOS, down to the general-purpose routines and zeropage/stack variables. It was for this reason that I was able to create disk ports so easily: TetrisFDS, dr-mario-fds
The shared codebase contributes to the following quirks:
- There is absolutely no safety against lag frames. Both games can freeze/crash if NMI occurs at a point that would cause temp variable conflicts ($00, $01, $48, $49, and maybe some others I haven't identified yet). Amusingly, both games implement score multipliers as repeated additions in a loop, and this is the primary contributor to lag frames. (They were definitely aware of this bottleneck - NWC Tetris masks IRQs during score addition)
- The controller reread routine consists of a bitwise AND of two consecutive controller reads. This would have worked had the DPCM conflict manifested as bit flips instead of bit deletions in the controller reports. The result is that button releases/represses can be corrupted by DPCM samples (only an issue in Dr. Mario, turn off the music to avoid this). The routine uses temp variables ($48, $49) which conflict with certain routines in both games, causing freezes that can be controlled by certain controller inputs.
- The sound driver is of the "Hip Tanaka" type with DMC playback implemented, hence the need for the controller workaround. However, Tetris doesn't use DPCM samples.
- Both games make an error when initialising the stack variables. They write #$AC to $104 instead of $103 (which is supposed to denote the first boot of a disk game). I had to fix this to make the disk ports reset properly.
The polling loop no longer crosses a page boundary in Tetris & Dr. Mario, throwing off the parity and causing false reads. It's very likely that the developers noticed this issue during testing and implemented the AND workaround as a "quick fix" without fully testing it. The other controller reading routines from the FDS BIOS are left intact in both games, so it's possible to use Game Genie codes to "select" an alternate routine.
I wonder what the development process was like for these games. Were these developed on the FDS to begin with, or were they developed on MMC1 with a reused codebase? FDS units are visibly being used in documentary footage taken around/during SMB3's development period, so targeting the FDS first might not have been that unusual within Nintendo.
Statistics: Posted by TakuikaNinja — Sun Oct 13, 2024 11:53 pm — Replies 2 — Views 176