Files
psxrecomp/runtime/src/iso_reader_c.cpp
T
Matthew Stanley 5c64071155 cdrom: multi-track .cue TOC support (GetTN/GetTD report real tracks)
The .cue parser only extracted the FILE line and the CD model hardcoded a
single data track: GetTN always returned 01..01 and GetTD returned LBA 0 for
any track. Multi-track discs with a CD-DA audio track (Tomba 2: TRACK 02 AUDIO
@ 38:48:74) therefore reported a bogus TOC.

- iso_reader: parse TRACK/INDEX lines into a CDTrack table; synthesize a single
  data track for bare .bin/.iso. New TrackCount/TrackStartLBA/TrackIsAudio +
  iso_track_* C wrappers.
- cdrom.c GetTN returns first=1/last=track_count (BCD); GetTD returns each
  track's real start MSF (lead-out via 0xAA/track 0 unchanged).

Framework fix for every CD-DA title. NOTE: does not by itself unblock Tomba 2's
boot — that still stalls in a GetStat/GetID/Init disc-init loop (display toggles,
reading=0) which does NOT call GetTN/GetTD; next is an oracle CD command/response
diff at that loop (and the hardcoded GetID region "SCEI" vs USA "SCEA" is a
candidate). cdrom_trace_dump floods with DMA 'D' events — fix that (Rule 15)
before the diff.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 23:16:06 -07:00

64 lines
1.7 KiB
C++

/*
* iso_reader_c.cpp — C wrapper for the C++ ISOReader class
*
* Provides iso_open() / iso_read_sector() / iso_close() for use by cdrom.c
*/
#include "iso_reader.h"
#include <cstdio>
extern "C" {
void* iso_open(const char* path) {
auto* reader = new PS1::ISOReader();
if (!reader->Open(path)) {
delete reader;
return nullptr;
}
return reader;
}
int iso_read_sector(void* handle, uint32_t lba, uint8_t* buffer, int size) {
if (!handle) return 0;
auto* reader = static_cast<PS1::ISOReader*>(handle);
(void)size; /* ReadSector always reads 2048 bytes */
return reader->ReadSector(lba, buffer) ? 1 : 0;
}
int iso_read_raw_sector(void* handle, uint32_t lba, uint8_t* buffer, int size) {
if (!handle || size < 2352) return 0;
auto* reader = static_cast<PS1::ISOReader*>(handle);
return reader->ReadRawSector(lba, buffer) ? 1 : 0;
}
uint32_t iso_sector_count(void* handle) {
if (!handle) return 0;
auto* reader = static_cast<PS1::ISOReader*>(handle);
return reader->GetSectorCount();
}
/* CD-track TOC accessors (multi-track / CD-DA support). track is 1-based. */
int iso_track_count(void* handle) {
if (!handle) return 1;
return static_cast<PS1::ISOReader*>(handle)->TrackCount();
}
uint32_t iso_track_start_lba(void* handle, int track) {
if (!handle) return 0;
return static_cast<PS1::ISOReader*>(handle)->TrackStartLBA(track);
}
int iso_track_is_audio(void* handle, int track) {
if (!handle) return 0;
return static_cast<PS1::ISOReader*>(handle)->TrackIsAudio(track) ? 1 : 0;
}
void iso_close(void* handle) {
if (!handle) return;
auto* reader = static_cast<PS1::ISOReader*>(handle);
reader->Close();
delete reader;
}
} /* extern "C" */