instruction decoding
This commit is contained in:
40
src/memory.c
40
src/memory.c
@@ -22,3 +22,43 @@ inline uint16_t memoryLoadWord(Memory* m, uint32_t address) {
|
||||
inline void memorySaveWord(Memory* m, uint32_t address, uint16_t value) {
|
||||
((uint16_t*)m->data)[address] = value;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
Reference in New Issue
Block a user