spo/simulator_SIC_XE/include/code.h
2025-12-21 17:17:52 +01:00

68 lines
No EOL
1.7 KiB
C++

#ifndef CODE_H
#define CODE_H
#include <vector>
#include <memory>
#include <unordered_map>
#include <cstdint>
#include "node.h"
class Code {
public:
Code() = default;
void addLine(const std::shared_ptr<Node>& line);
const std::vector<std::shared_ptr<Node>>& getLines() const;
const string toString() const;
// Two-pass assembler methods
void assemble();
std::vector<uint8_t> emitCode();
std::string emitText();
std::string dumpSymbols() const;
std::string dumpCode() const;
private:
std::vector<std::shared_ptr<Node>> _lines;
// Assembler state
std::unordered_map<std::string, int> _symbolTable;
std::vector<int> _locationCounters; // Location counter per line
int _startAddress = 0;
int _programLength = 0;
std::string _programName;
int _baseRegister = -1; // -1 means not set
struct ModificationRecord {
int address;
int halfBytes;
};
mutable std::vector<ModificationRecord> _modificationRecords;
// Pass 1: build symbol table and assign addresses
void firstPass();
// Pass 2: generate code
void secondPass();
// Helper methods
int getInstructionLength(const std::shared_ptr<Node>& node, int locationCounter) const;
std::vector<uint8_t> generateInstruction(const InstructionNode* inst, int address);
std::vector<uint8_t> generateData(const DataNode* data);
// Addressing mode selection
struct AddressingResult {
int nixbpe; // ni, x, b, p, e bits
int displacement; // 12-bit or 20-bit
bool success;
};
AddressingResult selectAddressingMode(int targetAddress, int pc, bool indexed, bool immediate, bool indirect, bool extended) const;
};
#endif // CODE_H