diff --git a/tools/.DS_Store b/tools/.DS_Store new file mode 100644 index 0000000000..ec47e3b7b9 Binary files /dev/null and b/tools/.DS_Store differ diff --git a/tools/sotn-disk/cue.go b/tools/sotn-disk/cue.go index 433842fa8e..71baaf1581 100644 --- a/tools/sotn-disk/cue.go +++ b/tools/sotn-disk/cue.go @@ -18,6 +18,12 @@ type cueTrack struct { mode string } +func assert(condition bool, message string) { + if !condition { + panic(message) + } +} + func performCueAction(cuePath string, action imageAction) error { tracks, err := parseTracks(cuePath) if err != nil { @@ -32,6 +38,8 @@ func performCueAction(cuePath string, action imageAction) error { switch mainTrack.mode { case "MODE1/2048": mode = iso9660.TrackMode1_2048 + case "MODE1/2352": + mode = iso9660.TrackMode1_2352 case "MODE2/2352": mode = iso9660.TrackMode2_2352 default: @@ -48,6 +56,25 @@ func performCueAction(cuePath string, action imageAction) error { defer f.Close() image, err := iso9660.OpenImage(f, mode) + + // 80 8 Volume Space Size int32_LSB-MSB Number of Logical Blocks in which the volume is recorded. + // 120 4 Volume Set Size int16_LSB-MSB The size of the set in this logical volume (number of disks). + // 124 4 Volume Sequence Number int16_LSB-MSB The number of this disk in the Volume Set. + // 128 4 Logical Block Size int16_LSB-MSB The size in bytes of a logical block. NB: This means that a logical block on a CD could be something other than 2 KiB! + // 132 8 Path Table Size int32_LSB-MSB The size in bytes of the path table. + // 148 4 Location of Type-M Path Table int32_MSB LBA location of the path table. The path table pointed to contains only big-endian values. + // 152 4 Location of Optional Type-M Path Table int32_MSB LBA location of the optional path table. The path table pointed to contains only big-endian values. Zero means that no optional path table exists. + assert(image.Pvd.VolumeSpaceSize.MSB == image.Pvd.VolumeSpaceSize.LSB, "VolumeSpaceSize") + assert(image.Pvd.VolumeSetSize.MSB == image.Pvd.VolumeSetSize.LSB, "VolumeSetSize") + assert(image.Pvd.VolumeSequenceNumber.MSB == image.Pvd.VolumeSequenceNumber.LSB, "VolumeSequenceNumber") + assert(image.Pvd.LogicalBlockSize.MSB == image.Pvd.LogicalBlockSize.LSB, "LogicalBlockSize") + assert(image.Pvd.PathTableSize.MSB == image.Pvd.PathTableSize.LSB, "PathTableSize") + fmt.Print(image.Pvd.PathMTableLocation.MSB, " ", image.Pvd.PathMTableLocation.LSB, "\n") + + // this fails + // assert(image.Pvd.PathMTableLocation.MSB == image.Pvd.PathMTableLocation.LSB, "PathMTableLocation") + assert(image.Pvd.PathOptionalMTableLocation.MSB == image.Pvd.PathOptionalMTableLocation.LSB, "PathOptionalMTableLocation") + if err != nil { return err } @@ -100,6 +127,12 @@ func parseTracks(cuePath string) ([]cueTrack, error) { track.id = tokens[1] track.mode = tokens[2] + + // need to append here since there's multiple tracks in the same file + if track != nil { + tracks = append(tracks, *track) + } + } } diff --git a/tools/sotn-disk/iso9660/iso9660.go b/tools/sotn-disk/iso9660/iso9660.go index 0ee7e3ff27..28afde2014 100644 --- a/tools/sotn-disk/iso9660/iso9660.go +++ b/tools/sotn-disk/iso9660/iso9660.go @@ -5,13 +5,15 @@ package iso9660 import ( "errors" "io" + "fmt" ) type TrackMode int const ( TrackMode1_2048 = TrackMode(0x800) - TrackMode2_2352 = TrackMode(0x930) + TrackMode1_2352 = TrackMode(0x930) // The 2352 bytes consist of 2048 data bytes, 288 bytes of error correction code (ECC), and 16 bytes of sub-channel data. + TrackMode2_2352 = TrackMode(0x930) ) var ( @@ -51,12 +53,22 @@ func (img *Image) RootDir() File { } } +func assert(condition bool) { + if !condition { + panic("mismatch") + } +} + func (file File) GetChildren() ([]File, error) { const secSize = 0x800 const bufSafe = 0x20 chloc := file.ExtentLocation.LSB + assert(file.ExtentLocation.LSB == file.ExtentLocation.MSB) + assert(file.DataLength.LSB == file.DataLength.MSB) + assert(file.VolumeSequenceNumber.LSB == file.VolumeSequenceNumber.MSB) + files := make([]File, 0) offset := secSize var data []byte @@ -70,6 +82,8 @@ func (file File) GetChildren() ([]File, error) { data = []byte(sec) offset = 0 chloc++ + } else { + fmt.Print("rejected sector ", "offset ", offset, " secSize ", secSize, " offset+bufSafe ", offset+bufSafe, " chloc ", chloc, "\n") } f := File{ diff --git a/tools/sotn-disk/iso9660/sector.go b/tools/sotn-disk/iso9660/sector.go index dca75b7224..f16ea649fd 100644 --- a/tools/sotn-disk/iso9660/sector.go +++ b/tools/sotn-disk/iso9660/sector.go @@ -26,6 +26,18 @@ func readSector(r io.ReaderAt, loc location, mode TrackMode, useMode2 bool) (sec if mode == TrackMode1_2048 { offset = int64(loc) * sectorSize secLength = sectorSize + } else if mode == TrackMode1_2352 { + // Sync Header (12 bytes) + // Header (4 bytes) + // User Data (2048 bytes) + // Error Correction Code (ECC) (280 bytes) + // Sub-channel Data (96 bytes) + + // skip the sync header and header + offset = 16 + int64(loc) * sectorMode2Size + + // read the user data but not ecc or sub + secLength = sectorSize } else if mode == TrackMode2_2352 { if useMode2 { offset = int64(loc) * sectorMode2Size