initial commit

This commit is contained in:
2026-07-15 15:02:54 +10:00
commit 8e26d3e19d
8 changed files with 168 additions and 0 deletions

12
meson.build Normal file
View File

@@ -0,0 +1,12 @@
project('MyLittleCPU', 'c')
sources = [
'src/main.c',
'src/emu.c',
'src/memory.c',
'src/instruction.c'
]
args = ['-Wall', '-Wextra', '-Wpedantic', '-O3']
executable('emu', sources, c_args: args)

19
src/emu.c Normal file
View File

@@ -0,0 +1,19 @@
#include "emu.h"
Emulator* initEmulator(uint32_t memorySize) {
Emulator* newEmu = malloc(sizeof(Emulator));
if (!newEmu)
return NULL;
// zero out registers
memset(newEmu->regs, 0, sizeof(newEmu->regs));
// init memory
newEmu->mem = initMemory(memorySize);
if (!newEmu->mem) {
free(newEmu);
return NULL;
}
return newEmu;
}

27
src/emu.h Normal file
View File

@@ -0,0 +1,27 @@
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "memory.h"
// -- TYPES -- //
typedef enum {
REG_A, REG_B, REG_C,
REG_X, REG_Y, REG_Z,
REG_R,
REG_PC, REG_IHP, REG_SP, REG_F,
REG_MAX // all registers should come before this one, this is so we can
// automatically know the length of the registers array
} Register;
typedef struct {
uint16_t regs[REG_MAX];
Memory* mem;
} Emulator;
// -- FUNCTIONS -- //
Emulator* initEmulator(uint32_t memorySize);

20
src/instruction.c Normal file
View File

@@ -0,0 +1,20 @@
#include "instruction.h"
const InstructionOperands INSTRUCTION_OPERAND_TYPES[] = {
{ INST_MVI, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_MOV, {OP_IMM4, OP_NONE, OP_NONE} },
{ INST_ADD, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_SUB, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_LOAD, {OP_IMM4, OP_IMM4, OP_IMM4} },
{ INST_STORE, {OP_IMM4, OP_IMM4, OP_IMM4} },
{ INST_AND, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_OR, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_XOR, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_SHF, {OP_IMM4, OP_IMM4, OP_IMM4} },
{ INST_JMP, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_JIZ, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_CALL, {OP_IMM4, OP_IMM4, OP_NONE} },
{ INST_RET, {OP_NONE, OP_NONE, OP_NONE} },
{ INST_SYS, {OP_IMM4, OP_IMM4, OP_IMM4} },
{ INST_HLT, {OP_NONE, OP_NONE, OP_NONE} },
};

30
src/instruction.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#include <stdint.h>
// -- TYPES -- //
typedef enum {
INST_MOV, INST_MVI, INST_ADD, INST_SUB, INST_LOAD, INST_STORE, INST_AND, INST_OR,
INST_XOR, INST_SHF, INST_JMP, INST_JIZ, INST_CALL, INST_RET, INST_SYS, INST_HLT
} InstructionOpcode;
typedef uint16_t SerializedInst;
typedef struct {
InstructionOpcode opcode;
uint16_t a;
uint16_t b;
uint16_t c;
} Instruction;
typedef enum {
OP_NONE, OP_IMM4
} OperandType;
typedef struct {
InstructionOpcode opcode;
OperandType operandTypes[3];
} InstructionOperands;
// -- CONSTANTS -- //
extern const InstructionOperands INSTRUCTION_OPERAND_TYPES[];

14
src/main.c Normal file
View File

@@ -0,0 +1,14 @@
#include <stdio.h>
#include "emu.h"
int main() {
Emulator* emu = initEmulator(0x00010FFF);
if (!emu) {
fprintf(stderr, "emu: error: failed to allocate memory for emulator\n");
return 1;
}
free(emu);
return 0;
}

24
src/memory.c Normal file
View File

@@ -0,0 +1,24 @@
#include "memory.h"
Memory* initMemory(uint32_t size) {
Memory* newMemory = malloc(sizeof(Memory));
if (!newMemory)
return NULL;
newMemory->size = size;
newMemory->data = calloc(size, sizeof(uint8_t));
if (!newMemory->data) {
free(newMemory);
return NULL;
}
return newMemory;
}
inline uint16_t memoryLoadWord(Memory* m, uint32_t address) {
return m->data[address];
}
inline void memorySaveWord(Memory* m, uint32_t address, uint16_t value) {
((uint16_t*)m->data)[address] = value;
}

22
src/memory.h Normal file
View File

@@ -0,0 +1,22 @@
#pragma once
#include <stdint.h>
#include <stdlib.h>
#include "instruction.h"
#define MEM_CALL_STACK_OFFSET 0x00000FFF
#define MEM_PROGRAM_START 0x00001000
#define MEM_PROGRAM_END 0x0000FFFF
#define MEM_GP_START 0x00010000
// -- TYPES -- //
typedef struct {
uint32_t size;
uint8_t* data;
} Memory;
// -- FUNCTIONS -- //
Memory* initMemory(uint32_t size);
uint16_t memoryLoadWord(Memory* m, uint32_t address);
void memorySaveWord(Memory* m, uint32_t address, uint16_t value);
Instruction decodeInstruction(Memory* m, uint32_t pc);