7#include <unordered_map>
10#include "absl/strings/match.h"
59 return std::hash<std::string>()(k.
mnemonic) ^
60 (std::hash<int>()(
static_cast<int>(k.
mode)) << 1);
66 std::vector<uint8_t>
Parse(
const std::string& instruction) {
69 if (tokens.size() < 1) {
70 throw std::runtime_error(
"Invalid instruction format: " + instruction);
74 std::vector<uint8_t> bytes;
75 while (index < tokens.size()) {
85 const std::string& mnemonic = tokens[index];
91 std::string qualifier =
"";
92 std::string potential_mode = tokens[index];
93 if (absl::StrContains(potential_mode,
".")) {
94 qualifier = potential_mode;
101 std::string operand = tokens[index];
102 if (operand ==
"#") {
106 if (tokens[index] ==
"#") {
108 operand = tokens[index];
111 }
else if (operand ==
"$") {
113 operand = tokens[index];
122 throw std::runtime_error(
"Opcode not found for mnemonic and mode: " +
126 bytes.push_back(opcode_entry->second);
135 std::vector<std::string>
Tokenize(
const std::string& instruction) {
136 std::vector<std::string> tokens;
137 std::regex tokenRegex{R
"((\w+|\.\w+|[\#$]|[0-9a-fA-F]+|[a-zA-Z]+))"};
138 auto words_begin = std::sregex_iterator(instruction.begin(),
139 instruction.end(), tokenRegex);
140 auto words_end = std::sregex_iterator();
142 for (std::sregex_iterator i = words_begin; i != words_end; ++i) {
143 std::smatch match = *i;
144 tokens.push_back(match.str());
151 const std::string& operand,
154 switch (addressing_mode) {
156 bytes.push_back(
static_cast<uint8_t
>(std::stoi(operand,
nullptr, 16)));
160 uint16_t word_operand =
161 static_cast<uint16_t
>(std::stoi(operand,
nullptr, 16));
162 bytes.push_back(
static_cast<uint8_t
>(word_operand & 0xFF));
163 bytes.push_back(
static_cast<uint8_t
>((word_operand >> 8) & 0xFF));
167 uint32_t long_operand =
168 static_cast<uint32_t
>(std::stoul(operand,
nullptr, 16));
169 bytes.push_back(
static_cast<uint8_t
>(long_operand & 0xFF));
170 bytes.push_back(
static_cast<uint8_t
>((long_operand >> 8) & 0xFF));
171 bytes.push_back(
static_cast<uint8_t
>((long_operand >> 16) & 0xFF));
179 bytes.push_back(
static_cast<uint8_t
>(std::stoi(operand,
nullptr, 16)));
184 const std::string& addressingMode = tokens[1];
185 if (addressingMode ==
".b") {
187 }
else if (addressingMode ==
".w") {
189 }
else if (addressingMode ==
".l") {
198 value = std::stoi(str,
nullptr, 16);
200 }
catch (
const std::invalid_argument& e) {
207 value = std::stoul(str,
nullptr, 16);
209 }
catch (
const std::invalid_argument& e) {
438 std::unordered_map<MnemonicMode, uint8_t, MnemonicModeHash>
std::vector< uint8_t > Parse(const std::string &instruction)
bool TryParseHex(const std::string &str, uint32_t &value)
std::unordered_map< MnemonicMode, uint8_t, MnemonicModeHash > mnemonic_to_opcode_
std::vector< std::string > Tokenize(const std::string &instruction)
void CreateInternalOpcodeMap()
bool TryParseByte(const std::string &str, uint8_t &value)
AddressingMode DetermineMode(const std::vector< std::string > &tokens)
void AppendOperandBytes(std::vector< uint8_t > &bytes, const std::string &operand, const AddressingMode &addressing_mode)
SNES Emulation and debugging tools.
@ kDirectPageIndirectIndexedY
@ kStackRelativeIndirectIndexedY
@ kStackRelativeIndirectIndexedYLong
@ kDirectPageIndirectLongIndexedX
@ kProgramCounterRelative
@ kDirectPageIndirectLong
@ kDirectPageIndirectLongIndexedY
@ kDirectPageIndirectIndexedX
@ kProgramCounterRelativeLong
@ kAbsoluteIndexedIndirect
Main namespace for the application.
std::size_t operator()(const MnemonicMode &k) const
bool operator==(const MnemonicMode &other) const