2020-02-11 22:01:06 -05:00
|
|
|
#pragma once
|
|
|
|
#include "stdafx.h"
|
|
|
|
#include <regex>
|
2020-06-06 22:27:54 -04:00
|
|
|
#include "IAssembler.h"
|
2020-02-11 22:01:06 -05:00
|
|
|
#include "CpuDisUtils.h"
|
|
|
|
|
|
|
|
class LabelManager;
|
|
|
|
|
|
|
|
struct LineData
|
|
|
|
{
|
|
|
|
string OpCode;
|
|
|
|
string Operand;
|
|
|
|
string OperandSuffix;
|
|
|
|
AddrMode Mode = AddrMode::Imp;
|
|
|
|
int OperandSize = 0;
|
|
|
|
bool IsHex = false;
|
|
|
|
bool IsDecimal = false;
|
|
|
|
bool IsImmediate = false;
|
|
|
|
bool HasComment = false;
|
|
|
|
bool HasOpeningParenthesis = false;
|
|
|
|
bool HasOpeningBracket = false;
|
|
|
|
};
|
|
|
|
|
2020-06-06 22:27:54 -04:00
|
|
|
class Assembler : public IAssembler
|
2020-02-11 22:01:06 -05:00
|
|
|
{
|
|
|
|
private:
|
|
|
|
std::unordered_map<string, std::unordered_set<int>> _availableModesByOpName;
|
|
|
|
bool _needSecondPass;
|
|
|
|
|
|
|
|
shared_ptr<LabelManager> _labelManager;
|
2021-03-10 11:13:28 -05:00
|
|
|
void ProcessLine(string code, uint32_t& instructionAddress, vector<int16_t>& output, std::unordered_map<string, uint32_t>& labels, bool firstPass, std::unordered_map<string, uint32_t>& currentPassLabels);
|
|
|
|
AssemblerSpecialCodes GetLineData(std::smatch match, LineData& lineData, std::unordered_map<string, uint32_t>& labels, bool firstPass);
|
|
|
|
AssemblerSpecialCodes GetAddrModeAndOperandSize(LineData& lineData, std::unordered_map<string, uint32_t>& labels, bool firstPass);
|
2020-02-11 22:01:06 -05:00
|
|
|
void AssembleInstruction(LineData& lineData, uint32_t& instructionAddress, vector<int16_t>& output, bool firstPass);
|
|
|
|
|
|
|
|
bool IsOpModeAvailable(string& opCode, AddrMode mode);
|
|
|
|
|
|
|
|
public:
|
|
|
|
Assembler(shared_ptr<LabelManager> labelManager);
|
2020-06-06 22:27:54 -04:00
|
|
|
virtual ~Assembler();
|
2020-02-11 22:01:06 -05:00
|
|
|
|
|
|
|
uint32_t AssembleCode(string code, uint32_t startAddress, int16_t* assembledCode);
|
2021-03-10 11:13:28 -05:00
|
|
|
};
|