-
-
Notifications
You must be signed in to change notification settings - Fork 4
CSB FMTowns Guide
This is the FM Towns counterpart to DM1's guide. Read both before changing CSB FM Towns startup, cache, media or runtime code. The games share Phar Lap and TownsOS conventions, but they do not share a title program, CD layout, save body or presentation owner.
Cross-fingerprint recovery revealed CSB CHTWE.EXP embeds several DM1 game data structures IDENTICALLY at per-game vaddrs:
| Payload | Bytes | DM1 vaddr | CSB vaddr | Firestaff alias module |
|---|---|---|---|---|
| OICON descriptor | 1344 | 0x224db | 0x27f77 | csb_v1_fmtowns_oicon_descriptor |
| DYNA_BUTTONS pool | 500+ | 0x24194 | 0x29d50 | csb_v1_fmtowns_dyna_buttons |
| SPELL_COSTS | 32 | 0x24388 | 0x29f64 | fmtowns_shared_tables_all_games |
| SPELL_MULT | 8 | 0x243a0 | 0x29f7c | fmtowns_shared_tables_all_games |
| PLAYER_COLOR | 8 | 0x291b8 | 0x2d164 | fmtowns_shared_tables_all_games |
| ICON_PAL | 6 | 0x28f44 | 0x2cd8a | fmtowns_shared_tables_all_games |
| CHAR geometry | 14 | 0x26c8a | 0x2c94c | fmtowns_geometry_all_games |
| ICON geometry | 8 | 0x26c68 | 0x2c938 | fmtowns_geometry_all_games |
| 768-byte font raster | 768 | (asset 557) | file@0x50f1a | fmtowns_font_raster_all_games |
| Phar Lap 4-slot bridge | — | ✓ | ✓ | fmtowns_pharlap_all_games |
| Direct I/O 0x04E9 | — | ✓ | ✓ | fmtowns_pharlap_all_games |
CSB pic_library (CDATA/GRAPHICS.DAT, sig 0x8001) reuses DM1's
parser via csb_v1_fmtowns_pic_library_open_ext_v1_pc34.
CSB TMENU.EXP has its own SYM1 table (1724 entries) shipped via
csb_v1_fmtowns_tmenu_sym1. CHTWE.EXP itself has no SYM1
(stripped) — use the byte-fingerprint modules above.
- CSB region table (independent menu layout)
- CSB CDDA track table (own soundtrack)
- CSB DOOR palette / animation-timings / STARTUP1 chain
- CSB SWITCHTW.EXP switch page, ANIMTW.EXP, UTILE.EXP
The admitted CSB F31 disc contains both language trees:
| Tree | Game data | Game program | Bootstrap save |
|---|---|---|---|
| English |
CDATA/GRAPHICS.DAT, CDATA/DUNGEON.DAT
|
CHTWE.EXP |
CDATA/MINI.DAT |
| Japanese |
CJDATA/GRAPHICS.DAT, CJDATA/DUNGEON.DAT
|
CHTWJ.EXP |
CJDATA/MINI.DAT |
src/shared/asset_status_m12.c first verifies the selected hash pair, then
materializes the complete ISO inventory and the original FMTOWNS.IMG /
FMTOWNS.CUE pair when the source is the retail ZIP/RAR. It must retain that
pair for the original TD/TR CD-DA commands; a derived track table or generated
PCM is not an equivalent source. A manually extracted original tree is also
admitted only when both language packages, their two P3 programs and all six
registered hashes agree. Production applies the selected F31 language before
startup. The runtime materializer creates a language-private cache with the selected flat
GRAPHICS.DAT/DUNGEON.DAT, the original nested CDATA/MINI.DAT or
CJDATA/MINI.DAT, root programs and original portraits, and removes stale
archive CUE/IMG files so loose media cannot borrow CDDA from a different
source. This is required even for a loose extraction: the hash-matched
GRAPHICS.DAT parent is only CDATA or CJDATA, whereas TITLE.ANM,
SWITCHTW.EXP and CHTWE.EXP/CHTWJ.EXP are owned by the disc root. The
scanner reports each admitted CSB edition, rather than using the selected
cache pair as evidence for another platform.
The opt-in real-media CTest rows retain that separation: with
FIRESTAFF_CSB_FMTOWNS_GAME_DATA_DIR set, the English and Japanese pairs
csb_v1_fmtowns_{en,ja}_native_cli_real_media exercise direct CLI startup
and --menu launch, while
csb_v1_fmtowns_{en,ja}_m11_real_media_handoff verifies the corresponding
M11 language-private title, switch and Game-program handoff. They add no
fixture bytes and report SKIP when the licensed disc is unavailable.
When FIRESTAFF_CSB_FMTOWNS_USER_SAVE names a language-matched, original
F0435 save, the native regression requires both direct --save and
--menu --save followed by Enter to enter the live C03 game session. The
explicit path is bound before either launch route builds its M12 intent, so
the menu route cannot silently discard it. Neither route may replay
TITLE.ANM or send F31 bytes through the Atari/CSBWin save readers.
They disable SDL device playback only for headless test stability; source
music and sound-route receipts remain part of the verified startup state.
CSB uses its own 31-track Red Book layout. Do not reuse DM1's mixed
MODE1/2048-and-audio offset calculation or DM2's Towns music helper. The CSB
reader is src/csb/csb_v1_fmtowns_cd.c; M11's live transport boundary is in
src/engine/m11_game_view.c.
TITLE.ANM ──return──> SWITCHTW.EXP ──Game──> CHTWE.EXP / CHTWJ.EXP
├─Story──> ANIMTW.EXP STORY.ANM ──return──┘
└─Utility──> UTILE.EXP / UTILJ.EXP
TITLE.ANM, STORY.ANM and ENDING.ANM are F2275/F8288 animation streams.
Their Timer-A waits, loop execution and TD/TR requests are source-owned.
ENDING.ANM holds its final frame when it returns; it does not route back to
the switch page. SWITCHTW.EXP owns the 320×200 language pages, palette,
four button streams and the selected handoff. AUTOEXEC.BAT establishes the
exit mapping. See ReDMCSB NECIO.C, SWITCH.C, ANIMTOWN.C and
STARTUP2.C.
The Game exit is a separate C03 program, not PC 3.4 TITLE.C:
- F31E admits only
CHTWE.EXP(283,936 bytes; FNV-1a3da136f6). - F31J admits only
CHTWJ.EXP(284,416 bytes; FNV-1af937db45). - Both enter the C004 Prison wait from
STARTUP1.C/ENTRANCE.C F0807.
include/csb_v1_fmtowns_game.h and src/csb/csb_v1_fmtowns_game.c carry
that admission receipt. M11 opens only the source-bound C004 entrance and
C002/C003 door sequence, then the verified C017/F0128 HUD/viewport session.
It must not replay the standalone title timeline after this transition.
F0128's runtime thing pass (DUNVIEW.C F0115) is also source-bound for both
F31 editions. The verified IMG2 GRAPHICS.DAT decoder supplies the native
MEDIA720 families: M613/454 for projectiles, M614/486 for explosions,
M612/498 for objects, and M618/584 for creatures. An unavailable or malformed
record is left blank; Firestaff never substitutes a PC bitmap or a marker.
The real-media handoff test byte-compares a record from each family and checks
that the 224×136 F0128 aperture changes after live source input. It also
executes the unmodified Prison C004/C002 command sequence: C004 attempts the
west side-step into the active retail group at map 4 (21,18), then C002
faces it. F0115 must issue at least one native group sprite blit and no marker
fallbacks. The test also identifies that group's direction/depth-selected
bitmap and byte-compares it with its exact IMG2 record. Capture-level draw
order and placement across populated rooms remain open.
MINI.DAT is neither an Atari/Amiga GAMEBLOCK nor a substitute DUNGEON.DAT.
ReDMCSB CEDTINCD.C F7051 validates its 512-byte C5 header through F7061,
then F7057-checks five save parts, reads four external portraits, and passes
the remaining dungeon tail to F7063.
| Receipt | English | Japanese |
|---|---|---|
| File size | 42,776 | 43,208 |
| FNV-1a | 494999c9 |
284799d1 |
| Header platform | F7 | F8 |
| Dungeon identity | C13 CSB Game | C13 CSB Game |
| Validated party pose | map 4, (22,18), direction 2 |
map 4, (22,18), direction 2 |
| Game time | 82 | 88 |
The verified save body has native GLOBAL_DATA, active groups, champion and
party data, events and timeline parts. The tail begins after the four
464-byte external portraits. Its checksum is validated and can be copied by
csb_v1_fmtowns_game_copy_verified_dungeon_tail() into the ordinary real
CSB dungeon reader. MAP coordinates are bytes 6/7 (OffsetMapX/Y), not the
unreferenced bytes 4/5; this follows ReDMCSB DEFS.H and DUNGEON.C F0154.
The production M11 resume path binds those owners as one transaction. The
real English and Japanese MINI.DAT files pass the end-to-end
test_csb_v1_fmtowns_mini_resume_real gate: CHTWE/CHTWJ enters the saved
map-4 pose at (22,18), direction 2, with one champion and no title replay.
This proves the shipped retail bootstrap save path. It does not prove an
arbitrary user CSBGAME.DAT until that file passes the same native F0435
header, five-part, portrait and dungeon-tail gates. For F31E C06, the selected
native CSBGAME.DAT medium is now read and updated through those gates:
F7001/F7052 creates its first slot privately from the hash-verified
MINI.DAT, F0433 updates later saves, F7004/F7051 reloads the same slot, and
F0435 may restore its native .BAK when the primary is damaged. This is not a
generic Firestaff save format and does not admit unverified external candidates.
Firestaff exposes the recovered C06 route explicitly in both launch surfaces:
the start menu's CSB Utility Disk (FM Towns) entry and
firestaff --csb-utility-disk --data-dir <path>. The CLI option implies CSB
and FM Towns. Both routes first select a hash-verified F31 package, execute
the normal C03 boot boundary, then enter C06; they fail closed when that
package cannot be admitted. They are not aliases for the separate Atari R1
Hint Oracle route (--csb-hint-oracle).
UTILE.EXP and UTILJ.EXP are separate C06_CEDT programs. Their P3
envelopes, six-label source pools, C09 icon palette, source-coordinate menu
boxes, F31 M653 font material and planar .CMP portrait decoder are
verified. For F31E this authorizes a deliberately small editor surface: the
verified C06 frame, champion selection, palette selection, planar 32×29
pixel drawing, connected-area fill, Revert and Undo. C06 first shows the
source-owned LOAD WHICH SAVED GAME? choice (DUNGEON MASTER, CHAOS STRIKES BACK, CANCEL). Those labels and the full PLEASE PUT THE GAME SAVE / DISK IN %DEVICE% prompt are read from individually hash-verified
UTILE.EXP P3 spans, not copied host strings. The CSB branch then waits for the separately
selected A: game-save medium; a CD MINI.DAT is explicitly not accepted as
that medium. Only an F0435-valid native CSBGAME.DAT (or its native .BAK
recovery) opens the editor. The current CSB installation keeps the Dungeon
Master branch closed until corresponding DM media is admitted. The undo image
is one source-format copy, and neither editing nor reverting writes a host or
user save. The
source-owned portrait transactions also cover revalidated F7002_ReadCMP
import after a catalogue selection and the source SAVE CHAMPIONS dialog.
F7000's PORTRAIT choice preserves an admitted .CMP header, then writes
the selected champion's live name, title and planar payload to the separate
portrait medium: ~/.firestaff/portraits on macOS/Linux or
INSTALLDIR\\portraits on Windows. The scanned CD catalogue stays read-only.
For F31E CSB, F7001's GAME choice is also bound: first save stages the
admitted MINI.DAT privately, writes a canonical native CSBGAME.DAT, and
later saves update that same slot through F0433 with the original .BAK rule.
F7004's GAME choice reloads only an F0435-valid selected slot.
It does not authorize the rest of Utility. The source-family chooser and its
A: medium gate were captured with the original F31J disc in Tsugaru running
the verified Towns ROM set (TBIOS_V31L22A), then implemented only for the
narrow F31J selector and its ROM-bound Shift-JIS font consumer.
F7004_LoadChampions now presents
its native GAME / PORTRAIT / CANCEL choice before PORTRAIT opens the
source-owned CEDT008/CEDT013 picker. Make New Adventure remains closed:
F7086/F7090 needs a verified source/destination dungeon transaction and the
real F7020 equipped-object modifier removal, neither of which can be inferred
from a party-only editor receipt. F31J's initial C06 chooser is now available
in its captured 640×400 geometry when the user supplies an authorised
FMT_FNT.ROM through FIRESTAFF_FMTOWNS_FONT_ROM. The later editor and save
dialogs remain closed until their own source execution is recovered. Keep
those routes modal until their specific owners are evidenced.
When the active M11 canvas is 320×200, Firestaff presents that owned 640×400 F31J source page by nearest-neighbour scaling. The native 640×400 indexed frame remains available to the presentation boundary; the scaling neither substitutes glyphs nor manufactures panel art.
This C06 boundary is narrower than the direct in-game save route. M11 can
read and update an explicitly selected, already admitted native
CSBGAME.DAT slot through F0435/F0433, including the source .BAK recovery
rule. Its recovered F7052 first-save helper can also materialize a new
canonical CSBGAME.DAT from the hash-verified selected MINI.DAT: it stages
the bootstrap privately, rebuilds the five keyed parts and F7062 header, then
atomically publishes only an F0435-valid native file. It does not turn
Firestaff's default .sav into F31 media or choose C06's drive-2 destination.
The C06 GAME choices remain closed until that UI mapping is source-bound.
| Purpose | Path |
|---|---|
| Game and MINI receipts |
include/csb_v1_fmtowns_game.h, src/csb/csb_v1_fmtowns_game.c
|
| Switch page and handoffs |
include/csb_v1_fmtowns_switch.h, src/csb/csb_v1_fmtowns_switch.c
|
| Disc, ISO and CD-DA reader |
include/csb_v1_fmtowns_cd.h, src/csb/csb_v1_fmtowns_cd.c
|
| Animation stream | src/csb/csb_v1_fmtowns_animation.c |
| Cache materializer | src/shared/asset_status_m12.c |
| M11 startup, entrance and transport | src/engine/m11_game_view.c |
| C06 preservation boundary | docs/source-lock/csb_v1_fmtowns_c06_utility_boundary.md |
| Japanese C06 text boundary | parity-evidence/csb_fmtowns_f31j_text_owner.md |
| Main remaining work |
TODO.md (CSB-FMTOWNS-RUNTIME-PARITY) |
- Never use PC 3.4 title, Utility, audio or save code as a FM Towns fallback.
- Never generate pixels, CD audio, menu labels or save/champion data when the verified F31 owner is missing.
- Keep the selected
CDATA/CJDATApair ahead of the opposite-language sidecar tree. - A development/test loose F31 cache must copy and hash the selected language's original
CDATA/MINI.DATorCJDATA/MINI.DATpath alongside its flatGRAPHICS.DATandDUNGEON.DAT; title media alone is not a valid C03/C06 startup owner. - Keep original data out of the repository. Tests use user-supplied, hash-admitted media and skip safely when it is unavailable.