mirror of
https://github.com/whscullin/apple2js.git
synced 2024-01-12 14:14:38 +00:00
50 lines
1.5 KiB
TypeScript
50 lines
1.5 KiB
TypeScript
|
import { word } from 'js/types';
|
||
|
import { ProDOSVolume } from '.';
|
||
|
import type { VDH } from './vdh';
|
||
|
|
||
|
const BLOCK_ENTRIES = 4096;
|
||
|
|
||
|
export class BitMap {
|
||
|
private vdh: VDH;
|
||
|
private blocks: Uint8Array[];
|
||
|
|
||
|
constructor(volume: ProDOSVolume) {
|
||
|
this.vdh = volume.vdh();
|
||
|
this.blocks = volume.blocks();
|
||
|
}
|
||
|
|
||
|
|
||
|
allocBlock () {
|
||
|
for (let idx = 0; idx < this.vdh.totalBlocks; idx++) {
|
||
|
const blockOffset = this.vdh.bitMapPointer + Math.floor(idx / BLOCK_ENTRIES);
|
||
|
const bitMapBlock = this.blocks[blockOffset];
|
||
|
const byteOffset = (idx - blockOffset * BLOCK_ENTRIES) >> 8;
|
||
|
const bits = bitMapBlock[byteOffset];
|
||
|
if (bits !== 0xff) {
|
||
|
let mask = 0x01;
|
||
|
for (let bitOffset = 0; bitOffset < 8; bitOffset++) {
|
||
|
if (!(bits & mask)) {
|
||
|
bitMapBlock[byteOffset] |= mask;
|
||
|
return idx;
|
||
|
}
|
||
|
mask <<= 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
throw new Error('Disk full');
|
||
|
}
|
||
|
|
||
|
freeBlock(block: word) {
|
||
|
if (block >= this.vdh.totalBlocks) {
|
||
|
throw new Error('Block out of range');
|
||
|
}
|
||
|
const blockOffset = this.vdh.bitMapPointer + Math.floor(block / BLOCK_ENTRIES);
|
||
|
const byteOffset = (block - blockOffset * BLOCK_ENTRIES) >> 8;
|
||
|
const bitOffset = block & 0x7;
|
||
|
|
||
|
const bitMapBlock = this.blocks[blockOffset];
|
||
|
|
||
|
bitMapBlock[byteOffset] &= 0xff ^ (0x01 << bitOffset);
|
||
|
}
|
||
|
}
|