mirror of
https://github.com/ivanizag/izapple2.git
synced 2024-12-27 11:30:02 +00:00
85 lines
1.6 KiB
Go
85 lines
1.6 KiB
Go
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
|
|
}
|