diff --git a/src/components/DiskInfo.vue b/src/components/DiskInfo.vue index a1663cf..208c2cd 100644 --- a/src/components/DiskInfo.vue +++ b/src/components/DiskInfo.vue @@ -1,20 +1,18 @@ diff --git a/src/components/HexDump.vue b/src/components/HexDump.vue index 8c483e7..313d903 100644 --- a/src/components/HexDump.vue +++ b/src/components/HexDump.vue @@ -76,7 +76,7 @@ pre { width: fit-content; padding: 0.5em 1em 10em; box-sizing: border-box; - overflow: scroll; + overflow-y: scroll; min-height: 10rem; height: 20rem; max-height: 20rem; diff --git a/src/floppy/disk.ts b/src/floppy/disk.ts index f110c4a..3405e0a 100644 --- a/src/floppy/disk.ts +++ b/src/floppy/disk.ts @@ -1,61 +1,108 @@ -export interface BiosParameterBlock { - oemId: string - bytesPerSector: number - sectorsPerCluster: number - numReservedSectors: number - numFATs: number - numRootDirEntries: number - totalSectors: number - mediaTypeDescriptor: number - sectorsPerFAT: number - sectorsPerTrack: number - numHeads: number - bootSignature: number - volumeId: number - volumeLabel: string - fileSystemId: string +export interface IBootSectorInfo { + jumpInstruction: [number, number, number] + oemName: string + biosParameterBlock: IBiosParameterBlock + extendedBootSector: IExtendedBootSectorSmall + bootPartitionSignature: number } -export function getBiosParameterBlock(buffer: ArrayBuffer): BiosParameterBlock | null { - if (buffer.byteLength < 64) { +export interface IExtendedBootSectorSmall { + driveNumber: number + reserved: number + bootSignature: number + volumeId?: number + volumeLabel?: string + fileSystemType?: string +} + +export interface IBiosParameterBlock { + bytesPerSector: number + sectorsPerCluster: number + reservedSectorCount: number + tableCount: number + rootEntryCount: number + totalSectorsSmall: number + mediaDescriptorType: number + sectorsPerTableSmall: number + sectorsPerTrack: number + headCount: number + hiddenSectorCount: number + totalSectorsLarge: number +} + +export function decodeBootSector(buffer: ArrayBuffer): IBootSectorInfo | null { + if (buffer.byteLength < 512) { return null } + const asciiDecoder = new TextDecoder('ascii') const data = new DataView(buffer) - const asciiDecoder = new TextDecoder('ascii') + const jumpInstruction: [number, number, number] = [ + data.getUint8(0), + data.getUint8(1), + data.getUint8(2), + ] - const oemId = asciiDecoder.decode(buffer.slice(3, 11)) + const oemName = asciiDecoder.decode(buffer.slice(3, 11)) const bytesPerSector = data.getUint16(11, true) const sectorsPerCluster = data.getUint8(13) - const numReservedSectors = data.getUint16(14, true) - const numFATs = data.getUint8(16) - const numRootDirEntries = data.getUint16(17, true) - const totalSectors = data.getUint16(19, true) - const mediaTypeDescriptor = data.getUint8(21) - const sectorsPerFAT = data.getUint16(22, true) + const reservedSectorCount = data.getUint16(14, true) + const tableCount = data.getUint8(16) + const rootEntryCount = data.getUint16(17, true) + const totalSectorsSmall = data.getUint16(19, true) + const mediaDescriptorType = data.getUint8(21) + const sectorsPerTableSmall = data.getUint16(22, true) const sectorsPerTrack = data.getUint16(24, true) - const numHeads = data.getUint16(26, true) + const headCount = data.getUint16(26, true) + const hiddenSectorCount = data.getUint32(28, true) + const totalSectorsLarge = data.getUint32(32, true) + const driveNumber = data.getUint8(36) + const reserved = data.getUint8(37) const bootSignature = data.getUint8(38) - const volumeId = data.getUint32(39, true) - const volumeLabel = asciiDecoder.decode(buffer.slice(43, 54)) - const fileSystemId = asciiDecoder.decode(buffer.slice(54, 62)) + + let volumeId + if (bootSignature === 0x28 || bootSignature === 0x29) { + volumeId = data.getUint32(39, true) + } + + let volumeLabel + if (bootSignature === 0x29) { + volumeLabel = asciiDecoder.decode(buffer.slice(43, 54)) + } + + let fileSystemType + if (bootSignature === 0x29) { + fileSystemType = asciiDecoder.decode(buffer.slice(54, 62)) + } + + const bootPartitionSignature = data.getUint16(510, true) return { - oemId, - bytesPerSector, - sectorsPerCluster, - numReservedSectors, - numFATs, - numRootDirEntries, - totalSectors, - mediaTypeDescriptor, - sectorsPerFAT, - sectorsPerTrack, - numHeads, - bootSignature, - volumeId, - volumeLabel, - fileSystemId, + jumpInstruction, + oemName, + bootPartitionSignature, + biosParameterBlock: { + bytesPerSector, + sectorsPerCluster, + reservedSectorCount, + tableCount, + rootEntryCount, + totalSectorsSmall, + mediaDescriptorType, + sectorsPerTableSmall, + sectorsPerTrack, + headCount, + hiddenSectorCount, + totalSectorsLarge, + }, + extendedBootSector: { + driveNumber, + reserved, + bootSignature, + volumeId, + volumeLabel, + fileSystemType, + }, } }