/***************************************************************************** * Disassemble a single command and return the number of bytes it uses. *****************************************************************************/ offs_t tms9900_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int OP, OP2, opc; int sarg, darg, smode, dmode; signed char displacement; int byte_count, checkpoint; int bit_position, bit_width; unsigned dasmflags = 0; const char *mnemonic; format_t format; int flags; /* Under tms9900, opcodes >0400->07FF are incompletely decoded: bits 11 is ignored, and so are bits 12-15 for instructions which do not require a register. On the other hand, ti990/10 generates an illegal instruction error when bit 11 is set, but still ignores bits 12-15. Additionally, ti990/12 and tms9995 will generate an illegal error when bits 12-15 are non-zero. */ #define BETTER_0200_DECODING (m_model_id == TI990_10_ID) #define COMPLETE_0200_DECODING (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS9995_ID)) int processor_mask = ps_any; if ((m_model_id == TI990_10_ID) /*|| (m_model_id == TI990_12_ID)*/ || (m_model_id >= TMS99000_ID)) processor_mask |= ps_mapper; /* processors with memory mapper (ti990/10, ti990/12, and tms99000 with mapper coprocessor) */ if (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS9995_ID)) processor_mask |= ps_tms9995; /* ti990/12, tms9995, and later */ if (/*(m_model_id == TI990_12_ID) ||*/ (m_model_id >= TMS99000_ID)) processor_mask |= ps_tms99000; /* ti990/12, tms99000, and later */ /*if ((m_model_id == TI990_12_ID)) processor_mask |= ps_ti990_12;*/ /* ti990/12, tms99000, and later */ offs_t PC = pc; OP = opcodes.r16(PC); PC += 2; /* let's identify the opcode */ if (OP >= 0x4000) opc = ops_4000_ffff_s12[(OP - 0x4000) >> 12]; else if (OP >= 0x2000)
inline uint16_t tms9900_disassembler::readop_arg(const data_buffer ¶ms, offs_t &PC) { uint16_t result = params.r16(PC); PC += 2;; return result; }
offs_t e0c6200_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { u16 op = opcodes.r16(pc) & 0xfff; int m; int p1 = -1; int p2 = -1; // determine id for mnemonic and param(s) switch (op & 0xf00) { // JP s case 0x000: m = em_JP; p1 = ep_S; break; // RETD e case 0x100: m = em_RETD; p1 = ep_E; break; // JP C,s case 0x200: m = em_JP; p1 = ep_cC; p2 = ep_S; break; // JP NC,s case 0x300: m = em_JP; p1 = ep_cNC; p2 = ep_S; break; // CALL s case 0x400: m = em_CALL; p1 = ep_S; break; // CALZ s case 0x500: m = em_CALZ; p1 = ep_S; break; // JP Z,s case 0x600: m = em_JP; p1 = ep_cZ; p2 = ep_S; break; // JP NZ,s case 0x700: m = em_JP; p1 = ep_cNZ; p2 = ep_S; break; // LD Y,e case 0x800: m = em_LD; p1 = ep_Y; p2 = ep_E; break; // LBPX MX,e case 0x900: m = em_LBPX; p1 = ep_MX; p2 = ep_E; break; // LD X,e case 0xb00: m = em_LD; p1 = ep_X; p2 = ep_E; break; default: switch (op) { // RLC r case 0xaf0: case 0xaf5: case 0xafa: case 0xaff: m = em_RLC; p1 = ep_R0; break; // NOT r case 0xd0f: case 0xd1f: case 0xd2f: case 0xd3f: m = em_NOT; p1 = ep_R4; break; // LD XP,r case 0xe80: case 0xe81: case 0xe82: case 0xe83: m = em_LD; p1 = ep_XP; p2 = ep_R0; break; // LD XH,r case 0xe84: case 0xe85: case 0xe86: case 0xe87: m = em_LD; p1 = ep_XH; p2 = ep_R0; break; // LD XL,r case 0xe88: case 0xe89: case 0xe8a: case 0xe8b: m = em_LD; p1 = ep_XL; p2 = ep_R0; break; // RRC r case 0xe8c: case 0xe8d: case 0xe8e: case 0xe8f: m = em_RRC; p1 = ep_R0; break; // LD YP,r case 0xe90: case 0xe91: case 0xe92: case 0xe93: m = em_LD; p1 = ep_YP; p2 = ep_R0; break; // LD YH,r case 0xe94: case 0xe95: case 0xe96: case 0xe97: m = em_LD; p1 = ep_YH; p2 = ep_R0; break; // LD YL,r case 0xe98: case 0xe99: case 0xe9a: case 0xe9b: m = em_LD; p1 = ep_YL; p2 = ep_R0; break; // LD r,XP case 0xea0: case 0xea1: case 0xea2: case 0xea3: m = em_LD; p1 = ep_R0; p2 = ep_XP; break; // LD r,XH case 0xea4: case 0xea5: case 0xea6: case 0xea7: m = em_LD; p1 = ep_R0; p2 = ep_XH; break; // LD r,XL case 0xea8: case 0xea9: case 0xeaa: case 0xeab: m = em_LD; p1 = ep_R0; p2 = ep_XL; break; // LD r,YP case 0xeb0: case 0xeb1: case 0xeb2: case 0xeb3: m = em_LD; p1 = ep_R0; p2 = ep_YP; break; // LD r,YH case 0xeb4: case 0xeb5: case 0xeb6: case 0xeb7: m = em_LD; p1 = ep_R0; p2 = ep_YH; break; // LD r,YL case 0xeb8: case 0xeb9: case 0xeba: case 0xebb: m = em_LD; p1 = ep_R0; p2 = ep_YL; break; // INC X case 0xee0: m = em_INC; p1 = ep_X; break; // INC Y case 0xef0: m = em_INC; p1 = ep_Y; break; // ACPX MX,r case 0xf28: case 0xf29: case 0xf2a: case 0xf2b: m = em_ACPX; p1 = ep_MX; p2 = ep_R0; break; // ACPY MY,r case 0xf2c: case 0xf2d: case 0xf2e: case 0xf2f: m = em_ACPY; p1 = ep_MY; p2 = ep_R0; break; // SCPX MX,r case 0xf38: case 0xf39: case 0xf3a: case 0xf3b: m = em_SCPX; p1 = ep_MX; p2 = ep_R0; break; // SCPY MY,r case 0xf3c: case 0xf3d: case 0xf3e: case 0xf3f: m = em_SCPY; p1 = ep_MY; p2 = ep_R0; break; // SCF case 0xf41: m = em_SCF; break; // SZF case 0xf42: m = em_SZF; break; // SDF case 0xf44: m = em_SDF; break; // EI case 0xf48: m = em_EI; break; // DI case 0xf57: m = em_DI; break; // RDF case 0xf5b: m = em_RDF; break; // RZF case 0xf5d: m = em_RZF; break; // RCF case 0xf5e: m = em_RCF; break; // PUSH r case 0xfc0: case 0xfc1: case 0xfc2: case 0xfc3: m = em_PUSH; p1 = ep_R0; break; // PUSH XP case 0xfc4: m = em_PUSH; p1 = ep_XP; break; // PUSH XH case 0xfc5: m = em_PUSH; p1 = ep_XH; break; // PUSH XL case 0xfc6: m = em_PUSH; p1 = ep_XL; break; // PUSH YP case 0xfc7: m = em_PUSH; p1 = ep_YP; break; // PUSH YH case 0xfc8: m = em_PUSH; p1 = ep_YH; break; // PUSH YL case 0xfc9: m = em_PUSH; p1 = ep_YL; break; // PUSH F case 0xfca: m = em_PUSH; p1 = ep_F; break; // DEC SP case 0xfcb: m = em_DEC; p1 = ep_SP; break; // POP r case 0xfd0: case 0xfd1: case 0xfd2: case 0xfd3: m = em_POP; p1 = ep_R0; break; // POP XP case 0xfd4: m = em_POP; p1 = ep_XP; break; // POP XH case 0xfd5: m = em_POP; p1 = ep_XH; break; // POP XL case 0xfd6: m = em_POP; p1 = ep_XL; break; // POP YP case 0xfd7: m = em_POP; p1 = ep_YP; break; // POP YH case 0xfd8: m = em_POP; p1 = ep_YH; break; // POP YL case 0xfd9: m = em_POP; p1 = ep_YL; break; // POP F case 0xfda: m = em_POP; p1 = ep_F; break; // INC SP case 0xfdb: m = em_INC; p1 = ep_SP; break; // RETS case 0xfde: m = em_RETS; break; // RET case 0xfdf: m = em_RET; break; // LD SPH,r case 0xfe0: case 0xfe1: case 0xfe2: case 0xfe3: m = em_LD; p1 = ep_SPH; p2 = ep_R0; break; // LD r,SPH case 0xfe4: case 0xfe5: case 0xfe6: case 0xfe7: m = em_LD; p1 = ep_R0; p2 = ep_SPH; break; // JPBA case 0xfe8: m = em_JPBA; break; // LD SPL,r case 0xff0: case 0xff1: case 0xff2: case 0xff3: m = em_LD; p1 = ep_SPL; p2 = ep_R0; break; // LD r,SPL case 0xff4: case 0xff5: case 0xff6: case 0xff7: m = em_LD; p1 = ep_R0; p2 = ep_SPL; break; // HALT case 0xff8: m = em_HALT; break; // SLP case 0xff9: m = em_SLP; break; // NOP5 case 0xffb: m = em_NOP5; break; // NOP7 case 0xfff: m = em_NOP7; break; default: switch (op & 0xff0) { // ADC XH,i case 0xa00: m = em_ADC; p1 = ep_XH; p2 = ep_I; break; // ADC XL,i case 0xa10: m = em_ADC; p1 = ep_XL; p2 = ep_I; break; // ADC YH,i case 0xa20: m = em_ADC; p1 = ep_YH; p2 = ep_I; break; // ADC YL,i case 0xa30: m = em_ADC; p1 = ep_YL; p2 = ep_I; break; // CP XH,i case 0xa40: m = em_CP; p1 = ep_XH; p2 = ep_I; break; // CP XL,i case 0xa50: m = em_CP; p1 = ep_XL; p2 = ep_I; break; // CP YH,i case 0xa60: m = em_CP; p1 = ep_YH; p2 = ep_I; break; // CP YL,i case 0xa70: m = em_CP; p1 = ep_YL; p2 = ep_I; break; // ADD r,q case 0xa80: m = em_ADD; p1 = ep_R2; p2 = ep_Q; break; // ADC r,q case 0xa90: m = em_ADC; p1 = ep_R2; p2 = ep_Q; break; // SUB r,q case 0xaa0: m = em_SUB; p1 = ep_R2; p2 = ep_Q; break; // SBC r,q case 0xab0: m = em_SBC; p1 = ep_R2; p2 = ep_Q; break; // AND r,q case 0xac0: m = em_AND; p1 = ep_R2; p2 = ep_Q; break; // OR r,q case 0xad0: m = em_OR; p1 = ep_R2; p2 = ep_Q; break; // XOR r,q case 0xae0: m = em_XOR; p1 = ep_R2; p2 = ep_Q; break; // ADD r,i case 0xc00: case 0xc10: case 0xc20: case 0xc30: m = em_ADD; p1 = ep_R4; p2 = ep_I; break; // ADC r,i case 0xc40: case 0xc50: case 0xc60: case 0xc70: m = em_ADC; p1 = ep_R4; p2 = ep_I; break; // AND r,i case 0xc80: case 0xc90: case 0xca0: case 0xcb0: m = em_AND; p1 = ep_R4; p2 = ep_I; break; // OR r,i case 0xcc0: case 0xcd0: case 0xce0: case 0xcf0: m = em_OR; p1 = ep_R4; p2 = ep_I; break; // XOR r,i case 0xd00: case 0xd10: case 0xd20: case 0xd30: m = em_XOR; p1 = ep_R4; p2 = ep_I; break; // SBC r,i case 0xd40: case 0xd50: case 0xd60: case 0xd70: m = em_SBC; p1 = ep_R4; p2 = ep_I; break; // FAN r,i case 0xd80: case 0xd90: case 0xda0: case 0xdb0: m = em_FAN; p1 = ep_R4; p2 = ep_I; break; // CP r,i case 0xdc0: case 0xdd0: case 0xde0: case 0xdf0: m = em_CP; p1 = ep_R4; p2 = ep_I; break; // LD r,i case 0xe00: case 0xe10: case 0xe20: case 0xe30: m = em_LD; p1 = ep_R4; p2 = ep_I; break; // PSET p case 0xe40: case 0xe50: m = em_PSET; p1 = ep_P; break; // LDPX MX,i case 0xe60: m = em_LDPX; p1 = ep_MX; p2 = ep_I; break; // LDPY MY,i case 0xe70: m = em_LDPY; p1 = ep_MY; p2 = ep_I; break; // LD r,q case 0xec0: m = em_LD; p1 = ep_R2; p2 = ep_Q; break; // LDPX r,q case 0xee0: m = em_LDPX; p1 = ep_R2; p2 = ep_Q; break; // LDPY r,q case 0xef0: m = em_LDPY; p1 = ep_R2; p2 = ep_Q; break; // CP r,q case 0xf00: m = em_CP; p1 = ep_R2; p2 = ep_Q; break; // FAN r,q case 0xf10: m = em_FAN; p1 = ep_R2; p2 = ep_Q; break; // SET F,i case 0xf40: m = em_SET; p1 = ep_F; p2 = ep_I; break; // RST F,i case 0xf50: m = em_RST; p1 = ep_F; p2 = ep_I; break; // INC Mn case 0xf60: m = em_INC; p1 = ep_MN; break; // DEC Mn case 0xf70: m = em_DEC; p1 = ep_MN; break; // LD Mn,A case 0xf80: m = em_LD; p1 = ep_MN; p2 = ep_A; break; // LD Mn,B case 0xf90: m = em_LD; p1 = ep_MN; p2 = ep_B; break; // LD A,Mn case 0xfa0: m = em_LD; p1 = ep_A; p2 = ep_MN; break; // LD B,Mn case 0xfb0: m = em_LD; p1 = ep_B; p2 = ep_MN; break; // illegal opcode default: m = em_ILL; break; } // 0xff0 break; } // 0xfff break; } // 0xf00 (big switch) // fetch mnemonic util::stream_format(stream, "%-6s", em_name[m]); // fetch param(s) if (p1 != -1) { util::stream_format(stream, "%s", decode_param(op, p1)); if (p2 != -1) { util::stream_format(stream, ",%s", decode_param(op, p2)); } } return 1 | em_flags[m] | SUPPORTED; }
void capricorn_disassembler::direct_addr(std::ostream &stream, offs_t pc, const data_buffer &opcodes) { util::stream_format(stream, "$%04x", opcodes.r16(pc)); }
offs_t v810_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { uint32_t flags = 0; uint32_t opc,opc2; unsigned size; opc = opcodes.r16(pc); opc2 = opcodes.r16(pc+2); switch(opc>>10) { case 0x00: util::stream_format(stream,"MOV %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x01: util::stream_format(stream,"ADD %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x02: util::stream_format(stream,"SUB %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x03: util::stream_format(stream,"CMP %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x04: util::stream_format(stream,"SHL %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x05: util::stream_format(stream,"SHR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x06: util::stream_format(stream,"JMP [%s]",GET1s(opc)); size=2; if ((opc&0x1f) == 31) flags = STEP_OUT; break; case 0x07: util::stream_format(stream,"SAR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x08: util::stream_format(stream,"MUL %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x09: util::stream_format(stream,"DIV %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x0a: util::stream_format(stream,"MULU %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x0b: util::stream_format(stream,"DIVU %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x0c: util::stream_format(stream,"OR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x0d: util::stream_format(stream,"AND %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x0e: util::stream_format(stream,"XOR %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x0f: util::stream_format(stream,"NOT %s,%s",GET1s(opc),GET2s(opc)); size=2; break; case 0x10: util::stream_format(stream,"MOV %X,%s",I5(opc),GET2s(opc)); size=2; break; case 0x11: util::stream_format(stream,"ADD %X,%s",I5(opc),GET2s(opc)); size=2; break; case 0x12: util::stream_format(stream,"SETF %X,%s",I5(opc),GET2s(opc)); size=2; break; case 0x13: util::stream_format(stream,"CMP %X,%s",I5(opc),GET2s(opc)); size=2; break; case 0x14: util::stream_format(stream,"SHL %X,%s",UI5(opc),GET2s(opc)); size=2; break; case 0x15: util::stream_format(stream,"SHR %X,%s",UI5(opc),GET2s(opc)); size=2; break; case 0x16: util::stream_format(stream,"EI"); size=2; break; case 0x17: util::stream_format(stream,"SAR %X,%s",UI5(opc),GET2s(opc)); size=2; break; case 0x18: util::stream_format(stream,"TRAP %X",I5(opc)); size=2; break; case 0x19: util::stream_format(stream,"RETI"); size=2; flags = STEP_OUT; break; case 0x1a: util::stream_format(stream,"HALT"); size=2; break; case 0x1b: util::stream_format(stream,"Unk 0x1B"); size=2; break; case 0x1c: util::stream_format(stream,"LDSR %s,%s",GET2s(opc),GETRs(opc));size=2; break; case 0x1d: util::stream_format(stream,"STSR %s,%s",GETRs(opc),GET2s(opc));size=2; break; case 0x1e: util::stream_format(stream,"DI"); size=2; break; case 0x1f: switch(opc&0x1f) { case 0x00: util::stream_format(stream,"SCH0BSU"); break; case 0x01: util::stream_format(stream,"SCH0BSD"); break; case 0x02: util::stream_format(stream,"SCH1BSU"); break; case 0x03: util::stream_format(stream,"SCH1BSD"); break; case 0x04: util::stream_format(stream,"UnkS 4"); break; case 0x05: util::stream_format(stream,"UnkS 5"); break; case 0x06: util::stream_format(stream,"UnkS 6"); break; case 0x08: util::stream_format(stream,"ORBSU"); break; case 0x09: util::stream_format(stream,"ANDBSU"); break; case 0x0a: util::stream_format(stream,"XORBSU"); break; case 0x0b: util::stream_format(stream,"MOVBSU"); break; case 0x0c: util::stream_format(stream,"ORNBSU"); break; case 0x0d: util::stream_format(stream,"ANDNBSU"); break; case 0x0e: util::stream_format(stream,"XORNBSU"); break; case 0x0f: util::stream_format(stream,"NOTBSU"); break; default: util::stream_format(stream,"UnkBS 0x%X",opc&0x1f); break; } size=2; break; case 0x20: case 0x21: case 0x22: case 0x23: case 0x24: case 0x25: case 0x26: case 0x27: switch( (opc>>9) &0xf) { case 0x0: util::stream_format(stream,"BV %X",pc+D9(opc)); break; case 0x1: util::stream_format(stream,"BL %X",pc+D9(opc)); break; case 0x2: util::stream_format(stream,"BE %X",pc+D9(opc)); break; case 0x3: util::stream_format(stream,"BNH %X",pc+D9(opc)); break; case 0x4: util::stream_format(stream,"BN %X",pc+D9(opc)); break; case 0x5: util::stream_format(stream,"BR %X",pc+D9(opc)); break; case 0x6: util::stream_format(stream,"BLT %X",pc+D9(opc)); break; case 0x7: util::stream_format(stream,"BLE %X",pc+D9(opc)); break; case 0x8: util::stream_format(stream,"BNV %X",pc+D9(opc)); break; case 0x9: util::stream_format(stream,"BNL %X",pc+D9(opc)); break; case 0xa: util::stream_format(stream,"BNE %X",pc+D9(opc)); break; case 0xb: util::stream_format(stream,"BH %X",pc+D9(opc)); break; case 0xc: util::stream_format(stream,"BP %X",pc+D9(opc)); break; case 0xd: util::stream_format(stream,"NOP"); break; case 0xe: util::stream_format(stream,"BGE %X",pc+D9(opc)); break; case 0xf: util::stream_format(stream,"BGT %X",pc+D9(opc)); break; } size=2; break; case 0x28: util::stream_format(stream,"MOVEA %X, %s, %s",I16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x29: util::stream_format(stream,"ADDI %X, %s, %s",I16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2a: util::stream_format(stream,"JR %X",pc+D26(opc,opc2));size=4; break; case 0x2b: util::stream_format(stream,"JAL %X",pc+D26(opc,opc2));size=4; flags = STEP_OVER; break; case 0x2c: util::stream_format(stream,"ORI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2d: util::stream_format(stream,"ANDI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2e: util::stream_format(stream,"XORI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x2f: util::stream_format(stream,"MOVHI %X, %s, %s",UI16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x30: util::stream_format(stream,"LDB %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x31: util::stream_format(stream,"LDH %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x32: util::stream_format(stream,"Unk 0x32"); size=2; break; case 0x33: util::stream_format(stream,"LDW %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x34: util::stream_format(stream,"STB %s, %X[%s]",GET2s(opc),D16(opc2),GET1s(opc));size=4; break; case 0x35: util::stream_format(stream,"STH %s, %X[%s]",GET2s(opc),D16(opc2),GET1s(opc));size=4; break; case 0x36: util::stream_format(stream,"Unk 0x36"); size=2; break; case 0x37: util::stream_format(stream,"STW %s, %X[%s]",GET2s(opc),D16(opc2),GET1s(opc));size=4; break; case 0x38: util::stream_format(stream,"INB %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x39: util::stream_format(stream,"INH %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x3a: util::stream_format(stream,"CAXI %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x3b: util::stream_format(stream,"INW %X[%s], %s",D16(opc2),GET1s(opc),GET2s(opc));size=4; break; case 0x3c: util::stream_format(stream,"OUTB %s, %X[%s]",GET2s(opc),D16(opc2),GET1s(opc));size=4; break; case 0x3d: util::stream_format(stream,"OUTH %s, %X[%s]",GET2s(opc),D16(opc2),GET1s(opc));size=4; break; case 0x3e: switch((opc2&0xfc00)>>10) { case 0x0: util::stream_format(stream,"CMPF.S %s, %s",GET1s(opc),GET2s(opc)); break; case 0x2: util::stream_format(stream,"CVT.WS %s, %s",GET1s(opc),GET2s(opc)); break; case 0x3: util::stream_format(stream,"CVT.SW %s, %s",GET1s(opc),GET2s(opc)); break; case 0x4: util::stream_format(stream,"ADDF.S %s, %s",GET1s(opc),GET2s(opc)); break; case 0x5: util::stream_format(stream,"SUBF.S %s, %s",GET1s(opc),GET2s(opc)); break; case 0x6: util::stream_format(stream,"MULF.S %s, %s",GET1s(opc),GET2s(opc)); break; case 0x7: util::stream_format(stream,"DIVF.S %s, %s",GET1s(opc),GET2s(opc)); break; case 0xb: util::stream_format(stream,"TRNC.SW %s, %s",GET1s(opc),GET2s(opc)); break; default : util::stream_format(stream,"Unkf 0x%X",(opc2&0xfc00)>>10); break; } size=4; break; case 0x3f: util::stream_format(stream,"OUTW %s, %X[%s]",GET2s(opc),D16(opc2),GET1s(opc));size=4; break; default : size=2; } return size | flags | SUPPORTED; }
offs_t n8x300_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { unsigned startpc = pc; uint16_t opcode = opcodes.r16(pc); uint8_t inst = opcode >> 13; pc+=1; // determine instruction switch (inst) { case 0x00: stream << "MOVE " << reg_names[SRC]; if(is_rot(opcode)) util::stream_format(stream, "(%i),", ROTLEN); else util::stream_format(stream, ",%i,", ROTLEN); stream << reg_names[DST]; break; case 0x01: stream << "ADD " << reg_names[SRC]; if(is_rot(opcode)) util::stream_format(stream, "(%i),", ROTLEN); else util::stream_format(stream, ",%i,", ROTLEN); stream << reg_names[DST]; break; case 0x02: stream << "AND " << reg_names[SRC]; if(is_rot(opcode)) util::stream_format(stream, "(%i),", ROTLEN); else util::stream_format(stream, ",%i,", ROTLEN); stream << reg_names[DST]; break; case 0x03: stream << "XOR " << reg_names[SRC]; if(is_rot(opcode)) util::stream_format(stream, "(%i),", ROTLEN); else util::stream_format(stream, ",%i,", ROTLEN); stream << reg_names[DST]; break; case 0x04: stream << "XEC " << reg_names[SRC]; if(is_src_rot(opcode)) { util::stream_format(stream, ",%02XH", IMM8); } else { util::stream_format(stream, ",%i", ROTLEN); util::stream_format(stream, ",%02XH", IMM5); } break; case 0x05: stream << "NZT " << reg_names[SRC]; if(is_src_rot(opcode)) { util::stream_format(stream, ",%02XH", IMM8); } else { util::stream_format(stream, ",%i", ROTLEN); util::stream_format(stream, ",%02XH", IMM5); } break; case 0x06: stream << "XMIT "; if(is_src_rot(opcode)) { util::stream_format(stream, "%02XH,", IMM8); stream << reg_names[SRC]; } else { util::stream_format(stream, "%02XH,", IMM5); stream << reg_names[SRC]; util::stream_format(stream, ",%i", ROTLEN); } break; case 0x07: util::stream_format(stream, "JMP %04XH", (opcode & 0x1fff)); break; } return (pc - startpc); }
uint16_t tms34010_disassembler::r16(offs_t &pos, const data_buffer &opcodes) { uint16_t r = opcodes.r16(pos); pos += 16; return r; }
offs_t pic16c5x_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { int a, b, d, f, k; /* these can all be filled in by parsing an instruction */ int i; int op; int cnt = 1; int code; int bit; //char *buffertmp; const char *cp; /* character pointer in OpFormats */ uint32_t flags = 0; op = -1; /* no matching opcode */ code = opcodes.r16(pc); for ( i = 0; i < int(Op.size()); i++) { if ((code & Op[i].mask) == Op[i].bits) { if (op != -1) { osd_printf_debug("Error: opcode %04Xh matches %d (%s) and %d (%s)\n", code,i,Op[i].fmt,op,Op[op].fmt); } op = i; } } if (op == -1) { util::stream_format(stream, "???? dw %04Xh",code); return cnt | SUPPORTED; } //buffertmp = buffer; if (Op[op].extcode) /* Actually, theres no double length opcodes */ { bit = 27; code <<= 16; code |= params.r16(pc+cnt); cnt++; } else { bit = 11; } /* shift out operands */ cp = Op[op].parse; a = b = d = f = k = 0; while (bit >= 0) { /* osd_printf_debug("{%c/%d}",*cp,bit); */ switch (*cp) { case 'a': a <<=1; a |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'b': b <<=1; b |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'd': d <<=1; d |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'f': f <<=1; f |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case 'k': k <<=1; k |= ((code & (1<<bit)) ? 1 : 0); bit--; break; case ' ': break; case '1': case '0': bit--; break; case '\0': throw std::logic_error(util::string_format("premature end of parse string, opcode %x, bit = %d\n",code,bit)); } cp++; } /* now traverse format string */ cp = Op[op].fmt; if (!strncmp(cp, "call", 4)) flags = STEP_OVER; else if (!strncmp(cp, "ret", 3)) flags = STEP_OUT; while (*cp) { if (*cp == '%') { cp++; switch (*cp++) { case 'A': util::stream_format(stream, "$%03X", a); break; case 'B': util::stream_format(stream, "%d", b); break; case 'D': util::stream_format(stream, "%s", dest[d]); break; case 'F': util::stream_format(stream, "%s", regfile[f]); break; case 'K': util::stream_format(stream, "%02Xh", k); break; default: throw std::logic_error(util::string_format("illegal escape character in format '%s'\n",Op[op].fmt)); } } else { stream << *cp++; } } return cnt | flags | SUPPORTED; }
offs_t sh_disassembler::disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) { u16 opcode = opcodes.r16(pc); return dasm_one(stream, pc, opcode); }