diff --git a/src/disassembler/arguments.c b/src/disassembler/arguments.c index 0dcb14b..c97c11b 100644 --- a/src/disassembler/arguments.c +++ b/src/disassembler/arguments.c @@ -89,8 +89,8 @@ static ArgType instr_args[3][256] = { __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, MR, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, MR, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __ }, { @@ -138,7 +138,7 @@ static ArgType instr_args_extended[3][256] = { __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, __, __, __, __, __, __, MI, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, @@ -196,7 +196,7 @@ static ArgType instr_args_bits[3][256] = { __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, MB, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, @@ -214,7 +214,7 @@ static ArgType instr_args_bits[3][256] = { __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, - __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, + __, __, __, __, __, __, __, __, B_, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, @@ -407,44 +407,45 @@ static ArgType instr_args_index_bits[3][256] = { /* Decode an immediate argument. */ -static void decode_immediate(char *arg, ArgType type, const uint8_t *bytes) +static void decode_immediate( + char *arg, ArgType type, const uint8_t *bytes, size_t shift) { char *format; + size_t take; + uint8_t b = bytes[shift]; switch (type) { - case AT_IMM_U16: - sprintf(arg, "$%04X", bytes[1] + (bytes[2] << 8)); + case AT_IMM_U16: // 16-bit immediate + sprintf(arg, "$%04X", bytes[shift + 1] + (bytes[shift + 2] << 8)); break; - case AT_IMM_U8: - // TODO: one byte? - strcpy(arg, "???"); + case AT_IMM_U8: // 8-bit unsigned immediate + if ((bytes[0] == 0xDD || bytes[0] == 0xFD) && bytes[1] == 0x36) + take = 2; + else + take = 1; + sprintf(arg, "$%02X", bytes[shift + take]); break; - case AT_IMM_REL: - // TODO: one byte, signed, plus 2? - strcpy(arg, "???"); + case AT_IMM_REL: // 8-bit relative offset (JP and DJNZ) + sprintf(arg, "%hhd", (int8_t) (bytes[shift + 1] + 2)); break; - case AT_IMM_BIT: - // TODO: bit ... - strcpy(arg, "???"); + case AT_IMM_BIT: // Bit position + sprintf(arg, "%d", (b & 0x38) >> 3); break; - case AT_IMM_RST: - // TODO: reset ... - strcpy(arg, "???"); + case AT_IMM_RST: // Reset + sprintf(arg, "$%02X", b & 0x38); break; - case AT_IMM_IM: - // TODO: interrupt mode ... - strcpy(arg, "???"); + case AT_IMM_IM: // Interrupt mode + sprintf(arg, "%d", !(b & (1 << 4)) ? 0 : !(b & (1 << 3)) ? 1 : 2); break; - case AT_IDR_IMM: - // TODO: two bytes? - strcpy(arg, "???"); + case AT_IDR_IMM: // Indirect immediate + sprintf(arg, "($%04X)", bytes[shift + 1] + (bytes[shift + 2] << 8)); break; - case AT_IX_IY: + case AT_IX_IY: // Indexed offset format = bytes[0] == 0xDD ? "(ix%+hhd)" : "(iy%+hhd)"; - sprintf(arg, format, (int8_t) bytes[1]); + sprintf(arg, format, (int8_t) bytes[shift + 1]); break; - case AT_PORT_IM: - sprintf(arg, "(%u)", bytes[1]); + case AT_PORT_IM: // Immediate port + sprintf(arg, "(%u)", bytes[shift + 1]); break; default: FATAL("invalid call: decode_immediate(arg, %d, ...)", type) @@ -455,7 +456,8 @@ static void decode_immediate(char *arg, ArgType type, const uint8_t *bytes) /* Decode a single argument, given its type. */ -static void decode_argument(char *arg, ArgType type, const uint8_t *bytes) +static void decode_argument( + char *arg, ArgType type, const uint8_t *bytes, size_t shift) { const char *value; @@ -506,7 +508,7 @@ static void decode_argument(char *arg, ArgType type, const uint8_t *bytes) case AT_IDR_IMM: case AT_IX_IY: case AT_PORT_IM: - decode_immediate(arg, type, bytes); + decode_immediate(arg, type, bytes, shift); return; default: FATAL("invalid call: decode_argument(arg, %d, ...)", type) @@ -518,24 +520,26 @@ static void decode_argument(char *arg, ArgType type, const uint8_t *bytes) /* Return the appropriate argument table for the given instruction. - This function also increments the instruction bytes array to skip any - prefix bits, so bytes[0] will always be the instruction. + This function also adds the number of instruction bytes to skip to its + shift argument (corresponding to any prefix bits), so bytes[*shift] will + always be the instruction opcode. This function return type is ridiculous, but it returns a pointer to an array of 3 arrays of 256 ArgTypes. */ -static inline ArgType (*get_table_and_adjust(const uint8_t **bytes))[3][256] +static inline ArgType (*get_table_and_shift( + const uint8_t *bytes, size_t *shift))[3][256] { - uint8_t b = (*bytes)[0]; + uint8_t b = bytes[0]; if (b == 0xED) - return (*bytes)++, &instr_args_extended; + return (*shift)++, &instr_args_extended; if (b == 0xCB) - return (*bytes)++, &instr_args_bits; + return (*shift)++, &instr_args_bits; if (b == 0xDD || b == 0xFD) { - if ((*bytes)[1] == 0xCB) - return (*bytes) += 2, &instr_args_index_bits; - return (*bytes)++, &instr_args_index; + if (bytes[1] == 0xCB) + return (*shift) += 2, &instr_args_index_bits; + return (*shift)++, &instr_args_index; } return &instr_args; } @@ -549,12 +553,12 @@ char* decode_arguments(const uint8_t *bytes) { char args[3][MAX_ARG_SIZE], *result; ArgType (*table)[3][256], type; - size_t i, len; + size_t shift = 0, i, len; - table = get_table_and_adjust(&bytes); + table = get_table_and_shift(bytes, &shift); for (i = 0; i < 3; i++) { - type = (*table)[i][bytes[0]]; - decode_argument(args[i], type, bytes); + type = (*table)[i][bytes[shift]]; + decode_argument(args[i], type, bytes, shift); } if (!*args[0]) diff --git a/src/z80.c b/src/z80.c index 2fed89f..1e054da 100644 --- a/src/z80.c +++ b/src/z80.c @@ -225,8 +225,12 @@ static inline void trace_instruction(Z80 *z80) TRACE_NOEOL("repeat last: %llu times\r", z80->trace.counter); return; } - if (z80->trace.fresh) + if (z80->trace.fresh) { + TRACE("PC ADDR RAW INSTR\tARGS") + TRACE("------- --- -----\t----") z80->trace.fresh = false; + } + z80->trace.last_addr = z80->regfile.pc; z80->trace.counter = 0;