izapple2/hardDisk.go

85 lines
1.6 KiB
Go

package apple2
import (
"bytes"
"encoding/binary"
)
/*
Valid for ProDos hard disks in 2MG format. Read only.
See:
https://apple2.org.za/gswv/a2zine/Docs/DiskImage_2MG_Info.txt
*/
const (
proDosBlockSize = uint32(512)
hardDisk2mgPreamble = uint32(1196247346) // "2IMG"
hardDisk2mgFormatProdos = 1
hardDisk2mgVersion = 1
)
type hardDisk struct {
data []uint8
header hardDisk2mgHeader
}
type hardDisk2mgHeader 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 (hd *hardDisk) read(block uint32) []uint8 {
if block >= hd.header.Blocks {
return nil
}
offset := hd.header.OffsetData + block*proDosBlockSize
return hd.data[offset : offset+proDosBlockSize]
}
func loadHardDisk2mg(filename string) *hardDisk {
var hd hardDisk
hd.data = loadResource(filename)
size := len(hd.data)
if size < binary.Size(&hd.header) {
panic("2mg file is too short")
}
buf := bytes.NewReader(hd.data)
err := binary.Read(buf, binary.LittleEndian, &hd.header)
if err != nil {
panic(err)
}
if hd.header.Preamble != hardDisk2mgPreamble {
panic("2mg file must start with '2IMG'")
}
if hd.header.Format != hardDisk2mgFormatProdos {
panic("Only prodos hard disks are supported")
}
if hd.header.Version != hardDisk2mgVersion {
panic("Version of 2MG image not supported")
}
if size < int(hd.header.OffsetData+hd.header.Blocks*proDosBlockSize) {
panic("Thr 2MG file is too small")
}
return &hd
}