ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/mon/src/mon_68k.cpp
Revision: 1.1
Committed: 1999-10-04T19:31:09Z (25 years, 1 month ago) by cebix
Branch: MAIN
Branch point for: cebix
Log Message:
Initial revision

File Contents

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