Add reading of BIOS parameter block
This commit is contained in:
parent
d32ba75413
commit
4ae049f5d4
19
src/components/DiskInfo.vue
Normal file
19
src/components/DiskInfo.vue
Normal 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>
|
||||||
@ -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>
|
|
||||||
|
|||||||
@ -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
61
src/floppy/disk.ts
Normal 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,
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user