Add reading of BIOS parameter block

This commit is contained in:
Jordan Goulder 2025-01-13 00:28:30 -05:00
parent d32ba75413
commit 4ae049f5d4
4 changed files with 116 additions and 41 deletions

View File

@ -0,0 +1,19 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { getBiosParameterBlock } from '@/floppy/disk.ts'
const { data = new ArrayBuffer(0) } = defineProps<{ data: ArrayBuffer }>()
const biosParameterBlock = computed(() => {
return getBiosParameterBlock(data)
})
</script>
<template>
<section v-if="biosParameterBlock">
<h3>BIOS Parameter Block (BPB)</h3>
<pre>{{ biosParameterBlock }}</pre>
</section>
</template>
<style scoped></style>

View File

@ -1,10 +1,8 @@
<script lang="ts" setup></script> <script lang="ts" setup></script>
<template> <template>
<header> <h1>Floppy Drive</h1>
<h1>Floppy Drive</h1> <p>Load floppy disk(images) right from your browser.</p>
<p>Load floppy disk(images) right from your browser.</p>
</header>
<section> <section>
<h2>What is it?</h2> <h2>What is it?</h2>
<p> <p>
@ -22,10 +20,4 @@
</section> </section>
</template> </template>
<style scoped> <style scoped></style>
header p {
margin: 0;
font-style: italic;
font-size: 0.95em;
}
</style>

View File

@ -2,6 +2,7 @@
import { ref } from 'vue' import { ref } from 'vue'
import DiskReader from '@/components/DiskReader.vue' import DiskReader from '@/components/DiskReader.vue'
import HexDump from '@/components/HexDump.vue' import HexDump from '@/components/HexDump.vue'
import DiskInfo from '@/components/DiskInfo.vue'
type DiskReadyState = 'empty' | 'read-started' | 'read-success' | 'read-failed' type DiskReadyState = 'empty' | 'read-started' | 'read-success' | 'read-failed'
@ -45,39 +46,41 @@ function onReadProgress(read: number, total: number) {
<nav> <nav>
<a href="/#/">Home</a> <a href="/#/">Home</a>
</nav> </nav>
<h1>Playground</h1>
<p>This is my playground for testing out my code.</p>
<p>
<strong><em>WARNING!!!</em> Use at your own risk!</strong>
</p>
<section> <section>
<h2>Playground</h2> <h2>Disk Read</h2>
<p>This is my playground for testing out my code.</p> <div class="cols">
<p> <DiskReader
<strong><em>WARNING!!!</em> Use at your own risk!</strong> @error="onReadError"
</p> @progress="onReadProgress"
<section> @start="onReadStart"
<h3>Disk Read</h3> @success="onReadSuccess"
<div class="cols"> />
<DiskReader <div v-if="diskReadyState === 'read-started'">
@error="onReadError" {{ diskName }} reading
@progress="onReadProgress" <progress :max="diskTotalBytes" :value="diskReadBytes">
@start="onReadStart"
@success="onReadSuccess"
/>
<div v-if="diskReadyState === 'read-started'">
{{ diskName }} reading
<progress :max="diskTotalBytes" :value="diskReadBytes">
{{ ((diskReadBytes / diskTotalBytes) * 100.0).toFixed(2) }} %
</progress>
{{ ((diskReadBytes / diskTotalBytes) * 100.0).toFixed(2) }} % {{ ((diskReadBytes / diskTotalBytes) * 100.0).toFixed(2) }} %
</div> </progress>
<div v-else-if="diskReadyState === 'read-success'">{{ diskName }} loaded</div> {{ ((diskReadBytes / diskTotalBytes) * 100.0).toFixed(2) }} %
<div v-else-if="diskReadyState === 'read-failed'">
error reading disk: {{ diskReadError }}
</div>
<div v-else>No disk loaded</div>
</div> </div>
</section> <div v-else-if="diskReadyState === 'read-success'">{{ diskName }} loaded</div>
<section> <div v-else-if="diskReadyState === 'read-failed'">
<h3>Disk Hex Dump</h3> error reading disk: {{ diskReadError }}
<HexDump :buffer="diskData" /> </div>
</section> <div v-else>No disk loaded</div>
</div>
</section>
<section>
<h2>Disk Hex Dump</h2>
<HexDump :buffer="diskData" />
</section>
<section>
<h2>Disk Info</h2>
<DiskInfo :data="diskData" />
</section> </section>
</template> </template>

61
src/floppy/disk.ts Normal file
View File

@ -0,0 +1,61 @@
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 function getBiosParameterBlock(buffer: ArrayBuffer): BiosParameterBlock | null {
if (buffer.byteLength < 64) {
return null
}
const data = new DataView(buffer)
const asciiDecoder = new TextDecoder('ascii')
const oemId = 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 sectorsPerTrack = data.getUint16(24, true)
const numHeads = data.getUint16(26, true)
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))
return {
oemId,
bytesPerSector,
sectorsPerCluster,
numReservedSectors,
numFATs,
numRootDirEntries,
totalSectors,
mediaTypeDescriptor,
sectorsPerFAT,
sectorsPerTrack,
numHeads,
bootSignature,
volumeId,
volumeLabel,
fileSystemId,
}
}