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,798 @@
1
+ /* ============================================
2
+ MEMORY BROWSER WINDOW
3
+ ============================================ */
4
+
5
+ .mem-browser-toolbar {
6
+ display: flex;
7
+ flex-direction: column;
8
+ gap: 6px;
9
+ padding-bottom: 8px;
10
+ border-bottom: 1px solid var(--glass-border-subtle);
11
+ margin-bottom: 8px;
12
+ }
13
+
14
+ .mem-browser-jumps {
15
+ display: flex;
16
+ flex-wrap: wrap;
17
+ gap: 3px;
18
+ }
19
+
20
+ .mem-jump-btn {
21
+ padding: 3px 6px;
22
+ font-family: var(--font-mono);
23
+ font-size: 9px;
24
+ background: var(--control-bg);
25
+ border: 1px solid var(--glass-border-subtle);
26
+ border-radius: 3px;
27
+ color: var(--text-muted);
28
+ cursor: pointer;
29
+ transition: all 0.1s;
30
+ }
31
+
32
+ .mem-jump-btn:hover {
33
+ background: var(--accent-blue-bg-strong);
34
+ color: var(--accent-blue);
35
+ }
36
+
37
+ .mem-browser-nav {
38
+ display: flex;
39
+ gap: 4px;
40
+ }
41
+
42
+ .mem-addr-input,
43
+ .mem-search-input {
44
+ width: 60px;
45
+ padding: 4px 6px;
46
+ font-family: var(--font-mono);
47
+ font-size: 10px;
48
+ background: var(--input-bg-deeper);
49
+ border: 1px solid var(--control-border);
50
+ border-radius: var(--radius-sm);
51
+ color: var(--text-primary);
52
+ }
53
+
54
+ .mem-go-btn,
55
+ .mem-search-btn,
56
+ .mem-refresh-btn {
57
+ padding: 4px 8px;
58
+ font-size: 10px;
59
+ background: var(--glass-bg-header);
60
+ border: 1px solid var(--control-border);
61
+ border-radius: var(--radius-sm);
62
+ color: var(--text-secondary);
63
+ cursor: pointer;
64
+ transition: all 0.1s;
65
+ }
66
+
67
+ .mem-go-btn:hover,
68
+ .mem-search-btn:hover,
69
+ .mem-refresh-btn:hover {
70
+ background: var(--accent-blue-bg-strong);
71
+ color: var(--accent-blue);
72
+ }
73
+
74
+ .mem-browser-region {
75
+ font-size: 10px;
76
+ color: var(--text-muted);
77
+ margin-bottom: 4px;
78
+ }
79
+
80
+ .mem-region-name {
81
+ color: var(--accent-green);
82
+ font-weight: 500;
83
+ }
84
+
85
+ .mem-browser-header {
86
+ display: flex;
87
+ gap: 4px;
88
+ padding: 4px 6px;
89
+ background: var(--input-bg-dark);
90
+ border-radius: var(--radius-sm);
91
+ margin-bottom: 4px;
92
+ font-size: 9px;
93
+ white-space: nowrap;
94
+ }
95
+
96
+ .mem-addr-col {
97
+ color: var(--text-muted);
98
+ }
99
+
100
+ .mem-hdr-separator {
101
+ color: var(--mem-separator);
102
+ }
103
+
104
+ .mem-hdr-bytes {
105
+ color: var(--text-muted);
106
+ }
107
+
108
+ .mem-ascii-sep {
109
+ color: transparent;
110
+ }
111
+
112
+ .mem-ascii-hdr {
113
+ margin-left: auto;
114
+ color: var(--text-muted);
115
+ }
116
+
117
+ .mem-browser-scroll-container {
118
+ display: flex;
119
+ flex: 1;
120
+ overflow: hidden;
121
+ }
122
+
123
+ .mem-browser-content {
124
+ flex: 1;
125
+ overflow: hidden;
126
+ }
127
+
128
+ .mem-browser-scrollbar {
129
+ width: 12px;
130
+ padding: 2px;
131
+ }
132
+
133
+ .mem-scrollbar-track {
134
+ width: 100%;
135
+ height: 100%;
136
+ background: var(--input-bg-dark);
137
+ border-radius: 4px;
138
+ position: relative;
139
+ cursor: pointer;
140
+ }
141
+
142
+ .mem-scrollbar-thumb {
143
+ position: absolute;
144
+ width: 100%;
145
+ background: var(--mem-scrollbar-thumb);
146
+ border-radius: 4px;
147
+ cursor: grab;
148
+ transition: background 0.1s;
149
+ }
150
+
151
+ .mem-scrollbar-thumb:hover {
152
+ background: var(--mem-scrollbar-thumb-hover);
153
+ }
154
+
155
+ .mem-row {
156
+ display: flex;
157
+ gap: 4px;
158
+ padding: 1px 4px;
159
+ font-size: 11px;
160
+ }
161
+
162
+ .mem-row:hover {
163
+ background: var(--accent-blue-bg);
164
+ }
165
+
166
+ .mem-addr {
167
+ color: var(--mem-addr);
168
+ font-weight: 500;
169
+ min-width: 42px;
170
+ }
171
+
172
+ .mem-separator {
173
+ color: var(--mem-separator);
174
+ }
175
+
176
+ .mem-byte {
177
+ width: 18px;
178
+ text-align: center;
179
+ color: var(--mem-byte);
180
+ cursor: pointer;
181
+ border-radius: 2px;
182
+ }
183
+
184
+ .mem-byte:hover {
185
+ background: var(--accent-blue-bg-strong);
186
+ color: var(--text-primary);
187
+ }
188
+
189
+ .mem-byte.mem-zero {
190
+ color: var(--mem-zero);
191
+ }
192
+
193
+ .mem-byte.mem-printable {
194
+ color: var(--mem-printable);
195
+ }
196
+
197
+ .mem-byte.mem-highbit {
198
+ color: var(--mem-highbit);
199
+ }
200
+
201
+ .mem-byte.changed {
202
+ background: var(--accent-orange-border-strong);
203
+ color: var(--accent-orange);
204
+ }
205
+
206
+ .mem-ascii {
207
+ margin-left: auto;
208
+ color: var(--mem-ascii);
209
+ font-size: 10px;
210
+ white-space: pre;
211
+ }
212
+
213
+ /* ============================================
214
+ MEMORY HEAT MAP WINDOW
215
+ ============================================ */
216
+
217
+ .heatmap-toolbar {
218
+ display: flex;
219
+ gap: 6px;
220
+ align-items: center;
221
+ padding-bottom: 8px;
222
+ border-bottom: 1px solid var(--glass-border-subtle);
223
+ margin-bottom: 8px;
224
+ }
225
+
226
+ .heatmap-toggle-btn,
227
+ .heatmap-clear-btn {
228
+ padding: 4px 10px;
229
+ font-size: 10px;
230
+ background: var(--glass-bg-header);
231
+ border: 1px solid var(--control-border);
232
+ border-radius: var(--radius-sm);
233
+ color: var(--text-secondary);
234
+ cursor: pointer;
235
+ transition: all 0.1s;
236
+ }
237
+
238
+ .heatmap-toggle-btn:hover,
239
+ .heatmap-clear-btn:hover {
240
+ background: var(--accent-blue-bg-strong);
241
+ color: var(--accent-blue);
242
+ }
243
+
244
+ .heatmap-toggle-btn.active {
245
+ background: var(--accent-green-bg-stronger);
246
+ border-color: var(--accent-green-border);
247
+ color: var(--accent-green);
248
+ }
249
+
250
+ .heatmap-mode-select {
251
+ padding: 4px 6px;
252
+ font-size: 10px;
253
+ background: var(--input-bg-deeper);
254
+ border: 1px solid var(--control-border);
255
+ border-radius: var(--radius-sm);
256
+ color: var(--text-secondary);
257
+ cursor: pointer;
258
+ }
259
+
260
+ .heatmap-decay-label {
261
+ display: flex;
262
+ align-items: center;
263
+ gap: 4px;
264
+ font-size: 10px;
265
+ color: var(--text-muted);
266
+ cursor: pointer;
267
+ }
268
+
269
+ .heatmap-dual-container {
270
+ display: flex;
271
+ gap: 8px;
272
+ justify-content: center;
273
+ }
274
+
275
+ .heatmap-panel {
276
+ display: flex;
277
+ flex-direction: column;
278
+ align-items: center;
279
+ }
280
+
281
+ .heatmap-panel-title {
282
+ font-size: 9px;
283
+ font-weight: 600;
284
+ color: var(--accent-blue);
285
+ text-transform: uppercase;
286
+ letter-spacing: 0.05em;
287
+ margin-bottom: 4px;
288
+ }
289
+
290
+ .heatmap-canvas-container {
291
+ position: relative;
292
+ display: flex;
293
+ justify-content: center;
294
+ padding: 8px;
295
+ background: var(--input-bg-dark);
296
+ border-radius: var(--radius-sm);
297
+ }
298
+
299
+ .heatmap-canvas {
300
+ image-rendering: pixelated;
301
+ border: 1px solid var(--control-border);
302
+ cursor: crosshair;
303
+ }
304
+
305
+ .heatmap-tooltip {
306
+ position: absolute;
307
+ padding: 4px 8px;
308
+ background: rgba(0, 0, 0, 0.9);
309
+ border-radius: 3px;
310
+ font-size: 10px;
311
+ color: var(--text-primary);
312
+ pointer-events: none;
313
+ display: none;
314
+ }
315
+
316
+ .heatmap-legend {
317
+ display: flex;
318
+ justify-content: center;
319
+ gap: 16px;
320
+ padding: 8px 0;
321
+ font-size: 10px;
322
+ }
323
+
324
+ .heatmap-legend-item {
325
+ display: flex;
326
+ align-items: center;
327
+ gap: 4px;
328
+ color: var(--text-muted);
329
+ }
330
+
331
+ .legend-color {
332
+ width: 12px;
333
+ height: 12px;
334
+ border-radius: 2px;
335
+ }
336
+
337
+ .legend-color.reads {
338
+ background: #18ABEA;
339
+ }
340
+
341
+ .legend-color.writes {
342
+ background: #F68D35;
343
+ }
344
+
345
+ .legend-color.both {
346
+ background: #B55DB6;
347
+ }
348
+
349
+ .heatmap-info {
350
+ display: flex;
351
+ justify-content: space-between;
352
+ padding: 6px 8px;
353
+ background: var(--input-bg);
354
+ border-radius: var(--radius-sm);
355
+ font-size: 10px;
356
+ }
357
+
358
+ .heatmap-addr {
359
+ font-family: var(--font-mono);
360
+ color: var(--accent-purple);
361
+ }
362
+
363
+ .heatmap-region {
364
+ color: var(--text-secondary);
365
+ }
366
+
367
+ .heatmap-counts {
368
+ font-family: var(--font-mono);
369
+ color: var(--text-muted);
370
+ }
371
+
372
+ /* ============================================
373
+ STACK VIEWER WINDOW
374
+ ============================================ */
375
+
376
+ .stack-info {
377
+ display: flex;
378
+ gap: 16px;
379
+ padding: 6px 8px;
380
+ background: var(--input-bg-dark);
381
+ border-radius: var(--radius-sm);
382
+ margin-bottom: 8px;
383
+ font-size: 11px;
384
+ }
385
+
386
+ .stack-sp-label,
387
+ .stack-depth-label {
388
+ color: var(--text-muted);
389
+ }
390
+
391
+ .stack-sp-value {
392
+ font-family: var(--font-mono);
393
+ color: var(--accent-green);
394
+ font-weight: 500;
395
+ }
396
+
397
+ .stack-depth-value {
398
+ color: var(--text-primary);
399
+ font-weight: 500;
400
+ }
401
+
402
+ .stack-depth-bar {
403
+ height: 6px;
404
+ background: var(--input-bg-dark);
405
+ border-radius: 3px;
406
+ margin-bottom: 8px;
407
+ overflow: hidden;
408
+ }
409
+
410
+ .stack-depth-fill {
411
+ height: 100%;
412
+ background: var(--accent-green);
413
+ border-radius: 3px;
414
+ transition: width 0.2s, background 0.2s;
415
+ }
416
+
417
+ .stack-depth-fill.warning {
418
+ background: var(--accent-orange);
419
+ }
420
+
421
+ .stack-depth-fill.danger {
422
+ background: var(--accent-red);
423
+ }
424
+
425
+ .stack-call-stack {
426
+ padding: 3px 8px;
427
+ font-family: var(--font-mono);
428
+ font-size: 10px;
429
+ color: var(--text-secondary);
430
+ white-space: nowrap;
431
+ overflow: hidden;
432
+ text-overflow: ellipsis;
433
+ border-bottom: 1px solid var(--glass-border-subtle);
434
+ }
435
+
436
+ .stack-call-stack:empty {
437
+ display: none;
438
+ }
439
+
440
+ .call-stack-label {
441
+ color: var(--text-muted);
442
+ font-weight: 600;
443
+ }
444
+
445
+ .call-stack-addr {
446
+ color: var(--accent-blue);
447
+ cursor: default;
448
+ }
449
+
450
+ .stack-header {
451
+ display: flex;
452
+ gap: 12px;
453
+ padding: 4px 8px;
454
+ background: var(--input-bg);
455
+ border-radius: var(--radius-sm);
456
+ margin-bottom: 4px;
457
+ font-size: 9px;
458
+ color: var(--text-muted);
459
+ text-transform: uppercase;
460
+ }
461
+
462
+ .stack-col-addr {
463
+ min-width: 50px;
464
+ }
465
+
466
+ .stack-col-value {
467
+ min-width: 40px;
468
+ }
469
+
470
+ .stack-col-info {
471
+ flex: 1;
472
+ }
473
+
474
+ .stack-content {
475
+ flex: 1;
476
+ overflow-y: auto;
477
+ }
478
+
479
+ .stack-entry {
480
+ display: flex;
481
+ gap: 12px;
482
+ padding: 3px 8px;
483
+ font-size: 11px;
484
+ border-radius: 2px;
485
+ }
486
+
487
+ .stack-entry:hover {
488
+ background: var(--accent-blue-bg);
489
+ }
490
+
491
+ .stack-entry.stack-top {
492
+ background: var(--accent-green-bg);
493
+ border-left: 2px solid var(--accent-green);
494
+ }
495
+
496
+ .stack-entry.return-addr-high,
497
+ .stack-entry.return-addr-low {
498
+ background: rgba(163, 113, 247, 0.1);
499
+ }
500
+
501
+ .stack-addr {
502
+ font-family: var(--font-mono);
503
+ color: var(--accent-purple);
504
+ min-width: 50px;
505
+ }
506
+
507
+ .stack-value {
508
+ font-family: var(--font-mono);
509
+ color: var(--text-secondary);
510
+ min-width: 40px;
511
+ }
512
+
513
+ .stack-info-text {
514
+ color: var(--text-muted);
515
+ font-size: 10px;
516
+ }
517
+
518
+ .stack-empty {
519
+ text-align: center;
520
+ padding: 20px;
521
+ color: var(--text-muted);
522
+ font-style: italic;
523
+ }
524
+
525
+ /* ============================================
526
+ ZERO PAGE WATCH WINDOW
527
+ ============================================ */
528
+
529
+ .zp-toolbar {
530
+ display: flex;
531
+ gap: 6px;
532
+ padding-bottom: 8px;
533
+ border-bottom: 1px solid var(--glass-border-subtle);
534
+ margin-bottom: 8px;
535
+ }
536
+
537
+ .zp-add-btn {
538
+ padding: 4px 10px;
539
+ font-size: 10px;
540
+ background: var(--glass-bg-header);
541
+ border: 1px solid var(--control-border);
542
+ border-radius: var(--radius-sm);
543
+ color: var(--text-secondary);
544
+ cursor: pointer;
545
+ transition: all 0.1s;
546
+ }
547
+
548
+ .zp-add-btn:hover {
549
+ background: var(--accent-green-bg-strong);
550
+ color: var(--accent-green);
551
+ }
552
+
553
+ .zp-groups {
554
+ flex: 1;
555
+ overflow-y: auto;
556
+ }
557
+
558
+ .zp-group {
559
+ margin-bottom: 8px;
560
+ }
561
+
562
+ .zp-group-header {
563
+ display: flex;
564
+ align-items: center;
565
+ gap: 6px;
566
+ padding: 4px 6px;
567
+ background: var(--input-bg);
568
+ border-radius: var(--radius-sm);
569
+ cursor: pointer;
570
+ user-select: none;
571
+ }
572
+
573
+ .zp-group-header:hover {
574
+ background: var(--input-bg-deep);
575
+ }
576
+
577
+ .zp-expand-icon {
578
+ font-size: 8px;
579
+ color: var(--text-muted);
580
+ }
581
+
582
+ .zp-group-name {
583
+ font-size: 10px;
584
+ font-weight: 600;
585
+ color: var(--accent-blue);
586
+ }
587
+
588
+ .zp-group-content {
589
+ padding: 4px 0 4px 16px;
590
+ }
591
+
592
+ .zp-group-content.collapsed {
593
+ display: none;
594
+ }
595
+
596
+ .zp-watch {
597
+ display: flex;
598
+ align-items: center;
599
+ gap: 8px;
600
+ padding: 3px 6px;
601
+ border-radius: 3px;
602
+ transition: background 0.2s;
603
+ }
604
+
605
+ .zp-watch:hover {
606
+ background: var(--accent-blue-bg);
607
+ }
608
+
609
+ .zp-watch.changed {
610
+ background: var(--accent-orange-bg-strong);
611
+ }
612
+
613
+ .zp-addr {
614
+ font-family: var(--font-mono);
615
+ font-size: 10px;
616
+ color: var(--accent-purple);
617
+ min-width: 24px;
618
+ }
619
+
620
+ .zp-label {
621
+ font-family: var(--font-mono);
622
+ font-size: 10px;
623
+ font-weight: 600;
624
+ color: var(--accent-blue);
625
+ min-width: 60px;
626
+ }
627
+
628
+ .zp-size {
629
+ font-family: var(--font-mono);
630
+ font-size: 8px;
631
+ color: var(--text-muted);
632
+ opacity: 0.6;
633
+ min-width: 22px;
634
+ }
635
+
636
+ .zp-value {
637
+ font-family: var(--font-mono);
638
+ font-size: 10px;
639
+ color: var(--accent-green);
640
+ min-width: 85px;
641
+ text-align: right;
642
+ }
643
+
644
+ .zp-desc {
645
+ font-size: 9px;
646
+ color: var(--text-muted);
647
+ flex: 1;
648
+ overflow: hidden;
649
+ text-overflow: ellipsis;
650
+ white-space: nowrap;
651
+ text-align: right;
652
+ padding-left: 8px;
653
+ }
654
+
655
+ .zp-remove-btn {
656
+ padding: 0 4px;
657
+ font-size: 12px;
658
+ background: none;
659
+ border: none;
660
+ color: var(--text-muted);
661
+ cursor: pointer;
662
+ opacity: 0.5;
663
+ transition: opacity 0.1s;
664
+ }
665
+
666
+ .zp-remove-btn:hover {
667
+ opacity: 1;
668
+ color: var(--accent-red);
669
+ }
670
+
671
+ /* ============================================
672
+ MEMORY MAP WINDOW
673
+ ============================================ */
674
+
675
+ .memory-map-content {
676
+ display: flex;
677
+ flex-direction: column;
678
+ gap: 8px;
679
+ }
680
+
681
+ .bank-map {
682
+ display: flex;
683
+ flex-direction: column;
684
+ gap: 4px;
685
+ }
686
+
687
+ .bank-row {
688
+ display: flex;
689
+ align-items: center;
690
+ gap: 8px;
691
+ }
692
+
693
+ .bank-addr {
694
+ font-family: var(--font-mono);
695
+ font-size: 9px;
696
+ color: var(--text-muted);
697
+ min-width: 75px;
698
+ }
699
+
700
+ .bank-region {
701
+ flex: 1;
702
+ padding: 4px 8px;
703
+ font-size: 9px;
704
+ text-align: center;
705
+ border-radius: 3px;
706
+ font-weight: 500;
707
+ }
708
+
709
+ .bank-region.hidden {
710
+ display: none;
711
+ }
712
+
713
+ .bank-main {
714
+ background: var(--accent-green-bg-strong);
715
+ border: 1px solid var(--accent-green-border);
716
+ color: var(--accent-green);
717
+ }
718
+
719
+ .bank-aux {
720
+ background: var(--accent-orange-bg-strong);
721
+ border: 1px solid var(--accent-orange-border-strong);
722
+ color: var(--accent-orange);
723
+ }
724
+
725
+ .bank-rom {
726
+ background: var(--accent-blue-bg-strong);
727
+ border: 1px solid var(--accent-blue-border);
728
+ color: var(--accent-blue);
729
+ }
730
+
731
+ .bank-ram {
732
+ background: rgba(163, 113, 247, 0.2);
733
+ border: 1px solid rgba(163, 113, 247, 0.4);
734
+ color: var(--accent-purple);
735
+ }
736
+
737
+ .bank-slot {
738
+ background: var(--accent-red-bg-stronger);
739
+ border: 1px solid var(--accent-red-border);
740
+ color: var(--accent-red);
741
+ }
742
+
743
+ .bank-io {
744
+ background: rgba(139, 148, 158, 0.2);
745
+ border: 1px solid rgba(139, 148, 158, 0.4);
746
+ color: var(--text-secondary);
747
+ }
748
+
749
+ .bank-legend {
750
+ display: flex;
751
+ justify-content: center;
752
+ gap: 12px;
753
+ margin-top: 8px;
754
+ padding-top: 6px;
755
+ border-top: 1px solid var(--glass-border-subtle);
756
+ }
757
+
758
+ .legend-item {
759
+ display: flex;
760
+ align-items: center;
761
+ gap: 4px;
762
+ font-size: 9px;
763
+ color: var(--text-muted);
764
+ }
765
+
766
+ .legend-box {
767
+ width: 12px;
768
+ height: 12px;
769
+ border-radius: 2px;
770
+ }
771
+
772
+ .bank-status {
773
+ display: flex;
774
+ flex-direction: column;
775
+ gap: 4px;
776
+ padding: 8px;
777
+ background: var(--input-bg-dark);
778
+ border-radius: var(--radius-sm);
779
+ margin-top: 4px;
780
+ }
781
+
782
+ .bank-status-row {
783
+ display: flex;
784
+ align-items: center;
785
+ gap: 8px;
786
+ font-size: 10px;
787
+ }
788
+
789
+ .bank-status-label {
790
+ color: var(--text-muted);
791
+ min-width: 40px;
792
+ }
793
+
794
+ .bank-status-value {
795
+ color: var(--text-primary);
796
+ font-family: var(--font-mono);
797
+ font-weight: 500;
798
+ }