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