yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
disassembler_65816.h
Go to the documentation of this file.
1#ifndef YAZE_CLI_SERVICE_AGENT_DISASSEMBLER_65816_H_
2#define YAZE_CLI_SERVICE_AGENT_DISASSEMBLER_65816_H_
3
4#include <cstdint>
5#include <string>
6#include <vector>
7#include <unordered_map>
8
9#include "absl/strings/str_format.h"
10
11namespace yaze {
12namespace cli {
13namespace agent {
14
15// 65816 addressing modes
16enum class AddressingMode {
17 Implied, // No operand
18 Accumulator, // A
19 Immediate8, // #$nn (8-bit immediate based on M flag)
20 Immediate16, // #$nnnn (16-bit immediate based on M flag)
21 ImmediateX, // #$nn or #$nnnn (based on X flag)
22 Absolute, // $nnnn
23 AbsoluteLong, // $nnnnnn
24 AbsoluteX, // $nnnn,X
25 AbsoluteXLong, // $nnnnnn,X
26 AbsoluteY, // $nnnn,Y
27 Direct, // $nn
28 DirectX, // $nn,X
29 DirectY, // $nn,Y
30 Indirect, // ($nn)
31 IndirectX, // ($nn,X)
32 IndirectY, // ($nn),Y
33 IndirectLong, // [$nn]
34 IndirectLongY, // [$nn],Y
35 StackRel, // $nn,S
36 StackRelY, // ($nn,S),Y
37 Relative8, // +/-$nn (branches)
38 Relative16, // +/-$nnnn (BRL)
39 BlockMove, // $nn,$nn (MVN/MVP)
40};
41
42// Instruction information
44 std::string mnemonic;
46 uint8_t base_size; // Base instruction size (not including M/X flag variations)
47 uint8_t cycles; // Base cycle count
48};
49
50// 65816 Disassembler
52 public:
53 Disassembler65816() : m_flag_(false), x_flag_(false) {
55 }
56
57 // Set processor status flags that affect instruction size
58 void SetFlags(bool m_flag, bool x_flag) {
59 m_flag_ = m_flag;
60 x_flag_ = x_flag;
61 }
62
63 // Disassemble a single instruction
64 // Returns the instruction size in bytes
65 uint8_t DisassembleInstruction(uint32_t address, const uint8_t* data,
66 std::string& mnemonic,
67 std::string& operand_str,
68 std::vector<uint8_t>& operands);
69
70 // Get instruction size without full disassembly
71 uint8_t GetInstructionSize(uint8_t opcode) const;
72
73 // Format an address for display
74 static std::string FormatAddress(uint32_t address) {
75 return absl::StrFormat("$%02X:%04X", (address >> 16) & 0xFF, address & 0xFFFF);
76 }
77
78 private:
80 std::string FormatOperand(AddressingMode mode, uint32_t address,
81 const std::vector<uint8_t>& operands) const;
82 uint8_t GetEffectiveSize(uint8_t opcode, AddressingMode mode) const;
83
84 bool m_flag_; // 8-bit accumulator when true
85 bool x_flag_; // 8-bit index registers when true
86 std::unordered_map<uint8_t, InstructionInfo> opcode_table_;
87};
88
89// Execution trace buffer for recording executed instructions
91 public:
92 static constexpr size_t kDefaultBufferSize = 10000;
93
94 struct TraceEntry {
95 uint32_t address; // Full 24-bit address
96 uint8_t opcode; // Opcode byte
97 std::vector<uint8_t> operands; // Operand bytes
98 std::string mnemonic; // Instruction mnemonic
99 std::string operand_str; // Formatted operand string
100 uint64_t cycle_count; // Cycle count when executed
101
102 // CPU state snapshot
103 uint16_t a_reg;
104 uint16_t x_reg;
105 uint16_t y_reg;
106 uint16_t sp;
107 uint16_t pc;
108 uint8_t pb;
109 uint8_t db;
110 uint8_t status;
111 };
112
113 explicit ExecutionTraceBuffer(size_t max_size = kDefaultBufferSize)
114 : max_size_(max_size) {
115 buffer_.reserve(max_size);
116 }
117
118 // Record an instruction execution
119 void RecordExecution(const TraceEntry& entry);
120
121 // Get the last N entries
122 std::vector<TraceEntry> GetRecentEntries(size_t count) const;
123
124 // Get entries in a specific address range
125 std::vector<TraceEntry> GetEntriesInRange(uint32_t start_addr,
126 uint32_t end_addr) const;
127
128 // Clear the buffer
129 void Clear() { buffer_.clear(); }
130
131 // Get total number of recorded entries
132 size_t GetSize() const { return buffer_.size(); }
133
134 private:
135 size_t max_size_;
136 std::vector<TraceEntry> buffer_;
137 size_t write_index_ = 0; // For circular buffer behavior
138};
139
140} // namespace agent
141} // namespace cli
142} // namespace yaze
143
144#endif // YAZE_CLI_SERVICE_AGENT_DISASSEMBLER_65816_H_
void SetFlags(bool m_flag, bool x_flag)
uint8_t DisassembleInstruction(uint32_t address, const uint8_t *data, std::string &mnemonic, std::string &operand_str, std::vector< uint8_t > &operands)
std::unordered_map< uint8_t, InstructionInfo > opcode_table_
uint8_t GetInstructionSize(uint8_t opcode) const
static std::string FormatAddress(uint32_t address)
std::string FormatOperand(AddressingMode mode, uint32_t address, const std::vector< uint8_t > &operands) const
uint8_t GetEffectiveSize(uint8_t opcode, AddressingMode mode) const
void RecordExecution(const TraceEntry &entry)
std::vector< TraceEntry > GetRecentEntries(size_t count) const
ExecutionTraceBuffer(size_t max_size=kDefaultBufferSize)
std::vector< TraceEntry > GetEntriesInRange(uint32_t start_addr, uint32_t end_addr) const