package storage import ( "encoding/binary" "errors" "io" ) /* Valid for ProDos disks in 2MG format. See: https://apple2.org.za/gswv/a2zine/Docs/DiskImage_2MG_Info.txt */ const ( file2mgPreamble = uint32(1196247346) // "2IMG" file2mgFormatProdos = 1 file2mgVersion = 1 ) type file2mgHeader struct { Preamble uint32 Creator uint32 HeaderSize uint16 Version uint16 Format uint32 Flags uint32 Blocks uint32 OffsetData uint32 LengthData uint32 OffsetComment uint32 LengthComment uint32 OffsetCreator uint32 LengthCreator uint32 } func parse2mg(bd *BlockDisk) error { fileInfo, err := bd.file.Stat() if err != nil { return err } var header file2mgHeader minHeaderSize := binary.Size(&header) if fileInfo.Size() < int64(minHeaderSize) { return errors.New("Invalid 2MG file") } err = readHeader(bd.file, &header) if err != nil { return err } bd.blocks = header.Blocks bd.dataOffset = header.OffsetData if fileInfo.Size() < int64(bd.dataOffset+bd.blocks*ProDosBlockSize) { return errors.New("The 2MG file is too small") } return nil } func readHeader(buf io.Reader, header *file2mgHeader) error { err := binary.Read(buf, binary.LittleEndian, header) if err != nil { return err } if header.Preamble != file2mgPreamble { return errors.New("The 2mg file must start with '2IMG'") } if header.Format != file2mgFormatProdos { return errors.New("Only prodos disks are supported") } if header.Version != file2mgVersion { return errors.New("Version of 2MG image not supported") } return nil }