68 lines
1.6 KiB
C
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)) {}
|
||
|
|
};
|