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