From af8475caf71cc8c85a1932e4752161ba34519294 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Tue, 11 Jul 2023 15:57:12 +0900 Subject: [PATCH] Make a5 and a6 work --- src/instructions.c | 8 ++++---- src/instructions.h | 1 + src/instructions/arithmetics.c | 25 ++++++++++++++++++++++++- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/src/instructions.c b/src/instructions.c index ae6b976..d85766d 100644 --- a/src/instructions.c +++ b/src/instructions.c @@ -343,7 +343,7 @@ const instruction_t extended[][8] = { {.opcode = 0x04, .extended = -2, .name = "shl %s, 1", .mode = {R_M8, END}, .exec = &shl}, {.opcode = 0x05, .extended = -2, .name = "shr %s, 1", .mode = {R_M8, END}, .exec = NULL}, /**/{.opcode = 0x06, .extended = -2, .name = "invalid", .mode = {END}, .exec = NULL}, - {.opcode = 0x07, .extended = -2, .name = "sar %s, 1", .mode = {R_M8, END}, .exec = NULL}, + {.opcode = 0x07, .extended = -2, .name = "sar %s, 1", .mode = {R_M8, END}, .exec = &sar}, }, // 0xd1 extended { @@ -354,7 +354,7 @@ const instruction_t extended[][8] = { {.opcode = 0x04, .extended = -2, .name = "shl %s, 1", .mode = {R_M16, END}, .exec = &shl}, {.opcode = 0x05, .extended = -2, .name = "shr %s, 1", .mode = {R_M16, END}, .exec = NULL}, /**/{.opcode = 0x06, .extended = -2, .name = "invalid", .mode = {END}, .exec = NULL}, - {.opcode = 0x07, .extended = -2, .name = "sar %s, 1", .mode = {R_M16, END}, .exec = NULL}, + {.opcode = 0x07, .extended = -2, .name = "sar %s, 1", .mode = {R_M16, END}, .exec = &sar}, }, // 0xd2 extended { @@ -365,7 +365,7 @@ const instruction_t extended[][8] = { {.opcode = 0x04, .extended = -2, .name = "shl %s, cl", .mode = {R_M8, END}, .exec = &shl}, {.opcode = 0x05, .extended = -2, .name = "shr %s, cl", .mode = {R_M8, END}, .exec = NULL}, /**/{.opcode = 0x06, .extended = -2, .name = "invalid", .mode = {END}, .exec = NULL}, - {.opcode = 0x07, .extended = -2, .name = "sar %s, cl", .mode = {R_M8, END}, .exec = NULL}, + {.opcode = 0x07, .extended = -2, .name = "sar %s, cl", .mode = {R_M8, END}, .exec = &sar}, }, // 0xd3 extended { @@ -376,7 +376,7 @@ const instruction_t extended[][8] = { {.opcode = 0x04, .extended = -2, .name = "shl %s, cl", .mode = {R_M16, END}, .exec = &shl}, {.opcode = 0x05, .extended = -2, .name = "shr %s, cl", .mode = {R_M16, END}, .exec = NULL}, /**/{.opcode = 0x06, .extended = -2, .name = "invalid", .mode = {END}, .exec = NULL}, - {.opcode = 0x07, .extended = -2, .name = "sar %s, cl", .mode = {R_M16, END}, .exec = NULL}, + {.opcode = 0x07, .extended = -2, .name = "sar %s, cl", .mode = {R_M16, END}, .exec = &sar}, }, }; diff --git a/src/instructions.h b/src/instructions.h index 8f7a353..2d765fd 100644 --- a/src/instructions.h +++ b/src/instructions.h @@ -44,4 +44,5 @@ void cbw(const instruction_t *self, state_t *state); void cwd(const instruction_t *self, state_t *state); void neg(const instruction_t *self, state_t *state); void shl(const instruction_t *self, state_t *state); +void sar(const instruction_t *self, state_t *state); void xchg(const instruction_t *self, state_t *state); diff --git a/src/instructions/arithmetics.c b/src/instructions/arithmetics.c index 02ab7a2..6ff3337 100644 --- a/src/instructions/arithmetics.c +++ b/src/instructions/arithmetics.c @@ -201,11 +201,34 @@ void shl(const instruction_t *self, state_t *state) write_op(to, new); - state->cf = value >> (8 - shft); + state->of = new != read_op(to); + state->cf = value >> (8 - shft) & 1; state->sf = new & (is_operand_wide(self, 0) ? 0x8000 : 0x80); state->zf = new == 0; } +void sar(const instruction_t *self, state_t *state) +{ + operand_t to = get_operand(self, 0, state); + unsigned value = read_op(to); + uint8_t opgrp =state->binary[state->pc]; + unsigned shft = (opgrp == 0xd0 || opgrp == 0xd1) ? 1 : state->cl; + + unsigned signMask = (is_operand_wide(self, 0) ? 0x8000 : 0x80); + + unsigned new = value >> shft; + if (value & signMask) + new |= signMask; + else + new &= ~signMask; + + write_op(to, new); + + state->cf = (value >> (shft - 1)) & 1; + state->sf = value & signMask; + state->zf = new == 0; +} + void xchg(const instruction_t *self, state_t *state) { operand_t from = get_operand(self, 0, state);