DEV Community

Nivando Soares
Nivando Soares

Posted on

Porting Test Drive II from SNES to PC, Part 23: Mapping DOS menu contracts onto the SNES front end

Porting Test Drive II from SNES to PC, Part 23: Mapping DOS menu contracts onto the SNES front end

Most of the recent work in this port has been about the attract-mode provenance chain: which ROM blobs own which visible scanlines, which callbacks produce the writes, and which parts of the frame are still unresolved.

That work is still active, but it was time to start a second line of attack.

The DOS version already gives a verified runtime model for the front end:

  • a live selector vector
  • separate car and scenery materialization handlers
  • a play-session gate that refuses to advance until both catalogs are valid
  • explicit persistence for the current choices

So instead of treating the SNES menu as a fresh mystery, I used those DOS contracts as search targets.

The result is a first-pass SNES/DOS correlation baseline with machine-readable outputs and a tighter list of unknowns.

What the SNES front end now looks like

The strongest verified read is that the SNES version keeps its live menu state in one compact WRAM neighborhood rather than in a recovered DOS-style selector vector.

Right now the important block is centered on:

  • $1C6A
  • $1C70
  • $1C78
  • $1C7C
  • $1C90

And then one setup path derives secondary fields such as:

  • $1C74
  • $1C76
  • $1C7A
  • $1C7E
  • $1C80

That is a useful shift in framing.

The DOS side led with a slot-indexed selector vector rooted at 0x8A1C.
The SNES side, at least from the current evidence, looks more like a flattened state block with named fields feeding one derived descriptor.

The recovered materializer is shared, not split

The clearest SNES builder right now is the L008C10/L008CA2 path in bank 1.

That path:

  • computes a row selector from $1CA8 + $1C7E
  • reads bank-1 tables in the 01:8016..01:8330 family
  • writes a descriptor cluster at $1CAC/$1CCA/$1CFA/$1CAA/$1CE2/$1CE4/$1CE6/...
  • hands those values to the deeper bundle and transfer routines

That gives me one strong conclusion:

the current recovered SNES front end is not yet showing the same explicit split that DOS has between car-catalog and scenery-catalog builders.

There may still be a deeper split later in the ROM, but the verified surface today is one shared descriptor materializer fed by multiple selectors.

Two domain-specific menu surfaces are finally separated

The correlation pass also split out two front-end surfaces that had previously been mixed together.

First, there is a verified car-specific customization surface.

The string block at 01:880D contains:

  • CUSTOMIZE CAR
  • Autoshift
  • Car Height
  • Drag Coeff
  • Accel Coeff
  • Brake Coeff
  • Max G Force
  • Scrub Rate
  • 0-60
  • 0-100
  • 1/4 Mile
  • 1/4 Speed
  • Top Speed
  • Top Time
  • Lives

And the matching routine copies a set of live parameter fields back into the active working block before returning to the shared descriptor flow.

Second, there is a verified three-choice animated preview rebuilder through $0202.

That path rebuilds one preview bundle from 0x0009 + $0202 and later commits the chosen value into $1C78.

I still cannot prove from names alone that $1C78 is the main car selector, but it is now the strongest car-facing candidate instead of just another unlabeled field.

The persistence answer is sharper than expected

One of the DOS contracts asks a simple question:

where did the persisted menu choices go on SNES?

The ROM header gives a strong first answer:

  • cart_type = 0x00
  • sram_size = 0x00

So the shipped image does not advertise battery-backed SRAM at all.

That does not prove the SNES version has no persistence path of any kind, but it does rule out the most obvious equivalent to DOS select.dat.

That is a useful negative result because it narrows the search.

If the SNES version preserved choices across boots, it probably did not do it with ordinary cartridge SRAM.

The gameplay gate is still only partially mapped

The DOS handoff into gameplay is valuable because it validates both catalogs before advancing.

On SNES I can now point to two nearby surfaces:

  • a verified front-end success gate rooted at L008B26
  • a probable gameplay-handoff candidate at L009568/L0095AD

What I still do not have is the exact DOS-style proof:

a branch that clearly refuses to enter gameplay until separate car and scenery working sets are both valid.

So the current result is not “the gate is solved.”

It is:

  • the selector block is better defined
  • the descriptor builder is explicit
  • the persistence surface is narrowed
  • the nearest gameplay boundary is now concrete enough to target next

The concrete outputs

This checkpoint produced five baseline artifacts:

  • snes_selection_state_contract.json
  • snes_catalog_contracts.json
  • snes_play_session_gate.json
  • docs/snes_dos_correlation.md
  • docs/snes_unknowns.md

Those files matter because they force the SNES claims into the same audit discipline as the DOS side:

  • what is verified
  • what is only probable
  • what still needs a name-bearing asset, trace, or ROM-offset proof

That is a better foundation for the next archaeology pass than continuing to accumulate isolated notes.

What comes next

The next high-value probes are now narrower:

  • prove whether $0202/$1C78 is really the car-facing selector domain
  • prove whether $1C7C is track/scenery-facing
  • decode the 01:8000 and 01:8016..01:8330 table families into named rows
  • follow L009568/L0095AD into the first confirmed gameplay callback chain

That should tell us whether the SNES version flattened the DOS menu model or whether the missing split is just hiding behind one more layer of table-driven setup.

Top comments (0)