2

I'm developing a library for reading CD-ROMs and the ISO9660 file system.

Long story short, pretty much everything is working except for one thing I'm having a hard time figuring out how it's done:

Where does XA standard defines differentiation among Mode 2 Form 1 from Mode 2 Form 2?

Currently, I am using the following pseudo-code to differentiate between both forms; albeit it's a naive heuristic, it does work but well, it's far from ideal:

var buffer = ... // this is a raw sector of 2352 bytes
var m2F1   = ISector.Cast<SectorMode2Form1>(buffer);
var edc1   = EdcHelper.ComputeBlock(0, buffer, 16, 2056);
var edc2   = BitConverter.ToUInt32(m2F1.Edc, 0);
var isM2F1 = edc1 == edc2;
if (isM2F1) return CdRomSectorMode.Mode2Form1;

// NOTE we cannot reliably check EDC of M2F2 since it's optional
var isForm2 =
    m2F1.SubHeaderCopy1.SubMode.HasFlag(SectorMode2Form1SubHeaderSubMode.Form2) &&
    m2F1.SubHeaderCopy2.SubMode.HasFlag(SectorMode2Form1SubHeaderSubMode.Form2);
if (isForm2) return CdRomSectorMode.Mode2Form2;

return CdRomSectorMode.Mode2Formless;

If you look at some software like IsoBuster, it appears to be a track-level property, however, I'm failing to understand where the value would be read from within the track.

aybe
  • 15,516
  • 9
  • 57
  • 105

1 Answers1

2

I'm actually doing something similar in typescript for my ps1 mod tools. It seems like you actually probably have it correct here, since I'm going to assume your HasFlag check is checking position bit position 6 of the subheader. If that flag is set, you are in form 2.

So what you probably want something like:

const sectorBytes = new Uint8Arrray(buffer);
if (sectorBytes[0x012] & 0x20) === 0x20) {
  return CdRomSectorMode.Mode2Form2;
} else {
  return CdRomSectorMode.Mode2Form1;
}

You could of course use the flag code you already have, but that would require you to use one of the types first to get that. This just keeps it generic bytes and checks the flag, then returns the relevant mode.

Rob Louie
  • 2,462
  • 1
  • 19
  • 24
  • I have a rather (not so) surprising answer to this, it turns out that when you look at the SCSI MMC-3 specs (to read from raw metal), the drive actually can tell that precisely. I've looked at your viewer, when you look for images or models, they'll never be M2F2 unless the guys screwed their mastering or do some cheap protection. In our case, mere mortals, for PSX we can assume that .XA, .AV, .STR are M2F2, anything else isn't because it's supposed to be scratch-resistant with error correction and thus can be read as M2F1. – aybe May 27 '22 at 02:24