@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":"RtcCard.d.ts","sourceRoot":"","sources":["../../src/cards/RtcCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAE5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AAGzC,gEAAgE;AAChE,MAAM,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC;AAOlC,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAW;IAC/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAwB;IAC5C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAY;gBAEpB,EAAE,SAAQ,EAAE,IAAI,GAAE,cAAmB,EAAE,KAAK,GAAE,QAAqB;IAgB/E,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,KAAK,IAAI,IAAI;IAIb,OAAO,CAAC,OAAO;IAef,OAAO,CAAC,QAAQ;CAGjB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { u8 } from '../util/bits.js';
|
|
2
|
+
/** Deterministic default when no host clock is wired (tests, headless builds). */
|
|
3
|
+
const EPOCH_ZERO = () => new Date(0);
|
|
4
|
+
const bcd = (n) => (((Math.floor(n / 10) % 10) << 4) | (n % 10)) & 0xff;
|
|
5
|
+
/**
|
|
6
|
+
* National MM58167 real-time clock (Story 5.10). A 32-register clock/calendar
|
|
7
|
+
* chip on an I/O window: the counter registers (0x00–0x07) read the host wall
|
|
8
|
+
* clock as BCD, the rest (RAM / compare / interrupt / status) are plain storage.
|
|
9
|
+
*
|
|
10
|
+
* The host time comes from `ctx.services.clock` (a `() => Date`), so the machine
|
|
11
|
+
* reads real time while tests stay deterministic by injecting a fixed clock.
|
|
12
|
+
* Writes to the live counters are ignored — you can't set the host's clock.
|
|
13
|
+
*/
|
|
14
|
+
export class RtcCard {
|
|
15
|
+
id;
|
|
16
|
+
base;
|
|
17
|
+
now;
|
|
18
|
+
ram = new Uint8Array(0x20); // 0x08..0x1F are read/write storage
|
|
19
|
+
dev;
|
|
20
|
+
constructor(id = 'rtc', opts = {}, clock = EPOCH_ZERO) {
|
|
21
|
+
this.id = id;
|
|
22
|
+
this.base = (opts.base ?? 0x40) & 0xff;
|
|
23
|
+
this.now = clock;
|
|
24
|
+
const self = this;
|
|
25
|
+
const ports = [];
|
|
26
|
+
for (let i = 0; i < 0x20; i++)
|
|
27
|
+
ports.push((this.base + i) & 0xff);
|
|
28
|
+
this.dev = {
|
|
29
|
+
id: `${id}:io`,
|
|
30
|
+
basePorts: ports,
|
|
31
|
+
ioRead: (port) => self.readReg((port - self.base) & 0x1f),
|
|
32
|
+
ioWrite: (port, value) => self.writeReg((port - self.base) & 0x1f, value),
|
|
33
|
+
reset: () => self.ram.fill(0),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
attach(bus) {
|
|
37
|
+
bus.attachIODevice(this.dev);
|
|
38
|
+
}
|
|
39
|
+
reset() {
|
|
40
|
+
this.ram.fill(0);
|
|
41
|
+
}
|
|
42
|
+
readReg(off) {
|
|
43
|
+
const d = this.now();
|
|
44
|
+
switch (off) {
|
|
45
|
+
case 0x00: return 0; // thousandths of a second
|
|
46
|
+
case 0x01: return bcd(Math.floor(d.getMilliseconds() / 10)); // hundredths
|
|
47
|
+
case 0x02: return bcd(d.getSeconds());
|
|
48
|
+
case 0x03: return bcd(d.getMinutes());
|
|
49
|
+
case 0x04: return bcd(d.getHours());
|
|
50
|
+
case 0x05: return bcd(d.getDay() + 1); // day of week, 1–7
|
|
51
|
+
case 0x06: return bcd(d.getDate()); // day of month
|
|
52
|
+
case 0x07: return bcd(d.getMonth() + 1); // month, 1–12
|
|
53
|
+
default: return this.ram[off] ?? 0; // RAM / compare / status registers
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
writeReg(off, value) {
|
|
57
|
+
if (off > 0x07)
|
|
58
|
+
this.ram[off] = u8(value); // live counters are read-only
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=RtcCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RtcCard.js","sourceRoot":"","sources":["../../src/cards/RtcCard.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
/** The UART chip a serial card is built around. */
|
|
5
|
+
export type SerialChip = 'i8251' | 'm6850';
|
|
6
|
+
/** A serial channel: an I/O device that also streams characters. */
|
|
7
|
+
interface SerialChannel extends IIODevice {
|
|
8
|
+
onTransmit(cb: (byte: number) => void): void;
|
|
9
|
+
enqueueRx(byte: number): void;
|
|
10
|
+
reset(): void;
|
|
11
|
+
}
|
|
12
|
+
export interface SerialCardOptions {
|
|
13
|
+
readonly dataPort?: number;
|
|
14
|
+
readonly ctrlPort?: number;
|
|
15
|
+
readonly chip?: SerialChip;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A single-channel serial (UART) card — the general console board authored
|
|
19
|
+
* serial cards resolve to (Story 5.7). Unlike a bare chip wrapped in
|
|
20
|
+
* `deviceCard`, it exposes its `channel` so the host wires it to the operator
|
|
21
|
+
* terminal (ConsoleHub looks for `.channel`). Backed by an 8251 or a 6850.
|
|
22
|
+
*/
|
|
23
|
+
export declare class SerialCard implements IS100Card {
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly channel: SerialChannel;
|
|
26
|
+
constructor(id?: string, opts?: SerialCardOptions);
|
|
27
|
+
attach(bus: Bus): void;
|
|
28
|
+
reset(): void;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=SerialCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SerialCard.d.ts","sourceRoot":"","sources":["../../src/cards/SerialCard.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;AAIzC,mDAAmD;AACnD,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,OAAO,CAAC;AAE3C,oEAAoE;AACpE,UAAU,aAAc,SAAQ,SAAS;IACvC,UAAU,CAAC,EAAE,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;IAC7C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,EAAE,UAAU,CAAC;CAC5B;AAED;;;;;GAKG;AACH,qBAAa,UAAW,YAAW,SAAS;IAC1C,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;gBAEpB,EAAE,SAAW,EAAE,IAAI,GAAE,iBAAsB;IAUvD,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Usart8251 } from './Usart8251.js';
|
|
2
|
+
import { Mc6850Acia } from './Mc6850Acia.js';
|
|
3
|
+
/**
|
|
4
|
+
* A single-channel serial (UART) card — the general console board authored
|
|
5
|
+
* serial cards resolve to (Story 5.7). Unlike a bare chip wrapped in
|
|
6
|
+
* `deviceCard`, it exposes its `channel` so the host wires it to the operator
|
|
7
|
+
* terminal (ConsoleHub looks for `.channel`). Backed by an 8251 or a 6850.
|
|
8
|
+
*/
|
|
9
|
+
export class SerialCard {
|
|
10
|
+
id;
|
|
11
|
+
channel;
|
|
12
|
+
constructor(id = 'serial', opts = {}) {
|
|
13
|
+
const dataPort = opts.dataPort ?? 0x10;
|
|
14
|
+
const ctrlPort = opts.ctrlPort ?? 0x11;
|
|
15
|
+
this.id = id;
|
|
16
|
+
this.channel =
|
|
17
|
+
opts.chip === 'm6850'
|
|
18
|
+
? new Mc6850Acia(`${id}:ch`, ctrlPort, dataPort) // 6850: status/ctrl port, data port
|
|
19
|
+
: new Usart8251(`${id}:ch`, dataPort, ctrlPort); // 8251: data port, ctrl port
|
|
20
|
+
}
|
|
21
|
+
attach(bus) {
|
|
22
|
+
bus.attachIODevice(this.channel);
|
|
23
|
+
}
|
|
24
|
+
reset() {
|
|
25
|
+
this.channel.reset();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=SerialCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SerialCard.js","sourceRoot":"","sources":["../../src/cards/SerialCard.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAkB7C;;;;;GAKG;AACH,MAAM,OAAO,UAAU;IACZ,EAAE,CAAS;IACX,OAAO,CAAgB;IAEhC,YAAY,EAAE,GAAG,QAAQ,EAAE,OAA0B,EAAE;QACrD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC;QACvC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,OAAO;YACV,IAAI,CAAC,IAAI,KAAK,OAAO;gBACnB,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,oCAAoC;gBACrF,CAAC,CAAC,IAAI,SAAS,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,6BAA6B;IACpF,CAAC;IAED,MAAM,CAAC,GAAQ;QACb,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { IIODevice } from '../interfaces/IIODevice.js';
|
|
2
|
+
type TransmitCallback = (byte: number) => void;
|
|
3
|
+
type ControlCallback = (value: number) => void;
|
|
4
|
+
/**
|
|
5
|
+
* TR1602B / TMS-6011 / AY-5-1013 / HD-6402 standalone UART, as used on the
|
|
6
|
+
* IMSAI MIO board. Unlike the Intel 8251 (see {@link Usart8251}), this chip has
|
|
7
|
+
* no software-writable mode/command registers — the data format is fixed by
|
|
8
|
+
* hardware jumpers. There is therefore no initialization sequence, and the
|
|
9
|
+
* transmitter is ready immediately after power-on. The UART itself has no CTS
|
|
10
|
+
* awareness: TxRDY (TBRE) is high whenever the transmit buffer is empty.
|
|
11
|
+
*
|
|
12
|
+
* Occupies two consecutive I/O ports:
|
|
13
|
+
* dataPort — read: received byte (clears Data-Received); write: transmit
|
|
14
|
+
* statusPort — read: status flags; write: board control register (8212)
|
|
15
|
+
*
|
|
16
|
+
* Status byte (SIO-2-compatible wiring — the recommended MIO configuration):
|
|
17
|
+
* bit0 TxRDY (TBRE) — 1 = ready to accept a byte to transmit (always 1)
|
|
18
|
+
* bit1 RxRDY (DR) — 1 = a received byte is available
|
|
19
|
+
* bit2 TxEMPTY (TRE) — 1 = transmit shift register idle (always 1)
|
|
20
|
+
* bit3 PE — parity error on the last received byte
|
|
21
|
+
* bit4 OE — overrun (byte arrived before the previous was read)
|
|
22
|
+
* bit5 FE — framing error on the last received byte
|
|
23
|
+
* bit6/7 — board-specific, unused here
|
|
24
|
+
*/
|
|
25
|
+
export declare class Tr1602Uart implements IIODevice {
|
|
26
|
+
private readonly dataPort;
|
|
27
|
+
private readonly statusPort;
|
|
28
|
+
readonly id: string;
|
|
29
|
+
readonly basePorts: ReadonlyArray<number>;
|
|
30
|
+
private errorFlags;
|
|
31
|
+
private rxQueue;
|
|
32
|
+
private controlReg;
|
|
33
|
+
private transmitCb;
|
|
34
|
+
private controlCb;
|
|
35
|
+
constructor(id: string, dataPort: number, statusPort: number);
|
|
36
|
+
ioRead(port: number): number;
|
|
37
|
+
ioWrite(port: number, value: number): void;
|
|
38
|
+
reset(): void;
|
|
39
|
+
/**
|
|
40
|
+
* Feed a received byte to the UART. Sets Data-Received (RxRDY). A byte
|
|
41
|
+
* arriving while the single-byte buffer is still full flags an overrun (OE),
|
|
42
|
+
* mirroring the TR1602's lack of a receive FIFO.
|
|
43
|
+
*/
|
|
44
|
+
enqueueRx(byte: number): void;
|
|
45
|
+
onTransmit(cb: TransmitCallback): void;
|
|
46
|
+
/** Register a callback fired on writes to the board control register. */
|
|
47
|
+
onControl(cb: ControlCallback): void;
|
|
48
|
+
/** Last value written to the board control register (statusPort write). */
|
|
49
|
+
get control(): number;
|
|
50
|
+
/** Inject receive error flags (parity / overrun / framing) for the next read. */
|
|
51
|
+
setErrors(pe: boolean, oe: boolean, fe: boolean): void;
|
|
52
|
+
private buildStatus;
|
|
53
|
+
}
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=Tr1602Uart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tr1602Uart.d.ts","sourceRoot":"","sources":["../../src/cards/Tr1602Uart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAC/C,KAAK,eAAe,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,UAAW,YAAW,SAAS;IAWlB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAAU,OAAO,CAAC,QAAQ,CAAC,UAAU;IAVtF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAG1C,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,SAAS,CAA8B;gBAEnC,EAAE,EAAE,MAAM,EAAmB,QAAQ,EAAE,MAAM,EAAmB,UAAU,EAAE,MAAM;IAK9F,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAY5B,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAY1C,KAAK,IAAI,IAAI;IAOb;;;;OAIG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAO7B,UAAU,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI;IAItC,yEAAyE;IACzE,SAAS,CAAC,EAAE,EAAE,eAAe,GAAG,IAAI;IAIpC,2EAA2E;IAC3E,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,iFAAiF;IACjF,SAAS,CAAC,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI;IAItD,OAAO,CAAC,WAAW;CAOpB"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { u8 } from '../util/bits.js';
|
|
2
|
+
/**
|
|
3
|
+
* TR1602B / TMS-6011 / AY-5-1013 / HD-6402 standalone UART, as used on the
|
|
4
|
+
* IMSAI MIO board. Unlike the Intel 8251 (see {@link Usart8251}), this chip has
|
|
5
|
+
* no software-writable mode/command registers — the data format is fixed by
|
|
6
|
+
* hardware jumpers. There is therefore no initialization sequence, and the
|
|
7
|
+
* transmitter is ready immediately after power-on. The UART itself has no CTS
|
|
8
|
+
* awareness: TxRDY (TBRE) is high whenever the transmit buffer is empty.
|
|
9
|
+
*
|
|
10
|
+
* Occupies two consecutive I/O ports:
|
|
11
|
+
* dataPort — read: received byte (clears Data-Received); write: transmit
|
|
12
|
+
* statusPort — read: status flags; write: board control register (8212)
|
|
13
|
+
*
|
|
14
|
+
* Status byte (SIO-2-compatible wiring — the recommended MIO configuration):
|
|
15
|
+
* bit0 TxRDY (TBRE) — 1 = ready to accept a byte to transmit (always 1)
|
|
16
|
+
* bit1 RxRDY (DR) — 1 = a received byte is available
|
|
17
|
+
* bit2 TxEMPTY (TRE) — 1 = transmit shift register idle (always 1)
|
|
18
|
+
* bit3 PE — parity error on the last received byte
|
|
19
|
+
* bit4 OE — overrun (byte arrived before the previous was read)
|
|
20
|
+
* bit5 FE — framing error on the last received byte
|
|
21
|
+
* bit6/7 — board-specific, unused here
|
|
22
|
+
*/
|
|
23
|
+
export class Tr1602Uart {
|
|
24
|
+
dataPort;
|
|
25
|
+
statusPort;
|
|
26
|
+
id;
|
|
27
|
+
basePorts;
|
|
28
|
+
// bit0=PE, bit1=OE, bit2=FE — positioned into status bits 3-5 when read.
|
|
29
|
+
errorFlags = 0;
|
|
30
|
+
rxQueue = [];
|
|
31
|
+
controlReg = 0;
|
|
32
|
+
transmitCb;
|
|
33
|
+
controlCb;
|
|
34
|
+
constructor(id, dataPort, statusPort) {
|
|
35
|
+
this.dataPort = dataPort;
|
|
36
|
+
this.statusPort = statusPort;
|
|
37
|
+
this.id = id;
|
|
38
|
+
this.basePorts = [dataPort, statusPort];
|
|
39
|
+
}
|
|
40
|
+
ioRead(port) {
|
|
41
|
+
if (port === this.statusPort) {
|
|
42
|
+
return this.buildStatus();
|
|
43
|
+
}
|
|
44
|
+
// Data port read: pull the received byte, clearing Data-Received (DR).
|
|
45
|
+
const byte = this.rxQueue.shift();
|
|
46
|
+
if (this.rxQueue.length === 0) {
|
|
47
|
+
this.errorFlags &= ~0x02; // overrun clears once the buffer drains
|
|
48
|
+
}
|
|
49
|
+
return byte !== undefined ? byte : 0xff;
|
|
50
|
+
}
|
|
51
|
+
ioWrite(port, value) {
|
|
52
|
+
if (port === this.statusPort) {
|
|
53
|
+
// Board control register (8212): DTR / RTS / cassette motor / etc.
|
|
54
|
+
this.controlReg = u8(value);
|
|
55
|
+
this.controlCb?.(this.controlReg);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
// Data port write: transmit immediately. The UART is always ready — no
|
|
59
|
+
// init sequence and no CTS gating.
|
|
60
|
+
this.transmitCb?.(u8(value));
|
|
61
|
+
}
|
|
62
|
+
reset() {
|
|
63
|
+
this.errorFlags = 0;
|
|
64
|
+
this.rxQueue = [];
|
|
65
|
+
this.controlReg = 0;
|
|
66
|
+
// transmitCb / controlCb survive reset — they are host wiring.
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Feed a received byte to the UART. Sets Data-Received (RxRDY). A byte
|
|
70
|
+
* arriving while the single-byte buffer is still full flags an overrun (OE),
|
|
71
|
+
* mirroring the TR1602's lack of a receive FIFO.
|
|
72
|
+
*/
|
|
73
|
+
enqueueRx(byte) {
|
|
74
|
+
if (this.rxQueue.length > 0) {
|
|
75
|
+
this.errorFlags |= 0x02; // OE: previous byte was not read in time
|
|
76
|
+
}
|
|
77
|
+
this.rxQueue.push(u8(byte));
|
|
78
|
+
}
|
|
79
|
+
onTransmit(cb) {
|
|
80
|
+
this.transmitCb = cb;
|
|
81
|
+
}
|
|
82
|
+
/** Register a callback fired on writes to the board control register. */
|
|
83
|
+
onControl(cb) {
|
|
84
|
+
this.controlCb = cb;
|
|
85
|
+
}
|
|
86
|
+
/** Last value written to the board control register (statusPort write). */
|
|
87
|
+
get control() {
|
|
88
|
+
return this.controlReg;
|
|
89
|
+
}
|
|
90
|
+
/** Inject receive error flags (parity / overrun / framing) for the next read. */
|
|
91
|
+
setErrors(pe, oe, fe) {
|
|
92
|
+
this.errorFlags = (pe ? 0x01 : 0) | (oe ? 0x02 : 0) | (fe ? 0x04 : 0);
|
|
93
|
+
}
|
|
94
|
+
buildStatus() {
|
|
95
|
+
const txRDY = 0x01; // transmit buffer always ready
|
|
96
|
+
const rxRDY = this.rxQueue.length > 0 ? 0x02 : 0;
|
|
97
|
+
const txEMPTY = 0x04; // transmit register always idle
|
|
98
|
+
const errors = (this.errorFlags & 0x07) << 3;
|
|
99
|
+
return txRDY | rxRDY | txEMPTY | errors;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=Tr1602Uart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Tr1602Uart.js","sourceRoot":"","sources":["../../src/cards/Tr1602Uart.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { IIODevice } from '../interfaces/IIODevice.js';
|
|
2
|
+
type TransmitCallback = (byte: number) => void;
|
|
3
|
+
export declare class Usart8251 implements IIODevice {
|
|
4
|
+
private readonly dataPort;
|
|
5
|
+
private readonly ctrlPort;
|
|
6
|
+
readonly id: string;
|
|
7
|
+
readonly basePorts: ReadonlyArray<number>;
|
|
8
|
+
private phase;
|
|
9
|
+
private modeWord;
|
|
10
|
+
private txEnable;
|
|
11
|
+
private rxEnable;
|
|
12
|
+
private errorFlags;
|
|
13
|
+
private rxQueue;
|
|
14
|
+
private transmitCb;
|
|
15
|
+
private ctsActive;
|
|
16
|
+
private dsrActive;
|
|
17
|
+
constructor(id: string, dataPort: number, ctrlPort: number);
|
|
18
|
+
ioWrite(port: number, value: number): void;
|
|
19
|
+
ioRead(port: number): number;
|
|
20
|
+
reset(): void;
|
|
21
|
+
enqueueRx(byte: number): void;
|
|
22
|
+
onTransmit(cb: TransmitCallback): void;
|
|
23
|
+
setCts(active: boolean): void;
|
|
24
|
+
setDsr(active: boolean): void;
|
|
25
|
+
private buildStatus;
|
|
26
|
+
}
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=Usart8251.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Usart8251.d.ts","sourceRoot":"","sources":["../../src/cards/Usart8251.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAG5D,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;AAE/C,qBAAa,SAAU,YAAW,SAAS;IAejB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAAU,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAdpF,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAE1C,OAAO,CAAC,KAAK,CAA8B;IAC3C,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IAEzB,OAAO,CAAC,UAAU,CAAK;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,UAAU,CAA+B;IACjD,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,SAAS,CAAQ;gBAEb,EAAE,EAAE,MAAM,EAAmB,QAAQ,EAAE,MAAM,EAAmB,QAAQ,EAAE,MAAM;IAK5F,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IA6B1C,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;IAQ5B,KAAK,IAAI,IAAI;IAUb,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAI7B,UAAU,CAAC,EAAE,EAAE,gBAAgB,GAAG,IAAI;IAItC,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAI7B,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAI7B,OAAO,CAAC,WAAW;CAQpB"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { u8 } from '../util/bits.js';
|
|
2
|
+
export class Usart8251 {
|
|
3
|
+
dataPort;
|
|
4
|
+
ctrlPort;
|
|
5
|
+
id;
|
|
6
|
+
basePorts;
|
|
7
|
+
phase = 'mode';
|
|
8
|
+
modeWord = 0;
|
|
9
|
+
txEnable = false;
|
|
10
|
+
rxEnable = false;
|
|
11
|
+
// 3-bit error field: bit0=PE, bit1=OE, bit2=FE — packed into status bits 3-5
|
|
12
|
+
errorFlags = 0;
|
|
13
|
+
rxQueue = [];
|
|
14
|
+
transmitCb;
|
|
15
|
+
ctsActive = true;
|
|
16
|
+
dsrActive = true;
|
|
17
|
+
constructor(id, dataPort, ctrlPort) {
|
|
18
|
+
this.dataPort = dataPort;
|
|
19
|
+
this.ctrlPort = ctrlPort;
|
|
20
|
+
this.id = id;
|
|
21
|
+
this.basePorts = [dataPort, ctrlPort];
|
|
22
|
+
}
|
|
23
|
+
ioWrite(port, value) {
|
|
24
|
+
if (port === this.ctrlPort) {
|
|
25
|
+
if (this.phase === 'mode') {
|
|
26
|
+
this.modeWord = value;
|
|
27
|
+
this.phase = 'command';
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
if ((value & 0x40) !== 0) {
|
|
31
|
+
this.phase = 'mode';
|
|
32
|
+
this.txEnable = false;
|
|
33
|
+
this.rxEnable = false;
|
|
34
|
+
this.errorFlags = 0;
|
|
35
|
+
this.rxQueue = [];
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.txEnable = (value & 0x01) !== 0;
|
|
39
|
+
this.rxEnable = (value & 0x04) !== 0;
|
|
40
|
+
if ((value & 0x10) !== 0) {
|
|
41
|
+
this.errorFlags = 0;
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
if (port === this.dataPort) {
|
|
46
|
+
if (this.txEnable && this.ctsActive) {
|
|
47
|
+
this.transmitCb?.(u8(value));
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
ioRead(port) {
|
|
52
|
+
if (port === this.ctrlPort) {
|
|
53
|
+
return this.buildStatus();
|
|
54
|
+
}
|
|
55
|
+
const byte = this.rxQueue.shift();
|
|
56
|
+
return byte !== undefined ? byte : 0xff;
|
|
57
|
+
}
|
|
58
|
+
reset() {
|
|
59
|
+
this.phase = 'mode';
|
|
60
|
+
this.modeWord = 0;
|
|
61
|
+
this.txEnable = false;
|
|
62
|
+
this.rxEnable = false;
|
|
63
|
+
this.errorFlags = 0;
|
|
64
|
+
this.rxQueue = [];
|
|
65
|
+
// transmitCb, ctsActive, dsrActive survive reset — they are host wiring
|
|
66
|
+
}
|
|
67
|
+
enqueueRx(byte) {
|
|
68
|
+
this.rxQueue.push(u8(byte));
|
|
69
|
+
}
|
|
70
|
+
onTransmit(cb) {
|
|
71
|
+
this.transmitCb = cb;
|
|
72
|
+
}
|
|
73
|
+
setCts(active) {
|
|
74
|
+
this.ctsActive = active;
|
|
75
|
+
}
|
|
76
|
+
setDsr(active) {
|
|
77
|
+
this.dsrActive = active;
|
|
78
|
+
}
|
|
79
|
+
buildStatus() {
|
|
80
|
+
const txRDY = this.txEnable && this.ctsActive ? 0x01 : 0;
|
|
81
|
+
const rxRDY = this.rxEnable && this.rxQueue.length > 0 ? 0x02 : 0;
|
|
82
|
+
const txEMPTY = 0x04;
|
|
83
|
+
const errors = (this.errorFlags & 0x07) << 3;
|
|
84
|
+
const dsr = this.dsrActive ? 0x80 : 0;
|
|
85
|
+
return txRDY | rxRDY | txEMPTY | errors | dsr;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=Usart8251.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Usart8251.js","sourceRoot":"","sources":["../../src/cards/Usart8251.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 type { DisplaySurface } from './DisplaySurface.js';
|
|
4
|
+
export interface VdmCardOptions {
|
|
5
|
+
/** Video RAM base (the VDM-1 mapped its 1K at 0xCC00). */
|
|
6
|
+
readonly base?: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Processor Technology VDM-1 memory-mapped character display (Story 5.9).
|
|
10
|
+
*
|
|
11
|
+
* A passive display: 1 KB of video RAM the CPU writes ASCII into; a character
|
|
12
|
+
* generator turns each byte into a glyph (bit 7 = inverse). The card owns no
|
|
13
|
+
* memory of its own — its video RAM is a declared `MachineSpec.memory` region
|
|
14
|
+
* (so it's overlap-validated and shows on the memory-map ribbon), and the card
|
|
15
|
+
* reads it back through the bus each frame for the host to render.
|
|
16
|
+
*/
|
|
17
|
+
export declare class VdmCard implements IS100Card {
|
|
18
|
+
readonly id: string;
|
|
19
|
+
readonly display: DisplaySurface;
|
|
20
|
+
private readonly base;
|
|
21
|
+
private bus?;
|
|
22
|
+
constructor(id?: string, opts?: VdmCardOptions);
|
|
23
|
+
attach(bus: Bus): void;
|
|
24
|
+
reset(): void;
|
|
25
|
+
private readVram;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=VdmCard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VdmCard.d.ts","sourceRoot":"","sources":["../../src/cards/VdmCard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAO1D,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;GAQG;AACH,qBAAa,OAAQ,YAAW,SAAS;IACvC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,cAAc,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;IAC9B,OAAO,CAAC,GAAG,CAAC,CAAM;gBAEN,EAAE,SAAQ,EAAE,IAAI,GAAE,cAAmB;IASjD,MAAM,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI;IAItB,KAAK,IAAI,IAAI;IAEb,OAAO,CAAC,QAAQ;CAMjB"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Processor Technology VDM-1: 16 lines × 64 characters = 1024 bytes. */
|
|
2
|
+
const COLS = 64;
|
|
3
|
+
const ROWS = 16;
|
|
4
|
+
const SIZE = COLS * ROWS;
|
|
5
|
+
/**
|
|
6
|
+
* Processor Technology VDM-1 memory-mapped character display (Story 5.9).
|
|
7
|
+
*
|
|
8
|
+
* A passive display: 1 KB of video RAM the CPU writes ASCII into; a character
|
|
9
|
+
* generator turns each byte into a glyph (bit 7 = inverse). The card owns no
|
|
10
|
+
* memory of its own — its video RAM is a declared `MachineSpec.memory` region
|
|
11
|
+
* (so it's overlap-validated and shows on the memory-map ribbon), and the card
|
|
12
|
+
* reads it back through the bus each frame for the host to render.
|
|
13
|
+
*/
|
|
14
|
+
export class VdmCard {
|
|
15
|
+
id;
|
|
16
|
+
display;
|
|
17
|
+
base;
|
|
18
|
+
bus;
|
|
19
|
+
constructor(id = 'vdm', opts = {}) {
|
|
20
|
+
this.id = id;
|
|
21
|
+
this.base = (opts.base ?? 0xcc00) & 0xffff;
|
|
22
|
+
this.display = {
|
|
23
|
+
descriptor: { mode: 'charGrid', cols: COLS, rows: ROWS, font: 'vdm', attrBit: 7 },
|
|
24
|
+
frame: () => ({ bytes: this.readVram(), state: {} }),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
attach(bus) {
|
|
28
|
+
this.bus = bus; // the video RAM is a separate MachineSpec.memory region
|
|
29
|
+
}
|
|
30
|
+
reset() { }
|
|
31
|
+
readVram() {
|
|
32
|
+
const out = new Uint8Array(SIZE);
|
|
33
|
+
const bus = this.bus;
|
|
34
|
+
if (bus)
|
|
35
|
+
for (let i = 0; i < SIZE; i++)
|
|
36
|
+
out[i] = bus.read((this.base + i) & 0xffff) & 0xff;
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=VdmCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VdmCard.js","sourceRoot":"","sources":["../../src/cards/VdmCard.ts"],"names":[],"mappings":"AAIA,yEAAyE;AACzE,MAAM,IAAI,GAAG,EAAE,CAAC;AAChB,MAAM,IAAI,GAAG,EAAE,CAAC;AAChB,MAAM,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAOzB;;;;;;;;GAQG;AACH,MAAM,OAAO,OAAO;IACT,EAAE,CAAS;IACX,OAAO,CAAiB;IAChB,IAAI,CAAS;IACtB,GAAG,CAAO;IAElB,YAAY,EAAE,GAAG,KAAK,EAAE,OAAuB,EAAE;QAC/C,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,GAAG,MAAM,CAAC;QAC3C,IAAI,CAAC,OAAO,GAAG;YACb,UAAU,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,EAAE;YACjF,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;SACrD,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,GAAQ;QACb,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,wDAAwD;IAC1E,CAAC;IAED,KAAK,KAAU,CAAC;IAER,QAAQ;QACd,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;QACrB,IAAI,GAAG;YAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,CAAC,EAAE;gBAAE,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,IAAI,CAAC;QAC3F,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImmediateClock.d.ts","sourceRoot":"","sources":["../../src/clock/ImmediateClock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,qBAAa,cAAe,YAAW,MAAM;IAC3C,OAAO,CAAC,OAAO,CAAM;IAErB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,gBAAgB,IAAI,MAAM;IAI1B,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImmediateClock.js","sourceRoot":"","sources":["../../src/clock/ImmediateClock.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,cAAc;IACjB,OAAO,GAAG,EAAE,CAAC;IAErB,SAAS,CAAC,MAAc;QACtB,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;IACjC,CAAC;IAED,gBAAgB;QACd,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;IACpB,CAAC;CACF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IClock } from '../interfaces/IClock.js';
|
|
2
|
+
/**
|
|
3
|
+
* A real-time clock that tracks how far the simulation has run relative to a
|
|
4
|
+
* target CPU frequency. Uses performance.now() for timing — works in Node 16+,
|
|
5
|
+
* all browsers, Deno, Bun. Uses setTimeout(fn, 0) for yielding — no
|
|
6
|
+
* setImmediate or process.* dependencies.
|
|
7
|
+
*
|
|
8
|
+
* Drift accounting is absolute (cycles vs. wall time since the last baseline),
|
|
9
|
+
* so oversleeping or scheduler jitter self-corrects instead of accumulating.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SystemClock implements IClock {
|
|
12
|
+
private elapsed;
|
|
13
|
+
private hz;
|
|
14
|
+
private startTime;
|
|
15
|
+
private cyclesAtStart;
|
|
16
|
+
private readonly now;
|
|
17
|
+
constructor(hz?: number, now?: () => number);
|
|
18
|
+
addCycles(cycles: number): void;
|
|
19
|
+
getElapsedCycles(): bigint;
|
|
20
|
+
reset(): void;
|
|
21
|
+
get targetHz(): number;
|
|
22
|
+
/**
|
|
23
|
+
* Change the target frequency. Re-baselines so the new rate applies from
|
|
24
|
+
* this moment — cycles already executed are not retroactively repriced.
|
|
25
|
+
*/
|
|
26
|
+
setHz(hz: number): void;
|
|
27
|
+
/**
|
|
28
|
+
* Forfeit any accumulated drift and restart pacing from "now". Used after
|
|
29
|
+
* host stalls (GC pause, suspended tab) so the simulation doesn't sprint to
|
|
30
|
+
* catch up on lost wall time.
|
|
31
|
+
*/
|
|
32
|
+
resync(): void;
|
|
33
|
+
/**
|
|
34
|
+
* Returns a promise that resolves after yielding to the event loop.
|
|
35
|
+
* Callers should await this periodically to avoid blocking.
|
|
36
|
+
*/
|
|
37
|
+
yield(): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* How far ahead (in ms) the simulation is relative to wall time.
|
|
40
|
+
* Positive = running too fast (should sleep); negative = behind.
|
|
41
|
+
*/
|
|
42
|
+
getAheadMs(): number;
|
|
43
|
+
private rebaseline;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=SystemClock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SystemClock.d.ts","sourceRoot":"","sources":["../../src/clock/SystemClock.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD;;;;;;;;GAQG;AACH,qBAAa,WAAY,YAAW,MAAM;IACxC,OAAO,CAAC,OAAO,CAAM;IACrB,OAAO,CAAC,EAAE,CAAS;IACnB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,aAAa,CAAM;IAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,EAAE,SAAY,EAAE,GAAG,GAAE,MAAM,MAAgC;IAMvE,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI/B,gBAAgB,IAAI,MAAM;IAI1B,KAAK,IAAI,IAAI;IAKb,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;OAGG;IACH,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKvB;;;;OAIG;IACH,MAAM,IAAI,IAAI;IAId;;;OAGG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB;;;OAGG;IACH,UAAU,IAAI,MAAM;IAMpB,OAAO,CAAC,UAAU;CAInB"}
|