Commit | Line | Data |
---|---|---|
cf76e892 JPM |
1 | // |
2 | // Jaguar RISC Disassembly | |
3 | // | |
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 | |
8 | // | |
9 | // JLH = James Hammons <jlhamm@acm.org> | |
10 | // | |
11 | // Who When What | |
12 | // --- ---------- ------------------------------------------------------------- | |
13 | // JLH 06/01/2012 Created this log (long overdue! ;-) | |
14 | // JLH 01/23/2013 Beautifying of disassembly, including hex digits of opcodes | |
15 | // and operands | |
16 | // | |
17 | ||
18 | #include "jagdasm.h" | |
19 | ||
20 | #include <stdio.h> | |
21 | #include "jaguar.h" | |
22 | ||
23 | #define ROPCODE(a) JaguarReadWord(a) | |
24 | ||
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 }; | |
27 | ||
28 | const char * condition[32] = | |
29 | { | |
30 | "", | |
31 | "nz,", | |
32 | "z,", | |
33 | "???,", | |
34 | "nc,", | |
35 | "nc nz,", | |
36 | "nc z,", | |
37 | "???,", | |
38 | ||
39 | "c,", | |
40 | "c nz,", | |
41 | "c z,", | |
42 | "???,", | |
43 | "???,", | |
44 | "???,", | |
45 | "???,", | |
46 | "???,", | |
47 | ||
48 | "???,", | |
49 | "???,", | |
50 | "???,", | |
51 | "???,", | |
52 | "nn,", | |
53 | "nn nz,", | |
54 | "nn z,", | |
55 | "???,", | |
56 | ||
57 | "n,", | |
58 | "n nz,", | |
59 | "n z,", | |
60 | "???,", | |
61 | "???,", | |
62 | "???,", | |
63 | "???,", | |
64 | "never," | |
65 | }; | |
66 | ||
67 | ||
68 | ||
69 | char * signed_16bit(int16_t val) | |
70 | { | |
71 | static char temp[10]; | |
72 | ||
73 | if (val < 0) | |
74 | sprintf(temp, "-$%X", -val); | |
75 | else | |
76 | sprintf(temp, "$%X", val); | |
77 | ||
78 | return temp; | |
79 | } | |
80 | ||
81 | ||
82 | unsigned dasmjag(int dsp_type, char * bufferOut, unsigned pc) | |
83 | { | |
84 | char buffer[64]; | |
85 | int op = ROPCODE(pc); | |
86 | int reg1 = (op >> 5) & 31; | |
87 | int reg2 = op & 31; | |
88 | int size = 2; | |
89 | pc += 2; | |
90 | ||
91 | switch (op >> 10) | |
92 | { | |
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); | |
127 | else | |
128 | sprintf(buffer, "SUBQMOD $%X,R%02d", convert_zero[reg1], reg2); | |
129 | break; | |
130 | case 33: if (dsp_type == JAGUAR_GPU) | |
131 | sprintf(buffer, "SAT16 R%02d", reg2); | |
132 | else | |
133 | sprintf(buffer, "SAT16S R%02d", reg2); | |
134 | break; | |
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); | |
145 | else | |
146 | sprintf(buffer, "SAT32S R%02d", reg2); | |
147 | break; | |
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); | |
155 | else | |
156 | sprintf(buffer, "MIRROR R%02d", reg2); | |
157 | break; | |
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); | |
173 | else | |
174 | sprintf(buffer, "illegal [%d,%d]", reg1, reg2); | |
175 | break; | |
176 | case 63: if (dsp_type == JAGUAR_GPU) | |
177 | sprintf(buffer, (reg1 ? "UNPACK R%02d" : "PACK R%02d"), reg2); | |
178 | else | |
179 | sprintf(buffer, "ADDQMOD $%X,R%02d", convert_zero[reg1], reg2); | |
180 | break; | |
181 | } | |
182 | ||
183 | #if 0 | |
184 | sprintf(bufferOut,"%-24s (%04X)", buffer, op); | |
185 | #else | |
186 | if (size == 2) | |
187 | sprintf(bufferOut, "%04X %-24s", op, buffer); | |
188 | else | |
189 | { | |
190 | uint16_t word1 = ROPCODE(pc), word2 = ROPCODE(pc + 2); | |
191 | sprintf(bufferOut, "%04X %04X %04X %-24s", op, word1, word2, buffer); | |
192 | } | |
193 | #endif | |
194 | ||
195 | return size; | |
196 | } |