]> Shamusworld >> Repos - virtualjaguar/blob - src/jagdasm.cpp
Fix to M68K core vs. DSP thread sync problem.
[virtualjaguar] / src / jagdasm.cpp
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 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 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)(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)(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 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 }