@dcorp80/z80cpu 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 +202 -0
- package/NOTICE +2 -0
- package/README.md +317 -0
- package/dist/index.d.ts +280 -0
- package/dist/index.js +1 -0
- package/package.json +43 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
package/NOTICE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
# @dcorp80/z80cpu
|
|
2
|
+
|
|
3
|
+
### For the 50th anniversary of the Z80 CPU
|
|
4
|
+
|
|
5
|
+
A hardware-accurate half-cycle Z80 emulator for JavaScript and TypeScript.
|
|
6
|
+
Models the original NMOS Z80 (Zilog Z8400 family).
|
|
7
|
+
|
|
8
|
+
## What this library is
|
|
9
|
+
|
|
10
|
+
`@dcorp80/z80cpu` is a low-level, hardware-oriented Z80 core for:
|
|
11
|
+
- emulators
|
|
12
|
+
- debuggers
|
|
13
|
+
- reverse-engineering tools
|
|
14
|
+
- timing-sensitive simulation
|
|
15
|
+
|
|
16
|
+
It models half-cycle edges, bus-level behavior, interrupts, WAIT/BUSREQ timing,
|
|
17
|
+
and undocumented behavior while exposing enough state for external tooling.
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- Half-cycle timing accuracy — every rising and falling edge is a distinct simulation step.
|
|
22
|
+
- Full instruction set, including undocumented opcodes.
|
|
23
|
+
- Documented **and** undocumented flag behavior.
|
|
24
|
+
- Hardware-accurate RESET, interrupt, WAIT, and BUSREQ processing.
|
|
25
|
+
- Models the Special Reset feature plus all NMOS-Z80 RESET quirks beyond
|
|
26
|
+
the datasheet — see [RESET behavior](#reset-behavior).
|
|
27
|
+
- Fast: ~20 MHz effective Z80 throughput in Node.js on Apple M1.
|
|
28
|
+
- JIT-friendly — no allocations on the hot path.
|
|
29
|
+
- Pure ESM — works in Node and the browser, no CommonJS build.
|
|
30
|
+
- TypeScript types included.
|
|
31
|
+
- Introspectable — exposes internal state, upcoming sequencer step, and
|
|
32
|
+
architectural snapshots for debugger tooling.
|
|
33
|
+
|
|
34
|
+
## Validation
|
|
35
|
+
|
|
36
|
+
- 7000+ tests, with behavior validated against the Visual6502 Z80 netlist.
|
|
37
|
+
- Extensive coverage of undocumented and timing-sensitive behavior.
|
|
38
|
+
|
|
39
|
+
"Hardware-accurate" here refers to **externally observable** behavior:
|
|
40
|
+
bus pins, instruction effects, M-cycle and T-state timing visible to the
|
|
41
|
+
host. Internal state organization — the step pipeline, the bank-swap
|
|
42
|
+
encoding, sub-edge sequencing details — is the emulator's own design
|
|
43
|
+
and may differ from the real chip internals, even where external
|
|
44
|
+
behavior matches at every edge.
|
|
45
|
+
|
|
46
|
+
## Install
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
npm install @dcorp80/z80cpu
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { Z80Cpu } from "@dcorp80/z80cpu";
|
|
56
|
+
|
|
57
|
+
const cpu = new Z80Cpu();
|
|
58
|
+
const mem = new Uint8Array(0x10000);
|
|
59
|
+
mem[0] = 0x3E; mem[1] = 0x42; // LD A,42h
|
|
60
|
+
|
|
61
|
+
const resolve = () => {
|
|
62
|
+
const { nMREQ, nRD, nWR, addr, data } = cpu.bus;
|
|
63
|
+
if (nMREQ === 0) {
|
|
64
|
+
if (nRD === 0) cpu.bus.data = mem[addr];
|
|
65
|
+
if (nWR === 0) mem[addr] = data;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
for (let i = 0; i < 16; i++) {
|
|
70
|
+
resolve();
|
|
71
|
+
cpu.clockEdge();
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Each `clockEdge()` advances the CPU by one half-cycle (rising or falling). Run
|
|
76
|
+
your bus resolver *before* each edge: read the CPU's outputs, and on a read
|
|
77
|
+
cycle set `cpu.bus.data` to the value the CPU should sample.
|
|
78
|
+
|
|
79
|
+
## Introspection
|
|
80
|
+
|
|
81
|
+
The CPU exposes enough of itself for external observers (debuggers,
|
|
82
|
+
visualizers, tracers) to be built without reaching into the simulator's
|
|
83
|
+
implementation details.
|
|
84
|
+
|
|
85
|
+
### Architectural snapshot
|
|
86
|
+
|
|
87
|
+
```ts
|
|
88
|
+
import { Z80Cpu, type CpuState } from "@dcorp80/z80cpu";
|
|
89
|
+
|
|
90
|
+
const cpu = new Z80Cpu();
|
|
91
|
+
// …run for a while…
|
|
92
|
+
|
|
93
|
+
const s = cpu.snapshot(); // fresh CpuState each call
|
|
94
|
+
console.log(s.pc, s.main.a, s.alt.b, s.im, s.iff1);
|
|
95
|
+
|
|
96
|
+
// In tight loops, allocate once and reuse:
|
|
97
|
+
const buf: CpuState = cpu.snapshot();
|
|
98
|
+
for (let i = 0; i < N; i++) {
|
|
99
|
+
cpu.clockEdge();
|
|
100
|
+
cpu.snapshot(buf); // writes into buf, no allocation
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`CpuState` decodes the bank-swap encoding (`exAf`, `exx`, `exDe`) into
|
|
105
|
+
named `main` / `alt` register banks, flattens the IM flip-flops to `0|1|2`
|
|
106
|
+
and IFFs to booleans.
|
|
107
|
+
Numeric fields are plain JS numbers. Values are explicitly constrained
|
|
108
|
+
at CPU writeback sites, so out-of-range values indicate a bug rather than
|
|
109
|
+
runtime state. See **Plain arrays** below.
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
interface RegBank {
|
|
113
|
+
b: number; c: number; d: number; e: number;
|
|
114
|
+
h: number; l: number; a: number; f: number;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface CpuState {
|
|
118
|
+
pc: number;
|
|
119
|
+
sp: number;
|
|
120
|
+
ix: number;
|
|
121
|
+
iy: number;
|
|
122
|
+
i: number;
|
|
123
|
+
r: number;
|
|
124
|
+
wz: number; // internal "MEMPTR"
|
|
125
|
+
|
|
126
|
+
main: RegBank; // currently-visible bank
|
|
127
|
+
alt: RegBank; // what EXX / EX AF,AF' would expose
|
|
128
|
+
|
|
129
|
+
im: 0 | 1 | 2;
|
|
130
|
+
/**
|
|
131
|
+
* `true` when the IM flip-flops are in the undocumented
|
|
132
|
+
* `imFa=0, imFb=1` state — behaves as IM 0, `im` still reads `0`;
|
|
133
|
+
* this flag is the only way to tell the two IM-0 states apart.
|
|
134
|
+
*/
|
|
135
|
+
imUndocumented: boolean;
|
|
136
|
+
|
|
137
|
+
iff1: boolean;
|
|
138
|
+
iff2: boolean; // restored to IFF1 by RETN; exposed via P/V on LD A,I/R
|
|
139
|
+
nmiPending: boolean;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Use `decodeFlags(f)` to unpack an `F` byte into named bits when you
|
|
144
|
+
need the individual sign / zero / half-carry / etc. flags.
|
|
145
|
+
|
|
146
|
+
`halted` is intentionally omitted from `CpuState` — the HALT state is
|
|
147
|
+
surfaced through `cpu.ctl.haltLatch` (see the *Hardware-level state flags*
|
|
148
|
+
table below) and the `cpu.bus.nHALT` pin.
|
|
149
|
+
|
|
150
|
+
### Upcoming step
|
|
151
|
+
|
|
152
|
+
```ts
|
|
153
|
+
import { StepId } from "@dcorp80/z80cpu";
|
|
154
|
+
|
|
155
|
+
if (cpu.nextStep === StepId.M1_T1_0) {
|
|
156
|
+
// about to start new instruction — a clean boundary for breakpoints, etc.
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
`cpu.nextStep` returns the `StepId` of the step the sequencer will execute on
|
|
161
|
+
the next `clockEdge()`. Stable enum — the only public API for observing the
|
|
162
|
+
upcoming sequencer step. The sequencer's internal `cpu.next` function pointer stays
|
|
163
|
+
out of the public surface.
|
|
164
|
+
|
|
165
|
+
### Raw state
|
|
166
|
+
|
|
167
|
+
`cpu.regs`, `cpu.bus`, `cpu.seq`, and `cpu.ctl` are all public objects.
|
|
168
|
+
You can read any of them at any half-cycle edge.
|
|
169
|
+
|
|
170
|
+
The register file `cpu.regs.file: number[]` is a **hardware-like flat
|
|
171
|
+
view** — hardware slot positions rather than architectural register names.
|
|
172
|
+
The bank-swap state lives elsewhere:
|
|
173
|
+
|
|
174
|
+
- `cpu.seq.prefix` — bits `0` / `1` / `2` are the `exAf` / `exx` / `exDe`
|
|
175
|
+
flip-flops; bits `3` / `4` flag the IX / IY substitution active for the
|
|
176
|
+
current DD / FD prefix.
|
|
177
|
+
- `cpu.seq.exDe0` and `cpu.seq.exDe1` — the per-bank DE↔HL swap flip-flops
|
|
178
|
+
(multiplexed onto bit 2 of `prefix` by `exx`).
|
|
179
|
+
|
|
180
|
+
For most consumers, `cpu.snapshot()` is the right answer — it decodes
|
|
181
|
+
all of that into named `main` / `alt` register banks. Going through
|
|
182
|
+
`regs.file` directly is for code that needs to track or reproduce the
|
|
183
|
+
bank-routing logic itself (e.g. a netlist comparator).
|
|
184
|
+
|
|
185
|
+
### Hardware-level state flags
|
|
186
|
+
|
|
187
|
+
A few internal flip-flops are useful for instrumentation:
|
|
188
|
+
|
|
189
|
+
| Field | Meaning |
|
|
190
|
+
|--------------------------------|----------------------------------------------------------------------------------------------------------------------------|
|
|
191
|
+
| `cpu.seq.lastOpTState` | `true` during the last T-state of the current instruction — a convenient point to log state or single-step execution. |
|
|
192
|
+
| `cpu.seq.phase` | Clock phase, matches CLK: `true` after a rising edge (CLK high), `false` after a falling edge (CLK low). |
|
|
193
|
+
| `cpu.ctl.haltLatch` | Internal HALT state, set by the `HALT` instruction and cleared by RESET / INT / NMI. Distinct from the `nHALT` output pin. |
|
|
194
|
+
| `cpu.ctl.nres` | Normal-reset latch — set when RESET was sampled, cleared once recovery completes. |
|
|
195
|
+
| `cpu.ctl.sres` | Special-reset flip-flop — set when RESET is sampled during M1 T2. See [RESET behavior](#reset-behavior) section below |
|
|
196
|
+
| `cpu.ctl.iff1`, `cpu.ctl.iff2` | Interrupt-enable flip-flops (also surfaced in `CpuState`). |
|
|
197
|
+
| `cpu.ctl.nmiFf` | NMI pending — set by `cpu.nmi()`, cleared at the NMI M1. Surfaced as `nmiPending` in `CpuState`. |
|
|
198
|
+
|
|
199
|
+
## Bus and signals
|
|
200
|
+
|
|
201
|
+
The CPU exposes its pins through `cpu.bus`. The host advances time by
|
|
202
|
+
calling `cpu.clockEdge()` — that call *is* one half-cycle of CLK, so
|
|
203
|
+
there's no `nCLK` pin on the bus. Bus signals are exchanged between
|
|
204
|
+
those edges.
|
|
205
|
+
|
|
206
|
+
Active-low convention throughout: `0` = asserted, `1` = released. The
|
|
207
|
+
transaction signals (MREQ, IORQ, RD, WR) tri-state
|
|
208
|
+
represented as `undefined`, therefore typed `0 | 1 | undefined`. The
|
|
209
|
+
address bus (`number | undefined`, 16-bit) and data bus (`number | undefined`,
|
|
210
|
+
8-bit) tri-state alongside them. The status signals (M1, RFSH, HALT) and
|
|
211
|
+
BUSACK stay driven throughout — typed `0 | 1`.
|
|
212
|
+
|
|
213
|
+
```ts
|
|
214
|
+
cpu.bus.nM1 // 0 during M1 fetch
|
|
215
|
+
cpu.bus.nMREQ // memory request; undefined while granted
|
|
216
|
+
cpu.bus.nIORQ // I/O request; undefined while granted
|
|
217
|
+
cpu.bus.nRD // read strobe; undefined while granted
|
|
218
|
+
cpu.bus.nWR // write strobe; undefined while granted
|
|
219
|
+
cpu.bus.nRFSH // refresh (DRAM refresh during M1 T3/T4)
|
|
220
|
+
cpu.bus.nHALT // HALT acknowledged on the pin
|
|
221
|
+
cpu.bus.nBUSACK // bus-grant acknowledge
|
|
222
|
+
cpu.bus.addr // 16-bit address bus; undefined while granted
|
|
223
|
+
cpu.bus.data // 8-bit data bus; CPU drives during writes, host fills during reads
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Inputs are typed `0 | 1` — the host sets them, the CPU samples them at
|
|
227
|
+
the modeled sampling edges:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
cpu.bus.nRESET = 0; // assert RESET
|
|
231
|
+
cpu.bus.nINT = 0; // level-triggered interrupt request
|
|
232
|
+
cpu.bus.nWAIT = 0; // stretch the current memory / IO cycle
|
|
233
|
+
cpu.bus.nBUSRQ = 0; // request a bus grant
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
NMI is the exception. The real Z80 NMI pin is **edge-triggered** — a
|
|
237
|
+
falling edge latches a request internally. To model that faithfully
|
|
238
|
+
through a level pin you'd need the host to toggle it and the CPU to
|
|
239
|
+
detect the transition, which adds friction in a synchronous emulator.
|
|
240
|
+
Instead, NMI is a method:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
cpu.nmi();
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
One call = one edge = one latched NMI, serviced at the end of the
|
|
247
|
+
current instruction. Calling again while a previous NMI hasn't been
|
|
248
|
+
acknowledged is a no-op.
|
|
249
|
+
|
|
250
|
+
## RESET behavior
|
|
251
|
+
|
|
252
|
+
The reset path has more nuance than typical references suggest:
|
|
253
|
+
|
|
254
|
+
### Special Reset
|
|
255
|
+
|
|
256
|
+
A designed but historically obscure feature. If RESET is sampled during
|
|
257
|
+
`M1 T2`, the CPU performs a partial reset: only `PC` is cleared to `0`,
|
|
258
|
+
while registers and most internal state are preserved — *not* a full
|
|
259
|
+
reset. Documented by Tony Brewer at
|
|
260
|
+
[primrosebank.net](http://www.primrosebank.net/computers/z80/z80_special_reset.htm).
|
|
261
|
+
Surfaced as `cpu.ctl.sres`.
|
|
262
|
+
|
|
263
|
+
### Beyond-the-datasheet quirks
|
|
264
|
+
|
|
265
|
+
The Z80 datasheet warns that if RESET is sampled during `T2` or `T4`
|
|
266
|
+
of a cycle, `MREQ` may become indeterminate for one
|
|
267
|
+
T-state shortly afterward. In systems with dynamic RAM this can potentially
|
|
268
|
+
corrupt memory contents, which is why the datasheet recommends synchronizing
|
|
269
|
+
RESET with the falling edge of `M1` when RAM must be preserved.
|
|
270
|
+
|
|
271
|
+
The transistor-level netlist suggests broader behavior:
|
|
272
|
+
- **Sampled on the last T-state of any M-cycle**, not only `T2` or `T4`.
|
|
273
|
+
- **`RD` also becomes indeterminate**, alongside `MREQ`, during the next
|
|
274
|
+
`M1 T1`.
|
|
275
|
+
- **A spurious `RD` low pulse appears** on the following reset recovery
|
|
276
|
+
edge.
|
|
277
|
+
|
|
278
|
+
These effects may be netlist artifacts rather than real silicon
|
|
279
|
+
behavior, but are modeled for completeness.
|
|
280
|
+
|
|
281
|
+
## Plain arrays inside the CPU
|
|
282
|
+
|
|
283
|
+
The CPU's internal register state — `cpu.regs.file`, `cpu.regs.f` — is
|
|
284
|
+
plain `number[]`. `Uint8Array` is intentionally avoided here.
|
|
285
|
+
|
|
286
|
+
Why: V8 specializes object/array shapes by element-kind. Mixing typed
|
|
287
|
+
arrays with `number[]` on the same hot path tends to introduce element-kind
|
|
288
|
+
transitions ("type churn") that defeat inline caching. Sticking to
|
|
289
|
+
SMI-tagged 32-bit integers in plain arrays through the register file
|
|
290
|
+
keeps everything on one fast path.
|
|
291
|
+
|
|
292
|
+
Host-side storage is the host's choice. The bus resolver runs outside
|
|
293
|
+
the CPU — it can back memory and I/O ports with `Uint8Array`,
|
|
294
|
+
`Uint16Array`, plain `number[]`, or anything else that responds to
|
|
295
|
+
`addr` and yields a number.
|
|
296
|
+
|
|
297
|
+
Side effect of the plain-array choice: register values aren't
|
|
298
|
+
*automatically* truncated to 8/16 bits — the CPU does that explicitly
|
|
299
|
+
at every writeback site, and `cpu.snapshot()` trusts that invariant.
|
|
300
|
+
Consumers reading raw state shouldn't need to mask either, as long as
|
|
301
|
+
the CPU stays correct.
|
|
302
|
+
|
|
303
|
+
## Companion toolkit
|
|
304
|
+
|
|
305
|
+
Higher-level tooling built on top of this library — an interactive
|
|
306
|
+
debugger, a disassembler, and a REPL — lives in the
|
|
307
|
+
[z80cpu-lab](https://github.com/dcorp80/z80cpu-lab) sibling repo.
|
|
308
|
+
|
|
309
|
+
## License
|
|
310
|
+
|
|
311
|
+
Apache-2.0 — see [LICENSE](LICENSE) and [NOTICE](NOTICE).
|
|
312
|
+
|
|
313
|
+
## Acknowledgements
|
|
314
|
+
|
|
315
|
+
Inspired by the Visual6502 and VisualZ80 Remixed projects.
|
|
316
|
+
- [www.visual6502.org](http://www.visual6502.org/welcome.html)
|
|
317
|
+
- [floooh/v6502r](https://github.com/floooh/v6502r).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
type ExecutorFn = (cpu: Z80Cpu) => void;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* One Z80 register bank: B/C/D/E/H/L/A/F as seen by the programmer.
|
|
5
|
+
* `CpuState.main` is the currently-visible bank; `CpuState.alt` is the
|
|
6
|
+
* one that would become visible after `EXX` (and `EX AF,AF'` for A/F).
|
|
7
|
+
*/
|
|
8
|
+
interface RegBank {
|
|
9
|
+
b: number;
|
|
10
|
+
c: number;
|
|
11
|
+
d: number;
|
|
12
|
+
e: number;
|
|
13
|
+
h: number;
|
|
14
|
+
l: number;
|
|
15
|
+
a: number;
|
|
16
|
+
f: number;
|
|
17
|
+
}
|
|
18
|
+
interface CpuState {
|
|
19
|
+
pc: number;
|
|
20
|
+
sp: number;
|
|
21
|
+
ix: number;
|
|
22
|
+
iy: number;
|
|
23
|
+
i: number;
|
|
24
|
+
r: number;
|
|
25
|
+
wz: number;
|
|
26
|
+
main: RegBank;
|
|
27
|
+
alt: RegBank;
|
|
28
|
+
im: 0 | 1 | 2;
|
|
29
|
+
/**
|
|
30
|
+
* True when the IM flip-flops are in the undocumented `imFa=0, imFb=1`
|
|
31
|
+
* state — which behaves as IM 0 `im` reports `0`; consumers that care
|
|
32
|
+
* about the distinction read this flag.
|
|
33
|
+
*/
|
|
34
|
+
imUndocumented: boolean;
|
|
35
|
+
/** Interrupt enable flip-flops. */
|
|
36
|
+
iff1: boolean;
|
|
37
|
+
iff2: boolean;
|
|
38
|
+
/** NMI latched and waiting to be acknowledged at the next instruction boundary. */
|
|
39
|
+
nmiPending: boolean;
|
|
40
|
+
}
|
|
41
|
+
interface DecodedFlags {
|
|
42
|
+
s: boolean;
|
|
43
|
+
z: boolean;
|
|
44
|
+
x5: boolean;
|
|
45
|
+
h: boolean;
|
|
46
|
+
x3: boolean;
|
|
47
|
+
pv: boolean;
|
|
48
|
+
n: boolean;
|
|
49
|
+
c: boolean;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Decode an 8-bit Z80 flag register into individual booleans. Use on
|
|
53
|
+
* `snapshot().main.f` or `snapshot().alt.f` — kept out of the snapshot
|
|
54
|
+
* itself so `CpuState` stays a minimal, canonical representation.
|
|
55
|
+
*/
|
|
56
|
+
declare function decodeFlags(f: number): DecodedFlags;
|
|
57
|
+
/**
|
|
58
|
+
* Fill `out` (or a fresh object) with the CPU's architectural state.
|
|
59
|
+
* Pass a pre-allocated `CpuState` to avoid the per-call allocation in
|
|
60
|
+
* tight loops — `out.main` and `out.alt` must be present.
|
|
61
|
+
*/
|
|
62
|
+
declare function snapshotCpu(cpu: Z80Cpu, out?: CpuState): CpuState;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Identifier for every step function the sequencer can land on. Exposed as
|
|
66
|
+
* `cpu.nextStep` for external observers (debuggers, tracers); the simulator
|
|
67
|
+
* itself uses function pointers internally because identity-compare beats
|
|
68
|
+
* enum switching on the hot path. Consumers gate on `StepId.*` values
|
|
69
|
+
* instead of importing step functions directly.
|
|
70
|
+
*/
|
|
71
|
+
declare enum StepId {
|
|
72
|
+
M1_T1_0 = 0,
|
|
73
|
+
M1_T1_1 = 1,
|
|
74
|
+
M1_T2_0 = 2,
|
|
75
|
+
M1_T2_1 = 3,
|
|
76
|
+
M1_T3_0 = 4,
|
|
77
|
+
M1_T3_1 = 5,
|
|
78
|
+
M1_T4_0 = 6,
|
|
79
|
+
M1_T4_1 = 7,
|
|
80
|
+
OP_RD_T1_0 = 8,
|
|
81
|
+
OP_RD_T1_1 = 9,
|
|
82
|
+
M_RD_T1_0 = 10,
|
|
83
|
+
M_RD_T1_1 = 11,
|
|
84
|
+
RD_T2_0 = 12,
|
|
85
|
+
RD_T2_1 = 13,
|
|
86
|
+
RD_T3_0 = 14,
|
|
87
|
+
RD_T3_1 = 15,
|
|
88
|
+
M_WR_T1_0 = 16,
|
|
89
|
+
M_WR_T1_1 = 17,
|
|
90
|
+
M_WR_T2_0 = 18,
|
|
91
|
+
M_WR_T2_1 = 19,
|
|
92
|
+
M_WR_T3_0 = 20,
|
|
93
|
+
M_WR_T3_1 = 21,
|
|
94
|
+
INTERNAL_T1_0 = 22,
|
|
95
|
+
INTERNAL_T1_1 = 23,
|
|
96
|
+
INTERNAL_3T_T1_0 = 24,
|
|
97
|
+
INTERNAL_3T_T1_1 = 25,
|
|
98
|
+
INTERNAL_3T_T2_0 = 26,
|
|
99
|
+
INTERNAL_3T_T2_1 = 27,
|
|
100
|
+
INTERNAL_3T_T3_0 = 28,
|
|
101
|
+
INTERNAL_3T_T3_1 = 29,
|
|
102
|
+
INTERNAL_4T_T1_0 = 30,
|
|
103
|
+
INTERNAL_4T_T1_1 = 31,
|
|
104
|
+
INTERNAL_4T_T2_0 = 32,
|
|
105
|
+
INTERNAL_4T_T2_1 = 33,
|
|
106
|
+
INTERNAL_4T_T3_0 = 34,
|
|
107
|
+
INTERNAL_4T_T3_1 = 35,
|
|
108
|
+
INTERNAL_4T_T4_0 = 36,
|
|
109
|
+
INTERNAL_4T_T4_1 = 37,
|
|
110
|
+
IO_RD_T1_0 = 38,
|
|
111
|
+
IO_RD_T1_1 = 39,
|
|
112
|
+
IO_RD_T2_0 = 40,
|
|
113
|
+
IO_RD_T2_1 = 41,
|
|
114
|
+
IO_RD_TW_0 = 42,
|
|
115
|
+
IO_RD_TW_1 = 43,
|
|
116
|
+
IO_RD_T3_0 = 44,
|
|
117
|
+
IO_RD_T3_1 = 45,
|
|
118
|
+
IO_WR_T1_0 = 46,
|
|
119
|
+
IO_WR_T1_1 = 47,
|
|
120
|
+
IO_WR_T2_0 = 48,
|
|
121
|
+
IO_WR_T2_1 = 49,
|
|
122
|
+
IO_WR_TW_0 = 50,
|
|
123
|
+
IO_WR_TW_1 = 51,
|
|
124
|
+
IO_WR_T3_0 = 52,
|
|
125
|
+
IO_WR_T3_1 = 53,
|
|
126
|
+
NMI_M1_T1_0 = 54,
|
|
127
|
+
NMI_M1_T1_1 = 55,
|
|
128
|
+
NMI_M1_T2_0 = 56,
|
|
129
|
+
NMI_M1_T2_1 = 57,
|
|
130
|
+
NMI_M1_T3_0 = 58,
|
|
131
|
+
INT_M1_T1_0 = 59,
|
|
132
|
+
INT_M1_T1_1 = 60,
|
|
133
|
+
INT_M1_T2_0 = 61,
|
|
134
|
+
INT_M1_T2_1 = 62,
|
|
135
|
+
INT_M1_T3_0 = 63,
|
|
136
|
+
INT_M1_TW1_0 = 64,
|
|
137
|
+
INT_M1_TW1_1 = 65,
|
|
138
|
+
INT_M1_TW2_0 = 66,
|
|
139
|
+
INT_M1_TW2_1 = 67,
|
|
140
|
+
ENTER_RESET_1 = 68,
|
|
141
|
+
RESET_HOLD_0 = 69,
|
|
142
|
+
RESET_HOLD_1 = 70,
|
|
143
|
+
RESET_RECOVER_0 = 71,
|
|
144
|
+
RESET_RECOVER_1 = 72,
|
|
145
|
+
BUS_GRANT_0 = 73,
|
|
146
|
+
BUS_GRANT_1 = 74
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* A sequencer step. Plain `(cpu) => void` at the type level so internal
|
|
150
|
+
* assignments stay terse. At runtime every step function carries an
|
|
151
|
+
* `.id: StepId` property (attached by the tagging block at the bottom of
|
|
152
|
+
* this file) — `cpu.nextStep` reads it via a controlled cast so external
|
|
153
|
+
* code can compare via `cpu.nextStep === StepId.X` without ever needing
|
|
154
|
+
* to import a step function pointer.
|
|
155
|
+
*/
|
|
156
|
+
type StepFn = (cpu: Z80Cpu) => void;
|
|
157
|
+
|
|
158
|
+
declare const B = 0;
|
|
159
|
+
declare const C = 1;
|
|
160
|
+
declare const D = 2;
|
|
161
|
+
declare const E = 3;
|
|
162
|
+
declare const H = 4;
|
|
163
|
+
declare const L = 5;
|
|
164
|
+
declare const A = 7;
|
|
165
|
+
declare const B_ = 8;
|
|
166
|
+
declare const C_ = 9;
|
|
167
|
+
declare const D_ = 10;
|
|
168
|
+
declare const E_ = 11;
|
|
169
|
+
declare const H_ = 12;
|
|
170
|
+
declare const L_ = 13;
|
|
171
|
+
declare const A_ = 15;
|
|
172
|
+
declare const IXH = 20;
|
|
173
|
+
declare const IXL = 21;
|
|
174
|
+
declare const IYH = 28;
|
|
175
|
+
declare const IYL = 29;
|
|
176
|
+
declare class Registers {
|
|
177
|
+
file: number[];
|
|
178
|
+
f: number[];
|
|
179
|
+
sp: number;
|
|
180
|
+
pc: number;
|
|
181
|
+
i: number;
|
|
182
|
+
r: number;
|
|
183
|
+
r7: number;
|
|
184
|
+
wz: number;
|
|
185
|
+
}
|
|
186
|
+
declare class Bus {
|
|
187
|
+
addr: number | undefined;
|
|
188
|
+
data: number | undefined;
|
|
189
|
+
nM1: 0 | 1;
|
|
190
|
+
nMREQ: 0 | 1 | undefined;
|
|
191
|
+
nIORQ: 0 | 1 | undefined;
|
|
192
|
+
nRD: 0 | 1 | undefined;
|
|
193
|
+
nWR: 0 | 1 | undefined;
|
|
194
|
+
nRFSH: 0 | 1;
|
|
195
|
+
nHALT: 0 | 1;
|
|
196
|
+
nBUSACK: 0 | 1;
|
|
197
|
+
nRESET: 0 | 1;
|
|
198
|
+
nINT: 0 | 1;
|
|
199
|
+
nWAIT: 0 | 1;
|
|
200
|
+
nBUSRQ: 0 | 1;
|
|
201
|
+
}
|
|
202
|
+
declare class Seq {
|
|
203
|
+
op: number;
|
|
204
|
+
y: number;
|
|
205
|
+
z: number;
|
|
206
|
+
executor: ExecutorFn;
|
|
207
|
+
hasMoreMCycles: boolean;
|
|
208
|
+
hasExtraT: boolean;
|
|
209
|
+
mAddr: number;
|
|
210
|
+
aluDst: number | undefined;
|
|
211
|
+
aluVal: number;
|
|
212
|
+
aluF: number | undefined;
|
|
213
|
+
aluFMask: number;
|
|
214
|
+
fWritten: boolean;
|
|
215
|
+
cbFf: number;
|
|
216
|
+
edFf: number;
|
|
217
|
+
m1T2Exec: ExecutorFn;
|
|
218
|
+
prefix: number;
|
|
219
|
+
exDe0: number;
|
|
220
|
+
exDe1: number;
|
|
221
|
+
lastOpTState: boolean;
|
|
222
|
+
phase: boolean;
|
|
223
|
+
}
|
|
224
|
+
declare class Ctl {
|
|
225
|
+
skipInts: boolean;
|
|
226
|
+
iff1: number;
|
|
227
|
+
iff2: number;
|
|
228
|
+
intFf: boolean;
|
|
229
|
+
nmiFf: boolean;
|
|
230
|
+
nmiAck: boolean;
|
|
231
|
+
imFa: number;
|
|
232
|
+
imFb: number;
|
|
233
|
+
haltLatch: boolean;
|
|
234
|
+
resi: boolean;
|
|
235
|
+
nres: boolean;
|
|
236
|
+
sres: boolean;
|
|
237
|
+
throwAwayM1: boolean;
|
|
238
|
+
qres: boolean;
|
|
239
|
+
resetAtT1: boolean;
|
|
240
|
+
busrqFf: boolean;
|
|
241
|
+
busGrantResume: StepFn | undefined;
|
|
242
|
+
}
|
|
243
|
+
declare class Z80Cpu {
|
|
244
|
+
regs: Registers;
|
|
245
|
+
bus: Bus;
|
|
246
|
+
seq: Seq;
|
|
247
|
+
ctl: Ctl;
|
|
248
|
+
/**
|
|
249
|
+
* @internal — the sequencer's step pointer. Internal code uses identity
|
|
250
|
+
* compares (`this.next === m1_t1_0`) because they're faster than enum
|
|
251
|
+
* switching on the hot path. External consumers (debuggers, tracers)
|
|
252
|
+
* should compare via {@link Z80Cpu["nextStep"]} instead.
|
|
253
|
+
*/
|
|
254
|
+
next: StepFn;
|
|
255
|
+
/**
|
|
256
|
+
* Identifier of the step the sequencer will run on the next
|
|
257
|
+
* `clockEdge()`. Stable enum value — `cpu.nextStep === StepId.M1_T1_0`
|
|
258
|
+
* is the public way to gate on the upcoming step.
|
|
259
|
+
*
|
|
260
|
+
* The cast is safe by construction: every value stored in `this.next`
|
|
261
|
+
* comes from z80tPhase.ts, which tags every step function with its
|
|
262
|
+
* `id` at module init.
|
|
263
|
+
*/
|
|
264
|
+
get nextStep(): StepId;
|
|
265
|
+
clockEdge(): void;
|
|
266
|
+
/** Assert NMI (edge-triggered). Sets internal NMI flip-flop;
|
|
267
|
+
* will be serviced at the end of the current instruction. */
|
|
268
|
+
nmi(): void;
|
|
269
|
+
/**
|
|
270
|
+
* Architectural-level snapshot — registers, IM, IFFs, NMI-pending —
|
|
271
|
+
* with the internal bank-swap encoding decoded into `main` / `alt`.
|
|
272
|
+
* Pass a pre-allocated `CpuState` to avoid the per-call allocation.
|
|
273
|
+
*
|
|
274
|
+
* Defined as a thin wrapper to keep z80cpu.ts focused on simulation;
|
|
275
|
+
* the actual decoding lives in z80state.ts.
|
|
276
|
+
*/
|
|
277
|
+
snapshot(out?: CpuState): CpuState;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
export { A, A_, B, B_, C, C_, type CpuState, D, D_, type DecodedFlags, E, E_, H, H_, IXH, IXL, IYH, IYL, L, L_, type RegBank, StepId, Z80Cpu, decodeFlags, snapshotCpu };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var le=(r=>(r[r.M1_T1_0=0]="M1_T1_0",r[r.M1_T1_1=1]="M1_T1_1",r[r.M1_T2_0=2]="M1_T2_0",r[r.M1_T2_1=3]="M1_T2_1",r[r.M1_T3_0=4]="M1_T3_0",r[r.M1_T3_1=5]="M1_T3_1",r[r.M1_T4_0=6]="M1_T4_0",r[r.M1_T4_1=7]="M1_T4_1",r[r.OP_RD_T1_0=8]="OP_RD_T1_0",r[r.OP_RD_T1_1=9]="OP_RD_T1_1",r[r.M_RD_T1_0=10]="M_RD_T1_0",r[r.M_RD_T1_1=11]="M_RD_T1_1",r[r.RD_T2_0=12]="RD_T2_0",r[r.RD_T2_1=13]="RD_T2_1",r[r.RD_T3_0=14]="RD_T3_0",r[r.RD_T3_1=15]="RD_T3_1",r[r.M_WR_T1_0=16]="M_WR_T1_0",r[r.M_WR_T1_1=17]="M_WR_T1_1",r[r.M_WR_T2_0=18]="M_WR_T2_0",r[r.M_WR_T2_1=19]="M_WR_T2_1",r[r.M_WR_T3_0=20]="M_WR_T3_0",r[r.M_WR_T3_1=21]="M_WR_T3_1",r[r.INTERNAL_T1_0=22]="INTERNAL_T1_0",r[r.INTERNAL_T1_1=23]="INTERNAL_T1_1",r[r.INTERNAL_3T_T1_0=24]="INTERNAL_3T_T1_0",r[r.INTERNAL_3T_T1_1=25]="INTERNAL_3T_T1_1",r[r.INTERNAL_3T_T2_0=26]="INTERNAL_3T_T2_0",r[r.INTERNAL_3T_T2_1=27]="INTERNAL_3T_T2_1",r[r.INTERNAL_3T_T3_0=28]="INTERNAL_3T_T3_0",r[r.INTERNAL_3T_T3_1=29]="INTERNAL_3T_T3_1",r[r.INTERNAL_4T_T1_0=30]="INTERNAL_4T_T1_0",r[r.INTERNAL_4T_T1_1=31]="INTERNAL_4T_T1_1",r[r.INTERNAL_4T_T2_0=32]="INTERNAL_4T_T2_0",r[r.INTERNAL_4T_T2_1=33]="INTERNAL_4T_T2_1",r[r.INTERNAL_4T_T3_0=34]="INTERNAL_4T_T3_0",r[r.INTERNAL_4T_T3_1=35]="INTERNAL_4T_T3_1",r[r.INTERNAL_4T_T4_0=36]="INTERNAL_4T_T4_0",r[r.INTERNAL_4T_T4_1=37]="INTERNAL_4T_T4_1",r[r.IO_RD_T1_0=38]="IO_RD_T1_0",r[r.IO_RD_T1_1=39]="IO_RD_T1_1",r[r.IO_RD_T2_0=40]="IO_RD_T2_0",r[r.IO_RD_T2_1=41]="IO_RD_T2_1",r[r.IO_RD_TW_0=42]="IO_RD_TW_0",r[r.IO_RD_TW_1=43]="IO_RD_TW_1",r[r.IO_RD_T3_0=44]="IO_RD_T3_0",r[r.IO_RD_T3_1=45]="IO_RD_T3_1",r[r.IO_WR_T1_0=46]="IO_WR_T1_0",r[r.IO_WR_T1_1=47]="IO_WR_T1_1",r[r.IO_WR_T2_0=48]="IO_WR_T2_0",r[r.IO_WR_T2_1=49]="IO_WR_T2_1",r[r.IO_WR_TW_0=50]="IO_WR_TW_0",r[r.IO_WR_TW_1=51]="IO_WR_TW_1",r[r.IO_WR_T3_0=52]="IO_WR_T3_0",r[r.IO_WR_T3_1=53]="IO_WR_T3_1",r[r.NMI_M1_T1_0=54]="NMI_M1_T1_0",r[r.NMI_M1_T1_1=55]="NMI_M1_T1_1",r[r.NMI_M1_T2_0=56]="NMI_M1_T2_0",r[r.NMI_M1_T2_1=57]="NMI_M1_T2_1",r[r.NMI_M1_T3_0=58]="NMI_M1_T3_0",r[r.INT_M1_T1_0=59]="INT_M1_T1_0",r[r.INT_M1_T1_1=60]="INT_M1_T1_1",r[r.INT_M1_T2_0=61]="INT_M1_T2_0",r[r.INT_M1_T2_1=62]="INT_M1_T2_1",r[r.INT_M1_T3_0=63]="INT_M1_T3_0",r[r.INT_M1_TW1_0=64]="INT_M1_TW1_0",r[r.INT_M1_TW1_1=65]="INT_M1_TW1_1",r[r.INT_M1_TW2_0=66]="INT_M1_TW2_0",r[r.INT_M1_TW2_1=67]="INT_M1_TW2_1",r[r.ENTER_RESET_1=68]="ENTER_RESET_1",r[r.RESET_HOLD_0=69]="RESET_HOLD_0",r[r.RESET_HOLD_1=70]="RESET_HOLD_1",r[r.RESET_RECOVER_0=71]="RESET_RECOVER_0",r[r.RESET_RECOVER_1=72]="RESET_RECOVER_1",r[r.BUS_GRANT_0=73]="BUS_GRANT_0",r[r.BUS_GRANT_1=74]="BUS_GRANT_1",r))(le||{});function G(e){let s=e.seq.executor;e.seq.executor=w,e.seq.hasMoreMCycles=false,s(e);}function J(e){if(e.seq.hasExtraT){e.seq.hasExtraT=false;return}e.ctl.busrqFf=!e.bus.nBUSRQ,e.ctl.qres=e.ctl.resi;}var Os=e=>{e.bus.nMREQ=void 0,e.bus.nIORQ=void 0,e.bus.nRD=void 0,e.bus.nWR=void 0,e.bus.addr=void 0,e.bus.data=void 0;},H=e=>{e.bus.nMREQ=1,e.bus.nIORQ=1,e.bus.nWR=1,e.bus.nRD=e.ctl.qres&&!e.ctl.nres?0:1;},oe=e=>{e.bus.nMREQ=e.ctl.qres?void 0:1,e.bus.nIORQ=1,e.bus.nRD=e.ctl.qres?void 0:1,e.bus.nWR=1,e.bus.nBUSACK=1,e.bus.data=void 0,e.regs.pc=0,e.regs.i=0,e.regs.r=0,e.regs.r7=0,e.seq.executor=w,e.seq.hasMoreMCycles=false,e.seq.hasExtraT=false,e.seq.aluDst=void 0,e.seq.aluF=void 0,e.seq.aluFMask=0,e.ctl.haltLatch=false,e.ctl.busGrantResume=void 0,e.ctl.throwAwayM1=false,e.next=e.ctl.resetAtT1?ie:_e,e.ctl.resetAtT1=false;},ie=e=>{e.bus.nM1=1,e.bus.nRFSH=1,e.bus.addr=void 0,e.ctl.nres=false,e.next=qe;},qe=e=>{e.bus.nRD=1,e.ctl.resi?e.next=ie:e.next=_e;},_e=e=>{e.bus.nM1=1,e.bus.nRFSH=1,e.bus.nMREQ=1,e.bus.nIORQ=1,e.bus.nWR=1,e.bus.nRD=e.ctl.qres?0:1,e.bus.addr=void 0,e.ctl.nres=false,e.ctl.resi?e.next=qe:e.next=Ie;},Ie=e=>{e.next=D;};function Q(e,s){e.bus.nBUSRQ&&(e.ctl.busrqFf=false),e.bus.nBUSACK=0,e.bus.nRFSH=1,Os(e),e.ctl.busGrantResume=s,e.next=Ce;}var Oe=e=>{e.bus.nBUSRQ&&(e.ctl.busrqFf=false),e.next=Ce;},Ce=e=>{e.ctl.busrqFf?e.next=Oe:(e.bus.nBUSACK=1,e.next=e.ctl.busGrantResume,e.ctl.busGrantResume=void 0);},K=e=>{e.ctl.haltLatch=false,e.bus.nHALT=1,e.ctl.iff1=0,G(e),e.ctl.intFf?(e.ctl.iff2=0,e.next=me):e.next=he;},Me=e=>{if(e.regs.file[n[e.seq.prefix][e.seq.aluDst]]=e.seq.aluVal,e.seq.aluDst===o&&(e.seq.op===87||e.seq.op===95)){let s=e.seq.aluF;e.ctl.iff2&&(s|=A),e.seq.aluF=s;}e.seq.aluDst=void 0;},$=e=>{e.seq.lastOpTState=true,e.ctl.skipInts?e.ctl.skipInts=false:e.ctl.nmiAck?e.ctl.nmiAck=false:e.ctl.nmiFf?e.ctl.nmiAck=true:e.ctl.iff1&&!e.bus.nINT&&(e.ctl.intFf=true);},D=e=>{if(e.seq.lastOpTState=false,e.ctl.busrqFf){Q(e,D);return}e.bus.addr=e.regs.pc,e.bus.nM1=0,e.bus.nRFSH=1,H(e),e.next=Le;},Le=e=>{e.bus.nMREQ=0,e.bus.nRD=0,e.ctl.haltLatch||(e.regs.pc=e.regs.pc+1&65535),e.ctl.sres&&(e.regs.pc=0),e.ctl.qres=false,e.next=de;},de=e=>{e.next=He;},He=e=>{if(e.ctl.sres&&(e.ctl.throwAwayM1=true),e.ctl.nres||(e.ctl.sres=e.ctl.resi),!e.bus.nWAIT){e.next=de;return}e.seq.aluDst!==void 0&&Me(e),e.seq.m1T2Exec(e),e.next=Qe;},Qe=e=>{ye(e.bus.data,e),e.bus.nM1=1,e.bus.nMREQ=1,e.bus.nRD=1,e.bus.addr=e.regs.i<<8|e.regs.r&127|e.regs.r7,e.bus.nRFSH=0,e.next=re;},re=e=>{e.bus.nMREQ=0,e.regs.r=e.regs.r+1&127,e.seq.aluF!==void 0?(e.seq.fWritten=true,e.regs.f[e.seq.prefix&1]=e.regs.f[e.seq.prefix&1]&~e.seq.aluFMask|e.seq.aluF&e.seq.aluFMask,e.seq.aluF=void 0,e.seq.aluFMask=0):e.seq.fWritten=false,e.next=Be;},Be=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=Se;},Se=e=>{if(e.bus.nMREQ=1,e.ctl.throwAwayM1){e.ctl.throwAwayM1=false,e.seq.executor=w,e.seq.hasMoreMCycles=false,e.next=D;return}if(e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}if(e.ctl.haltLatch){e.seq.executor=w,e.seq.hasMoreMCycles=false,e.next=D;return}e.next=D,G(e);},d=e=>{if(e.ctl.busrqFf){Q(e,d);return}e.bus.addr=e.regs.pc,e.bus.nRFSH=1,H(e),e.next=ve;},ve=e=>{e.bus.nMREQ=0,e.bus.nRD=0,e.regs.pc=e.regs.pc+1&65535,e.next=ne;},T=e=>{if(e.ctl.busrqFf){Q(e,T);return}e.bus.addr=e.seq.mAddr,e.bus.nRFSH=1,H(e),e.next=Pe;},Pe=e=>{e.bus.nMREQ=0,e.bus.nRD=0,e.next=ne;},ne=e=>{e.next=Ge;},Ge=e=>{if(!e.bus.nWAIT){e.next=ne;return}e.next=Ue;},Ue=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=Xe;},Xe=e=>{if(e.bus.nMREQ=1,e.bus.nRD=1,e.seq.aluVal=e.bus.data&255,e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},m=e=>{if(e.ctl.busrqFf){Q(e,m);return}e.bus.addr=e.seq.mAddr,e.bus.nRFSH=1,H(e),e.next=je;},je=e=>{e.bus.nMREQ=0,e.bus.data=e.seq.aluVal&255,e.next=Te;},Te=e=>{e.next=Ye;},Ye=e=>{if(e.bus.nWR=0,!e.bus.nWAIT){e.next=Te;return}e.next=Je;},Je=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=Ke;},Ke=e=>{if(e.bus.nMREQ=1,e.bus.nWR=1,e.bus.data=void 0,e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},i=e=>{if(e.ctl.busrqFf){Q(e,i);return}e.bus.nRFSH=1,H(e),J(e),e.seq.hasMoreMCycles||$(e),e.next=$e;},$e=e=>{if(e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},V=e=>{if(e.ctl.busrqFf){Q(e,V);return}e.bus.nRFSH=1,H(e),e.next=ce;},ce=e=>{e.next=ue;},ue=e=>{e.next=pe;},pe=e=>{e.next=es;},es=e=>{e.next=ss;},ss=e=>{e.next=ts;},ts=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=rs;},rs=e=>{if(e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},se=e=>{if(e.ctl.busrqFf){Q(e,se);return}e.bus.nRFSH=1,H(e),e.next=ns;},ns=e=>{e.next=fs;},fs=e=>{e.next=as;},as=e=>{e.next=xs;},xs=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=ls;},ls=e=>{if(e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},u=e=>{if(e.ctl.busrqFf){Q(e,u);return}e.bus.addr=e.seq.mAddr,e.bus.nRFSH=1,H(e),e.next=os;},os=e=>{e.next=is;},is=e=>{e.bus.nIORQ=0,e.bus.nRD=0,e.next=qs;},qs=e=>{e.next=ge;},ge=e=>{e.next=_s;},_s=e=>{if(!e.bus.nWAIT){e.next=ge;return}e.next=Cs;},Cs=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=Ms;},Ms=e=>{if(e.bus.nIORQ=1,e.bus.nRD=1,e.seq.aluVal=e.bus.data&255,e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},p=e=>{if(e.ctl.busrqFf){Q(e,p);return}e.bus.addr=e.seq.mAddr,e.bus.nRFSH=1,H(e),e.next=ds;},ds=e=>{e.bus.data=e.seq.aluVal&255,e.next=Ts;},Ts=e=>{e.bus.nIORQ=0,e.bus.nWR=0,e.next=gs;},gs=e=>{e.next=Re;},Re=e=>{e.next=Rs;},Rs=e=>{if(!e.bus.nWAIT){e.next=Re;return}e.next=hs;},hs=e=>{J(e),e.seq.hasMoreMCycles||$(e),e.next=bs;},bs=e=>{if(e.bus.nIORQ=1,e.bus.nWR=1,e.bus.data=void 0,e.seq.lastOpTState&&(e.ctl.nmiAck||e.ctl.intFf)){K(e);return}e.next=D,G(e);},he=e=>{if(e.seq.lastOpTState=false,e.ctl.busrqFf){Q(e,he);return}e.ctl.nmiFf=false,e.bus.addr=e.regs.pc,e.bus.nM1=0,e.bus.nRFSH=1,H(e),e.next=ms;},ms=e=>{e.bus.nMREQ=0,e.bus.nRD=0,e.ctl.sres&&(e.regs.pc=0),e.next=be;},be=e=>{e.next=Zs;},Zs=e=>{if(e.ctl.sres&&(e.ctl.throwAwayM1=true),e.ctl.nres||(e.ctl.sres=e.ctl.resi),!e.bus.nWAIT){e.next=be;return}e.seq.aluDst!==void 0&&Me(e),e.seq.m1T2Exec(e),e.next=ys;},ys=e=>{e.regs.wz=102,e.seq.aluVal=0,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ee,e.bus.nM1=1,e.bus.nMREQ=1,e.bus.nRD=1,e.bus.addr=e.regs.i<<8|e.regs.r&127|e.regs.r7,e.bus.nRFSH=0,e.next=re;},me=e=>{if(e.seq.lastOpTState=false,e.ctl.busrqFf){Q(e,me);return}e.ctl.intFf=false,e.bus.addr=e.regs.pc,e.bus.nM1=0,e.bus.nRFSH=1,H(e),e.next=Es;},Es=e=>{e.ctl.sres&&(e.regs.pc=0),e.next=As;},As=e=>{e.next=Fs;},Fs=e=>{e.ctl.sres&&(e.ctl.throwAwayM1=true),e.ctl.nres||(e.ctl.sres=e.ctl.resi),e.seq.aluDst!==void 0&&Me(e),e.seq.m1T2Exec(e),e.next=ks;},ks=e=>{e.next=Ns;},Ns=e=>{e.bus.nIORQ=0,e.next=Ze;},Ze=e=>{e.next=Ds;},Ds=e=>{if(!e.bus.nWAIT){e.next=Ze;return}e.next=Vs;},Vs=e=>{e.ctl.imFa?e.ctl.imFb?(e.regs.wz=e.bus.data&255,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ws):(e.regs.wz=56,e.seq.aluVal=0,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ee):ye(e.bus.data,e),e.bus.nM1=1,e.bus.nIORQ=1,e.bus.addr=e.regs.i<<8|e.regs.r&127|e.regs.r7,e.bus.nRFSH=0,e.next=re;},l=(e,s)=>{e.id=s;};l(D,0);l(Le,1);l(de,2);l(He,3);l(Qe,4);l(re,5);l(Be,6);l(Se,7);l(d,8);l(ve,9);l(T,10);l(Pe,11);l(ne,12);l(Ge,13);l(Ue,14);l(Xe,15);l(m,16);l(je,17);l(Te,18);l(Ye,19);l(Je,20);l(Ke,21);l(i,22);l($e,23);l(se,24);l(ns,25);l(fs,26);l(as,27);l(xs,28);l(ls,29);l(V,30);l(ce,31);l(ue,32);l(pe,33);l(es,34);l(ss,35);l(ts,36);l(rs,37);l(u,38);l(os,39);l(is,40);l(qs,41);l(ge,42);l(_s,43);l(Cs,44);l(Ms,45);l(p,46);l(ds,47);l(Ts,48);l(gs,49);l(Re,50);l(Rs,51);l(hs,52);l(bs,53);l(he,54);l(ms,55);l(be,56);l(Zs,57);l(ys,58);l(me,59);l(Es,60);l(As,61);l(Fs,62);l(Vs,63);l(ks,64);l(Ns,65);l(Ze,66);l(Ds,67);l(oe,68);l(ie,69);l(qe,70);l(_e,71);l(Ie,72);l(Oe,73);l(Ce,74);var E=128,y=64,M=40,Z=16,A=4,N=2,R=1,w=()=>{},te=e=>(e^=e>>4,154020>>(e&15)&A),Ls=e=>{let{y:s,aluVal:t}=e.seq,f=e.regs.f[e.seq.prefix&1]&R,a,x;switch(s){case 0:a=t>>>7,x=(t<<1|a)&255;break;case 1:a=t&1,x=(a<<7|t>>>1)&255;break;case 2:a=t>>>7,x=(t<<1|f)&255;break;case 3:a=t&1,x=(f<<7|t>>>1)&255;break;default:return}e.seq.aluF=x&M|a,e.seq.aluVal=x;},Ee=e=>{let{y:s,aluVal:t}=e.seq,f=e.regs.f[e.seq.prefix&1]&R,a,x;switch(s){case 0:a=t>>>7,x=(t<<1|a)&255;break;case 1:a=t&1,x=(a<<7|t>>>1)&255;break;case 2:a=t>>>7,x=(t<<1|f)&255;break;case 3:a=t&1,x=(f<<7|t>>>1)&255;break;case 4:a=t>>>7,x=t<<1&255;break;case 5:a=t&1,x=(t&128|t>>>1)&255;break;case 6:a=t>>>7,x=(t<<1|1)&255;break;case 7:a=t&1,x=t>>>1&255;break;default:return}let C=x&(E|M);x===0&&(C|=y),C|=te(x),e.seq.aluF=C|a,e.seq.aluFMask=255,e.seq.aluVal=x;},Hs=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Qs;},Qs=e=>{e.regs.wz=e.seq.aluVal,e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Bs;},Bs=e=>{let s=e.seq.aluVal<<8|e.regs.wz&255;switch(e.seq.mAddr=s,e.seq.y){case 4:e.regs.wz=s+1&65535,e.next=m,e.seq.aluVal=e.regs.file[n[e.seq.prefix][q]],e.seq.hasMoreMCycles=true,e.seq.executor=Ss;break;case 5:e.regs.wz=s+1&65535,e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=vs;break;case 6:e.regs.wz=e.regs.file[n[e.seq.prefix][o]]<<8|s+1&255,e.next=m,e.seq.aluVal=e.regs.file[n[e.seq.prefix][o]];break;case 7:e.regs.wz=s+1&65535,e.next=T,e.seq.executor=Ae;break}},Ss=e=>{e.seq.mAddr=e.regs.wz,e.seq.aluVal=e.regs.file[n[e.seq.prefix][_]],e.next=m;},vs=e=>{e.regs.file[n[e.seq.prefix][q]]=e.seq.aluVal,e.seq.mAddr=e.regs.wz,e.next=T,e.seq.executor=Ps;},Ps=e=>{e.regs.file[n[e.seq.prefix][_]]=e.seq.aluVal;},Ae=e=>{e.regs.file[n[e.seq.prefix][o]]=e.seq.aluVal;},Gs=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Us;},Us=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Xs;},Xs=e=>{e.next=i,e.seq.executor=js;},js=e=>{let s=e.seq.aluVal<<24>>24,t=e.regs.pc+s&65535;e.regs.wz=t,e.regs.pc=t;},zs=e=>{let s=1;switch(e.seq.y){case 3:break;case 2:{let t=e.regs.file[n[e.seq.prefix][h]]-1&255;e.regs.file[n[e.seq.prefix][h]]=t,s=t;break}case 4:s=~e.regs.f[e.seq.prefix&1]&y;break;case 5:s=e.regs.f[e.seq.prefix&1]&y;break;case 6:s=~e.regs.f[e.seq.prefix&1]&R;break;case 7:s=e.regs.f[e.seq.prefix&1]&R;}s?Gs(e):e.next=d;},Ys=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Js;},Js=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Ks;},Ks=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=$s;},$s=e=>{let s=(e.seq.prefix&24)+12,t=e.regs.file[s]<<8|e.regs.file[s+1],f=e.seq.aluVal<<24>>24;t=t+f&65535,e.regs.wz=t,e.seq.mAddr=t,e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=cs;},cs=e=>{e.next=i;let s=e.seq.aluVal,t=e.seq.z&1,f=s+1-(t<<1)&255;e.seq.aluF=f&(E|M)|(f===0?y:0)|(s^f)&Z|(s===127+t?A:0)|t<<1,e.seq.aluFMask=~R&255,e.seq.aluVal=f,e.seq.hasMoreMCycles=true,e.seq.executor=fe;},fe=e=>{e.next=m;},us=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=ps;},ps=e=>{let s=(e.seq.prefix&24)+13,t=e.seq.aluVal<<24>>24;e.regs.wz=e.regs.file[s]+t,e.next=d,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=et;},et=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=st;},st=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=tt;},tt=e=>{let s=(e.seq.prefix&24)+12,t=(e.regs.file[s]<<8)+e.regs.wz&65535;e.regs.wz=t,e.seq.mAddr=t,e.next=m;},rt=e=>{e.seq.prefix=e.seq.prefix^1;},nt=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=zs;},ft=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.executor=at;},at=e=>{e.next=se,e.seq.executor=xt;},xt=e=>{let s=e.seq.y&6,t=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];e.regs.wz=t+1&65535;let f=s===6?e.regs.sp:e.regs.file[n[e.seq.prefix][s]]<<8|e.regs.file[n[e.seq.prefix][s+1]],a=t+f,x=(t^f^a)>>>8;e.regs.file[n[e.seq.prefix][q]]=a&255;let C=a>>>8&255;e.seq.aluF=C&M|x&Z|x>>>8&R,e.regs.file[n[e.seq.prefix][_]]=C,e.seq.aluFMask=M|Z|N|R;},lt=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=ot;},ot=e=>{let s=e.seq.y&6;s===6?e.regs.sp=e.seq.aluVal:e.regs.file[n[e.seq.prefix][s+1]]=e.seq.aluVal,e.next=d,e.seq.executor=it;},it=e=>{let s=e.seq.y&6;s===6?e.regs.sp=e.seq.aluVal<<8|e.regs.sp&255:e.regs.file[n[e.seq.prefix][s]]=e.seq.aluVal;},qt=e=>{let s=e.seq.y&2,t=s|1,f=e.regs.file[n[e.seq.prefix][s]]<<8|e.regs.file[n[e.seq.prefix][t]],a=e.regs.file[n[e.seq.prefix][o]];e.seq.mAddr=f,e.regs.wz=a<<8|f+1&255,e.seq.aluVal=a,e.next=m;},_t=e=>{let s=e.seq.y&2,t=s|1,f=e.regs.file[n[e.seq.prefix][s]]<<8|e.regs.file[n[e.seq.prefix][t]];e.seq.mAddr=f,e.regs.wz=f+1&65535,e.next=T,e.seq.executor=Ae;},Ct=e=>{let{y:s}=e.seq,t=s&1,f=s&6,a=f+1,x=f===6?e.regs.sp:e.regs.file[n[e.seq.prefix][f]]<<8|e.regs.file[n[e.seq.prefix][a]];x=x+1-(t<<1)&65535,f===6?e.regs.sp=x:(e.regs.file[n[e.seq.prefix][f]]=x>>>8,e.regs.file[n[e.seq.prefix][a]]=x&255),e.next=i,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Mt;},Mt=e=>{e.next=i;},dt=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Tt;},Tt=e=>{let s=e.seq.aluVal,t=e.seq.z&1,f=s+1-(t<<1)&255;e.seq.aluF=f&(E|M)|(f===0?y:0)|(s^f)&Z|(s===127+t?A:0)|t<<1,e.seq.aluFMask=~R&255,e.seq.aluVal=f,e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=fe;},gt=e=>{let{y:s,z:t}=e.seq,f=e.regs.file[n[e.seq.prefix][s]],a=t&1,x=f+1-(a<<1)&255;e.seq.aluDst=s,e.seq.aluVal=x,e.seq.aluF=x&(E|M)|(x===0?y:0)|(f^x)&Z|(f===127+a?A:0)|a<<1,e.seq.aluFMask=~R&255;},Rt=e=>{let{y:s}=e.seq;e.next=d,e.seq.hasMoreMCycles=s===6,e.seq.executor=ht;},ht=e=>{let{y:s}=e.seq;if(s===6){e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=m;return}e.seq.aluDst=s;},bt=e=>{let{y:s}=e.seq,t=M|Z|N|R,f=e.regs.file[n[e.seq.prefix][o]],a=e.regs.f[e.seq.prefix&1];switch(s){case 4:{t=255;let x=0,C=a&R;(a&Z||(f&15)>9)&&(x=6),(C||f>153)&&(x|=96,C=R);let b=f;f=a&N?f-x&255:f+x&255;let F=a&N|C;F|=f&(E|M),f===0&&(F|=y),F|=te(f),F|=(b^f)&Z,a=F,e.seq.aluVal=f,e.seq.aluDst=o;break}case 5:{t=M|Z|N;let x=~f&255;a=x&M|Z|N,e.seq.aluVal=x,e.seq.aluDst=o;break}case 6:a=(e.seq.fWritten?f:f|a)&M|R;break;case 7:{let x=a&R;a=(e.seq.fWritten?f:f|a)&M,a|=x===0?R:Z;break}}e.seq.aluF=a,e.seq.aluFMask=t;};function mt(e){let{y:s,z:t}=e.seq;if(t===0){if(s===0)return;if(s===1){e.seq.executor=rt;return}e.seq.hasMoreMCycles=true,s===2?(e.seq.hasExtraT=true,e.seq.executor=nt):e.seq.executor=zs;return}if(t===1){e.seq.hasMoreMCycles=true,s&1?e.seq.executor=ft:e.seq.executor=lt;return}if(t===2)switch(e.seq.hasMoreMCycles=true,s){case 0:case 2:e.seq.executor=qt;return;case 1:case 3:e.seq.executor=_t;return;case 4:case 5:case 6:case 7:e.seq.executor=Hs;return}if(t===3){e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Ct;return}if(t===4||t===5){if(s===6){e.seq.hasMoreMCycles=true,e.seq.executor=e.seq.prefix&24?Ys:dt;return}e.seq.executor=gt;}if(t===6){if(e.seq.hasMoreMCycles=true,s===6&&e.seq.prefix&24){e.seq.executor=us;return}e.seq.executor=Rt;return}if(t===7){if(s<4){e.seq.aluDst=7,e.seq.aluVal=e.regs.file[n[e.seq.prefix][o]],e.seq.aluFMask=M|Z|N|R,e.seq.executor=Ls;return}e.seq.executor=bt;}}var Zt=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=yt;},yt=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Et;},Et=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=At;},At=e=>{let s=(e.seq.prefix&24)+12,t=e.regs.file[s]<<8|e.regs.file[s+1],f=e.seq.aluVal<<24>>24;t=t+f&65535,e.regs.wz=t,e.seq.mAddr=t,e.next=T,e.seq.executor=Ft;},Ft=e=>{e.seq.prefix=e.seq.prefix&7,e.seq.aluDst=e.seq.y;},kt=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Nt;},Nt=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Dt;},Dt=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=Vt;},Vt=e=>{let s=(e.seq.prefix&24)+12,t=e.regs.file[s]<<8|e.regs.file[s+1],f=e.seq.aluVal<<24>>24;t=t+f&65535,e.regs.wz=t,e.seq.mAddr=t,e.seq.aluVal=e.regs.file[n[e.seq.prefix&7][e.seq.z]],e.next=m;},wt=e=>{e.ctl.haltLatch=true,e.bus.nHALT=0;},zt=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.seq.aluVal=e.regs.file[n[e.seq.prefix][e.seq.z]],e.next=m;},Wt=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.executor=It;},It=e=>{e.seq.aluDst=e.seq.y;},Ot=e=>{let{y:s,z:t}=e.seq;e.seq.aluDst=s,e.seq.aluVal=e.regs.file[n[e.seq.prefix][t]];};function Lt(e){let{y:s,z:t}=e.seq;if(s===6&&t===6){e.seq.executor=wt;return}if(s===6){e.seq.hasMoreMCycles=true,e.seq.executor=e.seq.prefix&24?kt:zt;return}if(t===6){e.seq.hasMoreMCycles=true,e.seq.executor=e.seq.prefix&24?Zt:Wt;return}e.seq.executor=Ot;}var ae=e=>{let{y:s}=e.seq,t=e.regs.file[n[e.seq.prefix][o]],f=e.seq.aluVal,a=0,x=0;s===4&&(a=t&f,x=Z),s===5&&(a=t^f),s===6&&(a=t|f),x|=a&(E|M),a===0&&(x|=y),x|=te(a),e.seq.aluFMask=255,e.seq.aluF=x,e.seq.aluDst=o,e.seq.aluVal=a&255;},xe=e=>{let{y:s}=e.seq,t=e.regs.file[n[e.seq.prefix][o]],f=e.seq.aluVal,a=t^f,x=f,C=s===1||s===3?e.regs.f[e.seq.prefix&1]&R:0;(s===2||s===3||s===7)&&(f=~f,C=C?0:1);let b=t+f+C;C=a^b;let F=b&255;s!==7&&(e.seq.aluDst=o,x=F),x&=M,(s===2||s===3||s===7)&&(x|=N),F===0&&(x|=y),x|=F&E|C&Z|(~(t^f)&(t^F)&128)>>>5|C>>>8&R,e.seq.aluFMask=255,e.seq.aluF=x,e.seq.aluVal=F;},Ht=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Qt;},Qt=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Bt;},Bt=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=St;},St=e=>{let{y:s}=e.seq,t=(e.seq.prefix&24)+12,f=e.regs.file[t]<<8|e.regs.file[t+1],a=e.seq.aluVal<<24>>24;f=f+a&65535,e.regs.wz=f,e.seq.mAddr=f,e.next=T,e.seq.executor=s<7&&s>3?ae:xe;},vt=e=>{let{y:s}=e.seq;e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.executor=s<7&&s>3?ae:xe;};function Pt(e){let{y:s,z:t}=e.seq;t===6?(e.seq.hasMoreMCycles=true,e.seq.executor=e.seq.prefix&24?Ht:vt):(e.seq.aluVal=e.regs.file[n[e.seq.prefix][t]],e.seq.executor=s<7&&s>3?ae:xe);}var Fe=e=>{e.seq.mAddr=e.regs.sp,e.seq.hasMoreMCycles=true,e.next=T,e.seq.executor=Gt;},Gt=e=>{e.regs.wz=e.seq.aluVal,e.seq.mAddr=e.regs.sp+1&65535,e.next=T,e.seq.executor=Ut;},Ut=e=>{let s=e.seq.aluVal<<8|e.regs.wz&255;e.regs.sp=e.regs.sp+2&65535,e.regs.wz=s,e.regs.pc=s;},ee=e=>{e.regs.wz=e.seq.aluVal<<8|e.regs.wz&255,e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=Xt;},Xt=e=>{e.seq.mAddr=e.regs.sp-1&65535,e.seq.aluVal=e.regs.pc>>>8,e.seq.hasMoreMCycles=true,e.next=m,e.seq.executor=jt;},jt=e=>{let s=e.regs.sp-2&65535;e.seq.mAddr=s,e.regs.sp=s,e.seq.aluVal=e.regs.pc&255,e.regs.pc=e.regs.wz,e.next=m;},Yt=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Jt;},Jt=e=>{let s=(e.seq.prefix&24)+13,t=e.seq.aluVal<<24>>24;e.regs.wz=e.regs.file[s]+t,e.next=d,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Kt;},Kt=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=$t;},$t=e=>{e.seq.op=e.seq.aluVal,e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=ct;},ct=e=>{let s=(e.seq.prefix&24)+12,t=(e.regs.file[s]<<8)+e.regs.wz&65535;e.regs.wz=t,e.seq.mAddr=t,e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,(e.seq.op&192)===64?e.seq.executor=ut:e.seq.executor=pt,e.seq.cbFf=0,e.seq.m1T2Exec=w;},ut=e=>{e.seq.y=e.seq.op>>3&7,ke(e,e.seq.aluVal,e.regs.wz>>>8),e.next=i;},pt=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=er;},er=e=>{let{op:s}=e.seq,t=s>>6&3;e.seq.y=s>>3&7;let f=s&7;switch(t){case 0:Ee(e);break;case 2:case 3:{let a=1<<e.seq.y;e.seq.aluVal=s&64?e.seq.aluVal|a:e.seq.aluVal&~a&255;}}e.next=m,f!==6&&(e.seq.aluDst=f,e.seq.prefix=e.seq.prefix&7);},sr=e=>{let s=e.regs.f[e.seq.prefix&1];switch(e.seq.y){case 0:s=~s&y;break;case 1:s&=y;break;case 2:s=~s&R;break;case 3:s&=R;break;case 4:s=~s&A;break;case 5:s&=A;break;case 6:s=~s&E;break;case 7:s&=E;break}e.next=i,s&&(e.seq.hasMoreMCycles=true,e.seq.executor=Fe);},tr=e=>{e.seq.prefix=e.seq.prefix^2,e.seq.prefix=e.seq.prefix&27|(e.seq.prefix&2?e.seq.exDe1:e.seq.exDe0);},rr=e=>{e.regs.pc=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];},nr=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=fr;},fr=e=>{e.next=i,e.seq.executor=ar;},ar=e=>{e.regs.sp=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];},xr=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=lr;},lr=e=>{e.regs.wz=e.seq.aluVal,e.next=d,e.seq.executor=or;},or=e=>{let s=e.regs.f[e.seq.prefix&1],{y:t}=e.seq,f=e.seq.aluVal<<8|e.regs.wz&255;switch(e.regs.wz=f,t){case 0:s=~s&y;break;case 1:s&=y;break;case 2:s=~s&R;break;case 3:s&=R;break;case 4:s=~s&A;break;case 5:s&=A;break;case 6:s=~s&E;break;case 7:s&=E;break}s&&(e.regs.pc=f);},ir=e=>{e.seq.cbFf=1,e.seq.m1T2Exec=qr;},qr=e=>{e.seq.cbFf=0,e.seq.prefix=e.seq.prefix&7,e.seq.m1T2Exec=w;},_r=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Cr;},Cr=e=>{e.regs.wz=e.seq.aluVal,e.next=d,e.seq.executor=Mr;},Mr=e=>{let s=e.seq.aluVal<<8|e.regs.wz&255;e.regs.wz=s,e.regs.pc=s;},dr=e=>{e.seq.mAddr=e.regs.sp,e.seq.hasMoreMCycles=true,e.next=T,e.seq.executor=Tr;},Tr=e=>{e.regs.wz=e.seq.aluVal,e.seq.mAddr=e.regs.sp+1&65535,e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=gr;},gr=e=>{e.regs.wz=e.seq.aluVal<<8|e.regs.wz&255,e.seq.hasMoreMCycles=true,e.next=i,e.seq.executor=Rr;},Rr=e=>{e.seq.mAddr=e.regs.sp+1&65535,e.seq.aluVal=e.regs.file[n[e.seq.prefix][_]],e.seq.hasMoreMCycles=true,e.next=m,e.seq.executor=hr;},hr=e=>{e.seq.mAddr=e.regs.sp,e.seq.aluVal=e.regs.file[n[e.seq.prefix][q]],e.next=m,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=br;},br=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=mr;},mr=e=>{e.regs.file[n[e.seq.prefix][_]]=e.regs.wz>>>8,e.regs.file[n[e.seq.prefix][q]]=e.regs.wz&255,e.next=i;},Zr=e=>{e.seq.prefix&2?(e.seq.exDe1^=4,e.seq.prefix=e.seq.prefix&27|e.seq.exDe1):(e.seq.exDe0^=4,e.seq.prefix=e.seq.prefix&27|e.seq.exDe0);},yr=e=>{e.ctl.iff1=e.ctl.iff2=e.seq.y&1;},Er=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Ar;},Ar=e=>{let s=e.regs.file[n[e.seq.prefix][o]]<<8|e.seq.aluVal;e.seq.mAddr=s,e.regs.wz=s+1&65535,e.next=u,e.seq.executor=Ae;},Fr=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=kr;},kr=e=>{let s=e.regs.file[n[e.seq.prefix][o]],t=s<<8|e.seq.aluVal;e.seq.mAddr=t++,e.regs.wz=s<<8|t&255,e.seq.aluVal=s,e.next=p;},Nr=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Dr;},Dr=e=>{let s=e.regs.f[e.seq.prefix&1],{y:t}=e.seq;switch(e.regs.wz=e.seq.aluVal,e.next=d,t){case 0:s=~s&y;break;case 1:s&=y;break;case 2:s=~s&R;break;case 3:s&=R;break;case 4:s=~s&A;break;case 5:s&=A;break;case 6:s=~s&E;break;case 7:s&=E;break}s?(e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ee):e.seq.executor=Vr;},Vr=e=>{e.regs.wz=e.seq.aluVal<<8|e.regs.wz&255;},wr=e=>{e.seq.prefix=e.seq.prefix&7,e.seq.edFf=1,e.seq.m1T2Exec=zr;},zr=e=>{e.seq.edFf=0,e.seq.m1T2Exec=w;},Wr=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Ir;},Ir=e=>{e.regs.wz=e.seq.aluVal,e.next=d,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ee;},Or=e=>{e.seq.prefix=e.seq.prefix&7|8,e.seq.m1T2Exec=Ws;},Lr=e=>{e.seq.prefix=e.seq.prefix&7|16,e.seq.m1T2Exec=Ws;},Ws=e=>{e.seq.prefix=e.seq.prefix&7,e.seq.m1T2Exec=w;},Hr=e=>{e.seq.hasMoreMCycles=true,e.next=i,e.seq.executor=Qr;},Qr=e=>{e.seq.mAddr=e.regs.sp-1&65535;let s=e.seq.y&6;e.seq.aluVal=s===6?e.regs.file[n[e.seq.prefix][o]]:e.regs.file[n[e.seq.prefix][s]],e.seq.hasMoreMCycles=true,e.next=m,e.seq.executor=Br;},Br=e=>{let s=e.regs.sp-2&65535;e.seq.mAddr=s,e.regs.sp=s;let t=(e.seq.y&6)+1;e.seq.aluVal=t===7?e.regs.f[e.seq.prefix&1]:e.regs.file[n[e.seq.prefix][t]],e.next=m;},Sr=e=>{e.next=d;let{y:s}=e.seq;e.seq.executor=s<7&&s>3?ae:xe;},vr=e=>{e.seq.mAddr=e.regs.sp,e.seq.hasMoreMCycles=true,e.next=T,e.seq.executor=Pr;},Pr=e=>{let s=(e.seq.y&6)+1;s===7?e.regs.f[e.seq.prefix&1]=e.seq.aluVal:e.regs.file[n[e.seq.prefix][s]]=e.seq.aluVal,e.seq.mAddr=e.regs.sp+1&65535,e.next=T,e.seq.executor=Gr;},Gr=e=>{let s=e.seq.y&6;s===6?e.regs.file[n[e.seq.prefix][o]]=e.seq.aluVal:e.regs.file[n[e.seq.prefix][s]]=e.seq.aluVal,e.regs.sp=e.regs.sp+2&65535;};function Ur(e){let{y:s,z:t}=e.seq;if(t===0){e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=sr;return}if(t===1){switch(s){case 1:e.seq.hasMoreMCycles=true,e.seq.executor=Fe;return;case 3:e.seq.executor=tr;return;case 5:e.seq.executor=rr;return;case 7:e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=nr;return}e.seq.hasMoreMCycles=true,e.seq.executor=vr;return}if(t===2){e.seq.hasMoreMCycles=true,e.seq.executor=xr;return}if(t===3){if(s===1){e.seq.hasMoreMCycles=true,e.seq.prefix&24&&(e.seq.executor=Yt),e.seq.m1T2Exec=ir;return}if(s===0){e.seq.hasMoreMCycles=true,e.seq.executor=_r;return}if(s===4){e.seq.hasMoreMCycles=true,e.seq.executor=dr;return}if(s===5){e.seq.executor=Zr;return}if(s===6||s===7){e.ctl.skipInts=true,e.seq.executor=yr;return}if(s===3){e.seq.hasMoreMCycles=true,e.seq.executor=Er;return}if(s===2){e.seq.hasMoreMCycles=true,e.seq.executor=Fr;return}}if(t===4){e.seq.hasMoreMCycles=true,e.seq.executor=Nr;return}if(t===5){switch(s){case 5:e.seq.hasMoreMCycles=true,e.seq.m1T2Exec=wr;return;case 1:e.seq.hasMoreMCycles=true,e.seq.executor=Wr;return;case 3:e.seq.hasMoreMCycles=true,e.seq.m1T2Exec=Or;return;case 7:e.seq.hasMoreMCycles=true,e.seq.m1T2Exec=Lr;return}e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Hr;return}if(t===6){e.seq.hasMoreMCycles=true,e.seq.executor=Sr;return}t===7&&(e.regs.wz=s<<3,e.seq.aluVal=0,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ee);}var ke=(e,s,t)=>{let f=e.seq.y,a=s&1<<f,x=t&M|Z;a===0&&(x|=y|A),a&128&&(x|=E),e.seq.aluF=x,e.seq.aluFMask=~R&255;},Xr=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=jr;},jr=e=>{Ee(e),e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=fe;},Yr=e=>{let{z:s}=e.seq;if(s===6){e.seq.hasMoreMCycles=true,e.seq.executor=Xr;return}e.seq.aluDst=s,e.seq.aluVal=e.regs.file[n[e.seq.prefix][s]],e.seq.executor=Ee;},Jr=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Kr;},Kr=e=>{ke(e,e.seq.aluVal,e.regs.wz>>>8),e.next=i;},$r=e=>{let s=e.regs.file[n[e.seq.prefix][e.seq.z]];ke(e,s,s);},cr=e=>{let{z:s}=e.seq;if(s===6){e.seq.hasMoreMCycles=true,e.seq.executor=Jr;return}e.seq.executor=$r;},ur=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=pr;},pr=e=>{let s=1<<e.seq.y;e.seq.aluVal=e.seq.op&64?e.seq.aluVal|s:e.seq.aluVal&~s&255,e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=fe;},en=e=>{let s=1<<e.seq.y;e.seq.aluVal=e.seq.op&64?e.seq.aluVal|s:e.seq.aluVal&~s&255;},sn=e=>{let{z:s}=e.seq;if(s===6){e.seq.hasMoreMCycles=true,e.seq.executor=ur;return}e.seq.aluDst=s,e.seq.aluVal=e.regs.file[n[e.seq.prefix][e.seq.z]],e.seq.executor=en;},tn=e=>{e.ctl.iff1=e.ctl.iff2,e.seq.edFf=0,e.seq.m1T2Exec=w;},rn=e=>{let{y:s}=e.seq;e.ctl.imFa=s>>1&1,e.ctl.imFb=s&1;},nn=e=>{e.seq.mAddr=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]],e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=fn;},fn=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.executor=an;},an=e=>{let s=e.regs.file[n[e.seq.prefix][o]],t=s&240,f=s&15,a=e.seq.aluVal>>>4,x=e.seq.aluVal&15;e.seq.aluVal=e.seq.y&1?(t|a)<<8|x<<4|f:(t|x)<<8|f<<4|a,e.next=m,e.seq.executor=xn;},xn=e=>{e.regs.wz=e.seq.mAddr+1&65535;let s=e.seq.aluVal>>>8,t=s&(E|M);s===0&&(t|=y),t|=te(s),e.seq.aluVal=s,e.seq.aluDst=o,e.seq.aluF=t,e.seq.aluFMask=254;},ln=e=>{let{y:s}=e.seq;switch(e.next=i,s){case 0:e.regs.i=e.regs.file[n[e.seq.prefix][o]];return;case 1:e.regs.r=e.regs.file[n[e.seq.prefix][o]]&127,e.regs.r7=e.regs.file[n[e.seq.prefix][o]]&128;return;case 2:case 3:{let t=s&1?e.regs.r|e.regs.r7:e.regs.i;e.seq.aluVal=t,e.seq.aluDst=o;let f=t&(E|M);t===0&&(f|=y),e.seq.aluF=f,e.seq.aluFMask=254;return}}},on=e=>{let s=e.regs.file[n[e.seq.prefix][h]]<<8|e.regs.file[n[e.seq.prefix][k]]&255;if(e.seq.mAddr=s,e.regs.wz=s+1&65535,e.seq.z){e.seq.aluVal=e.regs.file[n[e.seq.prefix][e.seq.y]],e.next=p;return}e.next=u,e.seq.executor=qn;},qn=e=>{let{y:s}=e.seq,t=e.seq.aluVal,f=t&(M|E);t===0&&(f|=y),f|=te(t),e.seq.aluFMask=254,e.seq.aluF=f,s!==6&&(e.seq.aluVal=t,e.seq.aluDst=s);},_n=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.executor=Cn;},Cn=e=>{e.next=se,e.seq.executor=Mn;},Mn=e=>{let{y:s}=e.seq,t=s&6,f=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];e.regs.wz=f+1&65535;let a=t===6?e.regs.sp:e.regs.file[n[e.seq.prefix][t]]<<8|e.regs.file[n[e.seq.prefix][t+1]],x=e.regs.f[e.seq.prefix&1]&R,C=f^a;(s&1)===0&&(a=~a,x=x?0:1);let b=f+a+x;x=(C^b)>>>8,e.regs.file[n[e.seq.prefix][q]]=b&255;let F=b>>>8&255;e.regs.file[n[e.seq.prefix][_]]=F;let c=F&(E|M);(s&1)===0&&(c|=N),(b&65535)===0&&(c|=y),c|=x&Z|(~(f^a)&(f^b)&32768)>>>13|x>>>8&R,e.seq.aluFMask=255,e.seq.aluF=c;},dn=e=>{e.next=d,e.seq.hasMoreMCycles=true,e.seq.executor=Tn;},Tn=e=>{if(e.regs.wz=e.seq.aluVal,e.next=d,e.seq.hasMoreMCycles=true,e.seq.y&1){e.seq.executor=gn;return}e.seq.executor=bn;},gn=e=>{e.seq.mAddr=e.seq.aluVal<<8|e.regs.wz&255,e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=Rn;},Rn=e=>{let s=e.seq.y&6;s===6?e.regs.sp=e.seq.aluVal&255:e.regs.file[n[e.seq.prefix][s+1]]=e.seq.aluVal;let t=e.seq.mAddr+1&65535;e.seq.mAddr=t,e.regs.wz=t,e.next=T,e.seq.executor=hn;},hn=e=>{let s=e.seq.y&6;s===6?e.regs.sp=e.seq.aluVal<<8|e.regs.sp:e.regs.file[n[e.seq.prefix][s]]=e.seq.aluVal;},bn=e=>{e.seq.mAddr=e.seq.aluVal<<8|e.regs.wz&255;let s=e.seq.y&6;e.seq.aluVal=s===6?e.regs.sp&255:e.regs.file[n[e.seq.prefix][s+1]],e.next=m,e.seq.hasMoreMCycles=true,e.seq.executor=mn;},mn=e=>{let s=e.seq.mAddr+1&65535;e.seq.mAddr=s,e.regs.wz=s;let t=e.seq.y&6;e.seq.aluVal=t===6?e.regs.sp>>>8:e.regs.file[n[e.seq.prefix][t]],e.next=m;},Zn=e=>{let s=e.regs.file[n[e.seq.prefix][o]],t=~s+1,f=s^t,a=t&255,x=a&M|N;a===0&&(x|=y),x|=a&E|f&Z|(s&a&128)>>>5|f>>>8&R,e.seq.aluFMask=255,e.seq.aluF=x,e.seq.aluDst=o,e.seq.aluVal=a;},yn=e=>{let{y:s,z:t}=e.seq;switch(t){case 0:case 1:e.seq.hasMoreMCycles=true,e.seq.executor=on;return;case 2:e.seq.hasMoreMCycles=true,e.seq.executor=_n;return;case 3:e.seq.hasMoreMCycles=true,e.seq.executor=dn;return;case 4:e.seq.executor=Zn;return;case 5:e.seq.hasMoreMCycles=true,e.seq.executor=Fe,e.seq.m1T2Exec=tn;return;case 6:e.seq.executor=rn;return;case 7:if((s&6)===6)return;if(s&4){e.seq.hasMoreMCycles=true,e.seq.executor=nn;return}e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=ln;}},Is=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=En;},En=e=>{e.next=i,e.seq.executor=An;},An=e=>{let s=e.regs.pc;e.regs.wz=--s&65535,e.regs.pc=--s&65535;let t=e.seq.aluF&199|e.regs.pc>>>8&M,f=e.regs.file[n[e.seq.prefix][h]]&15;t&R&&(f=t&N?--f:++f,t|=f&Z);let a=f&7;t^=(a^a<<1^a<<2)&A,e.seq.aluF=t;},Fn=e=>{let s=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];e.seq.mAddr=e.seq.y&1?s--:s++,e.regs.file[n[e.seq.prefix][q]]=s&255,e.regs.file[n[e.seq.prefix][_]]=s>>>8&255,e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=kn;},kn=e=>{let s=e.regs.file[n[e.seq.prefix][O]]<<8|e.regs.file[n[e.seq.prefix][L]];e.seq.mAddr=e.seq.y&1?s--:s++,e.regs.file[n[e.seq.prefix][L]]=s&255,e.regs.file[n[e.seq.prefix][O]]=s>>>8&255,e.next=m,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Nn;},Nn=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Dn;},Dn=e=>{let s=(e.regs.file[n[e.seq.prefix][h]]<<8|e.regs.file[n[e.seq.prefix][k]])-1&65535;e.regs.file[n[e.seq.prefix][k]]=s&255,e.regs.file[n[e.seq.prefix][h]]=s>>>8,e.next=i,e.seq.y&2&&s&&(e.seq.hasMoreMCycles=true,e.seq.executor=Vn);let t=e.regs.file[n[e.seq.prefix][o]],f=s===0?0:A,a=t+e.seq.aluVal;e.seq.aluF=(a<<4|a&15)&M|f,e.seq.aluFMask=M|Z|N|A;},Vn=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=wn;},wn=e=>{e.next=i,e.seq.executor=zn;},zn=e=>{let s=e.regs.pc;e.regs.wz=--s&65535,e.regs.pc=--s&65535,e.seq.aluF=e.regs.pc>>>8&M|A,e.seq.aluFMask=M|Z|N|A;},Wn=e=>{let s=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];e.seq.mAddr=e.seq.y&1?s--:s++,e.regs.file[n[e.seq.prefix][q]]=s&255,e.regs.file[n[e.seq.prefix][_]]=s>>>8&255,e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=In;},In=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=On;},On=e=>{let{y:s}=e.seq,t=(e.regs.file[n[e.seq.prefix][h]]<<8|e.regs.file[n[e.seq.prefix][k]])-1&65535;e.regs.file[n[e.seq.prefix][k]]=t&255,e.regs.file[n[e.seq.prefix][h]]=t>>>8;let f=e.regs.file[n[e.seq.prefix][o]],a=f+~e.seq.aluVal+1;e.next=i,s&2&&t&&a&&(e.seq.aluVal=a,e.seq.hasMoreMCycles=true,e.seq.executor=Ln);let x=(f^e.seq.aluVal^a)&Z,C=x?a-1<<4|a-1&15:a<<4|a&15;C&=M,a===0&&(C|=y),t&&(C|=A),C|=N|x,C|=a&E,e.seq.aluF=C,e.seq.aluFMask=254;},Ln=e=>{e.next=V,e.seq.hasMoreMCycles=true,e.seq.hasExtraT=true,e.seq.executor=Hn;},Hn=e=>{e.next=i,e.seq.executor=Qn;},Qn=e=>{let s=e.regs.pc;e.regs.wz=--s&65535,e.regs.pc=--s&65535;let t=e.regs.pc>>>8&M|A,f=M|Z|N|A;t|=e.seq.aluVal&(E|Z),t|=N,f|=E|y,e.seq.aluF=t,e.seq.aluFMask=f;},Bn=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=Sn;},Sn=e=>{let s=e.regs.file[n[e.seq.prefix][h]],t=e.regs.file[n[e.seq.prefix][k]],f=s<<8|t;e.seq.mAddr=f,e.regs.file[n[e.seq.prefix][h]]=s-1&255,e.regs.wz=(e.seq.y&1?--f:++f)&65535,e.next=u,e.seq.hasMoreMCycles=true,e.seq.executor=vn;},vn=e=>{let s=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];e.seq.mAddr=e.seq.y&1?s--:s++,e.regs.file[n[e.seq.prefix][q]]=s&255,e.regs.file[n[e.seq.prefix][_]]=s>>>8&255;let t=e.regs.file[n[e.seq.prefix][h]],f=t&(E|M);t===0&&(f|=y),f|=e.seq.aluVal>>>6&N;let a=e.seq.aluVal+(e.regs.wz&255);f|=a>>>8,f|=a>>>4&Z;let x=t;x^=t>>4,x^=a&7,x^=x<<2,x^=x>>1,f|=~x&A,e.seq.aluF=f,e.seq.aluFMask=255,e.next=m,e.seq.y&2&&t&&(e.seq.hasMoreMCycles=true,e.seq.executor=Is);},Pn=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=Gn;},Gn=e=>{let s=e.regs.file[n[e.seq.prefix][_]]<<8|e.regs.file[n[e.seq.prefix][q]];e.seq.mAddr=e.seq.y&1?s--:s++,e.regs.file[n[e.seq.prefix][q]]=s&255,e.regs.file[n[e.seq.prefix][_]]=s>>>8&255,e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=Un;},Un=e=>{let s=--e.regs.file[n[e.seq.prefix][h]]&255,t=e.regs.file[n[e.seq.prefix][k]],f=s<<8|t;e.seq.mAddr=f,e.regs.file[n[e.seq.prefix][h]]=s,e.regs.wz=(e.seq.y&1?--f:++f)&65535;let a=e.regs.file[n[e.seq.prefix][q]],x=s&(E|M);s===0&&(x|=y),x|=e.seq.aluVal>>>6&N;let C=e.seq.aluVal+a;x|=C>>>8,x|=C>>>4&Z;let b=s;b^=s>>4,b^=C&7,b^=b<<2,b^=b>>1,x|=~b&A,e.seq.aluF=x,e.seq.aluFMask=255,e.next=p,e.seq.y&2&&s&&(e.seq.hasMoreMCycles=true,e.seq.executor=Is);},Xn=e=>{let{y:s,z:t}=e.seq;if(s&4)switch(e.seq.hasMoreMCycles=true,t){case 0:e.seq.executor=Fn;return;case 1:e.seq.executor=Wn;return;case 2:e.seq.hasExtraT=true,e.seq.executor=Bn;return;case 3:e.seq.hasExtraT=true,e.seq.executor=Pn;}},ye=(e,s)=>{let t=e>>6&3;if(s.seq.op=e&255,s.seq.y=e>>3&7,s.seq.z=e&7,s.seq.executor=w,s.seq.hasMoreMCycles=false,s.seq.cbFf){switch(t){case 0:Yr(s);break;case 1:cr(s);break;case 2:case 3:sn(s);break}return}if(s.seq.edFf){switch(t){case 1:yn(s);break;case 2:Xn(s);break}return}switch(t){case 0:mt(s);break;case 1:Lt(s);break;case 2:Pt(s);break;case 3:Ur(s);break}},ws=e=>{e.next=i,e.seq.hasMoreMCycles=true,e.seq.executor=jn;},jn=e=>{e.seq.mAddr=e.regs.sp-1&65535,e.seq.aluVal=e.regs.pc>>>8,e.next=m,e.seq.hasMoreMCycles=true,e.seq.executor=Yn;},Yn=e=>{let s=e.regs.sp-2&65535;e.seq.mAddr=s,e.regs.sp=s,e.seq.aluVal=e.regs.pc&255,e.next=m,e.seq.hasMoreMCycles=true,e.seq.executor=Jn;},Jn=e=>{let s=e.regs.i<<8|e.regs.wz;e.seq.mAddr=s,e.regs.wz=s+1&65535,e.next=T,e.seq.hasMoreMCycles=true,e.seq.executor=Kn;},Kn=e=>{e.seq.mAddr=e.regs.wz,e.regs.wz=e.seq.aluVal,e.next=T,e.seq.executor=$n;},$n=e=>{let s=(e.seq.aluVal<<8|e.regs.wz)&65535;e.regs.wz=s,e.regs.pc=s;};function cn(e){return {s:(e&128)!==0,z:(e&64)!==0,x5:(e&32)!==0,h:(e&16)!==0,x3:(e&8)!==0,pv:(e&4)!==0,n:(e&2)!==0,c:(e&1)!==0}}function Ne(e,s={main:{},alt:{}}){let t=e.regs.file,f=e.regs.f,a=e.seq.prefix&7,x=a&2,C=x?e.seq.exDe0:e.seq.exDe1,b=n[a],F=n[a&1|x^2|C],c=n[a^1],g=s;return g.pc=e.regs.pc,g.sp=e.regs.sp,g.ix=t[B]<<8|t[S],g.iy=t[v]<<8|t[P],g.i=e.regs.i,g.r=e.regs.r&127|e.regs.r7,g.wz=e.regs.wz,g.main.b=t[b[0]],g.main.c=t[b[1]],g.main.d=t[b[2]],g.main.e=t[b[3]],g.main.h=t[b[4]],g.main.l=t[b[5]],g.main.a=t[b[7]],g.main.f=f[a&1],g.alt.b=t[F[0]],g.alt.c=t[F[1]],g.alt.d=t[F[2]],g.alt.e=t[F[3]],g.alt.h=t[F[4]],g.alt.l=t[F[5]],g.alt.a=t[c[7]],g.alt.f=f[a&1^1],g.im=e.ctl.imFa===0?0:e.ctl.imFb===0?1:2,g.imUndocumented=e.ctl.imFa===0&&e.ctl.imFb!==0,g.iff1=!!e.ctl.iff1,g.iff2=!!e.ctl.iff2,g.nmiPending=!!e.ctl.nmiFf,g}var h=0,k=1,O=2,L=3,_=4,q=5,o=7,z=8,W=9,U=10,X=11,j=12,Y=13,I=15,B=20,S=21,v=28,P=29,n=[[h,k,O,L,_,q,6,o],[h,k,O,L,_,q,6,I],[z,W,U,X,j,Y,6,o],[z,W,U,X,j,Y,6,I],[h,k,_,q,O,L,6,o],[h,k,_,q,O,L,6,I],[z,W,j,Y,U,X,6,o],[z,W,j,Y,U,X,6,I],[h,k,O,L,B,S,-1,o],[h,k,O,L,B,S,-1,I],[z,W,U,X,B,S,-1,o],[z,W,U,X,B,S,-1,I],[h,k,_,q,B,S,-1,o],[h,k,_,q,B,S,-1,I],[z,W,j,Y,B,S,-1,o],[z,W,j,Y,B,S,-1,I],[h,k,O,L,v,P,-1,o],[h,k,O,L,v,P,-1,I],[z,W,U,X,v,P,-1,o],[z,W,U,X,v,P,-1,I],[h,k,_,q,v,P,-1,o],[h,k,_,q,v,P,-1,I],[z,W,j,Y,v,P,-1,o],[z,W,j,Y,v,P,-1,I]],De=class{file=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];f=[0,0];sp=0;pc=0;i=0;r=0;r7=0;wz=0},Ve=class{addr=0;data=void 0;nM1=1;nMREQ=1;nIORQ=1;nRD=1;nWR=1;nRFSH=1;nHALT=1;nBUSACK=1;nRESET=1;nINT=1;nWAIT=1;nBUSRQ=1},we=class{op=0;y=0;z=0;executor=w;hasMoreMCycles=false;hasExtraT=false;mAddr=0;aluDst=void 0;aluVal=0;aluF=void 0;aluFMask=0;fWritten=false;cbFf=0;edFf=0;m1T2Exec=w;prefix=0;exDe0=0;exDe1=0;lastOpTState=false;phase=true},ze=class{skipInts=false;iff1=0;iff2=0;intFf=false;nmiFf=false;nmiAck=false;imFa=0;imFb=0;haltLatch=false;resi=false;nres=false;sres=false;throwAwayM1=false;qres=false;resetAtT1=false;busrqFf=false;busGrantResume=void 0},We=class{regs=new De;bus=new Ve;seq=new we;ctl=new ze;next=D;get nextStep(){return this.next.id}clockEdge(){if(this.seq.phase=!this.seq.phase,!this.seq.phase)this.ctl.resi=!this.bus.nRESET;else if(this.ctl.nres)this.next=oe;else if(this.ctl.resi&&!(this.nextStep===3||this.nextStep===57||this.nextStep===62)){this.ctl.nres=true,this.ctl.sres=false;let s=this.nextStep;this.ctl.resetAtT1=s===1||s===55||s===60,this.ctl.iff1=0,this.ctl.iff2=0,this.ctl.imFa=0,this.ctl.imFb=0,this.seq.cbFf=0,this.seq.edFf=0,this.bus.nHALT=1;}this.next(this);}nmi(){this.ctl.nmiAck||(this.ctl.nmiFf=true);}snapshot(s){return Ne(this,s)}};export{o as A,I as A_,h as B,z as B_,k as C,W as C_,O as D,U as D_,L as E,X as E_,_ as H,j as H_,B as IXH,S as IXL,v as IYH,P as IYL,q as L,Y as L_,le as StepId,We as Z80Cpu,cn as decodeFlags,Ne as snapshotCpu};
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dcorp80/z80cpu",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The hardware-accurate Z80 CPU emulator",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"z80",
|
|
7
|
+
"zilog",
|
|
8
|
+
"cpu",
|
|
9
|
+
"emulator",
|
|
10
|
+
"z80-emulator",
|
|
11
|
+
"zx-spectrum",
|
|
12
|
+
"retrocomputing",
|
|
13
|
+
"emulation",
|
|
14
|
+
"8-bit",
|
|
15
|
+
"typescript",
|
|
16
|
+
"javascript",
|
|
17
|
+
"browser",
|
|
18
|
+
"cycle-accurate",
|
|
19
|
+
"hardware-emulation"
|
|
20
|
+
],
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/dcorp80/z80cpu-lab/issues"
|
|
23
|
+
},
|
|
24
|
+
"license": "Apache-2.0",
|
|
25
|
+
"author": "dcorp80",
|
|
26
|
+
"type": "module",
|
|
27
|
+
"sideEffects": false,
|
|
28
|
+
"main": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"exports": {
|
|
31
|
+
".": {
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"files": [
|
|
37
|
+
"dist",
|
|
38
|
+
"NOTICE"
|
|
39
|
+
],
|
|
40
|
+
"publishConfig": {
|
|
41
|
+
"access": "public"
|
|
42
|
+
}
|
|
43
|
+
}
|