mirror of
https://github.com/zellyn/diskii.git
synced 2024-11-25 04:31:32 +00:00
prodos: working on load/save of free block bitmap
This commit is contained in:
parent
df80529449
commit
1d7be34b5c
@ -12,10 +12,45 @@ import (
|
|||||||
"github.com/zellyn/diskii/lib/disk"
|
"github.com/zellyn/diskii/lib/disk"
|
||||||
)
|
)
|
||||||
|
|
||||||
type VolumeBitMap []disk.Block
|
// blockBase represents a 512-byte block of data.
|
||||||
|
type blockBase struct {
|
||||||
|
block uint16 // Block index this data was loaded from.
|
||||||
|
}
|
||||||
|
|
||||||
func NewVolumeBitMap(blocks uint16) VolumeBitMap {
|
// GetBlock gets the block index from a blockBase.
|
||||||
vbm := VolumeBitMap(make([]disk.Block, (blocks+(512*8)-1)/(512*8)))
|
func (bb blockBase) GetBlock() uint16 {
|
||||||
|
return bb.block
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetBlock sets the block index of a blockBase.
|
||||||
|
func (bb *blockBase) SetBlock(block uint16) {
|
||||||
|
bb.block = block
|
||||||
|
}
|
||||||
|
|
||||||
|
// A bitmapPart is a single block of a volumeBitMap.
|
||||||
|
type bitmapPart struct {
|
||||||
|
blockBase
|
||||||
|
data disk.Block
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromBlock unmarshals a bitmapPart from a Block.
|
||||||
|
func (bp *bitmapPart) FromBlock(block disk.Block) error {
|
||||||
|
bp.data = block
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToBlock marshals a bitmapPart struct to a block.
|
||||||
|
func (bp bitmapPart) ToBlock() (disk.Block, error) {
|
||||||
|
return bp.data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type VolumeBitMap []bitmapPart
|
||||||
|
|
||||||
|
func NewVolumeBitMap(startBlock uint16, blocks uint16) VolumeBitMap {
|
||||||
|
vbm := VolumeBitMap(make([]bitmapPart, (blocks+(512*8)-1)/(512*8)))
|
||||||
|
for i := range vbm {
|
||||||
|
vbm[i].SetBlock(startBlock + uint16(i))
|
||||||
|
}
|
||||||
for b := 0; b < int(blocks); b++ {
|
for b := 0; b < int(blocks); b++ {
|
||||||
vbm.MarkUnused(uint16(b))
|
vbm.MarkUnused(uint16(b))
|
||||||
}
|
}
|
||||||
@ -36,9 +71,9 @@ func (vbm VolumeBitMap) mark(block uint16, set bool) {
|
|||||||
blockByteIndex := byteIndex % 512
|
blockByteIndex := byteIndex % 512
|
||||||
bit := byte(1 << (7 - (block & 7)))
|
bit := byte(1 << (7 - (block & 7)))
|
||||||
if set {
|
if set {
|
||||||
vbm[blockIndex][blockByteIndex] |= bit
|
vbm[blockIndex].data[blockByteIndex] |= bit
|
||||||
} else {
|
} else {
|
||||||
vbm[blockIndex][blockByteIndex] &^= bit
|
vbm[blockIndex].data[blockByteIndex] &^= bit
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,29 +84,26 @@ func (vbm VolumeBitMap) IsFree(block uint16) bool {
|
|||||||
blockIndex := byteIndex / 512
|
blockIndex := byteIndex / 512
|
||||||
blockByteIndex := byteIndex % 512
|
blockByteIndex := byteIndex % 512
|
||||||
bit := byte(1 << (7 - (block & 7)))
|
bit := byte(1 << (7 - (block & 7)))
|
||||||
return vbm[blockIndex][blockByteIndex]&bit > 0
|
return vbm[blockIndex].data[blockByteIndex]&bit > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadVolumeBitMap
|
// ReadVolumeBitMap
|
||||||
func ReadVolumeBitMap(bd disk.BlockDevice, startBlock uint16) (VolumeBitMap, error) {
|
func ReadVolumeBitMap(bd disk.BlockDevice, startBlock uint16) (VolumeBitMap, error) {
|
||||||
blocks := bd.Blocks() / 4096
|
blocks := bd.Blocks() / 4096
|
||||||
vbm := make([]disk.Block, blocks)
|
vbm := NewVolumeBitMap(startBlock, blocks)
|
||||||
for i := uint16(0); i < blocks; i++ {
|
for i := 0; i < len(vbm); i++ {
|
||||||
block, err := bd.ReadBlock(startBlock + i)
|
if err := disk.UnmarshalBlock(bd, &vbm[i], vbm[i].GetBlock()); err != nil {
|
||||||
if err != nil {
|
return nil, fmt.Errorf("cannot read block %d (device block %d) of Volume Bit Map: %v", i, vbm[i].GetBlock(), err)
|
||||||
return nil, fmt.Errorf("cannot read block %d of Volume Bit Map: %v", err)
|
|
||||||
}
|
}
|
||||||
vbm[i] = block
|
|
||||||
}
|
}
|
||||||
return VolumeBitMap(vbm), nil
|
return VolumeBitMap(vbm), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write writes the Volume Bit Map to a block device, starting at the
|
// Write writes the Volume Bit Map to a block device.
|
||||||
// given block.
|
func (vbm VolumeBitMap) Write(bd disk.BlockDevice) error {
|
||||||
func (vbm VolumeBitMap) Write(bd disk.BlockDevice, startBlock uint16) error {
|
for i, bp := range vbm {
|
||||||
for i, block := range vbm {
|
if err := disk.MarshalBlock(bd, bp); err != nil {
|
||||||
if err := bd.WriteBlock(startBlock+uint16(i), block); err != nil {
|
return fmt.Errorf("cannot write block %d (device block %d) of Volume Bit Map: %v", i, bp.GetBlock(), err)
|
||||||
return fmt.Errorf("cannot write block %d of Volume Bit Map: %v", err)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
Loading…
Reference in New Issue
Block a user