diff --git a/.eslintrc.json b/.eslintrc.json index 442f3ea..3407a0a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -25,6 +25,19 @@ "error", "always" ], + "@typescript-eslint/member-delimiter-style": [ + "error", + { + "multiline": { + "delimiter": "semi", + "requireLast": true + }, + "singleline": { + "delimiter": "semi", + "requireLast": false + } + } + ], "no-use-before-define": "off", "@typescript-eslint/no-floating-promises": "error", "@typescript-eslint/no-use-before-define": [ diff --git a/js/apple2io.ts b/js/apple2io.ts index 5895995..caffcb1 100644 --- a/js/apple2io.ts +++ b/js/apple2io.ts @@ -9,15 +9,15 @@ type paddle = 0 | 1 | 2 | 3; type annunciator = 0 | 1 | 2 | 3; interface Annunciators { - 0: boolean, - 1: boolean, - 2: boolean, - 3: boolean, + 0: boolean; + 1: boolean; + 2: boolean; + 3: boolean; } export interface Apple2IOState { annunciators: Annunciators; - cards: Array + cards: Array; } export type SampleListener = (sample: number[]) => void; diff --git a/js/cards/cffa.ts b/js/cards/cffa.ts index be18880..4751f1f 100644 --- a/js/cards/cffa.ts +++ b/js/cards/cffa.ts @@ -82,7 +82,7 @@ const IDENTITY = { }; export interface CFFAState { - disks: Array + disks: Array; } export default class CFFA implements Card, MassStorage, Restorable { diff --git a/js/cards/disk2.ts b/js/cards/disk2.ts index c0ef974..bc6a3e0 100644 --- a/js/cards/disk2.ts +++ b/js/cards/disk2.ts @@ -161,29 +161,29 @@ export interface Callbacks { interface BaseDrive { /** Current disk format. */ - format: NibbleFormat, + format: NibbleFormat; /** Current disk volume number. */ - volume: byte, + volume: byte; /** Displayed disk name */ - name: string, + name: string; /** (Optional) Disk side (Front/Back, A/B) */ - side?: string, + side?: string; /** Quarter track position of read/write head. */ - track: byte, + track: byte; /** Position of the head on the track. */ - head: byte, + head: byte; /** Current active coil in the head stepper motor. */ - phase: Phase, + phase: Phase; /** Whether the drive write protect is on. */ - readOnly: boolean, + readOnly: boolean; /** Whether the drive has been written to since it was loaded. */ - dirty: boolean, + dirty: boolean; } /** WOZ format track data from https://applesaucefdc.com/woz/reference2/. */ interface WozDrive extends BaseDrive { /** Woz encoding */ - encoding: typeof ENCODING_BITSTREAM + encoding: typeof ENCODING_BITSTREAM; /** Maps quarter tracks to data in rawTracks; `0xFF` = random garbage. */ trackMap: byte[]; /** Unique track bitstreams. The index is arbitrary; it is NOT the track number. */ @@ -193,7 +193,7 @@ interface WozDrive extends BaseDrive { /** Nibble format track data. */ interface NibbleDrive extends BaseDrive { /** Nibble encoding */ - encoding: typeof ENCODING_NIBBLE + encoding: typeof ENCODING_NIBBLE; /** Nibble data. The index is the track number. */ tracks: memory[]; } @@ -209,19 +209,19 @@ function isWozDrive(drive: Drive): drive is WozDrive { } interface DriveState { - format: NibbleFormat, - encoding: typeof ENCODING_BITSTREAM | typeof ENCODING_NIBBLE - volume: byte, - name: string, - side?: string, - tracks: memory[], - track: byte, - head: byte, - phase: Phase, - readOnly: boolean, - dirty: boolean, - trackMap: number[], - rawTracks: Uint8Array[], + format: NibbleFormat; + encoding: typeof ENCODING_BITSTREAM | typeof ENCODING_NIBBLE; + volume: byte; + name: string; + side?: string; + tracks: memory[]; + track: byte; + head: byte; + phase: Phase; + readOnly: boolean; + dirty: boolean; + trackMap: number[]; + rawTracks: Uint8Array[]; } interface State { diff --git a/js/cards/mouse.ts b/js/cards/mouse.ts index cc7083b..6f9daaf 100644 --- a/js/cards/mouse.ts +++ b/js/cards/mouse.ts @@ -44,7 +44,7 @@ const ENTRIES = { interface MouseState { clampXMin: word; clampYMin: word; - clampXMax: word + clampXMax: word; clampYMax: word; x: word; y: word; @@ -94,8 +94,8 @@ export default class Mouse implements Card, Restorable { constructor( private cpu: CPU6502, private cbs: { - setMouse: (mouse: Mouse) => void, - mouseMode: (on: boolean) => void + setMouse: (mouse: Mouse) => void; + mouseMode: (on: boolean) => void; } ) { this.cbs.setMouse(this); diff --git a/js/cards/smartport.ts b/js/cards/smartport.ts index 49342cc..b9b5278 100644 --- a/js/cards/smartport.ts +++ b/js/cards/smartport.ts @@ -11,7 +11,7 @@ import { dump } from '../formats/prodos/utils'; const ID = 'SMARTPORT.J.S'; export interface SmartPortState { - disks: BlockDisk[] + disks: BlockDisk[]; } export interface SmartPortOptions { diff --git a/js/cards/videoterm.ts b/js/cards/videoterm.ts index 1f3d975..57d8bc7 100644 --- a/js/cards/videoterm.ts +++ b/js/cards/videoterm.ts @@ -3,12 +3,12 @@ import { Card, Restorable, byte, Color, memory, word } from '../types'; import { ROM, VIDEO_ROM } from '../roms/cards/videoterm'; interface VideotermState { - curReg: byte, - startPos: word, - cursorPos: word, - bank: byte, - buffer: memory, - regs: byte[], + curReg: byte; + startPos: word; + cursorPos: word; + bank: byte; + buffer: memory; + regs: byte[]; } const LOC = { diff --git a/js/components/Modal.tsx b/js/components/Modal.tsx index be215c7..10d960d 100644 --- a/js/components/Modal.tsx +++ b/js/components/Modal.tsx @@ -154,9 +154,9 @@ export const ModalHeader = ({ onClose, title }: ModalHeaderProps) => { * Modal component properties */ export interface ModalProps { - onClose?: (closeBox?: boolean) => void - isOpen: boolean - title: string + onClose?: (closeBox?: boolean) => void; + isOpen: boolean; + title: string; } /** diff --git a/js/components/OptionsModal.tsx b/js/components/OptionsModal.tsx index 9bf3a73..1aec9ff 100644 --- a/js/components/OptionsModal.tsx +++ b/js/components/OptionsModal.tsx @@ -74,7 +74,7 @@ const Select = ({ option, value, setValue } : SelectProps) => { [name, setValue] ); - const makeOption = (option: { name: string, value: string }) => ( + const makeOption = (option: { name: string; value: string }) => ( diff --git a/js/cpu6502.ts b/js/cpu6502.ts index 9d445ca..102da50 100644 --- a/js/cpu6502.ts +++ b/js/cpu6502.ts @@ -18,24 +18,24 @@ export const FLAVORS = [ export type Flavor = MemberOf; export interface CpuOptions { - flavor?: Flavor + flavor?: Flavor; } export interface CpuState { /** Accumulator */ - a: byte, + a: byte; /** X index */ - x: byte, + x: byte; /** Y index */ - y: byte, + y: byte; /** Status register */ - s: byte, + s: byte; /** Program counter */ - pc: word, + pc: word; /** Stack pointer */ - sp: byte, + sp: byte; /** Elapsed cycles */ - cycles: number + cycles: number; } export type Mode = @@ -90,19 +90,19 @@ export type flag = 0x80 | 0x40 | 0x20 | 0x10 | 0x08 | 0x04 | 0x02 | 0x01; */ export type DebugInfo = { /** Program counter */ - pc: word, + pc: word; /** Accumulator */ - ar: byte, + ar: byte; /** X index */ - xr: byte, + xr: byte; /** Y index */ - yr: byte, + yr: byte; /** Status register */ - sr: byte, + sr: byte; /** Stack pointer */ - sp: byte, + sp: byte; /** Current command */ - cmd: byte[], + cmd: byte[]; }; /** Flags to status byte mask. */ @@ -148,10 +148,10 @@ type ReadAddrFn = (opts?: Opts) => word; type ImpliedFn = () => void; interface Instruction { - name: string - mode: Mode - op: (fn: T) => void - modeFn: T + name: string; + mode: Mode; + op: (fn: T) => void; + modeFn: T; } type StrictInstruction = diff --git a/js/formats/types.ts b/js/formats/types.ts index 26cca08..ed45441 100644 --- a/js/formats/types.ts +++ b/js/formats/types.ts @@ -9,13 +9,13 @@ export type DriveNumber = MemberOf; */ export interface DiskOptions { - name: string - side?: string - volume: byte - readOnly: boolean - data?: memory[][] - rawData?: ArrayBuffer - blockVolume?: boolean + name: string; + side?: string; + volume: byte; + readOnly: boolean; + data?: memory[][]; + rawData?: ArrayBuffer; + blockVolume?: boolean; } /** @@ -34,11 +34,11 @@ export interface DiskDescriptor { */ export interface JSONBinaryImage { - type: 'binary', - start: word, - length: word, - data: byte[], - gamepad?: GamepadConfiguration, + type: 'binary'; + start: word; + length: word; + data: byte[]; + gamepad?: GamepadConfiguration; } /** @@ -47,9 +47,9 @@ export interface JSONBinaryImage { */ export interface Disk { - name: string - side?: string - readOnly: boolean + name: string; + side?: string; + readOnly: boolean; } export const ENCODING_NIBBLE = 'nibble'; @@ -57,24 +57,24 @@ export const ENCODING_BITSTREAM = 'bitstream'; export const ENCODING_BLOCK = 'block'; export interface FloppyDisk extends Disk { - tracks: memory[] + tracks: memory[]; } export interface NibbleDisk extends FloppyDisk { - encoding: typeof ENCODING_NIBBLE - format: DiskFormat - volume: byte + encoding: typeof ENCODING_NIBBLE; + format: DiskFormat; + volume: byte; } export interface WozDisk extends FloppyDisk { - encoding: typeof ENCODING_BITSTREAM - trackMap: number[] - rawTracks: Uint8Array[] + encoding: typeof ENCODING_BITSTREAM; + trackMap: number[]; + rawTracks: Uint8Array[]; } export interface BlockDisk extends Disk { - encoding: typeof ENCODING_BLOCK - blocks: Uint8Array[] + encoding: typeof ENCODING_BLOCK; + blocks: Uint8Array[]; } /** @@ -123,9 +123,9 @@ export class JSONDiskBase { */ export interface Base64JSONDisk extends JSONDiskBase { - type: Exclude - encoding: 'base64' - data: string[][] + type: Exclude; + encoding: 'base64'; + data: string[][]; } /** @@ -133,9 +133,9 @@ export interface Base64JSONDisk extends JSONDiskBase { */ export interface Base64JSONNibbleDisk extends JSONDiskBase { - type: 'nib' - encoding: 'base64' - data: string[] + type: 'nib'; + encoding: 'base64'; + data: string[]; } /** @@ -143,9 +143,9 @@ export interface Base64JSONNibbleDisk extends JSONDiskBase { */ export interface BinaryJSONDisk extends JSONDiskBase { - type: DiskFormat - encoding: 'binary' - data: memory[][] + type: DiskFormat; + encoding: 'binary'; + data: memory[][]; } /** @@ -164,30 +164,30 @@ export const PROCESS_JSON = 'PROCESS_JSON'; /** Binary disk file message */ export interface ProcessBinaryMessage { - type: typeof PROCESS_BINARY + type: typeof PROCESS_BINARY; payload: { - drive: DriveNumber - fmt: NibbleFormat - options: DiskOptions - } + drive: DriveNumber; + fmt: NibbleFormat; + options: DiskOptions; + }; } /** Processed JSON file message (used for localStorage) */ export interface ProcessJsonDiskMessage { - type: typeof PROCESS_JSON_DISK + type: typeof PROCESS_JSON_DISK; payload: { - drive: DriveNumber - jsonDisk: JSONDisk - } + drive: DriveNumber; + jsonDisk: JSONDisk; + }; } /** Raw JSON file message */ export interface ProcessJsonMessage { - type: typeof PROCESS_JSON + type: typeof PROCESS_JSON; payload: { - drive: DriveNumber - json: string - } + drive: DriveNumber; + json: string; + }; } export type FormatWorkerMessage = @@ -202,11 +202,11 @@ export type FormatWorkerMessage = export const DISK_PROCESSED = 'DISK_PROCESSED'; export interface DiskProcessedResponse { - type: typeof DISK_PROCESSED + type: typeof DISK_PROCESSED; payload: { - drive: DriveNumber - disk: Disk | null - } + drive: DriveNumber; + disk: Disk | null; + }; } export type FormatWorkerResponse = @@ -216,5 +216,5 @@ export type FormatWorkerResponse = * Block device common interface */ export interface MassStorage { - setBinary(drive: number, name: string, ext: BlockFormat, data: ArrayBuffer): boolean + setBinary(drive: number, name: string, ext: BlockFormat, data: ArrayBuffer): boolean; } diff --git a/js/formats/woz.ts b/js/formats/woz.ts index 63475a3..5e200ba 100644 --- a/js/formats/woz.ts +++ b/js/formats/woz.ts @@ -118,9 +118,9 @@ export class TrksChunk1 extends TrksChunk { } export interface Trk { - startBlock: word - blockCount: word - bitCount: number + startBlock: word; + blockCount: word; + bitCount: number; } export class TrksChunk2 extends TrksChunk { @@ -191,11 +191,11 @@ export class MetaChunk { } interface Chunks { - [key: string]: any - info?: InfoChunk - tmap?: TMapChunk - trks?: TrksChunk - meta?: MetaChunk + [key: string]: any; + info?: InfoChunk; + tmap?: TMapChunk; + trks?: TrksChunk; + meta?: MetaChunk; } /** diff --git a/js/mmu.ts b/js/mmu.ts index bc78534..c1bfee5 100644 --- a/js/mmu.ts +++ b/js/mmu.ts @@ -122,29 +122,29 @@ class AuxRom implements Memory { } export interface MMUState { - bank1: boolean - readbsr: boolean - writebsr: boolean - prewrite: boolean + bank1: boolean; + readbsr: boolean; + writebsr: boolean; + prewrite: boolean; - intcxrom: boolean - slot3rom: boolean - intc8rom: boolean + intcxrom: boolean; + slot3rom: boolean; + intc8rom: boolean; - auxRamRead: boolean - auxRamWrite: boolean - altzp: boolean + auxRamRead: boolean; + auxRamWrite: boolean; + altzp: boolean; - _80store: boolean - page2: boolean - hires: boolean + _80store: boolean; + page2: boolean; + hires: boolean; - mem00_01: [RAMState, RAMState] - mem02_03: [RAMState, RAMState] - mem0C_1F: [RAMState, RAMState] - mem60_BF: [RAMState, RAMState] - memD0_DF: [ROMState, RAMState, RAMState, RAMState, RAMState] - memE0_FF: [ROMState, RAMState, RAMState] + mem00_01: [RAMState, RAMState]; + mem02_03: [RAMState, RAMState]; + mem0C_1F: [RAMState, RAMState]; + mem60_BF: [RAMState, RAMState]; + memD0_DF: [ROMState, RAMState, RAMState, RAMState, RAMState]; + memE0_FF: [ROMState, RAMState, RAMState]; } export default class MMU implements Memory, Restorable { diff --git a/js/options.ts b/js/options.ts index 0ed7944..b02075f 100644 --- a/js/options.ts +++ b/js/options.ts @@ -4,31 +4,31 @@ export const BOOLEAN_OPTION = 'BOOLEAN_OPTION'; export const SELECT_OPTION = 'SELECT_OPTION'; export interface Option { - name: string - label: string - type: string - defaultVal: string | boolean + name: string; + label: string; + type: string; + defaultVal: string | boolean; } export interface BooleanOption extends Option { - type: typeof BOOLEAN_OPTION - defaultVal: boolean + type: typeof BOOLEAN_OPTION; + defaultVal: boolean; } export interface SelectOption extends Option { - type: typeof SELECT_OPTION - defaultVal: string - values: Array<{name: string, value: string}> + type: typeof SELECT_OPTION; + defaultVal: string; + values: Array<{name: string; value: string}>; } export interface OptionSection { - name: string - options: Option[] + name: string; + options: Option[]; } export interface OptionHandler { - getOptions: () => OptionSection[] - setOption: (name: string, value: string | boolean) => void + getOptions: () => OptionSection[]; + setOption: (name: string, value: string | boolean) => void; } export class Options { diff --git a/js/types.ts b/js/types.ts index 3e47499..99a5629 100644 --- a/js/types.ts +++ b/js/types.ts @@ -110,7 +110,7 @@ export interface Restorable { // Read-only typed arrays for constants export type TypedArrayMutableProperties = 'copyWithin' | 'fill' | 'reverse' | 'set' | 'sort'; export interface ReadonlyUint8Array extends Omit { - readonly [n: number]: number + readonly [n: number]: number; } // Readonly RGB color value diff --git a/js/ui/apple2.ts b/js/ui/apple2.ts index 3f740d5..dd1a2b6 100644 --- a/js/ui/apple2.ts +++ b/js/ui/apple2.ts @@ -49,7 +49,7 @@ const options = new Options(); const optionsModal = new OptionsModal(options); type DiskCollection = { - [name: string]: DiskDescriptor[] + [name: string]: DiskDescriptor[]; }; const CIDERPRESS_EXTENSION = /#([0-9a-f]{2})([0-9a-f]{4})$/i; @@ -306,8 +306,8 @@ export function doDelete(name: string) { } interface LoadOptions { - address?: word, - runOnLoad?: boolean, + address?: word; + runOnLoad?: boolean; } function doLoadLocal(drive: DriveNumber, file: File, options: Partial = {}) { @@ -650,7 +650,7 @@ function updateLocalStorage() { } type LocalDiskIndex = { - [name: string]: string, + [name: string]: string; }; function saveLocalStorage(drive: DriveNumber, name: string) { diff --git a/js/ui/audio_worker.ts b/js/ui/audio_worker.ts index a854559..4ed7389 100644 --- a/js/ui/audio_worker.ts +++ b/js/ui/audio_worker.ts @@ -9,7 +9,7 @@ declare global { new(options?: AudioWorkletNodeOptions): AudioWorkletProcessor; }; - function registerProcessor(name: string, ctor :{ new(): AudioWorkletProcessor; }): void; + function registerProcessor(name: string, ctor :{ new(): AudioWorkletProcessor }): void; } export class AppleAudioProcessor extends AudioWorkletProcessor { diff --git a/js/videomodes.ts b/js/videomodes.ts index 883223d..057a19b 100644 --- a/js/videomodes.ts +++ b/js/videomodes.ts @@ -4,10 +4,10 @@ export type bank = 0 | 1; export type pageNo = 1 | 2; export interface Region { - top: number, - bottom: number, - left: number, - right: number, + top: number; + bottom: number; + left: number; + right: number; } export interface GraphicsState { @@ -15,30 +15,30 @@ export interface GraphicsState { } export interface VideoModesState { - grs: [gr1: GraphicsState, gr2: GraphicsState], - hgrs: [hgr1: GraphicsState, hgr2: GraphicsState], - textMode: boolean, - mixedMode: boolean, - hiresMode: boolean, - pageMode: pageNo, - _80colMode: boolean, - altCharMode: boolean, - an3State: boolean, - flag: number, + grs: [gr1: GraphicsState, gr2: GraphicsState]; + hgrs: [hgr1: GraphicsState, hgr2: GraphicsState]; + textMode: boolean; + mixedMode: boolean; + hiresMode: boolean; + pageMode: pageNo; + _80colMode: boolean; + altCharMode: boolean; + an3State: boolean; + flag: number; } export interface VideoPage extends MemoryPages, Restorable { - imageData: ImageData + imageData: ImageData; dirty: Region; - bank0(): MemoryPages - bank1(): MemoryPages + bank0(): MemoryPages; + bank1(): MemoryPages; - refresh: () => void + refresh: () => void; } export interface LoresPage extends VideoPage { - getText: () => string + getText: () => string; } export interface HiresPage extends VideoPage { @@ -46,49 +46,49 @@ export interface HiresPage extends VideoPage { } export interface VideoModes extends Restorable { - textMode: boolean - mixedMode: boolean - hiresMode: boolean - pageMode: pageNo - _80colMode: boolean - altCharMode: boolean - an3State: boolean - doubleHiresMode: boolean + textMode: boolean; + mixedMode: boolean; + hiresMode: boolean; + pageMode: pageNo; + _80colMode: boolean; + altCharMode: boolean; + an3State: boolean; + doubleHiresMode: boolean; - flag: number - monoMode: boolean + flag: number; + monoMode: boolean; context: CanvasRenderingContext2D; - page(pageNo: number): void + page(pageNo: number): void; - blit(altData?: ImageData): boolean + blit(altData?: ImageData): boolean; - reset(): void + reset(): void; - setLoresPage(page: pageNo, lores: LoresPage): void - setHiresPage(page: pageNo, lores: HiresPage): void + setLoresPage(page: pageNo, lores: LoresPage): void; + setHiresPage(page: pageNo, lores: HiresPage): void; - _80col(on: boolean): void - altChar(on: boolean): void - an3(on: boolean): void - doubleHires(on: boolean): void - hires(on: boolean): void - mixed(on: boolean): void - text(on: boolean): void + _80col(on: boolean): void; + altChar(on: boolean): void; + an3(on: boolean): void; + doubleHires(on: boolean): void; + hires(on: boolean): void; + mixed(on: boolean): void; + text(on: boolean): void; - is80Col(): boolean - isAltChar(): boolean - isDoubleHires(): boolean - isHires(): boolean - isMixed(): boolean - isPage2(): boolean - isText(): boolean + is80Col(): boolean; + isAltChar(): boolean; + isDoubleHires(): boolean; + isHires(): boolean; + isMixed(): boolean; + isPage2(): boolean; + isText(): boolean; - mono(on: boolean): void - scanlines(on: boolean): void + mono(on: boolean): void; + scanlines(on: boolean): void; - getText(): string + getText(): string; - ready: Promise + ready: Promise; } diff --git a/test/cpu-tom-harte.spec.ts b/test/cpu-tom-harte.spec.ts index 6b66cae..22f9989 100644 --- a/test/cpu-tom-harte.spec.ts +++ b/test/cpu-tom-harte.spec.ts @@ -32,19 +32,19 @@ type MemoryValue = [address: word, value: byte]; */ interface TestState { /** Program counter */ - pc: word + pc: word; /** Stack register */ - s: byte + s: byte; /** Accumulator */ - a: byte + a: byte; /** X index */ - x: byte + x: byte; /** Y index */ - y: byte + y: byte; /** Processor status register */ - p: byte + p: byte; /** M */ - ram: MemoryValue[] + ram: MemoryValue[]; } /** @@ -57,13 +57,13 @@ type Cycle = [address: word, value: byte, type: 'read'|'write']; */ interface Test { /** Test name */ - name: string + name: string; /** Initial CPU register and memory state */ - initial: TestState + initial: TestState; /** Final CPU register and memory state */ - final: TestState + final: TestState; /** Detailed CPU cycles */ - cycles: Cycle[] + cycles: Cycle[]; } /** @@ -145,9 +145,9 @@ function expectState(cpu: CPU6502, memory: TestMemory, test: Test) { } interface OpTest { - op: string - name: string - mode: string + op: string; + name: string; + mode: string; } const testPath = process.env.TOM_HARTE_TEST_PATH;