From 03066c54eb0185a0a0ebe052a77078bd832164e3 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Fri, 27 Mar 2015 16:02:54 -0400 Subject: [PATCH] Implement INC ss. --- src/z80.c | 37 +++++++++++++++++++++++++++++++++++++ src/z80_instructions.inc | 30 ++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/z80.c b/src/z80.c index 8bcf29f..3cb2186 100644 --- a/src/z80.c +++ b/src/z80.c @@ -4,6 +4,11 @@ #include "logging.h" #include "z80.h" +#define REG_AF 0 +#define REG_BC 1 +#define REG_DE 2 +#define REG_HL 3 + #define FLAG_CARRY 0 #define FLAG_SUBTRACT 1 #define FLAG_PARITY 2 @@ -63,6 +68,38 @@ void z80_power(Z80 *z80) } /* + Get the value of a register pair. +*/ +static inline uint16_t get_pair(Z80 *z80, uint8_t pair) +{ + Z80RegFile *regfile = &z80->regfile; + + switch (pair) { + case REG_AF: return (((uint16_t) regfile->a) << 8) + regfile->f; + case REG_BC: return (((uint16_t) regfile->b) << 8) + regfile->c; + case REG_DE: return (((uint16_t) regfile->d) << 8) + regfile->e; + case REG_HL: return (((uint16_t) regfile->h) << 8) + regfile->l; + default: FATAL("Invalid call: get_pair(z80, %u)", pair) + } +} + +/* + Set the value of a register pair. +*/ +static inline void set_pair(Z80 *z80, uint8_t pair, uint16_t value) +{ + Z80RegFile *regfile = &z80->regfile; + + switch (pair) { + case REG_AF: regfile->a = value >> 8; regfile->f = value; break; + case REG_BC: regfile->b = value >> 8; regfile->c = value; break; + case REG_DE: regfile->d = value >> 8; regfile->e = value; break; + case REG_HL: regfile->h = value >> 8; regfile->l = value; break; + default: FATAL("Invalid call: set_pair(z80, %u, 0x%04X)", pair, value) + } +} + +/* Return whether a particular flag is set in the F register. */ static inline bool get_flag(const Z80 *z80, uint8_t flag) diff --git a/src/z80_instructions.inc b/src/z80_instructions.inc index d980749..b9aa3cb 100644 --- a/src/z80_instructions.inc +++ b/src/z80_instructions.inc @@ -62,11 +62,33 @@ static uint8_t z80_inst_inc_r(Z80 *z80, uint8_t opcode) return 4; } +/* + INC ss (0x03, 0x13, 0x23, 0x33): + Increment the 16-bit register encoded in the opcode. +*/ +static uint8_t z80_inst_inc_ss(Z80 *z80, uint8_t opcode) +{ + if (opcode == 0x33) { + z80->regfile.sp++; + } else { + uint8_t pair; + switch(opcode) { + case 0x03: pair = REG_BC; break; + case 0x13: pair = REG_DE; break; + case 0x23: pair = REG_HL; break; + } + set_pair(z80, pair, get_pair(z80, pair) + 1); + } + + z80->regfile.pc++; + return 6; +} + static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { /* 0x00 */ z80_inst_nop, /* 0x01 */ z80_inst_unimplemented, // TODO /* 0x02 */ z80_inst_unimplemented, // TODO - /* 0x03 */ z80_inst_unimplemented, // TODO + /* 0x03 */ z80_inst_inc_ss, /* 0x04 */ z80_inst_inc_r, /* 0x05 */ z80_inst_unimplemented, // TODO /* 0x06 */ z80_inst_unimplemented, // TODO @@ -82,7 +104,7 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { /* 0x10 */ z80_inst_unimplemented, // TODO /* 0x11 */ z80_inst_unimplemented, // TODO /* 0x12 */ z80_inst_unimplemented, // TODO - /* 0x13 */ z80_inst_unimplemented, // TODO + /* 0x13 */ z80_inst_inc_ss, /* 0x14 */ z80_inst_inc_r, /* 0x15 */ z80_inst_unimplemented, // TODO /* 0x16 */ z80_inst_unimplemented, // TODO @@ -98,7 +120,7 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { /* 0x20 */ z80_inst_unimplemented, // TODO /* 0x21 */ z80_inst_unimplemented, // TODO /* 0x22 */ z80_inst_unimplemented, // TODO - /* 0x23 */ z80_inst_unimplemented, // TODO + /* 0x23 */ z80_inst_inc_ss, /* 0x24 */ z80_inst_inc_r, /* 0x25 */ z80_inst_unimplemented, // TODO /* 0x26 */ z80_inst_unimplemented, // TODO @@ -114,7 +136,7 @@ static uint8_t (*instruction_lookup_table[256])(Z80*, uint8_t) = { /* 0x30 */ z80_inst_unimplemented, // TODO /* 0x31 */ z80_inst_unimplemented, // TODO /* 0x32 */ z80_inst_unimplemented, // TODO - /* 0x33 */ z80_inst_unimplemented, // TODO + /* 0x33 */ z80_inst_inc_ss, /* 0x34 */ z80_inst_unimplemented, // TODO /* 0x35 */ z80_inst_unimplemented, // TODO /* 0x36 */ z80_inst_unimplemented, // TODO