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,661 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <meta
7
+ name="description"
8
+ content="Apple II Enhanced emulator for the browser"
9
+ />
10
+ <meta name="theme-color" content="#0a0a0b" />
11
+ <meta name="mobile-web-app-capable" content="yes" />
12
+ <meta
13
+ name="apple-mobile-web-app-status-bar-style"
14
+ content="black-translucent"
15
+ />
16
+ <meta name="apple-mobile-web-app-title" content="Apple //e" />
17
+ <title>Apple //e Emulator</title>
18
+ <link rel="manifest" href="/manifest.json" />
19
+ <link rel="icon" type="image/svg+xml" href="/icons/icon-192.svg" />
20
+ <link rel="apple-touch-icon" href="/icons/icon-192.svg" />
21
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
22
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
23
+ <link
24
+ href="https://fonts.googleapis.com/css2?family=EB+Garamond:ital,wght@0,400;0,500;0,600;1,400&family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
25
+ rel="stylesheet"
26
+ />
27
+ </head>
28
+ <body>
29
+ <div id="app">
30
+ <header>
31
+ <div class="header-left">
32
+ <div class="logo">
33
+ <img
34
+ class="logo-image"
35
+ src="/assets/apple-logo.png"
36
+ alt="Apple //e"
37
+ />
38
+ <span id="app-version" class="app-version"></span>
39
+ </div>
40
+ <!--<span class="tagline">Apple II Enhanced Emulator</span>-->
41
+ <a
42
+ href="https://RetroTech71.co.uk"
43
+ target="_blank"
44
+ rel="noopener"
45
+ class="retro-brand"
46
+ >
47
+ <span
48
+ class="retro-brand-text"
49
+ data-text="RetroTech71.co.uk"
50
+ >RetroTech71.co.uk</span
51
+ >
52
+ </a>
53
+ </div>
54
+ <nav class="header-controls">
55
+ <!-- Power, Reset, Reboot (standalone top-level buttons) -->
56
+ <button
57
+ id="btn-power"
58
+ class="control-btn power-btn off"
59
+ title="Power On"
60
+ >
61
+ <svg
62
+ viewBox="0 0 24 24"
63
+ fill="none"
64
+ stroke="currentColor"
65
+ stroke-width="2"
66
+ >
67
+ <path d="M12 2v10M18.4 6.6a9 9 0 1 1-12.8 0" />
68
+ </svg>
69
+ </button>
70
+ <button
71
+ id="btn-warm-reset"
72
+ class="header-text-btn"
73
+ title="Ctrl+Reset (warm reset, preserves memory)"
74
+ >
75
+ Ctrl+Reset
76
+ </button>
77
+ <button
78
+ id="btn-cold-reset"
79
+ class="header-text-btn"
80
+ title="Cold Reset (full restart)"
81
+ >
82
+ Reboot
83
+ </button>
84
+
85
+ <!-- File menu (state management) -->
86
+ <div class="header-menu-container" id="file-menu-container">
87
+ <button class="header-menu-trigger" id="btn-file-menu">
88
+ <span>File</span>
89
+ <svg
90
+ class="menu-chevron"
91
+ viewBox="0 0 12 12"
92
+ width="10"
93
+ height="10"
94
+ >
95
+ <path
96
+ d="M3 5l3 3 3-3"
97
+ fill="none"
98
+ stroke="currentColor"
99
+ stroke-width="1.5"
100
+ />
101
+ </svg>
102
+ </button>
103
+ <div class="header-menu" id="file-menu">
104
+ <div class="header-menu-item menu-toggle-item">
105
+ <div class="state-row-label">
106
+ <span>Auto-Save</span>
107
+ <span class="state-row-hint"
108
+ >Save every 5 seconds</span
109
+ >
110
+ </div>
111
+ <label class="toggle-switch">
112
+ <input
113
+ type="checkbox"
114
+ id="autosave-toggle"
115
+ checked
116
+ />
117
+ <span class="toggle-slider"></span>
118
+ </label>
119
+ </div>
120
+ <div class="header-menu-separator"></div>
121
+ <button
122
+ class="header-menu-item"
123
+ id="btn-save-states"
124
+ >
125
+ <span>Save States...</span>
126
+ </button>
127
+ <div
128
+ id="state-last-saved"
129
+ class="header-menu-footer"
130
+ ></div>
131
+ </div>
132
+ </div>
133
+
134
+ <!-- View menu -->
135
+ <div class="header-menu-container" id="view-menu-container">
136
+ <button class="header-menu-trigger" id="btn-view-menu">
137
+ <span>View</span>
138
+ <svg
139
+ class="menu-chevron"
140
+ viewBox="0 0 12 12"
141
+ width="10"
142
+ height="10"
143
+ >
144
+ <path
145
+ d="M3 5l3 3 3-3"
146
+ fill="none"
147
+ stroke="currentColor"
148
+ stroke-width="1.5"
149
+ />
150
+ </svg>
151
+ </button>
152
+ <div class="header-menu" id="view-menu">
153
+ <div
154
+ class="header-menu-item menu-toggle-item theme-selector-row"
155
+ >
156
+ <span>Theme</span>
157
+ <div class="theme-btn-group">
158
+ <button
159
+ class="theme-btn"
160
+ data-theme="light"
161
+ title="Light"
162
+ >
163
+ <svg
164
+ viewBox="0 0 16 16"
165
+ width="14"
166
+ height="14"
167
+ fill="none"
168
+ stroke="currentColor"
169
+ stroke-width="1.5"
170
+ >
171
+ <circle cx="8" cy="8" r="3.5" />
172
+ <path
173
+ d="M8 1.5v1.5M8 13v1.5M1.5 8H3M13 8h1.5M3.17 3.17l1.06 1.06M11.77 11.77l1.06 1.06M3.17 12.83l1.06-1.06M11.77 4.23l1.06-1.06"
174
+ />
175
+ </svg>
176
+ </button>
177
+ <button
178
+ class="theme-btn"
179
+ data-theme="dark"
180
+ title="Dark"
181
+ >
182
+ <svg
183
+ viewBox="0 0 16 16"
184
+ width="14"
185
+ height="14"
186
+ fill="none"
187
+ stroke="currentColor"
188
+ stroke-width="1.5"
189
+ >
190
+ <path
191
+ d="M13.5 8.5a5.5 5.5 0 0 1-7-7 6 6 0 1 0 7 7z"
192
+ />
193
+ </svg>
194
+ </button>
195
+ <button
196
+ class="theme-btn"
197
+ data-theme="system"
198
+ title="System"
199
+ >
200
+ <svg
201
+ viewBox="0 0 16 16"
202
+ width="14"
203
+ height="14"
204
+ fill="none"
205
+ stroke="currentColor"
206
+ stroke-width="1.5"
207
+ >
208
+ <rect
209
+ x="2"
210
+ y="3"
211
+ width="12"
212
+ height="9"
213
+ rx="1.5"
214
+ />
215
+ <path d="M6 14h4" />
216
+ </svg>
217
+ </button>
218
+ </div>
219
+ </div>
220
+ <div class="header-menu-separator"></div>
221
+ <button class="header-menu-item" id="btn-drives">
222
+ <span>Disk Drives</span>
223
+ </button>
224
+ <button class="header-menu-item" id="btn-hard-drives">
225
+ <span>SmartPort Drives</span>
226
+ </button>
227
+ <button
228
+ class="header-menu-item"
229
+ id="btn-file-explorer"
230
+ >
231
+ <span>File Explorer</span>
232
+ </button>
233
+ <div class="header-menu-separator"></div>
234
+ <button class="header-menu-item" id="btn-display">
235
+ <span>Display</span>
236
+ </button>
237
+ <button class="header-menu-item" id="btn-joystick">
238
+ <span>Joystick / Paddles</span>
239
+ </button>
240
+ <button class="header-menu-item" id="btn-slots">
241
+ <span>Expansion Slots</span>
242
+ </button>
243
+ </div>
244
+ </div>
245
+
246
+ <!-- Debug menu -->
247
+ <div
248
+ class="header-menu-container"
249
+ id="debug-menu-container"
250
+ >
251
+ <button class="header-menu-trigger" id="btn-debug-menu">
252
+ <span>Debug</span>
253
+ <svg
254
+ class="menu-chevron"
255
+ viewBox="0 0 12 12"
256
+ width="10"
257
+ height="10"
258
+ >
259
+ <path
260
+ d="M3 5l3 3 3-3"
261
+ fill="none"
262
+ stroke="currentColor"
263
+ stroke-width="1.5"
264
+ />
265
+ </svg>
266
+ </button>
267
+ <div class="header-menu" id="debug-menu">
268
+ <button class="header-menu-item" data-window="cpu">
269
+ CPU Debugger
270
+ </button>
271
+ <button
272
+ class="header-menu-item"
273
+ data-window="switches"
274
+ >
275
+ Soft Switches
276
+ </button>
277
+ <button
278
+ class="header-menu-item"
279
+ data-window="memmap"
280
+ >
281
+ Memory Map
282
+ </button>
283
+ <div class="header-menu-separator"></div>
284
+ <button
285
+ class="header-menu-item"
286
+ data-window="memory"
287
+ >
288
+ Memory Browser
289
+ </button>
290
+ <button
291
+ class="header-menu-item"
292
+ data-window="heatmap"
293
+ >
294
+ Memory Heat Map
295
+ </button>
296
+ <button
297
+ class="header-menu-item"
298
+ data-window="stack"
299
+ >
300
+ Stack Viewer
301
+ </button>
302
+ <button
303
+ class="header-menu-item"
304
+ data-window="zeropage"
305
+ >
306
+ Zero Page Watch
307
+ </button>
308
+ <button
309
+ class="header-menu-item"
310
+ data-window="trace"
311
+ >
312
+ Instruction Trace
313
+ </button>
314
+ <div class="header-menu-separator"></div>
315
+ <button
316
+ class="header-menu-item"
317
+ data-window="mockingboard"
318
+ >
319
+ Mockingboard
320
+ </button>
321
+ <button
322
+ class="header-menu-item"
323
+ data-window="mouse-card"
324
+ >
325
+ Mouse Card
326
+ </button>
327
+ </div>
328
+ </div>
329
+
330
+ <!-- Tools menu -->
331
+ <div class="header-menu-container" id="dev-menu-container">
332
+ <button class="header-menu-trigger" id="btn-dev-menu">
333
+ <span>Dev</span>
334
+ <svg
335
+ class="menu-chevron"
336
+ viewBox="0 0 12 12"
337
+ width="10"
338
+ height="10"
339
+ >
340
+ <path
341
+ d="M3 5l3 3 3-3"
342
+ fill="none"
343
+ stroke="currentColor"
344
+ stroke-width="1.5"
345
+ />
346
+ </svg>
347
+ </button>
348
+ <div class="header-menu" id="dev-menu">
349
+ <button
350
+ class="header-menu-item"
351
+ data-window="basic"
352
+ >
353
+ Applesoft BASIC
354
+ </button>
355
+ <button
356
+ class="header-menu-item"
357
+ data-window="assembler"
358
+ >
359
+ Assembler
360
+ </button>
361
+ </div>
362
+ </div>
363
+
364
+ <!-- Standalone buttons -->
365
+ <div class="control-group">
366
+ <button
367
+ id="btn-fullscreen"
368
+ class="control-btn"
369
+ title="Full Page Mode (Ctrl+Escape to exit)"
370
+ aria-label="Full Page Mode"
371
+ >
372
+ <svg
373
+ viewBox="0 0 24 24"
374
+ fill="none"
375
+ stroke="currentColor"
376
+ stroke-width="2"
377
+ >
378
+ <path
379
+ d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"
380
+ />
381
+ </svg>
382
+ </button>
383
+ <div class="sound-control-wrapper">
384
+ <button
385
+ id="btn-sound"
386
+ class="control-btn"
387
+ title="Sound Settings"
388
+ aria-label="Sound Settings"
389
+ >
390
+ <svg
391
+ class="icon-unmuted"
392
+ viewBox="0 0 24 24"
393
+ fill="none"
394
+ stroke="currentColor"
395
+ stroke-width="2"
396
+ >
397
+ <path d="M11 5L6 9H2v6h4l5 4V5z" />
398
+ <path
399
+ d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"
400
+ />
401
+ </svg>
402
+ <svg
403
+ class="icon-muted hidden"
404
+ viewBox="0 0 24 24"
405
+ fill="none"
406
+ stroke="currentColor"
407
+ stroke-width="2"
408
+ >
409
+ <path d="M11 5L6 9H2v6h4l5 4V5z" />
410
+ <line x1="23" y1="9" x2="17" y2="15" />
411
+ <line x1="17" y1="9" x2="23" y2="15" />
412
+ </svg>
413
+ </button>
414
+ <div id="sound-popup" class="sound-popup hidden">
415
+ <div class="sound-popup-row">
416
+ <label for="volume-slider">Volume</label>
417
+ <input
418
+ type="range"
419
+ id="volume-slider"
420
+ min="0"
421
+ max="100"
422
+ value="50"
423
+ />
424
+ <span id="volume-value" aria-live="polite"
425
+ >50%</span
426
+ >
427
+ </div>
428
+ <div class="sound-popup-row">
429
+ <label>Mute</label>
430
+ <label class="toggle-switch">
431
+ <input
432
+ type="checkbox"
433
+ id="mute-toggle"
434
+ />
435
+ <span class="toggle-slider"></span>
436
+ </label>
437
+ </div>
438
+ <div class="sound-popup-row">
439
+ <label>Drive Sounds</label>
440
+ <label class="toggle-switch">
441
+ <input
442
+ type="checkbox"
443
+ id="drive-sounds-toggle"
444
+ checked
445
+ />
446
+ <span class="toggle-slider"></span>
447
+ </label>
448
+ </div>
449
+ </div>
450
+ </div>
451
+ <button
452
+ id="btn-agent"
453
+ class="control-btn agent-btn disconnected"
454
+ title="Connect to Agent - The Agent MCP Server must be Running"
455
+ >
456
+ <svg
457
+ viewBox="0 0 24 24"
458
+ width="16"
459
+ height="16"
460
+ fill="currentColor"
461
+ >
462
+ <path
463
+ d="M12 2l1.5 4.5L18 8l-4.5 1.5L12 14l-1.5-4.5L6 8l4.5-1.5L12 2zM6 16l.75 2.25L9 19l-2.25.75L6 22l-.75-2.25L3 19l2.25-.75L6 16zM18 16l.75 2.25L21 19l-2.25.75L18 22l-.75-2.25L15 19l2.25-.75L18 16z"
464
+ />
465
+ </svg>
466
+ </button>
467
+ </div>
468
+
469
+ <!-- Help menu -->
470
+ <div class="header-menu-container" id="help-menu-container">
471
+ <button
472
+ class="header-menu-trigger"
473
+ id="btn-help-menu"
474
+ title="Help (F1)"
475
+ >
476
+ <svg
477
+ viewBox="0 0 24 24"
478
+ width="14"
479
+ height="14"
480
+ fill="none"
481
+ stroke="currentColor"
482
+ stroke-width="2"
483
+ stroke-linecap="round"
484
+ stroke-linejoin="round"
485
+ >
486
+ <circle cx="12" cy="12" r="10" />
487
+ <path
488
+ d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3"
489
+ />
490
+ <line x1="12" y1="17" x2="12.01" y2="17" />
491
+ </svg>
492
+ <span class="update-badge" id="update-badge"></span>
493
+ <svg
494
+ class="menu-chevron"
495
+ viewBox="0 0 12 12"
496
+ width="10"
497
+ height="10"
498
+ >
499
+ <path
500
+ d="M3 5l3 3 3-3"
501
+ fill="none"
502
+ stroke="currentColor"
503
+ stroke-width="1.5"
504
+ />
505
+ </svg>
506
+ </button>
507
+ <div
508
+ class="header-menu header-menu-right"
509
+ id="help-menu"
510
+ >
511
+ <button class="header-menu-item" id="btn-help">
512
+ <span>Documentation</span>
513
+ <span class="menu-hint">F1</span>
514
+ </button>
515
+ <button
516
+ class="header-menu-item"
517
+ id="btn-release-notes-menu"
518
+ >
519
+ <span>Release Notes</span>
520
+ </button>
521
+ <div class="header-menu-separator"></div>
522
+ <button class="header-menu-item" id="btn-update">
523
+ <span>Check for Updates</span>
524
+ </button>
525
+ </div>
526
+ </div>
527
+ </nav>
528
+ </header>
529
+
530
+ <main>
531
+ <div class="emulator-section">
532
+ <div id="monitor-frame">
533
+ <canvas id="screen"></canvas>
534
+ </div>
535
+ </div>
536
+ </main>
537
+
538
+ <!-- Full page mode toolbar (auto-hiding) -->
539
+ <div class="full-page-toolbar-wrapper">
540
+ <div class="full-page-toolbar-trigger"></div>
541
+ <div class="full-page-toolbar" id="full-page-toolbar">
542
+ <button
543
+ id="fp-power"
544
+ class="fp-toolbar-btn fp-power-btn off"
545
+ title="Power"
546
+ >
547
+ <svg
548
+ viewBox="0 0 24 24"
549
+ fill="none"
550
+ stroke="currentColor"
551
+ stroke-width="2"
552
+ >
553
+ <path d="M12 2v10M18.4 6.6a9 9 0 1 1-12.8 0" />
554
+ </svg>
555
+ </button>
556
+ <div class="fp-toolbar-separator"></div>
557
+ <button
558
+ id="fp-warm-reset"
559
+ class="fp-toolbar-btn fp-text-btn"
560
+ title="Ctrl+Reset (warm reset)"
561
+ >
562
+ Ctrl+Reset
563
+ </button>
564
+ <button
565
+ id="fp-cold-reset"
566
+ class="fp-toolbar-btn fp-text-btn"
567
+ title="Cold Reset (full restart)"
568
+ >
569
+ Reboot
570
+ </button>
571
+ <div class="fp-toolbar-separator"></div>
572
+ <button
573
+ id="fp-exit"
574
+ class="fp-toolbar-btn fp-text-btn fp-exit-btn"
575
+ title="Exit Full Page Mode"
576
+ >
577
+ Exit
578
+ </button>
579
+ </div>
580
+ </div>
581
+
582
+
583
+ <div id="loading">
584
+ <div class="loader">
585
+ <div class="loader-ring"></div>
586
+ <div class="loader-ring"></div>
587
+ <div class="loader-ring"></div>
588
+ </div>
589
+ <p>Initializing Apple //e...</p>
590
+ </div>
591
+
592
+ <!-- Power On Reminder -->
593
+ <div id="power-reminder" class="power-reminder hidden">
594
+ <div class="reminder-content">
595
+ <div class="reminder-icon">⚡</div>
596
+ <div class="reminder-text">
597
+ <span class="reminder-title">Ready to go!</span>
598
+ <span class="reminder-hint"
599
+ >Click the <strong>power button</strong> to start
600
+ the Apple //e</span
601
+ >
602
+ </div>
603
+ </div>
604
+ <div class="reminder-arrow"></div>
605
+ </div>
606
+
607
+ <div id="basic-reminder" class="floating-reminder hidden">
608
+ <div class="reminder-content">
609
+ <div class="reminder-text">
610
+ <span class="reminder-hint"
611
+ >No disk? Press <strong>Ctrl+Reset</strong> for
612
+ Apple II BASIC</span
613
+ >
614
+ </div>
615
+ </div>
616
+ <div class="reminder-arrow"></div>
617
+ </div>
618
+
619
+ <!-- Save Disk Modal -->
620
+ <dialog id="save-disk-modal" class="modal">
621
+ <div class="modal-content">
622
+ <div class="modal-header">
623
+ <h3>Save Disk Image?</h3>
624
+ </div>
625
+ <div class="modal-body">
626
+ <p>
627
+ This disk has been modified. Would you like to save
628
+ it before ejecting?
629
+ </p>
630
+ <div class="modal-input-group">
631
+ <label for="save-disk-filename">Filename:</label>
632
+ <input
633
+ type="text"
634
+ id="save-disk-filename"
635
+ placeholder="disk.dsk"
636
+ />
637
+ </div>
638
+ </div>
639
+ <div class="modal-footer">
640
+ <button
641
+ id="save-disk-cancel"
642
+ class="modal-btn modal-btn-secondary"
643
+ >
644
+ Don't Save
645
+ </button>
646
+ <button
647
+ id="save-disk-confirm"
648
+ class="modal-btn modal-btn-primary"
649
+ >
650
+ Save
651
+ </button>
652
+ </div>
653
+ </div>
654
+ </dialog>
655
+ </div>
656
+
657
+ <script defer src="https://analytics.retrotech71.co.uk/script.js" data-website-id="8088b282-f7f1-453a-9622-c111f63cc5c1"></script>
658
+ <script src="/a2e.js"></script>
659
+ <script type="module" src="/src/js/main.js"></script>
660
+ </body>
661
+ </html>