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.
*/
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])


+ 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);
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;



Loading…
Cancel
Save