@joezilla/8sim 0.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +542 -0
  3. package/dist/8sim.browser.js +4728 -0
  4. package/dist/bundles/CardBundle.d.ts +83 -0
  5. package/dist/bundles/CardBundle.d.ts.map +1 -0
  6. package/dist/bundles/CardBundle.js +41 -0
  7. package/dist/bundles/CardBundle.js.map +1 -0
  8. package/dist/bundles/kernels.d.ts +48 -0
  9. package/dist/bundles/kernels.d.ts.map +1 -0
  10. package/dist/bundles/kernels.js +132 -0
  11. package/dist/bundles/kernels.js.map +1 -0
  12. package/dist/bundles/seed/index.d.ts +24 -0
  13. package/dist/bundles/seed/index.d.ts.map +1 -0
  14. package/dist/bundles/seed/index.js +266 -0
  15. package/dist/bundles/seed/index.js.map +1 -0
  16. package/dist/bus/Bus.d.ts +21 -0
  17. package/dist/bus/Bus.d.ts.map +1 -0
  18. package/dist/bus/Bus.js +62 -0
  19. package/dist/bus/Bus.js.map +1 -0
  20. package/dist/bus/BusRegion.d.ts +8 -0
  21. package/dist/bus/BusRegion.d.ts.map +1 -0
  22. package/dist/bus/BusRegion.js +8 -0
  23. package/dist/bus/BusRegion.js.map +1 -0
  24. package/dist/bus/SnoopBus.d.ts +15 -0
  25. package/dist/bus/SnoopBus.d.ts.map +1 -0
  26. package/dist/bus/SnoopBus.js +41 -0
  27. package/dist/bus/SnoopBus.js.map +1 -0
  28. package/dist/cards/BankRamCard.d.ts +35 -0
  29. package/dist/cards/BankRamCard.d.ts.map +1 -0
  30. package/dist/cards/BankRamCard.js +56 -0
  31. package/dist/cards/BankRamCard.js.map +1 -0
  32. package/dist/cards/DazzlerCard.d.ts +42 -0
  33. package/dist/cards/DazzlerCard.d.ts.map +1 -0
  34. package/dist/cards/DazzlerCard.js +83 -0
  35. package/dist/cards/DazzlerCard.js.map +1 -0
  36. package/dist/cards/DisplaySurface.d.ts +32 -0
  37. package/dist/cards/DisplaySurface.d.ts.map +1 -0
  38. package/dist/cards/DisplaySurface.js +11 -0
  39. package/dist/cards/DisplaySurface.js.map +1 -0
  40. package/dist/cards/FdcPlusClient.d.ts +35 -0
  41. package/dist/cards/FdcPlusClient.d.ts.map +1 -0
  42. package/dist/cards/FdcPlusClient.js +130 -0
  43. package/dist/cards/FdcPlusClient.js.map +1 -0
  44. package/dist/cards/ImsaiMioCard.d.ts +36 -0
  45. package/dist/cards/ImsaiMioCard.d.ts.map +1 -0
  46. package/dist/cards/ImsaiMioCard.js +48 -0
  47. package/dist/cards/ImsaiMioCard.js.map +1 -0
  48. package/dist/cards/ImsaiSioCard.d.ts +19 -0
  49. package/dist/cards/ImsaiSioCard.d.ts.map +1 -0
  50. package/dist/cards/ImsaiSioCard.js +54 -0
  51. package/dist/cards/ImsaiSioCard.js.map +1 -0
  52. package/dist/cards/KeyboardCard.d.ts +37 -0
  53. package/dist/cards/KeyboardCard.d.ts.map +1 -0
  54. package/dist/cards/KeyboardCard.js +79 -0
  55. package/dist/cards/KeyboardCard.js.map +1 -0
  56. package/dist/cards/Mc6850Acia.d.ts +68 -0
  57. package/dist/cards/Mc6850Acia.d.ts.map +1 -0
  58. package/dist/cards/Mc6850Acia.js +132 -0
  59. package/dist/cards/Mc6850Acia.js.map +1 -0
  60. package/dist/cards/Mits2SioCard.d.ts +27 -0
  61. package/dist/cards/Mits2SioCard.d.ts.map +1 -0
  62. package/dist/cards/Mits2SioCard.js +36 -0
  63. package/dist/cards/Mits2SioCard.js.map +1 -0
  64. package/dist/cards/MitsDcddCard.d.ts +52 -0
  65. package/dist/cards/MitsDcddCard.d.ts.map +1 -0
  66. package/dist/cards/MitsDcddCard.js +294 -0
  67. package/dist/cards/MitsDcddCard.js.map +1 -0
  68. package/dist/cards/ParallelCard.d.ts +35 -0
  69. package/dist/cards/ParallelCard.d.ts.map +1 -0
  70. package/dist/cards/ParallelCard.js +32 -0
  71. package/dist/cards/ParallelCard.js.map +1 -0
  72. package/dist/cards/Port8212.d.ts +31 -0
  73. package/dist/cards/Port8212.d.ts.map +1 -0
  74. package/dist/cards/Port8212.js +47 -0
  75. package/dist/cards/Port8212.js.map +1 -0
  76. package/dist/cards/RtcCard.d.ts +30 -0
  77. package/dist/cards/RtcCard.d.ts.map +1 -0
  78. package/dist/cards/RtcCard.js +61 -0
  79. package/dist/cards/RtcCard.js.map +1 -0
  80. package/dist/cards/SerialCard.d.ts +31 -0
  81. package/dist/cards/SerialCard.d.ts.map +1 -0
  82. package/dist/cards/SerialCard.js +28 -0
  83. package/dist/cards/SerialCard.js.map +1 -0
  84. package/dist/cards/Tr1602Uart.d.ts +55 -0
  85. package/dist/cards/Tr1602Uart.d.ts.map +1 -0
  86. package/dist/cards/Tr1602Uart.js +102 -0
  87. package/dist/cards/Tr1602Uart.js.map +1 -0
  88. package/dist/cards/Usart8251.d.ts +28 -0
  89. package/dist/cards/Usart8251.d.ts.map +1 -0
  90. package/dist/cards/Usart8251.js +88 -0
  91. package/dist/cards/Usart8251.js.map +1 -0
  92. package/dist/cards/VdmCard.d.ts +27 -0
  93. package/dist/cards/VdmCard.d.ts.map +1 -0
  94. package/dist/cards/VdmCard.js +40 -0
  95. package/dist/cards/VdmCard.js.map +1 -0
  96. package/dist/clock/ImmediateClock.d.ts +8 -0
  97. package/dist/clock/ImmediateClock.d.ts.map +1 -0
  98. package/dist/clock/ImmediateClock.js +13 -0
  99. package/dist/clock/ImmediateClock.js.map +1 -0
  100. package/dist/clock/SystemClock.d.ts +45 -0
  101. package/dist/clock/SystemClock.d.ts.map +1 -0
  102. package/dist/clock/SystemClock.js +71 -0
  103. package/dist/clock/SystemClock.js.map +1 -0
  104. package/dist/cpu/Cpu8080.d.ts +34 -0
  105. package/dist/cpu/Cpu8080.d.ts.map +1 -0
  106. package/dist/cpu/Cpu8080.js +126 -0
  107. package/dist/cpu/Cpu8080.js.map +1 -0
  108. package/dist/cpu/Decoder.d.ts +12 -0
  109. package/dist/cpu/Decoder.d.ts.map +1 -0
  110. package/dist/cpu/Decoder.js +23 -0
  111. package/dist/cpu/Decoder.js.map +1 -0
  112. package/dist/cpu/Flags.d.ts +18 -0
  113. package/dist/cpu/Flags.d.ts.map +1 -0
  114. package/dist/cpu/Flags.js +33 -0
  115. package/dist/cpu/Flags.js.map +1 -0
  116. package/dist/cpu/Registers.d.ts +22 -0
  117. package/dist/cpu/Registers.d.ts.map +1 -0
  118. package/dist/cpu/Registers.js +26 -0
  119. package/dist/cpu/Registers.js.map +1 -0
  120. package/dist/cpu/instructions/alu.d.ts +3 -0
  121. package/dist/cpu/instructions/alu.d.ts.map +1 -0
  122. package/dist/cpu/instructions/alu.js +221 -0
  123. package/dist/cpu/instructions/alu.js.map +1 -0
  124. package/dist/cpu/instructions/branch.d.ts +3 -0
  125. package/dist/cpu/instructions/branch.d.ts.map +1 -0
  126. package/dist/cpu/instructions/branch.js +117 -0
  127. package/dist/cpu/instructions/branch.js.map +1 -0
  128. package/dist/cpu/instructions/control.d.ts +3 -0
  129. package/dist/cpu/instructions/control.d.ts.map +1 -0
  130. package/dist/cpu/instructions/control.js +12 -0
  131. package/dist/cpu/instructions/control.js.map +1 -0
  132. package/dist/cpu/instructions/data.d.ts +3 -0
  133. package/dist/cpu/instructions/data.d.ts.map +1 -0
  134. package/dist/cpu/instructions/data.js +137 -0
  135. package/dist/cpu/instructions/data.js.map +1 -0
  136. package/dist/cpu/instructions/io.d.ts +3 -0
  137. package/dist/cpu/instructions/io.d.ts.map +1 -0
  138. package/dist/cpu/instructions/io.js +18 -0
  139. package/dist/cpu/instructions/io.js.map +1 -0
  140. package/dist/cpu/instructions/logical.d.ts +3 -0
  141. package/dist/cpu/instructions/logical.d.ts.map +1 -0
  142. package/dist/cpu/instructions/logical.js +129 -0
  143. package/dist/cpu/instructions/logical.js.map +1 -0
  144. package/dist/cpu/instructions/rotate.d.ts +3 -0
  145. package/dist/cpu/instructions/rotate.d.ts.map +1 -0
  146. package/dist/cpu/instructions/rotate.js +34 -0
  147. package/dist/cpu/instructions/rotate.js.map +1 -0
  148. package/dist/cpu/instructions/stack.d.ts +3 -0
  149. package/dist/cpu/instructions/stack.d.ts.map +1 -0
  150. package/dist/cpu/instructions/stack.js +84 -0
  151. package/dist/cpu/instructions/stack.js.map +1 -0
  152. package/dist/cpu/status8080.d.ts +33 -0
  153. package/dist/cpu/status8080.d.ts.map +1 -0
  154. package/dist/cpu/status8080.js +73 -0
  155. package/dist/cpu/status8080.js.map +1 -0
  156. package/dist/cpu/z80/CpuZ80.d.ts +53 -0
  157. package/dist/cpu/z80/CpuZ80.d.ts.map +1 -0
  158. package/dist/cpu/z80/CpuZ80.js +168 -0
  159. package/dist/cpu/z80/CpuZ80.js.map +1 -0
  160. package/dist/cpu/z80/DecoderZ80.d.ts +26 -0
  161. package/dist/cpu/z80/DecoderZ80.d.ts.map +1 -0
  162. package/dist/cpu/z80/DecoderZ80.js +107 -0
  163. package/dist/cpu/z80/DecoderZ80.js.map +1 -0
  164. package/dist/cpu/z80/FlagsZ80.d.ts +27 -0
  165. package/dist/cpu/z80/FlagsZ80.d.ts.map +1 -0
  166. package/dist/cpu/z80/FlagsZ80.js +47 -0
  167. package/dist/cpu/z80/FlagsZ80.js.map +1 -0
  168. package/dist/cpu/z80/RegistersZ80.d.ts +60 -0
  169. package/dist/cpu/z80/RegistersZ80.d.ts.map +1 -0
  170. package/dist/cpu/z80/RegistersZ80.js +90 -0
  171. package/dist/cpu/z80/RegistersZ80.js.map +1 -0
  172. package/dist/cpu/z80/flagHelpers.d.ts +25 -0
  173. package/dist/cpu/z80/flagHelpers.d.ts.map +1 -0
  174. package/dist/cpu/z80/flagHelpers.js +136 -0
  175. package/dist/cpu/z80/flagHelpers.js.map +1 -0
  176. package/dist/cpu/z80/instructions/alu16.d.ts +4 -0
  177. package/dist/cpu/z80/instructions/alu16.d.ts.map +1 -0
  178. package/dist/cpu/z80/instructions/alu16.js +27 -0
  179. package/dist/cpu/z80/instructions/alu16.js.map +1 -0
  180. package/dist/cpu/z80/instructions/alu8.d.ts +4 -0
  181. package/dist/cpu/z80/instructions/alu8.d.ts.map +1 -0
  182. package/dist/cpu/z80/instructions/alu8.js +100 -0
  183. package/dist/cpu/z80/instructions/alu8.js.map +1 -0
  184. package/dist/cpu/z80/instructions/bits.d.ts +10 -0
  185. package/dist/cpu/z80/instructions/bits.d.ts.map +1 -0
  186. package/dist/cpu/z80/instructions/bits.js +164 -0
  187. package/dist/cpu/z80/instructions/bits.js.map +1 -0
  188. package/dist/cpu/z80/instructions/block.d.ts +10 -0
  189. package/dist/cpu/z80/instructions/block.d.ts.map +1 -0
  190. package/dist/cpu/z80/instructions/block.js +141 -0
  191. package/dist/cpu/z80/instructions/block.js.map +1 -0
  192. package/dist/cpu/z80/instructions/control.d.ts +4 -0
  193. package/dist/cpu/z80/instructions/control.d.ts.map +1 -0
  194. package/dist/cpu/z80/instructions/control.js +62 -0
  195. package/dist/cpu/z80/instructions/control.js.map +1 -0
  196. package/dist/cpu/z80/instructions/ed.d.ts +4 -0
  197. package/dist/cpu/z80/instructions/ed.d.ts.map +1 -0
  198. package/dist/cpu/z80/instructions/ed.js +149 -0
  199. package/dist/cpu/z80/instructions/ed.js.map +1 -0
  200. package/dist/cpu/z80/instructions/exchange.d.ts +4 -0
  201. package/dist/cpu/z80/instructions/exchange.d.ts.map +1 -0
  202. package/dist/cpu/z80/instructions/exchange.js +37 -0
  203. package/dist/cpu/z80/instructions/exchange.js.map +1 -0
  204. package/dist/cpu/z80/instructions/io.d.ts +8 -0
  205. package/dist/cpu/z80/instructions/io.d.ts.map +1 -0
  206. package/dist/cpu/z80/instructions/io.js +22 -0
  207. package/dist/cpu/z80/instructions/io.js.map +1 -0
  208. package/dist/cpu/z80/instructions/jump.d.ts +4 -0
  209. package/dist/cpu/z80/instructions/jump.d.ts.map +1 -0
  210. package/dist/cpu/z80/instructions/jump.js +113 -0
  211. package/dist/cpu/z80/instructions/jump.js.map +1 -0
  212. package/dist/cpu/z80/instructions/load.d.ts +7 -0
  213. package/dist/cpu/z80/instructions/load.d.ts.map +1 -0
  214. package/dist/cpu/z80/instructions/load.js +103 -0
  215. package/dist/cpu/z80/instructions/load.js.map +1 -0
  216. package/dist/cpu/z80/instructions/rotate.d.ts +9 -0
  217. package/dist/cpu/z80/instructions/rotate.d.ts.map +1 -0
  218. package/dist/cpu/z80/instructions/rotate.js +48 -0
  219. package/dist/cpu/z80/instructions/rotate.js.map +1 -0
  220. package/dist/cpu/z80/instructions/stack.d.ts +4 -0
  221. package/dist/cpu/z80/instructions/stack.d.ts.map +1 -0
  222. package/dist/cpu/z80/instructions/stack.js +19 -0
  223. package/dist/cpu/z80/instructions/stack.js.map +1 -0
  224. package/dist/cpu/z80/regcodes.d.ts +22 -0
  225. package/dist/cpu/z80/regcodes.d.ts.map +1 -0
  226. package/dist/cpu/z80/regcodes.js +93 -0
  227. package/dist/cpu/z80/regcodes.js.map +1 -0
  228. package/dist/cpu/z80/types.d.ts +59 -0
  229. package/dist/cpu/z80/types.d.ts.map +1 -0
  230. package/dist/cpu/z80/types.js +2 -0
  231. package/dist/cpu/z80/types.js.map +1 -0
  232. package/dist/cpu/z80/views.d.ts +8 -0
  233. package/dist/cpu/z80/views.d.ts.map +1 -0
  234. package/dist/cpu/z80/views.js +40 -0
  235. package/dist/cpu/z80/views.js.map +1 -0
  236. package/dist/index.d.ts +67 -0
  237. package/dist/index.d.ts.map +1 -0
  238. package/dist/index.js +49 -0
  239. package/dist/index.js.map +1 -0
  240. package/dist/interfaces/IBus.d.ts +8 -0
  241. package/dist/interfaces/IBus.d.ts.map +1 -0
  242. package/dist/interfaces/IBus.js +2 -0
  243. package/dist/interfaces/IBus.js.map +1 -0
  244. package/dist/interfaces/IBusObserver.d.ts +7 -0
  245. package/dist/interfaces/IBusObserver.d.ts.map +1 -0
  246. package/dist/interfaces/IBusObserver.js +2 -0
  247. package/dist/interfaces/IBusObserver.js.map +1 -0
  248. package/dist/interfaces/IClock.d.ts +6 -0
  249. package/dist/interfaces/IClock.d.ts.map +1 -0
  250. package/dist/interfaces/IClock.js +2 -0
  251. package/dist/interfaces/IClock.js.map +1 -0
  252. package/dist/interfaces/ICpu.d.ts +46 -0
  253. package/dist/interfaces/ICpu.d.ts.map +1 -0
  254. package/dist/interfaces/ICpu.js +2 -0
  255. package/dist/interfaces/ICpu.js.map +1 -0
  256. package/dist/interfaces/IIODevice.d.ts +7 -0
  257. package/dist/interfaces/IIODevice.d.ts.map +1 -0
  258. package/dist/interfaces/IIODevice.js +2 -0
  259. package/dist/interfaces/IIODevice.js.map +1 -0
  260. package/dist/interfaces/IInterruptController.d.ts +8 -0
  261. package/dist/interfaces/IInterruptController.d.ts.map +1 -0
  262. package/dist/interfaces/IInterruptController.js +2 -0
  263. package/dist/interfaces/IInterruptController.js.map +1 -0
  264. package/dist/interfaces/IMemory.d.ts +9 -0
  265. package/dist/interfaces/IMemory.d.ts.map +1 -0
  266. package/dist/interfaces/IMemory.js +2 -0
  267. package/dist/interfaces/IMemory.js.map +1 -0
  268. package/dist/interfaces/IModule.d.ts +5 -0
  269. package/dist/interfaces/IModule.d.ts.map +1 -0
  270. package/dist/interfaces/IModule.js +2 -0
  271. package/dist/interfaces/IModule.js.map +1 -0
  272. package/dist/interfaces/IS100Card.d.ts +6 -0
  273. package/dist/interfaces/IS100Card.d.ts.map +1 -0
  274. package/dist/interfaces/IS100Card.js +2 -0
  275. package/dist/interfaces/IS100Card.js.map +1 -0
  276. package/dist/interfaces/index.d.ts +10 -0
  277. package/dist/interfaces/index.d.ts.map +1 -0
  278. package/dist/interfaces/index.js +2 -0
  279. package/dist/interfaces/index.js.map +1 -0
  280. package/dist/interrupt/InterruptController.d.ts +13 -0
  281. package/dist/interrupt/InterruptController.d.ts.map +1 -0
  282. package/dist/interrupt/InterruptController.js +36 -0
  283. package/dist/interrupt/InterruptController.js.map +1 -0
  284. package/dist/io/IoSpace.d.ts +9 -0
  285. package/dist/io/IoSpace.d.ts.map +1 -0
  286. package/dist/io/IoSpace.js +30 -0
  287. package/dist/io/IoSpace.js.map +1 -0
  288. package/dist/machine/MachineRunner.d.ts +54 -0
  289. package/dist/machine/MachineRunner.d.ts.map +1 -0
  290. package/dist/machine/MachineRunner.js +102 -0
  291. package/dist/machine/MachineRunner.js.map +1 -0
  292. package/dist/machine/MachineSpec.d.ts +80 -0
  293. package/dist/machine/MachineSpec.d.ts.map +1 -0
  294. package/dist/machine/MachineSpec.js +9 -0
  295. package/dist/machine/MachineSpec.js.map +1 -0
  296. package/dist/machine/buildMachine.d.ts +19 -0
  297. package/dist/machine/buildMachine.d.ts.map +1 -0
  298. package/dist/machine/buildMachine.js +122 -0
  299. package/dist/machine/buildMachine.js.map +1 -0
  300. package/dist/memory/MemoryMappedIOAdapter.d.ts +14 -0
  301. package/dist/memory/MemoryMappedIOAdapter.d.ts.map +1 -0
  302. package/dist/memory/MemoryMappedIOAdapter.js +23 -0
  303. package/dist/memory/MemoryMappedIOAdapter.js.map +1 -0
  304. package/dist/memory/Ram.d.ts +17 -0
  305. package/dist/memory/Ram.d.ts.map +1 -0
  306. package/dist/memory/Ram.js +36 -0
  307. package/dist/memory/Ram.js.map +1 -0
  308. package/dist/memory/Rom.d.ts +13 -0
  309. package/dist/memory/Rom.d.ts.map +1 -0
  310. package/dist/memory/Rom.js +25 -0
  311. package/dist/memory/Rom.js.map +1 -0
  312. package/dist/util/bits.d.ts +11 -0
  313. package/dist/util/bits.d.ts.map +1 -0
  314. package/dist/util/bits.js +35 -0
  315. package/dist/util/bits.js.map +1 -0
  316. package/dist/util/hostConsole.d.ts +2 -0
  317. package/dist/util/hostConsole.d.ts.map +1 -0
  318. package/dist/util/hostConsole.js +4 -0
  319. package/dist/util/hostConsole.js.map +1 -0
  320. package/package.json +39 -0
@@ -0,0 +1,84 @@
1
+ import { u16 } from '../../util/bits.js';
2
+ export function registerStack(decoder) {
3
+ // PUSH B (0xC5)
4
+ decoder.register(0xc5, (regs, _flags, bus) => {
5
+ regs.sp = u16(regs.sp - 1);
6
+ bus.write(regs.sp, regs.b);
7
+ regs.sp = u16(regs.sp - 1);
8
+ bus.write(regs.sp, regs.c);
9
+ return 11;
10
+ });
11
+ // PUSH D (0xD5)
12
+ decoder.register(0xd5, (regs, _flags, bus) => {
13
+ regs.sp = u16(regs.sp - 1);
14
+ bus.write(regs.sp, regs.d);
15
+ regs.sp = u16(regs.sp - 1);
16
+ bus.write(regs.sp, regs.e);
17
+ return 11;
18
+ });
19
+ // PUSH H (0xE5)
20
+ decoder.register(0xe5, (regs, _flags, bus) => {
21
+ regs.sp = u16(regs.sp - 1);
22
+ bus.write(regs.sp, regs.h);
23
+ regs.sp = u16(regs.sp - 1);
24
+ bus.write(regs.sp, regs.l);
25
+ return 11;
26
+ });
27
+ // PUSH PSW (0xF5) — A and Flags
28
+ decoder.register(0xf5, (regs, flags, bus) => {
29
+ regs.sp = u16(regs.sp - 1);
30
+ bus.write(regs.sp, regs.a);
31
+ regs.sp = u16(regs.sp - 1);
32
+ bus.write(regs.sp, flags.toByte());
33
+ return 11;
34
+ });
35
+ // POP B (0xC1)
36
+ decoder.register(0xc1, (regs, _flags, bus) => {
37
+ regs.c = bus.read(regs.sp);
38
+ regs.sp = u16(regs.sp + 1);
39
+ regs.b = bus.read(regs.sp);
40
+ regs.sp = u16(regs.sp + 1);
41
+ return 10;
42
+ });
43
+ // POP D (0xD1)
44
+ decoder.register(0xd1, (regs, _flags, bus) => {
45
+ regs.e = bus.read(regs.sp);
46
+ regs.sp = u16(regs.sp + 1);
47
+ regs.d = bus.read(regs.sp);
48
+ regs.sp = u16(regs.sp + 1);
49
+ return 10;
50
+ });
51
+ // POP H (0xE1)
52
+ decoder.register(0xe1, (regs, _flags, bus) => {
53
+ regs.l = bus.read(regs.sp);
54
+ regs.sp = u16(regs.sp + 1);
55
+ regs.h = bus.read(regs.sp);
56
+ regs.sp = u16(regs.sp + 1);
57
+ return 10;
58
+ });
59
+ // POP PSW (0xF1) — A and Flags
60
+ decoder.register(0xf1, (regs, flags, bus) => {
61
+ const psw = bus.read(regs.sp);
62
+ regs.sp = u16(regs.sp + 1);
63
+ regs.a = bus.read(regs.sp);
64
+ regs.sp = u16(regs.sp + 1);
65
+ flags.fromByte(psw);
66
+ return 10;
67
+ });
68
+ // XTHL (0xE3) — Exchange top of stack with HL
69
+ decoder.register(0xe3, (regs, _flags, bus) => {
70
+ const lo = bus.read(regs.sp);
71
+ const hi = bus.read(u16(regs.sp + 1));
72
+ bus.write(regs.sp, regs.l);
73
+ bus.write(u16(regs.sp + 1), regs.h);
74
+ regs.l = lo;
75
+ regs.h = hi;
76
+ return 18;
77
+ });
78
+ // SPHL (0xF9) — SP = HL
79
+ decoder.register(0xf9, (regs, _flags, _bus) => {
80
+ regs.sp = regs.hl;
81
+ return 5;
82
+ });
83
+ }
84
+ //# sourceMappingURL=stack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../../src/cpu/instructions/stack.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * 8080 status word (Bitsby8 cockpit front panel).
3
+ *
4
+ * At the start of every machine cycle the 8080 emits a status byte on the data
5
+ * bus (latched by the 8228 at SYNC); the Altair front panel wires eight of these
6
+ * to lamps. 8sim executes a whole instruction per `step()`, so there is no single
7
+ * live machine cycle to reflect — instead we characterize the instruction from
8
+ * its opcode into one representative status byte. That's exactly what a debugger
9
+ * single-stepping wants: after each step the lamps show what that instruction
10
+ * did (fetch, memory read/write, IN/OUT, stack, halt).
11
+ *
12
+ * `WO` is active-low on real hardware (1 = read cycle, 0 = write); we keep that
13
+ * convention so the panel's WO lamp lights on reads, as on the Altair.
14
+ */
15
+ export declare const STATUS: {
16
+ readonly INTA: 1;
17
+ readonly WO: 2;
18
+ readonly STACK: 4;
19
+ readonly HLTA: 8;
20
+ readonly OUT: 16;
21
+ readonly M1: 32;
22
+ readonly INP: 64;
23
+ readonly MEMR: 128;
24
+ };
25
+ /** The status byte characterizing one opcode's machine cycles. */
26
+ export declare function statusByteForOpcode(op: number): number;
27
+ /** A 256-entry lookup so `step()` pays only one array read. */
28
+ export declare function buildStatusTable(): Uint8Array;
29
+ /** The status byte during an interrupt-acknowledge machine cycle. */
30
+ export declare const INTA_STATUS: number;
31
+ /** The idle/reset fetch pattern (about to fetch the first opcode). */
32
+ export declare const FETCH_STATUS: number;
33
+ //# sourceMappingURL=status8080.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status8080.d.ts","sourceRoot":"","sources":["../../src/cpu/status8080.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,MAAM;;;;;;;;;CAST,CAAC;AA4BX,kEAAkE;AAClE,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAStD;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,IAAI,UAAU,CAI7C;AAED,qEAAqE;AACrE,eAAO,MAAM,WAAW,QAAsC,CAAC;AAE/D,sEAAsE;AACtE,eAAO,MAAM,YAAY,QAAsC,CAAC"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * 8080 status word (Bitsby8 cockpit front panel).
3
+ *
4
+ * At the start of every machine cycle the 8080 emits a status byte on the data
5
+ * bus (latched by the 8228 at SYNC); the Altair front panel wires eight of these
6
+ * to lamps. 8sim executes a whole instruction per `step()`, so there is no single
7
+ * live machine cycle to reflect — instead we characterize the instruction from
8
+ * its opcode into one representative status byte. That's exactly what a debugger
9
+ * single-stepping wants: after each step the lamps show what that instruction
10
+ * did (fetch, memory read/write, IN/OUT, stack, halt).
11
+ *
12
+ * `WO` is active-low on real hardware (1 = read cycle, 0 = write); we keep that
13
+ * convention so the panel's WO lamp lights on reads, as on the Altair.
14
+ */
15
+ export const STATUS = {
16
+ INTA: 0x01, // interrupt acknowledge
17
+ WO: 0x02, // write/output — active LOW (set = a read cycle)
18
+ STACK: 0x04, // stack access
19
+ HLTA: 0x08, // halt acknowledge
20
+ OUT: 0x10, // output write
21
+ M1: 0x20, // first machine cycle (opcode fetch)
22
+ INP: 0x40, // input read
23
+ MEMR: 0x80, // memory read
24
+ };
25
+ const isRst = (op) => (op & 0xc7) === 0xc7; // 11 xxx 111
26
+ // PUSH / CALL (incl. conditional) / RST / XTHL push to the stack; plus the
27
+ // direct memory stores. These make the cycle a write (WO low).
28
+ const writesMemory = (op) => op === 0x32 || // STA
29
+ op === 0x22 || // SHLD
30
+ op === 0x02 || op === 0x12 || // STAX B/D
31
+ op === 0x36 || // MVI M,d8
32
+ (op >= 0x70 && op <= 0x77 && op !== 0x76) || // MOV M,r
33
+ op === 0xc5 || op === 0xd5 || op === 0xe5 || op === 0xf5 || // PUSH
34
+ op === 0xcd || op === 0xc4 || op === 0xcc || op === 0xd4 || op === 0xdc ||
35
+ op === 0xe4 || op === 0xec || op === 0xf4 || op === 0xfc || // CALL (all)
36
+ op === 0xe3 || // XTHL
37
+ isRst(op);
38
+ const touchesStack = (op) => op === 0xc5 || op === 0xd5 || op === 0xe5 || op === 0xf5 || // PUSH
39
+ op === 0xc1 || op === 0xd1 || op === 0xe1 || op === 0xf1 || // POP
40
+ op === 0xcd || op === 0xc4 || op === 0xcc || op === 0xd4 || op === 0xdc ||
41
+ op === 0xe4 || op === 0xec || op === 0xf4 || op === 0xfc || // CALL (all)
42
+ op === 0xc9 || op === 0xc0 || op === 0xc8 || op === 0xd0 || op === 0xd8 ||
43
+ op === 0xe0 || op === 0xe8 || op === 0xf0 || op === 0xf8 || // RET (all)
44
+ op === 0xe3 || // XTHL
45
+ isRst(op);
46
+ /** The status byte characterizing one opcode's machine cycles. */
47
+ export function statusByteForOpcode(op) {
48
+ // Every instruction begins with an M1 opcode fetch — a memory read.
49
+ let s = STATUS.M1 | STATUS.MEMR | STATUS.WO;
50
+ if (op === 0x76)
51
+ return s | STATUS.HLTA; // HLT
52
+ if (op === 0xdb)
53
+ s |= STATUS.INP; // IN port
54
+ if (op === 0xd3)
55
+ s = (s | STATUS.OUT) & ~STATUS.WO; // OUT port (a write cycle)
56
+ if (touchesStack(op))
57
+ s |= STATUS.STACK;
58
+ if (writesMemory(op))
59
+ s &= ~STATUS.WO; // a write cycle drives WO low
60
+ return s;
61
+ }
62
+ /** A 256-entry lookup so `step()` pays only one array read. */
63
+ export function buildStatusTable() {
64
+ const t = new Uint8Array(256);
65
+ for (let op = 0; op < 256; op++)
66
+ t[op] = statusByteForOpcode(op);
67
+ return t;
68
+ }
69
+ /** The status byte during an interrupt-acknowledge machine cycle. */
70
+ export const INTA_STATUS = STATUS.INTA | STATUS.M1 | STATUS.WO;
71
+ /** The idle/reset fetch pattern (about to fetch the first opcode). */
72
+ export const FETCH_STATUS = STATUS.M1 | STATUS.MEMR | STATUS.WO;
73
+ //# sourceMappingURL=status8080.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status8080.js","sourceRoot":"","sources":["../../src/cpu/status8080.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ import type { IBus } from '../../interfaces/IBus.js';
2
+ import type { ICpu, CpuState } from '../../interfaces/ICpu.js';
3
+ import type { IInterruptController } from '../../interfaces/IInterruptController.js';
4
+ import type { Z80Core } from './types.js';
5
+ import { RegistersZ80 } from './RegistersZ80.js';
6
+ import { FlagsZ80 } from './FlagsZ80.js';
7
+ /**
8
+ * Zilog Z80 CPU core. Fully implements the documented and undocumented
9
+ * instruction set, IM 0/1/2 + NMI interrupts, and the shadow/index register file.
10
+ *
11
+ * Interrupt conventions (no change to {@link IInterruptController} required):
12
+ * - IM 0: the byte from `acknowledge()` is executed as an opcode. The stock
13
+ * controller returns a single-byte RST, which is the common real-world case.
14
+ * - IM 2: the `acknowledge()` byte is used as the low half of the vector-table
15
+ * pointer (`(I << 8) | ackByte`); the vector is read from memory.
16
+ * A maskable interrupt is serviced only when IFF1 is set; NMI (via
17
+ * {@link triggerNMI}) is always serviced and ignores IFF1.
18
+ */
19
+ export declare class CpuZ80 implements ICpu, Z80Core {
20
+ readonly regs: RegistersZ80;
21
+ readonly flags: FlagsZ80;
22
+ readonly bus: IBus;
23
+ private readonly pic;
24
+ private readonly dec;
25
+ iff1: boolean;
26
+ iff2: boolean;
27
+ im: 0 | 1 | 2;
28
+ pendingEI: boolean;
29
+ halted: boolean;
30
+ private pendingNMI;
31
+ /** Front-panel status byte of the last instruction (8080-style approximation). */
32
+ private lastStatus;
33
+ private readonly statusTable;
34
+ constructor(bus: IBus, pic: IInterruptController);
35
+ /** Program counter accessor (ICpu). */
36
+ get pc(): number;
37
+ set pc(v: number);
38
+ /** Uniform register/flags snapshot for introspection (ICpu). */
39
+ state(): CpuState;
40
+ /** Assert a non-maskable interrupt (edge-triggered latch; serviced next step). */
41
+ triggerNMI(): void;
42
+ fetchByte(): number;
43
+ fetchWord(): number;
44
+ push16(v: number): void;
45
+ pop16(): number;
46
+ reset(): void;
47
+ step(): number;
48
+ private serviceINT;
49
+ private serviceNMI;
50
+ /** Run until halted or `maxCycles` T-states elapse; returns total T-states. */
51
+ run(maxCycles?: number): bigint;
52
+ }
53
+ //# sourceMappingURL=CpuZ80.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CpuZ80.d.ts","sourceRoot":"","sources":["../../../src/cpu/z80/CpuZ80.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAKzC;;;;;;;;;;;GAWG;AACH,qBAAa,MAAO,YAAW,IAAI,EAAE,OAAO;IAC1C,QAAQ,CAAC,IAAI,eAAsB;IACnC,QAAQ,CAAC,KAAK,WAAkB;IAChC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC;IACnB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuB;IAC3C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAa;IAEjC,IAAI,UAAS;IACb,IAAI,UAAS;IACb,EAAE,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAK;IAClB,SAAS,UAAS;IAClB,MAAM,UAAS;IACf,OAAO,CAAC,UAAU,CAAS;IAC3B,kFAAkF;IAClF,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsB;gBAEtC,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,oBAAoB;IAMhD,uCAAuC;IACvC,IAAI,EAAE,IAAI,MAAM,CAAyB;IACzC,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,EAA4B;IAE5C,gEAAgE;IAChE,KAAK,IAAI,QAAQ;IAKjB,kFAAkF;IAClF,UAAU,IAAI,IAAI;IAMlB,SAAS,IAAI,MAAM;IAMnB,SAAS,IAAI,MAAM;IAMnB,MAAM,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAOvB,KAAK,IAAI,MAAM;IAQf,KAAK,IAAI,IAAI;IAYb,IAAI,IAAI,MAAM;IAuCd,OAAO,CAAC,UAAU;IA8BlB,OAAO,CAAC,UAAU;IAWlB,+EAA+E;IAC/E,GAAG,CAAC,SAAS,SAAW,GAAG,MAAM;CAOlC"}
@@ -0,0 +1,168 @@
1
+ import { RegistersZ80 } from './RegistersZ80.js';
2
+ import { FlagsZ80 } from './FlagsZ80.js';
3
+ import { DecoderZ80 } from './DecoderZ80.js';
4
+ import { buildStatusTable, FETCH_STATUS, INTA_STATUS } from '../status8080.js';
5
+ import { u16 } from '../../util/bits.js';
6
+ /**
7
+ * Zilog Z80 CPU core. Fully implements the documented and undocumented
8
+ * instruction set, IM 0/1/2 + NMI interrupts, and the shadow/index register file.
9
+ *
10
+ * Interrupt conventions (no change to {@link IInterruptController} required):
11
+ * - IM 0: the byte from `acknowledge()` is executed as an opcode. The stock
12
+ * controller returns a single-byte RST, which is the common real-world case.
13
+ * - IM 2: the `acknowledge()` byte is used as the low half of the vector-table
14
+ * pointer (`(I << 8) | ackByte`); the vector is read from memory.
15
+ * A maskable interrupt is serviced only when IFF1 is set; NMI (via
16
+ * {@link triggerNMI}) is always serviced and ignores IFF1.
17
+ */
18
+ export class CpuZ80 {
19
+ regs = new RegistersZ80();
20
+ flags = new FlagsZ80();
21
+ bus;
22
+ pic;
23
+ dec;
24
+ iff1 = false;
25
+ iff2 = false;
26
+ im = 0;
27
+ pendingEI = false;
28
+ halted = false;
29
+ pendingNMI = false;
30
+ /** Front-panel status byte of the last instruction (8080-style approximation). */
31
+ lastStatus = FETCH_STATUS;
32
+ statusTable = buildStatusTable();
33
+ constructor(bus, pic) {
34
+ this.bus = bus;
35
+ this.pic = pic;
36
+ this.dec = new DecoderZ80();
37
+ }
38
+ /** Program counter accessor (ICpu). */
39
+ get pc() { return this.regs.pc; }
40
+ set pc(v) { this.regs.pc = u16(v); }
41
+ /** Uniform register/flags snapshot for introspection (ICpu). */
42
+ state() {
43
+ const r = this.regs;
44
+ return { pc: r.pc, sp: r.sp, a: r.a, f: this.flags.toByte(), b: r.b, c: r.c, d: r.d, e: r.e, h: r.h, l: r.l, halted: this.halted, inte: this.iff1, intPending: this.pic.hasPendingInterrupt(), status: this.lastStatus };
45
+ }
46
+ /** Assert a non-maskable interrupt (edge-triggered latch; serviced next step). */
47
+ triggerNMI() {
48
+ this.pendingNMI = true;
49
+ }
50
+ // --- Z80Core memory/stack helpers ---
51
+ fetchByte() {
52
+ const b = this.bus.read(this.regs.pc);
53
+ this.regs.pc = u16(this.regs.pc + 1);
54
+ return b;
55
+ }
56
+ fetchWord() {
57
+ const lo = this.fetchByte();
58
+ const hi = this.fetchByte();
59
+ return (hi << 8) | lo;
60
+ }
61
+ push16(v) {
62
+ this.regs.sp = u16(this.regs.sp - 1);
63
+ this.bus.write(this.regs.sp, (v >> 8) & 0xff);
64
+ this.regs.sp = u16(this.regs.sp - 1);
65
+ this.bus.write(this.regs.sp, v & 0xff);
66
+ }
67
+ pop16() {
68
+ const lo = this.bus.read(this.regs.sp);
69
+ this.regs.sp = u16(this.regs.sp + 1);
70
+ const hi = this.bus.read(this.regs.sp);
71
+ this.regs.sp = u16(this.regs.sp + 1);
72
+ return (hi << 8) | lo;
73
+ }
74
+ reset() {
75
+ this.regs.reset();
76
+ this.flags.reset();
77
+ this.iff1 = false;
78
+ this.iff2 = false;
79
+ this.im = 0;
80
+ this.pendingEI = false;
81
+ this.halted = false;
82
+ this.pendingNMI = false;
83
+ this.lastStatus = FETCH_STATUS;
84
+ }
85
+ step() {
86
+ // 1. NMI has top priority; it wakes HALT and ignores IFF1.
87
+ if (this.pendingNMI)
88
+ return this.serviceNMI();
89
+ // 2. Commit a pending EI: the instruction after EI is the first that can be
90
+ // interrupted, so remember whether the commit happened *this* step.
91
+ const eiJustCommitted = this.pendingEI;
92
+ if (this.pendingEI) {
93
+ this.iff1 = true;
94
+ this.iff2 = true;
95
+ this.pendingEI = false;
96
+ }
97
+ // 3. Maskable interrupt (not on the very step EI committed).
98
+ if (this.iff1 && !eiJustCommitted && this.pic.hasPendingInterrupt()) {
99
+ return this.serviceINT();
100
+ }
101
+ // 4. HALT executes internal NOPs; refresh keeps ticking.
102
+ if (this.halted) {
103
+ this.regs.incR();
104
+ return 4;
105
+ }
106
+ // 5. Fetch opcode, absorbing any DD/FD prefix chain.
107
+ let op = this.fetchByte();
108
+ this.regs.incR();
109
+ let table = this.dec.main;
110
+ let prefixT = 0;
111
+ while (op === 0xdd || op === 0xfd) {
112
+ table = op === 0xdd ? this.dec.mainIX : this.dec.mainIY;
113
+ prefixT += 4;
114
+ op = this.fetchByte();
115
+ this.regs.incR();
116
+ }
117
+ this.lastStatus = this.statusTable[op]; // latch the panel status byte
118
+ return prefixT + table[op](this);
119
+ }
120
+ serviceINT() {
121
+ this.iff1 = false;
122
+ this.iff2 = false;
123
+ this.halted = false;
124
+ this.lastStatus = INTA_STATUS;
125
+ this.regs.incR();
126
+ const ackByte = this.bus.acknowledgeInterrupt();
127
+ switch (this.im) {
128
+ case 0: {
129
+ // Execute the ack byte as an opcode (PC not advanced for this fetch).
130
+ // The stock controller returns a single-byte RST n.
131
+ return 2 + this.dec.main[ackByte & 0xff](this);
132
+ }
133
+ case 1:
134
+ this.push16(this.regs.pc);
135
+ this.regs.pc = 0x0038;
136
+ this.regs.wz = 0x0038;
137
+ return 13;
138
+ case 2: {
139
+ const vector = ((this.regs.i << 8) | (ackByte & 0xff)) & 0xffff;
140
+ this.push16(this.regs.pc);
141
+ const lo = this.bus.read(vector);
142
+ const hi = this.bus.read(u16(vector + 1));
143
+ this.regs.pc = (hi << 8) | lo;
144
+ this.regs.wz = this.regs.pc;
145
+ return 19;
146
+ }
147
+ }
148
+ }
149
+ serviceNMI() {
150
+ this.pendingNMI = false;
151
+ this.halted = false;
152
+ this.iff1 = false; // IFF2 preserved so RETN can restore IFF1
153
+ this.regs.incR();
154
+ this.push16(this.regs.pc);
155
+ this.regs.pc = 0x0066;
156
+ this.regs.wz = 0x0066;
157
+ return 11;
158
+ }
159
+ /** Run until halted or `maxCycles` T-states elapse; returns total T-states. */
160
+ run(maxCycles = Infinity) {
161
+ let total = 0n;
162
+ while (!this.halted && total < BigInt(maxCycles)) {
163
+ total += BigInt(this.step());
164
+ }
165
+ return total;
166
+ }
167
+ }
168
+ //# sourceMappingURL=CpuZ80.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CpuZ80.js","sourceRoot":"","sources":["../../../src/cpu/z80/CpuZ80.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Z80Handler, Z80IndexedCbHandler } from './types.js';
2
+ /**
3
+ * The Z80 opcode tables. `main`/`mainIX`/`mainIY` are the three views of the
4
+ * unprefixed space; `cb` and `ed` are the CB- and ED-prefixed spaces; `idxCb`
5
+ * holds the DDCB/FDCB bodies (address precomputed by the dispatcher, shared
6
+ * between IX and IY).
7
+ */
8
+ export declare class DecoderZ80 {
9
+ readonly main: Z80Handler[];
10
+ readonly mainIX: Z80Handler[];
11
+ readonly mainIY: Z80Handler[];
12
+ readonly cb: Z80Handler[];
13
+ readonly ed: Z80Handler[];
14
+ readonly idxCb: Z80IndexedCbHandler[];
15
+ constructor();
16
+ private buildMain;
17
+ /**
18
+ * main[0xCB]: plain CB dispatch (fetch op, R++, run cb table).
19
+ * mainIX/IY[0xCB]: DDCB/FDCB dispatch — displacement fetched BEFORE the final
20
+ * opcode, and that final byte is NOT an M1 fetch (only DD and CB tick R).
21
+ */
22
+ private wireCbDispatch;
23
+ /** main/mainIX/mainIY[0xED]: identical ED dispatch (a DD/FD before ED is ignored). */
24
+ private wireEdDispatch;
25
+ }
26
+ //# sourceMappingURL=DecoderZ80.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DecoderZ80.d.ts","sourceRoot":"","sources":["../../../src/cpu/z80/DecoderZ80.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,mBAAmB,EAAsB,MAAM,YAAY,CAAC;AAkCtF;;;;;GAKG;AACH,qBAAa,UAAU;IACrB,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,CAAqB;IAChD,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAuB;IACpD,QAAQ,CAAC,MAAM,EAAE,UAAU,EAAE,CAAuB;IACpD,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,CAAmB;IAC5C,QAAQ,CAAC,EAAE,EAAE,UAAU,EAAE,CAAmB;IAC5C,QAAQ,CAAC,KAAK,EAAE,mBAAmB,EAAE,CAAoB;;IAyBzD,OAAO,CAAC,SAAS;IAYjB;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAkBtB,sFAAsF;IACtF,OAAO,CAAC,cAAc;CAUvB"}
@@ -0,0 +1,107 @@
1
+ import { HL_VIEW, IX_VIEW, IY_VIEW, sext8 } from './views.js';
2
+ import { registerLoad } from './instructions/load.js';
3
+ import { registerExchange } from './instructions/exchange.js';
4
+ import { registerAlu8 } from './instructions/alu8.js';
5
+ import { registerAlu16 } from './instructions/alu16.js';
6
+ import { registerRotate } from './instructions/rotate.js';
7
+ import { registerJump } from './instructions/jump.js';
8
+ import { registerStack } from './instructions/stack.js';
9
+ import { registerIO } from './instructions/io.js';
10
+ import { registerControl } from './instructions/control.js';
11
+ import { registerBits } from './instructions/bits.js';
12
+ import { registerEd } from './instructions/ed.js';
13
+ import { registerBlock } from './instructions/block.js';
14
+ /** Build a 256-entry table pre-filled with a warn-on-execute stub. */
15
+ function makeTable(name) {
16
+ return new Array(256).fill((_cpu) => 4).map((_, i) => {
17
+ return (_cpu) => {
18
+ console.warn(`[Z80] Unimplemented ${name} opcode: 0x${i.toString(16).padStart(2, '0')}`);
19
+ return 4;
20
+ };
21
+ });
22
+ }
23
+ function makeIdxCbTable() {
24
+ return new Array(256).fill((_c, _a) => 8).map((_, i) => {
25
+ return (_cpu, _addr) => {
26
+ console.warn(`[Z80] Unimplemented DDCB opcode: 0x${i.toString(16).padStart(2, '0')}`);
27
+ return 8;
28
+ };
29
+ });
30
+ }
31
+ /**
32
+ * The Z80 opcode tables. `main`/`mainIX`/`mainIY` are the three views of the
33
+ * unprefixed space; `cb` and `ed` are the CB- and ED-prefixed spaces; `idxCb`
34
+ * holds the DDCB/FDCB bodies (address precomputed by the dispatcher, shared
35
+ * between IX and IY).
36
+ */
37
+ export class DecoderZ80 {
38
+ main = makeTable('main');
39
+ mainIX = makeTable('mainIX');
40
+ mainIY = makeTable('mainIY');
41
+ cb = makeTable('CB');
42
+ ed = makeTable('ED');
43
+ idxCb = makeIdxCbTable();
44
+ constructor() {
45
+ // Unassigned ED slots behave as NONI + NOP (8 T-states, no warning spam).
46
+ for (let i = 0; i < 256; i++) {
47
+ this.ed[i] = (_cpu) => 8;
48
+ }
49
+ // Build the three views of the main table.
50
+ this.buildMain(this.main, HL_VIEW);
51
+ this.buildMain(this.mainIX, IX_VIEW);
52
+ this.buildMain(this.mainIY, IY_VIEW);
53
+ // CB-prefixed space (shared) and its DDCB/FDCB bodies.
54
+ registerBits(this.cb, this.idxCb);
55
+ // ED-prefixed space (shared): misc + block ops.
56
+ registerEd(this.ed);
57
+ registerBlock(this.ed);
58
+ // Wire the prefix dispatchers into each main table.
59
+ this.wireCbDispatch();
60
+ this.wireEdDispatch();
61
+ }
62
+ buildMain(table, view) {
63
+ registerLoad(table, view);
64
+ registerExchange(table, view);
65
+ registerAlu8(table, view);
66
+ registerAlu16(table, view);
67
+ registerRotate(table, view);
68
+ registerJump(table, view);
69
+ registerStack(table, view);
70
+ registerIO(table, view);
71
+ registerControl(table, view);
72
+ }
73
+ /**
74
+ * main[0xCB]: plain CB dispatch (fetch op, R++, run cb table).
75
+ * mainIX/IY[0xCB]: DDCB/FDCB dispatch — displacement fetched BEFORE the final
76
+ * opcode, and that final byte is NOT an M1 fetch (only DD and CB tick R).
77
+ */
78
+ wireCbDispatch() {
79
+ this.main[0xcb] = (cpu) => {
80
+ const op = cpu.fetchByte();
81
+ cpu.regs.incR();
82
+ return this.cb[op](cpu);
83
+ };
84
+ const idxDispatch = (getPair) => (cpu) => {
85
+ const d = sext8(cpu.fetchByte());
86
+ cpu.regs.incR(); // the CB prefix byte
87
+ const addr = (getPair(cpu) + d) & 0xffff;
88
+ cpu.regs.wz = addr;
89
+ const op = cpu.fetchByte(); // final byte — not an M1 cycle
90
+ return this.idxCb[op](cpu, addr);
91
+ };
92
+ this.mainIX[0xcb] = idxDispatch((cpu) => cpu.regs.ix);
93
+ this.mainIY[0xcb] = idxDispatch((cpu) => cpu.regs.iy);
94
+ }
95
+ /** main/mainIX/mainIY[0xED]: identical ED dispatch (a DD/FD before ED is ignored). */
96
+ wireEdDispatch() {
97
+ const dispatch = (cpu) => {
98
+ const op = cpu.fetchByte();
99
+ cpu.regs.incR();
100
+ return this.ed[op](cpu);
101
+ };
102
+ this.main[0xed] = dispatch;
103
+ this.mainIX[0xed] = dispatch;
104
+ this.mainIY[0xed] = dispatch;
105
+ }
106
+ }
107
+ //# sourceMappingURL=DecoderZ80.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DecoderZ80.js","sourceRoot":"","sources":["../../../src/cpu/z80/DecoderZ80.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Zilog Z80 flags register (F).
3
+ *
4
+ * Byte layout: S Z Y H X PV N C (bit 7 → bit 0)
5
+ * S (0x80) Sign
6
+ * Z (0x40) Zero
7
+ * Y (0x20) undocumented copy of result bit 5
8
+ * H (0x10) Half-carry
9
+ * X (0x08) undocumented copy of result bit 3
10
+ * PV (0x04) Parity / overflow (context-dependent)
11
+ * N (0x02) Add/Subtract (set by subtractions)
12
+ * C (0x01) Carry
13
+ */
14
+ export declare class FlagsZ80 {
15
+ s: boolean;
16
+ z: boolean;
17
+ y: boolean;
18
+ h: boolean;
19
+ x: boolean;
20
+ pv: boolean;
21
+ n: boolean;
22
+ c: boolean;
23
+ toByte(): number;
24
+ fromByte(b: number): void;
25
+ reset(): void;
26
+ }
27
+ //# sourceMappingURL=FlagsZ80.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FlagsZ80.d.ts","sourceRoot":"","sources":["../../../src/cpu/z80/FlagsZ80.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,qBAAa,QAAQ;IACnB,CAAC,UAAS;IACV,CAAC,UAAS;IACV,CAAC,UAAS;IACV,CAAC,UAAS;IACV,CAAC,UAAS;IACV,EAAE,UAAS;IACX,CAAC,UAAS;IACV,CAAC,UAAS;IAEV,MAAM,IAAI,MAAM;IAahB,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAWzB,KAAK,IAAI,IAAI;CAGd"}