import type { byte, memory, MemberOf, word } from '../types'; import type { GamepadConfiguration } from '../ui/types'; import { InfoChunk } from './woz'; export const SUPPORTED_SECTORS = [13, 16] as const; export type SupportedSectors = MemberOf; export const DRIVE_NUMBERS = [1, 2] as const; export type DriveNumber = MemberOf; /** * Arguments for the disk format processors. */ export interface DiskOptions { name: string; side?: string | undefined; volume: byte; readOnly: boolean; data?: memory[][]; rawData?: ArrayBuffer; blockVolume?: boolean; } /** * JSON file entry format */ export interface DiskDescriptor { name: string; disk?: number; filename: string; e?: boolean; category: string; } /** * JSON binary image (not used?) */ export interface JSONBinaryImage { type: 'binary'; start: word; length: word; data: byte[]; gamepad?: GamepadConfiguration; } /** * Information about a disk image not directly related to the * disk contents. For example, the name or even a scan of the * disk label are "metadata", but the volume number is not. */ export interface DiskMetadata { /** Displayed disk name */ name: string; /** (Optional) Disk side (Front/Back, A/B) */ side?: string | undefined; } /** * Return value from disk format processors. Describes raw disk * data which the DiskII card can process. */ export interface Disk { metadata: DiskMetadata; readOnly: boolean; } export const NO_DISK = 'empty'; export const ENCODING_NIBBLE = 'nibble'; export const ENCODING_BITSTREAM = 'bitstream'; export const ENCODING_BLOCK = 'block'; export interface FloppyDisk extends Disk { encoding: typeof ENCODING_NIBBLE | typeof ENCODING_BITSTREAM | typeof NO_DISK; } export interface NoFloppyDisk extends FloppyDisk { encoding: typeof NO_DISK; } export interface NibbleDisk extends FloppyDisk { encoding: typeof ENCODING_NIBBLE; format: Exclude; volume: byte; tracks: memory[]; } export interface WozDisk extends FloppyDisk { encoding: typeof ENCODING_BITSTREAM; format: 'woz'; trackMap: number[]; rawTracks: Uint8Array[]; info: InfoChunk | undefined; } export interface BlockDisk extends Disk { encoding: typeof ENCODING_BLOCK; format: BlockFormat; blocks: Uint8Array[]; } /** * File types supported by floppy devices in nibble mode. */ export const NIBBLE_FORMATS = [ '2mg', 'd13', 'do', 'dsk', 'po', 'nib', ] as const; /** * File types supported by floppy devices in bitstream mode. */ export const BITSTREAM_FORMATS = [ 'woz', ] as const; /** * All file types supported by floppy devices. */ export const FLOPPY_FORMATS = [ ...NIBBLE_FORMATS, ...BITSTREAM_FORMATS, ] as const; /** * File types supported by block devices. */ export const BLOCK_FORMATS = [ '2mg', 'hdv', 'po', ] as const; /** * All supported disk formats. */ export const DISK_FORMATS = [ ...FLOPPY_FORMATS, ...BLOCK_FORMATS, ] as const; export type FloppyFormat = MemberOf; export type NibbleFormat = MemberOf; export type BitstreamFormat = 'woz'; export type BlockFormat = MemberOf; export type DiskFormat = MemberOf; /** Type guard for nibble disk formats. */ export function isNibbleDiskFormat(f: DiskFormat): f is NibbleFormat { return NIBBLE_FORMATS.includes(f as NibbleFormat); } /** Type guard for block disk formats. */ export function isBlockDiskFormat(f: DiskFormat): f is BlockFormat { return BLOCK_FORMATS.includes(f as BlockFormat); } export function isNoFloppyDisk(disk: Disk): disk is NoFloppyDisk { return (disk as NoFloppyDisk)?.encoding === NO_DISK; } /** Type guard for NibbleDisks */ export function isNibbleDisk(disk: Disk): disk is NibbleDisk { return (disk as NibbleDisk)?.encoding === ENCODING_NIBBLE; } /** Type guard for NibbleDisks */ export function isWozDisk(disk: Disk): disk is WozDisk { return (disk as WozDisk)?.encoding === ENCODING_BITSTREAM; } /** * Base format for JSON defined disks */ export class JSONDiskBase { type: DiskFormat; name: string; disk?: string; category?: string; volume?: byte; readOnly?: boolean; gamepad?: GamepadConfiguration; } /** * JSON Disk format with base64 encoded tracks with sectors */ export interface Base64JSONDisk extends JSONDiskBase { type: Exclude; encoding: 'base64'; data: string[][]; } /** * JSON Disk format with base64 encoded nibblized tracks */ export interface Base64JSONNibbleDisk extends JSONDiskBase { type: 'nib'; encoding: 'base64'; data: string[]; } /** * JSON Disk format with byte array tracks */ export interface BinaryJSONDisk extends JSONDiskBase { type: DiskFormat; encoding: 'binary'; data: memory[][]; } /** * General JSON Disk format */ export type JSONDisk = Base64JSONDisk | Base64JSONNibbleDisk | BinaryJSONDisk; /** * Process Disk message payloads for worker */ export const PROCESS_BINARY = 'PROCESS_BINARY'; export const PROCESS_JSON_DISK = 'PROCESS_JSON_DISK'; export const PROCESS_JSON = 'PROCESS_JSON'; /** Binary disk file message */ export interface ProcessBinaryMessage { type: typeof PROCESS_BINARY; payload: { driveNo: DriveNumber; fmt: FloppyFormat; options: DiskOptions; }; } /** Processed JSON file message (used for localStorage) */ export interface ProcessJsonDiskMessage { type: typeof PROCESS_JSON_DISK; payload: { driveNo: DriveNumber; jsonDisk: JSONDisk; }; } /** Raw JSON file message */ export interface ProcessJsonMessage { type: typeof PROCESS_JSON; payload: { driveNo: DriveNumber; json: string; }; } export type FormatWorkerMessage = ProcessBinaryMessage | ProcessJsonDiskMessage | ProcessJsonMessage; /** * Format work result message type */ export const DISK_PROCESSED = 'DISK_PROCESSED'; export interface DiskProcessedResponse { type: typeof DISK_PROCESSED; payload: { driveNo: DriveNumber; disk: FloppyDisk | null; }; } export type FormatWorkerResponse = DiskProcessedResponse; export interface MassStorageData { metadata: DiskMetadata; ext: DiskFormat; readOnly: boolean; volume?: byte; data: ArrayBuffer; } /** * Block device common interface */ export interface MassStorage { setBinary(drive: number, name: string, ext: T, data: ArrayBuffer): boolean; getBinary(drive: number, ext?: T): MassStorageData | null; }