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.
- package/.clangd +5 -0
- package/.mcp.json +12 -0
- package/CLAUDE.md +362 -0
- package/CMakeLists.txt +774 -0
- package/LICENSE +21 -0
- package/README.md +392 -0
- package/build-wasm/generated/roms.cpp +2447 -0
- package/docker-compose.staging.yml +9 -0
- package/docs/basic-rom-disassembly.md +6663 -0
- package/docs/softswitch-comparison.md +273 -0
- package/docs/thunderclock-debug.md +89 -0
- package/examples/cube.bas +72 -0
- package/examples/hello.s +55 -0
- package/examples/scroll.s +140 -0
- package/package.json +18 -0
- package/public/assets/apple-logo-old.png +0 -0
- package/public/assets/apple-logo.png +0 -0
- package/public/assets/drive-closed-light-on.png +0 -0
- package/public/assets/drive-closed.png +0 -0
- package/public/assets/drive-open-light-on.png +0 -0
- package/public/assets/drive-open.png +0 -0
- package/public/audio-worklet.js +82 -0
- package/public/disks/Apple DOS 3.3 January 1983.dsk +0 -0
- package/public/disks/ProDOS 2.4.3.po +0 -0
- package/public/disks/h32mb.2mg +0 -0
- package/public/disks/library.json +26 -0
- package/public/docs/llms/llm-assembler.txt +90 -0
- package/public/docs/llms/llm-basic-program.txt +256 -0
- package/public/docs/llms/llm-disk-drives.txt +72 -0
- package/public/docs/llms/llm-file-explorer.txt +50 -0
- package/public/docs/llms/llm-hard-drives.txt +80 -0
- package/public/docs/llms/llm-main.txt +51 -0
- package/public/docs/llms/llm-slot-configuration.txt +66 -0
- package/public/icons/icon-192.svg +4 -0
- package/public/icons/icon-512.svg +4 -0
- package/public/index.html +661 -0
- package/public/llms.txt +49 -0
- package/public/manifest.json +29 -0
- package/public/shaders/burnin.glsl +22 -0
- package/public/shaders/crt.glsl +706 -0
- package/public/shaders/edge.glsl +109 -0
- package/public/shaders/vertex.glsl +8 -0
- package/public/sw.js +186 -0
- package/roms/341-0027.bin +0 -0
- package/roms/341-0160-A-US-UK.bin +0 -0
- package/roms/341-0160-A.bin +0 -0
- package/roms/342-0273-A-US-UK.bin +0 -0
- package/roms/342-0349-B-C0-FF.bin +0 -0
- package/roms/Apple Mouse Interface Card ROM - 342-0270-C.bin +0 -0
- package/roms/Thunderclock Plus ROM.bin +0 -0
- package/scripts/generate_roms.sh +69 -0
- package/src/bindings/wasm_interface.cpp +1940 -0
- package/src/core/assembler/assembler.cpp +1239 -0
- package/src/core/assembler/assembler.hpp +115 -0
- package/src/core/audio/audio.cpp +160 -0
- package/src/core/audio/audio.hpp +81 -0
- package/src/core/basic/basic_detokenizer.cpp +436 -0
- package/src/core/basic/basic_detokenizer.hpp +41 -0
- package/src/core/basic/basic_tokenizer.cpp +286 -0
- package/src/core/basic/basic_tokenizer.hpp +26 -0
- package/src/core/basic/basic_tokens.hpp +295 -0
- package/src/core/cards/disk2_card.cpp +568 -0
- package/src/core/cards/disk2_card.hpp +316 -0
- package/src/core/cards/expansion_card.hpp +185 -0
- package/src/core/cards/mockingboard/ay8910.cpp +616 -0
- package/src/core/cards/mockingboard/ay8910.hpp +159 -0
- package/src/core/cards/mockingboard/via6522.cpp +530 -0
- package/src/core/cards/mockingboard/via6522.hpp +163 -0
- package/src/core/cards/mockingboard_card.cpp +312 -0
- package/src/core/cards/mockingboard_card.hpp +159 -0
- package/src/core/cards/mouse_card.cpp +654 -0
- package/src/core/cards/mouse_card.hpp +190 -0
- package/src/core/cards/smartport/block_device.cpp +202 -0
- package/src/core/cards/smartport/block_device.hpp +60 -0
- package/src/core/cards/smartport/smartport_card.cpp +603 -0
- package/src/core/cards/smartport/smartport_card.hpp +120 -0
- package/src/core/cards/thunderclock_card.cpp +237 -0
- package/src/core/cards/thunderclock_card.hpp +122 -0
- package/src/core/cpu/cpu6502.cpp +1609 -0
- package/src/core/cpu/cpu6502.hpp +203 -0
- package/src/core/debug/condition_evaluator.cpp +470 -0
- package/src/core/debug/condition_evaluator.hpp +87 -0
- package/src/core/disassembler/disassembler.cpp +552 -0
- package/src/core/disassembler/disassembler.hpp +171 -0
- package/src/core/disk-image/disk_image.hpp +267 -0
- package/src/core/disk-image/dsk_disk_image.cpp +827 -0
- package/src/core/disk-image/dsk_disk_image.hpp +204 -0
- package/src/core/disk-image/gcr_encoding.cpp +147 -0
- package/src/core/disk-image/gcr_encoding.hpp +78 -0
- package/src/core/disk-image/woz_disk_image.cpp +1049 -0
- package/src/core/disk-image/woz_disk_image.hpp +343 -0
- package/src/core/emulator.cpp +2126 -0
- package/src/core/emulator.hpp +434 -0
- package/src/core/filesystem/dos33.cpp +178 -0
- package/src/core/filesystem/dos33.hpp +66 -0
- package/src/core/filesystem/pascal.cpp +262 -0
- package/src/core/filesystem/pascal.hpp +87 -0
- package/src/core/filesystem/prodos.cpp +369 -0
- package/src/core/filesystem/prodos.hpp +119 -0
- package/src/core/input/keyboard.cpp +227 -0
- package/src/core/input/keyboard.hpp +111 -0
- package/src/core/mmu/mmu.cpp +1387 -0
- package/src/core/mmu/mmu.hpp +236 -0
- package/src/core/types.hpp +196 -0
- package/src/core/video/video.cpp +680 -0
- package/src/core/video/video.hpp +156 -0
- package/src/css/assembler-editor.css +1617 -0
- package/src/css/base.css +470 -0
- package/src/css/basic-debugger.css +791 -0
- package/src/css/basic-editor.css +792 -0
- package/src/css/controls.css +783 -0
- package/src/css/cpu-debugger.css +1413 -0
- package/src/css/debug-base.css +160 -0
- package/src/css/debug-windows.css +6455 -0
- package/src/css/disk-drives.css +406 -0
- package/src/css/documentation.css +392 -0
- package/src/css/file-explorer.css +867 -0
- package/src/css/hard-drive.css +180 -0
- package/src/css/layout.css +217 -0
- package/src/css/memory-windows.css +798 -0
- package/src/css/modals.css +510 -0
- package/src/css/monitor.css +425 -0
- package/src/css/release-notes.css +101 -0
- package/src/css/responsive.css +400 -0
- package/src/css/rule-builder.css +340 -0
- package/src/css/save-states.css +201 -0
- package/src/css/settings-windows.css +1231 -0
- package/src/css/window-switcher.css +150 -0
- package/src/js/agent/agent-manager.js +643 -0
- package/src/js/agent/agent-tools.js +293 -0
- package/src/js/agent/agent-version-tools.js +131 -0
- package/src/js/agent/assembler-tools.js +357 -0
- package/src/js/agent/basic-program-tools.js +894 -0
- package/src/js/agent/disk-tools.js +417 -0
- package/src/js/agent/file-explorer-tools.js +269 -0
- package/src/js/agent/index.js +13 -0
- package/src/js/agent/main-tools.js +222 -0
- package/src/js/agent/slot-tools.js +303 -0
- package/src/js/agent/smartport-tools.js +257 -0
- package/src/js/agent/window-tools.js +80 -0
- package/src/js/audio/audio-driver.js +417 -0
- package/src/js/audio/audio-worklet.js +85 -0
- package/src/js/audio/index.js +8 -0
- package/src/js/config/default-layout.js +34 -0
- package/src/js/config/version.js +8 -0
- package/src/js/data/apple2-rom-routines.js +577 -0
- package/src/js/debug/assembler-editor-window.js +2993 -0
- package/src/js/debug/basic-breakpoint-manager.js +529 -0
- package/src/js/debug/basic-program-parser.js +436 -0
- package/src/js/debug/basic-program-window.js +2594 -0
- package/src/js/debug/basic-variable-inspector.js +447 -0
- package/src/js/debug/breakpoint-manager.js +472 -0
- package/src/js/debug/cpu-debugger-window.js +2396 -0
- package/src/js/debug/index.js +22 -0
- package/src/js/debug/label-manager.js +238 -0
- package/src/js/debug/memory-browser-window.js +416 -0
- package/src/js/debug/memory-heat-map-window.js +481 -0
- package/src/js/debug/memory-map-window.js +206 -0
- package/src/js/debug/mockingboard-window.js +882 -0
- package/src/js/debug/mouse-card-window.js +355 -0
- package/src/js/debug/rule-builder-window.js +648 -0
- package/src/js/debug/soft-switch-window.js +458 -0
- package/src/js/debug/stack-viewer-window.js +221 -0
- package/src/js/debug/symbols.js +416 -0
- package/src/js/debug/trace-panel.js +291 -0
- package/src/js/debug/zero-page-watch-window.js +297 -0
- package/src/js/disk-manager/disk-drives-window.js +212 -0
- package/src/js/disk-manager/disk-operations.js +284 -0
- package/src/js/disk-manager/disk-persistence.js +301 -0
- package/src/js/disk-manager/disk-surface-renderer.js +388 -0
- package/src/js/disk-manager/drive-sounds.js +139 -0
- package/src/js/disk-manager/hard-drive-manager.js +481 -0
- package/src/js/disk-manager/hard-drive-persistence.js +187 -0
- package/src/js/disk-manager/hard-drive-window.js +57 -0
- package/src/js/disk-manager/index.js +890 -0
- package/src/js/display/display-settings-window.js +383 -0
- package/src/js/display/index.js +10 -0
- package/src/js/display/screen-window.js +342 -0
- package/src/js/display/webgl-renderer.js +705 -0
- package/src/js/file-explorer/disassembler.js +574 -0
- package/src/js/file-explorer/dos33.js +266 -0
- package/src/js/file-explorer/file-viewer.js +359 -0
- package/src/js/file-explorer/index.js +1261 -0
- package/src/js/file-explorer/prodos.js +549 -0
- package/src/js/file-explorer/utils.js +67 -0
- package/src/js/help/documentation-window.js +1096 -0
- package/src/js/help/index.js +10 -0
- package/src/js/help/release-notes-window.js +85 -0
- package/src/js/help/release-notes.js +612 -0
- package/src/js/input/gamepad-handler.js +176 -0
- package/src/js/input/index.js +12 -0
- package/src/js/input/input-handler.js +396 -0
- package/src/js/input/joystick-window.js +404 -0
- package/src/js/input/mouse-handler.js +99 -0
- package/src/js/input/text-selection.js +462 -0
- package/src/js/main.js +653 -0
- package/src/js/state/index.js +15 -0
- package/src/js/state/save-states-window.js +393 -0
- package/src/js/state/state-manager.js +409 -0
- package/src/js/state/state-persistence.js +218 -0
- package/src/js/ui/confirm.js +43 -0
- package/src/js/ui/disk-drive-positioner.js +347 -0
- package/src/js/ui/reminder-controller.js +129 -0
- package/src/js/ui/slot-configuration-window.js +560 -0
- package/src/js/ui/theme-manager.js +61 -0
- package/src/js/ui/toast.js +44 -0
- package/src/js/ui/ui-controller.js +897 -0
- package/src/js/ui/window-switcher.js +275 -0
- package/src/js/utils/basic-autocomplete.js +832 -0
- package/src/js/utils/basic-highlighting.js +473 -0
- package/src/js/utils/basic-tokenizer.js +153 -0
- package/src/js/utils/basic-tokens.js +117 -0
- package/src/js/utils/constants.js +28 -0
- package/src/js/utils/indexeddb-helper.js +225 -0
- package/src/js/utils/merlin-editor-support.js +905 -0
- package/src/js/utils/merlin-highlighting.js +551 -0
- package/src/js/utils/storage.js +125 -0
- package/src/js/utils/string-utils.js +19 -0
- package/src/js/utils/wasm-memory.js +54 -0
- package/src/js/windows/base-window.js +690 -0
- package/src/js/windows/index.js +9 -0
- package/src/js/windows/window-manager.js +375 -0
- package/tests/catch2/catch.hpp +17976 -0
- package/tests/common/basic_program_builder.cpp +119 -0
- package/tests/common/basic_program_builder.hpp +209 -0
- package/tests/common/disk_image_builder.cpp +444 -0
- package/tests/common/disk_image_builder.hpp +141 -0
- package/tests/common/test_helpers.hpp +118 -0
- package/tests/gcr/gcr-test.cpp +142 -0
- package/tests/integration/check-rom.js +70 -0
- package/tests/integration/compare-boot.js +239 -0
- package/tests/integration/crash-trace.js +102 -0
- package/tests/integration/disk-boot-test.js +264 -0
- package/tests/integration/memory-crash.js +108 -0
- package/tests/integration/nibble-read-test.js +249 -0
- package/tests/integration/phase-test.js +159 -0
- package/tests/integration/test_emulator.cpp +291 -0
- package/tests/integration/test_emulator_basic.cpp +91 -0
- package/tests/integration/test_emulator_debug.cpp +344 -0
- package/tests/integration/test_emulator_disk.cpp +153 -0
- package/tests/integration/test_emulator_state.cpp +163 -0
- package/tests/klaus/6502_functional_test.bin +0 -0
- package/tests/klaus/65C02_extended_opcodes_test.bin +0 -0
- package/tests/klaus/klaus_6502_test.cpp +184 -0
- package/tests/klaus/klaus_65c02_test.cpp +197 -0
- package/tests/thunderclock/thunderclock_mmu_test.cpp +304 -0
- package/tests/thunderclock/thunderclock_test.cpp +550 -0
- package/tests/unit/test_assembler.cpp +521 -0
- package/tests/unit/test_audio.cpp +196 -0
- package/tests/unit/test_ay8910.cpp +311 -0
- package/tests/unit/test_basic_detokenizer.cpp +265 -0
- package/tests/unit/test_basic_tokenizer.cpp +382 -0
- package/tests/unit/test_block_device.cpp +259 -0
- package/tests/unit/test_condition_evaluator.cpp +219 -0
- package/tests/unit/test_cpu6502.cpp +1301 -0
- package/tests/unit/test_cpu_addressing.cpp +361 -0
- package/tests/unit/test_cpu_cycle_counts.cpp +409 -0
- package/tests/unit/test_cpu_decimal.cpp +166 -0
- package/tests/unit/test_cpu_interrupts.cpp +285 -0
- package/tests/unit/test_disassembler.cpp +323 -0
- package/tests/unit/test_disk2_card.cpp +330 -0
- package/tests/unit/test_dos33.cpp +273 -0
- package/tests/unit/test_dsk_disk_image.cpp +315 -0
- package/tests/unit/test_expansion_card.cpp +178 -0
- package/tests/unit/test_gcr_encoding.cpp +232 -0
- package/tests/unit/test_keyboard.cpp +262 -0
- package/tests/unit/test_mmu.cpp +555 -0
- package/tests/unit/test_mmu_slots.cpp +323 -0
- package/tests/unit/test_mockingboard.cpp +352 -0
- package/tests/unit/test_mouse_card.cpp +386 -0
- package/tests/unit/test_pascal.cpp +248 -0
- package/tests/unit/test_prodos.cpp +259 -0
- package/tests/unit/test_smartport_card.cpp +321 -0
- package/tests/unit/test_thunderclock.cpp +354 -0
- package/tests/unit/test_via6522.cpp +323 -0
- package/tests/unit/test_video.cpp +319 -0
- package/tests/unit/test_woz_disk_image.cpp +257 -0
- package/vite.config.js +96 -0
- package/wiki/AI-Agent.md +372 -0
- package/wiki/Architecture-Overview.md +303 -0
- package/wiki/Audio-System.md +449 -0
- package/wiki/CPU-Emulation.md +477 -0
- package/wiki/Debugger.md +516 -0
- package/wiki/Disk-Drives.md +161 -0
- package/wiki/Disk-System-Internals.md +547 -0
- package/wiki/Display-Settings.md +88 -0
- package/wiki/Expansion-Slots.md +187 -0
- package/wiki/File-Explorer.md +259 -0
- package/wiki/Getting-Started.md +156 -0
- package/wiki/Home.md +69 -0
- package/wiki/Input-Devices.md +183 -0
- package/wiki/Keyboard-Shortcuts.md +158 -0
- package/wiki/Memory-System.md +364 -0
- package/wiki/Save-States.md +172 -0
- package/wiki/Video-Rendering.md +658 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* disassembler.hpp - 65C02 instruction disassembler interface
|
|
3
|
+
*
|
|
4
|
+
* Written by
|
|
5
|
+
* Mike Daley <michael_daley@icloud.com>
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <cstdint>
|
|
11
|
+
#include <vector>
|
|
12
|
+
|
|
13
|
+
namespace a2e {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Standalone 6502/65C02 disassembler
|
|
17
|
+
*
|
|
18
|
+
* Returns raw structured data for frontend rendering.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
// Addressing modes
|
|
22
|
+
enum class AddrMode : uint8_t {
|
|
23
|
+
IMP = 0, // Implied
|
|
24
|
+
ACC = 1, // Accumulator
|
|
25
|
+
IMM = 2, // Immediate #$nn
|
|
26
|
+
ZP = 3, // Zero Page $nn
|
|
27
|
+
ZPX = 4, // Zero Page,X $nn,X
|
|
28
|
+
ZPY = 5, // Zero Page,Y $nn,Y
|
|
29
|
+
ABS = 6, // Absolute $nnnn
|
|
30
|
+
ABX = 7, // Absolute,X $nnnn,X
|
|
31
|
+
ABY = 8, // Absolute,Y $nnnn,Y
|
|
32
|
+
IND = 9, // Indirect ($nnnn)
|
|
33
|
+
IZX = 10, // Indexed Indirect ($nn,X)
|
|
34
|
+
IZY = 11, // Indirect Indexed ($nn),Y
|
|
35
|
+
REL = 12, // Relative (branches)
|
|
36
|
+
ZPI = 13, // Zero Page Indirect ($nn) - 65C02
|
|
37
|
+
AIX = 14, // Absolute Indexed Indirect ($nnnn,X) - 65C02
|
|
38
|
+
ZPR = 15 // Zero Page Relative (BBR/BBS) - 65C02
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
// Instruction categories for syntax highlighting
|
|
42
|
+
enum class InstrCategory : uint8_t {
|
|
43
|
+
BRANCH = 0, // Jumps and branches
|
|
44
|
+
LOAD = 1, // Load/store
|
|
45
|
+
MATH = 2, // Math and logic
|
|
46
|
+
STACK = 3, // Stack and register operations
|
|
47
|
+
FLAG = 4, // Flag operations
|
|
48
|
+
UNKNOWN = 5 // Unknown/illegal opcodes
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// Opcode info structure (maps opcode byte to mnemonic, mode, category)
|
|
52
|
+
struct OpcodeInfo {
|
|
53
|
+
uint8_t mnemonicIndex;
|
|
54
|
+
uint8_t mode; // AddrMode enum value
|
|
55
|
+
uint8_t category; // InstrCategory enum value
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Get pointer to the 256-entry opcode table
|
|
60
|
+
*/
|
|
61
|
+
const OpcodeInfo* getOpcodeTable();
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Get the number of mnemonics in the mnemonic table
|
|
65
|
+
*/
|
|
66
|
+
int getMnemonicCount();
|
|
67
|
+
|
|
68
|
+
// Disassembled instruction data - 16 bytes per instruction
|
|
69
|
+
// Layout: [address:2][target:2][length:1][opcode:1][op1:1][op2:1][mode:1][cat:1][mnem:4][pad:2]
|
|
70
|
+
struct DisasmInstruction {
|
|
71
|
+
uint16_t address; // offset 0-1: Memory address
|
|
72
|
+
uint16_t target; // offset 2-3: Branch/jump target address
|
|
73
|
+
uint8_t length; // offset 4: Instruction length (1-3)
|
|
74
|
+
uint8_t opcode; // offset 5: Opcode byte
|
|
75
|
+
uint8_t operand1; // offset 6: First operand byte
|
|
76
|
+
uint8_t operand2; // offset 7: Second operand byte
|
|
77
|
+
uint8_t mode; // offset 8: AddrMode enum value
|
|
78
|
+
uint8_t category; // offset 9: InstrCategory enum value
|
|
79
|
+
char mnemonic[4]; // offset 10-13: Mnemonic (null-padded)
|
|
80
|
+
uint8_t padding[2]; // offset 14-15: Alignment padding
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// Result structure for disassembly
|
|
84
|
+
struct DisasmResult {
|
|
85
|
+
std::vector<DisasmInstruction> instructions;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get the length of an instruction given its opcode
|
|
90
|
+
*/
|
|
91
|
+
int getInstructionLength(uint8_t opcode);
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Get mnemonic string for an opcode
|
|
95
|
+
*/
|
|
96
|
+
const char* getMnemonic(uint8_t opcode);
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get mnemonic string by index (for use with DisasmInstruction.mnemonicIndex)
|
|
100
|
+
*/
|
|
101
|
+
const char* getMnemonicByIndex(uint8_t index);
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Get addressing mode for an opcode
|
|
105
|
+
*/
|
|
106
|
+
AddrMode getAddressingMode(uint8_t opcode);
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Get instruction category for an opcode
|
|
110
|
+
*/
|
|
111
|
+
InstrCategory getInstructionCategory(uint8_t opcode);
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Disassemble a single instruction from raw data
|
|
115
|
+
*/
|
|
116
|
+
DisasmInstruction disassembleInstruction(const uint8_t *data, size_t size,
|
|
117
|
+
uint16_t address);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Disassemble a block of raw binary data (linear)
|
|
121
|
+
*/
|
|
122
|
+
DisasmResult disassembleBlock(const uint8_t *data, size_t size,
|
|
123
|
+
uint16_t baseAddress);
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Instruction flow classification
|
|
127
|
+
*/
|
|
128
|
+
enum class FlowType : uint8_t {
|
|
129
|
+
SEQUENTIAL = 0, // Continue to next instruction
|
|
130
|
+
CONDITIONAL = 1, // Branch may or may not be taken (Bxx, BBRx, BBSx)
|
|
131
|
+
UNCONDITIONAL = 2, // Always transfers control (JMP abs, BRA)
|
|
132
|
+
CALL = 3, // Subroutine call (JSR) - returns to next instruction
|
|
133
|
+
RETURN = 4, // Returns via stack (RTS, RTI)
|
|
134
|
+
INDIRECT = 5, // Indirect jump - target unknown (JMP indirect)
|
|
135
|
+
HALT = 6 // Stops execution (BRK, STP, WAI)
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Get the flow type of an instruction
|
|
140
|
+
*/
|
|
141
|
+
FlowType getFlowType(uint8_t opcode);
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Disassemble using recursive descent / control flow analysis
|
|
145
|
+
*
|
|
146
|
+
* This approach traces execution paths from entry points to better
|
|
147
|
+
* distinguish code from data:
|
|
148
|
+
* 1. Decode instruction at entry point
|
|
149
|
+
* 2. If sequential, continue to next instruction
|
|
150
|
+
* 3. If branch/jump, add target to visit list
|
|
151
|
+
* 4. If JSR, add target AND return address
|
|
152
|
+
* 5. If RTS/RTI/indirect jump, stop this path
|
|
153
|
+
* 6. Repeat until no more addresses to visit
|
|
154
|
+
*
|
|
155
|
+
* @param data Raw binary data
|
|
156
|
+
* @param size Size of data in bytes
|
|
157
|
+
* @param baseAddress Memory address of first byte
|
|
158
|
+
* @param entryPoints List of known entry points to start tracing from
|
|
159
|
+
* @return Disassembly result with instructions sorted by address
|
|
160
|
+
*/
|
|
161
|
+
DisasmResult disassembleWithFlowAnalysis(const uint8_t *data, size_t size,
|
|
162
|
+
uint16_t baseAddress,
|
|
163
|
+
const std::vector<uint16_t> &entryPoints);
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Convenience overload with single entry point (defaults to baseAddress)
|
|
167
|
+
*/
|
|
168
|
+
DisasmResult disassembleWithFlowAnalysis(const uint8_t *data, size_t size,
|
|
169
|
+
uint16_t baseAddress);
|
|
170
|
+
|
|
171
|
+
} // namespace a2e
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* disk_image.hpp - Abstract base class for disk image formats
|
|
3
|
+
*
|
|
4
|
+
* Written by
|
|
5
|
+
* Mike Daley <michael_daley@icloud.com>
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#pragma once
|
|
9
|
+
|
|
10
|
+
#include <cstdint>
|
|
11
|
+
#include <string>
|
|
12
|
+
|
|
13
|
+
namespace a2e {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* DiskImage - Abstract base class for disk image formats
|
|
17
|
+
*
|
|
18
|
+
* This interface defines the contract for disk image implementations.
|
|
19
|
+
* The disk controller uses this interface to access disk data without
|
|
20
|
+
* needing to know the specific format details.
|
|
21
|
+
*
|
|
22
|
+
* The disk image manages head positioning internally based on stepper
|
|
23
|
+
* motor phase changes. The controller only knows about phases (0-3),
|
|
24
|
+
* not tracks. The disk image translates phase sequences into head
|
|
25
|
+
* movement using 4-phase stepper motor physics.
|
|
26
|
+
*
|
|
27
|
+
* Data access is nibble-based. The controller reads nibbles sequentially
|
|
28
|
+
* as the virtual disk spins. Each track contains a stream of nibbles
|
|
29
|
+
* that encode the sector data using GCR (Group Coded Recording).
|
|
30
|
+
*/
|
|
31
|
+
class DiskImage {
|
|
32
|
+
public:
|
|
33
|
+
/**
|
|
34
|
+
* Disk image format types
|
|
35
|
+
*/
|
|
36
|
+
enum class Format {
|
|
37
|
+
Unknown,
|
|
38
|
+
WOZ1,
|
|
39
|
+
WOZ2,
|
|
40
|
+
DSK, // Raw sector format (140KB, 35 tracks x 16 sectors x 256 bytes)
|
|
41
|
+
DO, // DOS-order DSK (same as DSK)
|
|
42
|
+
PO // ProDOS-order DSK
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
virtual ~DiskImage() = default;
|
|
46
|
+
|
|
47
|
+
// Non-copyable
|
|
48
|
+
DiskImage(const DiskImage &) = delete;
|
|
49
|
+
DiskImage &operator=(const DiskImage &) = delete;
|
|
50
|
+
|
|
51
|
+
// Movable
|
|
52
|
+
DiskImage(DiskImage &&) = default;
|
|
53
|
+
DiskImage &operator=(DiskImage &&) = default;
|
|
54
|
+
|
|
55
|
+
// ===== Loading =====
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Load a disk image from raw data
|
|
59
|
+
* @param data Pointer to disk image data
|
|
60
|
+
* @param size Size of the data
|
|
61
|
+
* @param filename Original filename (for format detection)
|
|
62
|
+
* @return true on success, false on failure
|
|
63
|
+
*/
|
|
64
|
+
virtual bool load(const uint8_t *data, size_t size,
|
|
65
|
+
const std::string &filename) = 0;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Check if a disk image is currently loaded
|
|
69
|
+
* @return true if a valid disk image is loaded
|
|
70
|
+
*/
|
|
71
|
+
virtual bool isLoaded() const = 0;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Get the format of the loaded disk image
|
|
75
|
+
* @return Format enum value
|
|
76
|
+
*/
|
|
77
|
+
virtual Format getFormat() const = 0;
|
|
78
|
+
|
|
79
|
+
// ===== Head Positioning =====
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Notify the disk of a phase magnet state change
|
|
83
|
+
* The disk image tracks phase states and moves the head accordingly
|
|
84
|
+
* using 4-phase stepper motor physics.
|
|
85
|
+
*
|
|
86
|
+
* @param phase Phase number (0-3)
|
|
87
|
+
* @param on true if phase is being activated, false if deactivated
|
|
88
|
+
*/
|
|
89
|
+
virtual void setPhase(int phase, bool on) = 0;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Get the current quarter-track position (0-139)
|
|
93
|
+
* This is for display/debugging purposes only.
|
|
94
|
+
* @return Current quarter-track position
|
|
95
|
+
*/
|
|
96
|
+
virtual int getQuarterTrack() const = 0;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the current track position (0-34)
|
|
100
|
+
* This is for display/debugging purposes only.
|
|
101
|
+
* @return Current track number (quarter_track / 4)
|
|
102
|
+
*/
|
|
103
|
+
virtual int getTrack() const = 0;
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Set the quarter-track position directly (for state restoration)
|
|
107
|
+
* @param quarter_track Quarter-track position (0-139)
|
|
108
|
+
*/
|
|
109
|
+
virtual void setQuarterTrack(int quarter_track) = 0;
|
|
110
|
+
|
|
111
|
+
// ===== Geometry =====
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Get the number of tracks on the disk
|
|
115
|
+
* Standard 5.25" disks have 35 tracks (0-34)
|
|
116
|
+
* @return Number of tracks
|
|
117
|
+
*/
|
|
118
|
+
virtual int getTrackCount() const = 0;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Check if current head position has data
|
|
122
|
+
* @return true if the current position has data
|
|
123
|
+
*/
|
|
124
|
+
virtual bool hasData() const = 0;
|
|
125
|
+
|
|
126
|
+
// ===== Data Access =====
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Advance the bit position based on elapsed CPU cycles
|
|
130
|
+
* This simulates the disk rotating while the motor is on.
|
|
131
|
+
* Call this before reading to account for disk rotation during
|
|
132
|
+
* the time since the last read.
|
|
133
|
+
*
|
|
134
|
+
* @param current_cycles Current total CPU cycle count
|
|
135
|
+
*/
|
|
136
|
+
virtual void advanceBitPosition(uint64_t current_cycles) = 0;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Read a nibble from the disk at the current position
|
|
140
|
+
* This simulates the disk read head reading data.
|
|
141
|
+
* The bit position advances as bits are read until a complete
|
|
142
|
+
* nibble (byte with high bit set) is assembled.
|
|
143
|
+
*
|
|
144
|
+
* @return The nibble read (high bit set for valid data)
|
|
145
|
+
*/
|
|
146
|
+
virtual uint8_t readNibble() = 0;
|
|
147
|
+
|
|
148
|
+
// ===== Write Operations =====
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Write a nibble to the disk at the current position
|
|
152
|
+
* This simulates the disk write head writing data.
|
|
153
|
+
* The bit position advances as bits are written.
|
|
154
|
+
*
|
|
155
|
+
* @param nibble The nibble to write (should have high bit set for valid GCR
|
|
156
|
+
* data)
|
|
157
|
+
*/
|
|
158
|
+
virtual void writeNibble(uint8_t nibble) = 0;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Read a single bit from the disk at the current position
|
|
162
|
+
* Advances the bit position by one.
|
|
163
|
+
* Used by the Logic State Sequencer for cycle-accurate disk access.
|
|
164
|
+
*
|
|
165
|
+
* @return 0 or 1
|
|
166
|
+
*/
|
|
167
|
+
virtual uint8_t readBit() = 0;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Write a single bit to the disk at the current position
|
|
171
|
+
* Advances the bit position by one.
|
|
172
|
+
* Used by the Logic State Sequencer for cycle-accurate disk access.
|
|
173
|
+
*
|
|
174
|
+
* @param bit The bit value (0 or 1)
|
|
175
|
+
*/
|
|
176
|
+
virtual void writeBit(uint8_t bit) = 0;
|
|
177
|
+
|
|
178
|
+
// ===== Status =====
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Check if the disk is write-protected
|
|
182
|
+
* @return true if write-protected
|
|
183
|
+
*/
|
|
184
|
+
virtual bool isWriteProtected() const = 0;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Check if the disk has been modified
|
|
188
|
+
* @return true if modified since load
|
|
189
|
+
*/
|
|
190
|
+
virtual bool isModified() const = 0;
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Get a human-readable format name
|
|
194
|
+
* @return Format name string (e.g., "WOZ 2.0")
|
|
195
|
+
*/
|
|
196
|
+
virtual std::string getFormatName() const = 0;
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get the raw sector data for saving (DSK format)
|
|
200
|
+
* @param size Output: size of the data
|
|
201
|
+
* @return Pointer to sector data, or nullptr if not available
|
|
202
|
+
*/
|
|
203
|
+
virtual const uint8_t *getSectorData(size_t *size) const = 0;
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Export disk data in its native format for saving
|
|
207
|
+
* This reconstructs the disk image file that can be saved to disk.
|
|
208
|
+
* The returned pointer is valid until the next call to exportData()
|
|
209
|
+
* or until the disk image is destroyed.
|
|
210
|
+
*
|
|
211
|
+
* @param size Output: size of the exported data
|
|
212
|
+
* @return Pointer to exported data, or nullptr if export not supported
|
|
213
|
+
*/
|
|
214
|
+
virtual const uint8_t *exportData(size_t *size) = 0;
|
|
215
|
+
|
|
216
|
+
// ===== Debug Methods =====
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Get a nibble at a specific track and position (debug only)
|
|
220
|
+
* @param track Track number (0-34)
|
|
221
|
+
* @param position Position in nibble stream
|
|
222
|
+
* @return Nibble value at that position
|
|
223
|
+
*/
|
|
224
|
+
virtual uint8_t getNibbleAt(int track, int position) const = 0;
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* Get the number of nibbles in a track (debug only)
|
|
228
|
+
* @param track Track number (0-34)
|
|
229
|
+
* @return Number of nibbles in the track
|
|
230
|
+
*/
|
|
231
|
+
virtual int getTrackNibbleCount(int track) const = 0;
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get the current nibble position within the track (debug only)
|
|
235
|
+
* @return Current nibble position
|
|
236
|
+
*/
|
|
237
|
+
virtual size_t getCurrentNibblePosition() const = 0;
|
|
238
|
+
|
|
239
|
+
// ===== Reset =====
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Reset runtime positioning state while preserving loaded disk data.
|
|
243
|
+
* Resets head position, phase states, bit position, and cycle counters
|
|
244
|
+
* back to initial values as if the disk was freshly inserted.
|
|
245
|
+
*/
|
|
246
|
+
virtual void resetState() = 0;
|
|
247
|
+
|
|
248
|
+
// ===== Filename Tracking =====
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Get the filename associated with this disk image
|
|
252
|
+
* @return Filename string
|
|
253
|
+
*/
|
|
254
|
+
const std::string &getFilename() const { return filename_; }
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Set the filename associated with this disk image
|
|
258
|
+
* @param filename The filename to set
|
|
259
|
+
*/
|
|
260
|
+
void setFilename(const std::string &filename) { filename_ = filename; }
|
|
261
|
+
|
|
262
|
+
protected:
|
|
263
|
+
DiskImage() = default;
|
|
264
|
+
std::string filename_;
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
} // namespace a2e
|