298 lines
6.5 KiB
TypeScript
298 lines
6.5 KiB
TypeScript
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<typeof SUPPORTED_SECTORS>;
|
|
|
|
export const DRIVE_NUMBERS = [1, 2] as const;
|
|
export type DriveNumber = MemberOf<typeof DRIVE_NUMBERS>;
|
|
|
|
/**
|
|
* 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<NibbleFormat, 'woz'>;
|
|
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<typeof FLOPPY_FORMATS>;
|
|
export type NibbleFormat = MemberOf<typeof NIBBLE_FORMATS>;
|
|
export type BitstreamFormat = 'woz';
|
|
export type BlockFormat = MemberOf<typeof BLOCK_FORMATS>;
|
|
export type DiskFormat = MemberOf<typeof DISK_FORMATS>;
|
|
|
|
/** Type guard for nibble disk formats. */
|
|
export function isNibbleDiskFormat(f: DiskFormat): f is NibbleFormat {
|
|
return f in NIBBLE_FORMATS;
|
|
}
|
|
|
|
/** Type guard for block disk formats. */
|
|
export function isBlockDiskFormat(f: DiskFormat): f is BlockFormat {
|
|
return f in BLOCK_FORMATS;
|
|
}
|
|
|
|
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<DiskFormat, 'nib'>;
|
|
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<T> {
|
|
setBinary(drive: number, name: string, ext: T, data: ArrayBuffer): boolean;
|
|
getBinary(drive: number, ext?: T): MassStorageData | null;
|
|
}
|