3 * Bart Trzynadlowski, July 24, 2000
6 * Some changes by Björn Stenberg <bjorn@haxx.se>
18 #define ZERO_F 0 /* 0 format */
19 #define N_F 1 /* n format */
20 #define M_F 2 /* m format */
21 #define NM_F 3 /* nm format */
22 #define MD_F 4 /* md format */
23 #define ND4_F 5 /* nd4 format */
24 #define NMD_F 6 /* nmd format */
25 #define D_F 7 /* d format */
26 #define D12_F 8 /* d12 format */
27 #define ND8_F 9 /* nd8 format */
28 #define I_F 10 /* i format */
29 #define NI_F 11 /* ni format */
35 unsigned short mask
; /* mask used to obtain opcode bits */
36 unsigned short bits
; /* opcode bits */
37 int dat
; /* specific data for situation */
38 int sh2
; /* SH-2 specific */
41 /* register name lookup added by bjorn@haxx.se 2001-12-09 */
44 /* 0 1 2 3 4 5 6 7 8 9 a b c d e f */
45 "","","","","","","","","","","","","","","","", /* 0 */
46 "","","","","","","","","","","","","","","","", /* 10 */
47 "","","","","","","","","","","","","","","","", /* 20 */
48 "","","","","","","","","","","","","","","","", /* 30 */
49 "","","","","","","","","","","","","","","","", /* 40 */
50 "","","","","","","","","","","","","","","","", /* 50 */
51 "","","","","","","","","","","","","","","","", /* 60 */
52 "","","","","","","","","","","","","","","","", /* 70 */
53 "","","","","","","","","","","","","","","","", /* 80 */
54 "","","","","","","","","","","","","","","","", /* 90 */
55 "","","","","","","","","","","","","","","","", /* a0 */
56 "","","","","","","","","","","","","","","","", /* b0 */
58 "SMR0","BRR0","SCR0","TDR0","SSR0","RDR0","","", /* c0 */
59 "SMR1","BRR1","SCR1","TDR1","SSR1","RDR1","","", /* c8 */
60 "","","","","","","","","","","","","","","","", /* d0 */
61 "ADDRAH","ADDRAL","ADDRBH","ADDRBL", /* e0 */
62 "ADDRCH","ADDRCL","ADDRDH","ADDRDL", /* e4 */
63 "ADCSR","ADCR","","","","","","", /* e8 */
64 "","","","","","","","","","","","","","","","", /* f0 */
65 "TSTR","TSNC","TMDR","TFCR","TCR0","TIOR0","TIER0","TSR0", /* 100 */
66 "TCNT0","!","GRA0","!","GRB0","!","TCR1","TIORL", /* 108 */
67 "TIERI","TSR1","TCNT1","!","GRA1","!","GRB1","!", /* 110 */
68 "TCR2","TIOR2","TIER2","TSR2","TCNT2","!","GRA2","!", /* 118 */
69 "GRB2","!","TCR3","TIOR3","TIER3","TSR3","TCNT3","!", /* 120 */
70 "GRA3","!","GRB3","!","BRA3","!","BRB3","!", /* 128 */
71 "","TOCR","TCR4","TIOR4","TIER4","TSR4","TCNT4","!", /* 130 */
72 "GRA4","!","GRB4","!","BRA4","!","BRB4","!", /* 138 */
73 "SAR0","!","!","!","DAR0","!","!","!", /* 140 */
74 "DMAOR","!","TCR0","!","","","CHCR0","!", /* 148 */
75 "SAR1","!","!","!","DAR1","!","!","!", /* 150 */
76 "","","TCR1","!","","","CHCR1","!", /* 158 */
77 "SAR2","!","!","!","DAR2","!","!","!", /* 160 */
78 "","","TCR2","!","","","CHCR2","!", /* 168 */
79 "SAR3","!","!","!","DAR3","!","!","!", /* 170 */
80 "","","TCR3","!","","","CHCR3","!", /* 178 */
81 "","","","","IPRA","!","IPRB","!", /* 180 */
82 "IPRC","!","IPRD","!","IPRE","!","ICR","!", /* 188 */
83 "BARH","!","BARL","!","BAMRH","!","BAMRL","!", /* 190 */
84 "BBR","!","","","","","","", /* 198 */
85 "BCR","!","WCR1","!","WCR2","!","WCR3","!", /* 1a0 */
86 "DCR","!","PCR","!","RCR","!","RTCSR","!", /* 1a8 */
87 "RTCNT","!","RTCOR","!","","","","", /* 1b0 */
88 "TCSR","TCNT","","RSTCSR","SBYCR","","","", /* 1b8 */
89 "PADR","!","PBDR","!","PAIOR","!","PBIOR","!", /* 1c0 */
90 "PACR1","!","PACR2","!","PBCR1","!","PBCR2","!", /* 1c8 */
91 "PCDR","!","","","","","","","","","","","","","","", /* 1d0 */
92 "","","","","","","","","","","","","","","CASCR","!", /* 1e0 */
93 "TPMR","TPCR","NDERB","NDERA","NDRB","NDRA","NDRB","NDRA", /* 1f0 */
94 "","","","","","","",""
99 { ZERO_F
, "clrt", 0xffff, 0x8, 0, 0 },
100 { ZERO_F
, "clrmac", 0xffff, 0x28, 0, 0 },
101 { ZERO_F
, "div0u", 0xffff, 0x19, 0, 0 },
102 { ZERO_F
, "nop", 0xffff, 0x9, 0, 0 },
103 { ZERO_F
, "rte", 0xffff, 0x2b, 0, 0 },
104 { ZERO_F
, "rts", 0xffff, 0xb, 0, 0 },
105 { ZERO_F
, "sett", 0xffff, 0x18, 0, 0 },
106 { ZERO_F
, "sleep", 0xffff, 0x1b, 0, 0 },
107 { N_F
, "cmp/pl\tr%d", 0xf0ff, 0x4015, 0, 0 },
108 { N_F
, "cmp/pz\tr%d", 0xf0ff, 0x4011, 0, 0 },
109 { N_F
, "dt\tr%d", 0xf0ff, 0x4010, 0, 1 },
110 { N_F
, "movt\tr%d", 0xf0ff, 0x0029, 0, 0 },
111 { N_F
, "rotl\tr%d", 0xf0ff, 0x4004, 0, 0 },
112 { N_F
, "rotr\tr%d", 0xf0ff, 0x4005, 0, 0 },
113 { N_F
, "rotcl\tr%d", 0xf0ff, 0x4024, 0, 0 },
114 { N_F
, "rotcr\tr%d", 0xf0ff, 0x4025, 0, 0 },
115 { N_F
, "shal\tr%d", 0xf0ff, 0x4020, 0, 0 },
116 { N_F
, "shar\tr%d", 0xf0ff, 0x4021, 0, 0 },
117 { N_F
, "shll\tr%d", 0xf0ff, 0x4000, 0, 0 },
118 { N_F
, "shlr\tr%d", 0xf0ff, 0x4001, 0, 0 },
119 { N_F
, "shll2\tr%d", 0xf0ff, 0x4008, 0, 0 },
120 { N_F
, "shlr2\tr%d", 0xf0ff, 0x4009, 0, 0 },
121 { N_F
, "shll8\tr%d", 0xf0ff, 0x4018, 0, 0 },
122 { N_F
, "shlr8\tr%d", 0xf0ff, 0x4019, 0, 0 },
123 { N_F
, "shll16\tr%d", 0xf0ff, 0x4028, 0, 0 },
124 { N_F
, "shlr16\tr%d", 0xf0ff, 0x4029, 0, 0 },
125 { N_F
, "stc\tsr,r%d", 0xf0ff, 0x0002, 0, 0 },
126 { N_F
, "stc\tgbr,r%d", 0xf0ff, 0x0012, 0, 0 },
127 { N_F
, "stc\tvbr,r%d", 0xf0ff, 0x0022, 0, 0 },
128 { N_F
, "sts\tmach,r%d", 0xf0ff, 0x000a, 0, 0 },
129 { N_F
, "sts\tmacl,r%d", 0xf0ff, 0x001a, 0, 0 },
130 { N_F
, "sts\tpr,r%d", 0xf0ff, 0x002a, 0, 0 },
131 { N_F
, "tas.b\t@r%d", 0xf0ff, 0x401b, 0, 0 },
132 { N_F
, "stc.l\tsr,@-r%d", 0xf0ff, 0x4003, 0, 0 },
133 { N_F
, "stc.l\tgbr,@-r%d", 0xf0ff, 0x4013, 0, 0 },
134 { N_F
, "stc.l\tvbr,@-r%d", 0xf0ff, 0x4023, 0, 0 },
135 { N_F
, "sts.l\tmach,@-r%d", 0xf0ff, 0x4002, 0, 0 },
136 { N_F
, "sts.l\tmacl,@-r%d", 0xf0ff, 0x4012, 0, 0 },
137 { N_F
, "sts.l\tpr,@-r%d", 0xf0ff, 0x4022, 0, 0 },
138 { M_F
, "ldc\tr%d,sr", 0xf0ff, 0x400e, 0, 0 },
139 { M_F
, "ldc\tr%d,gbr", 0xf0ff, 0x401e, 0, 0 },
140 { M_F
, "ldc\tr%d,vbr", 0xf0ff, 0x402e, 0, 0 },
141 { M_F
, "lds\tr%d,mach", 0xf0ff, 0x400a, 0, 0 },
142 { M_F
, "lds\tr%d,macl", 0xf0ff, 0x401a, 0, 0 },
143 { M_F
, "lds\tr%d,pr", 0xf0ff, 0x402a, 0, 0 },
144 { M_F
, "jmp\t@r%d", 0xf0ff, 0x402b, 0, 0 },
145 { M_F
, "jsr\t@r%d", 0xf0ff, 0x400b, 0, 0 },
146 { M_F
, "ldc.l\t@r%d+,sr", 0xf0ff, 0x4007, 0, 0 },
147 { M_F
, "ldc.l\t@r%d+,gbr", 0xf0ff, 0x4017, 0, 0 },
148 { M_F
, "ldc.l\t@r%d+,vbr", 0xf0ff, 0x4027, 0, 0 },
149 { M_F
, "lds.l\t@r%d+,mach", 0xf0ff, 0x4006, 0, 0 },
150 { M_F
, "lds.l\t@r%d+,macl", 0xf0ff, 0x4016, 0, 0 },
151 { M_F
, "lds.l\t@r%d+,pr", 0xf0ff, 0x4026, 0, 0 },
152 { M_F
, "braf\tr%d", 0xf0ff, 0x0023, 0, 1 },
153 { M_F
, "bsrf\tr%d", 0xf0ff, 0x0003, 0, 1 },
154 { NM_F
, "add\tr%d,r%d", 0xf00f, 0x300c, 0, 0 },
155 { NM_F
, "addc\tr%d,r%d", 0xf00f, 0x300e, 0, 0 },
156 { NM_F
, "addv\tr%d,r%d", 0xf00f, 0x300f, 0, 0 },
157 { NM_F
, "and\tr%d,r%d", 0xf00f, 0x2009, 0, 0 },
158 { NM_F
, "cmp/eq\tr%d,r%d", 0xf00f, 0x3000, 0, 0 },
159 { NM_F
, "cmp/hs\tr%d,r%d", 0xf00f, 0x3002, 0, 0 },
160 { NM_F
, "cmp/ge\tr%d,r%d", 0xf00f, 0x3003, 0, 0 },
161 { NM_F
, "cmp/hi\tr%d,r%d", 0xf00f, 0x3006, 0, 0 },
162 { NM_F
, "cmp/gt\tr%d,r%d", 0xf00f, 0x3007, 0, 0 },
163 { NM_F
, "cmp/str\tr%d,r%d", 0xf00f, 0x200c, 0, 0 },
164 { NM_F
, "div1\tr%d,r%d", 0xf00f, 0x3004, 0, 0 },
165 { NM_F
, "div0s\tr%d,r%d", 0xf00f, 0x2007, 0, 0 },
166 { NM_F
, "dmuls.l\tr%d,r%d", 0xf00f, 0x300d, 0, 1 },
167 { NM_F
, "dmulu.l\tr%d,r%d", 0xf00f, 0x3005, 0, 1 },
168 { NM_F
, "exts.b\tr%d,r%d", 0xf00f, 0x600e, 0, 0 },
169 { NM_F
, "exts.w\tr%d,r%d", 0xf00f, 0x600f, 0, 0 },
170 { NM_F
, "extu.b\tr%d,r%d", 0xf00f, 0x600c, 0, 0 },
171 { NM_F
, "extu.w\tr%d,r%d", 0xf00f, 0x600d, 0, 0 },
172 { NM_F
, "mov\tr%d,r%d", 0xf00f, 0x6003, 0, 0 },
173 { NM_F
, "mul.l\tr%d,r%d", 0xf00f, 0x0007, 0, 1 },
174 { NM_F
, "muls.w\tr%d,r%d", 0xf00f, 0x200f, 0, 0 },
175 { NM_F
, "mulu.w\tr%d,r%d", 0xf00f, 0x200e, 0, 0 },
176 { NM_F
, "neg\tr%d,r%d", 0xf00f, 0x600b, 0, 0 },
177 { NM_F
, "negc\tr%d,r%d", 0xf00f, 0x600a, 0, 0 },
178 { NM_F
, "not\tr%d,r%d", 0xf00f, 0x6007, 0, 0 },
179 { NM_F
, "or\tr%d,r%d", 0xf00f, 0x200b, 0, 0 },
180 { NM_F
, "sub\tr%d,r%d", 0xf00f, 0x3008, 0, 0 },
181 { NM_F
, "subc\tr%d,r%d", 0xf00f, 0x300a, 0, 0 },
182 { NM_F
, "subv\tr%d,r%d", 0xf00f, 0x300b, 0, 0 },
183 { NM_F
, "swap.b\tr%d,r%d", 0xf00f, 0x6008, 0, 0 },
184 { NM_F
, "swap.w\tr%d,r%d", 0xf00f, 0x6009, 0, 0 },
185 { NM_F
, "tst\tr%d,r%d", 0xf00f, 0x2008, 0, 0 },
186 { NM_F
, "xor\tr%d,r%d", 0xf00f, 0x200a, 0, 0 },
187 { NM_F
, "xtrct\tr%d,r%d", 0xf00f, 0x200d, 0, 0 },
188 { NM_F
, "mov.b\tr%d,@r%d", 0xf00f, 0x2000, 0, 0 },
189 { NM_F
, "mov.w\tr%d,@r%d", 0xf00f, 0x2001, 0, 0 },
190 { NM_F
, "mov.l\tr%d,@r%d", 0xf00f, 0x2002, 0, 0 },
191 { NM_F
, "mov.b\t@r%d,r%d", 0xf00f, 0x6000, 0, 0 },
192 { NM_F
, "mov.w\t@r%d,r%d", 0xf00f, 0x6001, 0, 0 },
193 { NM_F
, "mov.l\t@r%d,r%d", 0xf00f, 0x6002, 0, 0 },
194 { NM_F
, "mac.l\t@r%d+,@r%d+", 0xf00f, 0x000f, 0, 1 },
195 { NM_F
, "mac.w\t@r%d+,@r%d+", 0xf00f, 0x400f, 0, 0 },
196 { NM_F
, "mov.b\t@r%d+,r%d", 0xf00f, 0x6004, 0, 0 },
197 { NM_F
, "mov.w\t@r%d+,r%d", 0xf00f, 0x6005, 0, 0 },
198 { NM_F
, "mov.l\t@r%d+,r%d", 0xf00f, 0x6006, 0, 0 },
199 { NM_F
, "mov.b\tr%d,@-r%d", 0xf00f, 0x2004, 0, 0 },
200 { NM_F
, "mov.w\tr%d,@-r%d", 0xf00f, 0x2005, 0, 0 },
201 { NM_F
, "mov.l\tr%d,@-r%d", 0xf00f, 0x2006, 0, 0 },
202 { NM_F
, "mov.b\tr%d,@(r0,r%d)", 0xf00f, 0x0004, 0, 0 },
203 { NM_F
, "mov.w\tr%d,@(r0,r%d)", 0xf00f, 0x0005, 0, 0 },
204 { NM_F
, "mov.l\tr%d,@(r0,r%d)", 0xf00f, 0x0006, 0, 0 },
205 { NM_F
, "mov.b\t@(r0,r%d),r%d", 0xf00f, 0x000c, 0, 0 },
206 { NM_F
, "mov.w\t@(r0,r%d),r%d", 0xf00f, 0x000d, 0, 0 },
207 { NM_F
, "mov.l\t@(r0,r%d),r%d", 0xf00f, 0x000e, 0, 0 },
208 { MD_F
, "mov.b\t@(0x%03X,r%d), r0", 0xff00, 0x8400, 0, 0 },
209 { MD_F
, "mov.w\t@(0x%03X,r%d), r0", 0xff00, 0x8500, 0, 0 },
210 { ND4_F
, "mov.b\tr0,@(0x%03X,r%d)", 0xff00, 0x8000, 0, 0 },
211 { ND4_F
, "mov.w\tr0,@(0x%03X,r%d)", 0xff00, 0x8100, 0, 0 },
212 { NMD_F
, "mov.l\tr%d,@(0x%03X,r%d)", 0xf000, 0x1000, 0,0 },
213 { NMD_F
, "mov.l\t@(0x%03X,r%d),r%d", 0xf000, 0x5000, 0,0 },
214 { D_F
, "mov.b\tr0,@(0x%03X,gbr)", 0xff00, 0xc000, 1, 0 },
215 { D_F
, "mov.w\tr0,@(0x%03X,gbr)", 0xff00, 0xc100, 2, 0 },
216 { D_F
, "mov.l\tr0,@(0x%03X,gbr)", 0xff00, 0xc200, 4, 0 },
217 { D_F
, "mov.b\t@(0x%03X,gbr),r0", 0xff00, 0xc400, 1, 0 },
218 { D_F
, "mov.w\t@(0x%03X,gbr),r0", 0xff00, 0xc500, 2, 0 },
219 { D_F
, "mov.l\t@(0x%03X,gbr),r0", 0xff00, 0xc600, 4, 0 },
220 { D_F
, "mova\t@(0x%03X,pc),r0", 0xff00, 0xc700, 4, 0 },
221 { D_F
, "bf\t0x%08X", 0xff00, 0x8b00, 5, 0 },
222 { D_F
, "bf/s\t0x%08X", 0xff00, 0x8f00, 5, 1 },
223 { D_F
, "bt\t0x%08X", 0xff00, 0x8900, 5, 0 },
224 { D_F
, "bt/s\t0x%08X", 0xff00, 0x8d00, 5, 1 },
225 { D12_F
, "bra\t0x%08X", 0xf000, 0xa000, 0, 0 },
226 { D12_F
, "bsr\t0x%08X", 0xf000, 0xb000, 0, 0 },
227 { ND8_F
, "mov.w\t@(0x%03X,pc),r%d", 0xf000, 0x9000, 2, 0 },
228 { ND8_F
, "mov.l\t@(0x%03X,pc),r%d", 0xf000, 0xd000, 4, 0 },
229 { I_F
, "and.b\t#0x%02X,@(r0,gbr)", 0xff00, 0xcd00, 0,0 },
230 { I_F
, "or.b\t#0x%02X,@(r0,gbr)", 0xff00, 0xcf00, 0,0 },
231 { I_F
, "tst.b\t#0x%02X,@(r0,gbr)", 0xff00, 0xcc00, 0,0 },
232 { I_F
, "xor.b\t#0x%02X,@(r0,gbr)", 0xff00, 0xce00, 0,0 },
233 { I_F
, "and\t#0x%02X,r0", 0xff00, 0xc900, 0, 0 },
234 { I_F
, "cmp/eq\t#0x%02X,r0", 0xff00, 0x8800, 0, 0 },
235 { I_F
, "or\t#0x%02X,r0", 0xff00, 0xcb00, 0, 0 },
236 { I_F
, "tst\t#0x%02X,r0", 0xff00, 0xc800, 0, 0 },
237 { I_F
, "xor\t#0x%02X,r0", 0xff00, 0xca00, 0, 0 },
238 { I_F
, "trapa\t#0x%X", 0xff00, 0xc300, 0, 0 },
239 { NI_F
, "add\t#0x%02X,r%d", 0xf000, 0x7000, 0, 0 },
240 { NI_F
, "mov\t#0x%02X,r%d", 0xf000, 0xe000, 0, 0 },
241 { 0, NULL
, 0, 0, 0, 0 }
245 int FindOption(char *option
, int p
, int h
, int u
, int argc
, char **argv
)
247 static int t
[] = { 0, 0, 0, 0, 0, 0, 0, 0,
248 0, 0, 0, 0, 0, 0, 0, 0,
249 0, 0, 0, 0, 0, 0, 0, 0,
250 0, 0, 0, 0, 0, 0, 0, 0,
251 0, 0, 0, 0, 0, 0, 0, 0,
252 0, 0, 0, 0, 0, 0, 0, 0,
253 0, 0, 0, 0, 0, 0, 0, 0,
254 0, 0, 0, 0, 0, 0, 0, 0,
255 0, 0, 0, 0, 0, 0, 0, 0,
256 0, 0, 0, 0, 0, 0, 0, 0,
257 0, 0, 0, 0, 0, 0, 0, 0,
258 0, 0, 0, 0, 0, 0, 0, 0,
259 0, 0, 0, 0, 0, 0, 0, 0,
260 0, 0, 0, 0, 0, 0, 0, 0,
261 0, 0, 0, 0, 0, 0, 0, 0,
262 0, 0, 0, 0, 0, 0, 0, 0 };
267 argc
= 128; /* maximum this function can handle is 128 */
270 * if p = 1 and h = 0 will find option and return decimal value of
271 * argv[i+1], if h = 1 will read it as hex.
272 * if p = 0 then it will return index of option in argv[], 0 not found
273 * if u = 1 will return index of first occurance of untouched option
276 if (u
) /* find first untouched element */
278 for (i
= 1; i
< argc
; i
++)
280 if (!t
[i
]) /* 0 indicates untouched */
286 if (p
) /* find option and return integer value following it */
288 for (i
= 1; i
< argc
; i
++)
290 if (strcmp(argv
[i
], option
) == 0) /* found */
292 if (i
>= argc
) /* bounds! */
294 t
[i
+ 1] = t
[i
] = 1; /* touched */
296 return atoi(argv
[i
+ 1]);
298 return strtoul(argv
[i
+ 1], &c
, 16);
301 return 0; /* no match */
303 else /* find option and return position */
305 for (i
= 1; i
< argc
; i
++)
307 if (strcmp(argv
[i
], option
) == 0)
310 return i
; /* found! return position */
318 * SH2Disasm(): SH-1/SH-2 disassembler routine. If mode = 0 then SH-2 mode,
319 * otherwise SH-1 mode
322 void SH2Disasm(unsigned v_addr
, unsigned char *p_addr
, int mode
, char *m_addr
)
327 op
= (unsigned short) (*p_addr
<< 8) | *(p_addr
+ 1);
328 printf("0x%08X: 0x%04X\t", v_addr
, op
);
330 if (m_addr
[0]==ND8_F
)
334 unsigned int tmp
= (op
<< 16) | ((unsigned int) (p_addr
[2] << 8) | p_addr
[3]);
335 printf(".long\t0x%08X\t; 0x%08X",tmp
,v_addr
- (unsigned)m_addr
[1]);
338 printf(".short\t0x%08X\t; 0x%08X",op
,v_addr
- (unsigned)m_addr
[1]);
340 else if (m_addr
[0] != -1)
342 for (i
= 0; tab
[i
].mnem
!= NULL
; i
++) /* 0 format */
344 if ((op
& tab
[i
].mask
) == tab
[i
].bits
)
346 if (tab
[i
].sh2
&& mode
) /* if SH-1 mode, no SH-2 */
348 else if (tab
[i
].format
== ZERO_F
)
349 printf("%s", tab
[i
].mnem
);
350 else if (tab
[i
].format
== N_F
)
351 printf(tab
[i
].mnem
, (op
>> 8) & 0xf);
352 else if (tab
[i
].format
== M_F
)
353 printf(tab
[i
].mnem
, (op
>> 8) & 0xf);
354 else if (tab
[i
].format
== NM_F
)
355 printf(tab
[i
].mnem
, (op
>> 4) & 0xf,
357 else if (tab
[i
].format
== MD_F
)
360 printf(tab
[i
].mnem
, (op
& 0xf) * 2,
363 printf(tab
[i
].mnem
, op
& 0xf,
366 else if (tab
[i
].format
== ND4_F
)
369 printf(tab
[i
].mnem
, (op
& 0xf) * 2,
372 printf(tab
[i
].mnem
, (op
& 0xf),
375 else if (tab
[i
].format
== NMD_F
)
377 if ((op
& 0xf000) == 0x1000)
378 printf(tab
[i
].mnem
, (op
>> 4) & 0xf,
382 printf(tab
[i
].mnem
, (op
& 0xf) * 4,
386 else if (tab
[i
].format
== D_F
)
390 if ((op
& 0xff00) == 0xc700)
407 if (op
& 0x80) /* sign extend */
419 else if (tab
[i
].format
== D12_F
)
421 if (op
& 0x800) /* sign extend */
423 ((op
& 0xfff) + 0xfffff000) * 2
426 printf(tab
[i
].mnem
, (op
& 0xfff) * 2 +
429 else if (tab
[i
].format
== ND8_F
)
431 int imm
= (op
& 0xff) * tab
[i
].dat
+ 4;
432 if ((op
& 0xf000) == 0x9000) /* .W */
434 int dat
= (unsigned short) (*(imm
+ p_addr
) << 8) | *(imm
+ p_addr
+ 1);
435 m_addr
[imm
+0] = ND8_F
; /* this couldn't be an instruction so mark it ! */
440 printf("\t; 0x%08X (0x%04X)",
445 unsigned char *b_addr
= (unsigned char *)((intptr_t)p_addr
& ~3);
446 int dat
= (unsigned int) (*(imm
+ b_addr
) << 24) | (*(imm
+ b_addr
+ 1) << 16)
447 | (*(imm
+ b_addr
+ 2) << 8) | *(imm
+ b_addr
+ 3) ;
448 /* SH-1 register name lookup */
450 if ( (dat
& 0xfffffe00) == 0x05fffe00 )
451 str
= regname
[dat
& 0x1ff];
452 m_addr
[imm
+(b_addr
-p_addr
)+0] = ND8_F
; /* this couldn't be an instruction so mark it ! */
453 m_addr
[imm
+(b_addr
-p_addr
)+1] = imm
;
454 m_addr
[imm
+(b_addr
-p_addr
)+2] = -1;
458 printf("\t; 0x%08X (0x%08X) %s",
459 imm
+ (v_addr
& 0xfffffffc), dat
, str
);
462 else if (tab
[i
].format
== I_F
)
463 printf(tab
[i
].mnem
, op
& 0xff);
464 else if (tab
[i
].format
== NI_F
)
465 printf(tab
[i
].mnem
, op
& 0xff, (op
>> 8) &
482 printf("sh2d Version %s by Bart Trzynadlowski: A Free SH-1/SH-2 "
483 "Disassembler\n", VERSION
);
484 printf("Usage: sh2d <file> [options]\n");
485 printf("Options: -?,-h Show this help text\n");
486 printf(" -s # Start offset (hexadecimal)\n");
487 printf(" -l # Number of bytes (decimal)\n");
488 printf(" -o # Set origin (hexadecimal)\n");
489 printf(" -sh1 SH-1 disassembly only\n");
490 printf(" -sh2 SH-2 disassembly (default)\n");
494 int main(int argc
, char **argv
)
497 long fsize
, file
, mode
;
498 unsigned start
, len
, calc_len
= 0, org
, do_org
, i
, j
= 0;
502 if (argc
== 1) /* show help */
504 if (FindOption("-?", 0, 0, 0, argc
, argv
) ||
505 FindOption("-h", 0, 0, 0, argc
, argv
))
508 if (FindOption("-sh1", 0, 0, 0, argc
, argv
))
509 mode
= 1; /* SH-1 mode */
511 mode
= 0; /* SH-2 mode */
512 if (FindOption("-sh2", 0, 0, 0, argc
, argv
))
513 mode
= 0; /* SH-2 mode */
515 start
= FindOption("-s", 1, 1, 0, argc
, argv
);
516 org
= FindOption("-o", 1, 1, 0, argc
, argv
);
517 if (!(len
= FindOption("-l", 1, 0, 0, argc
, argv
)))
519 if (FindOption("-l", 0, 0, 0, argc
, argv
))
520 return 0; /* -l was actually specified w/ 0 */
521 calc_len
= 1; /* no -l, calculate length */
524 if (FindOption("-o", 0, 0, 0, argc
, argv
))
525 do_org
= 1; /* -o was actually 0 */
527 do_org
= 0; /* there was no -o, ignore the org variable */
529 if (!(file
= FindOption(NULL
, 0, 0, 1, argc
, argv
)))
531 fprintf(stderr
, "sh2d: No input file specified. Try "
532 "\"sh2d -h\" for usage instructions\n");
536 if ((fp
= fopen(argv
[file
], "rb")) == NULL
)
538 fprintf(stderr
, "sh2d: Failed to open file: %s\n",
542 fseek(fp
, 0, SEEK_END
);
545 if ((buffer
= (char *) calloc(fsize
* 2, sizeof(unsigned short)))
548 fprintf(stderr
, "sh2d: Not enough memory to load input "
549 "file: %s, %lu bytes\n", argv
[file
], fsize
);
552 fread(buffer
, sizeof(unsigned char), fsize
, fp
);
558 mark
= buffer
+ fsize
;
560 for (i
= start
; i
< (unsigned) fsize
&& j
< len
; i
+= 2)
564 SH2Disasm(org
, (unsigned char*)&buffer
[i
], mode
, &mark
[i
]);
568 SH2Disasm(i
, (unsigned char *)&buffer
[i
], mode
, &mark
[i
]);