2 // Jaguar RISC Disassembly
4 // Originally by David Raingeard
5 // GCC/SDL port by Niels Wagenaar (Linux/WIN32) and Carwin Jones (BeOS)
6 // Minor cleanups by James Hammons
7 // (C) 2012 Underground Software
9 // JLH = James Hammons <jlhamm@acm.org>
12 // --- ---------- -------------------------------------------------------------
13 // JLH 06/01/2012 Created this log (long overdue! ;-)
14 // JLH 01/23/2013 Beautifying of disassembly, including hex digits of opcodes
23 #define ROPCODE(a) JaguarReadWord(a)
25 uint8_t convert_zero
[32] =
26 { 32,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 };
28 const char * condition
[32] =
69 char * signed_16bit(int16_t val
)
74 sprintf(temp
, "-$%X", -val
);
76 sprintf(temp
, "$%X", val
);
82 unsigned dasmjag(int dsp_type
, char * bufferOut
, unsigned pc
)
86 int reg1
= (op
>> 5) & 31;
93 case 0: sprintf(buffer
, "ADD R%02d,R%02d", reg1
, reg2
); break;
94 case 1: sprintf(buffer
, "ADDC R%02d,R%02d", reg1
, reg2
); break;
95 case 2: sprintf(buffer
, "ADDQ $%X,R%02d", convert_zero
[reg1
], reg2
); break;
96 case 3: sprintf(buffer
, "ADDQT $%X,R%02d", convert_zero
[reg1
], reg2
); break;
97 case 4: sprintf(buffer
, "SUB R%02d,R%02d", reg1
, reg2
); break;
98 case 5: sprintf(buffer
, "SUBC R%02d,R%02d", reg1
, reg2
); break;
99 case 6: sprintf(buffer
, "SUBQ $%X,R%02d", convert_zero
[reg1
], reg2
); break;
100 case 7: sprintf(buffer
, "SUBQT $%X,R%02d", convert_zero
[reg1
], reg2
); break;
101 case 8: sprintf(buffer
, "NEG R%02d", reg2
); break;
102 case 9: sprintf(buffer
, "AND R%02d,R%02d", reg1
, reg2
); break;
103 case 10: sprintf(buffer
, "OR R%02d,R%02d", reg1
, reg2
); break;
104 case 11: sprintf(buffer
, "XOR R%02d,R%02d", reg1
, reg2
); break;
105 case 12: sprintf(buffer
, "NOT R%02d", reg2
); break;
106 case 13: sprintf(buffer
, "BTST $%X,R%02d", reg1
, reg2
); break;
107 case 14: sprintf(buffer
, "BSET $%X,R%02d", reg1
, reg2
); break;
108 case 15: sprintf(buffer
, "BCLR $%X,R%02d", reg1
, reg2
); break;
109 case 16: sprintf(buffer
, "MULT R%02d,R%02d", reg1
, reg2
); break;
110 case 17: sprintf(buffer
, "IMULT R%02d,R%02d", reg1
, reg2
); break;
111 case 18: sprintf(buffer
, "IMULTN R%02d,R%02d", reg1
, reg2
); break;
112 case 19: sprintf(buffer
, "RESMAC R%02d", reg2
); break;
113 case 20: sprintf(buffer
, "IMACN R%02d,R%02d", reg1
, reg2
); break;
114 case 21: sprintf(buffer
, "DIV R%02d,R%02d", reg1
, reg2
); break;
115 case 22: sprintf(buffer
, "ABS R%02d", reg2
); break;
116 case 23: sprintf(buffer
, "SH R%02d,R%02d", reg1
, reg2
); break;
117 case 24: sprintf(buffer
, "SHLQ $%X,R%02d", 32 - reg1
, reg2
); break;
118 case 25: sprintf(buffer
, "SHRQ $%X,R%02d", convert_zero
[reg1
], reg2
); break;
119 case 26: sprintf(buffer
, "SHA R%02d,R%02d", reg1
, reg2
); break;
120 case 27: sprintf(buffer
, "SHARQ $%X,R%02d", convert_zero
[reg1
], reg2
); break;
121 case 28: sprintf(buffer
, "ROR R%02d,R%02d", reg1
, reg2
); break;
122 case 29: sprintf(buffer
, "RORQ $%X,R%02d", convert_zero
[reg1
], reg2
); break;
123 case 30: sprintf(buffer
, "CMP R%02d,R%02d", reg1
, reg2
); break;
124 case 31: sprintf(buffer
, "CMPQ %s,R%02d", signed_16bit((int16_t)(reg1
<< 11) >> 11), reg2
);break;
125 case 32: if (dsp_type
== JAGUAR_GPU
)
126 sprintf(buffer
, "SAT8 R%02d", reg2
);
128 sprintf(buffer
, "SUBQMOD $%X,R%02d", convert_zero
[reg1
], reg2
);
130 case 33: if (dsp_type
== JAGUAR_GPU
)
131 sprintf(buffer
, "SAT16 R%02d", reg2
);
133 sprintf(buffer
, "SAT16S R%02d", reg2
);
135 case 34: sprintf(buffer
, "MOVE R%02d,R%02d", reg1
, reg2
); break;
136 case 35: sprintf(buffer
, "MOVEQ %d,R%02d", reg1
, reg2
); break;
137 case 36: sprintf(buffer
, "MOVETA R%02d,R%02d", reg1
, reg2
); break;
138 case 37: sprintf(buffer
, "MOVEFA R%02d,R%02d", reg1
, reg2
); break;
139 case 38: sprintf(buffer
, "MOVEI #$%X,R%02d", ROPCODE(pc
) | (ROPCODE(pc
+2)<<16), reg2
); size
= 6; break;
140 case 39: sprintf(buffer
, "LOADB (R%02d),R%02d", reg1
, reg2
); break;
141 case 40: sprintf(buffer
, "LOADW (R%02d),R%02d", reg1
, reg2
); break;
142 case 41: sprintf(buffer
, "LOAD (R%02d),R%02d", reg1
, reg2
); break;
143 case 42: if (dsp_type
== JAGUAR_GPU
)
144 sprintf(buffer
, "LOADP (R%02d),R%02d", reg1
, reg2
);
146 sprintf(buffer
, "SAT32S R%02d", reg2
);
148 case 43: sprintf(buffer
, "LOAD (R14+$%X),R%02d", convert_zero
[reg1
]*4, reg2
);break;
149 case 44: sprintf(buffer
, "LOAD (R15+$%X),R%02d", convert_zero
[reg1
]*4, reg2
);break;
150 case 45: sprintf(buffer
, "STOREB R%02d,(R%02d)", reg2
, reg1
); break;
151 case 46: sprintf(buffer
, "STOREW R%02d,(R%02d)", reg2
, reg1
); break;
152 case 47: sprintf(buffer
, "STORE R%02d,(R%02d)", reg2
, reg1
); break;
153 case 48: if (dsp_type
== JAGUAR_GPU
)
154 sprintf(buffer
, "STOREP R%02d,(R%02d)", reg2
, reg1
);
156 sprintf(buffer
, "MIRROR R%02d", reg2
);
158 case 49: sprintf(buffer
, "STORE R%02d,(R14+$%X)", reg2
, convert_zero
[reg1
]*4);break;
159 case 50: sprintf(buffer
, "STORE R%02d,(R15+$%X)", reg2
, convert_zero
[reg1
]*4);break;
160 case 51: sprintf(buffer
, "MOVE PC,R%02d", reg2
); break;
161 case 52: sprintf(buffer
, "JUMP %s(R%02d)", condition
[reg2
], reg1
); break;
162 case 53: sprintf(buffer
, "JR %s$%X", condition
[reg2
], pc
+ ((int8_t)(reg1
<< 3) >> 2)); break;
163 case 54: sprintf(buffer
, "MMULT R%02d,R%02d", reg1
, reg2
); break;
164 case 55: sprintf(buffer
, "MTOI R%02d,R%02d", reg1
, reg2
); break;
165 case 56: sprintf(buffer
, "NORMI R%02d,R%02d", reg1
, reg2
); break;
166 case 57: sprintf(buffer
, "NOP"); break;
167 case 58: sprintf(buffer
, "LOAD (R14+R%02d),R%02d", reg1
, reg2
); break;
168 case 59: sprintf(buffer
, "LOAD (R15+R%02d),R%02d", reg1
, reg2
); break;
169 case 60: sprintf(buffer
, "STORE R%02d,(R14+R%02d)", reg2
, reg1
); break;
170 case 61: sprintf(buffer
, "STORE R%02d,(R15+R%02d)", reg2
, reg1
); break;
171 case 62: if (dsp_type
== JAGUAR_GPU
)
172 sprintf(buffer
, "SAT24 R%02d", reg2
);
174 sprintf(buffer
, "illegal [%d,%d]", reg1
, reg2
);
176 case 63: if (dsp_type
== JAGUAR_GPU
)
177 sprintf(buffer
, (reg1
? "UNPACK R%02d" : "PACK R%02d"), reg2
);
179 sprintf(buffer
, "ADDQMOD $%X,R%02d", convert_zero
[reg1
], reg2
);
184 sprintf(bufferOut
,"%-24s (%04X)", buffer
, op
);
187 sprintf(bufferOut
, "%04X %-24s", op
, buffer
);
190 uint16_t word1
= ROPCODE(pc
), word2
= ROPCODE(pc
+ 2);
191 sprintf(bufferOut
, "%04X %04X %04X %-24s", op
, word1
, word2
, buffer
);