#pragma once #include "stdafx.h" #include #include #include "CPU.h" class LabelManager; struct LineData { string OpCode; string Operand; string OperandSuffix; AddrMode Mode = AddrMode::None; int OperandSize = 0; bool IsHex = false; bool IsDecimal = false; bool IsImmediate = false; bool HasComment = false; bool HasOpeningParenthesis = false; }; enum AssemblerSpecialCodes { OK = 0, EndOfLine = -1, ParsingError = -2, OutOfRangeJump = -3, LabelRedefinition = -4, MissingOperand = -5, OperandOutOfRange = -6, InvalidHex = -7, InvalidSpaces = -8, TrailingText = -9, UnknownLabel = -10, InvalidInstruction = -11, }; class Assembler { private: std::unordered_map> _availableModesByOpName; bool _needSecondPass; shared_ptr _labelManager; void ProcessLine(string code, uint16_t &instructionAddress, vector& output, std::unordered_map &labels, bool firstPass, std::unordered_map ¤tPassLabels); AssemblerSpecialCodes GetLineData(std::smatch match, LineData &lineData, std::unordered_map &labels, bool firstPass); AssemblerSpecialCodes GetAddrModeAndOperandSize(LineData &lineData, std::unordered_map &labels, bool firstPass); void AssembleInstruction(LineData &lineData, uint16_t &instructionAddress, vector& output, bool firstPass); bool IsOpModeAvailable(string &opCode, AddrMode mode); public: Assembler(shared_ptr labelManager); uint32_t AssembleCode(string code, uint16_t startAddress, int16_t* assembledCode); };