Improve boot sectore decoding

This commit is contained in:
Jordan Goulder 2025-01-14 16:18:16 -05:00
parent 85e07598d4
commit 98ad0d4dfe
3 changed files with 99 additions and 54 deletions

View File

@ -1,20 +1,18 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { getBiosParameterBlock } from '@/floppy/disk.ts'
import PropertyList from '@/components/PropertyList.vue'
import { decodeBootSector } from '@/floppy/disk.ts'
const { data = new ArrayBuffer(0) } = defineProps<{ data: ArrayBuffer }>()
const biosParameterBlock = computed(() => {
return getBiosParameterBlock(data)
const bootSector = computed(() => {
return decodeBootSector(data)
})
</script>
<template>
<section v-if="biosParameterBlock">
<h3>BIOS Parameter Block (BPB)</h3>
<PropertyList :obj="biosParameterBlock" />
<pre>{{ biosParameterBlock }}</pre>
<section v-if="bootSector">
<h3>Boot Sector</h3>
<pre>{{ bootSector }}</pre>
</section>
</template>

View File

@ -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;

View File

@ -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,
jumpInstruction,
oemName,
bootPartitionSignature,
biosParameterBlock: {
bytesPerSector,
sectorsPerCluster,
numReservedSectors,
numFATs,
numRootDirEntries,
totalSectors,
mediaTypeDescriptor,
sectorsPerFAT,
reservedSectorCount,
tableCount,
rootEntryCount,
totalSectorsSmall,
mediaDescriptorType,
sectorsPerTableSmall,
sectorsPerTrack,
numHeads,
headCount,
hiddenSectorCount,
totalSectorsLarge,
},
extendedBootSector: {
driveNumber,
reserved,
bootSignature,
volumeId,
volumeLabel,
fileSystemId,
fileSystemType,
},
}
}