diff --git a/src/instructions.c b/src/instructions.c index a772efa..c0f5cfa 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -30,7 +30,7 @@ const instruction_t instructions[] = { {.opcode = 0x03, .extended = -1, .name = "add", .mode = {REG16, R_M16, END}, .exec = NULL}, {.opcode = 0x04, .extended = -1, .name = "add", .mode = {OPREG8, IMM8, END}, .exec = NULL}, {.opcode = 0x05, .extended = -1, .name = "add", .mode = {OPREG16, IMM16, END}, .exec = NULL}, - {.opcode = 0x06, .extended = -1, .name = "push es", .mode = {END}, .exec = NULL}, + {.opcode = 0x06, .extended = -1, .name = "push es", .mode = {END}, .exec = &push}, {.opcode = 0x07, .extended = -1, .name = "pop es", .mode = {END}, .exec = NULL}, {.opcode = 0x08, .extended = -1, .name = "or", .mode = {R_M8, REG8, END}, .exec = NULL}, {.opcode = 0x09, .extended = -1, .name = "or", .mode = {R_M16, REG16, END}, .exec = NULL}, @@ -38,7 +38,7 @@ const instruction_t instructions[] = { {.opcode = 0x0B, .extended = -1, .name = "or", .mode = {REG16, R_M16, END}, .exec = NULL}, {.opcode = 0x0C, .extended = -1, .name = "or", .mode = {OPREG8, IMM8, END}, .exec = NULL}, {.opcode = 0x0D, .extended = -1, .name = "or", .mode = {OPREG16, IMM16, END}, .exec = NULL}, - {.opcode = 0x0E, .extended = -1, .name = "push cs", .mode = {END}, .exec = NULL}, + {.opcode = 0x0E, .extended = -1, .name = "push cs", .mode = {END}, .exec = &push}, {.opcode = 0x10, .extended = -1, .name = "adc", .mode = {R_M8, REG8, END}, .exec = NULL}, {.opcode = 0x11, .extended = -1, .name = "adc", .mode = {R_M16, REG16, END}, .exec = NULL}, @@ -46,7 +46,7 @@ const instruction_t instructions[] = { {.opcode = 0x13, .extended = -1, .name = "adc", .mode = {REG16, R_M16, END}, .exec = NULL}, {.opcode = 0x14, .extended = -1, .name = "adc", .mode = {OPREG8, IMM8, END}, .exec = NULL}, {.opcode = 0x15, .extended = -1, .name = "adc", .mode = {OPREG16, IMM16, END}, .exec = NULL}, - {.opcode = 0x16, .extended = -1, .name = "push ss", .mode = {END}, .exec = NULL}, + {.opcode = 0x16, .extended = -1, .name = "push ss", .mode = {END}, .exec = &push}, {.opcode = 0x17, .extended = -1, .name = "pop ss", .mode = {END}, .exec = NULL}, {.opcode = 0x18, .extended = -1, .name = "sbb", .mode = {R_M8, REG8, END}, .exec = NULL}, {.opcode = 0x19, .extended = -1, .name = "sbb", .mode = {R_M16, REG16, END}, .exec = NULL}, @@ -54,7 +54,7 @@ const instruction_t instructions[] = { {.opcode = 0x1B, .extended = -1, .name = "sbb", .mode = {REG16, R_M16, END}, .exec = NULL}, {.opcode = 0x1C, .extended = -1, .name = "sbb", .mode = {OPREG8, IMM8, END}, .exec = NULL}, {.opcode = 0x1D, .extended = -1, .name = "sbb", .mode = {OPREG16, IMM16, END}, .exec = NULL}, - {.opcode = 0x1E, .extended = -1, .name = "push ds", .mode = {END}, .exec = NULL}, + {.opcode = 0x1E, .extended = -1, .name = "push ds", .mode = {END}, .exec = &push}, {.opcode = 0x1F, .extended = -1, .name = "pop ds", .mode = {END}, .exec = NULL}, {.opcode = 0x20, .extended = -1, .name = "and", .mode = {R_M8, REG8, END}, .exec = NULL}, {.opcode = 0x21, .extended = -1, .name = "and", .mode = {R_M16, REG16, END}, .exec = NULL}, @@ -104,14 +104,14 @@ const instruction_t instructions[] = { {.opcode = 0x4D, .extended = -1, .name = "dec", .mode = {OPREG16, END}, .exec = NULL}, {.opcode = 0x4E, .extended = -1, .name = "dec", .mode = {OPREG16, END}, .exec = NULL}, {.opcode = 0x4F, .extended = -1, .name = "dec", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x50, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x51, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x52, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x53, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x54, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x55, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x56, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, - {.opcode = 0x57, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = NULL}, + {.opcode = 0x50, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x51, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x52, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x53, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x54, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x55, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x56, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, + {.opcode = 0x57, .extended = -1, .name = "push", .mode = {OPREG16, END}, .exec = &push}, {.opcode = 0x58, .extended = -1, .name = "pop", .mode = {OPREG16, END}, .exec = NULL}, {.opcode = 0x59, .extended = -1, .name = "pop", .mode = {OPREG16, END}, .exec = NULL}, {.opcode = 0x5A, .extended = -1, .name = "pop", .mode = {OPREG16, END}, .exec = NULL}, @@ -164,7 +164,7 @@ const instruction_t instructions[] = { {.opcode = 0x99, .extended = -1, .name = "cwd", .mode = {END}, .exec = NULL}, // {.opcode = 0x9A, .extended = -1, .name = "call", .mode = {CALL_INTER, END}, .exec = NULL}, {.opcode = 0x9B, .extended = -1, .name = "wait", .mode = {END}, .exec = NULL}, - {.opcode = 0x9C, .extended = -1, .name = "pushf", .mode = {END}, .exec = NULL}, + {.opcode = 0x9C, .extended = -1, .name = "pushf", .mode = {END}, .exec = &push}, {.opcode = 0x9D, .extended = -1, .name = "popf", .mode = {END}, .exec = NULL}, {.opcode = 0x9E, .extended = -1, .name = "sahf", .mode = {END}, .exec = NULL}, {.opcode = 0x9F, .extended = -1, .name = "lahf", .mode = {END}, .exec = NULL}, @@ -330,7 +330,7 @@ const instruction_t extended[][8] = { {.opcode = 0x03, .extended = -2, .name = "call", .mode = {R_M16, END}, .exec = NULL}, {.opcode = 0x04, .extended = -2, .name = "jmp", .mode = {R_M16, END}, .exec = NULL}, {.opcode = 0x05, .extended = -2, .name = "jmp", .mode = {R_M16, END}, .exec = NULL}, - {.opcode = 0x06, .extended = -2, .name = "push", .mode = {R_M16, END}, .exec = NULL}, + {.opcode = 0x06, .extended = -2, .name = "push", .mode = {R_M16, END}, .exec = &push}, /**/{.opcode = 0x07, .extended = -2, .name = "invalid", .mode = {END}, .exec = NULL}, }, diff --git a/src/instructions.h b/src/instructions.h index 504a516..6bcd5c9 100644 --- a/src/instructions.h +++ b/src/instructions.h @@ -4,5 +4,6 @@ #include "interpretor.h" void mov(const instruction_t *self, state_t *state); +void push(const instruction_t *self, state_t *state); void int_inst(const instruction_t *self, state_t *state); void sub(const instruction_t *self, state_t *state); diff --git a/src/instructions/memory.c b/src/instructions/memory.c index f0435b4..9a2a00d 100644 --- a/src/instructions/memory.c +++ b/src/instructions/memory.c @@ -17,6 +17,15 @@ void mov(const instruction_t *self, state_t *state) *(uint8_t *)from = *(uint8_t *)to; } +void push(const instruction_t *self, state_t *state) +{ + uint16_t what = *(uint16_t *)get_operand(self, 0, state); + + if (is_operand_wide(self, 0)) + state->memory[state->sp--] = what >> 8; + state->memory[state->sp--] = what & 0xFF; +} + void int_inst(const instruction_t *self, state_t *state) { // I have no clue what the use of type is. diff --git a/src/interpretor.c b/src/interpretor.c index b45b791..b7c4b02 100644 --- a/src/interpretor.c +++ b/src/interpretor.c @@ -5,7 +5,7 @@ #include "dasm.h" #include "interpretor.h" -void *get_reg_operand(state_t *state, bool is16bit, bool is_in_op) +void *get_reg_operand(state_t *state, bool is16bit, unsigned reg) { uint8_t *registers8[8] = { &state->al, @@ -28,9 +28,6 @@ void *get_reg_operand(state_t *state, bool is16bit, bool is_in_op) &state->di, }; - unsigned reg = is_in_op - ? state->binary[state->pc] & 0b111 - : (state->binary[state->pc + 1] & 0b111000) >> 3; if (is16bit) return registers16[reg]; return registers8[reg]; @@ -42,7 +39,7 @@ void *get_rm_operand(state_t *state, unsigned *imm_idx, bool is16bit) unsigned rm = state->binary[state->pc + 1] & 0b111; if (mod == 0b11) - return get_reg_operand(state, is16bit, false); + return get_reg_operand(state, is16bit, rm); if (mod == 0 && rm == 0b110) { *imm_idx += 2; @@ -102,16 +99,16 @@ void *get_operand(const instruction_t *inst, unsigned i, state_t *state) ret = &state->parse_data.operand_holder[i]; break; case REG8: - ret = get_reg_operand(state, false, false); + ret = get_reg_operand(state, false, (state->binary[state->pc + 1] & 0b111000) >> 3); break; case REG16: - ret = get_reg_operand(state, true, false); + ret = get_reg_operand(state, true, (state->binary[state->pc + 1] & 0b111000) >> 3); break; case OPREG8: - ret = get_reg_operand(state, false, true); + ret = get_reg_operand(state, false, state->binary[state->pc] & 0b111); break; case OPREG16: - ret = get_reg_operand(state, true, true); + ret = get_reg_operand(state, true, state->binary[state->pc] & 0b111); break; case R_M8: ret = get_rm_operand(state, &imm_idx, false);