OpenDiskSysROM continues FreeDiskSysROM by James Athey, which has not changed since 2020. It keeps that project's history, goal, rules and license (LGPL-3.0); the work here adds what was missing to run games: the disk I/O routines and the boot loader. It is developed for Retrolarium, whose studio plays Famicom Disk System games in MAME without asking for Nintendo's BIOS.
Files James Athey wrote keep his copyright notice; files changed or added here say so in their header.
This project has one goal - a compatible re-implementation of the Famicom Disk System BIOS under an OSS license. Unlike the Famicom console itself, which has no program ROM built-in, the Famicom Disk System includes an 8 KiB PRG-ROM containing disk I/O routines, VRAM transfer routines, joypad reading code, an animation featuring Mario and Luigi when no disk is present in the drive, and more. The code, data, graphics, music, and animation contained in the original BIOS are copyrighted by Nintendo.
OpenDiskSysROM aims to provide a replacement for the original FDS BIOS that can be freely redistributed and that is capable of running all published FDS software.
Famicom and NES emulators historically require a dump of the Famicom Disk System BIOS to be able to emulate FDS titles. Emulators can ship OpenDiskSysROM with their installers instead of requiring end-users to either copy the ROM out of their own FDS hardware or breaking copyright law by downloading a BIOS rip from elsewhere on the Internet.
Modern hardware clones of the FDS RAM Adapter or FPGA re-implementations of the entire Famicom Disk System also need a BIOS.
Every documented entry point is implemented. The disk routines boot and run Super Mario Bros., All Night Nippon Super Mario Bros. and Super Mario Bros. 2 in MAME, and their writes were checked by reading them back.
| Address | Name | # of Games | Implemented |
|---|---|---|---|
| $e149 | Delay131 | ✅ | |
| $e153 | Delayms | ✅ | |
| $e161 | DisPFObj | ✅ | |
| $e16b | EnPFObj | ✅ | |
| $e171 | DisObj | ✅ | |
| $e178 | EnObj | ✅ | |
| $e17e | DisPF | ✅ | |
| $e185 | EnPF | ✅ | |
| $e18b | NMI | ✅ | |
| $e1b2 | VINTWait | ✅ | |
| $e1c7 | IRQ | ✅ | |
| $e1f8 | LoadFiles | ✅ | |
| $e237 | AppendFile | ✅ | |
| $e239 | WriteFile | ✅ | |
| $e2b7 | CheckFileCount | ✅ | |
| $e2bb | AdjustFileCount | ✅ | |
| $e301 | SetFileCount1 | ✅ | |
| $e305 | SetFileCount | ✅ | |
| $e32a | GetDiskInfo | ✅ | |
| $e3da | AddYtoPtr0A | ✅ | |
| $e3e7 | GetHardCodedPointers | ✅ | |
| $e3ea | GetHardCodedPointersWriteProtected | ✅ | |
| $e445 | CheckDiskHeader | ✅ | |
| $e484 | GetNumFiles | ✅ | |
| $e492 | SetNumFiles | ✅ | |
| $e4a0 | FileMatchTest | 0 | ✅ |
| $e4da | SkipFiles | 0 | ✅ |
| $e4f9 | LoadData | ✅ | |
| $e506 | ReadData | ✅ | |
| $e5b5 | SaveData | ✅ | |
| $e64d | WaitForDriveReady | ✅ | |
| $e685 | StopMotor | ✅ | |
| $e68f | CheckBlockType | ✅ | |
| $e6b0 | WriteBlockType | ✅ | |
| $e6e3 | StartXfer | ✅ | |
| $e706 | EndOfBlockRead | ✅ | |
| $e729 | EndOfBlkWrite | ✅ | |
| $e778 | XferDone | ✅ | |
| $e794 | Xfer1stByte | ✅ | |
| $e7a3 | XferByte | ✅ | |
| $e7bb | VRAMStructWrite | ✅ | |
| $e844 | FetchDirectPtr | ✅ | |
| $e86a | WriteVRAMBuffers | ✅ | |
| $e8b3 | ReadIndividualVRAMBytes | ✅ | |
| $e8d2 | PrepareVRAMString | ✅ | |
| $e8e1 | PrepareVRAMStrings | ✅ | |
| $e94f | GetVRAMBufferByte | ✅ | |
| $e97d | Pixel2NamConv | ✅ | |
| $e997 | Nam2PixelConv | ✅ | |
| $e9b1 | Random | ✅ | |
| $e9c8 | SpriteDMA | ✅ | |
| $e9d3 | CounterLogic | ✅ | |
| $e9eb | ReadPads | ✅ | |
| $ea1a | ReadDownPads | ✅ | |
| $ea1f | ReadOrDownPads | ✅ | |
| $ea36 | ReadDownVerifyPads | ✅ | |
| $ea4c | ReadOrDownVerifyPads | ✅ | |
| $ea68 | ReadDownExpPads | ✅ | |
| $ea84 | VRAMFill | ✅ | |
| $ead2 | MemFill | ✅ | |
| $eaea | SetScroll | ✅ | |
| $eafd | JumpEngine | ✅ | |
| $eb13 | ReadKeyboard | 0 | ✅ |
| $ebaf | LoadTileset | ✅ | |
| $ec22 | UploadObject | ✅ | |
| $ee17 | StartMotor | ✅ |
On a cold start the BIOS clears the console's state and goes to the boot loader; on a soft reset with a game in RAM ($0102/$0103 = $35/$53 or $35/$AC) it starts that game through its reset vector again. The boot loader shows INSERT A DISK in the BIOS font until a disk is in the drive, then loads every file whose ID is not above the disk's boot file code. A failed load shows DISK ERROR with the error number for about two seconds and tries again. There is no animation: the original's Mario and Luigi are Nintendo's.
The scripts in tests/ assemble the BIOS, start MAME's fds system with it
from a private ROM path and check what the routines did through MAME's Lua
interface. Each takes a disk image and MAME (--mame or the MAME variable),
and asm6f (--asm6f, the ASM6F variable or asm6f on PATH):
| Script | Checks |
|---|---|
boot_test.py |
the boot loader puts every boot file in place |
boot_error_test.py |
the DISK ERROR screen, then a retry that boots the intact disk |
loadfiles_test.py |
LoadFiles on a running game, including a wrong disk ID |
writefile_test.py |
WriteFile, AppendFile, the file count calls and GetDiskInfo |
lowlevel_test.py |
the block calls a game's own loader uses, with interrupts enabled |
keyboard_test.py |
ReadKeyboard with and without MAME's Family BASIC keyboard |
uploadobject_test.py |
UploadObject against a model of the object structure |
MAME keeps disk writes in memory, so the image is never changed. In a window (the tests run without one) MAME first asks for a key press, because the BIOS is not the one it knows.
To build, use asm6f.
asm6f freedisksys.asm build/opendisksys.bin
MAME and most emulators look for the BIOS as disksys.rom or, in MAME's fds
ROM set, rp2c33a-01a.bin.
The -l flag is very useful for development - it shows the addresses assigned
to each instruction, so you can easily see how much room remains for a given
subroutine.
Rules:
- Do not even look at a disassembly of the original FDS BIOS.
- Only contribute code to which you hold the copyright or which is already under a compatible license.
OpenDiskSysROM, like FreeDiskSysROM, is licensed under the GNU LGPL v3. The intent in using this license is to allow anyone to replace the 8 KiB official FDS BIOS with OpenDiskSysROM, whether for commerical or non-commercial purposes, so long as the source of OpenDiskSysROM (including any modifications) is made available to the end-user under the same license.
Although the Famicom does not have an OS or any concept of dynamic linking, the FDS BIOS is analogous to a system library in practice. FDS titles, FDS emulators, and FDS clone systems are all permitted to utilize OpenDiskSysROM without regard to or changes to the licenses of their own code.