ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_68k.cpp
Revision: 1.3
Committed: 1999-10-05T14:43:43Z (25 years, 1 month ago) by cebix
Branch: MAIN
Changes since 1.2: +3 -5 lines
Log Message:
- fixed some compiler warnings
- sorted mon_atraps.h

File Contents

# User Rev Content
1 cebix 1.1 /*
2     * mon_m68k.cpp - 68k disassembler
3     *
4 cebix 1.2 * mon (C) 1997-1999 Christian Bauer, Marc Hellwig
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 cebix 1.1 */
20    
21     /*
22 cebix 1.2 * TODO
23     * - add missing f-lines
24     * - MULx.L/DIVx.L
25     * - use tab instead of spaces
26 cebix 1.1 */
27 cebix 1.2
28     #include "sysdeps.h"
29 cebix 1.1
30     #include "mon.h"
31     #include "mon_68k.h"
32     #include "mon_atraps.h"
33    
34     enum t_size {BYTE, WORD, LONG, NOSIZE, BYTE_SILENT, WORD_SILENT, LONG_SILENT}; // "silent" means "don't append size qualifier to opcode"
35     enum t_errors {ER_UNKNOWN_ADDRESS_MODE, ER_UNKNOWN_OPCODE, ER_ILLEGAL_OPCODE};
36     enum t_address {AD_C=1000, AD_BRANCH, AD_MULT, AD_DATA, AD_DATA_IMM, AD_CACHE};
37    
38     static void error(t_errors code);
39     static int8 read_int8(void);
40     static uint16 read_uint16(void);
41     static int16 read_int16(void);
42     static int32 read_int32(void);
43     static void parse ();
44     static void add_int32_str (char *old,int32 value);
45     static void add_int16_str (char *old,int16 value);
46     static void add_int8_str (char *old,int8 value);
47     static void add_dec_int_str (char *old,int32 value);
48     static void print_range (int from,int to);
49     static int decode_address_mode (uint16 eee,uint16 aaa,t_size size);
50     static void diss (char *ndest,uint16 *nmem,int &npos,unsigned int adr);
51    
52     enum t_control {C_UNKNOWN,C_SR,C_CCR,C_SFC,C_DFC,C_CACR,C_TC,C_ITT0,C_ITT1,C_DTT0,C_DTT1,C_BUSCR,C_USP,C_VBR,C_CAAR,C_MSP,C_ISP,C_MMUSR,C_URP,C_SRP,C_PCR};
53     static char *con_str[]={"???","sr","ccr","sfc","dfc","cacr","tc","itt0","itt1","dtt0","dtt1","buscr","usp","vbr","caar","msp","isp","mmusr","urp","srp","pcr"};
54     static char *cc_str[]= {"t","f","hi","ls","cc","cs","ne","eq","vc","vs","pl",
55     "mi","ge","lt","gt","le","ra","sr"};
56     static uint16 opcode;
57     static uint16 source_eee;
58     static uint16 source_aaa;
59     static uint16 dest_eee;
60     static uint16 dest_aaa;
61     static int32 data_val;
62     static uint16 mask; // for movem !!! aaarrrggglll ...
63     static t_size size;
64     static int count_param;
65     static uint16 *mem;
66     static int mem_pos;
67     static char *dest;
68     static char op_name[50];
69     static unsigned int adr_off;
70    
71     static void error (t_errors code) {
72     switch (code) {
73     case ER_UNKNOWN_ADDRESS_MODE:
74     printf ("unknown address mode\n");
75     break;
76     case ER_UNKNOWN_OPCODE:
77     printf ("unknown opcode\n");
78     break;
79     case ER_ILLEGAL_OPCODE:
80     printf ("illegal opcode\n");
81     break;
82     default:
83     printf ("general error\n");
84     }
85     }
86    
87     static int8 read_int8(void) {
88     return mem[mem_pos++];
89     }
90    
91     static uint16 read_uint16(void) {
92     return mem[mem_pos++];
93     }
94    
95     static int16 read_int16(void) {
96     return (int16)(mem[mem_pos++]);
97     }
98    
99     static int32 read_int32(void) {
100     int32 val = (mem[mem_pos] << 16) | mem[mem_pos+1];
101     mem_pos+=2;
102     return val;
103     }
104    
105     // opcode table
106     #define def_param(n,c,s,se,sa,de,da) \
107     strcpy(op_name,n);\
108     count_param=c;\
109     size=s;\
110     source_eee=se;\
111     source_aaa=sa;\
112     dest_eee=de;\
113     dest_aaa=da;
114     #define no_param(n) \
115     def_param(n,0,NOSIZE,0,0,0,0)
116     #define bits(pos,count) ((opcode >> pos)&((1<<count)-1))
117     #define mshort(s) \
118     if (bits(6,3)==1) \
119     {def_param("movea",2,s,bits(3,3),bits(0,3),1,bits(9,3))}\
120     else\
121     {def_param("move",2,s,bits(3,3),bits(0,3),bits(6,3),bits(9,3))}
122     #define imshort(n) \
123     if (bits(6,2)<2) data_val = read_int16(); else data_val = read_int32();\
124     def_param(n,2,(t_size)bits(6,2),AD_DATA_IMM,0,bits(3,3),bits(0,3))
125     #define imshortcs(n) \
126     switch (bits(0,8)) { \
127     case 0x3c: \
128     data_val = read_int16();\
129     def_param(n,2,BYTE_SILENT,AD_DATA_IMM,0,AD_C,C_CCR) break; \
130     case 0x7c: \
131     data_val = read_int16();\
132     def_param(n,2,WORD_SILENT,AD_DATA_IMM,0,AD_C,C_SR) break; \
133     break; \
134     default: \
135     imshort(n) \
136     break;\
137     }
138     #define addshort(n) \
139     if (bits(8,1)==0)\
140     {def_param(n,2,(t_size)bits(6,2),bits(3,3),bits(0,3),0,bits(9,3))}\
141     else\
142     {def_param(n,2,(t_size)bits(6,2),0,bits(9,3),bits(3,3),bits(0,3))}
143     #define addxshort(n) \
144     if (bits(3,1)==0) {\
145     def_param(n,2,(t_size)bits(6,2),0,bits(0,3),0,bits(9,3))\
146     } else {\
147     def_param(n,2,(t_size)bits(6,2),4,bits(0,3),4,bits(9,3))\
148     }
149     #define addashort(n) \
150     def_param(n,2,NOSIZE,bits(3,3),bits(0,3),1,bits(9,3))\
151     if (bits(8,1)==0) size=WORD; else size=LONG;
152     #define deashort(n) \
153     def_param(n,2,(t_size)bits(6,2),0,bits(9,3),bits(3,3),bits(0,3))
154     #define bitshort(n) \
155     def_param(n,2,BYTE_SILENT,AD_DATA_IMM,0,bits(3,3),bits(0,3))\
156     data_val=read_int8();
157     #define bitdynshort(n) \
158     def_param(n,2,BYTE_SILENT,0,bits(9,3),bits(3,3),bits(0,3))
159     #define prwshort(n) \
160     if (((op2 >> 9) & 1)==1) \
161     {def_param(n,2,LONG,AD_C,C_UNKNOWN,bits(3,3),bits(0,3))}\
162     else\
163     {def_param(n,2,LONG,bits(3,3),bits(0,3),AD_C,C_UNKNOWN)}
164     #define mshiftshort(n) \
165     def_param(n,1,WORD,bits(3,3),bits(0,3),0,0)\
166     if (bits(8,1)==0) {\
167     strcat(op_name,"r");\
168     } else {\
169     strcat(op_name,"l");\
170     }
171     #define rshiftshort(n) \
172     if (bits(5,1)==0) {\
173     data_val=bits(9,3);\
174     if (data_val==0) data_val=8;\
175     def_param(n,2,(t_size)bits(6,2),AD_DATA_IMM,0,0,bits(0,3))\
176     } else {\
177     def_param(n,2,(t_size)bits(6,2),0,bits(9,3) % 64,0,bits(0,3))\
178     }\
179     if (bits(8,1)==0) {\
180     strcat(op_name,"r");\
181     } else {\
182     strcat(op_name,"l");\
183     }
184     #define abcdshort(n) \
185     if (bits(3,1)==0) {\
186     def_param(n,2,BYTE,0,bits(0,3),0,bits(9,3))\
187     } else {\
188     def_param(n,2,BYTE,4,bits(0,3),4,bits(9,3))\
189     }
190     #define cinvpush(n) \
191     def_param(n,bits(3,2) == 3 ? 1 : 2,NOSIZE,AD_CACHE,bits(6,2),2,bits(0,3))\
192     switch (bits(3,2)) {\
193     case 1: strcat(op_name, "l"); break;\
194     case 2: strcat(op_name, "p"); break;\
195     case 3: strcat(op_name, "a"); count_param = 1;\
196     }
197    
198     static void parse () {
199     switch (bits(12,4)) {
200     case 0: // Bit Manipulation/MOVEP/Immediate
201     if (bits(8,1)==0) { // Immediate + Bit Manipulation static
202     if (bits(6,2)==3) { // RTM, CALLM, CMP2, CHK2, BSET, CAS2, CAS
203     switch (bits(9,3)) {
204     case 3: // RTM, CALLM
205     break;
206     case 0: case 1: case 2: // CMP2, CHK2
207     break;
208     case 4: // BSET !
209     bitshort("bset") break;
210     default: // CAS2, CAS
211     break;
212     }
213     } else {
214     switch (bits(9,3)) {
215     case 0: // ORI
216     imshortcs("ori") break;
217     case 1: // ANDI
218     imshortcs("andi") break;
219     case 2: // SUBI
220     imshort("subi") break;
221     case 3: // ADDI
222     imshort("addi") break;
223     case 4: // BTST, BCHG, BCLR static
224     switch (bits(6,2)) {
225     case 0: // BTST
226     bitshort("btst") break;
227     case 1: // BCHG
228     bitshort("bchg") break;
229     case 2: // BCLR
230     bitshort ("bclr") break;
231     }
232     break;
233     case 5: // EORI
234     imshortcs("eori"); break;
235     case 6: // CMPI
236     imshort("cmpi"); break;
237     case 7: // MOVES
238     break;
239     }
240     }
241     } else { // Bit Manipulation dynamic, MOVEP
242     if (bits(3,3)==1) { // MOVEP
243     if (bits(7,1)==0) { // MOVEP d(Ay),Dx
244     def_param("movep",2,NOSIZE,5,bits(0,3),0,bits(9,3))
245     } else { // MOVEP Dx,d(Ay)
246     def_param("movep",2,NOSIZE,0,bits(9,3),5,bits(0,3))
247     }
248     if (bits(6,1)==0) size=WORD; else size=LONG;
249     } else { // Bit Manipulation
250     switch (bits(6,2)) {
251     case 0: // BTST
252     bitdynshort("btst") break;
253     case 1: // BCHG
254     bitdynshort("bchg") break;
255     case 2: // BCLR
256     bitdynshort ("bclr") break;
257     case 3: // BSET
258     bitdynshort ("bset") break;
259     }
260     }
261     }
262     break;
263     case 1: // Move Byte
264     mshort(BYTE)
265     break;
266     case 2: // Move Long
267     mshort(LONG)
268     break;
269     case 3: // Move Word
270     mshort(WORD)
271     break;
272     case 4: // Miscellaneous
273     switch (bits(0,12)) { // First all fixed opcodes ...
274     case 0xcfa: // BGND
275     no_param("bgnd")
276     break;
277     case 0xafc: // ILLEGAL
278     no_param("illegal")
279     break;
280     case 0xe70: // RESET
281     no_param("reset")
282     break;
283     case 0xe71: // NOP
284     no_param("nop")
285     break;
286     case 0xe72: // STOP
287     data_val=read_int16();
288     def_param("stop",1,WORD_SILENT,AD_DATA_IMM,0,0,0) break;
289     case 0xe73: // RTE
290     no_param("rte")
291     break;
292     case 0xe74: // RTD
293     data_val=read_int16();
294     def_param("rtd",1,WORD_SILENT,AD_DATA,0,0,0) break;
295     case 0xe75: // RTS
296     no_param("rts")
297     break;
298     case 0xe76: // TRAPV
299     no_param("trapv")
300     break;
301     case 0xe77: // RTR
302     no_param("rtr")
303     break;
304     case 0xe7a: case 0xe7b: { // MOVEC
305     uint16 op2 = read_uint16();
306     uint16 val;
307     switch (op2 & 0xfff) {
308     case 0: val=C_SFC; break;
309     case 1: val=C_DFC; break;
310     case 2: val=C_CACR; break;
311     case 3: val=C_TC; break;
312     case 4: val=C_ITT0; break;
313     case 5: val=C_ITT1; break;
314     case 6: val=C_DTT0; break;
315     case 7: val=C_DTT1; break;
316     case 8: val=C_BUSCR; break;
317     case 0x800: val=C_USP; break;
318     case 0x801: val=C_VBR; break;
319     case 0x802: val=C_CAAR; break;
320     case 0x803: val=C_MSP; break;
321     case 0x804: val=C_ISP; break;
322     case 0x805: val=C_MMUSR; break;
323     case 0x806: val=C_URP; break;
324     case 0x807: val=C_SRP; break;
325     case 0x808: val=C_PCR; break;
326     default: val=C_UNKNOWN; break; // ERROR unknown control_reg
327     }
328     if (bits(0,1)==0) { // MOVEC Ctrl,AD
329     def_param("movec",2,NOSIZE,AD_C,val,((op2 >> 15) & 1),((op2 >> 12) & 7))
330     } else { // MOVEC AD,Ctrl
331     def_param("movec",2,NOSIZE,((op2 >> 15) & 1),((op2 >> 12) & 7),AD_C,val)
332     }
333     break;
334     }
335     default:
336     switch (bits(3,9)) {
337     case 0x110: case 0x118: // EXT maybe more ??? nicht ganz sauber
338     def_param("ext",1,((bits(6,2)==2) ? WORD : LONG),0,bits(0,3),0,0) break;
339     case 0x101: // LINK
340     data_val=read_int32();
341     def_param("link",2,LONG,1,bits(0,3),AD_DATA_IMM,0) break;
342     case 0x108: // SWAP
343     def_param("swap",1,NOSIZE,0,bits(0,3),0,0) break;
344     case 0x109: // BKPT
345     data_val=bits(0,3);
346     def_param("bkpt",1,BYTE,AD_DATA,0,0,0) break;
347     case 0x1c8: case 0x1c9: // TRAP
348     data_val=bits(0,4);
349     def_param("trap",1,BYTE,AD_DATA,0,0,0) break;
350     case 0x1ca: // LINK
351     data_val=read_int16();
352     def_param("link",2,WORD_SILENT,1,bits(0,3),AD_DATA_IMM,0) break;
353     case 0x1cb: // UNLK
354     def_param("unlk",1,NOSIZE,1,bits(0,3),0,0) break;
355     case 0x1cc: case 0x1cd: // MOVE USP
356     if (bits(3,1)==0) { // MOVE An,USP
357     def_param("move",2,LONG,1,bits(0,3),AD_C,C_USP)
358     } else { // MOVE USP,An
359     def_param("move",2,LONG,AD_C,C_USP,1,bits(0,3))
360     }
361     break;
362     default:
363     switch (bits(6,6)) {
364     case 3: // MOVE from SR
365     def_param("move",2,WORD_SILENT,AD_C,C_SR,bits(3,3),bits(0,3)) break;
366     case 0xb: // MOVE from CCR
367     def_param("move",2,WORD_SILENT,AD_C,C_CCR,bits(3,3),bits(0,3)) break;
368     case 0: case 1: case 2: // NEGX
369     def_param("negx",1,(t_size)bits(6,2),bits(3,3),bits(0,3),0,0) break;
370     case 8: case 9: case 0xa: // CLR
371     def_param("clr",1,(t_size)bits(6,2),bits(3,3),bits(0,3),0,0) break;
372     case 0x13: // MOVE to CCR
373     def_param("move",2,WORD_SILENT,bits(3,3),bits(0,3),AD_C,C_CCR) break;
374     case 0x10: case 0x11: case 0x12:// NEG
375     def_param("neg",1,(t_size)bits(6,2),bits(3,3),bits(0,3),0,0) break;
376     case 0x18: case 0x19: case 0x1a:// NOT
377     def_param("not",1,(t_size)bits(6,2),bits(3,3),bits(0,3),0,0) break;
378     case 0x1b: // MOVE to SR
379     def_param("move",2,WORD_SILENT,bits(3,3),bits(0,3),AD_C,C_SR) break;
380     case 0x20: // NBCD
381     def_param("nbcd",1,BYTE,bits(3,3),bits(0,3),0,0) break;
382     case 0x21: // PEA
383     def_param("pea",1,LONG,bits(3,3),bits(0,3),0,0) break;
384     case 0x2b: // TAS
385     def_param("tas",1,BYTE,bits(3,3),bits(0,3),0,0) break;
386     case 0x28: case 0x29: case 0x2a:// TST
387     def_param("tst",1,(t_size)bits(6,2),bits(3,3),bits(0,3),0,0) break;
388     case 0x30: // MULU, MULS, DIVU, DIVUL
389     //!!
390     break;
391     case 0x31: // DIVS, DIVSL
392     //!!
393     break;
394     case 0x3a: // JSR
395     def_param("jsr ",1,NOSIZE,bits(3,3),bits(0,3),0,0) break;
396     case 0x3b: // JMP
397     def_param("jmp ",1,NOSIZE,bits(3,3),bits(0,3),0,0) break;
398     case 0x22: case 0x23: case 0x32: case 0x33:// MOVEM
399     mask=read_uint16();
400     if (bits(10,1)!=0)
401     {def_param("movem",2,NOSIZE,bits(3,3),bits(0,3),AD_MULT,0)}
402     else
403     {def_param("movem",2,NOSIZE,AD_MULT,((bits(3,3)==4) ? 1 : 0),bits(3,3),bits(0,3))}
404     if (bits(6,1)==0) size=WORD; else size=LONG;
405     break;
406     default:
407     switch (bits(6,3)) {
408     case 7: // LEA
409     def_param("lea",2,NOSIZE,bits(3,3),bits(0,3),1,bits(9,3)) break;
410     case 0: case 2: case 4: case 6:// CHK -> possible error ! check !
411     def_param("chk",2,WORD,bits(3,3),bits(0,3),0,bits(9,3)) break;
412     default: // ERROR unknown opcode
413     break;
414     }
415     }
416     }
417     }
418     break;
419     case 5: // ADDQ/SUBQ/Scc/DBcc/TRAPcc
420     if (bits(6,2)==3) { // DBcc/TRAPcc/Scc
421     switch (bits(3,3)) {
422     case 1: // DBcc
423     def_param("db",2,WORD_SILENT,0,bits(0,3),AD_BRANCH,bits(8,4))
424     break;
425     case 7: // TRAPcc
426     // not yet implemented
427     break;
428     default: // Scc
429     def_param("s",1,BYTE,bits(3,3),bits(0,3),AD_BRANCH,bits(8,4))
430     }
431     } else { // ADDQ/SUBQ
432     if (bits(8,1)==0) { // ADDQ
433     data_val=bits(9,3);
434     def_param("addq",2,(t_size)bits(6,2),AD_DATA_IMM,0,bits(3,3),bits(0,3))
435     } else { // SUBQ
436     data_val=bits(9,3);
437     def_param("subq",2,(t_size)bits(6,2),AD_DATA_IMM,0,bits(3,3),bits(0,3))
438     }
439     }
440     break;
441     case 6: // Bcc/BSR/BRA
442     def_param("b",1,NOSIZE,AD_BRANCH,bits(0,8),AD_BRANCH,bits(8,4))
443     if (dest_aaa < 2) dest_aaa += 16; //Bcc -> BSR,BRA
444     switch (bits(0,8)) {
445     case 0: size = WORD; break;
446     case 0xff: size = LONG; break;
447     default: size = BYTE;
448     }
449     break;
450     case 7: // MOVEQ
451     data_val=bits(0,8);
452     def_param("moveq",2,BYTE_SILENT,AD_DATA_IMM,0,0,bits(9,3))
453     break;
454     case 8: // OR/DIV/SBCD
455     switch (bits(4,5)) {
456     case 0x10: // SBCD
457     abcdshort("sbcd") break;
458     case 0x14: // PACK
459     break;
460     case 0x18: // UNPK
461     break;
462     default:
463     switch (bits(6,3)) {
464     case 3: // DIVU/DIVUL
465     def_param("divu",2,WORD,bits(3,3),bits(0,3),0,bits(9,3)) break;
466     case 7: // DIVS/DIVSL
467     def_param("divs",2,WORD,bits(3,3),bits(0,3),0,bits(9,3)) break;
468     default: // OR
469     addshort("or")
470     break;
471     }
472     }
473     break;
474     case 9: // SUB/SUBX
475     if (bits(6,2)==3) { // SUBA
476     addashort("suba")
477     } else {
478     if ((bits(4,2)==0)&&(bits(8,1)==1)) {// SUBX
479     addxshort("subx")
480     } else { // SUB
481     addshort("sub")
482     }
483     }
484     break;
485     case 0xa: { // (Unassigned, Reserved)
486     int position = 0;
487     no_param("a-line")
488     while (atraps[position].word!=0) {
489     if (atraps[position].word == opcode) {
490     no_param(atraps[position].name)
491     break;
492     }
493     position++;
494     }
495     break;
496     }
497     case 0xb: // CMP/EOR
498     if (bits(6,2)==3) { // CMPA
499     def_param("cmpa",2,((bits(8,1)==0) ? WORD : LONG),bits(3,3),bits(0,3),1,bits(9,3))
500     } else {
501     if (bits(8,1)==1) { // CMPM/EOR
502     if (bits(3,3)==1) { // CMPM
503     def_param("cmpm",2,(t_size)bits(6,2),3,bits(0,3),3,bits(9,3))
504     } else { // EOR
505     deashort("eor")
506     }
507     } else { // CMP
508     deashort("cmp")
509     }
510     }
511     break;
512     case 0xc: // AND/MUL/ABCD/EXG
513     switch (bits(6,3)) {
514     case 3: // MULU
515     def_param("mulu",2,WORD,bits(3,3),bits(0,3),0,bits(9,3)) break;
516     case 7: // MULS
517     def_param("muls",2,WORD,bits(3,3),bits(0,3),0,bits(9,3)) break;
518     default: // ABCD/EXG/AND
519     if (bits(4,5)==0x10) { // ABCD
520     abcdshort("abcd")
521     } else { // EXG/AND
522     if ((bits(3,6)==0x28)||(bits(3,6)==0x29)||(bits(3,6)==0x31)) {//EXG
523     switch (bits(3,5)) {
524     case 8: def_param("exg",2,LONG,0,bits(0,3),0,bits(9,3)) break;
525     case 9: def_param("exg",2,LONG,1,bits(0,3),1,bits(9,3)) break;
526     case 0x11: def_param("exg",2,LONG,1,bits(0,3),0,bits(9,3)) break;
527     }
528     } else { // AND
529     addshort("and")
530     }
531     }
532     }
533     break;
534     case 0xd: // ADD/ADDX
535     if (bits(6,2)==3) { // ADDA
536     addashort("adda")
537     } else { // ADDX/ADD
538     if ((bits(4,2)==0)&&(bits(8,1)==1)) {// ADDX
539     addxshort("addx")
540     } else { // ADD
541     addshort("add")
542     }
543     }
544     break;
545     case 0xe: // Shift/Rotate/Bit Field
546     if (bits(6,2)==3) { // Mem Shift/Rotate, Bit Field
547     if (bits(11,1)==0) { // Mem Shift/Rotate
548     switch (bits(9,2)) {
549     case 0: // ASL/ASR
550     mshiftshort("as") break;
551     case 1: // LSL/LSR
552     mshiftshort("ls") break;
553     case 2: // ROXL/ROXR
554     mshiftshort("rox") break;
555     case 3: // ROL/ROR
556     mshiftshort ("ro") break;
557     }
558     } else { // Bit Field
559     switch (bits(8,3)) {
560     case 0: // BFTST
561     break;
562     case 1: // BFEXTU
563     break;
564     case 2: // BFCHG
565     break;
566     case 3: // BFEXTS
567     break;
568     case 4: // BFCLR
569     break;
570     case 5: // BFFFO
571     break;
572     case 6: // BFSET
573     break;
574     case 7: // BFINS
575     break;
576     }
577     }
578     } else { // Register Shift/Rotate
579     switch (bits(3,2)) {
580     case 0: // ASL/ASR
581     rshiftshort("as") break;
582     case 1: // LSL/LSR
583     rshiftshort("ls") break;
584     case 2: // ROXL/ROXR
585     rshiftshort("rox") break;
586     case 3: // ROL/ROR
587     rshiftshort("ro") break;
588     }
589     }
590     break;
591     case 0xf: // Coprocessor Interface/MC68040
592     // and CPU32 Extensions
593     switch (bits(6,6)) {
594     case 0: { // P...
595     uint16 op2 = read_uint16();
596     switch ((op2 >> 13) & 7) {
597     case 0: // PMOVE
598     prwshort("pmove") break;
599     case 1: // PLOAD/PVALID/PFLUSH
600     no_param("pload/pvalid/pflush") break;
601     case 2: // PMOVE
602     prwshort ("pmove") break;
603     case 3: // PMOVE
604     prwshort ("pmove") break;
605     case 4: // PTST
606     prwshort ("ptest") break;
607     case 5: // PFLUSHR
608     def_param ("pflushhr",1,LONG,bits(3,3),bits(0,3),0,0) break;
609     }
610     break;
611     }
612     case 0x10: case 0x11: case 0x12: case 0x13:// Cache
613     if (bits(5,1)==0) { // CINV
614     cinvpush("cinv");
615     } else { // CPUSH
616     cinvpush("cpush");
617     }
618     break;
619     }
620     break;
621     default: // should never happen
622     break;
623     }}
624     //
625    
626     static void add_int32_str (char *old,int32 value) {
627     sprintf (&(old[strlen(old)]),"$%08x",value);
628     }
629    
630     static void add_int16_str (char *old,int16 value) {
631     sprintf (&(old[strlen(old)]),"$%04x",value);
632     }
633    
634     static void add_int8_str (char *old,int8 value) {
635     sprintf (&(old[strlen(old)]),"$%02x",value);
636     }
637    
638     static void add_dec_int_str (char *old,int32 value) {
639     sprintf (&(old[strlen(old)]),"%d",value);
640     }
641    
642     static void print_range (int from,int to) {
643     if (from < 8) dest = strcat (dest,"d"); else dest = strcat(dest,"a");
644     add_dec_int_str(dest,from & 7);
645     if (to > from) {
646     dest = strcat(dest,"-");
647     if (to < 8) dest = strcat (dest,"d"); else dest = strcat(dest,"a");
648     add_dec_int_str(dest,to & 7);
649     }
650     }
651    
652     static void decode_extended (bool a_reg,uint16 aaa,int32 old_mem) {
653     uint16 value = read_uint16();
654     uint16 scale = 1 << ((value >> 9) & 3);
655     uint16 d_a = (value >> 15) & 1;
656     uint16 reg = (value >> 12) & 7;
657     uint16 w_l = (value >> 11) & 1;
658     strcat (dest,"(");
659     if (((value >> 8) & 1)==0) { // standard format
660     if (a_reg) {
661     add_int8_str(dest,value & 0xff);
662     strcat (dest,",a");
663     add_dec_int_str(dest,aaa);
664     } else {
665     add_int32_str(dest,old_mem*2+adr_off+(int32)(int8)(value));
666     strcat (dest,",pc");
667     }
668     if (d_a==0) strcat (dest,",d"); else strcat (dest,",a");
669     add_dec_int_str(dest,reg);
670     if (w_l==0) strcat (dest,".w"); else strcat (dest,".l");
671     if (scale > 1) {
672     strcat (dest,"*");
673     add_dec_int_str(dest,scale);
674     }
675     } else { // extended format
676     uint16 i_is = value & 3;
677     uint16 bd_size = (value >> 4) & 3;
678     uint16 bs = (value >> 7) & 1;
679     uint16 is = (value >> 6) & 1;
680     if (i_is!=0) strcat(dest,"[");
681     if (bd_size!=1) { // base displacement
682     switch (bd_size) {
683     case 2: if (a_reg)
684     add_int32_str(dest,read_int16());
685     else
686     add_int32_str(dest,old_mem*2+adr_off+(int32)read_int16());
687     break;
688     case 3: if (a_reg)
689     add_int32_str(dest,read_int32());
690     else
691     add_int32_str(dest,old_mem*2+adr_off+read_int32());
692     break;
693     default:
694     strcat (dest,"illegal base displacement ");
695     }
696     }
697     if (bs==0) {
698     if (bd_size!=1) strcat(dest,",");
699     if (a_reg) {
700     strcat (dest,"a");
701     add_dec_int_str(dest,aaa);
702     } else {
703     strcat (dest,"pc");
704     }
705     }
706     if ((is==0)&&(i_is>4)&&(i_is<8)) strcat(dest,"]");
707     if (is==0) {
708     if (bs==0||bd_size!=1) strcat(dest,",");
709     if (d_a==0) strcat (dest,",d"); else strcat (dest,",a");
710     add_dec_int_str(dest,reg);
711     if (w_l==0) strcat (dest,".w"); else strcat (dest,".l");
712     if (scale > 1) {
713     strcat (dest,"*");
714     add_dec_int_str(dest,scale);
715     }
716     }
717     if ((i_is>0)&&(i_is<4)) strcat(dest,"]");
718     if (((is==0)&&(i_is==4))||((is==1)&&(i_is>4))) strcat(dest,"reserved"); else
719     switch (i_is & 3) {
720     case 2: strcat(dest,",");
721     add_int32_str(dest,read_int16());
722     break;
723     case 3: strcat(dest,",");
724     add_int32_str(dest,read_int32());
725     break;
726     }
727     }
728     strcat (dest,")");
729     }
730    
731     static int decode_address_mode (uint16 eee,uint16 aaa,t_size size) {
732     int32 old_mem = mem_pos;
733     switch (eee) {
734     case 0: strcat (dest,"d");
735     add_dec_int_str(dest,aaa);
736     break;
737     case 1: strcat (dest,"a");
738     add_dec_int_str(dest,aaa);
739     break;
740     case 2: strcat (dest,"(a");
741     add_dec_int_str(dest,aaa);
742     strcat (dest,")");
743     break;
744     case 3: strcat (dest,"(a");
745     add_dec_int_str(dest,aaa);
746     strcat (dest,")+");
747     break;
748     case 4: strcat (dest,"-(a");
749     add_dec_int_str(dest,aaa);
750     strcat (dest,")");
751     break;
752     case 5: strcat (dest,"(");
753     add_int16_str(dest,read_int16());
754     strcat (dest,",a");
755     add_dec_int_str(dest,aaa);
756     strcat (dest,")");
757     break;
758     case 6: decode_extended(true,aaa,0);
759     break;
760     case 7: switch (aaa) {
761     case 0: add_int16_str(dest,read_int16());
762     strcat (dest,".w");
763     break;
764     case 1: add_int32_str(dest,read_int32());
765     strcat (dest,".l");
766     break;
767     case 2: strcat (dest,"(");
768     add_int32_str(dest,old_mem*2+adr_off+(int32)read_int16());
769     strcat (dest,",pc)");
770     break;
771     case 3: decode_extended(false,0,old_mem);
772     break;
773     case 4: strcat (dest,"#");
774     switch (size) {
775     case BYTE_SILENT:
776     case BYTE: add_int8_str(dest,read_int8() & 0xff);
777     break;
778     case WORD_SILENT:
779     case WORD: add_int16_str(dest,read_int16());
780     break;
781     case LONG_SILENT:
782     case LONG: add_int32_str(dest,read_int32());
783     break;
784     case NOSIZE: add_int8_str(dest,opcode & 0xff);
785     break;
786     default: ;
787     }
788     break;
789     default: error (ER_UNKNOWN_ADDRESS_MODE);
790     return -1;
791     }
792     break;
793     case AD_C: strcat (dest,con_str[aaa]);
794     break;
795     case AD_BRANCH:
796     switch (size){
797     case BYTE_SILENT:
798     case BYTE: add_int32_str(dest, (int32)(int8)aaa+old_mem*2+adr_off);
799     break;
800     case WORD_SILENT:
801     case WORD: add_int32_str(dest, (int32)read_int16()+old_mem*2+adr_off);
802     break;
803     case LONG_SILENT:
804     case LONG: add_int32_str(dest, read_int32()+old_mem*2+adr_off);
805 cebix 1.3 break;
806     default:
807     abort();
808 cebix 1.1 break;
809     }
810     break;
811     case AD_MULT: {
812     int dir = 1;
813     int off = 0;
814     if (aaa != 0) {
815     dir = -1;
816     off = 15;
817     }
818     int lend = -1;
819     bool first = true;
820     for (int i=0;i < 16;i++) {
821     if (((mask >> (off + dir * i))& 1) == 0) {
822     // print reg from lend+1 to i-1
823     if ((lend+1) <= (i-1)) {
824     if (!first) dest = strcat (dest,"/"); else first = false;
825     if (((lend + 1) < 8) && ((i-1) > 7)) {
826     print_range (lend+1,7);
827     dest = strcat (dest,"/");
828     print_range (8,i-1);
829     } else {
830     print_range (lend+1,i-1);
831     }
832     }
833     lend = i;
834     }
835     }
836     if (((mask >> (off + dir * 15)) & 1) == 1) { // print last regs
837     if (!first) dest = strcat (dest,"/");
838     print_range (lend+1,15);
839     }
840     break;
841     }
842     case AD_DATA_IMM:
843     strcat (dest,"#");
844     switch (size) {
845     case BYTE: case BYTE_SILENT: add_int8_str(dest,data_val); break;
846     case WORD: case WORD_SILENT: add_int16_str(dest,data_val); break;
847     case LONG: case LONG_SILENT: add_int32_str(dest,data_val); break;
848     default: ;
849     }
850     break;
851     case AD_DATA:
852     switch (size) {
853     case BYTE: case BYTE_SILENT: add_int8_str(dest,data_val); break;
854     case WORD: case WORD_SILENT: add_int16_str(dest,data_val); break;
855     case LONG: case LONG_SILENT: add_int32_str(dest,data_val); break;
856     default: ;
857     }
858     break;
859     case AD_CACHE:
860     switch (aaa) {
861     case 1: strcat(dest, "dc"); break;
862     case 2: strcat(dest, "ic"); break;
863     case 3: strcat(dest, "dc/ic"); break;
864     default: strcat(dest, "?"); break;
865     }
866     break;
867     default:
868     error (ER_UNKNOWN_ADDRESS_MODE);
869     return -1;
870     }
871     return 0;
872     }
873    
874     static void diss (char *ndest,uint16 *nmem,int &npos,unsigned int adr) {
875     dest = ndest; mem = nmem; mem_pos = npos; adr_off=adr;
876     dest[0]=0;
877     opcode = read_uint16 ();
878     strcat(dest,"\t");
879    
880     no_param("?")
881     parse();
882    
883     dest = strcat(dest,op_name);
884     if ((dest_eee == AD_BRANCH) && (size != NOSIZE)) dest = strcat (dest,cc_str[dest_aaa]);
885     switch (size) {
886     case BYTE: strcat (dest,source_eee == AD_BRANCH ? ".s\t" : ".b\t"); break;
887     case WORD: strcat (dest,source_eee == AD_BRANCH ? "\t" : ".w\t"); break;
888     case LONG: strcat (dest,".l\t"); break;
889     default: dest = strcat (dest,"\t"); break;
890     }
891     if (count_param > 0) {
892     if (decode_address_mode(source_eee,source_aaa,size) == -1) {
893     npos = mem_pos;
894     return;
895     }
896     if (count_param > 1) {
897     strcat (dest, ",");
898     if (decode_address_mode(dest_eee,dest_aaa,size) == -1) {
899     npos = mem_pos;
900     return;
901     }
902     }
903     }
904     npos = mem_pos;
905     }
906    
907    
908     /*
909     * Disassemble one instruction, return number of bytes
910     */
911    
912     int disass_68k(FILE *f, uint32 adr, uint16 *m)
913     {
914     char output[80];
915     int mem_pos = 0;
916     diss(output, m, mem_pos,adr);
917     for (int i=0;i<4;i++) if (i<mem_pos) fprintf(f,"%04x ", m[i]); else fprintf(f," ");
918     fprintf(f, "%s\n", output);
919     return mem_pos << 1;
920     }