@joezilla/8sim 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +542 -0
- package/dist/8sim.browser.js +4728 -0
- package/dist/bundles/CardBundle.d.ts +83 -0
- package/dist/bundles/CardBundle.d.ts.map +1 -0
- package/dist/bundles/CardBundle.js +41 -0
- package/dist/bundles/CardBundle.js.map +1 -0
- package/dist/bundles/kernels.d.ts +48 -0
- package/dist/bundles/kernels.d.ts.map +1 -0
- package/dist/bundles/kernels.js +132 -0
- package/dist/bundles/kernels.js.map +1 -0
- package/dist/bundles/seed/index.d.ts +24 -0
- package/dist/bundles/seed/index.d.ts.map +1 -0
- package/dist/bundles/seed/index.js +266 -0
- package/dist/bundles/seed/index.js.map +1 -0
- package/dist/bus/Bus.d.ts +21 -0
- package/dist/bus/Bus.d.ts.map +1 -0
- package/dist/bus/Bus.js +62 -0
- package/dist/bus/Bus.js.map +1 -0
- package/dist/bus/BusRegion.d.ts +8 -0
- package/dist/bus/BusRegion.d.ts.map +1 -0
- package/dist/bus/BusRegion.js +8 -0
- package/dist/bus/BusRegion.js.map +1 -0
- package/dist/bus/SnoopBus.d.ts +15 -0
- package/dist/bus/SnoopBus.d.ts.map +1 -0
- package/dist/bus/SnoopBus.js +41 -0
- package/dist/bus/SnoopBus.js.map +1 -0
- package/dist/cards/BankRamCard.d.ts +35 -0
- package/dist/cards/BankRamCard.d.ts.map +1 -0
- package/dist/cards/BankRamCard.js +56 -0
- package/dist/cards/BankRamCard.js.map +1 -0
- package/dist/cards/DazzlerCard.d.ts +42 -0
- package/dist/cards/DazzlerCard.d.ts.map +1 -0
- package/dist/cards/DazzlerCard.js +83 -0
- package/dist/cards/DazzlerCard.js.map +1 -0
- package/dist/cards/DisplaySurface.d.ts +32 -0
- package/dist/cards/DisplaySurface.d.ts.map +1 -0
- package/dist/cards/DisplaySurface.js +11 -0
- package/dist/cards/DisplaySurface.js.map +1 -0
- package/dist/cards/FdcPlusClient.d.ts +35 -0
- package/dist/cards/FdcPlusClient.d.ts.map +1 -0
- package/dist/cards/FdcPlusClient.js +130 -0
- package/dist/cards/FdcPlusClient.js.map +1 -0
- package/dist/cards/ImsaiMioCard.d.ts +36 -0
- package/dist/cards/ImsaiMioCard.d.ts.map +1 -0
- package/dist/cards/ImsaiMioCard.js +48 -0
- package/dist/cards/ImsaiMioCard.js.map +1 -0
- package/dist/cards/ImsaiSioCard.d.ts +19 -0
- package/dist/cards/ImsaiSioCard.d.ts.map +1 -0
- package/dist/cards/ImsaiSioCard.js +54 -0
- package/dist/cards/ImsaiSioCard.js.map +1 -0
- package/dist/cards/KeyboardCard.d.ts +37 -0
- package/dist/cards/KeyboardCard.d.ts.map +1 -0
- package/dist/cards/KeyboardCard.js +79 -0
- package/dist/cards/KeyboardCard.js.map +1 -0
- package/dist/cards/Mc6850Acia.d.ts +68 -0
- package/dist/cards/Mc6850Acia.d.ts.map +1 -0
- package/dist/cards/Mc6850Acia.js +132 -0
- package/dist/cards/Mc6850Acia.js.map +1 -0
- package/dist/cards/Mits2SioCard.d.ts +27 -0
- package/dist/cards/Mits2SioCard.d.ts.map +1 -0
- package/dist/cards/Mits2SioCard.js +36 -0
- package/dist/cards/Mits2SioCard.js.map +1 -0
- package/dist/cards/MitsDcddCard.d.ts +52 -0
- package/dist/cards/MitsDcddCard.d.ts.map +1 -0
- package/dist/cards/MitsDcddCard.js +294 -0
- package/dist/cards/MitsDcddCard.js.map +1 -0
- package/dist/cards/ParallelCard.d.ts +35 -0
- package/dist/cards/ParallelCard.d.ts.map +1 -0
- package/dist/cards/ParallelCard.js +32 -0
- package/dist/cards/ParallelCard.js.map +1 -0
- package/dist/cards/Port8212.d.ts +31 -0
- package/dist/cards/Port8212.d.ts.map +1 -0
- package/dist/cards/Port8212.js +47 -0
- package/dist/cards/Port8212.js.map +1 -0
- package/dist/cards/RtcCard.d.ts +30 -0
- package/dist/cards/RtcCard.d.ts.map +1 -0
- package/dist/cards/RtcCard.js +61 -0
- package/dist/cards/RtcCard.js.map +1 -0
- package/dist/cards/SerialCard.d.ts +31 -0
- package/dist/cards/SerialCard.d.ts.map +1 -0
- package/dist/cards/SerialCard.js +28 -0
- package/dist/cards/SerialCard.js.map +1 -0
- package/dist/cards/Tr1602Uart.d.ts +55 -0
- package/dist/cards/Tr1602Uart.d.ts.map +1 -0
- package/dist/cards/Tr1602Uart.js +102 -0
- package/dist/cards/Tr1602Uart.js.map +1 -0
- package/dist/cards/Usart8251.d.ts +28 -0
- package/dist/cards/Usart8251.d.ts.map +1 -0
- package/dist/cards/Usart8251.js +88 -0
- package/dist/cards/Usart8251.js.map +1 -0
- package/dist/cards/VdmCard.d.ts +27 -0
- package/dist/cards/VdmCard.d.ts.map +1 -0
- package/dist/cards/VdmCard.js +40 -0
- package/dist/cards/VdmCard.js.map +1 -0
- package/dist/clock/ImmediateClock.d.ts +8 -0
- package/dist/clock/ImmediateClock.d.ts.map +1 -0
- package/dist/clock/ImmediateClock.js +13 -0
- package/dist/clock/ImmediateClock.js.map +1 -0
- package/dist/clock/SystemClock.d.ts +45 -0
- package/dist/clock/SystemClock.d.ts.map +1 -0
- package/dist/clock/SystemClock.js +71 -0
- package/dist/clock/SystemClock.js.map +1 -0
- package/dist/cpu/Cpu8080.d.ts +34 -0
- package/dist/cpu/Cpu8080.d.ts.map +1 -0
- package/dist/cpu/Cpu8080.js +126 -0
- package/dist/cpu/Cpu8080.js.map +1 -0
- package/dist/cpu/Decoder.d.ts +12 -0
- package/dist/cpu/Decoder.d.ts.map +1 -0
- package/dist/cpu/Decoder.js +23 -0
- package/dist/cpu/Decoder.js.map +1 -0
- package/dist/cpu/Flags.d.ts +18 -0
- package/dist/cpu/Flags.d.ts.map +1 -0
- package/dist/cpu/Flags.js +33 -0
- package/dist/cpu/Flags.js.map +1 -0
- package/dist/cpu/Registers.d.ts +22 -0
- package/dist/cpu/Registers.d.ts.map +1 -0
- package/dist/cpu/Registers.js +26 -0
- package/dist/cpu/Registers.js.map +1 -0
- package/dist/cpu/instructions/alu.d.ts +3 -0
- package/dist/cpu/instructions/alu.d.ts.map +1 -0
- package/dist/cpu/instructions/alu.js +221 -0
- package/dist/cpu/instructions/alu.js.map +1 -0
- package/dist/cpu/instructions/branch.d.ts +3 -0
- package/dist/cpu/instructions/branch.d.ts.map +1 -0
- package/dist/cpu/instructions/branch.js +117 -0
- package/dist/cpu/instructions/branch.js.map +1 -0
- package/dist/cpu/instructions/control.d.ts +3 -0
- package/dist/cpu/instructions/control.d.ts.map +1 -0
- package/dist/cpu/instructions/control.js +12 -0
- package/dist/cpu/instructions/control.js.map +1 -0
- package/dist/cpu/instructions/data.d.ts +3 -0
- package/dist/cpu/instructions/data.d.ts.map +1 -0
- package/dist/cpu/instructions/data.js +137 -0
- package/dist/cpu/instructions/data.js.map +1 -0
- package/dist/cpu/instructions/io.d.ts +3 -0
- package/dist/cpu/instructions/io.d.ts.map +1 -0
- package/dist/cpu/instructions/io.js +18 -0
- package/dist/cpu/instructions/io.js.map +1 -0
- package/dist/cpu/instructions/logical.d.ts +3 -0
- package/dist/cpu/instructions/logical.d.ts.map +1 -0
- package/dist/cpu/instructions/logical.js +129 -0
- package/dist/cpu/instructions/logical.js.map +1 -0
- package/dist/cpu/instructions/rotate.d.ts +3 -0
- package/dist/cpu/instructions/rotate.d.ts.map +1 -0
- package/dist/cpu/instructions/rotate.js +34 -0
- package/dist/cpu/instructions/rotate.js.map +1 -0
- package/dist/cpu/instructions/stack.d.ts +3 -0
- package/dist/cpu/instructions/stack.d.ts.map +1 -0
- package/dist/cpu/instructions/stack.js +84 -0
- package/dist/cpu/instructions/stack.js.map +1 -0
- package/dist/cpu/status8080.d.ts +33 -0
- package/dist/cpu/status8080.d.ts.map +1 -0
- package/dist/cpu/status8080.js +73 -0
- package/dist/cpu/status8080.js.map +1 -0
- package/dist/cpu/z80/CpuZ80.d.ts +53 -0
- package/dist/cpu/z80/CpuZ80.d.ts.map +1 -0
- package/dist/cpu/z80/CpuZ80.js +168 -0
- package/dist/cpu/z80/CpuZ80.js.map +1 -0
- package/dist/cpu/z80/DecoderZ80.d.ts +26 -0
- package/dist/cpu/z80/DecoderZ80.d.ts.map +1 -0
- package/dist/cpu/z80/DecoderZ80.js +107 -0
- package/dist/cpu/z80/DecoderZ80.js.map +1 -0
- package/dist/cpu/z80/FlagsZ80.d.ts +27 -0
- package/dist/cpu/z80/FlagsZ80.d.ts.map +1 -0
- package/dist/cpu/z80/FlagsZ80.js +47 -0
- package/dist/cpu/z80/FlagsZ80.js.map +1 -0
- package/dist/cpu/z80/RegistersZ80.d.ts +60 -0
- package/dist/cpu/z80/RegistersZ80.d.ts.map +1 -0
- package/dist/cpu/z80/RegistersZ80.js +90 -0
- package/dist/cpu/z80/RegistersZ80.js.map +1 -0
- package/dist/cpu/z80/flagHelpers.d.ts +25 -0
- package/dist/cpu/z80/flagHelpers.d.ts.map +1 -0
- package/dist/cpu/z80/flagHelpers.js +136 -0
- package/dist/cpu/z80/flagHelpers.js.map +1 -0
- package/dist/cpu/z80/instructions/alu16.d.ts +4 -0
- package/dist/cpu/z80/instructions/alu16.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/alu16.js +27 -0
- package/dist/cpu/z80/instructions/alu16.js.map +1 -0
- package/dist/cpu/z80/instructions/alu8.d.ts +4 -0
- package/dist/cpu/z80/instructions/alu8.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/alu8.js +100 -0
- package/dist/cpu/z80/instructions/alu8.js.map +1 -0
- package/dist/cpu/z80/instructions/bits.d.ts +10 -0
- package/dist/cpu/z80/instructions/bits.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/bits.js +164 -0
- package/dist/cpu/z80/instructions/bits.js.map +1 -0
- package/dist/cpu/z80/instructions/block.d.ts +10 -0
- package/dist/cpu/z80/instructions/block.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/block.js +141 -0
- package/dist/cpu/z80/instructions/block.js.map +1 -0
- package/dist/cpu/z80/instructions/control.d.ts +4 -0
- package/dist/cpu/z80/instructions/control.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/control.js +62 -0
- package/dist/cpu/z80/instructions/control.js.map +1 -0
- package/dist/cpu/z80/instructions/ed.d.ts +4 -0
- package/dist/cpu/z80/instructions/ed.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/ed.js +149 -0
- package/dist/cpu/z80/instructions/ed.js.map +1 -0
- package/dist/cpu/z80/instructions/exchange.d.ts +4 -0
- package/dist/cpu/z80/instructions/exchange.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/exchange.js +37 -0
- package/dist/cpu/z80/instructions/exchange.js.map +1 -0
- package/dist/cpu/z80/instructions/io.d.ts +8 -0
- package/dist/cpu/z80/instructions/io.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/io.js +22 -0
- package/dist/cpu/z80/instructions/io.js.map +1 -0
- package/dist/cpu/z80/instructions/jump.d.ts +4 -0
- package/dist/cpu/z80/instructions/jump.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/jump.js +113 -0
- package/dist/cpu/z80/instructions/jump.js.map +1 -0
- package/dist/cpu/z80/instructions/load.d.ts +7 -0
- package/dist/cpu/z80/instructions/load.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/load.js +103 -0
- package/dist/cpu/z80/instructions/load.js.map +1 -0
- package/dist/cpu/z80/instructions/rotate.d.ts +9 -0
- package/dist/cpu/z80/instructions/rotate.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/rotate.js +48 -0
- package/dist/cpu/z80/instructions/rotate.js.map +1 -0
- package/dist/cpu/z80/instructions/stack.d.ts +4 -0
- package/dist/cpu/z80/instructions/stack.d.ts.map +1 -0
- package/dist/cpu/z80/instructions/stack.js +19 -0
- package/dist/cpu/z80/instructions/stack.js.map +1 -0
- package/dist/cpu/z80/regcodes.d.ts +22 -0
- package/dist/cpu/z80/regcodes.d.ts.map +1 -0
- package/dist/cpu/z80/regcodes.js +93 -0
- package/dist/cpu/z80/regcodes.js.map +1 -0
- package/dist/cpu/z80/types.d.ts +59 -0
- package/dist/cpu/z80/types.d.ts.map +1 -0
- package/dist/cpu/z80/types.js +2 -0
- package/dist/cpu/z80/types.js.map +1 -0
- package/dist/cpu/z80/views.d.ts +8 -0
- package/dist/cpu/z80/views.d.ts.map +1 -0
- package/dist/cpu/z80/views.js +40 -0
- package/dist/cpu/z80/views.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/IBus.d.ts +8 -0
- package/dist/interfaces/IBus.d.ts.map +1 -0
- package/dist/interfaces/IBus.js +2 -0
- package/dist/interfaces/IBus.js.map +1 -0
- package/dist/interfaces/IBusObserver.d.ts +7 -0
- package/dist/interfaces/IBusObserver.d.ts.map +1 -0
- package/dist/interfaces/IBusObserver.js +2 -0
- package/dist/interfaces/IBusObserver.js.map +1 -0
- package/dist/interfaces/IClock.d.ts +6 -0
- package/dist/interfaces/IClock.d.ts.map +1 -0
- package/dist/interfaces/IClock.js +2 -0
- package/dist/interfaces/IClock.js.map +1 -0
- package/dist/interfaces/ICpu.d.ts +46 -0
- package/dist/interfaces/ICpu.d.ts.map +1 -0
- package/dist/interfaces/ICpu.js +2 -0
- package/dist/interfaces/ICpu.js.map +1 -0
- package/dist/interfaces/IIODevice.d.ts +7 -0
- package/dist/interfaces/IIODevice.d.ts.map +1 -0
- package/dist/interfaces/IIODevice.js +2 -0
- package/dist/interfaces/IIODevice.js.map +1 -0
- package/dist/interfaces/IInterruptController.d.ts +8 -0
- package/dist/interfaces/IInterruptController.d.ts.map +1 -0
- package/dist/interfaces/IInterruptController.js +2 -0
- package/dist/interfaces/IInterruptController.js.map +1 -0
- package/dist/interfaces/IMemory.d.ts +9 -0
- package/dist/interfaces/IMemory.d.ts.map +1 -0
- package/dist/interfaces/IMemory.js +2 -0
- package/dist/interfaces/IMemory.js.map +1 -0
- package/dist/interfaces/IModule.d.ts +5 -0
- package/dist/interfaces/IModule.d.ts.map +1 -0
- package/dist/interfaces/IModule.js +2 -0
- package/dist/interfaces/IModule.js.map +1 -0
- package/dist/interfaces/IS100Card.d.ts +6 -0
- package/dist/interfaces/IS100Card.d.ts.map +1 -0
- package/dist/interfaces/IS100Card.js +2 -0
- package/dist/interfaces/IS100Card.js.map +1 -0
- package/dist/interfaces/index.d.ts +10 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +2 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interrupt/InterruptController.d.ts +13 -0
- package/dist/interrupt/InterruptController.d.ts.map +1 -0
- package/dist/interrupt/InterruptController.js +36 -0
- package/dist/interrupt/InterruptController.js.map +1 -0
- package/dist/io/IoSpace.d.ts +9 -0
- package/dist/io/IoSpace.d.ts.map +1 -0
- package/dist/io/IoSpace.js +30 -0
- package/dist/io/IoSpace.js.map +1 -0
- package/dist/machine/MachineRunner.d.ts +54 -0
- package/dist/machine/MachineRunner.d.ts.map +1 -0
- package/dist/machine/MachineRunner.js +102 -0
- package/dist/machine/MachineRunner.js.map +1 -0
- package/dist/machine/MachineSpec.d.ts +80 -0
- package/dist/machine/MachineSpec.d.ts.map +1 -0
- package/dist/machine/MachineSpec.js +9 -0
- package/dist/machine/MachineSpec.js.map +1 -0
- package/dist/machine/buildMachine.d.ts +19 -0
- package/dist/machine/buildMachine.d.ts.map +1 -0
- package/dist/machine/buildMachine.js +122 -0
- package/dist/machine/buildMachine.js.map +1 -0
- package/dist/memory/MemoryMappedIOAdapter.d.ts +14 -0
- package/dist/memory/MemoryMappedIOAdapter.d.ts.map +1 -0
- package/dist/memory/MemoryMappedIOAdapter.js +23 -0
- package/dist/memory/MemoryMappedIOAdapter.js.map +1 -0
- package/dist/memory/Ram.d.ts +17 -0
- package/dist/memory/Ram.d.ts.map +1 -0
- package/dist/memory/Ram.js +36 -0
- package/dist/memory/Ram.js.map +1 -0
- package/dist/memory/Rom.d.ts +13 -0
- package/dist/memory/Rom.d.ts.map +1 -0
- package/dist/memory/Rom.js +25 -0
- package/dist/memory/Rom.js.map +1 -0
- package/dist/util/bits.d.ts +11 -0
- package/dist/util/bits.d.ts.map +1 -0
- package/dist/util/bits.js +35 -0
- package/dist/util/bits.js.map +1 -0
- package/dist/util/hostConsole.d.ts +2 -0
- package/dist/util/hostConsole.d.ts.map +1 -0
- package/dist/util/hostConsole.js +4 -0
- package/dist/util/hostConsole.js.map +1 -0
- package/package.json +39 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Mc6850Acia.js","sourceRoot":"","sources":["../../src/cards/Mc6850Acia.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { IS100Card } from '../interfaces/IS100Card.js';
|
|
2
|
+
import type { Bus } from '../bus/Bus.js';
|
|
3
|
+
import { Mc6850Acia } from './Mc6850Acia.js';
|
|
4
|
+
export interface Sio2CardOptions {
|
|
5
|
+
readonly basePort?: number;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* MITS Altair 88-2SIO dual serial card — two Motorola MC6850 ACIAs. Consumes
|
|
9
|
+
* four consecutive I/O addresses; the standard MITS base is 0x10:
|
|
10
|
+
*
|
|
11
|
+
* base+0 / base+1 Port 0 — control/status (0x10) + data (0x11)
|
|
12
|
+
* base+2 / base+3 Port 1 — control/status (0x12) + data (0x13)
|
|
13
|
+
*
|
|
14
|
+
* Port 0 is the conventional console. The 88-2SIO is the assumed serial board
|
|
15
|
+
* for nearly all MITS software (Altair BASIC, Altair DOS, and most CP/M BIOS
|
|
16
|
+
* implementations), so this is the card to attach when booting Altair CP/M.
|
|
17
|
+
*/
|
|
18
|
+
export declare class Mits2SioCard implements IS100Card {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
readonly port0: Mc6850Acia;
|
|
21
|
+
readonly port1: Mc6850Acia;
|
|
22
|
+
constructor(id?: string, options?: Sio2CardOptions);
|
|
23
|
+
attach(bus: Bus): void;
|
|
24
|
+
wireToConsole(): void;
|
|
25
|
+
reset(): void;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=Mits2SioCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Mits2SioCard.d.ts","sourceRoot":"","sources":["../../src/cards/Mits2SioCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;gBAEf,EAAE,SAAS,EAAE,OAAO,GAAE,eAAoB;IAOtD,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAKtB,aAAa,IAAI,IAAI;IAIrB,KAAK,IAAI,IAAI;CAId"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Mc6850Acia } from './Mc6850Acia.js';
|
|
2
|
+
import { writeHostStdout } from '../util/hostConsole.js';
|
|
3
|
+
/**
|
|
4
|
+
* MITS Altair 88-2SIO dual serial card — two Motorola MC6850 ACIAs. Consumes
|
|
5
|
+
* four consecutive I/O addresses; the standard MITS base is 0x10:
|
|
6
|
+
*
|
|
7
|
+
* base+0 / base+1 Port 0 — control/status (0x10) + data (0x11)
|
|
8
|
+
* base+2 / base+3 Port 1 — control/status (0x12) + data (0x13)
|
|
9
|
+
*
|
|
10
|
+
* Port 0 is the conventional console. The 88-2SIO is the assumed serial board
|
|
11
|
+
* for nearly all MITS software (Altair BASIC, Altair DOS, and most CP/M BIOS
|
|
12
|
+
* implementations), so this is the card to attach when booting Altair CP/M.
|
|
13
|
+
*/
|
|
14
|
+
export class Mits2SioCard {
|
|
15
|
+
id;
|
|
16
|
+
port0;
|
|
17
|
+
port1;
|
|
18
|
+
constructor(id = '2sio', options = {}) {
|
|
19
|
+
const base = options.basePort ?? 0x10;
|
|
20
|
+
this.id = id;
|
|
21
|
+
this.port0 = new Mc6850Acia(`${id}:port0`, base + 0, base + 1);
|
|
22
|
+
this.port1 = new Mc6850Acia(`${id}:port1`, base + 2, base + 3);
|
|
23
|
+
}
|
|
24
|
+
attach(bus) {
|
|
25
|
+
bus.attachIODevice(this.port0);
|
|
26
|
+
bus.attachIODevice(this.port1);
|
|
27
|
+
}
|
|
28
|
+
wireToConsole() {
|
|
29
|
+
this.port0.onTransmit((byte) => writeHostStdout(String.fromCharCode(byte & 0x7f)));
|
|
30
|
+
}
|
|
31
|
+
reset() {
|
|
32
|
+
this.port0.reset();
|
|
33
|
+
this.port1.reset();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=Mits2SioCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Mits2SioCard.js","sourceRoot":"","sources":["../../src/cards/Mits2SioCard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAMzD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,YAAY;IACd,EAAE,CAAS;IACX,KAAK,CAAa;IAClB,KAAK,CAAa;IAE3B,YAAY,EAAE,GAAG,MAAM,EAAE,UAA2B,EAAE;QACpD,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC;QACtC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;IACjE,CAAC;IAED,MAAM,CAAC,GAAQ;QACb,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC/B,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;IAED,aAAa;QACX,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACrF,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { IS100Card } from '../interfaces/IS100Card.js';
|
|
2
|
+
import type { IIODevice } from '../interfaces/IIODevice.js';
|
|
3
|
+
import type { Bus } from '../bus/Bus.js';
|
|
4
|
+
import { type WebSocketLike } from './FdcPlusClient.js';
|
|
5
|
+
export interface DcddOptions {
|
|
6
|
+
readonly basePort?: number;
|
|
7
|
+
}
|
|
8
|
+
export declare class MitsDcddCard implements IS100Card, IIODevice {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly basePorts: ReadonlyArray<number>;
|
|
11
|
+
private readonly fdcClient;
|
|
12
|
+
private readonly p1;
|
|
13
|
+
private readonly p2;
|
|
14
|
+
private readonly p3;
|
|
15
|
+
private selectedDrive;
|
|
16
|
+
private readonly driveTrack;
|
|
17
|
+
private headLoaded;
|
|
18
|
+
private writeEnabled;
|
|
19
|
+
private fetchPending;
|
|
20
|
+
private trackData;
|
|
21
|
+
private writeBuffer;
|
|
22
|
+
private writtenSectors;
|
|
23
|
+
private writeDirty;
|
|
24
|
+
private lastSector;
|
|
25
|
+
private byteInSector;
|
|
26
|
+
private cacheDrive;
|
|
27
|
+
/** Head position of the currently selected drive (0 when none selected). */
|
|
28
|
+
private get currentTrack();
|
|
29
|
+
private set currentTrack(value);
|
|
30
|
+
constructor(id: string, ws: WebSocketLike, options?: DcddOptions);
|
|
31
|
+
attach(bus: Bus): void;
|
|
32
|
+
ioRead(port: number): number;
|
|
33
|
+
ioWrite(port: number, value: number): void;
|
|
34
|
+
reset(): void;
|
|
35
|
+
private readStatus;
|
|
36
|
+
private writeDriveSelect;
|
|
37
|
+
private readSector;
|
|
38
|
+
private writeCommand;
|
|
39
|
+
private readData;
|
|
40
|
+
private writeData;
|
|
41
|
+
/**
|
|
42
|
+
* Start fetching the current track if the head is loaded, a drive is
|
|
43
|
+
* selected, we don't already have the data, and no fetch is in flight. Safe
|
|
44
|
+
* to call from any read/command path — it converges on caching the track the
|
|
45
|
+
* head is currently over.
|
|
46
|
+
*/
|
|
47
|
+
private ensureTrack;
|
|
48
|
+
private fetchTrack;
|
|
49
|
+
private flushWrite;
|
|
50
|
+
private issueStep;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=MitsDcddCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MitsDcddCard.d.ts","sourceRoot":"","sources":["../../src/cards/MitsDcddCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAiB,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAMvE,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,qBAAa,YAAa,YAAW,SAAS,EAAE,SAAS;IACvD,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAE1C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;IAC1C,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAC5B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAS;IAE5B,OAAO,CAAC,aAAa,CAAQ;IAK7B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmC;IAC9D,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,WAAW,CAA4B;IAC/C,OAAO,CAAC,cAAc,CAAqB;IAC3C,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,YAAY,CAAM;IAC1B,OAAO,CAAC,UAAU,CAAW;IAE7B,4EAA4E;IAC5E,OAAO,KAAK,YAAY,GAEvB;IAED,OAAO,KAAK,YAAY,QAEvB;gBAEW,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,OAAO,GAAE,WAAgB;IAUpE,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAO5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAM1C,KAAK,IAAI,IAAI;IAkBb,OAAO,CAAC,UAAU;IAkBlB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,UAAU;IAsBlB,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,QAAQ;IAiBhB,OAAO,CAAC,SAAS;IAmBjB;;;;;OAKG;IACH,OAAO,CAAC,WAAW;IAMnB,OAAO,CAAC,UAAU;IA0BlB,OAAO,CAAC,UAAU;IAyBlB,OAAO,CAAC,SAAS;CAWlB"}
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { FdcPlusClient } from './FdcPlusClient.js';
|
|
2
|
+
const TRACK_LEN = 137 * 32; // 4384 bytes — one full 8-inch track
|
|
3
|
+
const BYTES_PER_SECTOR = 137;
|
|
4
|
+
const MAX_TRACK = 76;
|
|
5
|
+
export class MitsDcddCard {
|
|
6
|
+
id;
|
|
7
|
+
basePorts;
|
|
8
|
+
fdcClient;
|
|
9
|
+
p1;
|
|
10
|
+
p2;
|
|
11
|
+
p3;
|
|
12
|
+
selectedDrive = 0xFF;
|
|
13
|
+
// Head position is PER-DRIVE state: each drive's arm stays where it was
|
|
14
|
+
// left. The BIOS seeks relatively from a per-drive track table in RAM, so a
|
|
15
|
+
// single shared counter desyncs the moment two drives interleave seeks
|
|
16
|
+
// (e.g. PIP copying between disks) and lands reads/writes on wrong tracks.
|
|
17
|
+
driveTrack = new Array(16).fill(0);
|
|
18
|
+
headLoaded = false;
|
|
19
|
+
writeEnabled = false;
|
|
20
|
+
fetchPending = false;
|
|
21
|
+
trackData = null;
|
|
22
|
+
writeBuffer = null;
|
|
23
|
+
writtenSectors = new Set(); // sectors touched since Write Enable
|
|
24
|
+
writeDirty = false;
|
|
25
|
+
lastSector = -1;
|
|
26
|
+
byteInSector = 0;
|
|
27
|
+
cacheDrive = 0xFF; // which drive the cached trackData belongs to
|
|
28
|
+
/** Head position of the currently selected drive (0 when none selected). */
|
|
29
|
+
get currentTrack() {
|
|
30
|
+
return this.selectedDrive === 0xFF ? 0 : (this.driveTrack[this.selectedDrive] ?? 0);
|
|
31
|
+
}
|
|
32
|
+
set currentTrack(track) {
|
|
33
|
+
if (this.selectedDrive !== 0xFF)
|
|
34
|
+
this.driveTrack[this.selectedDrive] = track;
|
|
35
|
+
}
|
|
36
|
+
constructor(id, ws, options = {}) {
|
|
37
|
+
this.id = id;
|
|
38
|
+
const base = options.basePort ?? 0x08;
|
|
39
|
+
this.p1 = base;
|
|
40
|
+
this.p2 = base + 1;
|
|
41
|
+
this.p3 = base + 2;
|
|
42
|
+
this.basePorts = [this.p1, this.p2, this.p3];
|
|
43
|
+
this.fdcClient = new FdcPlusClient(ws);
|
|
44
|
+
}
|
|
45
|
+
attach(bus) {
|
|
46
|
+
bus.attachIODevice(this);
|
|
47
|
+
}
|
|
48
|
+
ioRead(port) {
|
|
49
|
+
if (port === this.p1)
|
|
50
|
+
return this.readStatus();
|
|
51
|
+
if (port === this.p2)
|
|
52
|
+
return this.readSector();
|
|
53
|
+
if (port === this.p3)
|
|
54
|
+
return this.readData();
|
|
55
|
+
return 0xff;
|
|
56
|
+
}
|
|
57
|
+
ioWrite(port, value) {
|
|
58
|
+
if (port === this.p1) {
|
|
59
|
+
this.writeDriveSelect(value);
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (port === this.p2) {
|
|
63
|
+
this.writeCommand(value);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (port === this.p3) {
|
|
67
|
+
this.writeData(value);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
reset() {
|
|
72
|
+
this.flushWrite();
|
|
73
|
+
this.selectedDrive = 0xFF;
|
|
74
|
+
this.driveTrack.fill(0);
|
|
75
|
+
this.headLoaded = false;
|
|
76
|
+
this.writeEnabled = false;
|
|
77
|
+
this.fetchPending = false;
|
|
78
|
+
this.trackData = null;
|
|
79
|
+
this.writeBuffer = null;
|
|
80
|
+
this.writtenSectors.clear();
|
|
81
|
+
this.writeDirty = false;
|
|
82
|
+
this.lastSector = -1;
|
|
83
|
+
this.byteInSector = 0;
|
|
84
|
+
this.cacheDrive = 0xFF;
|
|
85
|
+
}
|
|
86
|
+
// --- Port 1: status (READ) / drive select (WRITE) ---
|
|
87
|
+
readStatus() {
|
|
88
|
+
this.ensureTrack(); // lazily (re)start a fetch if the current track isn't cached
|
|
89
|
+
// 88-DCDD status register, all bits active-low (0 = condition true):
|
|
90
|
+
// bit7 NRDA — new read data available
|
|
91
|
+
// bit6 TRK0 — head at track 0
|
|
92
|
+
// bit3 DRVRDY — drive ready (a drive is selected and its disk is present)
|
|
93
|
+
// bit2 HDSTAT — head loaded / positioning valid
|
|
94
|
+
// bit1 MVHEAD — head movement complete (instantaneous in emulation)
|
|
95
|
+
// bit0 ENWDAT — ready to accept write data
|
|
96
|
+
const nrda = (!this.headLoaded || !this.trackData || this.fetchPending) ? 0x80 : 0;
|
|
97
|
+
const trk0 = this.currentTrack === 0 ? 0x00 : 0x40;
|
|
98
|
+
const drvrdy = this.selectedDrive !== 0xFF ? 0x00 : 0x08;
|
|
99
|
+
const hdstat = this.headLoaded ? 0x00 : 0x04;
|
|
100
|
+
const mvhd = 0x00;
|
|
101
|
+
const enwd = this.writeEnabled ? 0x00 : 0x01;
|
|
102
|
+
return nrda | trk0 | drvrdy | hdstat | mvhd | enwd;
|
|
103
|
+
}
|
|
104
|
+
writeDriveSelect(value) {
|
|
105
|
+
if ((value & 0x80) !== 0) {
|
|
106
|
+
// Disable/deselect the drive. On real hardware this drops the drive-enable
|
|
107
|
+
// line but the head-load solenoid and the data already under the head are
|
|
108
|
+
// physical state that persists — the drive can be reselected with the head
|
|
109
|
+
// still loaded. The MITS multi-stage boot relies on exactly this (it
|
|
110
|
+
// reselects the drive and expects HEDLD to already be active). Only an
|
|
111
|
+
// explicit Head Unload command (Port 2 bit 3) lifts the head.
|
|
112
|
+
this.flushWrite();
|
|
113
|
+
this.selectedDrive = 0xFF;
|
|
114
|
+
this.writeEnabled = false;
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const drive = value & 0x0F;
|
|
118
|
+
// A dirty write buffer belongs to the drive we're switching away from —
|
|
119
|
+
// flush it before the selection changes, or it lands on the new drive.
|
|
120
|
+
if (drive !== this.selectedDrive)
|
|
121
|
+
this.flushWrite();
|
|
122
|
+
this.selectedDrive = drive;
|
|
123
|
+
// Selecting a different drive invalidates the cached track (different disk).
|
|
124
|
+
if (drive !== this.cacheDrive) {
|
|
125
|
+
this.trackData = null;
|
|
126
|
+
}
|
|
127
|
+
this.ensureTrack();
|
|
128
|
+
this.fdcClient
|
|
129
|
+
.stat(this.selectedDrive, this.headLoaded, this.currentTrack)
|
|
130
|
+
.catch(() => { });
|
|
131
|
+
}
|
|
132
|
+
// --- Port 2: sector position (READ) / command (WRITE) ---
|
|
133
|
+
readSector() {
|
|
134
|
+
const revMs = 166.667;
|
|
135
|
+
const secMs = revMs / 32;
|
|
136
|
+
const pos = performance.now() % revMs;
|
|
137
|
+
const sector = Math.floor(pos / secMs) & 0x1F;
|
|
138
|
+
const offset = pos % secMs;
|
|
139
|
+
// Sector True (bit 0) pulses LOW for first 1 ms of each sector window
|
|
140
|
+
const sectorTrue = offset < 1.0 ? 0 : 1;
|
|
141
|
+
if (sector !== this.lastSector || sectorTrue === 0) {
|
|
142
|
+
// New sector under the head, or the start-of-sector pulse. Sector True
|
|
143
|
+
// marks the beginning of the sector: software that samples it here (the
|
|
144
|
+
// BIOS waits for it before every transfer) expects the byte stream to
|
|
145
|
+
// start at byte 0 — even when re-targeting the sector it just finished,
|
|
146
|
+
// where the sector number alone wouldn't change.
|
|
147
|
+
this.lastSector = sector;
|
|
148
|
+
this.byteInSector = 0;
|
|
149
|
+
}
|
|
150
|
+
return 0xC0 | ((sector & 0x1F) << 1) | sectorTrue;
|
|
151
|
+
}
|
|
152
|
+
writeCommand(value) {
|
|
153
|
+
// Process all command bits; multiple may be set simultaneously
|
|
154
|
+
if ((value & 0x80) !== 0) { // Write Enable
|
|
155
|
+
// The BIOS issues Write Enable once per sector write. On real hardware
|
|
156
|
+
// each sector hits the disk immediately; here writes accumulate in the
|
|
157
|
+
// track buffer until flush, so Write Enable must NOT discard sectors
|
|
158
|
+
// buffered by earlier enables — only ensure a buffer exists.
|
|
159
|
+
this.writeEnabled = true;
|
|
160
|
+
if (!this.writeBuffer)
|
|
161
|
+
this.writeBuffer = new Uint8Array(TRACK_LEN);
|
|
162
|
+
}
|
|
163
|
+
if ((value & 0x08) !== 0) { // Head Unload
|
|
164
|
+
this.flushWrite();
|
|
165
|
+
this.headLoaded = false;
|
|
166
|
+
this.trackData = null;
|
|
167
|
+
}
|
|
168
|
+
if ((value & 0x04) !== 0) { // Head Load
|
|
169
|
+
this.headLoaded = true;
|
|
170
|
+
this.ensureTrack();
|
|
171
|
+
}
|
|
172
|
+
if ((value & 0x02) !== 0)
|
|
173
|
+
this.issueStep('out'); // Step Out
|
|
174
|
+
if ((value & 0x01) !== 0)
|
|
175
|
+
this.issueStep('in'); // Step In
|
|
176
|
+
}
|
|
177
|
+
// --- Port 3: data (READ/WRITE) ---
|
|
178
|
+
readData() {
|
|
179
|
+
if (!this.headLoaded || !this.trackData || this.fetchPending)
|
|
180
|
+
return 0xff;
|
|
181
|
+
// Past the 137th byte the head is over the inter-sector gap — nothing to
|
|
182
|
+
// read until the sector counter advances (which resets byteInSector).
|
|
183
|
+
if (this.byteInSector >= BYTES_PER_SECTOR)
|
|
184
|
+
return 0xff;
|
|
185
|
+
const sector = this.lastSector < 0 ? 0 : this.lastSector;
|
|
186
|
+
const offset = sector * BYTES_PER_SECTOR + this.byteInSector;
|
|
187
|
+
// A sector rewritten since Write Enable reads back its new contents.
|
|
188
|
+
const source = (this.writeBuffer && this.writtenSectors.has(sector))
|
|
189
|
+
? this.writeBuffer
|
|
190
|
+
: this.trackData;
|
|
191
|
+
if (offset >= source.length)
|
|
192
|
+
return 0xff;
|
|
193
|
+
const byte = source[offset] ?? 0xff;
|
|
194
|
+
this.byteInSector++;
|
|
195
|
+
return byte;
|
|
196
|
+
}
|
|
197
|
+
writeData(value) {
|
|
198
|
+
if (!this.writeEnabled || !this.writeBuffer)
|
|
199
|
+
return;
|
|
200
|
+
// The BIOS pads its 137-byte sector burst with trailing bytes; on real
|
|
201
|
+
// hardware they land in the inter-sector gap. Discard them — wrapping
|
|
202
|
+
// around would overwrite the start of the sector (the track-marker byte),
|
|
203
|
+
// corrupting it.
|
|
204
|
+
if (this.byteInSector >= BYTES_PER_SECTOR)
|
|
205
|
+
return;
|
|
206
|
+
const sector = this.lastSector < 0 ? 0 : this.lastSector;
|
|
207
|
+
const offset = sector * BYTES_PER_SECTOR + this.byteInSector;
|
|
208
|
+
if (offset < this.writeBuffer.length) {
|
|
209
|
+
this.writeBuffer[offset] = value & 0xff;
|
|
210
|
+
this.writtenSectors.add(sector);
|
|
211
|
+
this.writeDirty = true;
|
|
212
|
+
}
|
|
213
|
+
this.byteInSector++;
|
|
214
|
+
}
|
|
215
|
+
// --- Private helpers ---
|
|
216
|
+
/**
|
|
217
|
+
* Start fetching the current track if the head is loaded, a drive is
|
|
218
|
+
* selected, we don't already have the data, and no fetch is in flight. Safe
|
|
219
|
+
* to call from any read/command path — it converges on caching the track the
|
|
220
|
+
* head is currently over.
|
|
221
|
+
*/
|
|
222
|
+
ensureTrack() {
|
|
223
|
+
if (!this.headLoaded || this.selectedDrive === 0xFF)
|
|
224
|
+
return;
|
|
225
|
+
if (this.trackData || this.fetchPending)
|
|
226
|
+
return;
|
|
227
|
+
this.fetchTrack();
|
|
228
|
+
}
|
|
229
|
+
fetchTrack() {
|
|
230
|
+
if (this.selectedDrive === 0xFF || !this.headLoaded || this.fetchPending)
|
|
231
|
+
return;
|
|
232
|
+
this.fetchPending = true;
|
|
233
|
+
const drive = this.selectedDrive;
|
|
234
|
+
const track = this.currentTrack;
|
|
235
|
+
this.fdcClient
|
|
236
|
+
.readTrack(drive, track, TRACK_LEN)
|
|
237
|
+
.then((data) => {
|
|
238
|
+
// Only install the data if the head hasn't moved (and the same drive is
|
|
239
|
+
// still selected) since the fetch began — otherwise it belongs to a
|
|
240
|
+
// track we're no longer over and would corrupt the next read. A cache
|
|
241
|
+
// that appeared meanwhile is a flushed write image, which is fresher
|
|
242
|
+
// than what we just fetched — keep it.
|
|
243
|
+
if (track === this.currentTrack && drive === this.selectedDrive && !this.trackData) {
|
|
244
|
+
this.trackData = data;
|
|
245
|
+
this.cacheDrive = drive;
|
|
246
|
+
}
|
|
247
|
+
})
|
|
248
|
+
.catch(() => { })
|
|
249
|
+
.finally(() => {
|
|
250
|
+
this.fetchPending = false;
|
|
251
|
+
// If the head moved during the fetch, chase the track it's now over.
|
|
252
|
+
this.ensureTrack();
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
flushWrite() {
|
|
256
|
+
if (!this.writeDirty || !this.writeBuffer || this.selectedDrive === 0xFF)
|
|
257
|
+
return;
|
|
258
|
+
// WRIT replaces the whole track on the server, but the program only wrote
|
|
259
|
+
// some sectors — merge those over the cached track image so the rest keep
|
|
260
|
+
// their contents.
|
|
261
|
+
const image = this.trackData ? new Uint8Array(this.trackData) : new Uint8Array(TRACK_LEN);
|
|
262
|
+
for (const sector of this.writtenSectors) {
|
|
263
|
+
const off = sector * BYTES_PER_SECTOR;
|
|
264
|
+
image.set(this.writeBuffer.subarray(off, off + BYTES_PER_SECTOR), off);
|
|
265
|
+
}
|
|
266
|
+
const drive = this.selectedDrive;
|
|
267
|
+
const track = this.currentTrack;
|
|
268
|
+
this.writeBuffer = null;
|
|
269
|
+
this.writtenSectors.clear();
|
|
270
|
+
this.writeDirty = false;
|
|
271
|
+
this.writeEnabled = false;
|
|
272
|
+
// The merged image is now the freshest copy of the track — reads must see
|
|
273
|
+
// the written data, not the pre-write cache.
|
|
274
|
+
this.trackData = image;
|
|
275
|
+
this.cacheDrive = drive;
|
|
276
|
+
this.fdcClient.writeTrack(drive, track, image).catch((e) => {
|
|
277
|
+
console.error(`[${this.id}] track write failed (drive ${drive}, track ${track}): ${String(e)}`);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
issueStep(dir) {
|
|
281
|
+
// Seeks are instantaneous in emulation. A real-time settle delay would
|
|
282
|
+
// desync from the emulated CPU (which the software paces itself), and
|
|
283
|
+
// dropping "too-fast" step pulses would lose track position entirely.
|
|
284
|
+
this.flushWrite(); // a dirty buffer belongs to the track we're leaving
|
|
285
|
+
if (dir === 'in')
|
|
286
|
+
this.currentTrack = Math.min(MAX_TRACK, this.currentTrack + 1);
|
|
287
|
+
else
|
|
288
|
+
this.currentTrack = Math.max(0, this.currentTrack - 1);
|
|
289
|
+
this.trackData = null; // head moved; cached track is no longer under it
|
|
290
|
+
this.writeEnabled = false;
|
|
291
|
+
this.ensureTrack(); // begin fetching the new track
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
//# sourceMappingURL=MitsDcddCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MitsDcddCard.js","sourceRoot":"","sources":["../../src/cards/MitsDcddCard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { IS100Card } from '../interfaces/IS100Card.js';
|
|
2
|
+
import type { Bus } from '../bus/Bus.js';
|
|
3
|
+
/** Data direction of a parallel port from the operator's peripheral view. */
|
|
4
|
+
export type PortDirection = 'out' | 'in' | 'inout';
|
|
5
|
+
export interface ParallelCardOptions {
|
|
6
|
+
readonly port?: number;
|
|
7
|
+
readonly direction?: PortDirection;
|
|
8
|
+
}
|
|
9
|
+
/** The host-side surface a GPIO peripheral (LEDs / switches / printer) binds to. */
|
|
10
|
+
export interface GpioPort {
|
|
11
|
+
readonly direction: PortDirection;
|
|
12
|
+
/** The byte the CPU last latched on the output pins (drive LEDs / a printer). */
|
|
13
|
+
read(): number;
|
|
14
|
+
/** Drive the input pins — the value the CPU reads (sense switches). */
|
|
15
|
+
setInput(byte: number): void;
|
|
16
|
+
/** Fired whenever the CPU writes the output latch. */
|
|
17
|
+
onOutput(cb: (byte: number) => void): void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* A single 8-bit parallel I/O card (Story 5.8) — an 8212-style latched port the
|
|
21
|
+
* general GPIO cards resolve to. A CPU write latches the output byte; a CPU read
|
|
22
|
+
* returns the input pins. It exposes a `gpio` surface so the host wires it to a
|
|
23
|
+
* peripheral — an LED bank, sense switches, a printer, or real hardware GPIO.
|
|
24
|
+
* `direction` is a hint for the peripheral viewer (the 8212 is bidirectional).
|
|
25
|
+
*/
|
|
26
|
+
export declare class ParallelCard implements IS100Card {
|
|
27
|
+
readonly id: string;
|
|
28
|
+
readonly direction: PortDirection;
|
|
29
|
+
readonly gpio: GpioPort;
|
|
30
|
+
private readonly dev;
|
|
31
|
+
constructor(id?: string, opts?: ParallelCardOptions);
|
|
32
|
+
attach(bus: Bus): void;
|
|
33
|
+
reset(): void;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=ParallelCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParallelCard.d.ts","sourceRoot":"","sources":["../../src/cards/ParallelCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGzC,6EAA6E;AAC7E,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,IAAI,GAAG,OAAO,CAAC;AAEnD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,aAAa,CAAC;CACpC;AAED,oFAAoF;AACpF,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,iFAAiF;IACjF,IAAI,IAAI,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;CAC5C;AAED;;;;;;GAMG;AACH,qBAAa,YAAa,YAAW,SAAS;IAC5C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC;IAClC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAW;gBAEnB,EAAE,SAAa,EAAE,IAAI,GAAE,mBAAwB;IAY3D,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Port8212 } from './Port8212.js';
|
|
2
|
+
/**
|
|
3
|
+
* A single 8-bit parallel I/O card (Story 5.8) — an 8212-style latched port the
|
|
4
|
+
* general GPIO cards resolve to. A CPU write latches the output byte; a CPU read
|
|
5
|
+
* returns the input pins. It exposes a `gpio` surface so the host wires it to a
|
|
6
|
+
* peripheral — an LED bank, sense switches, a printer, or real hardware GPIO.
|
|
7
|
+
* `direction` is a hint for the peripheral viewer (the 8212 is bidirectional).
|
|
8
|
+
*/
|
|
9
|
+
export class ParallelCard {
|
|
10
|
+
id;
|
|
11
|
+
direction;
|
|
12
|
+
gpio;
|
|
13
|
+
dev;
|
|
14
|
+
constructor(id = 'parallel', opts = {}) {
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.direction = opts.direction ?? 'out';
|
|
17
|
+
this.dev = new Port8212(`${id}:port`, opts.port ?? 0x00);
|
|
18
|
+
this.gpio = {
|
|
19
|
+
direction: this.direction,
|
|
20
|
+
read: () => this.dev.output,
|
|
21
|
+
setInput: (byte) => this.dev.setInput(byte),
|
|
22
|
+
onOutput: (cb) => this.dev.onWrite(cb),
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
attach(bus) {
|
|
26
|
+
bus.attachIODevice(this.dev);
|
|
27
|
+
}
|
|
28
|
+
reset() {
|
|
29
|
+
this.dev.reset();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=ParallelCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ParallelCard.js","sourceRoot":"","sources":["../../src/cards/ParallelCard.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAqBzC;;;;;;GAMG;AACH,MAAM,OAAO,YAAY;IACd,EAAE,CAAS;IACX,SAAS,CAAgB;IACzB,IAAI,CAAW;IACP,GAAG,CAAW;IAE/B,YAAY,EAAE,GAAG,UAAU,EAAE,OAA4B,EAAE;QACzD,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC;QACzC,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,GAAG;YACV,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,IAAI,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM;YAC3B,QAAQ,EAAE,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC;YACnD,QAAQ,EAAE,CAAC,EAA0B,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;SAC/D,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAQ;QACb,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAED,KAAK;QACH,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;IACnB,CAAC;CACF"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { IIODevice } from '../interfaces/IIODevice.js';
|
|
2
|
+
type PortWriteCallback = (value: number) => void;
|
|
3
|
+
/**
|
|
4
|
+
* Intel / AMD 8212 eight-bit latched I/O port, as used for the IMSAI MIO
|
|
5
|
+
* board's two parallel ports. A CPU write latches the output byte (held on the
|
|
6
|
+
* output pins); a CPU read returns whatever is currently presented on the input
|
|
7
|
+
* pins. Output and input are independent, modelling a bidirectional 8212 port.
|
|
8
|
+
*
|
|
9
|
+
* The host drives the input pins with {@link setInput} and observes the latched
|
|
10
|
+
* output via {@link output} or an {@link onWrite} callback — this is how a
|
|
11
|
+
* printer, LED bank, switch bank, or other peripheral is wired to the port.
|
|
12
|
+
*/
|
|
13
|
+
export declare class Port8212 implements IIODevice {
|
|
14
|
+
readonly id: string;
|
|
15
|
+
readonly basePorts: ReadonlyArray<number>;
|
|
16
|
+
private outputLatch;
|
|
17
|
+
private inputLatch;
|
|
18
|
+
private writeCb;
|
|
19
|
+
constructor(id: string, port: number);
|
|
20
|
+
ioRead(_port: number): number;
|
|
21
|
+
ioWrite(_port: number, value: number): void;
|
|
22
|
+
reset(): void;
|
|
23
|
+
/** Drive the port's input pins — the value the CPU reads from this port. */
|
|
24
|
+
setInput(value: number): void;
|
|
25
|
+
/** The byte currently latched on the output pins. */
|
|
26
|
+
get output(): number;
|
|
27
|
+
/** Register a callback fired whenever the CPU writes the output latch. */
|
|
28
|
+
onWrite(cb: PortWriteCallback): void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=Port8212.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Port8212.d.ts","sourceRoot":"","sources":["../../src/cards/Port8212.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,KAAK,iBAAiB,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAEjD;;;;;;;;;GASG;AACH,qBAAa,QAAS,YAAW,SAAS;IACxC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAE1C,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,UAAU,CAAQ;IAC1B,OAAO,CAAC,OAAO,CAAgC;gBAEnC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAKpC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAI7B,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAK3C,KAAK,IAAI,IAAI;IAMb,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,qDAAqD;IACrD,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED,0EAA0E;IAC1E,OAAO,CAAC,EAAE,EAAE,iBAAiB,GAAG,IAAI;CAGrC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { u8 } from '../util/bits.js';
|
|
2
|
+
/**
|
|
3
|
+
* Intel / AMD 8212 eight-bit latched I/O port, as used for the IMSAI MIO
|
|
4
|
+
* board's two parallel ports. A CPU write latches the output byte (held on the
|
|
5
|
+
* output pins); a CPU read returns whatever is currently presented on the input
|
|
6
|
+
* pins. Output and input are independent, modelling a bidirectional 8212 port.
|
|
7
|
+
*
|
|
8
|
+
* The host drives the input pins with {@link setInput} and observes the latched
|
|
9
|
+
* output via {@link output} or an {@link onWrite} callback — this is how a
|
|
10
|
+
* printer, LED bank, switch bank, or other peripheral is wired to the port.
|
|
11
|
+
*/
|
|
12
|
+
export class Port8212 {
|
|
13
|
+
id;
|
|
14
|
+
basePorts;
|
|
15
|
+
outputLatch = 0;
|
|
16
|
+
inputLatch = 0xff; // unconnected TTL inputs float high
|
|
17
|
+
writeCb;
|
|
18
|
+
constructor(id, port) {
|
|
19
|
+
this.id = id;
|
|
20
|
+
this.basePorts = [port];
|
|
21
|
+
}
|
|
22
|
+
ioRead(_port) {
|
|
23
|
+
return this.inputLatch;
|
|
24
|
+
}
|
|
25
|
+
ioWrite(_port, value) {
|
|
26
|
+
this.outputLatch = u8(value);
|
|
27
|
+
this.writeCb?.(this.outputLatch);
|
|
28
|
+
}
|
|
29
|
+
reset() {
|
|
30
|
+
this.outputLatch = 0;
|
|
31
|
+
this.inputLatch = 0xff;
|
|
32
|
+
// writeCb survives reset — it is host wiring.
|
|
33
|
+
}
|
|
34
|
+
/** Drive the port's input pins — the value the CPU reads from this port. */
|
|
35
|
+
setInput(value) {
|
|
36
|
+
this.inputLatch = u8(value);
|
|
37
|
+
}
|
|
38
|
+
/** The byte currently latched on the output pins. */
|
|
39
|
+
get output() {
|
|
40
|
+
return this.outputLatch;
|
|
41
|
+
}
|
|
42
|
+
/** Register a callback fired whenever the CPU writes the output latch. */
|
|
43
|
+
onWrite(cb) {
|
|
44
|
+
this.writeCb = cb;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=Port8212.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Port8212.js","sourceRoot":"","sources":["../../src/cards/Port8212.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;AAIrC;;;;;;;;;GASG;AACH,MAAM,OAAO,QAAQ;IACV,EAAE,CAAS;IACX,SAAS,CAAwB;IAElC,WAAW,GAAG,CAAC,CAAC;IAChB,UAAU,GAAG,IAAI,CAAC,CAAC,oCAAoC;IACvD,OAAO,CAAgC;IAE/C,YAAY,EAAU,EAAE,IAAY;QAClC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,KAAa;QAClB,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;IAED,OAAO,CAAC,KAAa,EAAE,KAAa;QAClC,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACnC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,WAAW,GAAG,CAAC,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,8CAA8C;IAChD,CAAC;IAED,4EAA4E;IAC5E,QAAQ,CAAC,KAAa;QACpB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IAED,qDAAqD;IACrD,IAAI,MAAM;QACR,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,0EAA0E;IAC1E,OAAO,CAAC,EAAqB;QAC3B,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { IS100Card } from '../interfaces/IS100Card.js';
|
|
2
|
+
import type { Bus } from '../bus/Bus.js';
|
|
3
|
+
/** Host time source injected via CardContext.services.clock. */
|
|
4
|
+
export type RtcClock = () => Date;
|
|
5
|
+
export interface RtcCardOptions {
|
|
6
|
+
/** Base I/O port; the chip occupies base..base+0x1F (32 registers). */
|
|
7
|
+
readonly base?: number;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* National MM58167 real-time clock (Story 5.10). A 32-register clock/calendar
|
|
11
|
+
* chip on an I/O window: the counter registers (0x00–0x07) read the host wall
|
|
12
|
+
* clock as BCD, the rest (RAM / compare / interrupt / status) are plain storage.
|
|
13
|
+
*
|
|
14
|
+
* The host time comes from `ctx.services.clock` (a `() => Date`), so the machine
|
|
15
|
+
* reads real time while tests stay deterministic by injecting a fixed clock.
|
|
16
|
+
* Writes to the live counters are ignored — you can't set the host's clock.
|
|
17
|
+
*/
|
|
18
|
+
export declare class RtcCard implements IS100Card {
|
|
19
|
+
readonly id: string;
|
|
20
|
+
private readonly base;
|
|
21
|
+
private readonly now;
|
|
22
|
+
private readonly ram;
|
|
23
|
+
private readonly dev;
|
|
24
|
+
constructor(id?: string, opts?: RtcCardOptions, clock?: RtcClock);
|
|
25
|
+
attach(bus: Bus): void;
|
|
26
|
+
reset(): void;
|
|
27
|
+
private readReg;
|
|
28
|
+
private writeReg;
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=RtcCard.d.ts.map
|