instruction encoding and decoding working

This commit is contained in:
2026-07-15 17:31:10 +10:00
parent 9d0c1de3f5
commit c06f070921
8 changed files with 221 additions and 10 deletions

View File

@@ -23,8 +23,44 @@ inline void memorySaveWord(Memory* m, uint32_t address, uint16_t value) {
((uint16_t*)m->data)[address] = value;
}
void putInst(Memory* m, SerializedInst inst, uint32_t offset) {
memcpy((SerializedInst*)(&m->data[MEM_PROGRAM_START]) + offset, &inst, sizeof(SerializedInst));
}
uint32_t memorySerializeInst(Memory* m, Instruction inst, uint32_t offset) {
SerializedInst packed = 0;
packed |= (SerializedInst)(inst.opcode & 0b0000000000001111) ;
packed |= (SerializedInst)(inst.operands[0] & 0b0000000000001111) << 4;
packed |= (SerializedInst)(inst.operands[1] & 0b0000000000001111) << 8;
packed |= (SerializedInst)(inst.operands[2] & 0b0000000000001111) << 12;
memcpy(m->data + MEM_PROGRAM_START + (offset * sizeof(SerializedInst)), &packed, sizeof(SerializedInst));
offset++;
// write the imm16 if the instruction has one
if (inst.hasImm16) {
memcpy(m->data + MEM_PROGRAM_START + (offset * sizeof(SerializedInst)), &inst.immediate, sizeof(SerializedInst));
offset++;
}
return offset;
}
void memoryLoadProgram(Memory* m, Instruction program[], size_t numInstructions) {
size_t offset = 0;
for (size_t i = 0; i < numInstructions; i++) {
offset = memorySerializeInst(m, program[i], offset);
}
}
Instruction decodeInstruction(Memory* m, uint32_t* pc) {
SerializedInst serialized = m->data[*pc];
SerializedInst serialized;
memcpy(&serialized, &m->data[*pc], sizeof(SerializedInst));
Instruction outputInst = {};
uint8_t opcode = serialized & 0b0000000000001111; // get four lowest bits for the opcode
@@ -38,14 +74,17 @@ Instruction decodeInstruction(Memory* m, uint32_t* pc) {
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;
outputInst.operands[i] = (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];
(*pc) += sizeof(SerializedInst);
uint16_t nextDataOver = m->data[*pc];
outputInst.immediate = nextDataOver;
outputInst.hasImm16 = true;
break;
}
@@ -53,12 +92,20 @@ Instruction decodeInstruction(Memory* m, uint32_t* pc) {
break;
}
}
if (opTypes[i] == OP_IMM16) break;
}
(*pc) += sizeof(SerializedInst);
return outputInst;
}
void freeMemory(Memory* m) {
free(m->data);
free(m);
}
inline uint32_t getAddress(uint16_t low, uint16_t high) {
return (high << 16) | low;
}