The Nintendo Gigaleak preserves a surprisingly complete Super Famicom disk and I/O environment inside the Super Mario Kart source directory.
This is the SFX-DOS stack: a SNES-side support layer for floppy access, directory walking, keyboard and serial I/O, printer output, and text-console interaction.
It survives inside the Mario Kart leak because the game’s editors were using it directly for save and load operations.
The biggest takeaways from the surviving files are:
DIR, DEL, REN, CHDISK, LOAD, and SAVEIf you are new to low-level SNES development terms, this quick glossary should help:
Z8530 serial communications controller used for keyboard and RS-232 handling.uPD72069 floppy disk controller used for physical disk access.uPD71055 programmable peripheral interface used here for printer I/O signaling.Taken together, the files look like a compact operating environment for development hardware:
| Layer | Main file | Role |
|---|---|---|
| System entry layer | sfxdos.asm |
Central dispatcher, interrupt wrapper, and COP-call API |
| File-system layer | fileio.asm |
Disk format, free space, directory scans, load/save, purge, and rename |
| Raw hardware layer | fdcdrv.asm, sccdrv.asm, ppidrv.asm |
Floppy, serial/keyboard, and printer drivers |
| Console UI layer | condrv.asm |
Text-console screen, cursor, input, and print routines |
| Operator shell | ccp_main.asm |
A command-style front end that calls into the DOS API |
The overall shape is easiest to grasp as a layered stack:
flowchart TD
A["<b>ccp_main.asm</b><br>operator shell and command prompt"] --> B["<b>condrv.asm</b><br>text console and screen control"]
B --> C["<b>sfxdos.asm</b><br>COP API and resident DOS services"]
C --> D["<b>fileio.asm</b><br>logical file system and directory layer"]
C --> E["<b>fdcdrv.asm</b><br>uPD72069 floppy driver"]
C --> F["<b>sccdrv.asm</b><br>Z8530 keyboard and RS-232"]
C --> G["<b>ppidrv.asm</b><br>uPD71055 printer I/O"]
H["<b>Mario Kart Editors</b><br>ed_dos1.asm / ed_dos2.asm"] --> C
The dates are useful too:
fileio.asm is dated 21 August 1991sfxdos.asm is dated 29 October 1991That timing makes the SFX-DOS code look like an older shared development layer that the Mario Kart team was still building on later.
The relevant files survive under the Gigaleak path:
other/SFC/ソースデータ/MarioKart
The important modules are:
sfxdos.asmfileio.asmfdcdrv.asmsccdrv.asmppidrv.asmcondrv.asmccp_main.asmed_dos1.asmed_dos2.asmThat location matters. This is not an abstract SDK disk on its own. It is a shared system layer surviving inside a real game workspace, with the Mario Kart editors still calling into it.
The heart of the stack is sfxdos.asm.
Its header calls it a Super Famicom Disk Operation System special version, programmed by Y. Nishida on 29 October 1991.
The file exports:
DOS_Entry - the resident bootstrap path that clears work RAM, installs vectors, and initializes the driversCOP_Entry - the software-interrupt gateway that dispatches byte-sized COP service callsIRQ_Entry - the resident IRQ (normal hardware interrupt) trampoline that hands control to the active DOS or user interrupt handlerNMI_Entry - the resident NMI (non-maskable, high-priority interrupt) trampoline used for DOS-side text refresh and user NMI handoffThat is already a strong clue that this is a resident support environment rather than a grab bag of routines.
On the 65c816 CPU, COP is a software interrupt instruction.
It behaves a bit like a built-in trap into a supervisor or monitor layer: the caller executes cop with a small immediate value, and the system-side handler reads that value and decides which service routine to run.
That matters here because the Mario Kart editor files are not jumping straight into a long list of internal SFX-DOS labels.
They are making compact cop calls like cop 15h and cop 16h, and sfxdos.asm turns those byte-sized service numbers into real disk, console, and file-system operations.
So when this page refers to the COP API, it means a software-interrupt gateway built on the CPU’s own COP instruction, not a separate coprocessor.
The most important architectural detail is COP_Entry.
It reads a function number from the instruction stream and dispatches through a Function_call$ jump table, effectively giving the Super Famicom code a callable DOS API.
The visible calls include:
| Code | Meaning | Target routine |
|---|---|---|
00 |
DOSRST |
DOS_Reset |
01 |
DOSSTP |
DOS_Stop |
02 |
TXTRST |
Text_Reset |
03 |
CONSNS |
Sense_Keyboard |
04 |
CONIN |
Input_Console |
05 |
CONOUT |
Output_Console |
06 |
CONRST |
Flush_Keyboard |
07 |
PRNSNS |
Sense_Printer |
08 |
PRNOUT |
Output_Printer |
09 |
AUXSNS |
Sense_RS232C |
10 |
AUXIN |
Input_RS232C |
11 |
AUXOUT |
Output_RS232C |
12 |
AUXRST |
Set_RS232C |
13 |
INPUT |
Input_String |
14 |
PRINT |
Print_String |
15 |
DSKRST |
Init_FDC_Driver |
16 |
FORMAT |
Disk_Format |
17 |
DSKFRE |
Disk_Free |
18 |
DIRFST |
Files_First |
19 |
DIRNXT |
Files_Next |
20 |
SELDSK |
Select_Drive |
21 |
LOAD |
Load_File |
22 |
SAVE |
Save_File |
23 |
PURGE |
Purge_File |
24 |
RENAME |
Rename_File |
25 |
EXEC |
documented in doscall.h, but not implemented in the surviving special version source |
That is one of the most important preservation details in the whole stack. The SNES-side tools were not doing floppy access through one-off hardcoded routines. They were calling into a stable service layer.
DOS_Entry behaves like a boot or reset path for the whole environment.
On entry it:
7E:1E00h through 7E:2FFFhThat startup flow is easier to scan as a sequence:
flowchart TD
A["<b>Set workspace</b><br>initialize direct-page state"] --> B["<b>Clear WRAM</b><br>7E:1E00h to 7E:2FFFh"]
B --> C["<b>Save user vectors</b><br>copy IRQ and NMI handlers"]
C --> D["<b>Init drivers</b><br>SCC, PPI, and FDC"]
D --> E["<b>Install DOS IRQ</b><br>activate SFX-DOS IRQ vector"]
Then the smaller lifecycle hooks round the system out:
DOS_Reset enables SCC and FDC interrupts and turns the DOS switch back onDOS_Stop disables those interrupts and restores the user vectorsText_Reset initializes the console driver and points NMI handling at the console-side text refresh pathThat makes SFX-DOS feel much closer to a resident development service than a normal game library.
If you are not used to low-level console terms: an interrupt is a hardware signal that briefly pauses the current code so the system can run a small handler.
IRQ is the regular interrupt path used for routine hardware events, while NMI is a special high-priority interrupt that cannot be disabled and is commonly used for time-critical work.
IRQ_Entry and NMI_Entry are smaller than DOS_Entry, but they still matter because they show how SFX-DOS sits between the running tool code and the machine’s interrupt flow.
IRQ_Entry jumps through the current IRQ vector, while NMI_Entry jumps through the current NMI vector.
In practice that means the resident layer can swap in its own handlers like Sfxdos_IRQ and Sfxdos_NMI, then later restore the user’s original vectors when DOS services are stopped.
That is one more sign that this was a resident environment rather than a pile of callable helpers. It owned the interrupt handoff path as well as the disk and console services.
One nice extra clue survives elsewhere in the Gigaleak.
Under the Yoshi’s Island tool tree there is a shared sfxdos.h, doscall.h, and sfxdos.doc, which document the same broader SFX-DOS package family reflected in the Mario Kart copy.
Those files fill in the memory map behind the code very neatly. The main DOS workspace is defined at:
DOS_variable = 001E00hand the big working buffers live at fixed WRAM addresses:
| Buffer | Address | Purpose |
|---|---|---|
Disk_FAT |
7E2000h |
FAT buffer |
Disk_Directory |
7E2800h |
directory-sector buffer |
Disk_Sector |
7E2C00h |
cluster or sector read/write buffer |
Text_VRAM |
7E3000h |
text-console screen buffer |
That layout is easier to picture visually:
flowchart TD
A["<b>001E00h</b><br>DOS_variable workspace"] --> B["<b>7E2000h</b><br>Disk_FAT"]
B --> C["<b>7E2800h</b><br>Disk_Directory"]
C --> D["<b>7E2C00h</b><br>Disk_Sector"]
D --> E["<b>7E3000h</b><br>Text_VRAM"]
That is useful because it turns the implementation from “somewhere in RAM” into a very explicit memory layout.
The header also explains one of the more confusing parts of the code: several buffers intentionally overlap.
For example:
directory_entry and Line_buffer share the same base regionsearch_filename and access_filename share the same regionrename_filename, data_address, and data_length sit on top of the same command-parameter spaceThat sounds messy, but it fits the way the shell and DOS layer operate. They do not need all of those structures at once, so the package reuses the same small DOS workspace for different command phases.
In other words, the overlap is not accidental sloppiness. It is part of the design.
This API table also explains the Mario Kart editor files more precisely than a simple “disk load” label does.
The editor bridge files do not know how to talk to the floppy controller directly.
They fill out shared DOS-side buffers, then hand off to the service layer with the same cop mechanism used everywhere else in SFX-DOS.
For example:
ed_dos1.asm and ed_dos2.asm both build filenames into 1ee0h1ef0h1ef4hcop 15h or cop 16hThat means the editor save and load paths are best understood as clients of SFX-DOS rather than bespoke game-only routines.
doscall.h is also a helpful small artifact because it shows how the package was meant to be used from application code.
It defines symbolic names like:
_DIRFST_DIRNXT_LOAD_SAVE_PURGE_RENAME_INPUT_PRINT_EXECand then wraps them in a simple:
DOS macro funccop funcThat is a tiny detail, but it makes the calling convention feel much more like a documented platform service and much less like a pile of ad hoc assembly entry points.
One interesting wrinkle is that the shared macro file and documentation describe an EXEC function at call 25, but the surviving Mario Kart and Yoshi’s Island special version source copies stop at RENAME.
That suggests the broader SFX-DOS package may once have had an execution or launcher-style service that is not present in this trimmed source branch, or that the documentation and macro layer were kept slightly ahead of the specific in-project build that survived here.
fileio.asm is where the stack becomes recognizably DOS-like.
Its header calls it the file I/O module, dated 21 August 1991.
It exports the practical file operations:
Disk_FormatDisk_FreeFiles_FirstFiles_NextSelect_DriveLoad_FileSave_FilePurge_FileRename_FileOne of the most interesting details in fileio.asm is that it carries full logical-disk layout tables for multiple media formats.
| Format | Sector size | Notable layout details |
|---|---|---|
2HD |
1024 bytes |
1 sector per cluster, 8 sectors per track, 1223 clusters |
2DD 8-sector |
512 bytes |
2 sectors per cluster, 8 sectors per track, 636 clusters |
2DD 9-sector |
512 bytes |
2 sectors per cluster, 9 sectors per track, 715 clusters |
The tables define:
That tells us SFX-DOS was not relying on opaque disk read and write commands. It was carrying a full logical file-system layer on top of the raw floppy controller.
The higher-level file operations go further than a game editor strictly needed.
Files_First and Files_Next support directory walking, and Rename_File actually rewrites directory entries with a new filename.
That is a useful clue about the intended environment. This stack was designed for browsing and managing files, not only loading one known block from one known disk.
fileio.asm also makes the directory structure much more concrete.
The code consistently treats each directory entry as a 32-byte record and looks for two special leading-byte values:
00h means end of directoryE5h means a deleted entry that can be reusedThat lines up neatly with the rest of the shell behavior.
DIR walks those 32-byte entries, DEL marks the first byte as E5h, and create or rename operations write new 11-byte 8.3 names back into the same fixed-size entry slots.
Several offsets are especially useful:
| Directory field | Offset | What the code uses it for |
|---|---|---|
| Filename | +0 to +10 |
8.3 name and extension |
| Attributes | +11 |
checked for normal file and read-only flags |
| First cluster | +26 |
starting cluster for file reads and writes |
| File size | +28 to +31 |
displayed by DIR and updated during writes |
That is one of the nicest low-level details in the whole package because it shows the shell and file layer are both operating on a real directory-entry format, not an abstract filename database.
The search logic in Sch_fname_first and Sch_fname_next is more sophisticated than the shell summary alone suggests.
The search process:
Disk_DirectoryCompare_fname? as a wildcard matchnotused_dir_idxThat last point is important. SFX-DOS is not only walking one small in-memory table. It is paging through the root directory sector by sector and keeping enough state to both find existing files and identify where a new file could be created later.
So when DIR or LOAD or SAVE asks for a file, the code is using a real wildcard-aware directory scan rather than a single fixed-file lookup.
The basic file-management commands are also more concrete in fileio.asm than they first appear.
Purge_File does not just remove a name from a list.
It:
current_clusterE5hUnlink_FATRename_File is similarly literal.
It swaps the old and new 11-byte names in buffers, checks that the new name does not already exist, then overwrites the filename bytes directly inside the directory entry.
That makes SFX-DOS feel much more like a full file system than a convenience wrapper. It is maintaining directory structure and allocation data coherently across create, delete, rename, and overwrite cases.
The FAT handling is one of the most interesting parts of fileio.asm.
The cluster logic is packed differently for even and odd cluster numbers:
You can see that pattern in:
Next_ClusterLink_FATSearch_VoidClusUnlink_FATDisk_FreeThat odd/even split is exactly what you would expect from a 12-bit FAT-style allocation table. The code is manually packing and unpacking cluster entries with shifts and masks rather than treating the FAT as a table of simple 16-bit words.
That is a very strong preservation detail. It means SFX-DOS was not only “DOS-like” in spirit. Its allocation logic is implementing a genuine packed FAT design.
The allocation side is especially readable once the helper names are lined up.
Search_VoidClus:
Link_FAT:
Unlink_FAT:
FF8h or aboveThat gives the file layer a very clear lifecycle:
So the storage model is not only “cluster based.” It is a proper linked allocation system with explicit end-of-chain handling.
The read and write paths in fileio.asm make the shell-level LOAD and SAVE commands much more tangible.
The flow is:
File_Open validates the disk, mounts the FAT, and locates or creates the directory entryFile_Read and File_Write stream through one cluster at a timeDisk_Sector bufferSet_TrkSec1 converts a cluster number into a logical sector, then into track and sector values for the floppy driverThat conversion path is especially important because it ties the logical file system to the physical disk geometry. Clusters are not abstract IDs. They are being translated into real floppy track and sector operations based on the active media format.
The format path is also more complete than the shell alone suggests.
Logical_Format in fileio.asm does not stop at low-level media formatting.
After the raw disk steps, it:
Initial_RootDirInitial_FATInitial_RootDir fills the directory area with deleted-entry style markers, while Initial_FAT seeds the FAT header with the media code and the initial reserved entries.
That is another clue that SFX-DOS is a real file system implementation.
FORMAT in the shell is ultimately triggering both physical formatting and logical file-system construction.
Once all of those pieces are put together, the write path becomes much easier to follow.
flowchart TD
A["<b>SAVE command</b><br>filename + address + length"] --> B["<b>File_Open</b><br>validate disk and locate or create entry"]
B --> C["<b>Search_VoidClus</b><br>reserve first free cluster"]
C --> D["<b>File_Write</b><br>copy data into Disk_Sector buffer"]
D --> E["<b>Write_Cluster</b><br>write current cluster to disk"]
E --> F["<b>Link_FAT</b><br>extend cluster chain if needed"]
F --> G["<b>File_Flush</b><br>write directory entry and FAT back"]
That diagram is obviously simplified, but it captures the important point: a SAVE in SFX-DOS is not one opaque disk write.
It is a chain of directory management, cluster allocation, buffered sector transfer, and FAT maintenance.
Three smaller files preserve the physical assumptions behind the environment.
fdcdrv.asm is the low-level floppy controller driver (FDC).
It explicitly targets the uPD72069 and implements raw commands like:
It also preserves the 2HD and 2DD geometry and timing values used to talk to the drive.
fdcdrv.asm is also more defensive than a bare minimum demo driver.
It includes explicit retry loops for operations like recalibrate, seek, read, write, and format, and it distinguishes between resetting standby and entering standby mode.
That matters because it makes the driver feel like real production-facing support code. The stack expected drive errors, spin-up delays, and controller state changes, not just a perfect always-ready floppy.
The standby logic is a nice detail on its own:
FDC_Set_Stdby puts the controller into standbyFDC_Reset_Stdby restarts the clock and clears the standby bitFDC_Reset begins by forcing the controller out of standby before reinitializing itSo even at the lowest level, SFX-DOS is managing hardware lifecycle rather than only issuing I/O commands.
sccdrv.asm targets the Z8530, and it is doing two jobs at once:
That split is spelled out in the comments and setup paths. It even preserves the PC-9800 keyboard translation tables, which is one of the nicest clues in the whole package about the host workstation environment sitting next to the Super Famicom hardware.
The file also preserves the default serial configuration very clearly.
Init_SCC_Driver initializes RS232C_baurate to 00001010b, which the baud table resolves to 9600 baud, and sets RS232C_status for 8-bit transfer, one stop bit, and no parity.
That is a small detail, but a useful one. It means the serial side of the environment was not an undefined “RS-232 support exists” stub. There was a concrete default communications setup ready to go.
The keyboard side goes further than simple byte input. It maintains a ring buffer, scans character sets, and maps keyboard scan codes through three separate conversion tables:
Keyboard_normalKeyboard_shiftKeyboard_ctrlThose tables are explicitly labeled as PC-9800 keyboard data. That is one of the clearest host-environment clues anywhere in the package. The Super Famicom-side tool stack was designed to receive keyboard input in a form that matched NEC PC-9800 hardware conventions.
ppidrv.asm targets the uPD71055.
It is simpler than the other two drivers, but still reveals that the environment expected to support printer output directly.
Its main jobs are:
Taken together, the three drivers show that SFX-DOS was built to talk to floppy drives, a keyboard, serial devices, and a printer from the same console-side software layer.
Even though ppidrv.asm is short, it still preserves useful low-level behavior.
Init_PPI_Driver configures the chip in mode 0 with:
It then writes an initial control value that disables IRQ and leaves the strobe line inactive.
From there the data path is very direct:
Sense_Printer reads PPI_port_B and checks bit 2 as the printer-ready or busy signalOutput_Printer spins in a tight loop until that bit says the printer is readyPPI_port_ASo while the printer support is much smaller than the floppy and serial layers, it is still real device I/O with readiness polling and a hardware output strobe rather than a placeholder API entry.
That is enough to tell us SFX-DOS expected a physically attached printer and knew how to hand bytes to it one by one from the Super Famicom side.
condrv.asm turns the hardware layer into something a person could actually use.
It provides:
Init_CON_Driver - Initializes the text console state, clears buffers, and prepares the display layer.Input_Console - Reads a single character from console input.Output_Console - Writes one character to the console, including control-code handling.Input_String - Reads and edits a full input line into the shared line buffer.Print_String - Prints a null-terminated string through the console output path.CON_Driver_NMI - Runs NMI-time console refresh tasks such as cursor and screen updates.Internally it maintains a text-VRAM emulation buffer, cursor positions, insert and delete line support, screen clearing, palette setup, and character initialization.
So this is more than a serial log window. It is a proper text console running on the Super Famicom side.
The initialization path is more elaborate than it first looks.
Init_CON_Driver blanks the screen, clears the text VRAM emulation buffer, initializes the BG screen, character data, and palette, then turns the display back on.
That sequence is worth calling out because it shows the console was not an abstract software terminal. It was a real SNES background layer being prepared for interactive use.
The driver also preserves concrete screen behavior:
x=2, y=30x0800 bytesThat is much closer to a miniature terminal than a simple debug print buffer.
Output_Console does more than write printable characters.
It has a full control-code jump table for:
The escape path then branches into dedicated handlers for things like insert line and delete line.
That is a surprisingly rich interface for a game-adjacent support tool. It means the higher-level shell could rely on proper screen control rather than repainting the whole display by hand every time.
The input side is just as complete.
Input_String does line editing on top of Input_Keyboard, handling backspace, carriage return, and control-style editing flows while storing the result in Line_buffer.
On the display side, CON_Driver_NMI and Cursor_Blink keep the cursor alive during NMI updates.
So the console was designed to feel interactive and stable while the SNES kept refreshing the screen in the background.
ccp_main.asm then looks like a shell or command processor built on top of that console and the DOS API.
It imports CON_Driver, DOS_Entry, COP_Entry, NMI_Entry, and IRQ_Entry, tracks current and selected drives, and includes command paths for file-management behavior such as rename support.
That is historically useful because it suggests SFX-DOS was not only a hidden service layer for game editors. It also had its own operator-facing environment.
ccp_main.asm makes the operator-facing side unusually tangible.
Its boot message literally prints:
Super Famicom DOS Ver 0.10Copyright (C) 1991 NintendoAfter boot, the shell drops to an A>-style prompt by outputting the current drive letter followed by >.
That is a great detail because it shows SFX-DOS was presenting itself like a tiny DOS command shell rather than an invisible subsystem buried under game tools.
The command table in ccp_main.asm is small but revealing.
The built-in commands are:
CLSDIRDELRENCHDISKFORMATLOADSAVESo the shell was not only for startup diagnostics. It exposed a compact but usable file-management workflow directly on the Super Famicom side.
There is even a commented-out DOSCUT test command, which temporarily halts SFX-DOS and then restarts it.
That is the sort of internal test hook that makes the whole package feel like active systems software rather than polished release tooling.
ccp_main.asm is more than a thin wrapper around the DOS API.
It contains a real command parser with tokenization, uppercasing, delimiter tracking, hex parsing, filename validation, and shared error handling.
The flow is roughly:
Line_bufferUpcase_linbufGet_TokenA:Search_CommandCommand_processThat makes the shell feel much more deliberate than a one-command test harness. It is parsing free-form command lines in a recognizably DOS-like way.
The filename handling code is especially nice because it shows what kind of file names the shell expected.
Set_filename builds an 8.3-style name into a fixed 11-character field, padding with spaces and rejecting characters like:
.:/\It also supports wildcard expansion.
If the user enters *, the parser fills the remaining filename or extension field with ?, which is then copied into the DOS-side access_fname buffer.
That is a surprisingly concrete preservation detail. This was not simply “give me a file name string.” It was a proper DOS-like 8.3 command shell with wildcard search behavior.
The shell also distinguishes between the current drive and the selected drive.
At the prompt it prints the current drive as A> or B>, but individual commands can override that with a drive prefix.
CHDISK then handles the media side.
Its parser accepts:
HDDDDD9and converts those into the disk-mode values later handed to the DOS-side reset call.
That detail pairs nicely with fileio.asm.
The shell is exposing the underlying 2HD and 2DD media distinctions directly to the operator instead of hiding them behind one generic “mount disk” action.
DIR is more than a stub that dumps fixed filenames.
Its flow is:
??????????? into access_fnameSELDSK to select and validate the current driveDIRFST to fetch the first matching entryDIRNXTDSKFRE and printing free-space informationThat means the shell is doing a real directory walk and then reporting remaining capacity at the end, not merely listing one static directory sector.
The display helpers are equally specific:
Display_fname inserts the dot between the 8-byte name and 3-byte extension before printingDisplay_fsize prints the 32-bit size from the directory entryDisplay_free converts the free-space result into a human-readable decimal byte countSo the shell was not only functional. It was trying to present the disk contents in a familiar, operator-friendly format.
LOAD and SAVE are some of the most revealing commands in the whole file because they show the shell was meant to move raw memory blocks, not merely copy files around abstractly.
Both commands expect:
The parser stores those numbers into the shared command buffer before calling the DOS API.
So a LOAD command here really means “read this file into this target memory range,” and SAVE means the reverse.
That makes the shell feel very development-oriented. It is closer to a hardware monitor or tool-loader than a home-computer file browser.
The shell also preserves a tidy shared error path.
Command errors and DOS errors are kept separate:
unknown command., bad drive number., bad file name, bad disk type, and bad xdigitDisk_error_msg table with messages like drive not ready, file not found, directory full, file read only, disk full, and file existThat is another strong sign that this was meant to be used interactively by humans. The stack is not only returning status codes. It is translating them into readable console feedback.
The easiest way to understand why this matters is to look at the Mario Kart editor bridge files.
ed_dos1.asm and ed_dos2.asm are not talking directly to floppy hardware.
They prepare filenames, addresses, and byte counts, then call the COP-based SFX-DOS API.
The differences between the editor save paths are especially revealing:
| Editor path | Save area | Transfer size | What it suggests |
|---|---|---|---|
SAVE_FILE1 / LOAD_FILE1 |
0800h |
0400h |
The first editor family writes a larger structured block |
SAVE_FILE2 / LOAD_FILE2 |
1c00h |
0080h |
The second editor family writes a compact object/map buffer |
BATTLE_SDISK / BATTLE_LDISK |
7f:9300 |
0c00h |
Battle editing stages its own larger transfer outside the generic wrappers |
That makes the Mario Kart toolchain much more concrete. The editors were not pretending to load and save. They were sitting on top of a genuine SNES-side file system and device environment.
At this point, the surviving code gives a pretty good sense of how SFX-DOS was meant to be used in practice.
A likely session would have looked something like this:
Super Famicom DOS Ver 0.10A>-style prompt driven by ccp_main.asmDIR and watch the shell enumerate 32-byte directory entries, print 8.3 filenames, and show remaining free spaceCHDISK HD, CHDISK DD, or CHDISK DD9 depending on the floppy in useLOAD filename address length to pull a file directly into target memorySAVE filename address length to write a raw memory region back out to diskThat operator flow is also easy to see as a command sequence:
flowchart TD
A["<b>Boot SFX-DOS</b><br>show version banner"] --> B["<b>Prompt appears</b><br>A>-style command prompt"]
B --> C["<b>DIR</b><br>list files and free space"]
C --> D["<b>CHDISK</b><br>set HD, DD, or DD9 mode"]
D --> E["<b>LOAD</b><br>read file into target memory"]
E --> F["<b>SAVE</b><br>write memory range back to disk"]
F --> G["<b>DOS layer work</b><br>directory scan, FAT update, cluster I/O"]
That flow matters because it makes the whole stack feel much less abstract. This was not only a library that happened to contain file-system code. It looks like a small working operating environment that a developer could actually sit in front of on Super Famicom hardware, using a keyboard, a floppy drive, and optionally a printer or serial device.
Seen that way, the Mario Kart editors fit naturally into the same world.
Their cop calls were not bypassing the shell and file system.
They were plugging into the same underlying environment that an operator could also drive manually from the command prompt.
The Gigaleak preserves at least two clearly related SFX-DOS copies:
other/SFC/ソースデータ/MarioKartother/SFC/ソースデータ/ヨッシーアイランド/ツール/tool/sfxdosThey are not byte-identical, but they are obviously the same package family.
The comparison is easier to scan in table form:
| Copy | What survives | What stands out |
|---|---|---|
| Mario Kart | sfxdos.asm, sfxdos.lib, in-project callers |
looks like a project-local working snapshot with a shorter source tail |
| Yoshi’s Island tools | sfxdos.asm, sfxdos.lib, sfxdos.h, doscall.h, sfxdos.doc, sfxdos.map, sfxdos.rel, sfxdos.hex |
preserves a fuller packaged tool copy with documentation and a more explicit vector layout |
The strongest signs of continuity are:
COP_Entry dispatcher structureINPUT and PRINTAt the same time, the Yoshi tool copy is fuller in a few useful ways:
sfxdos.asm source is longer, at 441 lines versus 400 in Mario Kartequ addresses for vectors like 0DFF6h through 0DFFEhsfxdos.h, doscall.h, sfxdos.doc, sfxdos.map, sfxdos.rel, and sfxdos.hexThe Mario Kart copy, by contrast, looks more like a project-local working snapshot:
Int_Exit and Return_longSo the best reading is not that Nintendo rewrote SFX-DOS separately for each game. It looks more like a shared 1991 support package that stayed fairly stable, then survived in slightly different project-local forms as teams kept carrying it forward.
That is useful historically because it means the Mario Kart copy is not an isolated oddity. It appears to be one snapshot of a broader internal SFX-DOS toolkit that was still recognizable in later Super Famicom development material.
SFX-DOS is one of the most illuminating support packages in the Gigaleak because it shows how development hardware, editor code, and game code met in the middle.
It preserves:
That is much more than a few disk routines. It is a snapshot of how a Super Famicom development environment could behave like a small operating system attached to a game project.