diskm8/disk/diskimage2mg.go

107 lines
2.8 KiB
Go

package disk
import "fmt"
/*
2MG format loader...
*/
const PREAMBLE_2MG_SIZE = 0x40
var MAGIC_2MG = []byte{byte('2'), byte('I'), byte('M'), byte('G')}
type Header2MG struct {
Data [64]byte
}
func (h *Header2MG) SetData(data []byte) {
for i, v := range data {
if i < 64 {
h.Data[i] = v
}
}
}
func (h *Header2MG) GetID() string {
return string(h.Data[0x00:0x04])
}
func (h *Header2MG) GetCreatorID() string {
return string(h.Data[0x04:0x08])
}
func (h *Header2MG) GetHeaderSize() int {
return int(h.Data[0x08]) + 256*int(h.Data[0x09])
}
func (h *Header2MG) GetVersion() int {
return int(h.Data[0x0A]) + 256*int(h.Data[0x0B])
}
func (h *Header2MG) GetImageFormat() int {
return int(h.Data[0x0C]) + 256*int(h.Data[0x0D]) + 65336*int(h.Data[0x0E]) + 16777216*int(h.Data[0x0F])
}
func (h *Header2MG) GetDOSFlags() int {
return int(h.Data[0x10]) + 256*int(h.Data[0x11]) + 65336*int(h.Data[0x12]) + 16777216*int(h.Data[0x13])
}
func (h *Header2MG) GetProDOSBlocks() int {
return int(h.Data[0x14]) + 256*int(h.Data[0x15]) + 65336*int(h.Data[0x16]) + 16777216*int(h.Data[0x17])
}
func (h *Header2MG) GetDiskDataStart() int {
return int(h.Data[0x18]) + 256*int(h.Data[0x19]) + 65336*int(h.Data[0x1A]) + 16777216*int(h.Data[0x1B])
}
func (h *Header2MG) GetDiskDataLength() int {
return int(h.Data[0x1C]) + 256*int(h.Data[0x1D]) + 65336*int(h.Data[0x1E]) + 16777216*int(h.Data[0x1F])
}
func (dsk *DSKWrapper) Is2MG() (bool, DiskFormat, SectorOrder, *DSKWrapper) {
h := &Header2MG{}
h.SetData(dsk.Data[:0x40])
if h.GetID() != "2IMG" {
return false, GetDiskFormat(DF_NONE), SectorOrderDOS33, nil
}
fmt.Println("Disk has 2MG Magic")
fmt.Printf("Block count %d\n", h.GetProDOSBlocks())
start := h.GetDiskDataStart()
size := h.GetDiskDataLength()
if size < len(dsk.Data)-start {
size = len(dsk.Data) - start
}
if size != STD_DISK_BYTES && size != PRODOS_800KB_DISK_BYTES && size != PRODOS_400KB_DISK_BYTES {
fmt.Printf("Bad size %d bytes @ start %d\n", size, start)
return false, GetDiskFormat(DF_NONE), SectorOrderDOS33, nil
}
data := dsk.Data[start : start+size]
format := h.GetImageFormat()
switch format {
case 0x00: /* DOS sector order */
zdsk, _ := NewDSKWrapperBin(dsk.Nibbles, data, dsk.Filename)
return true, GetDiskFormat(DF_DOS_SECTORS_16), SectorOrderDOS33, zdsk
case 0x01: /* ProDOS sector order */
zdsk, _ := NewDSKWrapperBin(dsk.Nibbles, data, dsk.Filename)
if h.GetProDOSBlocks() == 1600 {
return true, GetDiskFormat(DF_PRODOS_800KB), SectorOrderProDOSLinear, zdsk
} else if h.GetProDOSBlocks() == 800 {
return true, GetDiskFormat(DF_PRODOS_400KB), SectorOrderProDOSLinear, zdsk
} else {
return true, GetPDDiskFormat(DF_PRODOS_CUSTOM, h.GetProDOSBlocks()), SectorOrderProDOSLinear, zdsk
}
}
return false, GetDiskFormat(DF_NONE), SectorOrderDOS33, nil
}