1 /* Generator is (c) James Ponder, 1997-2001 http://www.squish.net/generator/ */
2 
3 #include <stdio.h>
4 #include <string.h>
5 #include <ctype.h>
6 
7 #include "generator.h"
8 #include "cpu68k.h"
9 
10 /* forward references */
11 
12 void diss68k_getoperand(char *text, t_ipc * ipc, t_iib * iib, t_type type);
13 
14 /* functions */
15 
diss68k_gettext(t_ipc * ipc,char * text)16 int diss68k_gettext(t_ipc * ipc, char *text)
17 {
18   t_iib *iib;
19   char *p;
20   const char *c;
21   char src[64], dst[64];
22   char mnemonic[64];
23 
24   *text = '\0';
25 
26   iib = cpu68k_iibtable[ipc->opcode];
27 
28   if (iib == NULL)
29     return 0;
30 
31   diss68k_getoperand(dst, ipc, iib, tp_dst);
32   diss68k_getoperand(src, ipc, iib, tp_src);
33 
34   if ((iib->mnemonic == i_Bcc) || (iib->mnemonic == i_BSR) ||
35       (iib->mnemonic == i_DBcc)) {
36     sprintf(src, "$%08x", (unsigned)ipc->src);
37   }
38 
39   strcpy(mnemonic, mnemonic_table[iib->mnemonic].name);
40 
41   if ((p = strstr(mnemonic, "cc")) != NULL) {
42     if (iib->mnemonic == i_Bcc && iib->cc == 0) {
43       p[0] = 'R';
44       p[1] = 'A';
45     } else {
46       c = condition_table[iib->cc];
47       strcpy(p, c);
48     }
49   }
50 
51   switch (iib->size) {
52   case sz_byte:
53     strcat(mnemonic, ".B");
54     break;
55   case sz_word:
56     strcat(mnemonic, ".W");
57     break;
58   case sz_long:
59     strcat(mnemonic, ".L");
60     break;
61   default:
62     break;
63   }
64 
65   sprintf(text, "%-10s %s%s%s %d", mnemonic, src, dst[0] ? "," : "", dst,iib->funcnum);
66 
67   return 1;
68 }
69 
diss68k_getoperand(char * text,t_ipc * ipc,t_iib * iib,t_type type)70 void diss68k_getoperand(char *text, t_ipc * ipc, t_iib * iib, t_type type)
71 {
72   int bitpos;
73   uint32 val;
74 
75   if (type == tp_src) {
76     bitpos = iib->sbitpos;
77     val = ipc->src;
78   } else {
79     bitpos = iib->dbitpos;
80     val = ipc->dst;
81   }
82 
83   switch (type == tp_src ? iib->stype : iib->dtype) {
84   case dt_Dreg:
85     sprintf(text, "D%d", (ipc->opcode >> bitpos) & 7);
86     break;
87   case dt_Areg:
88     sprintf(text, "A%d", (ipc->opcode >> bitpos) & 7);
89     break;
90   case dt_Aind:
91     sprintf(text, "(A%d)", (ipc->opcode >> bitpos) & 7);
92     break;
93   case dt_Ainc:
94     sprintf(text, "(A%d)+", (ipc->opcode >> bitpos) & 7);
95     break;
96   case dt_Adec:
97     sprintf(text, "-(A%d)", (ipc->opcode >> bitpos) & 7);
98     break;
99   case dt_Adis:
100     sprintf(text, "$%04x(A%d)", (uint16)val, (ipc->opcode >> bitpos) & 7);
101     break;
102   case dt_Aidx:
103     sprintf(text, "$%02x(A%d,Rx.X)", (uint8)val, (ipc->opcode >> bitpos) & 7);
104     break;
105   case dt_AbsW:
106     sprintf(text, "$%08x", (unsigned)val);
107     break;
108   case dt_AbsL:
109     sprintf(text, "$%08x", (unsigned)val);
110     break;
111   case dt_Pdis:
112     sprintf(text, "$%08x(pc)", (unsigned)val);
113     break;
114   case dt_Pidx:
115     sprintf(text, "$%08x(pc, Rx.X)", (unsigned)val);
116     break;
117   case dt_ImmB:
118     sprintf(text, "#$%02x", (unsigned)val);
119     break;
120   case dt_ImmW:
121     sprintf(text, "#$%04x", (unsigned)val);
122     break;
123   case dt_ImmL:
124     sprintf(text, "#$%08x", (unsigned)val);
125     break;
126   case dt_ImmS:
127     sprintf(text, "#%d", iib->immvalue);
128     break;
129   case dt_Imm3:
130     sprintf(text, "#%d", (ipc->opcode >> bitpos) & 7);
131     break;
132   case dt_Imm4:
133     sprintf(text, "#%d", (ipc->opcode >> bitpos) & 15);
134     break;
135   case dt_Imm8:
136     sprintf(text, "#%d", (ipc->opcode >> bitpos) & 255);
137     break;
138   case dt_Imm8s:
139     sprintf(text, "#%d", (signed int)val);
140     break;
141   default:
142     strcpy(text, "");
143     break;
144   }
145 }
146 
diss68k_getdumpline(uint32 addr68k,uint8 * addr,char * dumpline)147 int diss68k_getdumpline(uint32 addr68k, uint8 *addr, char *dumpline)
148 {
149   t_ipc ipc;
150   t_iib *iibp = cpu68k_iibtable[LOCENDIAN16(*(uint16 *)addr)];
151   int words, i;
152   char dissline[64], *p;
153 
154   if (addr68k < 256) {
155     sprintf(dissline, "dc.l $%08x", (unsigned)LOCENDIAN32(*(uint32 *)addr));
156     words = 2;
157   } else {
158     cpu68k_ipc(addr68k, addr, iibp, &ipc);
159     if (!diss68k_gettext(&ipc, dissline))
160       strcpy(dissline, "Illegal Instruction");
161     words = ipc.wordlen;
162   }
163 
164   p = dumpline;
165   p += sprintf(p, "%6x : %04x ", (unsigned)addr68k, (addr[0] << 8) + addr[1]);
166   for (i = 1; i < words; i++) {
167     p += sprintf(p, "%04x ", (addr[i * 2] << 8) + addr[i * 2 + 1]);
168   }
169   for (i = 29 - strlen(dumpline); i > 0; i--) {
170     *p++ = ' ';
171   }
172   p += sprintf(p, ": ");
173   for (i = 0; i < words; i++) {
174     if (isalnum(addr[i * 2])) {
175       *p++ = addr[i * 2];
176     } else
177       *p++ = '.';
178     if (isalnum(addr[i * 2 + 1])) {
179       *p++ = addr[i * 2 + 1];
180     } else
181       *p++ = '.';
182   }
183   *p = '\0';
184   for (i = 39 - strlen(dumpline); i > 0; i--) {
185     *p++ = ' ';
186   }
187   if (iibp) {
188     sprintf(p, " : %4d : %s\n", iibp->funcnum, dissline);
189   } else {
190     sprintf(p, " :      : %s\n", dissline);
191   }
192 
193   return words;
194 }
195