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,516 @@
1
+ # Debugger
2
+
3
+ The emulator includes a comprehensive suite of debug windows accessible via the Debug menu. These tools provide deep visibility into the CPU state, memory contents, peripheral hardware, and BASIC program execution.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ - [Overview](#overview)
10
+ - [CPU Debugger](#cpu-debugger)
11
+ - [Toolbar and Execution Control](#toolbar-and-execution-control)
12
+ - [Register Display](#register-display)
13
+ - [Disassembly View](#disassembly-view)
14
+ - [Breakpoints](#breakpoints)
15
+ - [Watchpoints](#watchpoints)
16
+ - [Watch Expressions](#watch-expressions)
17
+ - [Beam Breakpoints](#beam-breakpoints)
18
+ - [Bookmarks](#bookmarks)
19
+ - [Symbol Resolution](#symbol-resolution)
20
+ - [User Labels](#user-labels)
21
+ - [Memory Browser](#memory-browser)
22
+ - [Memory Heat Map](#memory-heat-map)
23
+ - [Memory Map](#memory-map)
24
+ - [Stack Viewer](#stack-viewer)
25
+ - [Zero Page Watch](#zero-page-watch)
26
+ - [Soft Switch Monitor](#soft-switch-monitor)
27
+ - [Mockingboard Debug](#mockingboard-debug)
28
+ - [Mouse Card Debug](#mouse-card-debug)
29
+ - [BASIC Program Window](#basic-program-window)
30
+ - [Editor](#editor)
31
+ - [BASIC Debugger](#basic-debugger)
32
+ - [Variable Inspector](#variable-inspector)
33
+ - [BASIC Breakpoints](#basic-breakpoints)
34
+ - [Rule Builder](#rule-builder)
35
+ - [Assembler Editor](#assembler-editor)
36
+ - [Instruction Trace](#instruction-trace)
37
+ - [Keyboard Shortcuts](#keyboard-shortcuts)
38
+ - [Source Files](#source-files)
39
+
40
+ ---
41
+
42
+ ## Overview
43
+
44
+ All debug windows extend the `BaseWindow` class from the window manager system. They share common behaviors: draggable/resizable chrome, persistence of position and size via localStorage, and automatic refresh when the emulator is paused or single-stepping.
45
+
46
+ Debug windows are organized into categories:
47
+
48
+ | Category | Windows |
49
+ |----------|---------|
50
+ | CPU & Memory | CPU Debugger, Memory Browser, Memory Heat Map, Memory Map, Stack Viewer, Zero Page Watch |
51
+ | Hardware | Soft Switch Monitor, Mockingboard, Mouse Card |
52
+ | Programming | BASIC Program Window, Assembler Editor |
53
+ | Tools | Rule Builder, Instruction Trace |
54
+
55
+ ---
56
+
57
+ ## CPU Debugger
58
+
59
+ The CPU Debugger (`cpu-debugger-window.js`) is the primary debug tool, providing register inspection, disassembly, breakpoint management, and stepping controls.
60
+
61
+ ### Toolbar and Execution Control
62
+
63
+ The toolbar provides:
64
+
65
+ - **Run** (F5): Resume execution from the current PC
66
+ - **Pause**: Break execution at the current instruction
67
+ - **Step Into** (F11): Execute a single instruction
68
+ - **Step Over** (F10): Execute the current instruction; if it is a JSR, run until the subroutine returns
69
+ - **Step Out** (Shift+F11): Run until the current subroutine returns (RTS/RTI)
70
+ - **Status indicator**: Shows RUNNING or PAUSED state
71
+
72
+ ### Register Display
73
+
74
+ The register section shows the current CPU state organized into groups:
75
+
76
+ **REGS section:**
77
+ - A, X, Y registers (8-bit hex)
78
+ - SP (stack pointer, 8-bit hex)
79
+ - PC (program counter, 16-bit hex)
80
+
81
+ **FLAGS section:**
82
+ - Individual status flags: N (Negative), V (Overflow), B (Break), D (Decimal), I (Interrupt Disable), Z (Zero), C (Carry)
83
+ - Active flags are visually highlighted
84
+
85
+ **TIMING section:**
86
+ - CYC: Total CPU cycles since reset
87
+ - Scanline and horizontal position (beam position)
88
+
89
+ Changed register values are highlighted to show what was modified by the last instruction.
90
+
91
+ ### Disassembly View
92
+
93
+ The disassembly panel shows a scrollable view of decoded 65C02 instructions centered around the current PC. Features include:
94
+
95
+ - Addresses with symbol annotations from the built-in symbol table
96
+ - Operand values resolved to known symbol names (soft switches, ROM routines, zero page locations)
97
+ - Color-coded symbol categories (zero page, soft switches, disk, ROM, BASIC, vectors, I/O)
98
+ - Current instruction highlighted
99
+ - Breakpoint markers in the gutter (click to toggle)
100
+ - Address bookmarks for quick navigation
101
+ - Profile heat overlay (optional) showing instruction execution frequency
102
+
103
+ The view can be navigated by clicking addresses or using the address input to jump to any location. When a disassembly view address is set manually, it overrides the PC-centered default.
104
+
105
+ ### Breakpoints
106
+
107
+ Execution breakpoints pause the emulator when the program counter reaches a specified address. The `BreakpointManager` provides:
108
+
109
+ | Feature | Description |
110
+ |---------|-------------|
111
+ | Address breakpoints | Break at a specific PC address |
112
+ | Range breakpoints | Break anywhere within an address range (start to end) |
113
+ | Conditional breakpoints | Break only when a C-style condition expression evaluates to true |
114
+ | Hit count targets | Break only after the Nth hit |
115
+ | Enable/disable | Toggle breakpoints without removing them |
116
+ | Temporary breakpoints | Used internally for Step Over / Step Out |
117
+
118
+ Breakpoints are persisted to localStorage (`a2e-breakpoints-v2`) and synchronized with the WASM module. Conditional breakpoints use the C++ condition evaluator (`src/core/debug/`) that supports register references (`A`, `X`, `Y`, `PC`, `SP`, `P`), memory reads (`[addr]`, `[addr,16]`), arithmetic operators, and logical combinators.
119
+
120
+ ### Watchpoints
121
+
122
+ Watchpoints monitor memory access at specific addresses:
123
+
124
+ | Type | Trigger |
125
+ |------|---------|
126
+ | Read | Breaks when the address is read |
127
+ | Write | Breaks when the address is written |
128
+ | Read/Write | Breaks on either access type |
129
+
130
+ Watchpoints support the same conditional expressions as breakpoints. They are managed through the same `BreakpointManager` with a `type` field distinguishing them from execution breakpoints.
131
+
132
+ ### Watch Expressions
133
+
134
+ The Watch panel allows arbitrary C-style expressions to be evaluated on each pause/step. Expressions can reference:
135
+
136
+ - CPU registers: `A`, `X`, `Y`, `SP`, `PC`, `P`
137
+ - Memory reads: `[address]` for 8-bit, `[address,16]` for 16-bit
138
+ - Arithmetic: `+`, `-`, `*`, `/`, `%`, `&`, `|`, `^`, `~`, `<<`, `>>`
139
+ - Comparison: `==`, `!=`, `<`, `>`, `<=`, `>=`
140
+
141
+ Watch values are displayed with change highlighting when values differ from the previous evaluation.
142
+
143
+ ### Beam Breakpoints
144
+
145
+ Beam breakpoints pause execution at a specific video scanline and optional horizontal position. This is useful for debugging video timing-sensitive code. Each beam breakpoint has:
146
+
147
+ - Scanline number (0-261)
148
+ - Horizontal position (optional)
149
+ - Enable/disable toggle
150
+ - Mode selection
151
+
152
+ ### Bookmarks
153
+
154
+ Address bookmarks provide quick navigation to frequently visited code locations. Bookmarks are shown as markers in the disassembly gutter and stored in localStorage.
155
+
156
+ ### Symbol Resolution
157
+
158
+ The built-in symbol table (`symbols.js`) provides names and descriptions for hundreds of Apple IIe addresses across categories:
159
+
160
+ | Category | Examples |
161
+ |----------|---------|
162
+ | Zero Page | LOMEM, WNDLFT, CH, CV, BASL, TXTTAB, VARTAB |
163
+ | Soft Switches | TEXT, MIXED, PAGE2, HIRES, 80COL, DHIRES |
164
+ | ROM Routines | COUT, RDKEY, HOME, PRBYTE, INIT |
165
+ | Disk | RWTS, IOB, DOS entry points |
166
+ | BASIC | Token handler addresses |
167
+ | Vectors | RESET, IRQ, NMI, BRK |
168
+ | I/O | Keyboard, speaker, game I/O |
169
+
170
+ Symbols are color-coded by category in the disassembly view.
171
+
172
+ ### User Labels
173
+
174
+ The `LabelManager` allows users to define custom labels and inline comments for any address. User labels override or supplement the built-in symbol table. Imported symbol files (from assemblers) are also supported. Labels persist to localStorage (`a2e-user-labels`).
175
+
176
+ ---
177
+
178
+ ## Memory Browser
179
+
180
+ The Memory Browser (`memory-browser-window.js`) provides a scrollable hex/ASCII view of the full 64 KB address space.
181
+
182
+ **Features:**
183
+ - 16 bytes per row with address, hex values, and ASCII representation
184
+ - Quick-jump buttons for common regions: Zero Page, Stack, Text Pages, HiRes Pages, I/O, ROM, DOS, Vectors
185
+ - Address input for direct navigation
186
+ - Hex byte search (finds the next occurrence of a byte sequence)
187
+ - Region indicator showing which memory area is currently visible
188
+ - Change highlighting: modified bytes flash briefly after they change
189
+ - Scroll wheel navigation
190
+
191
+ **Memory regions recognized:**
192
+
193
+ | Region | Address Range |
194
+ |--------|--------------|
195
+ | Zero Page | `$0000-$00FF` |
196
+ | Stack | `$0100-$01FF` |
197
+ | Input Buffer | `$0200-$02FF` |
198
+ | Text Page 1 | `$0400-$07FF` |
199
+ | Text Page 2 | `$0800-$0BFF` |
200
+ | HiRes Page 1 | `$2000-$3FFF` |
201
+ | HiRes Page 2 | `$4000-$5FFF` |
202
+ | DOS 3.3 | `$9600-$BFFF` |
203
+ | I/O Space | `$C000-$C0FF` |
204
+ | Slot ROMs | `$C100-$CFFF` |
205
+ | ROM / LC RAM | `$D000-$FFFF` |
206
+
207
+ ---
208
+
209
+ ## Memory Heat Map
210
+
211
+ The Memory Heat Map (`memory-heat-map-window.js`) provides a real-time visualization of memory access patterns using canvas-based rendering.
212
+
213
+ **Features:**
214
+ - Dual-panel display: Main memory (64 KB) and Auxiliary memory (64 KB)
215
+ - Three view modes: Combined (reads + writes), Reads Only, Writes Only
216
+ - Optional decay mode: hot spots fade over time instead of accumulating
217
+ - Start/Stop/Clear controls for tracking
218
+ - Hover tooltip showing the address and region under the cursor
219
+ - Click to jump to address in Memory Browser (when connected)
220
+
221
+ Each pixel in the heat map represents a small block of addresses. Color intensity indicates access frequency: brighter colors indicate more frequent access.
222
+
223
+ **Region labels are shown for both main and auxiliary memory**, with standard Apple IIe memory regions (Zero Page, Stack, Text Pages, HiRes Pages, etc.) and auxiliary equivalents.
224
+
225
+ ---
226
+
227
+ ## Memory Map
228
+
229
+ The Memory Map (`memory-map-window.js`) shows the current memory bank configuration at a glance. It displays a visual representation of which memory banks (Main vs Auxiliary) are active for each address range, driven by the current soft switch states.
230
+
231
+ The map shows bank switching for:
232
+ - Zero Page / Stack (`$0000-$01FF`)
233
+ - Text Page 1 (`$0400-$07FF`)
234
+ - HiRes Page 1 (`$2000-$3FFF`)
235
+ - HiRes Page 2 (`$4000-$5FFF`)
236
+ - RAM / ROM regions (`$C000-$FFFF`)
237
+ - Language Card bank configuration
238
+
239
+ Active banks are highlighted while inactive banks are dimmed.
240
+
241
+ ---
242
+
243
+ ## Stack Viewer
244
+
245
+ The Stack Viewer (`stack-viewer-window.js`) displays the current contents of the 6502 stack (page `$01xx`).
246
+
247
+ **Features:**
248
+ - Stack pointer value and depth indicator with visual fill bar
249
+ - Call stack reconstruction: identifies JSR return addresses on the stack (6502 pushes PC+2-1, so return addresses are adjusted by +1)
250
+ - Per-entry display: address, hex value, and analysis (e.g., "RTS to $XXXX" for detected return addresses)
251
+ - Previous SP tracking for highlighting stack changes
252
+ - Scroll to current stack pointer position
253
+
254
+ ---
255
+
256
+ ## Zero Page Watch
257
+
258
+ The Zero Page Watch (`zero-page-watch-window.js`) monitors specific zero page locations with predefined and custom watch groups.
259
+
260
+ **Predefined watch groups:**
261
+
262
+ | Group | Locations |
263
+ |-------|-----------|
264
+ | BASIC Pointers | TXTTAB, VARTAB, ARYTAB, STREND, FRETOP, MEMSIZ, CURLIN, TXTPTR |
265
+ | Screen/Window | WNDLFT, WNDWDTH, WNDTOP, WNDBTM, CH, CV, BASL, BAS2L |
266
+ | Graphics | GBASL, COLOR, HCOLOR1, HGRX, HGRY |
267
+ | DOS 3.3 | DOSSLOT, DOSDRIVE, FILTYP |
268
+ | System | LOC0, LOC2, CSWL, KSWL, A1L, A2L, A4L, ACC, XREG, YREG, STATUS |
269
+
270
+ **Features:**
271
+ - Collapsible groups with expand/collapse state persistence
272
+ - 8-bit and 16-bit value display
273
+ - Custom watches: add any zero page address with a custom label
274
+ - Change highlighting with fade-out animation
275
+ - Description tooltips for each location
276
+
277
+ ---
278
+
279
+ ## Soft Switch Monitor
280
+
281
+ The Soft Switch Monitor (`soft-switch-window.js`) displays the state of all Apple IIe soft switches organized by function.
282
+
283
+ **Switch groups:**
284
+
285
+ | Group | Switches |
286
+ |-------|----------|
287
+ | Display Mode | TEXT, MIXED, PAGE2, HIRES, 80COL, ALTCHAR, DHIRES |
288
+ | Memory Banking | RAMRD, RAMWRT, ALTZP, 80STORE, INTCXROM, SLOTC3ROM |
289
+ | Language Card | LCRAM, LCWRT, LCBNK2 |
290
+
291
+ Each switch shows:
292
+ - Name and current state (ON/OFF)
293
+ - Toggle address(es) (e.g., `$C050/51`)
294
+ - Brief description
295
+ - Active state highlighted with color
296
+
297
+ The display updates in real-time as switches change during emulation.
298
+
299
+ ---
300
+
301
+ ## Mockingboard Debug
302
+
303
+ The Mockingboard window (`mockingboard-window.js`) provides a unified channel-centric view of both AY-3-8910 PSGs and their VIA 6522 controllers.
304
+
305
+ **Channel cards** (6 total: PSG1 A/B/C, PSG2 A/B/C):
306
+ - Tone period and computed frequency with musical note name
307
+ - Volume level (0-15) with visual level meter
308
+ - Mixer state (tone enable, noise enable)
309
+ - Envelope mode indicator with shape waveform SVG
310
+ - Per-channel mute toggle
311
+ - Real-time inline waveform display
312
+
313
+ **VIA detail section:**
314
+ - Timer 1 counter, latch, and mode (one-shot / free-running)
315
+ - Timer 2 counter
316
+ - ACR, IFR, IER register values
317
+ - IRQ active state
318
+ - Port A/B data and direction registers
319
+
320
+ **Additional features:**
321
+ - Frequency-to-note conversion (A4 = 440 Hz reference)
322
+ - Envelope shape SVGs for all 16 shape values
323
+ - Color-coded channel badges (A = blue, B = green, C = red)
324
+ - Dirty checking for efficient DOM updates
325
+
326
+ ---
327
+
328
+ ## Mouse Card Debug
329
+
330
+ The Mouse Card window (`mouse-card-window.js`) displays the state of the Apple Mouse Interface Card.
331
+
332
+ **Sections:**
333
+ - **Status:** Installation state and slot number
334
+ - **Mouse State:** X/Y position, button state, interrupt flags
335
+ - **Mode:** Enabled, movement tracking, button tracking, VBL interrupt
336
+ - **PIA Registers:** MC6821 register values for the mouse protocol
337
+ - **Protocol Activity:** Last command (SET, READ, SERV, CLEAR, POS, INIT, CLAMP, HOME), timing
338
+
339
+ ---
340
+
341
+ ## BASIC Program Window
342
+
343
+ The BASIC Program Window (`basic-program-window.js`) combines a program editor with an integrated Applesoft BASIC debugger.
344
+
345
+ ### Editor
346
+
347
+ - Syntax-highlighted source code editor with Applesoft BASIC token recognition
348
+ - Autocomplete for BASIC keywords
349
+ - Line number gutter with breakpoint markers
350
+ - Direct loading of programs into emulator memory using tokenization
351
+ - Import/export of BASIC source files
352
+
353
+ ### BASIC Debugger
354
+
355
+ The debugger toolbar provides:
356
+ - **Run:** Tokenize and load the program, then execute it
357
+ - **Pause:** Break at the next BASIC line
358
+ - **Step:** Execute one BASIC statement
359
+
360
+ The debugger tracks execution state through zero page pointers:
361
+ - `CURLIN` (`$75-$76`): Current BASIC line number being executed
362
+ - `TXTPTR` (`$7A-$7B`): Pointer to current position in program text
363
+
364
+ When paused, the currently executing line is highlighted in the editor. Statement-level stepping allows stepping through individual statements within a multi-statement line (statements separated by colons).
365
+
366
+ ### Variable Inspector
367
+
368
+ The `BasicVariableInspector` reads BASIC variables directly from emulator memory:
369
+
370
+ | Memory Region | Pointer | Contents |
371
+ |---------------|---------|----------|
372
+ | Simple variables | VARTAB (`$69`) to ARYTAB (`$6B`) | 7-byte entries (2-byte name + 5-byte value) |
373
+ | Arrays | ARYTAB (`$6B`) to STREND (`$6D`) | Variable-length array entries |
374
+
375
+ **Variable types detected:**
376
+ - **Real:** 5-byte Applesoft floating point
377
+ - **Integer:** 2-byte signed 16-bit (high byte first)
378
+ - **String:** 1-byte length + 2-byte pointer to string data
379
+
380
+ Variables display with change highlighting. Arrays can be expanded to show individual elements. Auto-refresh mode updates variables while the program is running.
381
+
382
+ ### BASIC Breakpoints
383
+
384
+ The `BasicBreakpointManager` manages line-level breakpoints for BASIC programs. Breakpoints are set on BASIC line numbers (not memory addresses). The manager supports:
385
+
386
+ - Line breakpoints with hit counters
387
+ - Statement-level stepping mode
388
+ - Synchronization with the WASM breakpoint interface
389
+ - Persistence to localStorage (`a2e-basic-breakpoints`)
390
+
391
+ The `BasicProgramParser` reads the tokenized program from memory starting at TXTTAB, parsing the linked list of lines (each line: 2-byte next pointer, 2-byte line number, tokenized text, null terminator).
392
+
393
+ ---
394
+
395
+ ## Rule Builder
396
+
397
+ The Rule Builder (`rule-builder-window.js`) provides a visual interface for composing complex breakpoint conditions without writing condition expressions manually.
398
+
399
+ **Features:**
400
+ - Tree-based rule composition with AND/OR groups
401
+ - Nested groups for complex logic
402
+ - Operand types: registers (A, X, Y, SP, PC, P), memory reads, constants
403
+ - Comparison operators: equals, not equals, less than, greater than, less/greater or equal
404
+ - Bitwise operators for flag testing
405
+ - Live preview of the generated condition expression
406
+ - Apply/Cancel workflow that integrates with the CPU Debugger's breakpoint system
407
+
408
+ The rule builder is opened from the CPU Debugger when editing a breakpoint's condition. The generated expression string is passed to the C++ condition evaluator for runtime evaluation.
409
+
410
+ ---
411
+
412
+ ## Assembler Editor
413
+
414
+ The Assembler Editor (`assembler-editor-window.js`) provides a 65C02 assembly language editor with Merlin-style syntax support.
415
+
416
+ **Editor features:**
417
+ - Merlin-compatible column layout (label, opcode, operand, comment)
418
+ - Syntax highlighting for 65C02 mnemonics, directives, labels, and comments
419
+ - Real-time syntax validation with error markers in the gutter
420
+ - Line numbers, cycle counts per instruction, and assembled byte display in the gutter
421
+ - Expression evaluator for operands (arithmetic, symbols, `*` for current PC)
422
+ - Breakpoint toggles per assembled line (F9)
423
+ - Cursor position indicator showing line and column
424
+
425
+ **Toolbar:**
426
+ - New / Open / Save file operations
427
+ - Assemble: assemble source to machine code with error reporting
428
+ - Load: inject assembled code into emulator memory at the origin address
429
+ - Example program loader
430
+ - ROM Routines reference browser (searchable, categorized)
431
+
432
+ **Assembly output:**
433
+ - Per-line hex bytes and addresses
434
+ - Symbol table from labels
435
+ - Error display with line numbers
436
+ - Status bar showing assembled size and origin
437
+
438
+ ---
439
+
440
+ ## Instruction Trace
441
+
442
+ The Instruction Trace (`trace-panel.js`) displays a scrollable history of recently executed CPU instructions from a ring buffer maintained in WASM.
443
+
444
+ **Features:**
445
+ - Virtual scrolling for performance with large trace buffers
446
+ - Each entry shows: address, opcode bytes, mnemonic, operand, symbol annotations
447
+ - Cached opcode mnemonic table from the WASM disassembler
448
+ - Auto-scroll to most recent instruction on pause
449
+
450
+ ---
451
+
452
+ ## Keyboard Shortcuts
453
+
454
+ | Shortcut | Action |
455
+ |----------|--------|
456
+ | F5 | Run / Continue execution |
457
+ | F10 | Step Over |
458
+ | F11 | Step Into |
459
+ | Shift+F11 | Step Out |
460
+
461
+ See [[Keyboard Shortcuts]] for the complete shortcut reference.
462
+
463
+ ---
464
+
465
+ ## Source Files
466
+
467
+ ### Core Debug Windows
468
+
469
+ | File | Description |
470
+ |------|-------------|
471
+ | `src/js/debug/cpu-debugger-window.js` | CPU registers, disassembly, breakpoints, stepping |
472
+ | `src/js/debug/memory-browser-window.js` | Hex/ASCII memory viewer with search |
473
+ | `src/js/debug/memory-heat-map-window.js` | Real-time memory access visualization |
474
+ | `src/js/debug/memory-map-window.js` | Memory bank configuration overview |
475
+ | `src/js/debug/stack-viewer-window.js` | Stack contents with call stack reconstruction |
476
+ | `src/js/debug/zero-page-watch-window.js` | Zero page location monitoring |
477
+ | `src/js/debug/soft-switch-window.js` | Soft switch state display |
478
+
479
+ ### Hardware Debug Windows
480
+
481
+ | File | Description |
482
+ |------|-------------|
483
+ | `src/js/debug/mockingboard-window.js` | AY-3-8910 and VIA 6522 state display |
484
+ | `src/js/debug/mouse-card-window.js` | Mouse card PIA and protocol state |
485
+
486
+ ### BASIC and Assembly
487
+
488
+ | File | Description |
489
+ |------|-------------|
490
+ | `src/js/debug/basic-program-window.js` | BASIC editor with integrated debugger |
491
+ | `src/js/debug/basic-breakpoint-manager.js` | BASIC line breakpoint management |
492
+ | `src/js/debug/basic-variable-inspector.js` | BASIC variable memory reader |
493
+ | `src/js/debug/basic-program-parser.js` | Tokenized BASIC program parser |
494
+ | `src/js/debug/assembler-editor-window.js` | 65C02 assembler with Merlin syntax |
495
+
496
+ ### Supporting Modules
497
+
498
+ | File | Description |
499
+ |------|-------------|
500
+ | `src/js/debug/breakpoint-manager.js` | CPU breakpoint and watchpoint management |
501
+ | `src/js/debug/rule-builder-window.js` | Visual condition expression builder |
502
+ | `src/js/debug/symbols.js` | Apple IIe address symbol table |
503
+ | `src/js/debug/label-manager.js` | User-defined labels and imported symbols |
504
+ | `src/js/debug/trace-panel.js` | CPU instruction execution trace |
505
+ | `src/js/debug/index.js` | Debug subsystem module exports |
506
+
507
+ ### C++ Support
508
+
509
+ | File | Description |
510
+ |------|-------------|
511
+ | `src/core/debug/` | Condition evaluator for breakpoint expressions |
512
+ | `src/core/disassembler/` | 65C02 instruction disassembler |
513
+
514
+ ---
515
+
516
+ See also: [[CPU Emulation]] | [[Memory System]] | [[Audio System]] | [[Keyboard Shortcuts]]
@@ -0,0 +1,161 @@
1
+ # Disk Drives
2
+
3
+ The Disk Drives window provides a visual interface for the emulated Disk II controller. Open it from **View > Disk Drives** in the toolbar.
4
+
5
+ The Apple //e supported two floppy drives connected to the Disk II controller card in Slot 6. Each drive reads and writes 5.25-inch floppy disks with 35 tracks and 16 sectors per track.
6
+
7
+ ---
8
+
9
+ ## Table of Contents
10
+
11
+ - [Supported Disk Formats](#supported-disk-formats)
12
+ - [Loading a Disk](#loading-a-disk)
13
+ - [Ejecting a Disk](#ejecting-a-disk)
14
+ - [Blank Disks](#blank-disks)
15
+ - [Recent Disks](#recent-disks)
16
+ - [Disk Persistence](#disk-persistence)
17
+ - [Drive Status Display](#drive-status-display)
18
+ - [Surface Visualisation](#surface-visualisation)
19
+ - [Detail Panel](#detail-panel)
20
+ - [Drive Sounds](#drive-sounds)
21
+ - [Drag and Drop](#drag-and-drop)
22
+ - [Write Protection and Saving](#write-protection-and-saving)
23
+
24
+ ---
25
+
26
+ ## Supported Disk Formats
27
+
28
+ The emulator accepts the following 5.25-inch disk image formats:
29
+
30
+ | Format | Extension | Description |
31
+ |--------|-----------|-------------|
32
+ | **DSK** | `.dsk` | Raw sector-order disk image (140KB). The most common format. Sectors are stored in DOS 3.3 logical order. |
33
+ | **DO** | `.do` | Identical to DSK format. The extension explicitly indicates DOS 3.3 sector ordering. |
34
+ | **PO** | `.po` | ProDOS-order disk image (140KB). Sectors are stored in ProDOS physical order. |
35
+ | **NIB** | `.nib` | Nibblised disk image (232,960 bytes). Stores the raw GCR-encoded data as it appears on the disk surface, including sync bytes, address fields, and data fields. |
36
+ | **WOZ** | `.woz` | Bit-level disk image with timing and metadata. The most accurate format, capable of representing copy-protected disks. Stores individual flux transitions. |
37
+
38
+ The file input accepts all five extensions: `.dsk`, `.do`, `.po`, `.woz`, and `.nib`.
39
+
40
+ ## Loading a Disk
41
+
42
+ There are three ways to insert a disk:
43
+
44
+ 1. **Insert button** -- Click the **Insert** button on a drive to open a file browser. Select a disk image file to load it into that drive.
45
+
46
+ 2. **Drag and drop** -- Drag a disk image file from your desktop onto the emulator screen. The file will be loaded into the first empty drive. If both drives are occupied, it replaces the disk in Drive 1.
47
+
48
+ 3. **Recent Disks** -- Click the **Recent** button to see a dropdown of previously loaded disks. Click an entry to reload it instantly (see [Recent Disks](#recent-disks)).
49
+
50
+ When a disk is loaded, the drive displays the filename (with scrolling animation if the name is too long) and enables the Eject button.
51
+
52
+ ## Ejecting a Disk
53
+
54
+ Click the **Eject** button on a drive to remove the disk. If the disk has been modified since it was loaded, a save dialog appears offering to save the changes before ejecting:
55
+
56
+ - **Save** -- Opens the browser's file-save dialog with the current filename as the default. After saving (or cancelling the file picker), the disk is ejected.
57
+ - **Don't Save** -- Ejects the disk immediately, discarding any unsaved modifications.
58
+ - Press **Escape** to cancel the eject entirely and keep the disk inserted.
59
+
60
+ After ejecting, the drive display resets to "No Disk" and the surface visualisation clears.
61
+
62
+ ## Blank Disks
63
+
64
+ Click the **Blank** button to insert a fresh, empty 140KB DOS 3.3 disk image. This is useful for saving data from within the emulated Apple //e -- format the blank disk with DOS 3.3 `INIT` or ProDOS, then save files to it.
65
+
66
+ ## Recent Disks
67
+
68
+ Each drive maintains its own list of recently used disk images. Click **Recent** on a drive to see a dropdown of previous disks:
69
+
70
+ - Click a disk name to reload it into that drive.
71
+ - Click **Clear Recent** at the bottom of the list to remove all entries for that drive.
72
+ - Recent disks are stored in IndexedDB along with their full disk image data, so they survive browser restarts.
73
+
74
+ ## Disk Persistence
75
+
76
+ Inserted disks are automatically saved to IndexedDB so they persist across browser sessions:
77
+
78
+ - When you load a disk, its data is stored in IndexedDB keyed by drive number.
79
+ - On the next page load, both drives are automatically restored to their previous state.
80
+ - Ejecting a disk clears its persisted data for that drive.
81
+
82
+ This is separate from the [[Save-States]] system, which captures the entire emulator state including disk contents and modifications.
83
+
84
+ ## Drive Status Display
85
+
86
+ Each drive shows:
87
+
88
+ | Element | Description |
89
+ |---------|-------------|
90
+ | **Disk name** | The filename of the currently inserted disk. Long names scroll horizontally. |
91
+ | **Track indicator** | Shows the current head position as `T00` through `T34`. Highlighted in colour when the drive motor is on and this drive is selected. Displays `T--` when no disk is present. |
92
+
93
+ ## Surface Visualisation
94
+
95
+ Each drive includes a real-time canvas rendering of the disk surface. This animated view shows:
96
+
97
+ - **Rotating disk** -- The floppy disk spins at 300 RPM when the motor is active. When the motor turns off, the disk decelerates realistically before stopping.
98
+ - **35 tracks** -- Concentric rings from the outer edge to just outside the centre hub. Each track corresponds to one of the 35 tracks on a 5.25-inch floppy.
99
+ - **16 sectors** -- Radial lines divide the disk into 16 sectors, matching the Apple II's sector layout.
100
+ - **Head position** -- A small indicator shows which quarter-track the drive head is currently positioned over.
101
+ - **Track access heat map** -- Recently accessed tracks glow with a colour intensity proportional to access frequency. The heat decays over time, so you can see which areas of the disk are being read or written in real time.
102
+ - **Write mode indicator** -- The head indicator changes appearance when the drive is in write mode.
103
+ - **Sticker colour** -- Each inserted disk receives a randomly-assigned vintage label colour (cream, manila, pale green, pale blue, pink, yellow, lavender, or white) derived from a hash of the filename.
104
+ - **Hub hole and reinforcement ring** -- The centre of the disk shows the large hub hole and the white reinforcement ring, matching the physical appearance of a 5.25-inch floppy.
105
+ - **Index hole** -- A small hole in the hub ring area, used by the drive hardware to detect disk rotation.
106
+
107
+ The surface visualisation can be hidden by clicking the **eye icon** in the window title bar. When hidden, the window switches to a compact mode showing only the controls and status indicators.
108
+
109
+ ## Detail Panel
110
+
111
+ Click the **info icon** in the title bar to expand a technical detail panel below each drive. This shows low-level controller state updated in real time:
112
+
113
+ | Field | Description |
114
+ |-------|-------------|
115
+ | **QTrack** | Quarter-track position (0-139). The Disk II controller positions the head in quarter-track increments. |
116
+ | **Phase** | Current stepper motor phase. |
117
+ | **Nibble** | Current nibble position within the track's data stream. |
118
+ | **Motor** | Motor state: ON or OFF. |
119
+ | **Mode** | Read or Write mode. |
120
+ | **Byte** | The last byte read from or written to the disk (hex). Only shown for the currently selected drive. |
121
+
122
+ ## Drive Sounds
123
+
124
+ The emulator synthesises realistic Disk II drive sounds using the Web Audio API. All drive sounds are controlled by the master volume slider and can be toggled on or off from the **Sound** popup in the toolbar.
125
+
126
+ ### Sound Layers
127
+
128
+ **Seek / Step sound** -- A short mechanical click played each time the drive head moves to a new track. Synthesised from a combination of:
129
+ - A sharp initial noise transient (the physical click)
130
+ - A high-frequency metallic tick at ~2200 Hz
131
+ - A higher harmonic at ~3800 Hz for metallic character
132
+ - A lower body resonance at ~1200 Hz
133
+
134
+ All components decay rapidly within 25ms, passed through a 6 kHz low-pass filter.
135
+
136
+ **Motor sound** -- A continuous layered sound while the drive motor is spinning, composed of three layers:
137
+ - **Motor hum** -- A 55 Hz sawtooth oscillator through a 129 Hz low-pass filter, producing the low-frequency rumble of the spindle motor.
138
+ - **Mechanical whir** -- Band-passed noise centred at ~499 Hz, simulating the general mechanical noise of the drive mechanism.
139
+ - **Disk swish** -- Band-passed noise at ~1917 Hz modulated by a ~2.7 Hz LFO, reproducing the rhythmic sound of the floppy disk rubbing against its jacket at 300 RPM (~5 rotations per second).
140
+
141
+ When the motor stops, all layers fade out over 150ms to avoid audio clicks.
142
+
143
+ ### Sound Controls
144
+
145
+ - **Volume slider** -- The main volume slider in the toolbar header scales all drive sounds proportionally.
146
+ - **Mute toggle** -- The mute toggle silences all emulator audio including drive sounds.
147
+ - **Drive Sounds toggle** -- A dedicated toggle in the Sound popup enables or disables drive sounds independently of the main speaker and Mockingboard audio.
148
+
149
+ ## Drag and Drop
150
+
151
+ You can drag disk image files directly from your file manager onto the emulator screen:
152
+
153
+ 1. The monitor frame highlights to indicate it is ready to receive a drop.
154
+ 2. Drop the file to insert it into the first empty drive (Drive 1 checked first, then Drive 2).
155
+ 3. If both drives already have disks, the dropped file replaces Drive 1.
156
+
157
+ ## Write Protection and Saving
158
+
159
+ When ejecting a modified disk, the emulator prompts to save changes. The save dialog uses the browser's File System Access API (where available) to let you choose a save location and filename. The default filename is the original disk image name.
160
+
161
+ Disk modifications are also preserved in save states -- see [[Save-States]] for details.