web-a2e 1.0.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 (295) hide show
  1. package/.clangd +5 -0
  2. package/.mcp.json +12 -0
  3. package/CLAUDE.md +362 -0
  4. package/CMakeLists.txt +774 -0
  5. package/LICENSE +21 -0
  6. package/README.md +392 -0
  7. package/build-wasm/generated/roms.cpp +2447 -0
  8. package/docker-compose.staging.yml +9 -0
  9. package/docs/basic-rom-disassembly.md +6663 -0
  10. package/docs/softswitch-comparison.md +273 -0
  11. package/docs/thunderclock-debug.md +89 -0
  12. package/examples/cube.bas +72 -0
  13. package/examples/hello.s +55 -0
  14. package/examples/scroll.s +140 -0
  15. package/package.json +18 -0
  16. package/public/assets/apple-logo-old.png +0 -0
  17. package/public/assets/apple-logo.png +0 -0
  18. package/public/assets/drive-closed-light-on.png +0 -0
  19. package/public/assets/drive-closed.png +0 -0
  20. package/public/assets/drive-open-light-on.png +0 -0
  21. package/public/assets/drive-open.png +0 -0
  22. package/public/audio-worklet.js +82 -0
  23. package/public/disks/Apple DOS 3.3 January 1983.dsk +0 -0
  24. package/public/disks/ProDOS 2.4.3.po +0 -0
  25. package/public/disks/h32mb.2mg +0 -0
  26. package/public/disks/library.json +26 -0
  27. package/public/docs/llms/llm-assembler.txt +90 -0
  28. package/public/docs/llms/llm-basic-program.txt +256 -0
  29. package/public/docs/llms/llm-disk-drives.txt +72 -0
  30. package/public/docs/llms/llm-file-explorer.txt +50 -0
  31. package/public/docs/llms/llm-hard-drives.txt +80 -0
  32. package/public/docs/llms/llm-main.txt +51 -0
  33. package/public/docs/llms/llm-slot-configuration.txt +66 -0
  34. package/public/icons/icon-192.svg +4 -0
  35. package/public/icons/icon-512.svg +4 -0
  36. package/public/index.html +661 -0
  37. package/public/llms.txt +49 -0
  38. package/public/manifest.json +29 -0
  39. package/public/shaders/burnin.glsl +22 -0
  40. package/public/shaders/crt.glsl +706 -0
  41. package/public/shaders/edge.glsl +109 -0
  42. package/public/shaders/vertex.glsl +8 -0
  43. package/public/sw.js +186 -0
  44. package/roms/341-0027.bin +0 -0
  45. package/roms/341-0160-A-US-UK.bin +0 -0
  46. package/roms/341-0160-A.bin +0 -0
  47. package/roms/342-0273-A-US-UK.bin +0 -0
  48. package/roms/342-0349-B-C0-FF.bin +0 -0
  49. package/roms/Apple Mouse Interface Card ROM - 342-0270-C.bin +0 -0
  50. package/roms/Thunderclock Plus ROM.bin +0 -0
  51. package/scripts/generate_roms.sh +69 -0
  52. package/src/bindings/wasm_interface.cpp +1940 -0
  53. package/src/core/assembler/assembler.cpp +1239 -0
  54. package/src/core/assembler/assembler.hpp +115 -0
  55. package/src/core/audio/audio.cpp +160 -0
  56. package/src/core/audio/audio.hpp +81 -0
  57. package/src/core/basic/basic_detokenizer.cpp +436 -0
  58. package/src/core/basic/basic_detokenizer.hpp +41 -0
  59. package/src/core/basic/basic_tokenizer.cpp +286 -0
  60. package/src/core/basic/basic_tokenizer.hpp +26 -0
  61. package/src/core/basic/basic_tokens.hpp +295 -0
  62. package/src/core/cards/disk2_card.cpp +568 -0
  63. package/src/core/cards/disk2_card.hpp +316 -0
  64. package/src/core/cards/expansion_card.hpp +185 -0
  65. package/src/core/cards/mockingboard/ay8910.cpp +616 -0
  66. package/src/core/cards/mockingboard/ay8910.hpp +159 -0
  67. package/src/core/cards/mockingboard/via6522.cpp +530 -0
  68. package/src/core/cards/mockingboard/via6522.hpp +163 -0
  69. package/src/core/cards/mockingboard_card.cpp +312 -0
  70. package/src/core/cards/mockingboard_card.hpp +159 -0
  71. package/src/core/cards/mouse_card.cpp +654 -0
  72. package/src/core/cards/mouse_card.hpp +190 -0
  73. package/src/core/cards/smartport/block_device.cpp +202 -0
  74. package/src/core/cards/smartport/block_device.hpp +60 -0
  75. package/src/core/cards/smartport/smartport_card.cpp +603 -0
  76. package/src/core/cards/smartport/smartport_card.hpp +120 -0
  77. package/src/core/cards/thunderclock_card.cpp +237 -0
  78. package/src/core/cards/thunderclock_card.hpp +122 -0
  79. package/src/core/cpu/cpu6502.cpp +1609 -0
  80. package/src/core/cpu/cpu6502.hpp +203 -0
  81. package/src/core/debug/condition_evaluator.cpp +470 -0
  82. package/src/core/debug/condition_evaluator.hpp +87 -0
  83. package/src/core/disassembler/disassembler.cpp +552 -0
  84. package/src/core/disassembler/disassembler.hpp +171 -0
  85. package/src/core/disk-image/disk_image.hpp +267 -0
  86. package/src/core/disk-image/dsk_disk_image.cpp +827 -0
  87. package/src/core/disk-image/dsk_disk_image.hpp +204 -0
  88. package/src/core/disk-image/gcr_encoding.cpp +147 -0
  89. package/src/core/disk-image/gcr_encoding.hpp +78 -0
  90. package/src/core/disk-image/woz_disk_image.cpp +1049 -0
  91. package/src/core/disk-image/woz_disk_image.hpp +343 -0
  92. package/src/core/emulator.cpp +2126 -0
  93. package/src/core/emulator.hpp +434 -0
  94. package/src/core/filesystem/dos33.cpp +178 -0
  95. package/src/core/filesystem/dos33.hpp +66 -0
  96. package/src/core/filesystem/pascal.cpp +262 -0
  97. package/src/core/filesystem/pascal.hpp +87 -0
  98. package/src/core/filesystem/prodos.cpp +369 -0
  99. package/src/core/filesystem/prodos.hpp +119 -0
  100. package/src/core/input/keyboard.cpp +227 -0
  101. package/src/core/input/keyboard.hpp +111 -0
  102. package/src/core/mmu/mmu.cpp +1387 -0
  103. package/src/core/mmu/mmu.hpp +236 -0
  104. package/src/core/types.hpp +196 -0
  105. package/src/core/video/video.cpp +680 -0
  106. package/src/core/video/video.hpp +156 -0
  107. package/src/css/assembler-editor.css +1617 -0
  108. package/src/css/base.css +470 -0
  109. package/src/css/basic-debugger.css +791 -0
  110. package/src/css/basic-editor.css +792 -0
  111. package/src/css/controls.css +783 -0
  112. package/src/css/cpu-debugger.css +1413 -0
  113. package/src/css/debug-base.css +160 -0
  114. package/src/css/debug-windows.css +6455 -0
  115. package/src/css/disk-drives.css +406 -0
  116. package/src/css/documentation.css +392 -0
  117. package/src/css/file-explorer.css +867 -0
  118. package/src/css/hard-drive.css +180 -0
  119. package/src/css/layout.css +217 -0
  120. package/src/css/memory-windows.css +798 -0
  121. package/src/css/modals.css +510 -0
  122. package/src/css/monitor.css +425 -0
  123. package/src/css/release-notes.css +101 -0
  124. package/src/css/responsive.css +400 -0
  125. package/src/css/rule-builder.css +340 -0
  126. package/src/css/save-states.css +201 -0
  127. package/src/css/settings-windows.css +1231 -0
  128. package/src/css/window-switcher.css +150 -0
  129. package/src/js/agent/agent-manager.js +643 -0
  130. package/src/js/agent/agent-tools.js +293 -0
  131. package/src/js/agent/agent-version-tools.js +131 -0
  132. package/src/js/agent/assembler-tools.js +357 -0
  133. package/src/js/agent/basic-program-tools.js +894 -0
  134. package/src/js/agent/disk-tools.js +417 -0
  135. package/src/js/agent/file-explorer-tools.js +269 -0
  136. package/src/js/agent/index.js +13 -0
  137. package/src/js/agent/main-tools.js +222 -0
  138. package/src/js/agent/slot-tools.js +303 -0
  139. package/src/js/agent/smartport-tools.js +257 -0
  140. package/src/js/agent/window-tools.js +80 -0
  141. package/src/js/audio/audio-driver.js +417 -0
  142. package/src/js/audio/audio-worklet.js +85 -0
  143. package/src/js/audio/index.js +8 -0
  144. package/src/js/config/default-layout.js +34 -0
  145. package/src/js/config/version.js +8 -0
  146. package/src/js/data/apple2-rom-routines.js +577 -0
  147. package/src/js/debug/assembler-editor-window.js +2993 -0
  148. package/src/js/debug/basic-breakpoint-manager.js +529 -0
  149. package/src/js/debug/basic-program-parser.js +436 -0
  150. package/src/js/debug/basic-program-window.js +2594 -0
  151. package/src/js/debug/basic-variable-inspector.js +447 -0
  152. package/src/js/debug/breakpoint-manager.js +472 -0
  153. package/src/js/debug/cpu-debugger-window.js +2396 -0
  154. package/src/js/debug/index.js +22 -0
  155. package/src/js/debug/label-manager.js +238 -0
  156. package/src/js/debug/memory-browser-window.js +416 -0
  157. package/src/js/debug/memory-heat-map-window.js +481 -0
  158. package/src/js/debug/memory-map-window.js +206 -0
  159. package/src/js/debug/mockingboard-window.js +882 -0
  160. package/src/js/debug/mouse-card-window.js +355 -0
  161. package/src/js/debug/rule-builder-window.js +648 -0
  162. package/src/js/debug/soft-switch-window.js +458 -0
  163. package/src/js/debug/stack-viewer-window.js +221 -0
  164. package/src/js/debug/symbols.js +416 -0
  165. package/src/js/debug/trace-panel.js +291 -0
  166. package/src/js/debug/zero-page-watch-window.js +297 -0
  167. package/src/js/disk-manager/disk-drives-window.js +212 -0
  168. package/src/js/disk-manager/disk-operations.js +284 -0
  169. package/src/js/disk-manager/disk-persistence.js +301 -0
  170. package/src/js/disk-manager/disk-surface-renderer.js +388 -0
  171. package/src/js/disk-manager/drive-sounds.js +139 -0
  172. package/src/js/disk-manager/hard-drive-manager.js +481 -0
  173. package/src/js/disk-manager/hard-drive-persistence.js +187 -0
  174. package/src/js/disk-manager/hard-drive-window.js +57 -0
  175. package/src/js/disk-manager/index.js +890 -0
  176. package/src/js/display/display-settings-window.js +383 -0
  177. package/src/js/display/index.js +10 -0
  178. package/src/js/display/screen-window.js +342 -0
  179. package/src/js/display/webgl-renderer.js +705 -0
  180. package/src/js/file-explorer/disassembler.js +574 -0
  181. package/src/js/file-explorer/dos33.js +266 -0
  182. package/src/js/file-explorer/file-viewer.js +359 -0
  183. package/src/js/file-explorer/index.js +1261 -0
  184. package/src/js/file-explorer/prodos.js +549 -0
  185. package/src/js/file-explorer/utils.js +67 -0
  186. package/src/js/help/documentation-window.js +1096 -0
  187. package/src/js/help/index.js +10 -0
  188. package/src/js/help/release-notes-window.js +85 -0
  189. package/src/js/help/release-notes.js +612 -0
  190. package/src/js/input/gamepad-handler.js +176 -0
  191. package/src/js/input/index.js +12 -0
  192. package/src/js/input/input-handler.js +396 -0
  193. package/src/js/input/joystick-window.js +404 -0
  194. package/src/js/input/mouse-handler.js +99 -0
  195. package/src/js/input/text-selection.js +462 -0
  196. package/src/js/main.js +653 -0
  197. package/src/js/state/index.js +15 -0
  198. package/src/js/state/save-states-window.js +393 -0
  199. package/src/js/state/state-manager.js +409 -0
  200. package/src/js/state/state-persistence.js +218 -0
  201. package/src/js/ui/confirm.js +43 -0
  202. package/src/js/ui/disk-drive-positioner.js +347 -0
  203. package/src/js/ui/reminder-controller.js +129 -0
  204. package/src/js/ui/slot-configuration-window.js +560 -0
  205. package/src/js/ui/theme-manager.js +61 -0
  206. package/src/js/ui/toast.js +44 -0
  207. package/src/js/ui/ui-controller.js +897 -0
  208. package/src/js/ui/window-switcher.js +275 -0
  209. package/src/js/utils/basic-autocomplete.js +832 -0
  210. package/src/js/utils/basic-highlighting.js +473 -0
  211. package/src/js/utils/basic-tokenizer.js +153 -0
  212. package/src/js/utils/basic-tokens.js +117 -0
  213. package/src/js/utils/constants.js +28 -0
  214. package/src/js/utils/indexeddb-helper.js +225 -0
  215. package/src/js/utils/merlin-editor-support.js +905 -0
  216. package/src/js/utils/merlin-highlighting.js +551 -0
  217. package/src/js/utils/storage.js +125 -0
  218. package/src/js/utils/string-utils.js +19 -0
  219. package/src/js/utils/wasm-memory.js +54 -0
  220. package/src/js/windows/base-window.js +690 -0
  221. package/src/js/windows/index.js +9 -0
  222. package/src/js/windows/window-manager.js +375 -0
  223. package/tests/catch2/catch.hpp +17976 -0
  224. package/tests/common/basic_program_builder.cpp +119 -0
  225. package/tests/common/basic_program_builder.hpp +209 -0
  226. package/tests/common/disk_image_builder.cpp +444 -0
  227. package/tests/common/disk_image_builder.hpp +141 -0
  228. package/tests/common/test_helpers.hpp +118 -0
  229. package/tests/gcr/gcr-test.cpp +142 -0
  230. package/tests/integration/check-rom.js +70 -0
  231. package/tests/integration/compare-boot.js +239 -0
  232. package/tests/integration/crash-trace.js +102 -0
  233. package/tests/integration/disk-boot-test.js +264 -0
  234. package/tests/integration/memory-crash.js +108 -0
  235. package/tests/integration/nibble-read-test.js +249 -0
  236. package/tests/integration/phase-test.js +159 -0
  237. package/tests/integration/test_emulator.cpp +291 -0
  238. package/tests/integration/test_emulator_basic.cpp +91 -0
  239. package/tests/integration/test_emulator_debug.cpp +344 -0
  240. package/tests/integration/test_emulator_disk.cpp +153 -0
  241. package/tests/integration/test_emulator_state.cpp +163 -0
  242. package/tests/klaus/6502_functional_test.bin +0 -0
  243. package/tests/klaus/65C02_extended_opcodes_test.bin +0 -0
  244. package/tests/klaus/klaus_6502_test.cpp +184 -0
  245. package/tests/klaus/klaus_65c02_test.cpp +197 -0
  246. package/tests/thunderclock/thunderclock_mmu_test.cpp +304 -0
  247. package/tests/thunderclock/thunderclock_test.cpp +550 -0
  248. package/tests/unit/test_assembler.cpp +521 -0
  249. package/tests/unit/test_audio.cpp +196 -0
  250. package/tests/unit/test_ay8910.cpp +311 -0
  251. package/tests/unit/test_basic_detokenizer.cpp +265 -0
  252. package/tests/unit/test_basic_tokenizer.cpp +382 -0
  253. package/tests/unit/test_block_device.cpp +259 -0
  254. package/tests/unit/test_condition_evaluator.cpp +219 -0
  255. package/tests/unit/test_cpu6502.cpp +1301 -0
  256. package/tests/unit/test_cpu_addressing.cpp +361 -0
  257. package/tests/unit/test_cpu_cycle_counts.cpp +409 -0
  258. package/tests/unit/test_cpu_decimal.cpp +166 -0
  259. package/tests/unit/test_cpu_interrupts.cpp +285 -0
  260. package/tests/unit/test_disassembler.cpp +323 -0
  261. package/tests/unit/test_disk2_card.cpp +330 -0
  262. package/tests/unit/test_dos33.cpp +273 -0
  263. package/tests/unit/test_dsk_disk_image.cpp +315 -0
  264. package/tests/unit/test_expansion_card.cpp +178 -0
  265. package/tests/unit/test_gcr_encoding.cpp +232 -0
  266. package/tests/unit/test_keyboard.cpp +262 -0
  267. package/tests/unit/test_mmu.cpp +555 -0
  268. package/tests/unit/test_mmu_slots.cpp +323 -0
  269. package/tests/unit/test_mockingboard.cpp +352 -0
  270. package/tests/unit/test_mouse_card.cpp +386 -0
  271. package/tests/unit/test_pascal.cpp +248 -0
  272. package/tests/unit/test_prodos.cpp +259 -0
  273. package/tests/unit/test_smartport_card.cpp +321 -0
  274. package/tests/unit/test_thunderclock.cpp +354 -0
  275. package/tests/unit/test_via6522.cpp +323 -0
  276. package/tests/unit/test_video.cpp +319 -0
  277. package/tests/unit/test_woz_disk_image.cpp +257 -0
  278. package/vite.config.js +96 -0
  279. package/wiki/AI-Agent.md +372 -0
  280. package/wiki/Architecture-Overview.md +303 -0
  281. package/wiki/Audio-System.md +449 -0
  282. package/wiki/CPU-Emulation.md +477 -0
  283. package/wiki/Debugger.md +516 -0
  284. package/wiki/Disk-Drives.md +161 -0
  285. package/wiki/Disk-System-Internals.md +547 -0
  286. package/wiki/Display-Settings.md +88 -0
  287. package/wiki/Expansion-Slots.md +187 -0
  288. package/wiki/File-Explorer.md +259 -0
  289. package/wiki/Getting-Started.md +156 -0
  290. package/wiki/Home.md +69 -0
  291. package/wiki/Input-Devices.md +183 -0
  292. package/wiki/Keyboard-Shortcuts.md +158 -0
  293. package/wiki/Memory-System.md +364 -0
  294. package/wiki/Save-States.md +172 -0
  295. package/wiki/Video-Rendering.md +658 -0
@@ -0,0 +1,577 @@
1
+ /*
2
+ * apple2-rom-routines.js - Apple IIe ROM routine reference data
3
+ *
4
+ * Common Monitor, Applesoft, and DOS ROM entry points with documentation
5
+ */
6
+
7
+ export const ROM_ROUTINES = [
8
+ // ============================================================================
9
+ // Character I/O
10
+ // ============================================================================
11
+ {
12
+ name: "COUT",
13
+ address: 0xFDED,
14
+ category: "Character I/O",
15
+ description: "Output character to current output device (screen by default)",
16
+ inputs: [
17
+ { register: "A", description: "Character to output (high bit set for normal)" }
18
+ ],
19
+ outputs: [],
20
+ preserves: ["X", "Y"],
21
+ clobbers: ["A"],
22
+ example: ` LDA #$C1 ;'A' with high bit
23
+ JSR COUT`
24
+ },
25
+ {
26
+ name: "COUT1",
27
+ address: 0xFDF0,
28
+ category: "Character I/O",
29
+ description: "Output character, setting high bit automatically",
30
+ inputs: [
31
+ { register: "A", description: "Character to output (high bit will be set)" }
32
+ ],
33
+ outputs: [],
34
+ preserves: ["X", "Y"],
35
+ clobbers: ["A"],
36
+ example: ` LDA #'A' ;No need to set high bit
37
+ JSR COUT1`
38
+ },
39
+ {
40
+ name: "CROUT",
41
+ address: 0xFD8E,
42
+ category: "Character I/O",
43
+ description: "Output carriage return (move cursor to start of next line)",
44
+ inputs: [],
45
+ outputs: [],
46
+ preserves: ["X", "Y"],
47
+ clobbers: ["A"],
48
+ example: ` JSR CROUT ;New line`
49
+ },
50
+ {
51
+ name: "RDKEY",
52
+ address: 0xFD0C,
53
+ category: "Character I/O",
54
+ description: "Read character from keyboard, waiting for keypress",
55
+ inputs: [],
56
+ outputs: [
57
+ { register: "A", description: "Character read (high bit set)" }
58
+ ],
59
+ preserves: ["X", "Y"],
60
+ clobbers: ["A"],
61
+ example: ` JSR RDKEY ;Wait for key
62
+ CMP #$8D ;Return pressed?`
63
+ },
64
+ {
65
+ name: "GETLN",
66
+ address: 0xFD6A,
67
+ category: "Character I/O",
68
+ description: "Get line of input from keyboard into input buffer at $200",
69
+ inputs: [],
70
+ outputs: [
71
+ { register: "X", description: "Length of input string" }
72
+ ],
73
+ preserves: ["Y"],
74
+ clobbers: ["A", "X"],
75
+ notes: "Input stored at $200-$2FF, terminated by $8D",
76
+ example: ` JSR GETLN ;Get input
77
+ STX LENGTH ;Save length`
78
+ },
79
+
80
+ // ============================================================================
81
+ // Screen Control
82
+ // ============================================================================
83
+ {
84
+ name: "HOME",
85
+ address: 0xFC58,
86
+ category: "Screen",
87
+ description: "Clear screen and move cursor to top-left corner",
88
+ inputs: [],
89
+ outputs: [],
90
+ preserves: [],
91
+ clobbers: ["A", "X", "Y"],
92
+ example: ` JSR HOME ;Clear screen`
93
+ },
94
+ {
95
+ name: "VTAB",
96
+ address: 0xFC22,
97
+ category: "Screen",
98
+ description: "Move cursor to row specified in A",
99
+ inputs: [
100
+ { register: "A", description: "Row number (1-24)" }
101
+ ],
102
+ outputs: [],
103
+ preserves: ["X", "Y"],
104
+ clobbers: ["A"],
105
+ example: ` LDA #12 ;Row 12
106
+ JSR VTAB`
107
+ },
108
+ {
109
+ name: "CLREOL",
110
+ address: 0xFC9C,
111
+ category: "Screen",
112
+ description: "Clear from cursor to end of line",
113
+ inputs: [],
114
+ outputs: [],
115
+ preserves: ["X", "Y"],
116
+ clobbers: ["A"],
117
+ example: ` JSR CLREOL ;Clear to EOL`
118
+ },
119
+ {
120
+ name: "CLREOP",
121
+ address: 0xFC42,
122
+ category: "Screen",
123
+ description: "Clear from cursor to end of page (bottom of screen)",
124
+ inputs: [],
125
+ outputs: [],
126
+ preserves: [],
127
+ clobbers: ["A", "X", "Y"],
128
+ example: ` JSR CLREOP ;Clear to bottom`
129
+ },
130
+
131
+ // ============================================================================
132
+ // Numeric Output
133
+ // ============================================================================
134
+ {
135
+ name: "PRBYTE",
136
+ address: 0xFDDA,
137
+ category: "Numeric",
138
+ description: "Print accumulator as two hex digits",
139
+ inputs: [
140
+ { register: "A", description: "Byte value to print" }
141
+ ],
142
+ outputs: [],
143
+ preserves: ["X", "Y"],
144
+ clobbers: ["A"],
145
+ example: ` LDA VALUE
146
+ JSR PRBYTE ;Print as hex`
147
+ },
148
+ {
149
+ name: "PRNTAX",
150
+ address: 0xF941,
151
+ category: "Numeric",
152
+ description: "Print A and X registers as four hex digits (A high, X low)",
153
+ inputs: [
154
+ { register: "A", description: "High byte" },
155
+ { register: "X", description: "Low byte" }
156
+ ],
157
+ outputs: [],
158
+ preserves: ["Y"],
159
+ clobbers: ["A", "X"],
160
+ example: ` LDA #>ADDR ;High byte
161
+ LDX #<ADDR ;Low byte
162
+ JSR PRNTAX ;Print address`
163
+ },
164
+ {
165
+ name: "PRBLNK",
166
+ address: 0xF948,
167
+ category: "Numeric",
168
+ description: "Print a space character",
169
+ inputs: [],
170
+ outputs: [],
171
+ preserves: ["X", "Y"],
172
+ clobbers: ["A"],
173
+ example: ` JSR PRBLNK ;Print space`
174
+ },
175
+
176
+ // ============================================================================
177
+ // Sound
178
+ // ============================================================================
179
+ {
180
+ name: "BELL",
181
+ address: 0xFBE4,
182
+ category: "Sound",
183
+ description: "Sound the bell (beep)",
184
+ inputs: [],
185
+ outputs: [],
186
+ preserves: ["X", "Y"],
187
+ clobbers: ["A"],
188
+ example: ` JSR BELL ;Beep!`
189
+ },
190
+ {
191
+ name: "WAIT",
192
+ address: 0xFCA8,
193
+ category: "Utility",
194
+ description: "Delay for (26 + 27*A + 5*A*A) / 2 microseconds",
195
+ inputs: [
196
+ { register: "A", description: "Delay count (larger = longer delay)" }
197
+ ],
198
+ outputs: [],
199
+ preserves: ["X", "Y"],
200
+ clobbers: ["A"],
201
+ notes: "A=1 ~14µs, A=$FF ~66ms",
202
+ example: ` LDA #$FF ;Maximum delay
203
+ JSR WAIT`
204
+ },
205
+
206
+ // ============================================================================
207
+ // Paddle / Joystick
208
+ // ============================================================================
209
+ {
210
+ name: "PREAD",
211
+ address: 0xFB1E,
212
+ category: "Input",
213
+ description: "Read paddle/joystick position",
214
+ inputs: [
215
+ { register: "X", description: "Paddle number (0-3)" }
216
+ ],
217
+ outputs: [
218
+ { register: "Y", description: "Paddle position (0-255)" }
219
+ ],
220
+ preserves: [],
221
+ clobbers: ["A", "X", "Y"],
222
+ example: ` LDX #0 ;Paddle 0
223
+ JSR PREAD
224
+ STY POSITION`
225
+ },
226
+ {
227
+ name: "PREAD4",
228
+ address: 0xFB21,
229
+ category: "Input",
230
+ description: "Read paddle without resetting - use after PREAD for paddle 1-3",
231
+ inputs: [
232
+ { register: "X", description: "Paddle number (1-3)" }
233
+ ],
234
+ outputs: [
235
+ { register: "Y", description: "Paddle position (0-255)" }
236
+ ],
237
+ preserves: [],
238
+ clobbers: ["A", "X", "Y"],
239
+ example: ` LDX #0
240
+ JSR PREAD ;Read paddle 0
241
+ LDX #1
242
+ JSR PREAD4 ;Read paddle 1`
243
+ },
244
+
245
+ // ============================================================================
246
+ // Device Control
247
+ // ============================================================================
248
+ {
249
+ name: "SETKBD",
250
+ address: 0xFE89,
251
+ category: "Device",
252
+ description: "Set keyboard as current input device",
253
+ inputs: [],
254
+ outputs: [],
255
+ preserves: ["X", "Y"],
256
+ clobbers: ["A"],
257
+ example: ` JSR SETKBD ;Input from keyboard`
258
+ },
259
+ {
260
+ name: "SETVID",
261
+ address: 0xFE93,
262
+ category: "Device",
263
+ description: "Set 40-column screen as current output device",
264
+ inputs: [],
265
+ outputs: [],
266
+ preserves: ["X", "Y"],
267
+ clobbers: ["A"],
268
+ example: ` JSR SETVID ;Output to screen`
269
+ },
270
+ {
271
+ name: "SETINV",
272
+ address: 0xFE80,
273
+ category: "Screen",
274
+ description: "Set inverse text mode",
275
+ inputs: [],
276
+ outputs: [],
277
+ preserves: ["X", "Y"],
278
+ clobbers: ["A"],
279
+ example: ` JSR SETINV ;Inverse on
280
+ JSR COUT
281
+ JSR SETNORM ;Normal`
282
+ },
283
+ {
284
+ name: "SETNORM",
285
+ address: 0xFE84,
286
+ category: "Screen",
287
+ description: "Set normal text mode",
288
+ inputs: [],
289
+ outputs: [],
290
+ preserves: ["X", "Y"],
291
+ clobbers: ["A"],
292
+ example: ` JSR SETNORM ;Normal text`
293
+ },
294
+
295
+ // ============================================================================
296
+ // Graphics
297
+ // ============================================================================
298
+ {
299
+ name: "HLINE",
300
+ address: 0xF819,
301
+ category: "Lo-Res Graphics",
302
+ description: "Draw horizontal line in lo-res graphics",
303
+ inputs: [
304
+ { register: "Y", description: "Starting X coordinate" },
305
+ { register: "A", description: "Y coordinate" },
306
+ { register: "$2C", description: "Ending X coordinate (H2)" }
307
+ ],
308
+ outputs: [],
309
+ preserves: [],
310
+ clobbers: ["A", "X", "Y"],
311
+ notes: "Color set by $30 (COLOR)",
312
+ example: ` LDA #10 ;Y=10
313
+ LDY #5 ;X1=5
314
+ STA $2C ;X2=35
315
+ LDA #35
316
+ JSR HLINE`
317
+ },
318
+ {
319
+ name: "VLINE",
320
+ address: 0xF828,
321
+ category: "Lo-Res Graphics",
322
+ description: "Draw vertical line in lo-res graphics",
323
+ inputs: [
324
+ { register: "Y", description: "X coordinate" },
325
+ { register: "A", description: "Starting Y coordinate" },
326
+ { register: "$2D", description: "Ending Y coordinate (V2)" }
327
+ ],
328
+ outputs: [],
329
+ preserves: [],
330
+ clobbers: ["A", "X", "Y"],
331
+ notes: "Color set by $30 (COLOR)",
332
+ example: ` LDY #20 ;X=20
333
+ LDA #0 ;Y1=0
334
+ STA $2D
335
+ LDA #39 ;Y2=39
336
+ JSR VLINE`
337
+ },
338
+ {
339
+ name: "PLOT",
340
+ address: 0xF800,
341
+ category: "Lo-Res Graphics",
342
+ description: "Plot single point in lo-res graphics",
343
+ inputs: [
344
+ { register: "Y", description: "X coordinate (0-39)" },
345
+ { register: "A", description: "Y coordinate (0-47)" }
346
+ ],
347
+ outputs: [],
348
+ preserves: ["X"],
349
+ clobbers: ["A", "Y"],
350
+ notes: "Color set by $30 (COLOR)",
351
+ example: ` LDA #$0F ;Color = white
352
+ STA $30
353
+ LDY #20 ;X=20
354
+ LDA #24 ;Y=24
355
+ JSR PLOT`
356
+ },
357
+ {
358
+ name: "SETCOL",
359
+ address: 0xF864,
360
+ category: "Lo-Res Graphics",
361
+ description: "Set lo-res color",
362
+ inputs: [
363
+ { register: "A", description: "Color (0-15)" }
364
+ ],
365
+ outputs: [],
366
+ preserves: ["X", "Y"],
367
+ clobbers: ["A"],
368
+ notes: "Colors: 0=black,1=magenta,2=dk blue,3=purple,4=dk green,5=grey1,6=med blue,7=lt blue,8=brown,9=orange,10=grey2,11=pink,12=green,13=yellow,14=aqua,15=white",
369
+ example: ` LDA #1 ;Magenta
370
+ JSR SETCOL`
371
+ },
372
+
373
+ // ============================================================================
374
+ // Hi-Res Graphics
375
+ // ============================================================================
376
+ {
377
+ name: "HCLR",
378
+ address: 0xF3F2,
379
+ category: "Hi-Res Graphics",
380
+ description: "Clear current hi-res page to black",
381
+ inputs: [],
382
+ outputs: [],
383
+ preserves: [],
384
+ clobbers: ["A", "X", "Y"],
385
+ notes: "Clears page set by $E6 (HGR page: $20=page1, $40=page2)",
386
+ example: ` JSR HCLR ;Clear hi-res`
387
+ },
388
+ {
389
+ name: "HPOSN",
390
+ address: 0xF411,
391
+ category: "Hi-Res Graphics",
392
+ description: "Position hi-res cursor without plotting",
393
+ inputs: [
394
+ { register: "Y", description: "X coordinate low byte" },
395
+ { register: "X", description: "X coordinate high byte (0-1)" },
396
+ { register: "A", description: "Y coordinate (0-191)" }
397
+ ],
398
+ outputs: [],
399
+ preserves: [],
400
+ clobbers: ["A", "X", "Y"],
401
+ example: ` LDY #<140 ;X=140
402
+ LDX #>140
403
+ LDA #96 ;Y=96
404
+ JSR HPOSN`
405
+ },
406
+ {
407
+ name: "HPLOT",
408
+ address: 0xF457,
409
+ category: "Hi-Res Graphics",
410
+ description: "Plot point at current hi-res cursor position",
411
+ inputs: [],
412
+ outputs: [],
413
+ preserves: [],
414
+ clobbers: ["A", "X", "Y"],
415
+ notes: "Call HPOSN first to set position. Color set by HCOLOR ($1C)",
416
+ example: ` JSR HPOSN ;Set position
417
+ JSR HPLOT ;Plot point`
418
+ },
419
+ {
420
+ name: "HLIN",
421
+ address: 0xF53A,
422
+ category: "Hi-Res Graphics",
423
+ description: "Draw line from current position to new position",
424
+ inputs: [
425
+ { register: "Y", description: "End X coordinate low byte" },
426
+ { register: "X", description: "End X coordinate high byte" },
427
+ { register: "A", description: "End Y coordinate" }
428
+ ],
429
+ outputs: [],
430
+ preserves: [],
431
+ clobbers: ["A", "X", "Y"],
432
+ notes: "Call HPOSN first for start position",
433
+ example: ` JSR HPOSN ;Start position
434
+ LDY #<200 ;End X
435
+ LDX #>200
436
+ LDA #150 ;End Y
437
+ JSR HLIN ;Draw line`
438
+ },
439
+
440
+ // ============================================================================
441
+ // Memory / Utility
442
+ // ============================================================================
443
+ {
444
+ name: "MOVE",
445
+ address: 0xFE2C,
446
+ category: "Memory",
447
+ description: "Move memory block from source to destination",
448
+ inputs: [
449
+ { register: "$3C-$3D", description: "Source start address (A1L/A1H)" },
450
+ { register: "$3E-$3F", description: "Source end address (A2L/A2H)" },
451
+ { register: "$42-$43", description: "Destination address (A4L/A4H)" }
452
+ ],
453
+ outputs: [],
454
+ preserves: [],
455
+ clobbers: ["A", "X", "Y"],
456
+ notes: "Moves bytes from A1 to A2, storing at A4",
457
+ example: ` LDA #<SRC
458
+ STA $3C
459
+ LDA #>SRC
460
+ STA $3D ;Source start
461
+ LDA #<SRCEND
462
+ STA $3E
463
+ LDA #>SRCEND
464
+ STA $3F ;Source end
465
+ LDA #<DEST
466
+ STA $42
467
+ LDA #>DEST
468
+ STA $43 ;Destination
469
+ LDY #0
470
+ JSR MOVE`
471
+ },
472
+
473
+ // ============================================================================
474
+ // String Output (Applesoft)
475
+ // ============================================================================
476
+ {
477
+ name: "STROUT",
478
+ address: 0xDB3A,
479
+ category: "Applesoft",
480
+ description: "Print null-terminated string",
481
+ inputs: [
482
+ { register: "A", description: "String address low byte" },
483
+ { register: "Y", description: "String address high byte" }
484
+ ],
485
+ outputs: [],
486
+ preserves: [],
487
+ clobbers: ["A", "X", "Y"],
488
+ notes: "String must be null-terminated ($00). High bit handled automatically.",
489
+ example: ` LDA #<MSG
490
+ LDY #>MSG
491
+ JSR STROUT
492
+ MSG ASC "HELLO"
493
+ DFB $00`
494
+ },
495
+
496
+ // ============================================================================
497
+ // Keyboard
498
+ // ============================================================================
499
+ {
500
+ name: "KEYIN",
501
+ address: 0xFD1B,
502
+ category: "Character I/O",
503
+ description: "Check if key is pressed (non-blocking)",
504
+ inputs: [],
505
+ outputs: [
506
+ { register: "A", description: "Key code if pressed, or no change" },
507
+ { register: "C flag", description: "Set if key pressed" }
508
+ ],
509
+ preserves: ["X", "Y"],
510
+ clobbers: ["A"],
511
+ notes: "Use BCS to branch if key pressed",
512
+ example: `CHKKEY JSR KEYIN
513
+ BCC NOKEY ;No key pressed
514
+ ; Key in A`
515
+ },
516
+
517
+ // ============================================================================
518
+ // Monitor Entry Points
519
+ // ============================================================================
520
+ {
521
+ name: "MONZ",
522
+ address: 0xFF69,
523
+ category: "Monitor",
524
+ description: "Enter monitor (warm start)",
525
+ inputs: [],
526
+ outputs: [],
527
+ preserves: [],
528
+ clobbers: ["A", "X", "Y"],
529
+ notes: "Returns to monitor prompt",
530
+ example: ` JSR MONZ ;Enter monitor`
531
+ },
532
+ {
533
+ name: "RESET",
534
+ address: 0xFA62,
535
+ category: "Monitor",
536
+ description: "Perform cold reset",
537
+ inputs: [],
538
+ outputs: [],
539
+ preserves: [],
540
+ clobbers: ["A", "X", "Y"],
541
+ notes: "WARNING: This resets the machine!",
542
+ example: ` JMP RESET ;Cold reset`
543
+ }
544
+ ];
545
+
546
+ // Categories for filtering
547
+ export const ROM_CATEGORIES = [
548
+ "All",
549
+ "Character I/O",
550
+ "Screen",
551
+ "Numeric",
552
+ "Sound",
553
+ "Input",
554
+ "Device",
555
+ "Lo-Res Graphics",
556
+ "Hi-Res Graphics",
557
+ "Memory",
558
+ "Utility",
559
+ "Applesoft",
560
+ "Monitor"
561
+ ];
562
+
563
+ // Get routines by category
564
+ export function getRoutinesByCategory(category) {
565
+ if (category === "All") return ROM_ROUTINES;
566
+ return ROM_ROUTINES.filter(r => r.category === category);
567
+ }
568
+
569
+ // Search routines by name or description
570
+ export function searchRoutines(query) {
571
+ const q = query.toLowerCase();
572
+ return ROM_ROUTINES.filter(r =>
573
+ r.name.toLowerCase().includes(q) ||
574
+ r.description.toLowerCase().includes(q) ||
575
+ r.category.toLowerCase().includes(q)
576
+ );
577
+ }