Skip to content

Instantly share code, notes, and snippets.

@nicolasnoble
Created March 24, 2021 18:01
Show Gist options
  • Save nicolasnoble/02de2c3f185f26418003224ba20f8dc6 to your computer and use it in GitHub Desktop.
Save nicolasnoble/02de2c3f185f26418003224ba20f8dc6 to your computer and use it in GitHub Desktop.
Sector prober
#include <stdint.h>
#include <stdio.h>
static inline uint8_t from_BCD(uint8_t x) { return ((x & 0x0f) + ((x & 0xf0) >> 4) * 10); }
static inline uint32_t from_MSF(uint8_t m, uint8_t s, uint8_t f) {
return (from_BCD(m) * 60 + from_BCD(s)) * 75 + from_BCD(f);
}
static void probe_sector(const uint8_t* sector, unsigned expected_lba) {
// do we have a sync pattern?
if (*sector++ != 0x00) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0xff) return;
if (*sector++ != 0x00) return;
// next up: reading the MSF and mode
uint8_t m = *sector++;
uint8_t s = *sector++;
uint8_t f = *sector++;
uint8_t mode = *sector++;
// if sector isn't a mode2 sector, go away
if (mode != 2) return;
// if the MSF isn't what we expect, go away
if (from_MSF(m, s, f) != expected_lba) return;
// if the subheader isn't properly duplicated, go away
const uint8_t* subheader = sector;
if (subheader[0] != subheader[4]) return;
if (subheader[1] != subheader[5]) return;
if (subheader[2] != subheader[6]) return;
if (subheader[3] != subheader[7]) return;
// now decoding sector information
uint8_t FN = subheader[0];
uint8_t CN = subheader[1];
uint8_t SM = subheader[2];
uint8_t CI = subheader[3];
unsigned fEOR = (SM >> 0) & 1;
unsigned fV = (SM >> 1) & 1;
unsigned fA = (SM >> 2) & 1;
unsigned fD = (SM >> 3) & 1;
unsigned fT = (SM >> 4) & 1;
unsigned fF = (SM >> 5) & 1;
unsigned fRT = (SM >> 6) & 1;
unsigned fEOF = (SM >> 7) & 1;
printf("Sector %02x:%02x:%02x: FN: %i, CN: %i, SM: <EOR:%i,V:%i,A:%i,D:%i,T:%i,F:%i,RT:%i,EOF:%i>, CI: %02x\n", m, s, f, FN, CN, fEOR, fV, fA, fD, fT, fF, fRT, fEOF, CI);
if (fA) {
unsigned S = (CI >> 0) & 3;
unsigned FS = (CI >> 2) & 3;
unsigned BL = (CI >> 4) & 3;
unsigned E = (CI >> 6) & 1;
const char * sS;
const char * sFS;
const char * sBL;
const char * sE;
switch (S) {
case 0:
sS = "Mono";
break;
case 1:
sS = "Stereo";
break;
case 2:
sS = "Unknown Stereo Setting 2";
break;
case 3:
sS = "Unknown Stereo Setting 3";
break;
}
switch (FS) {
case 0:
sFS = "37.8kHz";
break;
case 1:
sFS = "18.9kHz";
break;
case 2:
sFS = "Unknown sampling frequency 2";
break;
case 3:
sFS = "Unknown sampling frequency 3";
break;
}
switch (BL) {
case 0:
sBL = "4 bits";
break;
case 1:
sBL = "8 bits";
break;
case 2:
sBL = "Unknown bit length 2";
break;
case 3:
sBL = "Unknown bit length 3";
break;
}
switch (E) {
case 0:
sE = "Emphasis disabled";
break;
case 1:
sE = "Emphasis enabled";
break;
}
printf(" --> XA: %s; %s; %s; %s\n", sS, sFS, sBL, sE);
}
}
int main(int argc, char** argv) {
if (argc != 2) {
fprintf(stderr, "Need one argument with the iso filename.\n");
return 1;
}
FILE* in = fopen(argv[1], "rb");
if (!in) {
fprintf(stderr, "Failed to open input file %s\n", argv[1]);
return 1;
}
uint8_t buffer[2352];
unsigned lba = 150;
while (!feof(in)) {
int r = fread(buffer, 2352, 1, in);
if (!r) return 1;
probe_sector(buffer, lba++);
}
return 0;
}
@nicolasnoble
Copy link
Author

Glossary:

FN = File Number
CN = Channel Number
SM = Sub Mode
CI = Channel Information

EOR = End of Record
V = Video
A = Audio
D = Data
T = Trigger
F = Form
RT = Real Time Sector
EOF = End Of File

@nicolasnoble
Copy link
Author

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment