Goal: Confirm or refute a claim I was given — that porting Marvel vs. Capcom from Dreamcast to Saturn would be an easy job.
Constraints: No source for either build. Inputs are a Dreamcast GD-ROM dump and the Saturn MSHvSF disc, plus the arcade CPS-2 ROM this series has already reverse-engineered.
Approach: Parse the GD-ROM filesystem, identify the per-character data, measure it, and test whether the size gap is compressible slack or real data. Then compare against the Saturn memory budget measured from the MSHvSF port.
Result: No. A Dreamcast character averages 11.41 MB — 1.45x the Saturn's entire memory, cart included, and 17x one character's art slot. It is already compressed, so there is no slack. And it is the wrong direction: both builds descend from the same arcade original, and the arcade→Saturn converters are the ones that already work in both directions.
Proof / Validation: the 19 character .PST files measure 9.80–13.09 MB (mean 11.41 MB); zlib -9 achieves only 1.13x on one at 7.01 bits/byte entropy; the Saturn's total RAM is 7,864,320 bytes.
The claim
Someone told me that getting MvC1 from the Dreamcast onto a Saturn would be straightforward. It's a reasonable-sounding claim — both are Sega consoles, both use Hitachi SH processors, and MvC1 is a 2D fighting game, so there are no polygons to cut down.
All three of those are true. None of them survive contact with the numbers.
What is actually on the disc
The dump is a three-track GD-ROM, 1,188,409,587 bytes. Its bootstrap identifies it plainly:
SEGA SEGAKATANA / SEGA ENTERPRISES T1202N V1.000 1999-07-29
title MARVEL VS.CAPCOM
boot 0.BINThe high-density track carries 504,150 sectors of 2048 bytes — 1,032 MB of addressable area — holding 334 MB across 328 files. And that data is dominated by one file type:
The .PST files are the per-character data, named by a hex id. Splitting them by size separates the fighters from everything else:
| count | mean | range | |
|---|---|---|---|
| character-sized (≥ 9 MB) | 19 | 11.41 MB | 9.80 – 13.09 MB |
| everything else | 15 | 4.62 MB | 0.20 – 6.73 MB |
Nineteen is exactly right. MvC1 has 15 main characters plus Roll and Shadow Lady with unique art — 17, which is precisely the contiguous 0C–1C run — and Onslaught's two forms account for the outliers 2D and 2E.
A Dreamcast character is 9.80–13.09 MB, averaging 11.41 MB.
The first version of this post said "1C.PST = 11,968,512 bytes, that is Strider." The arcade character ids run even, $02–$2C. The Dreamcast's PST ids run dense, 0x0B–0x2E, odd numbers included. They are not the same id space, so $1C meaning Strider on one does not make 1C.PST Strider on the other — I read a coincidence of range as a mapping.
The per-file measurement was right; the name attached to it wasn't established. The argument never depended on which character it is, so the corrected framing — a range across all 19 — is what the numbers actually support, and it is strictly stronger.
The comparison that ends the discussion
I have the Saturn side measured from the MSHvSF disc, so this is like for like:
| bytes | ||
|---|---|---|
| A Dreamcast character | 11,410,000 avg | mean of the 19 character .PSTs |
| Entire Saturn memory | 7,864,320 | 2 MB work + 1 MB VDP + 0.5 MB sound + 4 MB cart |
| Saturn per-character art slot | 668,448 | |
| Saturn per-character on disc | ~630,000 | art pack + code module |
The average Dreamcast character is 1.45× the Saturn's entire memory (the largest, 13.09 MB, is 1.66×) — all of it, including the mandatory 4 MB expansion cartridge — and 17.9× the slot a character's art actually gets.
The executable is its own version of the same joke. 0.BIN is 4,930,596 bytes: the Dreamcast game's code alone is 2.35× the Saturn's 2 MB of main work RAM.
"Just compress it harder"
The natural objection is that 11.97 MB must be bloat — Dreamcast had room, so surely the data is stored lazily and would pack down. I tested it rather than assuming:
The Dreamcast data is already compressed. Entropy of 7.01 bits per byte with 2.3% zeros is not a file waiting to be packed — it is a file that has been packed. The 17.9× gap is real data.
And the Saturn end has no give either. This series' own encoder for the MSHvSF sprite codec reaches 1.04× Capcom's own density — the Saturn side is already as tight as the people who shipped it managed. Neither end has anywhere near a 17.9× improvement available.
The hardware gap, for completeness
| Dreamcast | Saturn | |
|---|---|---|
| CPU | SH-4 @ 200 MHz, superscalar, FPU | 2 × SH-2 @ 28.6 MHz |
| Main RAM | 16 MB | 2 MB (+ 4 MB cart) |
| Video RAM | 8 MB | 1 MB (VDP1 512 KB + VDP2 512 KB) |
| Sound RAM | 2 MB | 512 KB |
| GPU | PowerVR2, tile-based deferred, per-pixel alpha | VDP1 textured quads + VDP2 tilemaps |
| Media | GD-ROM ~1.0 GB | CD-ROM ~682 MB |
One detail is worth stating because it is routinely assumed backwards: SH-2 code runs on an SH-4. SH-4 code does not run on an SH-2. Upward compatibility only points one way. 0.BIN uses instructions the SH-2 does not implement, so there is no question of running Dreamcast code on Saturn hardware — it would need recompiling from source that nobody outside Capcom has.
The part that actually matters: it is the wrong direction
Size and hardware make the port hard. This next bit makes it pointless.
Both versions descend from the same CPS-2 arcade original. The Saturn MSHvSF port is a source-level SH-2 recompile whose assets were pushed through deterministic converters — and this series has reverse-engineered those converters and can now run them in both directions, each verified to byte-identity.
Going via the Dreamcast means undoing a transformation that moved the data further from the Saturn's format, to get back to something arcade-shaped, so that you can then apply the arcade→Saturn conversion anyway. It inserts an unsolved reverse-engineering problem — the .PST container and whatever codec lives inside it — in front of a pipeline that already works starting from the arcade ROM.
The arcade ROM is 4 MB with plaintext data tables. The Dreamcast build is 334 MB of already-compressed unknown formats. There is no reading under which the second is the easier starting point.
Why the claim sounds right
Two intuitions, both wrong in an interesting way:
"Both are Sega consoles with SH CPUs." True, and irrelevant. The ISA compatibility runs the wrong way, and the memory gap is 3× on the spec sheet but 15–18× per character in practice, because the Dreamcast build spends its 16 MB rather than economising.
"It's 2D, so it should scale down." Being 2D is exactly what makes it large. There are no polygons to reduce and no level-of-detail to drop — it stores every animation frame at arcade fidelity because it has the memory to. The Saturn's constraint was never geometry. It was always memory, which is why Capcom's own Saturn ports lean on a mandatory 4 MB cartridge and a custom sprite codec.
None of this says MvC content can't reach a Saturn. My measured position on that is unchanged and much more optimistic — it just starts somewhere else:
- Phase 0 tooling is complete and verified to byte-identity: an MVS-LZ compressor that beats Capcom's, a PAC repacker that rebuilds 79/79 packs exactly, and an ISO sector patcher with working EDC/ECC.
- A modified sprite has been swapped into a real disc image and read back out byte-exact.
- All five per-character table schemas transfer from MvC to MSHvSF.
- Strider from the arcade ROM needs about 829 KB against a 668 KB slot — and both the slot addresses and per-character sizes are editable data tables, so he plausibly fits with a re-partition rather than a content cull.
Port from the arcade ROM. Not from the Dreamcast disc.
"But the Dreamcast version was really going to the Saturn"
The follow-up claim: that this build began life as a Saturn project, and would therefore be very similar in structure and cheap to move across.
The historical half isn't something a disc can settle — Capcom's internal plans aren't in the bytes. The structural half is directly testable, because I have the Saturn's formats fully reverse-engineered. Tested five ways:
| Saturn signature | in 0.BIN | in 1C.PST |
|---|---|---|
| PAC container headers | 0 | 0 |
arcade/Saturn spritelist header 00 02 00 .. | 0 | 0 |
PALET.TBL colour LUT bytes | no | no |
| MVS-LZ stream headers | chance-level noise only | chance-level noise only |
| big-endian word layout | no — little-endian, 440 vs 97 | — |
Nothing. Not one Saturn structure survives anywhere in the shipped build.
The endianness fingerprint settles it
The sharpest test fell out of the earlier finding that the Dreamcast carries arcade tables byte-swapped. Run against both ports, with a control:
| arcade table stored unswapped | stored byte-swapped | |
|---|---|---|
| Saturn (MC05, move-property) | yes | no |
Dreamcast (0.BIN, box-shape) | no | yes |
Dreamcast (0.BIN, hitbox) | no | yes |
The Saturn stores arcade data byte-identical, because the SH-2 is big-endian like the 68000 it came from. The Dreamcast stores the same tables byte-swapped, converted for the little-endian SH-4.
A build that began as a Saturn project would carry big-endian data, and retargeting it would leave big-endian remnants behind. Every carried table in 0.BIN is swapped for little-endian — and the control confirms the test can tell the difference, since the Saturn's own table is found unswapped and not swapped.
What is true, and why it still doesn't help
There is a real sense in which the two ports resemble each other: both are source-level recompiles of the same CPS-2 arcade game, and both carry some arcade tables verbatim. That's shared ancestry — and it's precisely why the arcade ROM is the right source for either of them.
It is not shared structure. Containers, compression, sprite codec, colour conversion and byte order all differ, all the way down. Similar ancestry doesn't make a port cheap; identical formats would, and there aren't any.
And the claim wouldn't help even if the history is true. What a Saturn import needs is the arcade → Saturn conversion — and that already exists in shipped form, in Capcom's own Saturn MSHvSF from 1998, whose converters I've reverse-engineered and can run in both directions. A hypothetical unreleased Saturn MvC1 would at best be a second copy of a pipeline I already have.
So is the Dreamcast disc useless to me?
That's a sharper question than the one I set out to answer, and it deserves a separate answer. "Bad port base" and "useless as a source" are different claims, and the second one turns out to be false — one of the findings actually weakens something I published in the Saturn writeup.
It carries the two tables the Saturn threw away
Scanning 0.BIN for the arcade tables, byte-swapped (SH-4 is little-endian, the arcade 68000 is big-endian):
| table | Strider | Ryu | Gambit |
|---|---|---|---|
| box-shape | 100% | 100% | 100% |
| hitbox | 99% | 98% | 99% |
| move-property | 25% | 0% | 32% |
| anim tree | 0% | 0% | 7% |
| palette | 0% | 0% | 0% |
Put next to the Saturn, the two ports are complementary witnesses — each kept what the other dropped:
| table | Saturn MSHvSF | Dreamcast MvC |
|---|---|---|
| move-property | 99.9% | 25% |
| sound map | 100% | — |
| box-shape | 0% | 100% |
| hitbox | 0% | 98–99% |
| palette | 0% | 0% |
This weakens a conclusion I published. The Saturn post concludes that hitboxes and box-shape are re-authored by the Saturn port and therefore "must be authored for any character imported to Saturn." The first half stands — the Saturn genuinely doesn't carry them. The second half was an over-reach. The Dreamcast demonstrates that the arcade hitbox and box-shape tables are directly usable, verbatim, by an SH-family recompile of this same game. Capcom carried them into one SH port and re-authored them for the other; that was a choice, not a necessity.
For an import where I'm writing the character's logic anyway, those tables can be carried rather than authored — provided I write the reader to match. That's a materially smaller job, and it moves two of the three "blocked" rows out of the unknown column.
Palette stays blocked and is the exception: 0% in both ports, because both converted it. Though for an import that path is mechanical anyway — take the arcade palette through the Saturn's own PALET.TBL, the 128KB CPS-2→BGR555 LUT already decoded in the Saturn work.
It is Capcom's own SH implementation of this exact game
0.BIN is 4,930,596 bytes of clean SH code — 97% of sampled words decode — loading at 0x8C010000:
0x8c011000 mov #1,r3
0x8c011004 mov.l r3,@r2
0x8c011006 mov.l 0x8c011034,r3
0x8c01100a jmp @r3Phase 3's wall is hand-authoring SH-2 character logic, because nobody outside Capcom has the Saturn source. The Dreamcast supplies Capcom's own SH-family implementation of Marvel vs. Capcom specifically — not a cousin game, the same one. SH-2 and SH-4 share the base instruction set, register conventions and calling structure, so algorithm shapes read across far more directly than translating 68000 would.
That is not source code and it is not a shortcut to a working character. It's a reference for how Capcom expressed this engine's per-character behaviour on an SH CPU — which is exactly what Phase 3 has to reproduce.
Revised summary
| use | verdict |
|---|---|
| port base | no — 17.9× a slot, already compressed, wrong direction |
| asset source | no — the arcade ROM is upstream and already readable |
| hitbox / box-shape witness | yes — proves they carry verbatim into an SH recompile |
| Phase 3 logic reference | yes — Capcom's own SH implementation of this game |
| audio source | untested, but the Saturn's ADPCM has 0% arcade identity, so worth a look |
So: don't port from it. Do keep it open on the other monitor.
The Saturn side of this — the codec, the cart budget, the converters, and the several times I got the numbers wrong before getting them right — is in Byte-Identical on a CD. The arcade-side character work these tools were built for is the Shuma-Gorath and Dark Sakura native ports.