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,1413 @@
1
+ /* ============================================
2
+ CPU DEBUGGER WINDOW
3
+ ============================================ */
4
+
5
+ /* Root */
6
+ .cpu-dbg {
7
+ display: flex;
8
+ flex-direction: column;
9
+ height: 100%;
10
+ min-height: 0;
11
+ }
12
+
13
+ /* ---- Toolbar ---- */
14
+ .cpu-dbg-toolbar {
15
+ display: flex;
16
+ align-items: center;
17
+ gap: 6px;
18
+ padding: 4px 0 5px;
19
+ border-bottom: 1px solid var(--separator-bg);
20
+ margin-bottom: 6px;
21
+ }
22
+
23
+ .cpu-dbg-btn-group {
24
+ display: flex;
25
+ gap: 2px;
26
+ }
27
+
28
+ .cpu-dbg-btn {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ gap: 3px;
32
+ padding: 4px 8px;
33
+ font-family: var(--font-sans);
34
+ font-size: 10px;
35
+ font-weight: 500;
36
+ background: var(--glass-bg-header);
37
+ border: 1px solid var(--control-border);
38
+ border-radius: var(--radius-sm);
39
+ color: var(--text-secondary);
40
+ cursor: pointer;
41
+ transition: all 0.15s;
42
+ white-space: nowrap;
43
+ }
44
+
45
+ .cpu-dbg-btn:hover {
46
+ background: var(--glass-border);
47
+ color: var(--text-primary);
48
+ }
49
+
50
+ .cpu-dbg-btn:active {
51
+ transform: scale(0.98);
52
+ }
53
+
54
+ .cpu-btn-run {
55
+ background: var(--accent-green-bg);
56
+ border-color: var(--accent-green-border-light);
57
+ color: var(--accent-green);
58
+ }
59
+
60
+ .cpu-btn-run:hover {
61
+ background: var(--accent-green-bg-stronger);
62
+ border-color: var(--accent-green-border);
63
+ color: var(--accent-green);
64
+ }
65
+
66
+ .cpu-btn-pause {
67
+ background: var(--accent-red-bg);
68
+ border-color: var(--accent-red-border-light, var(--accent-red-border));
69
+ color: var(--accent-red);
70
+ }
71
+
72
+ .cpu-btn-pause:hover {
73
+ background: var(--accent-red-bg-stronger);
74
+ border-color: var(--accent-red-border);
75
+ color: var(--accent-red);
76
+ }
77
+
78
+ #dbg-step,
79
+ #dbg-step-over,
80
+ #dbg-step-out {
81
+ background: var(--accent-orange-bg);
82
+ border-color: var(--accent-orange-border-light, var(--accent-orange-border));
83
+ color: var(--accent-orange);
84
+ }
85
+
86
+ #dbg-step:hover,
87
+ #dbg-step-over:hover,
88
+ #dbg-step-out:hover {
89
+ background: var(--accent-orange-bg-stronger, var(--accent-orange-bg-strong));
90
+ border-color: var(--accent-orange-border-strong);
91
+ color: var(--accent-orange);
92
+ }
93
+
94
+ .cpu-dbg-sep {
95
+ width: 1px;
96
+ height: 16px;
97
+ background: var(--separator-bg);
98
+ flex-shrink: 0;
99
+ }
100
+
101
+ /* ---- Status Bar ---- */
102
+ .cpu-dbg-status-bar {
103
+ display: flex;
104
+ align-items: center;
105
+ justify-content: space-between;
106
+ padding: 3px 6px;
107
+ background: var(--input-bg);
108
+ border: 1px solid var(--glass-border-subtle);
109
+ border-radius: 4px;
110
+ margin-bottom: 4px;
111
+ }
112
+
113
+ .cpu-dbg-status-bar-left {
114
+ display: flex;
115
+ align-items: center;
116
+ gap: 6px;
117
+ }
118
+
119
+ .cpu-dbg-status-dot {
120
+ width: 6px;
121
+ height: 6px;
122
+ border-radius: 50%;
123
+ background: var(--accent-orange);
124
+ flex-shrink: 0;
125
+ }
126
+
127
+ .cpu-dbg-status-bar[data-state="running"] .cpu-dbg-status-dot {
128
+ background: var(--accent-green);
129
+ animation: cpu-status-dot-pulse 1.5s ease-in-out infinite;
130
+ }
131
+
132
+ .cpu-dbg-status-bar[data-state="paused"] .cpu-dbg-status-dot {
133
+ animation: none;
134
+ }
135
+
136
+ .cpu-dbg-status-bar[data-state="off"] .cpu-dbg-status-dot {
137
+ background: var(--text-muted);
138
+ animation: none;
139
+ }
140
+
141
+ @keyframes cpu-status-dot-pulse {
142
+ 0%, 100% { opacity: 1; transform: scale(1); }
143
+ 50% { opacity: 0.4; transform: scale(0.75); }
144
+ }
145
+
146
+ .cpu-dbg-status-bar[data-state="off"] .cpu-dbg-status {
147
+ color: var(--text-muted);
148
+ }
149
+
150
+ .cpu-dbg-status {
151
+ font-family: var(--font-mono);
152
+ font-size: 9px;
153
+ font-weight: 700;
154
+ letter-spacing: 0.06em;
155
+ color: var(--accent-orange);
156
+ }
157
+
158
+ .cpu-dbg-status.running {
159
+ color: var(--accent-green);
160
+ }
161
+
162
+ /* ---- CPU State ---- */
163
+ .cpu-dbg-section {
164
+ display: flex;
165
+ align-items: center;
166
+ gap: 8px;
167
+ padding: 5px 6px;
168
+ border: 1px solid var(--glass-border-subtle);
169
+ border-radius: 4px;
170
+ background: var(--input-bg);
171
+ margin-bottom: 4px;
172
+ }
173
+
174
+ .cpu-dbg-section-label {
175
+ font-family: var(--font-mono);
176
+ font-size: 9px;
177
+ font-weight: 600;
178
+ color: var(--text-muted);
179
+ flex-shrink: 0;
180
+ min-width: 34px;
181
+ }
182
+
183
+ .cpu-dbg-regs {
184
+ display: flex;
185
+ gap: 3px;
186
+ flex: 1;
187
+ }
188
+
189
+ .cpu-dbg-reg {
190
+ display: flex;
191
+ align-items: center;
192
+ gap: 4px;
193
+ padding: 4px 6px;
194
+ background: var(--input-bg-deep);
195
+ border-radius: 3px;
196
+ flex: 1;
197
+ min-width: 0;
198
+ }
199
+
200
+ .cpu-dbg-reg.reg-wide {
201
+ flex: 1.5;
202
+ }
203
+
204
+ .reg-label {
205
+ font-size: 9px;
206
+ font-weight: 600;
207
+ color: var(--text-muted);
208
+ flex-shrink: 0;
209
+ }
210
+
211
+ .reg-value {
212
+ font-size: 13px;
213
+ font-weight: 600;
214
+ color: var(--accent-green);
215
+ font-family: var(--font-mono);
216
+ }
217
+
218
+ .reg-value.changed {
219
+ animation: reg-flash 0.6s ease-out;
220
+ }
221
+
222
+ .reg-value[style*="cursor"] {
223
+ border-radius: 2px;
224
+ transition: background 0.1s;
225
+ }
226
+
227
+ .reg-value[style*="cursor"]:hover {
228
+ background: var(--accent-blue-bg);
229
+ }
230
+
231
+ @keyframes reg-flash {
232
+ 0% { color: var(--reg-flash-color); background: var(--reg-flash-bg); }
233
+ 100% { color: var(--accent-green); background: transparent; }
234
+ }
235
+
236
+ /* ---- Flags ---- */
237
+ .cpu-flags {
238
+ display: flex;
239
+ gap: 2px;
240
+ flex: 1;
241
+ }
242
+
243
+ .cpu-flags .flag {
244
+ width: 20px;
245
+ height: 20px;
246
+ display: flex;
247
+ align-items: center;
248
+ justify-content: center;
249
+ font-size: 9px;
250
+ font-weight: 700;
251
+ background: var(--input-bg-deeper);
252
+ border: 1px solid transparent;
253
+ border-radius: 3px;
254
+ color: var(--text-muted);
255
+ transition: all 0.12s;
256
+ }
257
+
258
+ .cpu-flags .flag.separator {
259
+ background: none;
260
+ border: none;
261
+ width: 6px;
262
+ color: rgba(110, 118, 129, 0.4);
263
+ font-weight: 400;
264
+ }
265
+
266
+ .cpu-flags .flag.active {
267
+ background: var(--accent-green-bg-strong);
268
+ border-color: var(--accent-green-border);
269
+ color: var(--accent-green);
270
+ box-shadow: 0 0 6px var(--flag-active-glow);
271
+ }
272
+
273
+ .cpu-dbg-timing-row {
274
+ display: flex;
275
+ align-items: center;
276
+ gap: 6px;
277
+ flex: 1;
278
+ }
279
+
280
+ .cpu-dbg-cycles {
281
+ font-family: var(--font-mono);
282
+ font-size: 10px;
283
+ color: var(--text-secondary);
284
+ }
285
+
286
+ .cpu-dbg-cycles .meta-dim {
287
+ color: var(--text-muted);
288
+ font-size: 9px;
289
+ font-weight: 600;
290
+ }
291
+
292
+ .irq-indicator {
293
+ font-family: var(--font-mono);
294
+ font-size: 8px;
295
+ font-weight: 700;
296
+ padding: 1px 4px;
297
+ border-radius: 2px;
298
+ background: var(--irq-dim-bg);
299
+ border: 1px solid var(--irq-dim-border);
300
+ color: var(--text-muted);
301
+ transition: all 0.15s;
302
+ }
303
+
304
+ .irq-indicator.active {
305
+ background: var(--accent-red-bg-stronger);
306
+ border-color: var(--accent-red-border);
307
+ color: var(--accent-red);
308
+ }
309
+
310
+ /* ---- Scanline Row ---- */
311
+ .cpu-dbg-scanline-row {
312
+ display: flex;
313
+ align-items: center;
314
+ gap: 10px;
315
+ padding: 3px 4px;
316
+ background: var(--input-bg-dark);
317
+ border-radius: 3px;
318
+ flex: 1;
319
+ }
320
+
321
+ .scanline-item {
322
+ font-family: var(--font-mono);
323
+ font-size: 10px;
324
+ white-space: nowrap;
325
+ }
326
+
327
+ .scanline-label {
328
+ color: var(--text-muted);
329
+ font-size: 9px;
330
+ font-weight: 600;
331
+ }
332
+
333
+ .scanline-value {
334
+ color: var(--accent-blue);
335
+ font-weight: 600;
336
+ }
337
+
338
+ .scanline-badge {
339
+ font-family: var(--font-mono);
340
+ font-size: 8px;
341
+ font-weight: 700;
342
+ padding: 1px 5px;
343
+ border-radius: 2px;
344
+ margin-left: auto;
345
+ transition: all 0.15s;
346
+ }
347
+
348
+ .scanline-badge-visible {
349
+ background: var(--accent-green-bg-strong);
350
+ border: 1px solid var(--accent-green-border);
351
+ color: var(--accent-green);
352
+ }
353
+
354
+ .scanline-badge-hblank {
355
+ background: var(--accent-blue-bg-strong);
356
+ border: 1px solid var(--accent-blue-border);
357
+ color: var(--accent-blue);
358
+ }
359
+
360
+ .scanline-badge-vbl {
361
+ background: var(--accent-orange-bg-strong);
362
+ border: 1px solid var(--accent-orange-border-strong);
363
+ color: var(--accent-orange);
364
+ }
365
+
366
+ .scanline-badge-idle {
367
+ background: var(--input-bg-deep);
368
+ border: 1px solid var(--glass-border-subtle);
369
+ color: var(--text-muted);
370
+ }
371
+
372
+ /* ---- Beam Breakpoint List ---- */
373
+ .cpu-beam-list {
374
+ flex: 1;
375
+ overflow-y: auto;
376
+ }
377
+
378
+ .cpu-beam-item {
379
+ display: flex;
380
+ align-items: center;
381
+ gap: 4px;
382
+ padding: 3px 4px;
383
+ font-size: 10px;
384
+ border-radius: 3px;
385
+ cursor: default;
386
+ }
387
+
388
+ .cpu-beam-item:hover {
389
+ background: var(--overlay-faint);
390
+ }
391
+
392
+ .cpu-beam-item.disabled {
393
+ opacity: 0.45;
394
+ }
395
+
396
+ .cpu-beam-item.hit {
397
+ background: var(--accent-red-bg-strong);
398
+ animation: beam-hit-pulse 0.6s ease-in-out 2;
399
+ }
400
+
401
+ .beam-enable {
402
+ flex-shrink: 0;
403
+ }
404
+
405
+ .beam-enable input[type="checkbox"] {
406
+ width: 10px;
407
+ height: 10px;
408
+ margin: 0;
409
+ cursor: pointer;
410
+ }
411
+
412
+ .beam-type {
413
+ flex-shrink: 0;
414
+ font-size: 8px;
415
+ font-weight: 700;
416
+ min-width: 24px;
417
+ text-align: center;
418
+ padding: 1px 3px;
419
+ border-radius: 2px;
420
+ letter-spacing: 0.02em;
421
+ }
422
+
423
+ .beam-type-vbl {
424
+ background: var(--accent-red-bg-strong);
425
+ color: var(--accent-red);
426
+ }
427
+
428
+ .beam-type-hbl {
429
+ background: rgba(227, 179, 65, 0.15);
430
+ color: var(--accent-orange);
431
+ }
432
+
433
+ .beam-type-scan {
434
+ background: var(--accent-blue-bg);
435
+ color: var(--accent-blue);
436
+ }
437
+
438
+ .beam-type-col {
439
+ background: var(--accent-green-bg);
440
+ color: var(--accent-green);
441
+ }
442
+
443
+ .beam-type-sc {
444
+ background: var(--accent-purple-bg);
445
+ color: var(--accent-purple);
446
+ }
447
+
448
+ .beam-detail {
449
+ flex: 1;
450
+ min-width: 0;
451
+ font-family: var(--font-mono);
452
+ font-size: 10px;
453
+ color: var(--text-secondary);
454
+ overflow: hidden;
455
+ text-overflow: ellipsis;
456
+ white-space: nowrap;
457
+ }
458
+
459
+ .beam-remove {
460
+ display: none;
461
+ flex-shrink: 0;
462
+ background: none;
463
+ border: none;
464
+ color: var(--text-muted);
465
+ cursor: pointer;
466
+ font-size: 12px;
467
+ padding: 0 2px;
468
+ line-height: 1;
469
+ }
470
+
471
+ .cpu-beam-item:hover .beam-remove {
472
+ display: block;
473
+ }
474
+
475
+ .beam-remove:hover {
476
+ color: var(--accent-red);
477
+ }
478
+
479
+ @keyframes beam-hit-pulse {
480
+ 50% { background: rgba(248, 81, 73, 0.3); }
481
+ }
482
+
483
+ .cpu-dbg-tab-toolbar .beam-input {
484
+ width: 40px;
485
+ flex: 0 0 auto;
486
+ text-align: center;
487
+ }
488
+
489
+ /* ---- Disassembly ---- */
490
+ .cpu-dbg-disasm {
491
+ flex: 1;
492
+ display: flex;
493
+ flex-direction: column;
494
+ min-height: 0;
495
+ overflow: hidden;
496
+ margin-bottom: 4px;
497
+ }
498
+
499
+ .cpu-dbg-disasm-bar {
500
+ display: flex;
501
+ gap: 3px;
502
+ margin-bottom: 4px;
503
+ flex-shrink: 0;
504
+ }
505
+
506
+ .cpu-dbg-disasm-bar input {
507
+ flex: 1;
508
+ padding: 3px 6px;
509
+ font-family: var(--font-mono);
510
+ font-size: 10px;
511
+ background: var(--input-bg-deeper);
512
+ border: 1px solid var(--control-border);
513
+ border-radius: 3px;
514
+ color: var(--text-primary);
515
+ outline: none;
516
+ }
517
+
518
+ .cpu-dbg-disasm-bar input:focus {
519
+ border-color: var(--accent-blue-border);
520
+ }
521
+
522
+ .cpu-dbg-bar-btn {
523
+ padding: 3px 7px;
524
+ font-family: var(--font-mono);
525
+ font-size: 9px;
526
+ font-weight: 500;
527
+ background: var(--control-bg);
528
+ border: 1px solid var(--control-border);
529
+ border-radius: 3px;
530
+ color: var(--text-secondary);
531
+ cursor: pointer;
532
+ transition: all 0.1s;
533
+ }
534
+
535
+ .cpu-dbg-bar-btn:hover {
536
+ background: var(--glass-border);
537
+ color: var(--text-primary);
538
+ }
539
+
540
+ .cpu-disasm-view {
541
+ background: var(--input-bg-dark);
542
+ border: 1px solid var(--glass-border-subtle);
543
+ border-radius: 3px;
544
+ padding: 2px 0;
545
+ flex: 1;
546
+ overflow-y: auto;
547
+ min-height: 120px;
548
+ }
549
+
550
+ /* Disassembly lines */
551
+ .cpu-disasm-line {
552
+ display: flex;
553
+ align-items: center;
554
+ padding: 1px 6px;
555
+ cursor: pointer !important;
556
+ border-left: 2px solid transparent;
557
+ transition: background 0.08s;
558
+ user-select: none;
559
+ font-size: 11px;
560
+ line-height: 1.5;
561
+ }
562
+
563
+ .cpu-disasm-line:hover {
564
+ background: var(--overlay-subtle);
565
+ }
566
+
567
+ .cpu-disasm-line.current {
568
+ background: var(--accent-blue-bg);
569
+ border-left-color: var(--accent-blue);
570
+ }
571
+
572
+ .cpu-disasm-line.breakpoint {
573
+ background: var(--accent-red-bg);
574
+ border-left-color: var(--accent-red);
575
+ }
576
+
577
+ .cpu-disasm-line.current.breakpoint {
578
+ background: linear-gradient(90deg, var(--accent-blue-bg) 0%, var(--accent-red-bg) 100%);
579
+ border-left-color: var(--accent-red);
580
+ }
581
+
582
+ /* Gutter */
583
+ .cpu-disasm-gutter {
584
+ min-width: 14px;
585
+ width: 14px;
586
+ text-align: center;
587
+ font-size: 8px;
588
+ flex-shrink: 0;
589
+ }
590
+
591
+ .cpu-disasm-gutter .bp-dot {
592
+ display: inline-block;
593
+ width: 8px;
594
+ height: 8px;
595
+ background: var(--accent-red);
596
+ border-radius: 50%;
597
+ box-shadow: 0 0 4px rgba(248, 81, 73, 0.6);
598
+ }
599
+
600
+ .cpu-disasm-gutter .pc-arrow {
601
+ color: var(--accent-blue);
602
+ font-size: 9px;
603
+ text-shadow: 0 0 3px rgba(88, 166, 255, 0.5);
604
+ }
605
+
606
+ .cpu-disasm-gutter .bm-star {
607
+ color: var(--accent-orange);
608
+ font-size: 7px;
609
+ }
610
+
611
+ /* Disassembly columns */
612
+ .cpu-disasm-addr {
613
+ color: var(--accent-blue);
614
+ min-width: 36px;
615
+ opacity: 0.8;
616
+ font-size: 10px;
617
+ }
618
+
619
+ .cpu-disasm-line.current .cpu-disasm-addr {
620
+ color: var(--text-primary);
621
+ opacity: 1;
622
+ font-weight: 600;
623
+ }
624
+
625
+ .cpu-disasm-bytes {
626
+ color: var(--text-muted);
627
+ min-width: 68px;
628
+ font-size: 10px;
629
+ opacity: 0.7;
630
+ }
631
+
632
+ .cpu-disasm-instr {
633
+ display: flex;
634
+ gap: 6px;
635
+ flex: 1;
636
+ min-width: 0;
637
+ }
638
+
639
+ /* Mnemonic column - fixed width for alignment */
640
+ .cpu-disasm-mnemonic {
641
+ min-width: 28px;
642
+ color: var(--text-primary);
643
+ font-weight: 500;
644
+ flex-shrink: 0;
645
+ }
646
+
647
+ /* Control flow mnemonics stand out */
648
+ .cpu-disasm-mnemonic.flow {
649
+ color: var(--syntax-flow);
650
+ }
651
+
652
+ /* Operand column */
653
+ .cpu-disasm-operand {
654
+ color: var(--text-secondary);
655
+ overflow: hidden;
656
+ text-overflow: ellipsis;
657
+ white-space: nowrap;
658
+ }
659
+
660
+ /* Current line overrides */
661
+ .cpu-disasm-line.current .cpu-disasm-mnemonic {
662
+ color: var(--accent-green);
663
+ font-weight: 600;
664
+ }
665
+
666
+ .cpu-disasm-line.current .cpu-disasm-mnemonic.flow {
667
+ color: var(--syntax-flow-bright);
668
+ }
669
+
670
+ .cpu-disasm-line.current .cpu-disasm-operand {
671
+ color: var(--text-primary);
672
+ }
673
+
674
+ /* Constants */
675
+ .cpu-disasm-const {
676
+ color: var(--syntax-const);
677
+ }
678
+
679
+ .cpu-disasm-line.current .cpu-disasm-const {
680
+ color: var(--syntax-const-bright);
681
+ }
682
+
683
+ /* Symbols */
684
+ .cpu-disasm-symbol {
685
+ cursor: help;
686
+ border-bottom: 1px dotted currentColor;
687
+ padding-bottom: 1px;
688
+ position: relative;
689
+ }
690
+
691
+ .cpu-disasm-symbol::after {
692
+ content: attr(data-tooltip);
693
+ position: absolute;
694
+ bottom: 100%;
695
+ left: 50%;
696
+ transform: translateX(-50%);
697
+ padding: 3px 7px;
698
+ background: var(--glass-bg-solid);
699
+ color: #e0e0e0;
700
+ font-size: 10px;
701
+ font-weight: normal;
702
+ white-space: nowrap;
703
+ border-radius: 3px;
704
+ border: 1px solid var(--glass-border);
705
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
706
+ opacity: 0;
707
+ visibility: hidden;
708
+ transition: opacity 0.12s, visibility 0.12s;
709
+ z-index: 1000;
710
+ pointer-events: none;
711
+ margin-bottom: 3px;
712
+ }
713
+
714
+ .cpu-disasm-symbol:hover::after {
715
+ opacity: 1;
716
+ visibility: visible;
717
+ }
718
+
719
+ /* Symbol category colors */
720
+ .cpu-disasm-symbol.sym-zp { color: var(--syntax-symbol-zp); }
721
+ .cpu-disasm-symbol.sym-sw { color: var(--syntax-symbol-sw); }
722
+ .cpu-disasm-symbol.sym-disk { color: var(--syntax-symbol-disk); }
723
+ .cpu-disasm-symbol.sym-rom { color: var(--syntax-symbol-rom); }
724
+ .cpu-disasm-symbol.sym-basic { color: var(--syntax-symbol-basic); }
725
+ .cpu-disasm-symbol.sym-vec { color: var(--syntax-symbol-vec); }
726
+ .cpu-disasm-symbol.sym-io { color: var(--syntax-symbol-io); }
727
+ .cpu-disasm-symbol.sym-default { color: var(--syntax-symbol-rom); }
728
+
729
+ /* Brighter on current line */
730
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-zp { color: var(--syntax-symbol-zp-bright); }
731
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-sw { color: var(--syntax-symbol-sw-bright); }
732
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-disk { color: var(--syntax-symbol-disk-bright); }
733
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-rom { color: var(--syntax-symbol-rom-bright); }
734
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-basic { color: var(--syntax-symbol-basic-bright); }
735
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-vec { color: var(--syntax-symbol-vec-bright); }
736
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-io { color: var(--syntax-symbol-io-bright); }
737
+ .cpu-disasm-line.current .cpu-disasm-symbol.sym-default { color: var(--syntax-symbol-rom-bright); }
738
+
739
+ /* User labels */
740
+ .cpu-disasm-user-label {
741
+ color: var(--accent-orange);
742
+ font-weight: 600;
743
+ }
744
+
745
+ /* Label line above instruction */
746
+ .cpu-disasm-label-line {
747
+ font-size: 10px;
748
+ color: var(--accent-orange);
749
+ font-weight: 600;
750
+ padding: 2px 0 0 22px;
751
+ white-space: nowrap;
752
+ overflow: hidden;
753
+ text-overflow: ellipsis;
754
+ opacity: 0.9;
755
+ }
756
+
757
+ /* Bookmark */
758
+ .cpu-disasm-line.bookmarked .cpu-disasm-addr {
759
+ color: var(--accent-orange);
760
+ }
761
+
762
+ /* Inline comment */
763
+ .cpu-disasm-comment {
764
+ color: var(--text-muted);
765
+ font-style: italic;
766
+ font-size: 10px;
767
+ margin-left: 8px;
768
+ white-space: nowrap;
769
+ overflow: hidden;
770
+ text-overflow: ellipsis;
771
+ opacity: 0.7;
772
+ }
773
+
774
+ /* Execution heat overlay */
775
+ .cpu-disasm-line.heat-1 { background: rgba(255, 200, 0, 0.04); }
776
+ .cpu-disasm-line.heat-2 { background: rgba(255, 200, 0, 0.08); }
777
+ .cpu-disasm-line.heat-3 { background: rgba(255, 150, 0, 0.12); }
778
+ .cpu-disasm-line.heat-4 { background: rgba(255, 100, 0, 0.18); }
779
+ .cpu-disasm-line.heat-5 { background: rgba(255, 50, 0, 0.22); }
780
+
781
+ /* ---- Tabbed Bottom Panel (Breakpoints, Watch) ---- */
782
+ .cpu-dbg-tabs {
783
+ display: flex;
784
+ flex-direction: column;
785
+ min-height: 140px;
786
+ overflow: hidden;
787
+ border-top: 1px solid var(--control-border);
788
+ }
789
+
790
+ .cpu-dbg-tab-bar {
791
+ display: flex;
792
+ gap: 0;
793
+ flex-shrink: 0;
794
+ }
795
+
796
+ .cpu-dbg-tab {
797
+ padding: 5px 12px;
798
+ font-family: var(--font-mono);
799
+ font-size: 9px;
800
+ font-weight: 600;
801
+ text-transform: uppercase;
802
+ letter-spacing: 0.04em;
803
+ background: transparent;
804
+ border: none;
805
+ border-bottom: 2px solid transparent;
806
+ color: var(--text-muted);
807
+ cursor: pointer;
808
+ transition: all 0.12s;
809
+ display: flex;
810
+ align-items: center;
811
+ gap: 5px;
812
+ }
813
+
814
+ .cpu-dbg-tab:hover {
815
+ color: var(--text-secondary);
816
+ background: var(--overlay-white-02);
817
+ }
818
+
819
+ .cpu-dbg-tab.active {
820
+ color: var(--accent-blue);
821
+ border-bottom-color: var(--accent-blue);
822
+ }
823
+
824
+ .cpu-dbg-tab.hit-alert {
825
+ animation: tab-hit-pulse 0.6s ease-in-out infinite;
826
+ border-radius: 4px;
827
+ }
828
+
829
+ @keyframes tab-hit-pulse {
830
+ 50% { color: var(--accent-red); background: var(--accent-red-bg-strong); }
831
+ }
832
+
833
+ .cpu-dbg-tab-count {
834
+ font-size: 8px;
835
+ font-weight: 700;
836
+ min-width: 14px;
837
+ height: 14px;
838
+ line-height: 14px;
839
+ text-align: center;
840
+ border-radius: 7px;
841
+ background: var(--badge-dim-bg);
842
+ color: var(--text-muted);
843
+ display: inline-block;
844
+ }
845
+
846
+ .cpu-dbg-tab-count.has-items {
847
+ background: var(--accent-blue-bg-strong);
848
+ color: var(--accent-blue);
849
+ }
850
+
851
+ .cpu-dbg-tab.active .cpu-dbg-tab-count.has-items {
852
+ background: var(--accent-blue-bg-stronger);
853
+ }
854
+
855
+ .cpu-dbg-tab-content {
856
+ display: none;
857
+ flex-direction: column;
858
+ flex: 1;
859
+ min-height: 0;
860
+ overflow: hidden;
861
+ }
862
+
863
+ .cpu-dbg-tab-content.active {
864
+ display: flex;
865
+ }
866
+
867
+ .cpu-dbg-tab-toolbar {
868
+ display: flex;
869
+ gap: 3px;
870
+ padding: 4px 0;
871
+ flex-shrink: 0;
872
+ }
873
+
874
+ .cpu-dbg-tab-toolbar select {
875
+ padding: 2px 4px;
876
+ font-family: var(--font-mono);
877
+ font-size: 9px;
878
+ background: var(--control-bg);
879
+ border: 1px solid var(--control-border);
880
+ border-radius: 3px;
881
+ color: var(--text-secondary);
882
+ cursor: pointer;
883
+ flex-shrink: 0;
884
+ }
885
+
886
+ .cpu-dbg-tab-toolbar input {
887
+ flex: 1;
888
+ min-width: 0;
889
+ padding: 2px 5px;
890
+ font-family: var(--font-mono);
891
+ font-size: 10px;
892
+ background: var(--input-bg-deep);
893
+ border: 1px solid var(--control-border);
894
+ border-radius: 3px;
895
+ color: var(--text-primary);
896
+ outline: none;
897
+ }
898
+
899
+ .cpu-dbg-tab-toolbar input:focus {
900
+ border-color: var(--accent-blue-border);
901
+ }
902
+
903
+ .cpu-dbg-empty-state {
904
+ padding: 12px 8px;
905
+ text-align: center;
906
+ color: var(--text-muted);
907
+ font-size: 10px;
908
+ font-style: italic;
909
+ opacity: 0.7;
910
+ }
911
+
912
+ .cpu-dbg-add-btn {
913
+ padding: 2px 7px;
914
+ font-family: var(--font-mono);
915
+ font-size: 11px;
916
+ font-weight: 600;
917
+ background: var(--control-bg);
918
+ border: 1px solid var(--control-border);
919
+ border-radius: 3px;
920
+ color: var(--text-secondary);
921
+ cursor: pointer;
922
+ transition: all 0.1s;
923
+ flex-shrink: 0;
924
+ line-height: 1;
925
+ }
926
+
927
+ .cpu-dbg-add-btn:hover {
928
+ background: var(--accent-green-bg-strong);
929
+ border-color: var(--accent-green-border);
930
+ color: var(--accent-green);
931
+ }
932
+
933
+ /* Breakpoint list */
934
+ .cpu-bp-list {
935
+ flex: 1;
936
+ overflow-y: auto;
937
+ }
938
+
939
+ .cpu-bp-item {
940
+ display: flex;
941
+ align-items: center;
942
+ gap: 4px;
943
+ padding: 4px 4px;
944
+ font-size: 10px;
945
+ border-radius: 3px;
946
+ cursor: default;
947
+ }
948
+
949
+ .cpu-bp-item:hover {
950
+ background: var(--overlay-faint);
951
+ }
952
+
953
+ .cpu-bp-item.disabled {
954
+ opacity: 0.45;
955
+ }
956
+
957
+ .cpu-bp-item.hit {
958
+ background: var(--accent-red-bg-strong);
959
+ animation: bp-hit-pulse 0.6s ease-in-out 2;
960
+ }
961
+
962
+ @keyframes bp-hit-pulse {
963
+ 50% { background: rgba(248, 81, 73, 0.3); }
964
+ }
965
+
966
+ .cpu-bp-item .bp-enable {
967
+ flex-shrink: 0;
968
+ }
969
+
970
+ .cpu-bp-item .bp-enable input[type="checkbox"] {
971
+ width: 10px;
972
+ height: 10px;
973
+ margin: 0;
974
+ cursor: pointer;
975
+ }
976
+
977
+ .cpu-bp-item .bp-type {
978
+ flex-shrink: 0;
979
+ font-size: 9px;
980
+ font-weight: 700;
981
+ width: 16px;
982
+ text-align: center;
983
+ }
984
+
985
+ .cpu-bp-item .bp-type-exec {
986
+ color: var(--accent-red);
987
+ }
988
+
989
+ .cpu-bp-item .bp-type-watch {
990
+ color: var(--accent-blue);
991
+ }
992
+
993
+ .cpu-bp-item .bp-addr {
994
+ color: var(--accent-red);
995
+ flex-shrink: 0;
996
+ font-family: var(--font-mono);
997
+ }
998
+
999
+ .cpu-bp-item .bp-label {
1000
+ color: var(--text-muted);
1001
+ font-size: 9px;
1002
+ overflow: hidden;
1003
+ text-overflow: ellipsis;
1004
+ white-space: nowrap;
1005
+ max-width: 80px;
1006
+ }
1007
+
1008
+ .cpu-bp-item .bp-cond {
1009
+ color: var(--accent-orange);
1010
+ font-size: 9px;
1011
+ font-style: italic;
1012
+ flex-shrink: 0;
1013
+ }
1014
+
1015
+ .cpu-bp-item .bp-hits {
1016
+ color: var(--text-muted);
1017
+ font-size: 9px;
1018
+ flex-shrink: 0;
1019
+ margin-left: auto;
1020
+ }
1021
+
1022
+ .cpu-bp-item .bp-edit {
1023
+ background: var(--accent-blue-bg);
1024
+ border: 1px solid var(--accent-blue-bg-stronger);
1025
+ border-radius: 3px;
1026
+ color: var(--accent-blue);
1027
+ cursor: pointer;
1028
+ font-family: var(--font-mono);
1029
+ font-size: 9px;
1030
+ font-weight: 600;
1031
+ padding: 1px 6px;
1032
+ margin-left: auto;
1033
+ flex-shrink: 0;
1034
+ transition: all 0.12s;
1035
+ line-height: 1.3;
1036
+ white-space: nowrap;
1037
+ }
1038
+
1039
+ .cpu-bp-item .bp-edit:hover {
1040
+ background: var(--accent-blue-bg-strong);
1041
+ border-color: rgba(88, 166, 255, 0.6);
1042
+ color: var(--text-primary);
1043
+ }
1044
+
1045
+ .cpu-bp-item .bp-remove {
1046
+ background: none;
1047
+ border: none;
1048
+ color: var(--text-muted);
1049
+ cursor: pointer;
1050
+ font-size: 13px;
1051
+ padding: 0 4px;
1052
+ margin-left: 0;
1053
+ flex-shrink: 0;
1054
+ opacity: 0;
1055
+ transition: opacity 0.1s, color 0.1s;
1056
+ line-height: 1;
1057
+ }
1058
+
1059
+ .cpu-bp-item:hover .bp-remove {
1060
+ opacity: 0.6;
1061
+ }
1062
+
1063
+ .cpu-bp-item .bp-remove:hover {
1064
+ opacity: 1;
1065
+ color: var(--accent-red);
1066
+ }
1067
+
1068
+ .cpu-bp-item .bp-name {
1069
+ color: var(--accent-green);
1070
+ font-weight: 600;
1071
+ font-family: var(--font-mono);
1072
+ flex-shrink: 0;
1073
+ }
1074
+
1075
+ .cpu-bp-item .bp-range {
1076
+ color: var(--text-muted);
1077
+ font-size: 9px;
1078
+ font-family: var(--font-mono);
1079
+ flex-shrink: 0;
1080
+ }
1081
+
1082
+ #bp-source-select {
1083
+ flex-shrink: 0;
1084
+ }
1085
+
1086
+ #bp-switch-select {
1087
+ flex: 1;
1088
+ min-width: 0;
1089
+ }
1090
+
1091
+ /* Watch list */
1092
+ .cpu-watch-list {
1093
+ flex: 1;
1094
+ overflow-y: auto;
1095
+ }
1096
+
1097
+ .cpu-watch-item {
1098
+ display: flex;
1099
+ align-items: center;
1100
+ gap: 6px;
1101
+ padding: 4px 4px;
1102
+ font-size: 10px;
1103
+ border-radius: 3px;
1104
+ }
1105
+
1106
+ .cpu-watch-item:hover {
1107
+ background: var(--overlay-faint);
1108
+ }
1109
+
1110
+ .cpu-watch-item .watch-expr {
1111
+ color: var(--text-secondary);
1112
+ flex-shrink: 0;
1113
+ max-width: 120px;
1114
+ overflow: hidden;
1115
+ text-overflow: ellipsis;
1116
+ white-space: nowrap;
1117
+ }
1118
+
1119
+ .cpu-watch-item .watch-value {
1120
+ color: var(--accent-green);
1121
+ flex: 1;
1122
+ text-align: right;
1123
+ overflow: hidden;
1124
+ text-overflow: ellipsis;
1125
+ white-space: nowrap;
1126
+ font-family: var(--font-mono);
1127
+ }
1128
+
1129
+ .cpu-watch-item .watch-value.changed {
1130
+ animation: reg-flash 0.6s ease-out;
1131
+ }
1132
+
1133
+ .cpu-watch-item .watch-remove {
1134
+ background: none;
1135
+ border: none;
1136
+ color: var(--text-muted);
1137
+ cursor: pointer;
1138
+ font-size: 13px;
1139
+ padding: 0 4px;
1140
+ margin-left: auto;
1141
+ flex-shrink: 0;
1142
+ opacity: 0.5;
1143
+ transition: opacity 0.1s, color 0.1s;
1144
+ line-height: 1;
1145
+ }
1146
+
1147
+ .cpu-watch-item .watch-remove:hover {
1148
+ opacity: 1;
1149
+ color: var(--accent-red);
1150
+ }
1151
+
1152
+ /* Watch detail control visibility */
1153
+ .watch-detail-control {
1154
+ display: none;
1155
+ }
1156
+
1157
+ .watch-detail-control.active {
1158
+ display: block;
1159
+ }
1160
+
1161
+ /* Watch type icons */
1162
+ .watch-type-icon {
1163
+ font-family: var(--font-mono);
1164
+ font-size: 8px;
1165
+ font-weight: 700;
1166
+ width: 14px;
1167
+ height: 14px;
1168
+ line-height: 14px;
1169
+ text-align: center;
1170
+ border-radius: 2px;
1171
+ flex-shrink: 0;
1172
+ }
1173
+
1174
+ .watch-icon-reg {
1175
+ background: var(--accent-blue-bg-strong);
1176
+ color: var(--accent-blue);
1177
+ }
1178
+
1179
+ .watch-icon-flag {
1180
+ background: var(--accent-orange-bg-strong);
1181
+ color: var(--accent-yellow);
1182
+ }
1183
+
1184
+ .watch-icon-byte {
1185
+ background: var(--accent-green-bg-strong);
1186
+ color: var(--accent-green);
1187
+ }
1188
+
1189
+ .watch-icon-word {
1190
+ background: var(--accent-purple-bg-strong);
1191
+ color: var(--accent-purple);
1192
+ }
1193
+
1194
+ .watch-icon-expr {
1195
+ background: var(--overlay-white-10);
1196
+ color: var(--text-muted);
1197
+ }
1198
+
1199
+ /* ============================================================================
1200
+ Trace Panel
1201
+ ============================================================================ */
1202
+
1203
+ .trace-panel-content {
1204
+ display: flex;
1205
+ flex-direction: column;
1206
+ height: 100%;
1207
+ overflow: hidden;
1208
+ }
1209
+
1210
+ .trace-toolbar {
1211
+ display: flex;
1212
+ align-items: center;
1213
+ gap: 8px;
1214
+ padding: 4px 8px;
1215
+ border-bottom: 1px solid var(--control-border);
1216
+ }
1217
+
1218
+ .trace-toggle {
1219
+ display: flex;
1220
+ align-items: center;
1221
+ gap: 4px;
1222
+ font-size: 10px;
1223
+ color: var(--text-secondary);
1224
+ cursor: pointer;
1225
+ }
1226
+
1227
+ .trace-toggle input[type="checkbox"] {
1228
+ width: 12px;
1229
+ height: 12px;
1230
+ }
1231
+
1232
+ .trace-clear-btn {
1233
+ padding: 2px 8px;
1234
+ background: var(--control-bg-solid);
1235
+ border: 1px solid var(--control-border);
1236
+ border-radius: var(--radius-sm);
1237
+ color: var(--text-secondary);
1238
+ font-family: var(--font-sans);
1239
+ font-size: 10px;
1240
+ font-weight: 500;
1241
+ cursor: pointer;
1242
+ transition: all 0.1s;
1243
+ }
1244
+
1245
+ .trace-clear-btn:hover {
1246
+ background: var(--accent-red-bg-strong, var(--control-bg-hover));
1247
+ border-color: var(--accent-red-border, var(--control-border));
1248
+ color: var(--accent-red, var(--text-primary));
1249
+ }
1250
+
1251
+ .trace-count {
1252
+ font-size: 10px;
1253
+ color: var(--text-muted);
1254
+ margin-left: auto;
1255
+ }
1256
+
1257
+ .trace-header {
1258
+ display: flex;
1259
+ gap: 4px;
1260
+ padding: 2px 8px;
1261
+ font-size: 9px;
1262
+ font-weight: 600;
1263
+ color: var(--text-muted);
1264
+ text-transform: uppercase;
1265
+ letter-spacing: 0.05em;
1266
+ border-bottom: 1px solid var(--glass-border-subtle);
1267
+ white-space: nowrap;
1268
+ }
1269
+
1270
+ .trace-scroll-container {
1271
+ flex: 1;
1272
+ overflow-y: auto;
1273
+ position: relative;
1274
+ }
1275
+
1276
+ .trace-scroll-spacer {
1277
+ width: 1px;
1278
+ }
1279
+
1280
+ .trace-rows {
1281
+ position: absolute;
1282
+ left: 0;
1283
+ right: 0;
1284
+ top: 0;
1285
+ }
1286
+
1287
+ .trace-row {
1288
+ display: flex;
1289
+ gap: 4px;
1290
+ padding: 0 8px;
1291
+ height: 14px;
1292
+ line-height: 14px;
1293
+ font-family: var(--font-mono);
1294
+ font-size: 10px;
1295
+ white-space: nowrap;
1296
+ }
1297
+
1298
+ .trace-row:hover {
1299
+ background: var(--overlay-subtle);
1300
+ }
1301
+
1302
+ .trace-col-cycle { width: 64px; flex-shrink: 0; color: var(--text-muted); }
1303
+ .trace-col-pc { width: 36px; flex-shrink: 0; color: var(--accent-blue); }
1304
+ .trace-col-bytes { width: 68px; flex-shrink: 0; color: var(--text-muted); }
1305
+ .trace-col-mnemonic { width: 30px; flex-shrink: 0; color: var(--accent-green); font-weight: 600; }
1306
+ .trace-col-operand { width: 80px; flex-shrink: 0; color: var(--accent-orange, var(--text-primary)); }
1307
+ .trace-col-regs { flex: 1; color: var(--text-secondary); white-space: nowrap; }
1308
+
1309
+ .trace-empty {
1310
+ padding: 16px;
1311
+ text-align: center;
1312
+ color: var(--text-muted);
1313
+ font-size: 11px;
1314
+ }
1315
+
1316
+ /* Memory */
1317
+ .cpu-memory h4 {
1318
+ font-size: 9px;
1319
+ font-weight: 600;
1320
+ color: var(--text-muted);
1321
+ text-transform: uppercase;
1322
+ letter-spacing: 0.08em;
1323
+ margin-bottom: 4px;
1324
+ }
1325
+
1326
+ .cpu-mem-quicknav {
1327
+ display: flex;
1328
+ flex-wrap: wrap;
1329
+ gap: 3px;
1330
+ margin-bottom: 4px;
1331
+ }
1332
+
1333
+ .cpu-mem-quicknav .memory-nav-btn {
1334
+ padding: 2px 5px;
1335
+ font-family: var(--font-mono);
1336
+ font-size: 9px;
1337
+ background: var(--control-bg);
1338
+ border: 1px solid var(--glass-border-subtle);
1339
+ border-radius: 3px;
1340
+ color: var(--text-muted);
1341
+ cursor: pointer;
1342
+ transition: all 0.1s;
1343
+ }
1344
+
1345
+ .cpu-mem-quicknav .memory-nav-btn:hover {
1346
+ background: var(--accent-blue-bg-strong);
1347
+ color: var(--accent-blue);
1348
+ }
1349
+
1350
+ .cpu-mem-controls {
1351
+ display: flex;
1352
+ gap: 4px;
1353
+ margin-bottom: 4px;
1354
+ }
1355
+
1356
+ .cpu-mem-controls input {
1357
+ width: 50px;
1358
+ padding: 3px 6px;
1359
+ font-family: var(--font-mono);
1360
+ font-size: 10px;
1361
+ background: var(--input-bg-deeper);
1362
+ border: 1px solid var(--control-border);
1363
+ border-radius: var(--radius-sm);
1364
+ color: var(--text-primary);
1365
+ }
1366
+
1367
+ .cpu-mem-controls button {
1368
+ padding: 3px 8px;
1369
+ font-size: 10px;
1370
+ background: var(--glass-bg-header);
1371
+ border: 1px solid var(--control-border);
1372
+ border-radius: var(--radius-sm);
1373
+ color: var(--text-secondary);
1374
+ cursor: pointer;
1375
+ }
1376
+
1377
+ .cpu-mem-dump {
1378
+ background: var(--input-bg-dark);
1379
+ border-radius: var(--radius-sm);
1380
+ padding: 4px;
1381
+ max-height: 120px;
1382
+ overflow-y: auto;
1383
+ }
1384
+
1385
+ .cpu-mem-row {
1386
+ display: flex;
1387
+ white-space: nowrap;
1388
+ }
1389
+
1390
+ .cpu-mem-addr {
1391
+ color: var(--accent-purple);
1392
+ min-width: 38px;
1393
+ }
1394
+
1395
+ .cpu-mem-bytes {
1396
+ display: flex;
1397
+ gap: 4px;
1398
+ }
1399
+
1400
+ .cpu-mem-byte {
1401
+ color: var(--text-muted);
1402
+ }
1403
+
1404
+ .cpu-mem-byte.non-zero {
1405
+ color: var(--text-secondary);
1406
+ }
1407
+
1408
+ .cpu-mem-ascii {
1409
+ color: var(--text-muted);
1410
+ margin-left: 8px;
1411
+ opacity: 0.6;
1412
+ }
1413
+