static char *upper_address( UINT32 op, const UINT8 *opram ) { static char s_address[ 20 ]; UINT32 nextop = fetch_op( opram ); if( INS_OP( nextop ) == OP_ORI && INS_RT( op ) == INS_RS( nextop ) ) { sprintf( s_address, "$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) | INS_IMMEDIATE( nextop ) ); } else if( INS_OP( nextop ) == OP_ADDIU && INS_RT( op ) == INS_RS( nextop ) ) { sprintf( s_address, "$%04x ; 0x%08x", INS_IMMEDIATE( op ), ( INS_IMMEDIATE( op ) << 16 ) + (INT16) INS_IMMEDIATE( nextop ) ); } else { sprintf( s_address, "$%04x", INS_IMMEDIATE( op ) ); } return s_address; }
int mips_execute( int cycles ) { mips_ICount = cycles; do { THISOP = cpu_readop32(THISPC); THISPC += 4; switch( INS_OP( THISOP ) ) { case OP_SPECIAL: switch( INS_FUNCT( THISOP ) ) { case FUNCT_SLL: if( INS_RD( THISOP ) != 0 ) { RD = RT << SHAMT; } mips_advance_pc(); break; case FUNCT_SRL: if( INS_RD( THISOP ) != 0 ) { RD = RT >> SHAMT; } mips_advance_pc(); break; case FUNCT_SRA: if( INS_RD( THISOP ) != 0 ) { RD = (INT32) RT >> SHAMT; } mips_advance_pc(); break; case FUNCT_SLLV: if( INS_RD( THISOP ) != 0 ) { RD = RT << ( RS & 31 ); } mips_advance_pc(); break; case FUNCT_SRLV: if( INS_RD( THISOP ) != 0 ) { RD = RT >> ( RS & 31 ); } mips_advance_pc(); break; case FUNCT_SRAV: if( INS_RD( THISOP ) != 0 ) { RD = (INT32) RT >> ( RS & 31 ); }
unsigned DasmPSXCPU( psxcpu_state *state, char *buffer, UINT32 pc, const UINT8 *opram ) { UINT32 op; const UINT8 *oldopram; UINT32 flags = 0; oldopram = opram; op = fetch_op( opram ); opram += 4; sprintf( buffer, "dw $%08x", op ); switch( INS_OP( op ) ) { case OP_SPECIAL: switch( INS_FUNCT( op ) ) { case FUNCT_SLL: if( op == 0 ) { /* the standard nop is "sll zero,zero,$0000" */ sprintf( buffer, "nop" ); } else { sprintf( buffer, "sll %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) ); } break; case FUNCT_SRL: sprintf( buffer, "srl %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) ); break; case FUNCT_SRA: sprintf( buffer, "sra %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) ); break; case FUNCT_SLLV: sprintf( buffer, "sllv %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_SRLV: sprintf( buffer, "srlv %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_SRAV: sprintf( buffer, "srav %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_JR: sprintf( buffer, "jr %s", s_cpugenreg[ INS_RS( op ) ] ); if( INS_RS( op ) == 31 ) { flags = DASMFLAG_STEP_OUT; } break; case FUNCT_JALR: sprintf( buffer, "jalr %s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ] ); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); break; case FUNCT_SYSCALL: sprintf( buffer, "syscall $%05x", INS_CODE( op ) ); flags = DASMFLAG_STEP_OVER; break; case FUNCT_BREAK: sprintf( buffer, "break $%05x", INS_CODE( op ) ); flags = DASMFLAG_STEP_OVER; break; case FUNCT_MFHI: sprintf( buffer, "mfhi %s", s_cpugenreg[ INS_RD( op ) ] ); break; case FUNCT_MTHI: sprintf( buffer, "mthi %s", s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_MFLO: sprintf( buffer, "mflo %s", s_cpugenreg[ INS_RD( op ) ] ); break; case FUNCT_MTLO: sprintf( buffer, "mtlo %s", s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_MULT: sprintf( buffer, "mult %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_MULTU: sprintf( buffer, "multu %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_DIV: sprintf( buffer, "div %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_DIVU: sprintf( buffer, "divu %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_ADD: sprintf( buffer, "add %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_ADDU: sprintf( buffer, "addu %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SUB: sprintf( buffer, "sub %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SUBU: sprintf( buffer, "subu %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_AND: sprintf( buffer, "and %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_OR: sprintf( buffer, "or %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_XOR: sprintf( buffer, "xor %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_NOR: sprintf( buffer, "nor %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SLT: sprintf( buffer, "slt %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SLTU: sprintf( buffer, "sltu %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; } break; case OP_REGIMM: switch( INS_RT_REGIMM( op ) ) { case RT_BLTZ: if( INS_RT( op ) == RT_BLTZAL ) { sprintf( buffer, "bltzal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); } else { sprintf( buffer, "bltz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); } break; case RT_BGEZ: if( INS_RT( op ) == RT_BGEZAL ) { sprintf( buffer, "bgezal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); } else { sprintf( buffer, "bgez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], relative_address( state, pc, op ) ); } break; } break; case OP_J: sprintf( buffer, "j $%08x", jump_address( state, pc, op ) ); break; case OP_JAL: sprintf( buffer, "jal $%08x", jump_address( state, pc, op ) ); flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA( 1 ); break; case OP_BEQ: sprintf( buffer, "beq %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); break; case OP_BNE: sprintf( buffer, "bne %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); break; case OP_BLEZ: sprintf( buffer, "blez %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); break; case OP_BGTZ: sprintf( buffer, "bgtz %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], relative_address( state, pc, op ) ); break; case OP_ADDI: sprintf( buffer, "addi %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_ADDIU: sprintf( buffer, "addiu %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_SLTI: sprintf( buffer, "slti %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_SLTIU: sprintf( buffer, "sltiu %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_ANDI: sprintf( buffer, "andi %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_ORI: sprintf( buffer, "ori %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_XORI: sprintf( buffer, "xori %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_LUI: sprintf( buffer, "lui %s,%s", s_cpugenreg[ INS_RT( op ) ], upper_address( op, opram ) ); break; case OP_COP0: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc0 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp0genreg[ INS_RD( op ) ] ); break; case RS_CFC: sprintf( buffer, "!cfc0 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp0ctlreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc0 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp0genreg[ INS_RD( op ) ] ); break; case RS_CTC: sprintf( buffer, "!ctc0 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp0ctlreg[ INS_RD( op ) ] ); break; case RS_BC: case RS_BC_ALT: switch( INS_BC( op ) ) { case BC_BCF: sprintf( buffer, "bc0f $%08x", relative_address( state, pc, op ) ); break; case BC_BCT: sprintf( buffer, "bc0t $%08x", relative_address( state, pc, op ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop0 $%07x", INS_COFUN( op ) ); switch( INS_CF( op ) ) { case CF_TLBR: sprintf( buffer, "!tlbr" ); break; case CF_TLBWI: sprintf( buffer, "!tlbwi" ); break; case CF_TLBWR: sprintf( buffer, "!tlbwr" ); break; case CF_TLBP: sprintf( buffer, "!tlbp" ); break; case CF_RFE: sprintf( buffer, "rfe" ); break; } break; } break; } break; case OP_COP1: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1genreg[ INS_RD( op ) ] ); break; case RS_CFC: sprintf( buffer, "cfc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1ctlreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1genreg[ INS_RD( op ) ] ); break; case RS_CTC: sprintf( buffer, "ctc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1ctlreg[ INS_RD( op ) ] ); break; case RS_BC: case RS_BC_ALT: switch( INS_BC( op ) ) { case BC_BCF: sprintf( buffer, "bc1f $%08x", relative_address( state, pc, op ) ); break; case BC_BCT: sprintf( buffer, "bc1t $%08x", relative_address( state, pc, op ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop1 $%07x", INS_COFUN( op ) ); break; } break; } break; case OP_COP2: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2genreg[ INS_RD( op ) ] ); break; case RS_CFC: sprintf( buffer, "cfc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2ctlreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2genreg[ INS_RD( op ) ] ); break; case RS_CTC: sprintf( buffer, "ctc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2ctlreg[ INS_RD( op ) ] ); break; case RS_BC: case RS_BC_ALT: switch( INS_BC( op ) ) { case BC_BCF: sprintf( buffer, "bc2f $%08x", relative_address( state, pc, op ) ); break; case BC_BCT: sprintf( buffer, "bc2t $%08x", relative_address( state, pc, op ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop2 $%07x", INS_COFUN( op ) ); switch( GTE_FUNCT( op ) ) { case 0x00: // drop through to RTPS case 0x01: sprintf( buffer, "rtps%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x06: sprintf( buffer, "nclip" ); break; case 0x0c: sprintf( buffer, "op%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x10: sprintf( buffer, "dpcs%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x11: sprintf( buffer, "intpl%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x12: sprintf( buffer, "mvmva%s%s %s + %s * %s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ], s_gtecv[ GTE_CV( op ) ], s_gtemx[ GTE_MX( op ) ], s_gtev[ GTE_V( op ) ] ); break; case 0x13: sprintf( buffer, "ncds%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x14: sprintf( buffer, "cdp%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x16: sprintf( buffer, "ncdt%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x1b: sprintf( buffer, "nccs%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x1c: sprintf( buffer, "cc%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x1e: sprintf( buffer, "ncs%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x20: sprintf( buffer, "nct%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x28: sprintf( buffer, "sqr%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x1a: // end of NCDT case 0x29: sprintf( buffer, "dpcl%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x2a: sprintf( buffer, "dpct%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x2d: sprintf( buffer, "avsz3" ); break; case 0x2e: sprintf( buffer, "avsz4" ); break; case 0x30: sprintf( buffer, "rtpt%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x3d: sprintf( buffer, "gpf%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x3e: sprintf( buffer, "gpl%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; case 0x3f: sprintf( buffer, "ncct%s%s", s_gtesf[ GTE_SF( op ) ], s_gtelm[ GTE_LM( op ) ] ); break; } } break; } break; case OP_COP3: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc3 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp3genreg[ INS_RD( op ) ] ); break; case RS_CFC: sprintf( buffer, "cfc3 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp3ctlreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc3 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp3genreg[ INS_RD( op ) ] ); break; case RS_CTC: sprintf( buffer, "ctc3 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp3ctlreg[ INS_RD( op ) ] ); break; case RS_BC: case RS_BC_ALT: switch( INS_BC( op ) ) { case BC_BCF: sprintf( buffer, "bc3f $%08x", relative_address( state, pc, op ) ); break; case BC_BCT: sprintf( buffer, "bc3t $%08x", relative_address( state, pc, op ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop3 $%07x", INS_COFUN( op ) ); break; } break; } break; case OP_LB: sprintf( buffer, "lb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LH: sprintf( buffer, "lh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LWL: sprintf( buffer, "lwl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LW: sprintf( buffer, "lw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LBU: sprintf( buffer, "lbu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LHU: sprintf( buffer, "lhu %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LWR: sprintf( buffer, "lwr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SB: sprintf( buffer, "sb %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SH: sprintf( buffer, "sh %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SWL: sprintf( buffer, "swl %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SW: sprintf( buffer, "sw %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SWR: sprintf( buffer, "swr %s,%s", s_cpugenreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LWC0: sprintf( buffer, "lwc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LWC1: sprintf( buffer, "lwc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LWC2: sprintf( buffer, "lwc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_LWC3: sprintf( buffer, "lwc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SWC0: sprintf( buffer, "swc0 %s,%s", s_cp0genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SWC1: sprintf( buffer, "swc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SWC2: sprintf( buffer, "swc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; case OP_SWC3: sprintf( buffer, "swc3 %s,%s", s_cp2genreg[ INS_RT( op ) ], effective_address( state, pc, op ) ); break; } return ( opram - oldopram ) | flags | DASMFLAG_SUPPORTED; }
unsigned DasmMIPS( char *buffer, UINT32 pc, const UINT8 *opram ) { UINT32 op; const UINT8 *oldopram; oldopram = opram; op = ( opram[ 3 ] << 24 ) | ( opram[ 2 ] << 16 ) | ( opram[ 1 ] << 8 ) | ( opram[ 0 ] << 0 ); opram += 4; sprintf( buffer, "dw $%08x", op ); switch( INS_OP( op ) ) { case OP_SPECIAL: switch( INS_FUNCT( op ) ) { case FUNCT_SLL: if( op == 0 ) { /* the standard nop is "sll zero,zero,$0000" */ sprintf( buffer, "nop" ); } else { sprintf( buffer, "sll %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) ); } break; case FUNCT_SRL: sprintf( buffer, "srl %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) ); break; case FUNCT_SRA: sprintf( buffer, "sra %s,%s,$%02x", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], INS_SHAMT( op ) ); break; case FUNCT_SLLV: sprintf( buffer, "sllv %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_SRLV: sprintf( buffer, "srlv %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_SRAV: sprintf( buffer, "srav %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_JR: if( INS_RD( op ) == 0 ) { sprintf( buffer, "jr %s", s_cpugenreg[ INS_RS( op ) ] ); } break; case FUNCT_JALR: sprintf( buffer, "jalr %s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ] ); break; case FUNCT_SYSCALL: sprintf( buffer, "syscall $%05x", INS_CODE( op ) ); break; case FUNCT_BREAK: sprintf( buffer, "break $%05x", INS_CODE( op ) ); break; case FUNCT_MFHI: sprintf( buffer, "mfhi %s", s_cpugenreg[ INS_RD( op ) ] ); break; case FUNCT_MTHI: if( INS_RD( op ) == 0 ) { sprintf( buffer, "mthi %s", s_cpugenreg[ INS_RS( op ) ] ); } break; case FUNCT_MFLO: sprintf( buffer, "mflo %s", s_cpugenreg[ INS_RD( op ) ] ); break; case FUNCT_MTLO: if( INS_RD( op ) == 0 ) { sprintf( buffer, "mtlo %s", s_cpugenreg[ INS_RS( op ) ] ); } break; case FUNCT_MULT: if( INS_RD( op ) == 0 ) { sprintf( buffer, "mult %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); } break; case FUNCT_MULTU: if( INS_RD( op ) == 0 ) { sprintf( buffer, "multu %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); } break; case FUNCT_DIV: if( INS_RD( op ) == 0 ) { sprintf( buffer, "div %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); } break; case FUNCT_DIVU: if( INS_RD( op ) == 0 ) { sprintf( buffer, "divu %s,%s", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); } break; case FUNCT_ADD: sprintf( buffer, "add %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_ADDU: sprintf( buffer, "addu %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SUB: sprintf( buffer, "sub %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SUBU: sprintf( buffer, "subu %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_AND: sprintf( buffer, "and %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_OR: sprintf( buffer, "or %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_XOR: sprintf( buffer, "xor %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_NOR: sprintf( buffer, "nor %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SLT: sprintf( buffer, "slt %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; case FUNCT_SLTU: sprintf( buffer, "sltu %s,%s,%s", s_cpugenreg[ INS_RD( op ) ], s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ] ); break; } break; case OP_REGIMM: switch( INS_RT( op ) ) { case RT_BLTZ: sprintf( buffer, "bltz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case RT_BGEZ: sprintf( buffer, "bgez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case RT_BLTZAL: sprintf( buffer, "bltzal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case RT_BGEZAL: sprintf( buffer, "bgezal %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; } break; case OP_J: sprintf( buffer, "j $%08x", ( ( pc + 4 ) & 0xF0000000 ) + ( INS_TARGET( op ) << 2 ) ); break; case OP_JAL: sprintf( buffer, "jal $%08x", ( ( pc + 4 ) & 0xF0000000 ) + ( INS_TARGET( op ) << 2 ) ); break; case OP_BEQ: sprintf( buffer, "beq %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case OP_BNE: sprintf( buffer, "bne %s,%s,$%08x", s_cpugenreg[ INS_RS( op ) ], s_cpugenreg[ INS_RT( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case OP_BLEZ: if( INS_RT( op ) == 0 ) { sprintf( buffer, "blez %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); } break; case OP_BGTZ: if( INS_RT( op ) == 0 ) { sprintf( buffer, "bgtz %s,$%08x", s_cpugenreg[ INS_RS( op ) ], pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); } break; case OP_ADDI: sprintf( buffer, "addi %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_ADDIU: sprintf( buffer, "addiu %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_SLTI: sprintf( buffer, "slti %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_SLTIU: sprintf( buffer, "sltiu %s,%s,%s", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], make_signed_hex_str_16( INS_IMMEDIATE( op ) ) ); break; case OP_ANDI: sprintf( buffer, "andi %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_ORI: sprintf( buffer, "ori %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_XORI: sprintf( buffer, "xori %s,%s,$%04x", s_cpugenreg[ INS_RT( op ) ], s_cpugenreg[ INS_RS( op ) ], INS_IMMEDIATE( op ) ); break; case OP_LUI: sprintf( buffer, "lui %s,$%04x", s_cpugenreg[ INS_RT( op ) ], INS_IMMEDIATE( op ) ); break; case OP_COP0: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc0 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp0genreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc0 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp0genreg[ INS_RD( op ) ] ); break; case RS_BC: switch( INS_RT( op ) ) { case RT_BCF: sprintf( buffer, "bc0f $%08x", pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case RT_BCT: sprintf( buffer, "bc0t $%08x", pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop0 $%07x", INS_COFUN( op ) ); switch( INS_CF( op ) ) { case 1: sprintf( buffer, "tlbr" ); break; case 4: sprintf( buffer, "tlbwi" ); break; case 6: sprintf( buffer, "tlbwr" ); break; case 8: sprintf( buffer, "tlbp" ); break; case 16: sprintf( buffer, "rfe" ); break; } break; } break; } break; case OP_COP1: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1genreg[ INS_RD( op ) ] ); break; case RS_CFC: sprintf( buffer, "cfc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1ctlreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1genreg[ INS_RD( op ) ] ); break; case RS_CTC: sprintf( buffer, "ctc1 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp1ctlreg[ INS_RD( op ) ] ); break; case RS_BC: switch( INS_RT( op ) ) { case RT_BCF: sprintf( buffer, "bc1f $%08x", pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case RT_BCT: sprintf( buffer, "bc1t $%08x", pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop1 $%07x", INS_COFUN( op ) ); break; } break; } break; case OP_COP2: switch( INS_RS( op ) ) { case RS_MFC: sprintf( buffer, "mfc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2genreg[ INS_RD( op ) ] ); break; case RS_CFC: sprintf( buffer, "cfc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2ctlreg[ INS_RD( op ) ] ); break; case RS_MTC: sprintf( buffer, "mtc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2genreg[ INS_RD( op ) ] ); break; case RS_CTC: sprintf( buffer, "ctc2 %s,%s", s_cpugenreg[ INS_RT( op ) ], s_cp2ctlreg[ INS_RD( op ) ] ); break; case RS_BC: switch( INS_RT( op ) ) { case RT_BCF: sprintf( buffer, "bc2f $%08x", pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; case RT_BCT: sprintf( buffer, "bc2t $%08x", pc + 4 + ( MIPS_WORD_EXTEND( INS_IMMEDIATE( op ) ) << 2 ) ); break; } break; default: switch( INS_CO( op ) ) { case 1: sprintf( buffer, "cop2 $%07x", INS_COFUN( op ) ); switch( GTE_FUNCT( op ) ) { case 0x01: if( INS_COFUN( op ) == 0x0180001 ) { sprintf( buffer, "rtps" ); } break; case 0x06: if( INS_COFUN( op ) == 0x0400006 || INS_COFUN( op ) == 0x1400006 || INS_COFUN( op ) == 0x0155cc6 ) { sprintf( buffer, "nclip" ); } break; case 0x0c: if( GTE_OP( op ) == 0x17 ) { sprintf( buffer, "op%s", s_gtesf[ GTE_SF( op ) ] ); } break; case 0x10: if( INS_COFUN( op ) == 0x0780010 ) { sprintf( buffer, "dpcs" ); } break; case 0x11: if( INS_COFUN( op ) == 0x0980011 ) { sprintf( buffer, "intpl" ); } break; case 0x12: if( GTE_OP( op ) == 0x04 ) { sprintf( buffer, "mvmva%s %s + %s * %s (lm=%s)", s_gtesf[ GTE_SF( op ) ], s_gtecv[ GTE_CV( op ) ], s_gtemx[ GTE_MX( op ) ], s_gtev[ GTE_V( op ) ], s_gtelm[ GTE_LM( op ) ] ); } break; case 0x13: if( INS_COFUN( op ) == 0x0e80413 ) { sprintf( buffer, "ncds" ); } break; case 0x14: if( INS_COFUN( op ) == 0x1280414 ) { sprintf( buffer, "cdp" ); } break; case 0x16: if( INS_COFUN( op ) == 0x0f80416 ) { sprintf( buffer, "ncdt" ); } break; case 0x1b: if( INS_COFUN( op ) == 0x108041b ) { sprintf( buffer, "nccs" ); } break; case 0x1c: if( INS_COFUN( op ) == 0x138041c ) { sprintf( buffer, "cc" ); } break; case 0x1e: if( INS_COFUN( op ) == 0x0c8041e ) { sprintf( buffer, "ncs" ); } break; case 0x20: if( INS_COFUN( op ) == 0x0d80420 ) { sprintf( buffer, "nct" ); } break; case 0x28: if( GTE_OP( op ) == 0x0a && GTE_LM( op ) == 1 ) { sprintf( buffer, "sqr%s", s_gtesf[ GTE_SF( op ) ] ); } break; case 0x29: if( INS_COFUN( op ) == 0x0680029 ) { sprintf( buffer, "dcpl" ); } break; case 0x2a: if( INS_COFUN( op ) == 0x0f8002a ) { sprintf( buffer, "dpct" ); } break; case 0x2d: if( INS_COFUN( op ) == 0x158002d ) { sprintf( buffer, "avsz3" ); } break; case 0x2e: if( INS_COFUN( op ) == 0x168002e ) { sprintf( buffer, "avsz4" ); } break; case 0x30: if( INS_COFUN( op ) == 0x0280030 ) { sprintf( buffer, "rtpt" ); } break; case 0x3d: if( GTE_OP( op ) == 0x09 || GTE_OP( op ) == 0x19 ) { sprintf( buffer, "gpf%s", s_gtesf[ GTE_SF( op ) ] ); } break; case 0x3e: if( GTE_OP( op ) == 0x1a ) { sprintf( buffer, "gpl%s", s_gtesf[ GTE_SF( op ) ] ); } break; case 0x3f: if( INS_COFUN( op ) == 0x108043f || INS_COFUN( op ) == 0x118043f ) { sprintf( buffer, "ncct" ); } break; } } break; } break; case OP_LB: sprintf( buffer, "lb %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LH: sprintf( buffer, "lh %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LWL: sprintf( buffer, "lwl %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LW: sprintf( buffer, "lw %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LBU: sprintf( buffer, "lbu %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LHU: sprintf( buffer, "lhu %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LWR: sprintf( buffer, "lwr %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SB: sprintf( buffer, "sb %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SH: sprintf( buffer, "sh %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SWL: sprintf( buffer, "swl %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SW: sprintf( buffer, "sw %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SWR: sprintf( buffer, "swr %s,%s", s_cpugenreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LWC1: sprintf( buffer, "lwc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_LWC2: sprintf( buffer, "lwc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SWC1: sprintf( buffer, "swc1 %s,%s", s_cp1genreg[ INS_RT( op ) ], make_address( pc, op ) ); break; case OP_SWC2: sprintf( buffer, "swc2 %s,%s", s_cp2genreg[ INS_RT( op ) ], make_address( pc, op ) ); break; } return ( opram - oldopram ) | DASMFLAG_SUPPORTED; }