Files
MyLittleCPU/emulator.h
2026-07-14 19:54:23 +10:00

68 lines
1.6 KiB
C++

#pragma once
#include <cstdint>
#include <vector>
#include <array>
#include "instruction.h"
#define MEMORY_SIZE 0x00040000 // 256 kibibytes, or 262144
#define PROGRAM_ROM_START 0x00001000
#define GENERAL_PURPOSE_START 0x00010000
#define PC_REG_OFFSET 7
#define IHP_REG_OFFSET 8
#define SP_REG_OFFSET 9
#define FLAGS_REG_OFFSET 10
#define PC registers[PC_REG_OFFSET]
#define IHP registers[PC_REG_OFFSET]
#define SP registers[PC_REG_OFFSET]
#define FLAGS registers[PC_REG_OFFSET]
#define FLAGS_CARRY (1 << 0)
#define FLAGS_ZERO (1 << 1)
#define FLAGS_NEGATIVE (1 << 2)
/*
* All-purpose memory used by the emulator
* 4kb for call stack (0x00000000 -> 0x00000FFF)
* 65kb for program ROM (0x00001000 -> 0x0000FFFF)
* Rest for general purpose (0x00010000 -> MEMORY_SIZE)
*/
struct Memory {
size_t instructions = 0;
size_t calls = 0;
uint8_t memory[MEMORY_SIZE]{};
void addInstruction(const Instruction& inst);
void addCall(const uint16_t address);
uint8_t* operator[](const size_t& offset);
Memory() = default;
Memory(const std::vector<Instruction>& instructions) {
for (const auto& instruction : instructions) {
addInstruction(instruction.asBytecodeInstruction());
}
}
};
using Program = std::vector<Instruction>;
class Emulator {
private:
std::array<uint16_t, 11> registers = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
Memory memory = {};
bool halted = false;
Instruction fetchNextInst();
void updateFlags(int32_t opResult);
public:
void start();
Emulator() = delete;
Emulator(const Memory& memory) : memory(std::move(memory)) {}
};