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,119 @@
1
+ /*
2
+ * basic_program_builder.cpp - Programmatic BASIC token builders
3
+ */
4
+
5
+ #include "basic_program_builder.hpp"
6
+ #include <cstring>
7
+ #include <algorithm>
8
+
9
+ namespace test {
10
+
11
+ // ==================== ApplesoftProgramBuilder ====================
12
+
13
+ ApplesoftProgramBuilder::ApplesoftProgramBuilder(uint16_t baseAddr)
14
+ : baseAddr_(baseAddr) {}
15
+
16
+ void ApplesoftProgramBuilder::addLine(uint16_t lineNum, const std::vector<uint8_t>& tokens) {
17
+ lines_.push_back({lineNum, tokens});
18
+ }
19
+
20
+ void ApplesoftProgramBuilder::addLine(uint16_t lineNum, const std::string& text) {
21
+ // Simple tokenizer: just store the ASCII text as-is
22
+ // For proper tokenization, use the real tokenizer
23
+ std::vector<uint8_t> tokens(text.begin(), text.end());
24
+ lines_.push_back({lineNum, tokens});
25
+ }
26
+
27
+ std::vector<uint8_t> ApplesoftProgramBuilder::build() const {
28
+ std::vector<uint8_t> result;
29
+ uint16_t addr = baseAddr_;
30
+
31
+ for (const auto& line : lines_) {
32
+ // Calculate next line address
33
+ // Format: [next_addr:2][line_num:2][tokens...][0x00]
34
+ uint16_t nextAddr = addr + 4 + static_cast<uint16_t>(line.tokens.size()) + 1;
35
+
36
+ // Next line address
37
+ result.push_back(nextAddr & 0xFF);
38
+ result.push_back((nextAddr >> 8) & 0xFF);
39
+
40
+ // Line number
41
+ result.push_back(line.lineNum & 0xFF);
42
+ result.push_back((line.lineNum >> 8) & 0xFF);
43
+
44
+ // Tokens
45
+ result.insert(result.end(), line.tokens.begin(), line.tokens.end());
46
+
47
+ // Line terminator
48
+ result.push_back(0x00);
49
+
50
+ addr = nextAddr;
51
+ }
52
+
53
+ // Program terminator
54
+ result.push_back(0x00);
55
+ result.push_back(0x00);
56
+
57
+ return result;
58
+ }
59
+
60
+ std::vector<uint8_t> ApplesoftProgramBuilder::buildWithHeader() const {
61
+ auto program = build();
62
+ uint16_t len = static_cast<uint16_t>(program.size());
63
+
64
+ std::vector<uint8_t> result;
65
+ result.push_back(len & 0xFF);
66
+ result.push_back((len >> 8) & 0xFF);
67
+ result.insert(result.end(), program.begin(), program.end());
68
+
69
+ return result;
70
+ }
71
+
72
+ // ==================== IntegerBasicProgramBuilder ====================
73
+
74
+ IntegerBasicProgramBuilder::IntegerBasicProgramBuilder(uint16_t baseAddr)
75
+ : baseAddr_(baseAddr) {}
76
+
77
+ void IntegerBasicProgramBuilder::addLine(uint16_t lineNum, const std::vector<uint8_t>& tokens) {
78
+ lines_.push_back({lineNum, tokens});
79
+ }
80
+
81
+ std::vector<uint8_t> IntegerBasicProgramBuilder::build() const {
82
+ std::vector<uint8_t> result;
83
+
84
+ for (const auto& line : lines_) {
85
+ // Integer BASIC format: [length:1][line_num_lo:1][line_num_hi:1][tokens...][0x01]
86
+ uint8_t lineLen = 3 + static_cast<uint8_t>(line.tokens.size()) + 1;
87
+
88
+ result.push_back(lineLen);
89
+
90
+ // Line number (little-endian, same as Applesoft)
91
+ result.push_back(line.lineNum & 0xFF);
92
+ result.push_back((line.lineNum >> 8) & 0xFF);
93
+
94
+ // Tokens
95
+ result.insert(result.end(), line.tokens.begin(), line.tokens.end());
96
+
97
+ // Line terminator (0x01 for Integer BASIC)
98
+ result.push_back(0x01);
99
+ }
100
+
101
+ // Program terminator
102
+ result.push_back(0x00);
103
+
104
+ return result;
105
+ }
106
+
107
+ std::vector<uint8_t> IntegerBasicProgramBuilder::buildWithHeader() const {
108
+ auto program = build();
109
+ uint16_t len = static_cast<uint16_t>(program.size());
110
+
111
+ std::vector<uint8_t> result;
112
+ result.push_back(len & 0xFF);
113
+ result.push_back((len >> 8) & 0xFF);
114
+ result.insert(result.end(), program.begin(), program.end());
115
+
116
+ return result;
117
+ }
118
+
119
+ } // namespace test
@@ -0,0 +1,209 @@
1
+ /*
2
+ * basic_program_builder.hpp - Programmatic BASIC token builders for testing
3
+ */
4
+
5
+ #pragma once
6
+
7
+ #include <cstdint>
8
+ #include <string>
9
+ #include <vector>
10
+
11
+ namespace test {
12
+
13
+ /**
14
+ * ApplesoftProgramBuilder - Build tokenized Applesoft BASIC programs
15
+ *
16
+ * Applesoft token format:
17
+ * Each line: [next_addr:2][line_num:2][tokens...][0x00]
18
+ * Program ends with: [0x00][0x00]
19
+ *
20
+ * The base address is typically $0801.
21
+ */
22
+ class ApplesoftProgramBuilder {
23
+ public:
24
+ explicit ApplesoftProgramBuilder(uint16_t baseAddr = 0x0801);
25
+
26
+ // Add a raw tokenized line
27
+ void addLine(uint16_t lineNum, const std::vector<uint8_t>& tokens);
28
+
29
+ // Add a line from ASCII text (minimal tokenization - keywords in uppercase)
30
+ void addLine(uint16_t lineNum, const std::string& text);
31
+
32
+ // Build the complete tokenized program
33
+ std::vector<uint8_t> build() const;
34
+
35
+ // Build with a 2-byte length header prepended (as stored in DOS 3.3 files)
36
+ std::vector<uint8_t> buildWithHeader() const;
37
+
38
+ private:
39
+ struct Line {
40
+ uint16_t lineNum;
41
+ std::vector<uint8_t> tokens;
42
+ };
43
+
44
+ uint16_t baseAddr_;
45
+ std::vector<Line> lines_;
46
+
47
+ // Applesoft token values for common keywords
48
+ static constexpr uint8_t TOK_END = 0x80;
49
+ static constexpr uint8_t TOK_FOR = 0x81;
50
+ static constexpr uint8_t TOK_NEXT = 0x82;
51
+ static constexpr uint8_t TOK_DATA = 0x83;
52
+ static constexpr uint8_t TOK_INPUT = 0x84;
53
+ static constexpr uint8_t TOK_DEL = 0x85;
54
+ static constexpr uint8_t TOK_DIM = 0x86;
55
+ static constexpr uint8_t TOK_READ = 0x87;
56
+ static constexpr uint8_t TOK_GR = 0x88;
57
+ static constexpr uint8_t TOK_TEXT = 0x89;
58
+ static constexpr uint8_t TOK_PR = 0x8A;
59
+ static constexpr uint8_t TOK_IN = 0x8B;
60
+ static constexpr uint8_t TOK_CALL = 0x8C;
61
+ static constexpr uint8_t TOK_PLOT = 0x8D;
62
+ static constexpr uint8_t TOK_HLIN = 0x8E;
63
+ static constexpr uint8_t TOK_VLIN = 0x8F;
64
+ static constexpr uint8_t TOK_HGR2 = 0x90;
65
+ static constexpr uint8_t TOK_HGR = 0x91;
66
+ static constexpr uint8_t TOK_HCOLOR = 0x92;
67
+ static constexpr uint8_t TOK_HPLOT = 0x93;
68
+ static constexpr uint8_t TOK_DRAW = 0x94;
69
+ static constexpr uint8_t TOK_XDRAW = 0x95;
70
+ static constexpr uint8_t TOK_HTAB = 0x96;
71
+ static constexpr uint8_t TOK_HOME = 0x97;
72
+ static constexpr uint8_t TOK_ROT = 0x98;
73
+ static constexpr uint8_t TOK_SCALE = 0x99;
74
+ static constexpr uint8_t TOK_SHLOAD = 0x9A;
75
+ static constexpr uint8_t TOK_TRACE = 0x9B;
76
+ static constexpr uint8_t TOK_NOTRACE= 0x9C;
77
+ static constexpr uint8_t TOK_NORMAL = 0x9D;
78
+ static constexpr uint8_t TOK_INVERSE= 0x9E;
79
+ static constexpr uint8_t TOK_FLASH = 0x9F;
80
+ static constexpr uint8_t TOK_COLOR = 0xA0;
81
+ static constexpr uint8_t TOK_POP = 0xA1;
82
+ static constexpr uint8_t TOK_VTAB = 0xA2;
83
+ static constexpr uint8_t TOK_HIMEM = 0xA3;
84
+ static constexpr uint8_t TOK_LOMEM = 0xA4;
85
+ static constexpr uint8_t TOK_ONERR = 0xA5;
86
+ static constexpr uint8_t TOK_RESUME = 0xA6;
87
+ static constexpr uint8_t TOK_RECALL = 0xA7;
88
+ static constexpr uint8_t TOK_STORE = 0xA8;
89
+ static constexpr uint8_t TOK_SPEED = 0xA9;
90
+ static constexpr uint8_t TOK_LET = 0xAA;
91
+ static constexpr uint8_t TOK_GOTO = 0xAB;
92
+ static constexpr uint8_t TOK_RUN = 0xAC;
93
+ static constexpr uint8_t TOK_IF = 0xAD;
94
+ static constexpr uint8_t TOK_RESTORE= 0xAE;
95
+ static constexpr uint8_t TOK_AMP = 0xAF;
96
+ static constexpr uint8_t TOK_GOSUB = 0xB0;
97
+ static constexpr uint8_t TOK_RETURN = 0xB1;
98
+ static constexpr uint8_t TOK_REM = 0xB2;
99
+ static constexpr uint8_t TOK_STOP = 0xB3;
100
+ static constexpr uint8_t TOK_ON = 0xB4;
101
+ static constexpr uint8_t TOK_WAIT = 0xB5;
102
+ static constexpr uint8_t TOK_LOAD = 0xB6;
103
+ static constexpr uint8_t TOK_SAVE = 0xB7;
104
+ static constexpr uint8_t TOK_DEF = 0xB8;
105
+ static constexpr uint8_t TOK_POKE = 0xB9;
106
+ static constexpr uint8_t TOK_PRINT = 0xBA;
107
+ static constexpr uint8_t TOK_CONT = 0xBB;
108
+ static constexpr uint8_t TOK_LIST = 0xBC;
109
+ static constexpr uint8_t TOK_CLEAR = 0xBD;
110
+ static constexpr uint8_t TOK_GET = 0xBE;
111
+ static constexpr uint8_t TOK_NEW = 0xBF;
112
+ // Functions
113
+ static constexpr uint8_t TOK_TAB = 0xC0;
114
+ static constexpr uint8_t TOK_TO = 0xC1;
115
+ static constexpr uint8_t TOK_FN = 0xC2;
116
+ static constexpr uint8_t TOK_SPC = 0xC3;
117
+ static constexpr uint8_t TOK_THEN = 0xC4;
118
+ static constexpr uint8_t TOK_AT = 0xC5;
119
+ static constexpr uint8_t TOK_NOT = 0xC6;
120
+ static constexpr uint8_t TOK_STEP = 0xC7;
121
+ static constexpr uint8_t TOK_PLUS = 0xC8;
122
+ static constexpr uint8_t TOK_MINUS = 0xC9;
123
+ static constexpr uint8_t TOK_MULT = 0xCA;
124
+ static constexpr uint8_t TOK_DIV = 0xCB;
125
+ static constexpr uint8_t TOK_POWER = 0xCC;
126
+ static constexpr uint8_t TOK_AND = 0xCD;
127
+ static constexpr uint8_t TOK_OR = 0xCE;
128
+ static constexpr uint8_t TOK_GT = 0xCF;
129
+ static constexpr uint8_t TOK_EQ = 0xD0;
130
+ static constexpr uint8_t TOK_LT = 0xD1;
131
+ static constexpr uint8_t TOK_SGN = 0xD2;
132
+ static constexpr uint8_t TOK_INT = 0xD3;
133
+ static constexpr uint8_t TOK_ABS = 0xD4;
134
+ static constexpr uint8_t TOK_USR = 0xD5;
135
+ static constexpr uint8_t TOK_FRE = 0xD6;
136
+ static constexpr uint8_t TOK_SCRN = 0xD7;
137
+ static constexpr uint8_t TOK_PDL = 0xD8;
138
+ static constexpr uint8_t TOK_POS = 0xD9;
139
+ static constexpr uint8_t TOK_SQR = 0xDA;
140
+ static constexpr uint8_t TOK_RND = 0xDB;
141
+ static constexpr uint8_t TOK_LOG = 0xDC;
142
+ static constexpr uint8_t TOK_EXP = 0xDD;
143
+ static constexpr uint8_t TOK_COS = 0xDE;
144
+ static constexpr uint8_t TOK_SIN = 0xDF;
145
+ static constexpr uint8_t TOK_TAN = 0xE0;
146
+ static constexpr uint8_t TOK_ATN = 0xE1;
147
+ static constexpr uint8_t TOK_PEEK = 0xE2;
148
+ static constexpr uint8_t TOK_LEN = 0xE3;
149
+ static constexpr uint8_t TOK_STR = 0xE4;
150
+ static constexpr uint8_t TOK_VAL = 0xE5;
151
+ static constexpr uint8_t TOK_ASC = 0xE6;
152
+ static constexpr uint8_t TOK_CHR = 0xE7;
153
+ static constexpr uint8_t TOK_LEFT = 0xE8;
154
+ static constexpr uint8_t TOK_RIGHT = 0xE9;
155
+ static constexpr uint8_t TOK_MID = 0xEA;
156
+ };
157
+
158
+ /**
159
+ * IntegerBasicProgramBuilder - Build tokenized Integer BASIC programs
160
+ *
161
+ * Integer BASIC token format (different from Applesoft):
162
+ * Each line: [length:1][line_num:2][tokens...][0x01]
163
+ * Program ends with: [0x00]
164
+ *
165
+ * Integer BASIC tokens are quite different from Applesoft.
166
+ * Line numbers are stored in little-endian format (low byte first).
167
+ */
168
+ class IntegerBasicProgramBuilder {
169
+ public:
170
+ explicit IntegerBasicProgramBuilder(uint16_t baseAddr = 0x0801);
171
+
172
+ // Add a raw tokenized line
173
+ void addLine(uint16_t lineNum, const std::vector<uint8_t>& tokens);
174
+
175
+ // Build the complete tokenized program
176
+ std::vector<uint8_t> build() const;
177
+
178
+ // Build with a 2-byte length header prepended
179
+ std::vector<uint8_t> buildWithHeader() const;
180
+
181
+ // Integer BASIC token constants
182
+ static constexpr uint8_t TOK_FOR = 0x20;
183
+ static constexpr uint8_t TOK_GOTO = 0x22;
184
+ static constexpr uint8_t TOK_GOSUB = 0x24;
185
+ static constexpr uint8_t TOK_RETURN = 0x25;
186
+ static constexpr uint8_t TOK_REM = 0x5D;
187
+ static constexpr uint8_t TOK_LET = 0x2A;
188
+ static constexpr uint8_t TOK_IF = 0x28;
189
+ static constexpr uint8_t TOK_PRINT = 0x32;
190
+ static constexpr uint8_t TOK_INPUT = 0x21;
191
+ static constexpr uint8_t TOK_END = 0x51;
192
+ static constexpr uint8_t TOK_THEN = 0x29;
193
+ static constexpr uint8_t TOK_TO = 0x5A;
194
+ static constexpr uint8_t TOK_STEP = 0x5B;
195
+ static constexpr uint8_t TOK_NEXT = 0x23;
196
+ // Integer BASIC uses 0xB0-0xB9 for digits in numeric tokens
197
+ static constexpr uint8_t TOK_NUM_PREFIX = 0xB0;
198
+
199
+ private:
200
+ struct Line {
201
+ uint16_t lineNum;
202
+ std::vector<uint8_t> tokens;
203
+ };
204
+
205
+ uint16_t baseAddr_;
206
+ std::vector<Line> lines_;
207
+ };
208
+
209
+ } // namespace test