Files
MyLittleCPU/src/memory.c

64 lines
1.7 KiB
C
Raw Normal View History

2026-07-15 15:02:54 +10:00
#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;
}
2026-07-15 15:54:51 +10:00
Instruction decodeInstruction(Memory* m, uint32_t* pc) {
SerializedInst serialized = m->data[*pc];
Instruction outputInst = {};
uint8_t opcode = serialized & 0b0000000000001111; // get four lowest bits for the opcode
outputInst.opcode = opcode;
const OperandType* opTypes = INSTRUCTION_OPERAND_TYPES[opcode];
uint8_t offset = 0;
for (uint8_t i = 0; i < 3; i++) {
switch (opTypes[i]) {
case OP_REG: {
// get the data at the current offset, and grab the 4 bits that are there with a bitwise
// "and" operator
outputInst.operands[offset] = (serialized >> (4 * (offset + 1))) & 0b0000000000001111;
offset++;
break;
}
case OP_IMM16: { // the immediate 16 takes up the space where the next instruction would be
uint16_t nextDataOver = m->data[++*pc];
outputInst.immediate = nextDataOver;
break;
}
case OP_NONE: {
break;
}
}
}
return outputInst;
}
void freeMemory(Memory* m) {
free(m->data);
free(m);
}