Beispiel #1
0
int disasm_6800(struct _memory *memory, uint32_t address, char *instruction, int *cycles_min, int *cycles_max)
{
  int opcode;
  int size = 1;

  *cycles_min = -1;
  *cycles_max = -1;

  opcode = READ_RAM(address);

  switch(table_6800[opcode].operand_type)
  {
    case M6800_OP_UNDEF:
      strcpy(instruction, "???");
      break;
    case M6800_OP_NONE:
      strcpy(instruction, table_6800[opcode].instr);
      break;
    case M6800_OP_IMM8:
      sprintf(instruction, "%s #$%02x", table_6800[opcode].instr, READ_RAM(address+1));
      size = 2;
      break;
    case M6800_OP_IMM16:
      sprintf(instruction, "%s #$%04x", table_6800[opcode].instr, READ_RAM16(address + 1));
      size = 3;
      break;
    case M6800_OP_DIR_PAGE_8:
      sprintf(instruction, "%s $%02x", table_6800[opcode].instr, READ_RAM(address + 1));
      size = 2;
      break;
    case M6800_OP_ABSOLUTE_16:
      sprintf(instruction, "%s $%04x", table_6800[opcode].instr, READ_RAM16(address + 1));
      size = 3;
      break;
    case M6800_OP_NN_X:
      sprintf(instruction, "%s $%04x,X (%d)", table_6800[opcode].instr, (address + 2)+(char)(READ_RAM(address + 1)), (char)(READ_RAM(address + 1)));
      size = 2;
      break;
    case M6800_OP_REL_OFFSET:
      sprintf(instruction, "%s $%04x,X  (%d)", table_6800[opcode].instr, (address + 2)+(char)(READ_RAM(address + 1)), (char)READ_RAM(address + 1));
      size=2;
      break;
  }

  return size;
}
Beispiel #2
0
int disasm_6809(struct _memory *memory, uint32_t address, char *instruction, int *cycles_min, int *cycles_max)
{
  int opcode;
  int n;

  *cycles_min = -1;
  *cycles_max = -1;

  opcode = READ_RAM(address);

  if (opcode == 0x10 || opcode == 0x11)
  {
    opcode = READ_RAM16(address);

    n = 0;
    while(table_6809_16[n].instr != NULL)
    {
      if (table_6809_16[n].opcode == opcode)
      {
        strcpy(instruction, table_6809_16[n].instr);
        *cycles_min = table_6809_16[n].cycles_min;
        *cycles_max = table_6809_16[n].cycles_min;

        switch(table_6809_16[n].operand_type)
        {
          case M6809_OP_INHERENT:
          {
            return 2;
          }
          case M6809_OP_IMMEDIATE:
          {
            if (table_6809_16[n].bytes == 4)
            {
              sprintf(instruction, "%s #0x%02x", table_6809_16[n].instr, READ_RAM16(address + 2));
              return 4;
            }

            break;
          }
          case M6809_OP_EXTENDED:
          {
            if (table_6809_16[n].bytes == 4)
            {
              sprintf(instruction, "%s 0x%04x", table_6809_16[n].instr, READ_RAM16(address + 2));
              return 4;
            }

            break;
          }
          case M6809_OP_RELATIVE:
          {
            if (table_6809_16[n].bytes == 4)
            {
              int16_t offset = READ_RAM16(address + 2);

              sprintf(instruction, "%s 0x%04x (%d)", table_6809_16[n].instr, (address + 4 + offset) & 0xffff, offset);
              return 4;
            }

            break;
          }
          case M6809_OP_DIRECT:
          {
            if (table_6809_16[n].bytes == 3)
            {
              sprintf(instruction, "%s >0x%02x", table_6809_16[n].instr, READ_RAM(address + 2));
              return 3;
            }

            break;
          }
          case M6809_OP_INDEXED:
          {
            return get_indexed(memory, &table_6809_16[n], instruction, address + 2, cycles_min, cycles_max) + 3;

            break;
          }
          default:
          {
            //print_error_internal(asm_context, __FILE__, __LINE__);
            break;
          }
        }
      }

      n++;
    }
  }
  else
  {
    n = 0;
    while(table_6809[n].instr != NULL)
    {
      if (table_6809[n].opcode == opcode)
      {
        *cycles_min = table_6809[n].cycles_min;
        *cycles_max = table_6809[n].cycles_min;

        switch(table_6809[n].operand_type)
        {
          case M6809_OP_INHERENT:
          {
            strcpy(instruction, table_6809[n].instr);
            return 1;
          }
          case M6809_OP_IMMEDIATE:
          {
            if (table_6809[n].bytes == 2)
            {
              sprintf(instruction, "%s #0x%02x", table_6809[n].instr, READ_RAM(address + 1));
              return 2;
            }
              else
            if (table_6809[n].bytes == 3)
            {
              sprintf(instruction, "%s #0x%02x", table_6809[n].instr, READ_RAM16(address + 1));
              return 3;
            }

            break;
          }
          case M6809_OP_EXTENDED:
          {
            if (table_6809[n].bytes == 3)
            {
              sprintf(instruction, "%s 0x%04x", table_6809[n].instr, READ_RAM16(address + 1));
              return 3;
            }

            break;
          }
          case M6809_OP_RELATIVE:
          {
            if (table_6809[n].bytes == 2)
            {
              int8_t offset = READ_RAM(address + 1);

              sprintf(instruction, "%s 0x%04x (%d)", table_6809[n].instr, (address + 2 + offset) & 0xffff, offset);
              return 2;
            }

            break;
          }
          case M6809_OP_LONG_RELATIVE:
          {
            if (table_6809[n].bytes == 3)
            {
              int16_t offset = (READ_RAM(address + 1) << 8) | READ_RAM(address + 2);

              sprintf(instruction, "%s 0x%04x (%d)", table_6809[n].instr, (address + 3 + offset) & 0xffff, offset);
              return 2;
            }

            break;
          }
          case M6809_OP_DIRECT:
          {
            if (table_6809[n].bytes == 2)
            {
              sprintf(instruction, "%s >0x%02x", table_6809[n].instr, READ_RAM(address + 1));
              return 2;
            }

            break;
          }
          case M6809_OP_STACK:
          {
            if (table_6809[n].bytes == 2)
            {
              uint8_t reg_list = READ_RAM(address + 1);
              const char *reg_names[] = { "pc","u","y","x","dp","b","a","cc" };
              uint8_t index = 0x80;
              uint8_t count = 0;

              sprintf(instruction, "%s", table_6809[n].instr);
              for (n = 0; n < 8; n++)
              {
                if ((reg_list & index) != 0)
                {
                  if (count != 0) { strcat(instruction, ", "); }
                  else { strcat(instruction, " "); }
                  strcat(instruction, reg_names[n]);
                  count++;
                  // Each byte pushed adds 1 cycle to cycle counts
                  if (n >= 4) { *cycles_min += 1; *cycles_max += 1; }
                  else { *cycles_min += 2; *cycles_max += 2; }
                }

                index >>= 1;
              }

              return 2;
            }
          }
          case M6809_OP_TWO_REG:
          {
            const char *reg_post_byte[] = {
              "d", "x", "y",  "u",  "s", "pc", "?", "?",
              "a", "b", "cc", "dp", "?", "?",  "?", "?"
            };
            uint8_t post_byte = READ_RAM(address + 1);

            const char *src = reg_post_byte[post_byte >> 4];
            const char *dst = reg_post_byte[post_byte & 0xf];

            sprintf(instruction, "%s %s, %s", table_6809[n].instr, src, dst);

            return 2;
          }
          case M6809_OP_INDEXED:
          {
            return get_indexed(memory, &table_6809[n], instruction, address + 1, cycles_min, cycles_max) + 2;

            break;
          }
          default:
          {
            //print_error_internal(asm_context, __FILE__, __LINE__);
            break;
          }
        }
      }

      n++;
    }
Beispiel #3
0
int get_indexed(struct _memory *memory, struct _table_6809 *table, char *instruction, uint32_t address, int *cycles_min, int *cycles_max)
{
  const char *name[] = { "x", "y", "u", "s" };
  uint8_t post_byte = READ_RAM(address);
  int reg = (post_byte >> 5) & 0x3;

  if ((post_byte & 0x9f) == 0x84)
  {
    // ,R non-indirect
    sprintf(instruction, "%s ,%s", table->instr, name[reg]);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x94)
  {
    // [,R] indirect
    sprintf(instruction, "%s [,%s]", table->instr, name[reg]);
    ADD_CYCLES(3);
    return 0;
  }
    else
  if ((post_byte & 0x80) == 0x00)
  {
    // 5 bit offset, R non-indirect
    int8_t offset = post_byte & 0x1f;
    if ((offset & 0x10) != 0) { offset |= 0xe0; }
    sprintf(instruction, "%s %d,%s", table->instr, offset, name[reg]);
    ADD_CYCLES(1);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x88)
  {
    // 8 bit offset, R non-indirect
    int8_t offset = READ_RAM(address + 1);
    sprintf(instruction, "%s %d,%s", table->instr, offset, name[reg]);
    ADD_CYCLES(1);
    return 1;
  }
    else
  if ((post_byte & 0x9f) == 0x98)
  {
    // [8 bit offset, R] indirect
    int8_t offset = READ_RAM(address + 1);
    sprintf(instruction, "%s [%d,%s]", table->instr, offset, name[reg]);
    ADD_CYCLES(4);
    return 1;
  }
    else
  if ((post_byte & 0x9f) == 0x89)
  {
    // 16 bit offset, R non-indirect
    int16_t offset = READ_RAM16(address + 1);
    sprintf(instruction, "%s %d,%s", table->instr, offset, name[reg]);
    ADD_CYCLES(4);
    return 2;
  }
    else
  if ((post_byte & 0x9f) == 0x99)
  {
    // [16 bit offset, R] indirect
    int16_t offset = READ_RAM16(address + 1);
    sprintf(instruction, "%s [%d,%s]", table->instr, offset, name[reg]);
    ADD_CYCLES(7);
    return 2;
  }
    else
  if ((post_byte & 0x9f) == 0x86)
  {
    // A,R non-indirect
    sprintf(instruction, "%s a,%s", table->instr, name[reg]);
    ADD_CYCLES(1);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x96)
  {
    // [A,R] non-indirect
    sprintf(instruction, "%s [a,%s]", table->instr, name[reg]);
    ADD_CYCLES(4);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x85)
  {
    // B,R non-indirect
    sprintf(instruction, "%s b,%s", table->instr, name[reg]);
    ADD_CYCLES(1);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x95)
  {
    // [B,R] indirect
    sprintf(instruction, "%s [b,%s]", table->instr, name[reg]);
    ADD_CYCLES(4);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x8b)
  {
    // D,R non-indirect
    sprintf(instruction, "%s d,%s", table->instr, name[reg]);
    ADD_CYCLES(4);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x9b)
  {
    // [D,R] non-indirect
    sprintf(instruction, "%s [d,%s]", table->instr, name[reg]);
    ADD_CYCLES(7);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x80)
  {
    // ,R+ non-indirect
    sprintf(instruction, "%s ,%s+", table->instr, name[reg]);
    ADD_CYCLES(2);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x81)
  {
    // ,R++ non-indirect
    sprintf(instruction, "%s ,%s++", table->instr, name[reg]);
    ADD_CYCLES(3);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x91)
  {
    // [,R++] indirect
    sprintf(instruction, "%s [,%s++]", table->instr, name[reg]);
    ADD_CYCLES(6);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x82)
  {
    // ,-R non-indirect
    sprintf(instruction, "%s ,-%s", table->instr, name[reg]);
    ADD_CYCLES(2);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x83)
  {
    // ,--R non-indirect
    sprintf(instruction, "%s ,--%s", table->instr, name[reg]);
    ADD_CYCLES(3);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x93)
  {
    // [,--R] indirect
    sprintf(instruction, "%s [,--%s]", table->instr, name[reg]);
    ADD_CYCLES(6);
    return 0;
  }
    else
  if ((post_byte & 0x9f) == 0x8c)
  {
    // 8 bit offset, PCR non-indirect
    int8_t offset = READ_RAM(address + 1);
    sprintf(instruction, "%s %d,pc", table->instr, offset);
    ADD_CYCLES(1);
    return 1;
  }
    else
  if ((post_byte & 0x9f) == 0x9c)
  {
    // [8 bit offset, PCR] indirect
    int8_t offset = READ_RAM(address + 1);
    sprintf(instruction, "%s [%d,pc]", table->instr, offset);
    ADD_CYCLES(4);
    return 1;
  }
    else
  if ((post_byte & 0x9f) == 0x8d)
  {
    // 16 bit offset, PCR non-indirect
    int16_t offset = READ_RAM16(address + 1);
    sprintf(instruction, "%s %d,pc", table->instr, offset);
    ADD_CYCLES(5);
    return 2;
  }
    else
  if ((post_byte & 0x9f) == 0x9d)
  {
    // [16 bit offset, PCR] non-indirect
    int16_t offset = READ_RAM16(address + 1);
    sprintf(instruction, "%s [%d,pc]", table->instr, offset);
    ADD_CYCLES(8);
    return 2;
  }
    else
  if ((post_byte & 0x9f) == 0x9f)
  {
    // [16 bit offset] non-indirect
    int16_t offset = READ_RAM16(address + 1);
    sprintf(instruction, "%s [0x%04x]", table->instr, offset);
    ADD_CYCLES(5);
    return 2;
  }

  strcpy(instruction, "???");

  return 0;
}
Beispiel #4
0
int disasm_68hc08(struct _memory *memory, int address, char *instruction, int *cycles_min, int *cycles_max)
{
//int bit_instr;
int opcode;
int size=1;
int n;

  strcpy(instruction, "???");

  *cycles_min=-1;
  *cycles_max=-1;

  opcode=READ_RAM(address);

  if (m68hc08_table[opcode].instr==NULL)
  {
    opcode=READ_RAM16(address);

    n=0;
    while(m68hc08_16_table[n].instr!=NULL)
    {
      if (m68hc08_16_table[n].opcode==opcode)
      {
        switch(m68hc08_16_table[n].operand_type)
        {
          case CPU08_OP_OPR8_SP:
            sprintf(instruction, "%s $%02x,SP", m68hc08_16_table[n].instr, READ_RAM(address+2));
            size=3;
            break;
          case CPU08_OP_OPR8_SP_REL:
            sprintf(instruction, "%s $%02x,SP,$%04x", m68hc08_16_table[n].instr, READ_RAM(address+2), (address+4)+((char)READ_RAM(address+3)));
            size=4;
            break;
          case CPU08_OP_OPR16_SP:
            sprintf(instruction, "%s $%04x,SP", m68hc08_16_table[n].instr, READ_RAM16(address+2));
            size=4;
            break;
        }

        *cycles_min=m68hc08_16_table[n].cycles;
        *cycles_max=m68hc08_16_table[n].cycles;

        break;
      }
      n++;
    }

    return size;
  }

  *cycles_min=m68hc08_table[opcode].cycles;
  *cycles_max=m68hc08_table[opcode].cycles;

  switch(m68hc08_table[opcode].operand_type)
  {
    case CPU08_OP_NONE:
      sprintf(instruction, "%s", m68hc08_table[opcode].instr);
      break;
    case CPU08_OP_NUM16:
      sprintf(instruction, "%s #$%04x", m68hc08_table[opcode].instr, READ_RAM16(address+1));
      size=3;
      break;
    case CPU08_OP_NUM8:
      sprintf(instruction, "%s #$%02x", m68hc08_table[opcode].instr, READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_NUM8_OPR8:
      sprintf(instruction, "%s #$%02x,$%02x", m68hc08_table[opcode].instr, READ_RAM(address+1), READ_RAM(address+2));
      size=3;
      break;
    case CPU08_OP_NUM8_REL:
      sprintf(instruction, "%s #$%02x, $%04x (%d)", m68hc08_table[opcode].instr, READ_RAM(address+1), (address+3)+((char)READ_RAM(address+2)), (char)READ_RAM(address+2));
      size=3;
      break;
    case CPU08_OP_OPR16:
      sprintf(instruction, "%s $%04x", m68hc08_table[opcode].instr, READ_RAM16(address+1));
      size=3;
      break;
    case CPU08_OP_OPR16_X:
      sprintf(instruction, "%s $%04x,X", m68hc08_table[opcode].instr, READ_RAM16(address+1));
      size=3;
      break;
    case CPU08_OP_OPR8:
      sprintf(instruction, "%s $%02x", m68hc08_table[opcode].instr, READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_OPR8_OPR8:
      sprintf(instruction, "%s $%02x,$%02x", m68hc08_table[opcode].instr, READ_RAM(address+1), READ_RAM(address+2));
      size=3;
      break;
    case CPU08_OP_OPR8_REL:
      sprintf(instruction, "%s $%02x,$%04x (%d)", m68hc08_table[opcode].instr, READ_RAM(address+1), ((address+3)+(char)READ_RAM(address+2)), (char)READ_RAM(address+2));
      size=3;
      break;
    case CPU08_OP_OPR8_X:
      sprintf(instruction, "%s %02x,X", m68hc08_table[opcode].instr, READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_OPR8_X_PLUS:
      sprintf(instruction, "%s $%02x,X+", m68hc08_table[opcode].instr, READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_OPR8_X_PLUS_REL:
      sprintf(instruction, "%s $%02x,X+,$%04x (%d)", m68hc08_table[opcode].instr, READ_RAM(address+1), (address+3)+((char)READ_RAM(address+2)), (char)READ_RAM(address+2));
      size=3;
      break;
    case CPU08_OP_OPR8_X_REL:
      sprintf(instruction, "%s $%02x,X,$%04x (%d)", m68hc08_table[opcode].instr, READ_RAM(address+1), (address+3)+((char)READ_RAM(address+2)), (char)READ_RAM(address+2));
      size=3;
      break;
    case CPU08_OP_REL:
      sprintf(instruction, "%s $%04x (%d)", m68hc08_table[opcode].instr, (address+2)+((char)READ_RAM(address+1)), (char)READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_COMMA_X:
      sprintf(instruction, "%s ,X", m68hc08_table[opcode].instr);
      break;
    case CPU08_OP_X:
      sprintf(instruction, "%s X", m68hc08_table[opcode].instr);
      break;
    case CPU08_OP_X_PLUS_OPR8:
      sprintf(instruction, "%s ,X+,$%02x", m68hc08_table[opcode].instr, READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_X_PLUS_REL:
      sprintf(instruction, "%s ,X+,$%04x (%d)", m68hc08_table[opcode].instr, (address+2)+((char)READ_RAM(address+1)), (char)READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_X_REL:
      sprintf(instruction, "%s ,X,$%04x (%d)", m68hc08_table[opcode].instr, (address+2)+((char)READ_RAM(address+1)), (char)READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_0_COMMA_OPR:
    case CPU08_OP_1_COMMA_OPR:
    case CPU08_OP_2_COMMA_OPR:
    case CPU08_OP_3_COMMA_OPR:
    case CPU08_OP_4_COMMA_OPR:
    case CPU08_OP_5_COMMA_OPR:
    case CPU08_OP_6_COMMA_OPR:
    case CPU08_OP_7_COMMA_OPR:
      sprintf(instruction, "%s %d,$%02x", m68hc08_table[opcode].instr, m68hc08_table[opcode].operand_type-CPU08_OP_0_COMMA_OPR, READ_RAM(address+1));
      size=2;
      break;
    case CPU08_OP_0_COMMA_OPR_REL:
    case CPU08_OP_1_COMMA_OPR_REL:
    case CPU08_OP_2_COMMA_OPR_REL:
    case CPU08_OP_3_COMMA_OPR_REL:
    case CPU08_OP_4_COMMA_OPR_REL:
    case CPU08_OP_5_COMMA_OPR_REL:
    case CPU08_OP_6_COMMA_OPR_REL:
    case CPU08_OP_7_COMMA_OPR_REL:
      sprintf(instruction, "%s %d,$%02x,$%04x (%d)", m68hc08_table[opcode].instr, m68hc08_table[opcode].operand_type-CPU08_OP_0_COMMA_OPR_REL, READ_RAM(address+1), (address+3)+(char)READ_RAM(address+2), (char)READ_RAM(address+2));
      size=3;
      break;
  }

  return size;
}