Browse Source

Finish argument immediate decoding.

master
Ben Kurtovic 8 years ago
parent
commit
43e641fabd
2 changed files with 54 additions and 46 deletions
  1. +49
    -45
      src/disassembler/arguments.c
  2. +5
    -1
      src/z80.c

+ 49
- 45
src/disassembler/arguments.c View File

@@ -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. 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; char *format;
size_t take;
uint8_t b = bytes[shift];


switch (type) { 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; 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; 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; break;
case AT_IMM_BIT:
// TODO: bit ...
strcpy(arg, "???");
case AT_IMM_BIT: // Bit position
sprintf(arg, "%d", (b & 0x38) >> 3);
break; break;
case AT_IMM_RST:
// TODO: reset ...
strcpy(arg, "???");
case AT_IMM_RST: // Reset
sprintf(arg, "$%02X", b & 0x38);
break; 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; 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; break;
case AT_IX_IY:
case AT_IX_IY: // Indexed offset
format = bytes[0] == 0xDD ? "(ix%+hhd)" : "(iy%+hhd)"; format = bytes[0] == 0xDD ? "(ix%+hhd)" : "(iy%+hhd)";
sprintf(arg, format, (int8_t) bytes[1]);
sprintf(arg, format, (int8_t) bytes[shift + 1]);
break; break;
case AT_PORT_IM:
sprintf(arg, "(%u)", bytes[1]);
case AT_PORT_IM: // Immediate port
sprintf(arg, "(%u)", bytes[shift + 1]);
break; break;
default: default:
FATAL("invalid call: decode_immediate(arg, %d, ...)", type) 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. 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; 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_IDR_IMM:
case AT_IX_IY: case AT_IX_IY:
case AT_PORT_IM: case AT_PORT_IM:
decode_immediate(arg, type, bytes);
decode_immediate(arg, type, bytes, shift);
return; return;
default: default:
FATAL("invalid call: decode_argument(arg, %d, ...)", type) 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. 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 This function return type is ridiculous, but it returns a pointer to an
array of 3 arrays of 256 ArgTypes. 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) if (b == 0xED)
return (*bytes)++, &instr_args_extended;
return (*shift)++, &instr_args_extended;
if (b == 0xCB) if (b == 0xCB)
return (*bytes)++, &instr_args_bits;
return (*shift)++, &instr_args_bits;
if (b == 0xDD || b == 0xFD) { 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; return &instr_args;
} }
@@ -549,12 +553,12 @@ char* decode_arguments(const uint8_t *bytes)
{ {
char args[3][MAX_ARG_SIZE], *result; char args[3][MAX_ARG_SIZE], *result;
ArgType (*table)[3][256], type; 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++) { 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]) if (!*args[0])


+ 5
- 1
src/z80.c View File

@@ -225,8 +225,12 @@ static inline void trace_instruction(Z80 *z80)
TRACE_NOEOL("repeat last: %llu times\r", z80->trace.counter); TRACE_NOEOL("repeat last: %llu times\r", z80->trace.counter);
return; return;
} }
if (z80->trace.fresh)
if (z80->trace.fresh) {
TRACE("PC ADDR RAW INSTR\tARGS")
TRACE("------- --- -----\t----")
z80->trace.fresh = false; z80->trace.fresh = false;
}

z80->trace.last_addr = z80->regfile.pc; z80->trace.last_addr = z80->regfile.pc;
z80->trace.counter = 0; z80->trace.counter = 0;




Loading…
Cancel
Save