summaryrefslogtreecommitdiff
path: root/tools/sh2d.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/sh2d.c')
-rw-r--r--tools/sh2d.c573
1 files changed, 0 insertions, 573 deletions
diff --git a/tools/sh2d.c b/tools/sh2d.c
deleted file mode 100644
index 0fcf8b1f6b..0000000000
--- a/tools/sh2d.c
+++ /dev/null
@@ -1,573 +0,0 @@
1/*
2 * sh2d
3 * Bart Trzynadlowski, July 24, 2000
4 * Public domain
5 *
6 * Some changes by Björn Stenberg <bjorn@haxx.se>
7 * $Id$
8 */
9
10
11#include <stdint.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15
16#define VERSION "0.2"
17
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 */
30
31typedef struct
32{
33 int format;
34 const char *mnem;
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 */
39} i_descr;
40
41/* register name lookup added by bjorn@haxx.se 2001-12-09 */
42char* regname[] =
43{
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 */
57
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 "","","","","","","",""
95};
96
97i_descr tab[] =
98{
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 }
242};
243
244
245int FindOption(char *option, int p, int h, int u, int argc, char **argv)
246{
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 };
263 int i;
264 char *c;
265
266 if (argc > 128)
267 argc = 128; /* maximum this function can handle is 128 */
268
269 /*
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
274 */
275
276 if (u) /* find first untouched element */
277 {
278 for (i = 1; i < argc; i++)
279 {
280 if (!t[i]) /* 0 indicates untouched */
281 return i;
282 }
283 return 0;
284 }
285
286 if (p) /* find option and return integer value following it */
287 {
288 for (i = 1; i < argc; i++)
289 {
290 if (strcmp(argv[i], option) == 0) /* found */
291 {
292 if (i >= argc) /* bounds! */
293 return 0;
294 t[i + 1] = t[i] = 1; /* touched */
295 if (!h)
296 return atoi(argv[i + 1]);
297 else
298 return strtoul(argv[i + 1], &c, 16);
299 }
300 }
301 return 0; /* no match */
302 }
303 else /* find option and return position */
304 {
305 for (i = 1; i < argc; i++)
306 {
307 if (strcmp(argv[i], option) == 0)
308 {
309 t[i] = 1;
310 return i; /* found! return position */
311 }
312 }
313 return 0;
314 }
315}
316
317/*
318 * SH2Disasm(): SH-1/SH-2 disassembler routine. If mode = 0 then SH-2 mode,
319 * otherwise SH-1 mode
320 */
321
322void SH2Disasm(unsigned v_addr, unsigned char *p_addr, int mode, char *m_addr)
323 {
324 int i;
325 unsigned short op;
326
327 op = (unsigned short) (*p_addr << 8) | *(p_addr + 1);
328 printf("0x%08X: 0x%04X\t", v_addr, op);
329
330 if (m_addr[0]==ND8_F)
331 {
332 if (m_addr[2]==-1)
333 {
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]);
336 }
337 else
338 printf(".short\t0x%08X\t; 0x%08X",op,v_addr - (unsigned)m_addr[1]);
339 }
340 else if (m_addr[0] != -1)
341 {
342 for (i = 0; tab[i].mnem != NULL; i++) /* 0 format */
343 {
344 if ((op & tab[i].mask) == tab[i].bits)
345 {
346 if (tab[i].sh2 && mode) /* if SH-1 mode, no SH-2 */
347 printf("???");
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,
356 (op >> 8) & 0xf);
357 else if (tab[i].format == MD_F)
358 {
359 if (op & 0x100)
360 printf(tab[i].mnem, (op & 0xf) * 2,
361 (op >> 4) & 0xf);
362 else
363 printf(tab[i].mnem, op & 0xf,
364 (op >> 4) & 0xf);
365 }
366 else if (tab[i].format == ND4_F)
367 {
368 if (op & 0x100)
369 printf(tab[i].mnem, (op & 0xf) * 2,
370 (op >> 4) & 0xf);
371 else
372 printf(tab[i].mnem, (op & 0xf),
373 (op >> 4) & 0xf);
374 }
375 else if (tab[i].format == NMD_F)
376 {
377 if ((op & 0xf000) == 0x1000)
378 printf(tab[i].mnem, (op >> 4) & 0xf,
379 (op & 0xf) * 4,
380 (op >> 8) & 0xf);
381 else
382 printf(tab[i].mnem, (op & 0xf) * 4,
383 (op >> 4) & 0xf,
384 (op >> 8) & 0xf);
385 }
386 else if (tab[i].format == D_F)
387 {
388 if (tab[i].dat <= 4)
389 {
390 if ((op & 0xff00) == 0xc700)
391 {
392 printf(tab[i].mnem,
393 (op & 0xff) *
394 tab[i].dat + 4);
395 printf("\t; 0x%08X",
396 (op & 0xff) *
397 tab[i].dat + 4 +
398 v_addr);
399 }
400 else
401 printf(tab[i].mnem,
402 (op & 0xff) *
403 tab[i].dat);
404 }
405 else
406 {
407 if (op & 0x80) /* sign extend */
408 printf(tab[i].mnem,
409 (((op & 0xff) +
410 0xffffff00) * 2) +
411
412 v_addr + 4);
413 else
414 printf(tab[i].mnem,
415 ((op & 0xff) * 2) +
416 v_addr + 4);
417 }
418 }
419 else if (tab[i].format == D12_F)
420 {
421 if (op & 0x800) /* sign extend */
422 printf(tab[i].mnem,
423 ((op & 0xfff) + 0xfffff000) * 2
424 + v_addr + 4);
425 else
426 printf(tab[i].mnem, (op & 0xfff) * 2 +
427 v_addr + 4);
428 }
429 else if (tab[i].format == ND8_F)
430 {
431 int imm = (op & 0xff) * tab[i].dat + 4;
432 if ((op & 0xf000) == 0x9000) /* .W */
433 {
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 ! */
436 m_addr[imm+1] = imm;
437 printf(tab[i].mnem,
438 imm,
439 (op >> 8) & 0xf);
440 printf("\t; 0x%08X (0x%04X)",
441 imm + v_addr, dat);
442 }
443 else /* .L */
444 {
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 */
449 char* str = "";
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;
455 printf(tab[i].mnem,
456 imm,
457 (op >> 8) & 0xf);
458 printf("\t; 0x%08X (0x%08X) %s",
459 imm + (v_addr & 0xfffffffc), dat, str);
460 }
461 }
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) &
466 0xf);
467 else
468 printf("???");
469 printf("\n");
470 return;
471 }
472 }
473
474 printf("???");
475
476 }
477 printf("\n");
478 }
479
480void ShowHelp()
481{
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");
491 exit(0);
492}
493
494int main(int argc, char **argv)
495{
496 FILE *fp;
497 long fsize, file, mode;
498 unsigned start, len, calc_len = 0, org, do_org, i, j = 0;
499 char *buffer;
500 char *mark;
501
502 if (argc == 1) /* show help */
503 ShowHelp();
504 if (FindOption("-?", 0, 0, 0, argc, argv) ||
505 FindOption("-h", 0, 0, 0, argc, argv))
506 ShowHelp();
507
508 if (FindOption("-sh1", 0, 0, 0, argc, argv))
509 mode = 1; /* SH-1 mode */
510 else
511 mode = 0; /* SH-2 mode */
512 if (FindOption("-sh2", 0, 0, 0, argc, argv))
513 mode = 0; /* SH-2 mode */
514
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)))
518 {
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 */
522 }
523
524 if (FindOption("-o", 0, 0, 0, argc, argv))
525 do_org = 1; /* -o was actually 0 */
526 else
527 do_org = 0; /* there was no -o, ignore the org variable */
528
529 if (!(file = FindOption(NULL, 0, 0, 1, argc, argv)))
530 {
531 fprintf(stderr, "sh2d: No input file specified. Try "
532 "\"sh2d -h\" for usage instructions\n");
533 exit(1);
534 }
535
536 if ((fp = fopen(argv[file], "rb")) == NULL)
537 {
538 fprintf(stderr, "sh2d: Failed to open file: %s\n",
539 argv[file]);
540 exit(1);
541 }
542 fseek(fp, 0, SEEK_END);
543 fsize = ftell(fp);
544 rewind(fp);
545 if ((buffer = (char *) calloc(fsize * 2, sizeof(unsigned short)))
546 == NULL)
547 {
548 fprintf(stderr, "sh2d: Not enough memory to load input "
549 "file: %s, %lu bytes\n", argv[file], fsize);
550 exit(1);
551 }
552 fread(buffer, sizeof(unsigned char), fsize, fp);
553 fclose(fp);
554
555 if (calc_len)
556 len = fsize - start;
557
558 mark = buffer + fsize;
559
560 for (i = start; i < (unsigned) fsize && j < len; i += 2)
561 {
562 if (do_org)
563 {
564 SH2Disasm(org, (unsigned char*)&buffer[i], mode, &mark[i]);
565 org += 2;
566 }
567 else
568 SH2Disasm(i, (unsigned char *)&buffer[i], mode, &mark[i]);
569 j += 2;
570 }
571
572 return 0;
573}