From bb9ffebd4afcb6f384994f6d52278df59204032e Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Fri, 7 Jul 2023 18:01:03 +0900 Subject: [PATCH] Implement the call instruction --- src/instructions.c | 8 ++++---- src/instructions.h | 1 + src/instructions/memory.c | 9 +++++++++ src/interpretor.c | 7 +++---- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/instructions.c b/src/instructions.c index c0f5cfa..425b029 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -162,7 +162,7 @@ const instruction_t instructions[] = { {.opcode = 0x97, .extended = -1, .name = "xchg di, ax", .mode = {END}, .exec = NULL}, {.opcode = 0x98, .extended = -1, .name = "cbw", .mode = {END}, .exec = NULL}, {.opcode = 0x99, .extended = -1, .name = "cwd", .mode = {END}, .exec = NULL}, - // {.opcode = 0x9A, .extended = -1, .name = "call", .mode = {CALL_INTER, END}, .exec = NULL}, + // {.opcode = 0x9A, .extended = -1, .name = "call", .mode = {CALL_INTER, END}, .exec = &call}, {.opcode = 0x9B, .extended = -1, .name = "wait", .mode = {END}, .exec = NULL}, {.opcode = 0x9C, .extended = -1, .name = "pushf", .mode = {END}, .exec = &push}, {.opcode = 0x9D, .extended = -1, .name = "popf", .mode = {END}, .exec = NULL}, @@ -229,7 +229,7 @@ const instruction_t instructions[] = { {.opcode = 0xE5, .extended = -1, .name = "in ax", .mode = {IMM8, END}, .exec = NULL}, {.opcode = 0xE6, .extended = -1, .name = "out %s, al", .mode = {IMM8, END}, .exec = NULL}, {.opcode = 0xE7, .extended = -1, .name = "out %s, ax", .mode = {IMM8, END}, .exec = NULL}, - {.opcode = 0xE8, .extended = -1, .name = "call", .mode = {REL16, END}, .exec = NULL}, + {.opcode = 0xE8, .extended = -1, .name = "call", .mode = {REL16, END}, .exec = &call}, {.opcode = 0xE9, .extended = -1, .name = "jmp", .mode = {REL16, END}, .exec = NULL}, // {.opcode = 0xEA, .extended = -1, .name = "jmp", .mode = {CALL_INTER, END}, .exec = NULL}, {.opcode = 0xEB, .extended = -1, .name = "jmp short", .mode = {REL8, END}, .exec = NULL}, @@ -326,8 +326,8 @@ const instruction_t extended[][8] = { { {.opcode = 0x00, .extended = -2, .name = "inc", .mode = {R_M16, END}, .exec = NULL}, {.opcode = 0x01, .extended = -2, .name = "dec", .mode = {R_M16, END}, .exec = NULL}, - {.opcode = 0x02, .extended = -2, .name = "call", .mode = {R_M16, END}, .exec = NULL}, - {.opcode = 0x03, .extended = -2, .name = "call", .mode = {R_M16, END}, .exec = NULL}, + {.opcode = 0x02, .extended = -2, .name = "call", .mode = {R_M16, END}, .exec = &call}, + {.opcode = 0x03, .extended = -2, .name = "call", .mode = {R_M16, END}, .exec = &call}, {.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 = &push}, diff --git a/src/instructions.h b/src/instructions.h index 6bcd5c9..29608dc 100644 --- a/src/instructions.h +++ b/src/instructions.h @@ -5,5 +5,6 @@ void mov(const instruction_t *self, state_t *state); void push(const instruction_t *self, state_t *state); +void call(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 9a2a00d..198042f 100644 --- a/src/instructions/memory.c +++ b/src/instructions/memory.c @@ -26,6 +26,15 @@ void push(const instruction_t *self, state_t *state) state->memory[state->sp--] = what & 0xFF; } +void call(const instruction_t *self, state_t *state) +{ + uint16_t pc = *(uint16_t *)get_operand(self, 0, state); + + state->memory[state->sp--] = state->pc >> 8; + state->memory[state->sp--] = state->pc & 0xFF; + state->pc = pc - get_inst_size(*self, state->binary + state->pc, state->binary_size - state->pc); +} + 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 b7c4b02..ccb572d 100644 --- a/src/interpretor.c +++ b/src/interpretor.c @@ -189,20 +189,19 @@ int interpret(u_int8_t *binary, unsigned long size) printf(" AX BX CX DX SP BP SI DI FLAGS IP\n"); while (state->pc < size) { - instruction_t inst = parse_inst(binary, size - state->pc); - unsigned inst_size = get_inst_size(inst, binary, size - state->pc); + instruction_t inst = parse_inst(state->binary + state->pc, size - state->pc); + unsigned inst_size = get_inst_size(inst, state->binary + state->pc, size - state->pc); if (state->pc + inst_size > size) { return 0; } print_state(state); - print_instruction(state->pc, inst, inst_size, binary, false); + print_instruction(state->pc, inst, inst_size, state->binary + state->pc, false); state->parse_data.imm_idx = 1 + (inst.extended != -1 || has_reg(&inst)); if (inst.exec) inst.exec(&inst, state); else printf("Not implemented.\n"); state->pc += inst_size; - binary += inst_size; } return 0; }