8086emu 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Danish
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # multi-cpu-emu
2
+
3
+ A single Rust crate that emulates six classic microprocessors:
4
+
5
+ - **Intel 8086** — 16-bit, segmented, 1 MiB address space; includes an 8259 PIC
6
+ and 8253 PIT so timer interrupts (IRQ0 → `INT 8`) fire end-to-end
7
+ - **Intel 8085** — 8-bit, 64 KiB, accumulator-centric
8
+ - **Intel 8051 (MCS-51)** — 8-bit, SFRs, bit-addressable RAM, timers
9
+ - **MOS 6502** — 8-bit, decimal mode, NMI/IRQ/BRK vectoring
10
+ - **Zilog Z80** — 8-bit, IM 0/1/2, NMI/INT, full 8080 + Z80 ops
11
+ - **RISC-V rv32i (+M)** — 32-bit, base integer ISA plus the M-extension
12
+
13
+ Each core has a matching assembler, and the whole crate compiles to **one WASM
14
+ module** (via `wasm-bindgen`, feature `wasm`) plus a native `rlib`/`cdylib`.
15
+ A full dependency-free web IDE for students lives in `docs/` and deploys to
16
+ GitHub Pages with zero config.
17
+
18
+ Design was inspired by https://github.com/abuXsarkar/modern8086 (MIT) — used
19
+ only as an architecture/scope reference; all code here is written from scratch.
20
+ See `AGENTS.md` for the full architecture and per-ISA coverage.
21
+
22
+ ## Build & test
23
+
24
+ ```bash
25
+ cargo test # ~86 integration tests across all three ISAs
26
+ cargo clippy --all-targets # should be warning-free
27
+
28
+ # wasm build (needs wasm-pack)
29
+ wasm-pack build --target web --out-dir docs/pkg --release --features wasm
30
+
31
+ # self-contained WASM smoke test (exercises all three ISAs + new features)
32
+ node tools/wasm-smoke.mjs
33
+
34
+ # serve the web demo
35
+ python3 -m http.server -d docs 8000 # then open http://localhost:8000
36
+ ```
37
+
38
+ ## Web IDE / GitHub Pages
39
+
40
+ The demo in `docs/` is a student-oriented IDE: ISA selector (8086/8085/8051),
41
+ sample programs, line-numbered editor with assemble-error highlighting, step /
42
+ step-over / run / stop / reset, **click-in-gutter breakpoints** with Step-Back
43
+ time-travel, live register + flag panels, a memory dump with the PC highlighted,
44
+ a **live memory-map** (showing loaded ROM / external SRAM / 8051 EA state), an
45
+ **8051 SFR readout** (click a register to edit it live), and a program-output
46
+ console.
47
+
48
+ Deployment is handled by the workflow in `.github/workflows/pages.yml`: on every
49
+ push to `main` it builds the wasm pkg, runs the native tests, and deploys
50
+ `docs/` to GitHub Pages.
51
+
52
+ One-time setup in GitHub: **Settings → Pages → Source: "GitHub Actions"** (the
53
+ first workflow run may enable the site automatically). The site then appears at
54
+ `https://<user>.github.io/8086emu/`.
55
+
56
+ Alternative (no workflow): **Settings → Pages → Deploy from a branch → `main`,
57
+ folder `/docs`** — works because all asset paths in `docs/` are relative and the
58
+ prebuilt `docs/pkg/` is committed. After any Rust change, rebuild and commit it:
59
+ `wasm-pack build --target web --out-dir docs/pkg --release --features wasm`.
60
+ Root `index.html` redirects to `docs/` for local convenience.
61
+
62
+ ## Quick start
63
+
64
+ ### Run headless from a shell (CLI)
65
+
66
+ The CLI lives in `examples/run.rs`; it assembles source and runs the program,
67
+ printing registers, flags, and output.
68
+
69
+ ```bash
70
+ # build once
71
+ cargo build --release --example run
72
+
73
+ # 8086 hello world
74
+ cargo run --example run -- examples/hello.asm
75
+
76
+ # other ISAs, with a step cap
77
+ cargo run --example run -- --isa 8051 --max-steps 1000 examples/hello51.asm
78
+
79
+ # trace every instruction + peripheral (port) write
80
+ cargo run --example run -- --isa 8085 --verbose examples/traffic.asm
81
+
82
+ # automate checks (exit 0 = pass, 1 = fail, 2 = usage error)
83
+ cargo run --example run -- --grade tests/spec.txt examples/prog.asm
84
+
85
+ # measure emulation throughput (native numbers)
86
+ cargo run --example run -- --bench # default 10M steps
87
+ cargo run --example run -- --bench 2000000 --isa rv32
88
+ ```
89
+
90
+ ### Use it in the browser (WASM IDE)
91
+
92
+ ```bash
93
+ # serve the demo (from repo root)
94
+ python3 -m http.server -d docs 8000
95
+ # open http://localhost:8000 (root redirects to /docs/)
96
+ ```
97
+
98
+ In the IDE: pick an ISA → write code → `F7` assemble → `F5` run / `F8` step →
99
+ set breakpoints in the gutter → inspect registers, memory, and device panels.
100
+
101
+ **Browser throughput check** (open DevTools console on the IDE page; the
102
+ emulator is exposed as `window.emu`):
103
+
104
+ ```js
105
+ let t = performance.now();
106
+ let s = emu.run(1_000_000); // steps executed
107
+ let ms = performance.now() - t;
108
+ console.log(s, 'steps in', ms.toFixed(1), 'ms =>', Math.round(s / (ms/1000)), 'steps/sec');
109
+ ```
110
+
111
+ Both the CLI and the browser run the **same Rust core** (native vs WASM), so
112
+ bulk `run()` throughput is comparable; only per-instruction single-stepping
113
+ from JS is slower because of the JS↔WASM call boundary.
114
+
115
+
116
+ ## Examples
117
+
118
+ | File | ISA | Shows |
119
+ |---|---|---|
120
+ | `examples/hello.asm` | 8086 | `INT 21h` string output |
121
+ | `examples/hello85.asm` | 8085 | `OUT 01h` printing |
122
+ | `examples/hello51.asm` | 8051 | `SBUF` serial output |
123
+ | `examples/8155.asm` | 8085 | 8155 external RAM/I/O |
124
+ | `examples/timer51.asm` | 8051 | timer + interrupt |
125
+ | `examples/ser.rs` | 8051 | native serial-RX injection |
126
+ | `examples/bios.asm` | 8086 | BIOS image that boots from the reset vector `FFFF:FFF0` |
127
+
128
+ ## Layout
129
+
130
+ ```
131
+ ├── src/
132
+ │ ├── lib.rs # Emulator facade over the three cores
133
+ │ ├── cpu.rs # Cpu trait, Mem, Output, FlagSet, Reg, RunResult
134
+ │ ├── i8086.rs # 8086 CPU core (segmented, INT 21h/10h subset)
135
+ │ ├── i8085.rs # 8085 CPU core (full 8-bit ISA)
136
+ │ ├── mcs51.rs # 8051 CPU core (SFRs, bit ops, timers)
137
+ │ ├── asm/ # tokenizer + per-ISA assemblers
138
+ │ └── wasm.rs # wasm-bindgen surface (feature = "wasm")
139
+ ├── examples/run.rs # native CLI runner
140
+ ├── tests/emulation.rs # integration tests
141
+ ├── docs/ # GitHub Pages IDE (index.html + app.js + style.css + pkg/)
142
+ └── index.html # redirects to docs/
143
+ ```
144
+
145
+ ## WASM API
146
+
147
+ ```js
148
+ const emu = new Emulator("8086"); // "8086" | "8085" | "8051"
149
+ const code = emu.assemble(src); // throws on error
150
+ emu.load(code, 0x100); // write code + set PC
151
+ emu.set_pc(0x100); // (re)set the program counter
152
+ emu.run(1_000_000); // steps executed
153
+ emu.step(); emu.run_to(targetPc, 1_000_000); // step / run-to-line (Step-Over)
154
+ emu.pc(); emu.regs(); emu.flags(); // "AX=1234" / "ZF"
155
+ emu.mem(0, 64); // raw bytes
156
+ emu.out(); // program output (drains)
157
+ emu.halted(); emu.reset();
158
+ emu.snapshot(); emu.restore(bytes); // deterministic time-travel
159
+
160
+ // External memory (write-protected ROM / external SRAM / 8051 EA):
161
+ emu.set_rom_region(0xF0000, 0x10000); // mark ROM range
162
+ emu.load_rom(bytes, 0xF0000); // place a firmware image
163
+ emu.set_ea(false); // 8051: fetch code from XDATA
164
+ emu.set_sram(0x9000, 0x2000); // 8085: (re)map external SRAM
165
+ emu.rom_region(); emu.sram_region(); // live memory-map info
166
+ emu.ea_active(); emu.ext_code_region();
167
+
168
+ // 8051 peripheral registers:
169
+ emu.sfr(0xD0); emu.set_sfr(0xD0, 0x00); // read/write an SFR
170
+ ```
171
+
172
+ ## Program output conventions
173
+
174
+ - **8086** — `INT 21h` (AH=02, 06, 09, 4Ch) and `INT 10h` (AH=0Eh) write to the
175
+ output buffer.
176
+ - **8085** — `OUT 01h` prints the char in A.
177
+ - **8051** — writing to `SBUF` prints the char.
@@ -0,0 +1,317 @@
1
+ /* tslint:disable */
2
+ /* eslint-disable */
3
+
4
+ export class Emulator {
5
+ free(): void;
6
+ [Symbol.dispose](): void;
7
+ /**
8
+ * Assemble source for the current ISA; returns machine code bytes.
9
+ */
10
+ assemble(source: string): Uint8Array;
11
+ /**
12
+ * Assemble and return per-line machine code as "ADDR BYTES" strings
13
+ * (one per source line, empty for lines that emit nothing).
14
+ */
15
+ assemble_info(source: string): string[];
16
+ /**
17
+ * 8086 text cursor as [col, row]; [0,0] otherwise.
18
+ */
19
+ cursor(): Uint8Array;
20
+ /**
21
+ * Total clock cycles executed (machine cycles / T-states). Drives the
22
+ * cycle-accurate timers (8086 PIT, 8051 timers, 8085 8155 timer).
23
+ */
24
+ cycles(): bigint;
25
+ /**
26
+ * Disassemble `count` instructions starting at `addr`. Each returned line
27
+ * is "ADDR BYTES text" (use `Disasm::line`). Other ISAs return [].
28
+ */
29
+ disasm(addr: number, count: number): string[];
30
+ /**
31
+ * 8051 EA pin state (true = internal code, false = external via XDATA).
32
+ */
33
+ ea_active(): boolean;
34
+ /**
35
+ * 8051 external-code (XDATA) region (base, len) when EA is low, else null.
36
+ */
37
+ ext_code_region(): Uint32Array | undefined;
38
+ /**
39
+ * Active flag names as short strings (e.g. "ZF", "CY").
40
+ */
41
+ flags(): string[];
42
+ /**
43
+ * Read a file back from the 8086 DOS virtual filesystem (empty if absent).
44
+ */
45
+ fs_get(name: string): Uint8Array | undefined;
46
+ /**
47
+ * Preload a file into the 8086 DOS virtual filesystem.
48
+ */
49
+ fs_put(name: string, data: Uint8Array): void;
50
+ /**
51
+ * 8086 graphics framebuffer, or None when in a text mode / non-8086 ISA.
52
+ */
53
+ gfx(): GfxInfo | undefined;
54
+ /**
55
+ * True once the CPU has executed HLT (or otherwise stopped).
56
+ */
57
+ halted(): boolean;
58
+ /**
59
+ * Hardware interrupt: 8085 = "TRAP" | "RST75" | "RST65" | "RST55" |
60
+ * "INTR" (data = vector); 8051 = "INT0" | "INT1". Throws on unknown kind.
61
+ */
62
+ interrupt(kind: string, data: number): void;
63
+ /**
64
+ * Load raw machine code at `origin` and set PC there.
65
+ */
66
+ load(code: Uint8Array, origin: number): void;
67
+ /**
68
+ * Load a ROM image and mark its range read-only. 8051 routes to external
69
+ * code (XDATA) when EA is low.
70
+ */
71
+ load_rom(data: Uint8Array, addr: number): void;
72
+ /**
73
+ * Linear memory read of `len` bytes starting at `addr`.
74
+ */
75
+ mem(addr: number, len: number): Uint8Array;
76
+ /**
77
+ * Write bytes into memory (IDE memory poking).
78
+ */
79
+ mem_write(addr: number, data: Uint8Array): void;
80
+ /**
81
+ * Create an emulator for one of: "8086", "8085", "8051", "6502", "Z80", "rv32".
82
+ * Throws if the ISA name is unknown.
83
+ */
84
+ constructor(isa: string);
85
+ /**
86
+ * Drain the program output buffer.
87
+ */
88
+ out(): string;
89
+ /**
90
+ * Current program counter (instruction pointer).
91
+ */
92
+ pc(): number;
93
+ /**
94
+ * Current reload/count of an 8086 PIT channel (0..2). Other ISAs: 0.
95
+ */
96
+ pit_count(n: number): number;
97
+ /**
98
+ * Queue a key for the 8086's INT 21h keyboard reads (AH=01/06/07/08/0C).
99
+ */
100
+ port_read(port: number): number;
101
+ /**
102
+ * Write an I/O port byte (8085/8086: port space 0-255; 8051: P0-P3 pins).
103
+ */
104
+ port_write(port: number, val: number): void;
105
+ /**
106
+ * Queue a type-ahead character for INT 21h/keyboard reads (8086).
107
+ */
108
+ push_key(ch: number): void;
109
+ /**
110
+ * Register dump as "NAME=value" strings (e.g. "AX=1234").
111
+ */
112
+ regs(): string[];
113
+ /**
114
+ * Reset the CPU to its initial state (registers, flags, PC, memory preserved).
115
+ */
116
+ reset(): void;
117
+ /**
118
+ * Restore a previously captured `snapshot()` (state must match the ISA).
119
+ */
120
+ restore(data: Uint8Array): void;
121
+ /**
122
+ * Write-protected ROM region (base, len) if configured, else null.
123
+ */
124
+ rom_region(): Uint32Array | undefined;
125
+ /**
126
+ * Run up to `max_steps` instructions; returns steps executed.
127
+ */
128
+ run(max_steps: number): number;
129
+ /**
130
+ * Run until PC lands on one of `bps` (that instruction is NOT executed),
131
+ * or halt / blocked on input / max steps. Returns steps executed.
132
+ */
133
+ run_bp(max_steps: number, bps: Uint32Array): number;
134
+ /**
135
+ * Run until `target` is the next instruction to execute (not executed),
136
+ * or halt / blocked on input / max steps. Returns steps executed.
137
+ */
138
+ run_to(target_pc: number, max_steps: number): number;
139
+ /**
140
+ * 8086 text-mode framebuffer (80x25 char/attr pairs at 0xB8000); [] otherwise.
141
+ */
142
+ screen(): Uint8Array;
143
+ /**
144
+ * Inject a received serial byte into the 8051 (sets SBUF + RI).
145
+ */
146
+ serial_rx(ch: number): void;
147
+ /**
148
+ * Set the emulated DOS/BIOS date-time clock (INT 21h 2Ah/2Ch, INT 1Ah).
149
+ */
150
+ set_clock(year: number, month: number, day: number, hour: number, min: number, sec: number): void;
151
+ /**
152
+ * 8051 EA pin: false => fetch code from external program memory (XDATA).
153
+ */
154
+ set_ea(ea: boolean): void;
155
+ /**
156
+ * Set the Z80 interrupt mode (0/1 -> 0x0038, 2 -> I*0x100 + data).
157
+ */
158
+ set_interrupt_mode(m: number): void;
159
+ /**
160
+ * Set the program counter (entry point after load).
161
+ */
162
+ set_pc(addr: number): void;
163
+ /**
164
+ * Set a register by name (e.g. "AX", "PC", "R0"). Used by the IDE watch
165
+ * window for click-to-edit. Ignored for names the ISA does not expose.
166
+ */
167
+ set_reg(name: string, val: number): void;
168
+ /**
169
+ * Mark `[base, base+len)` of main memory as read-only ROM (8086/8085).
170
+ */
171
+ set_rom_region(base: number, len: number): void;
172
+ /**
173
+ * Write an 8051 SFR / IRAM byte (peripheral-register editor).
174
+ */
175
+ set_sfr(addr: number, v: number): void;
176
+ /**
177
+ * Set the 8085 SID (Serial Input Data) pin read by RIM (bit 7). 8085 only.
178
+ */
179
+ set_sid(v: boolean): void;
180
+ /**
181
+ * 8085: (re)configure the external SRAM chip window (default 8 KiB @ 0x9000).
182
+ */
183
+ set_sram(base: number, len: number): void;
184
+ /**
185
+ * Read an 8051 SFR / IRAM byte (peripheral-register readout).
186
+ */
187
+ sfr(addr: number): number;
188
+ /**
189
+ * Deterministic serialization of full CPU state (for save/restore and step-back).
190
+ */
191
+ snapshot(): Uint8Array;
192
+ /**
193
+ * Read the 8085 SOD (Serial Output Data) pin set by SIM (bit 7). 8085 only.
194
+ */
195
+ sod(): number;
196
+ /**
197
+ * External SRAM window (base, len) if configured (8055), else null.
198
+ */
199
+ sram_region(): Uint32Array | undefined;
200
+ /**
201
+ * Execute one instruction.
202
+ */
203
+ step(): void;
204
+ /**
205
+ * Current 8086 video mode (0 when not 8086 / unknown). MR=13h -> pixel graphics.
206
+ */
207
+ video_mode(): number;
208
+ /**
209
+ * True while the 8086 is blocked on an INT 21h read with an empty buffer.
210
+ */
211
+ waiting_input(): boolean;
212
+ }
213
+
214
+ /**
215
+ * Graphics framebuffer descriptor (8086 pixel modes). `base` is the linear
216
+ * memory address of the pixel data; `w`/`h` are the dimensions in pixels.
217
+ */
218
+ export class GfxInfo {
219
+ private constructor();
220
+ free(): void;
221
+ [Symbol.dispose](): void;
222
+ base: number;
223
+ h: number;
224
+ w: number;
225
+ }
226
+
227
+ export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
228
+
229
+ export interface InitOutput {
230
+ readonly memory: WebAssembly.Memory;
231
+ readonly __wbg_emulator_free: (a: number, b: number) => void;
232
+ readonly __wbg_get_gfxinfo_base: (a: number) => number;
233
+ readonly __wbg_get_gfxinfo_h: (a: number) => number;
234
+ readonly __wbg_get_gfxinfo_w: (a: number) => number;
235
+ readonly __wbg_gfxinfo_free: (a: number, b: number) => void;
236
+ readonly __wbg_set_gfxinfo_base: (a: number, b: number) => void;
237
+ readonly __wbg_set_gfxinfo_h: (a: number, b: number) => void;
238
+ readonly __wbg_set_gfxinfo_w: (a: number, b: number) => void;
239
+ readonly emulator_assemble: (a: number, b: number, c: number) => [number, number, number, number];
240
+ readonly emulator_assemble_info: (a: number, b: number, c: number) => [number, number, number, number];
241
+ readonly emulator_cursor: (a: number) => [number, number];
242
+ readonly emulator_cycles: (a: number) => bigint;
243
+ readonly emulator_disasm: (a: number, b: number, c: number) => [number, number];
244
+ readonly emulator_ea_active: (a: number) => number;
245
+ readonly emulator_ext_code_region: (a: number) => [number, number];
246
+ readonly emulator_flags: (a: number) => [number, number];
247
+ readonly emulator_fs_get: (a: number, b: number, c: number) => [number, number, number, number];
248
+ readonly emulator_fs_put: (a: number, b: number, c: number, d: number, e: number) => [number, number];
249
+ readonly emulator_gfx: (a: number) => number;
250
+ readonly emulator_halted: (a: number) => number;
251
+ readonly emulator_interrupt: (a: number, b: number, c: number, d: number) => [number, number];
252
+ readonly emulator_load: (a: number, b: number, c: number, d: number) => void;
253
+ readonly emulator_load_rom: (a: number, b: number, c: number, d: number) => void;
254
+ readonly emulator_mem: (a: number, b: number, c: number) => [number, number];
255
+ readonly emulator_mem_write: (a: number, b: number, c: number, d: number) => void;
256
+ readonly emulator_new: (a: number, b: number) => [number, number, number];
257
+ readonly emulator_out: (a: number) => [number, number];
258
+ readonly emulator_pc: (a: number) => number;
259
+ readonly emulator_pit_count: (a: number, b: number) => number;
260
+ readonly emulator_port_read: (a: number, b: number) => number;
261
+ readonly emulator_port_write: (a: number, b: number, c: number) => void;
262
+ readonly emulator_push_key: (a: number, b: number) => void;
263
+ readonly emulator_regs: (a: number) => [number, number];
264
+ readonly emulator_reset: (a: number) => void;
265
+ readonly emulator_restore: (a: number, b: number, c: number) => void;
266
+ readonly emulator_rom_region: (a: number) => [number, number];
267
+ readonly emulator_run: (a: number, b: number) => number;
268
+ readonly emulator_run_bp: (a: number, b: number, c: number, d: number) => number;
269
+ readonly emulator_run_to: (a: number, b: number, c: number) => number;
270
+ readonly emulator_screen: (a: number) => [number, number];
271
+ readonly emulator_serial_rx: (a: number, b: number) => [number, number];
272
+ readonly emulator_set_clock: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => [number, number];
273
+ readonly emulator_set_ea: (a: number, b: number) => void;
274
+ readonly emulator_set_interrupt_mode: (a: number, b: number) => [number, number];
275
+ readonly emulator_set_pc: (a: number, b: number) => void;
276
+ readonly emulator_set_reg: (a: number, b: number, c: number, d: number) => void;
277
+ readonly emulator_set_rom_region: (a: number, b: number, c: number) => void;
278
+ readonly emulator_set_sfr: (a: number, b: number, c: number) => void;
279
+ readonly emulator_set_sid: (a: number, b: number) => void;
280
+ readonly emulator_set_sram: (a: number, b: number, c: number) => void;
281
+ readonly emulator_sfr: (a: number, b: number) => number;
282
+ readonly emulator_snapshot: (a: number) => [number, number];
283
+ readonly emulator_sod: (a: number) => number;
284
+ readonly emulator_sram_region: (a: number) => [number, number];
285
+ readonly emulator_step: (a: number) => void;
286
+ readonly emulator_video_mode: (a: number) => number;
287
+ readonly emulator_waiting_input: (a: number) => number;
288
+ readonly __wbindgen_externrefs: WebAssembly.Table;
289
+ readonly __wbindgen_malloc: (a: number, b: number) => number;
290
+ readonly __wbindgen_realloc: (a: number, b: number, c: number, d: number) => number;
291
+ readonly __externref_table_dealloc: (a: number) => void;
292
+ readonly __wbindgen_free: (a: number, b: number, c: number) => void;
293
+ readonly __externref_drop_slice: (a: number, b: number) => void;
294
+ readonly __wbindgen_start: () => void;
295
+ }
296
+
297
+ export type SyncInitInput = BufferSource | WebAssembly.Module;
298
+
299
+ /**
300
+ * Instantiates the given `module`, which can either be bytes or
301
+ * a precompiled `WebAssembly.Module`.
302
+ *
303
+ * @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated.
304
+ *
305
+ * @returns {InitOutput}
306
+ */
307
+ export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput;
308
+
309
+ /**
310
+ * If `module_or_path` is {RequestInfo} or {URL}, makes a request and
311
+ * for everything else, calls `WebAssembly.instantiate` directly.
312
+ *
313
+ * @param {{ module_or_path: InitInput | Promise<InitInput> }} module_or_path - Passing `InitInput` directly is deprecated.
314
+ *
315
+ * @returns {Promise<InitOutput>}
316
+ */
317
+ export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise<InitInput> } | InitInput | Promise<InitInput>): Promise<InitOutput>;
@@ -0,0 +1,855 @@
1
+ /* @ts-self-types="./multi_cpu_emu.d.ts" */
2
+
3
+ export class Emulator {
4
+ __destroy_into_raw() {
5
+ const ptr = this.__wbg_ptr;
6
+ this.__wbg_ptr = 0;
7
+ EmulatorFinalization.unregister(this);
8
+ return ptr;
9
+ }
10
+ free() {
11
+ const ptr = this.__destroy_into_raw();
12
+ wasm.__wbg_emulator_free(ptr, 0);
13
+ }
14
+ /**
15
+ * Assemble source for the current ISA; returns machine code bytes.
16
+ * @param {string} source
17
+ * @returns {Uint8Array}
18
+ */
19
+ assemble(source) {
20
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
21
+ const len0 = WASM_VECTOR_LEN;
22
+ const ret = wasm.emulator_assemble(this.__wbg_ptr, ptr0, len0);
23
+ if (ret[3]) {
24
+ throw takeFromExternrefTable0(ret[2]);
25
+ }
26
+ var v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
27
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
28
+ return v2;
29
+ }
30
+ /**
31
+ * Assemble and return per-line machine code as "ADDR BYTES" strings
32
+ * (one per source line, empty for lines that emit nothing).
33
+ * @param {string} source
34
+ * @returns {string[]}
35
+ */
36
+ assemble_info(source) {
37
+ const ptr0 = passStringToWasm0(source, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
38
+ const len0 = WASM_VECTOR_LEN;
39
+ const ret = wasm.emulator_assemble_info(this.__wbg_ptr, ptr0, len0);
40
+ if (ret[3]) {
41
+ throw takeFromExternrefTable0(ret[2]);
42
+ }
43
+ var v2 = getArrayJsValueFromWasm0(ret[0], ret[1]);
44
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
45
+ return v2;
46
+ }
47
+ /**
48
+ * 8086 text cursor as [col, row]; [0,0] otherwise.
49
+ * @returns {Uint8Array}
50
+ */
51
+ cursor() {
52
+ const ret = wasm.emulator_cursor(this.__wbg_ptr);
53
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
54
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
55
+ return v1;
56
+ }
57
+ /**
58
+ * Total clock cycles executed (machine cycles / T-states). Drives the
59
+ * cycle-accurate timers (8086 PIT, 8051 timers, 8085 8155 timer).
60
+ * @returns {bigint}
61
+ */
62
+ cycles() {
63
+ const ret = wasm.emulator_cycles(this.__wbg_ptr);
64
+ return BigInt.asUintN(64, ret);
65
+ }
66
+ /**
67
+ * Disassemble `count` instructions starting at `addr`. Each returned line
68
+ * is "ADDR BYTES text" (use `Disasm::line`). Other ISAs return [].
69
+ * @param {number} addr
70
+ * @param {number} count
71
+ * @returns {string[]}
72
+ */
73
+ disasm(addr, count) {
74
+ const ret = wasm.emulator_disasm(this.__wbg_ptr, addr, count);
75
+ var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]);
76
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
77
+ return v1;
78
+ }
79
+ /**
80
+ * 8051 EA pin state (true = internal code, false = external via XDATA).
81
+ * @returns {boolean}
82
+ */
83
+ ea_active() {
84
+ const ret = wasm.emulator_ea_active(this.__wbg_ptr);
85
+ return ret !== 0;
86
+ }
87
+ /**
88
+ * 8051 external-code (XDATA) region (base, len) when EA is low, else null.
89
+ * @returns {Uint32Array | undefined}
90
+ */
91
+ ext_code_region() {
92
+ const ret = wasm.emulator_ext_code_region(this.__wbg_ptr);
93
+ let v1;
94
+ if (ret[0] !== 0) {
95
+ v1 = getArrayU32FromWasm0(ret[0], ret[1]).slice();
96
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
97
+ }
98
+ return v1;
99
+ }
100
+ /**
101
+ * Active flag names as short strings (e.g. "ZF", "CY").
102
+ * @returns {string[]}
103
+ */
104
+ flags() {
105
+ const ret = wasm.emulator_flags(this.__wbg_ptr);
106
+ var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]);
107
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
108
+ return v1;
109
+ }
110
+ /**
111
+ * Read a file back from the 8086 DOS virtual filesystem (empty if absent).
112
+ * @param {string} name
113
+ * @returns {Uint8Array | undefined}
114
+ */
115
+ fs_get(name) {
116
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
117
+ const len0 = WASM_VECTOR_LEN;
118
+ const ret = wasm.emulator_fs_get(this.__wbg_ptr, ptr0, len0);
119
+ if (ret[3]) {
120
+ throw takeFromExternrefTable0(ret[2]);
121
+ }
122
+ let v2;
123
+ if (ret[0] !== 0) {
124
+ v2 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
125
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
126
+ }
127
+ return v2;
128
+ }
129
+ /**
130
+ * Preload a file into the 8086 DOS virtual filesystem.
131
+ * @param {string} name
132
+ * @param {Uint8Array} data
133
+ */
134
+ fs_put(name, data) {
135
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
136
+ const len0 = WASM_VECTOR_LEN;
137
+ const ptr1 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
138
+ const len1 = WASM_VECTOR_LEN;
139
+ const ret = wasm.emulator_fs_put(this.__wbg_ptr, ptr0, len0, ptr1, len1);
140
+ if (ret[1]) {
141
+ throw takeFromExternrefTable0(ret[0]);
142
+ }
143
+ }
144
+ /**
145
+ * 8086 graphics framebuffer, or None when in a text mode / non-8086 ISA.
146
+ * @returns {GfxInfo | undefined}
147
+ */
148
+ gfx() {
149
+ const ret = wasm.emulator_gfx(this.__wbg_ptr);
150
+ return ret === 0 ? undefined : GfxInfo.__wrap(ret);
151
+ }
152
+ /**
153
+ * True once the CPU has executed HLT (or otherwise stopped).
154
+ * @returns {boolean}
155
+ */
156
+ halted() {
157
+ const ret = wasm.emulator_halted(this.__wbg_ptr);
158
+ return ret !== 0;
159
+ }
160
+ /**
161
+ * Hardware interrupt: 8085 = "TRAP" | "RST75" | "RST65" | "RST55" |
162
+ * "INTR" (data = vector); 8051 = "INT0" | "INT1". Throws on unknown kind.
163
+ * @param {string} kind
164
+ * @param {number} data
165
+ */
166
+ interrupt(kind, data) {
167
+ const ptr0 = passStringToWasm0(kind, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
168
+ const len0 = WASM_VECTOR_LEN;
169
+ const ret = wasm.emulator_interrupt(this.__wbg_ptr, ptr0, len0, data);
170
+ if (ret[1]) {
171
+ throw takeFromExternrefTable0(ret[0]);
172
+ }
173
+ }
174
+ /**
175
+ * Load raw machine code at `origin` and set PC there.
176
+ * @param {Uint8Array} code
177
+ * @param {number} origin
178
+ */
179
+ load(code, origin) {
180
+ const ptr0 = passArray8ToWasm0(code, wasm.__wbindgen_malloc);
181
+ const len0 = WASM_VECTOR_LEN;
182
+ wasm.emulator_load(this.__wbg_ptr, ptr0, len0, origin);
183
+ }
184
+ /**
185
+ * Load a ROM image and mark its range read-only. 8051 routes to external
186
+ * code (XDATA) when EA is low.
187
+ * @param {Uint8Array} data
188
+ * @param {number} addr
189
+ */
190
+ load_rom(data, addr) {
191
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
192
+ const len0 = WASM_VECTOR_LEN;
193
+ wasm.emulator_load_rom(this.__wbg_ptr, ptr0, len0, addr);
194
+ }
195
+ /**
196
+ * Linear memory read of `len` bytes starting at `addr`.
197
+ * @param {number} addr
198
+ * @param {number} len
199
+ * @returns {Uint8Array}
200
+ */
201
+ mem(addr, len) {
202
+ const ret = wasm.emulator_mem(this.__wbg_ptr, addr, len);
203
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
204
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
205
+ return v1;
206
+ }
207
+ /**
208
+ * Write bytes into memory (IDE memory poking).
209
+ * @param {number} addr
210
+ * @param {Uint8Array} data
211
+ */
212
+ mem_write(addr, data) {
213
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
214
+ const len0 = WASM_VECTOR_LEN;
215
+ wasm.emulator_mem_write(this.__wbg_ptr, addr, ptr0, len0);
216
+ }
217
+ /**
218
+ * Create an emulator for one of: "8086", "8085", "8051", "6502", "Z80", "rv32".
219
+ * Throws if the ISA name is unknown.
220
+ * @param {string} isa
221
+ */
222
+ constructor(isa) {
223
+ const ptr0 = passStringToWasm0(isa, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
224
+ const len0 = WASM_VECTOR_LEN;
225
+ const ret = wasm.emulator_new(ptr0, len0);
226
+ if (ret[2]) {
227
+ throw takeFromExternrefTable0(ret[1]);
228
+ }
229
+ this.__wbg_ptr = ret[0];
230
+ EmulatorFinalization.register(this, this.__wbg_ptr, this);
231
+ return this;
232
+ }
233
+ /**
234
+ * Drain the program output buffer.
235
+ * @returns {string}
236
+ */
237
+ out() {
238
+ let deferred1_0;
239
+ let deferred1_1;
240
+ try {
241
+ const ret = wasm.emulator_out(this.__wbg_ptr);
242
+ deferred1_0 = ret[0];
243
+ deferred1_1 = ret[1];
244
+ return getStringFromWasm0(ret[0], ret[1]);
245
+ } finally {
246
+ wasm.__wbindgen_free(deferred1_0, deferred1_1, 1);
247
+ }
248
+ }
249
+ /**
250
+ * Current program counter (instruction pointer).
251
+ * @returns {number}
252
+ */
253
+ pc() {
254
+ const ret = wasm.emulator_pc(this.__wbg_ptr);
255
+ return ret >>> 0;
256
+ }
257
+ /**
258
+ * Current reload/count of an 8086 PIT channel (0..2). Other ISAs: 0.
259
+ * @param {number} n
260
+ * @returns {number}
261
+ */
262
+ pit_count(n) {
263
+ const ret = wasm.emulator_pit_count(this.__wbg_ptr, n);
264
+ return ret;
265
+ }
266
+ /**
267
+ * Queue a key for the 8086's INT 21h keyboard reads (AH=01/06/07/08/0C).
268
+ * @param {number} port
269
+ * @returns {number}
270
+ */
271
+ port_read(port) {
272
+ const ret = wasm.emulator_port_read(this.__wbg_ptr, port);
273
+ return ret;
274
+ }
275
+ /**
276
+ * Write an I/O port byte (8085/8086: port space 0-255; 8051: P0-P3 pins).
277
+ * @param {number} port
278
+ * @param {number} val
279
+ */
280
+ port_write(port, val) {
281
+ wasm.emulator_port_write(this.__wbg_ptr, port, val);
282
+ }
283
+ /**
284
+ * Queue a type-ahead character for INT 21h/keyboard reads (8086).
285
+ * @param {number} ch
286
+ */
287
+ push_key(ch) {
288
+ wasm.emulator_push_key(this.__wbg_ptr, ch);
289
+ }
290
+ /**
291
+ * Register dump as "NAME=value" strings (e.g. "AX=1234").
292
+ * @returns {string[]}
293
+ */
294
+ regs() {
295
+ const ret = wasm.emulator_regs(this.__wbg_ptr);
296
+ var v1 = getArrayJsValueFromWasm0(ret[0], ret[1]);
297
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
298
+ return v1;
299
+ }
300
+ /**
301
+ * Reset the CPU to its initial state (registers, flags, PC, memory preserved).
302
+ */
303
+ reset() {
304
+ wasm.emulator_reset(this.__wbg_ptr);
305
+ }
306
+ /**
307
+ * Restore a previously captured `snapshot()` (state must match the ISA).
308
+ * @param {Uint8Array} data
309
+ */
310
+ restore(data) {
311
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
312
+ const len0 = WASM_VECTOR_LEN;
313
+ wasm.emulator_restore(this.__wbg_ptr, ptr0, len0);
314
+ }
315
+ /**
316
+ * Write-protected ROM region (base, len) if configured, else null.
317
+ * @returns {Uint32Array | undefined}
318
+ */
319
+ rom_region() {
320
+ const ret = wasm.emulator_rom_region(this.__wbg_ptr);
321
+ let v1;
322
+ if (ret[0] !== 0) {
323
+ v1 = getArrayU32FromWasm0(ret[0], ret[1]).slice();
324
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
325
+ }
326
+ return v1;
327
+ }
328
+ /**
329
+ * Run up to `max_steps` instructions; returns steps executed.
330
+ * @param {number} max_steps
331
+ * @returns {number}
332
+ */
333
+ run(max_steps) {
334
+ const ret = wasm.emulator_run(this.__wbg_ptr, max_steps);
335
+ return ret >>> 0;
336
+ }
337
+ /**
338
+ * Run until PC lands on one of `bps` (that instruction is NOT executed),
339
+ * or halt / blocked on input / max steps. Returns steps executed.
340
+ * @param {number} max_steps
341
+ * @param {Uint32Array} bps
342
+ * @returns {number}
343
+ */
344
+ run_bp(max_steps, bps) {
345
+ const ptr0 = passArray32ToWasm0(bps, wasm.__wbindgen_malloc);
346
+ const len0 = WASM_VECTOR_LEN;
347
+ const ret = wasm.emulator_run_bp(this.__wbg_ptr, max_steps, ptr0, len0);
348
+ return ret >>> 0;
349
+ }
350
+ /**
351
+ * Run until `target` is the next instruction to execute (not executed),
352
+ * or halt / blocked on input / max steps. Returns steps executed.
353
+ * @param {number} target_pc
354
+ * @param {number} max_steps
355
+ * @returns {number}
356
+ */
357
+ run_to(target_pc, max_steps) {
358
+ const ret = wasm.emulator_run_to(this.__wbg_ptr, target_pc, max_steps);
359
+ return ret >>> 0;
360
+ }
361
+ /**
362
+ * 8086 text-mode framebuffer (80x25 char/attr pairs at 0xB8000); [] otherwise.
363
+ * @returns {Uint8Array}
364
+ */
365
+ screen() {
366
+ const ret = wasm.emulator_screen(this.__wbg_ptr);
367
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
368
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
369
+ return v1;
370
+ }
371
+ /**
372
+ * Inject a received serial byte into the 8051 (sets SBUF + RI).
373
+ * @param {number} ch
374
+ */
375
+ serial_rx(ch) {
376
+ const ret = wasm.emulator_serial_rx(this.__wbg_ptr, ch);
377
+ if (ret[1]) {
378
+ throw takeFromExternrefTable0(ret[0]);
379
+ }
380
+ }
381
+ /**
382
+ * Set the emulated DOS/BIOS date-time clock (INT 21h 2Ah/2Ch, INT 1Ah).
383
+ * @param {number} year
384
+ * @param {number} month
385
+ * @param {number} day
386
+ * @param {number} hour
387
+ * @param {number} min
388
+ * @param {number} sec
389
+ */
390
+ set_clock(year, month, day, hour, min, sec) {
391
+ const ret = wasm.emulator_set_clock(this.__wbg_ptr, year, month, day, hour, min, sec);
392
+ if (ret[1]) {
393
+ throw takeFromExternrefTable0(ret[0]);
394
+ }
395
+ }
396
+ /**
397
+ * 8051 EA pin: false => fetch code from external program memory (XDATA).
398
+ * @param {boolean} ea
399
+ */
400
+ set_ea(ea) {
401
+ wasm.emulator_set_ea(this.__wbg_ptr, ea);
402
+ }
403
+ /**
404
+ * Set the Z80 interrupt mode (0/1 -> 0x0038, 2 -> I*0x100 + data).
405
+ * @param {number} m
406
+ */
407
+ set_interrupt_mode(m) {
408
+ const ret = wasm.emulator_set_interrupt_mode(this.__wbg_ptr, m);
409
+ if (ret[1]) {
410
+ throw takeFromExternrefTable0(ret[0]);
411
+ }
412
+ }
413
+ /**
414
+ * Set the program counter (entry point after load).
415
+ * @param {number} addr
416
+ */
417
+ set_pc(addr) {
418
+ wasm.emulator_set_pc(this.__wbg_ptr, addr);
419
+ }
420
+ /**
421
+ * Set a register by name (e.g. "AX", "PC", "R0"). Used by the IDE watch
422
+ * window for click-to-edit. Ignored for names the ISA does not expose.
423
+ * @param {string} name
424
+ * @param {number} val
425
+ */
426
+ set_reg(name, val) {
427
+ const ptr0 = passStringToWasm0(name, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
428
+ const len0 = WASM_VECTOR_LEN;
429
+ wasm.emulator_set_reg(this.__wbg_ptr, ptr0, len0, val);
430
+ }
431
+ /**
432
+ * Mark `[base, base+len)` of main memory as read-only ROM (8086/8085).
433
+ * @param {number} base
434
+ * @param {number} len
435
+ */
436
+ set_rom_region(base, len) {
437
+ wasm.emulator_set_rom_region(this.__wbg_ptr, base, len);
438
+ }
439
+ /**
440
+ * Write an 8051 SFR / IRAM byte (peripheral-register editor).
441
+ * @param {number} addr
442
+ * @param {number} v
443
+ */
444
+ set_sfr(addr, v) {
445
+ wasm.emulator_set_sfr(this.__wbg_ptr, addr, v);
446
+ }
447
+ /**
448
+ * Set the 8085 SID (Serial Input Data) pin read by RIM (bit 7). 8085 only.
449
+ * @param {boolean} v
450
+ */
451
+ set_sid(v) {
452
+ wasm.emulator_set_sid(this.__wbg_ptr, v);
453
+ }
454
+ /**
455
+ * 8085: (re)configure the external SRAM chip window (default 8 KiB @ 0x9000).
456
+ * @param {number} base
457
+ * @param {number} len
458
+ */
459
+ set_sram(base, len) {
460
+ wasm.emulator_set_sram(this.__wbg_ptr, base, len);
461
+ }
462
+ /**
463
+ * Read an 8051 SFR / IRAM byte (peripheral-register readout).
464
+ * @param {number} addr
465
+ * @returns {number}
466
+ */
467
+ sfr(addr) {
468
+ const ret = wasm.emulator_sfr(this.__wbg_ptr, addr);
469
+ return ret;
470
+ }
471
+ /**
472
+ * Deterministic serialization of full CPU state (for save/restore and step-back).
473
+ * @returns {Uint8Array}
474
+ */
475
+ snapshot() {
476
+ const ret = wasm.emulator_snapshot(this.__wbg_ptr);
477
+ var v1 = getArrayU8FromWasm0(ret[0], ret[1]).slice();
478
+ wasm.__wbindgen_free(ret[0], ret[1] * 1, 1);
479
+ return v1;
480
+ }
481
+ /**
482
+ * Read the 8085 SOD (Serial Output Data) pin set by SIM (bit 7). 8085 only.
483
+ * @returns {number}
484
+ */
485
+ sod() {
486
+ const ret = wasm.emulator_sod(this.__wbg_ptr);
487
+ return ret;
488
+ }
489
+ /**
490
+ * External SRAM window (base, len) if configured (8055), else null.
491
+ * @returns {Uint32Array | undefined}
492
+ */
493
+ sram_region() {
494
+ const ret = wasm.emulator_sram_region(this.__wbg_ptr);
495
+ let v1;
496
+ if (ret[0] !== 0) {
497
+ v1 = getArrayU32FromWasm0(ret[0], ret[1]).slice();
498
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
499
+ }
500
+ return v1;
501
+ }
502
+ /**
503
+ * Execute one instruction.
504
+ */
505
+ step() {
506
+ wasm.emulator_step(this.__wbg_ptr);
507
+ }
508
+ /**
509
+ * Current 8086 video mode (0 when not 8086 / unknown). MR=13h -> pixel graphics.
510
+ * @returns {number}
511
+ */
512
+ video_mode() {
513
+ const ret = wasm.emulator_video_mode(this.__wbg_ptr);
514
+ return ret;
515
+ }
516
+ /**
517
+ * True while the 8086 is blocked on an INT 21h read with an empty buffer.
518
+ * @returns {boolean}
519
+ */
520
+ waiting_input() {
521
+ const ret = wasm.emulator_waiting_input(this.__wbg_ptr);
522
+ return ret !== 0;
523
+ }
524
+ }
525
+ if (Symbol.dispose) Emulator.prototype[Symbol.dispose] = Emulator.prototype.free;
526
+
527
+ /**
528
+ * Graphics framebuffer descriptor (8086 pixel modes). `base` is the linear
529
+ * memory address of the pixel data; `w`/`h` are the dimensions in pixels.
530
+ */
531
+ export class GfxInfo {
532
+ static __wrap(ptr) {
533
+ const obj = Object.create(GfxInfo.prototype);
534
+ obj.__wbg_ptr = ptr;
535
+ GfxInfoFinalization.register(obj, obj.__wbg_ptr, obj);
536
+ return obj;
537
+ }
538
+ __destroy_into_raw() {
539
+ const ptr = this.__wbg_ptr;
540
+ this.__wbg_ptr = 0;
541
+ GfxInfoFinalization.unregister(this);
542
+ return ptr;
543
+ }
544
+ free() {
545
+ const ptr = this.__destroy_into_raw();
546
+ wasm.__wbg_gfxinfo_free(ptr, 0);
547
+ }
548
+ /**
549
+ * @returns {number}
550
+ */
551
+ get base() {
552
+ const ret = wasm.__wbg_get_gfxinfo_base(this.__wbg_ptr);
553
+ return ret >>> 0;
554
+ }
555
+ /**
556
+ * @returns {number}
557
+ */
558
+ get h() {
559
+ const ret = wasm.__wbg_get_gfxinfo_h(this.__wbg_ptr);
560
+ return ret >>> 0;
561
+ }
562
+ /**
563
+ * @returns {number}
564
+ */
565
+ get w() {
566
+ const ret = wasm.__wbg_get_gfxinfo_w(this.__wbg_ptr);
567
+ return ret >>> 0;
568
+ }
569
+ /**
570
+ * @param {number} arg0
571
+ */
572
+ set base(arg0) {
573
+ wasm.__wbg_set_gfxinfo_base(this.__wbg_ptr, arg0);
574
+ }
575
+ /**
576
+ * @param {number} arg0
577
+ */
578
+ set h(arg0) {
579
+ wasm.__wbg_set_gfxinfo_h(this.__wbg_ptr, arg0);
580
+ }
581
+ /**
582
+ * @param {number} arg0
583
+ */
584
+ set w(arg0) {
585
+ wasm.__wbg_set_gfxinfo_w(this.__wbg_ptr, arg0);
586
+ }
587
+ }
588
+ if (Symbol.dispose) GfxInfo.prototype[Symbol.dispose] = GfxInfo.prototype.free;
589
+ function __wbg_get_imports() {
590
+ const import0 = {
591
+ __proto__: null,
592
+ __wbg___wbindgen_throw_bb96b2010945f0bc: function(arg0, arg1) {
593
+ throw new Error(getStringFromWasm0(arg0, arg1));
594
+ },
595
+ __wbindgen_cast_0000000000000001: function(arg0, arg1) {
596
+ // Cast intrinsic for `Ref(String) -> Externref`.
597
+ const ret = getStringFromWasm0(arg0, arg1);
598
+ return ret;
599
+ },
600
+ __wbindgen_init_externref_table: function() {
601
+ const table = wasm.__wbindgen_externrefs;
602
+ const offset = table.grow(4);
603
+ table.set(0, undefined);
604
+ table.set(offset + 0, undefined);
605
+ table.set(offset + 1, null);
606
+ table.set(offset + 2, true);
607
+ table.set(offset + 3, false);
608
+ },
609
+ };
610
+ return {
611
+ __proto__: null,
612
+ "./multi_cpu_emu_bg.js": import0,
613
+ };
614
+ }
615
+
616
+ const EmulatorFinalization = (typeof FinalizationRegistry === 'undefined')
617
+ ? { register: () => {}, unregister: () => {} }
618
+ : new FinalizationRegistry(ptr => wasm.__wbg_emulator_free(ptr, 1));
619
+ const GfxInfoFinalization = (typeof FinalizationRegistry === 'undefined')
620
+ ? { register: () => {}, unregister: () => {} }
621
+ : new FinalizationRegistry(ptr => wasm.__wbg_gfxinfo_free(ptr, 1));
622
+
623
+ function getArrayJsValueFromWasm0(ptr, len) {
624
+ ptr = ptr >>> 0;
625
+ const mem = getDataViewMemory0();
626
+ const result = [];
627
+ for (let i = ptr; i < ptr + 4 * len; i += 4) {
628
+ result.push(wasm.__wbindgen_externrefs.get(mem.getUint32(i, true)));
629
+ }
630
+ wasm.__externref_drop_slice(ptr, len);
631
+ return result;
632
+ }
633
+
634
+ function getArrayU32FromWasm0(ptr, len) {
635
+ ptr = ptr >>> 0;
636
+ return getUint32ArrayMemory0().subarray(ptr / 4, ptr / 4 + len);
637
+ }
638
+
639
+ function getArrayU8FromWasm0(ptr, len) {
640
+ ptr = ptr >>> 0;
641
+ return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);
642
+ }
643
+
644
+ let cachedDataViewMemory0 = null;
645
+ function getDataViewMemory0() {
646
+ if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {
647
+ cachedDataViewMemory0 = new DataView(wasm.memory.buffer);
648
+ }
649
+ return cachedDataViewMemory0;
650
+ }
651
+
652
+ function getStringFromWasm0(ptr, len) {
653
+ return decodeText(ptr >>> 0, len);
654
+ }
655
+
656
+ let cachedUint32ArrayMemory0 = null;
657
+ function getUint32ArrayMemory0() {
658
+ if (cachedUint32ArrayMemory0 === null || cachedUint32ArrayMemory0.byteLength === 0) {
659
+ cachedUint32ArrayMemory0 = new Uint32Array(wasm.memory.buffer);
660
+ }
661
+ return cachedUint32ArrayMemory0;
662
+ }
663
+
664
+ let cachedUint8ArrayMemory0 = null;
665
+ function getUint8ArrayMemory0() {
666
+ if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {
667
+ cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);
668
+ }
669
+ return cachedUint8ArrayMemory0;
670
+ }
671
+
672
+ function passArray32ToWasm0(arg, malloc) {
673
+ const ptr = malloc(arg.length * 4, 4) >>> 0;
674
+ getUint32ArrayMemory0().set(arg, ptr / 4);
675
+ WASM_VECTOR_LEN = arg.length;
676
+ return ptr;
677
+ }
678
+
679
+ function passArray8ToWasm0(arg, malloc) {
680
+ const ptr = malloc(arg.length * 1, 1) >>> 0;
681
+ getUint8ArrayMemory0().set(arg, ptr / 1);
682
+ WASM_VECTOR_LEN = arg.length;
683
+ return ptr;
684
+ }
685
+
686
+ function passStringToWasm0(arg, malloc, realloc) {
687
+ if (realloc === undefined) {
688
+ const buf = cachedTextEncoder.encode(arg);
689
+ const ptr = malloc(buf.length, 1) >>> 0;
690
+ getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);
691
+ WASM_VECTOR_LEN = buf.length;
692
+ return ptr;
693
+ }
694
+
695
+ let len = arg.length;
696
+ let ptr = malloc(len, 1) >>> 0;
697
+
698
+ const mem = getUint8ArrayMemory0();
699
+
700
+ let offset = 0;
701
+
702
+ for (; offset < len; offset++) {
703
+ const code = arg.charCodeAt(offset);
704
+ if (code > 0x7F) break;
705
+ mem[ptr + offset] = code;
706
+ }
707
+ if (offset !== len) {
708
+ if (offset !== 0) {
709
+ arg = arg.slice(offset);
710
+ }
711
+ ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;
712
+ const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);
713
+ const ret = cachedTextEncoder.encodeInto(arg, view);
714
+
715
+ offset += ret.written;
716
+ ptr = realloc(ptr, len, offset, 1) >>> 0;
717
+ }
718
+
719
+ WASM_VECTOR_LEN = offset;
720
+ return ptr;
721
+ }
722
+
723
+ function takeFromExternrefTable0(idx) {
724
+ const value = wasm.__wbindgen_externrefs.get(idx);
725
+ wasm.__externref_table_dealloc(idx);
726
+ return value;
727
+ }
728
+
729
+ let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
730
+ cachedTextDecoder.decode();
731
+ const MAX_SAFARI_DECODE_BYTES = 2146435072;
732
+ let numBytesDecoded = 0;
733
+ function decodeText(ptr, len) {
734
+ numBytesDecoded += len;
735
+ if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {
736
+ cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
737
+ cachedTextDecoder.decode();
738
+ numBytesDecoded = len;
739
+ }
740
+ return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));
741
+ }
742
+
743
+ const cachedTextEncoder = new TextEncoder();
744
+
745
+ if (!('encodeInto' in cachedTextEncoder)) {
746
+ cachedTextEncoder.encodeInto = function (arg, view) {
747
+ const buf = cachedTextEncoder.encode(arg);
748
+ view.set(buf);
749
+ return {
750
+ read: arg.length,
751
+ written: buf.length
752
+ };
753
+ };
754
+ }
755
+
756
+ let WASM_VECTOR_LEN = 0;
757
+
758
+ let wasmModule, wasmInstance, wasm;
759
+ function __wbg_finalize_init(instance, module) {
760
+ wasmInstance = instance;
761
+ wasm = instance.exports;
762
+ wasmModule = module;
763
+ cachedDataViewMemory0 = null;
764
+ cachedUint32ArrayMemory0 = null;
765
+ cachedUint8ArrayMemory0 = null;
766
+ wasm.__wbindgen_start();
767
+ return wasm;
768
+ }
769
+
770
+ async function __wbg_load(module, imports) {
771
+ if (typeof Response === 'function' && module instanceof Response) {
772
+ if (!module.ok) {
773
+ throw new Error(`failed to fetch Wasm: ${module.status} ${module.statusText} fetching '${module.url}'`);
774
+ }
775
+
776
+ if (typeof WebAssembly.instantiateStreaming === 'function') {
777
+ try {
778
+ return await WebAssembly.instantiateStreaming(module, imports);
779
+ } catch (e) {
780
+ const validResponse = expectedResponseType(module.type);
781
+
782
+ if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {
783
+ console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
784
+
785
+ } else { throw e; }
786
+ }
787
+ }
788
+
789
+ const bytes = await module.arrayBuffer();
790
+ return await WebAssembly.instantiate(bytes, imports);
791
+ } else {
792
+ const instance = await WebAssembly.instantiate(module, imports);
793
+
794
+ if (instance instanceof WebAssembly.Instance) {
795
+ return { instance, module };
796
+ } else {
797
+ return instance;
798
+ }
799
+ }
800
+
801
+ function expectedResponseType(type) {
802
+ switch (type) {
803
+ case 'basic': case 'cors': case 'default': return true;
804
+ }
805
+ return false;
806
+ }
807
+ }
808
+
809
+ function initSync(module) {
810
+ if (wasm !== undefined) return wasm;
811
+
812
+
813
+ if (module !== undefined) {
814
+ if (Object.getPrototypeOf(module) === Object.prototype) {
815
+ ({module} = module)
816
+ } else {
817
+ console.warn('using deprecated parameters for `initSync()`; pass a single object instead')
818
+ }
819
+ }
820
+
821
+ const imports = __wbg_get_imports();
822
+ if (!(module instanceof WebAssembly.Module)) {
823
+ module = new WebAssembly.Module(module);
824
+ }
825
+ const instance = new WebAssembly.Instance(module, imports);
826
+ return __wbg_finalize_init(instance, module);
827
+ }
828
+
829
+ async function __wbg_init(module_or_path) {
830
+ if (wasm !== undefined) return wasm;
831
+
832
+
833
+ if (module_or_path !== undefined) {
834
+ if (Object.getPrototypeOf(module_or_path) === Object.prototype) {
835
+ ({module_or_path} = module_or_path)
836
+ } else {
837
+ console.warn('using deprecated parameters for the initialization function; pass a single object instead')
838
+ }
839
+ }
840
+
841
+ if (module_or_path === undefined) {
842
+ module_or_path = new URL('multi_cpu_emu_bg.wasm', import.meta.url);
843
+ }
844
+ const imports = __wbg_get_imports();
845
+
846
+ if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {
847
+ module_or_path = fetch(module_or_path);
848
+ }
849
+
850
+ const { instance, module } = await __wbg_load(await module_or_path, imports);
851
+
852
+ return __wbg_finalize_init(instance, module);
853
+ }
854
+
855
+ export { initSync, __wbg_init as default };
Binary file
package/package.json ADDED
@@ -0,0 +1,24 @@
1
+ {
2
+ "name": "8086emu",
3
+ "type": "module",
4
+ "collaborators": [
5
+ "Danish"
6
+ ],
7
+ "description": "8086 / 8085 / 8051 / 6502 / Z80 / RISC-V emulator cores in one Rust crate, compiles to WASM",
8
+ "version": "0.1.0",
9
+ "license": "MIT",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/danish9661/8086emu"
13
+ },
14
+ "files": [
15
+ "multi_cpu_emu_bg.wasm",
16
+ "multi_cpu_emu.js",
17
+ "multi_cpu_emu.d.ts"
18
+ ],
19
+ "main": "multi_cpu_emu.js",
20
+ "types": "multi_cpu_emu.d.ts",
21
+ "sideEffects": [
22
+ "./snippets/*"
23
+ ]
24
+ }