]> Shamusworld >> Repos - thunder/blob - src/dis63701.cpp
Added disassembler for 63701.
[thunder] / src / dis63701.cpp
1 //
2 // 63701 disassembler
3 //
4 // by James Hammons
5 //
6 // (c) 2004, 2014 Underground Software
7 //
8
9 #include "dis63701.h"
10
11 #include <stdio.h>
12 #include <string>
13
14
15 // Private globals variables
16
17 // Mode
18 // 0=ill, 1=ZP, 2=abs, 3=rel, 4=imm+ZP,X, 5=inh, 6=imm+ZP, 7=ZP,X, 8=imm, 9=long imm
19
20 static char opcodeMode[256] = {
21   0, 5, 0, 0, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,       // $0x
22   5, 5, 5, 5, 0, 0, 5, 5, 5, 5, 5, 5, 0, 0, 0, 0,
23   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,       // $2x
24   5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
25   5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,       // $4x
26   5, 0, 0, 5, 5, 0, 5, 5, 5, 5, 5, 0, 5, 5, 0, 5,
27   7, 4, 4, 7, 7, 4, 7, 7, 7, 7, 7, 4, 7, 7, 7, 7,       // $6x
28   2, 6, 6, 2, 2, 6, 2, 2, 2, 2, 2, 6, 2, 2, 2, 2,
29   8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 3, 9, 9,       // $8x
30   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
31   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,       // $Ax
32   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
33   8, 8, 8, 9, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9,       // $Cx
34   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
35   7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,       // $Ex
36   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2
37 };
38
39 static char mnemonics[256][6] = {
40   "???  ","NOP  ","???  ","???  ","LSRD ","ASLD ","TAP  ","TPA  ",      // $0x
41   "INX  ","DEX  ","CLV  ","SEV  ","CLC  ","SEC  ","CLI  ","SEI  ",
42   "SBA  ","CBA  ","UND1 ","UND2 ","???  ","???  ","TAB  ","TBA  ",      // $1x
43   "XGDX ","DAA  ","SLP  ","ABA  ","???  ","???  ","???  ","???  ",
44   "BRA  ","BRN  ","BHI  ","BLS  ","BCC  ","BCS  ","BNE  ","BEQ  ",      // $2x
45   "BVC  ","BVS  ","BPL  ","BMI  ","BGE  ","BLT  ","BGT  ","BLE  ",
46   "TSX  ","INS  ","PULA ","PULB ","DES  ","TXS  ","PSHA ","PSHB ",      // $3x
47   "PULX ","RTS  ","ABX  ","RTI  ","PSHX ","MUL  ","WAI  ","SWI  ",
48   "NEGA ","???  ","???  ","COMA ","LSRA ","???  ","RORA ","ASRA ",      // $4x
49   "ASLA ","ROLA ","DECA ","???  ","INCA ","TSTA ","???  ","CLRA ",
50   "NEGB ","???  ","???  ","COMB ","LSRB ","???  ","RORB ","ASRB ",      // $5x
51   "ASLB ","ROLB ","DECB ","???  ","INCB ","TSTB ","???  ","CLRB ",
52   "NEG  ","AIM  ","OIM  ","COM  ","LSR  ","EIM  ","ROR  ","ASR  ",      // $6x
53   "ASL  ","ROL  ","DEC  ","TIM  ","INC  ","TST  ","JMP  ","CLR  ",
54   "NEG  ","AIM  ","OIM  ","COM  ","LSR  ","EIM  ","ROR  ","ASR  ",      // $7x
55   "ASL  ","ROL  ","DEC  ","TIM  ","INC  ","TST  ","JMP  ","CLR  ",
56   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STA  ",      // $8x
57   "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","BSR  ","LDS  ","STS  ",
58   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ",      // $9x
59   "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","JSR  ","LDS  ","STS  ",
60   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ",      // $Ax
61   "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","JSR  ","LDS  ","STS  ",
62   "SUBA ","CMPA ","SBCA ","SUBD ","ANDA ","BITA ","LDAA ","STAA ",      // $Bx
63   "EORA ","ADCA ","ORAA ","ADDA ","CPX  ","JSR  ","LDS  ","STS  ",
64   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STB  ",      // $Cx
65   "EORB ","ADCB ","ORAB ","ADDB ","LDD  ","STD  ","LDX  ","STX  ",
66   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ",      // $Dx
67   "EORB ","ADCB ","ORAB ","ADDB ","LDD  ","STD  ","LDX  ","STX  ",
68   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ",      // $Ex
69   "EORB ","ADCB ","ORAB ","ADDB ","LDD  ","STD  ","LDX  ","STX  ",
70   "SUBB ","CMPB ","SBCB ","ADDD ","ANDB ","BITB ","LDAB ","STAB ",      // $Fx
71   "EORB ","ADCB ","ORAB ","ADDB ","LDD  ","STD  ","LDX  ","STX  "
72 };
73
74
75 //
76 // Display bytes in mem in hex
77 //
78 static void WriteBytesToString(uint8_t * mem, uint16_t src, uint32_t dst, char * s)
79 {
80         const char hex[17] = "0123456789ABCDEF";
81
82         if (s == 0)
83                 return;
84
85         sprintf(s, "%04X:                 ", src);
86
87         // That should fix the FFFF bug...
88         if (src > dst)
89                 dst += 0x10000;
90
91         for(uint32_t i=src; i<dst; i++)
92         {
93                 s[6 + ((i - src) * 3) + 0] = hex[mem[i & 0xFFFF] >> 4];
94                 s[6 + ((i - src) * 3) + 1] = hex[mem[i & 0xFFFF] & 0xF];
95         }
96 }
97
98
99 //
100 // Decode a 63701 instruction
101 //
102 uint32_t Decode63701(uint8_t * mem, uint16_t pc, char * buffer)
103 {
104         if (buffer == 0)
105                 return 0;
106
107         char instruction[80], byteString[80];
108
109         uint16_t addr = pc, offset;
110         uint8_t opcode = mem[addr++], extra;
111
112         // Decode the addressing mode...
113         switch (opcodeMode[opcode])
114         {
115         case 0:                                                         // Illegal
116                 sprintf(instruction, "???          ");
117                 break;
118         case 1:                                                         // Zero page
119                 sprintf(instruction, "%s $%02X    ", mnemonics[opcode], mem[addr++]);
120                 break;
121         case 2:                                                         // Absolute
122                 offset = (mem[addr + 0] << 8) | mem[addr + 1];
123                 addr += 2;
124                 sprintf(instruction, "%s $%04X  ", mnemonics[opcode], offset);
125                 break;
126         case 3:                                                         // Relative
127                 offset = addr + 1 + (int16_t)(int8_t)mem[addr];
128                 addr++;
129                 sprintf(instruction, "%s $%04X  ", mnemonics[opcode], offset);
130                 break;
131         case 5:                                                         // Inherent
132                 sprintf(instruction, "%s        ", mnemonics[opcode]);
133                 break;
134         case 7:                                                         // Indexed
135                 sprintf(instruction, "%s $%02X,X  ", mnemonics[opcode], mem[addr++]);
136                 break;
137         case 8:                                                         // Immediate
138                 sprintf(instruction, "%s #$%02X   ", mnemonics[opcode], mem[addr++]);
139                 break;
140         case 9:                                                         // Long Immediate
141                 offset = (mem[addr + 0] << 8) | mem[addr + 1];
142                 addr += 2;
143                 sprintf(instruction, "%s #$%04X ", mnemonics[opcode], offset);
144                 break;
145         case 6:                                                         // Immediate + zero page
146                 extra = mem[addr++];
147                 sprintf(instruction, "%s #$%02X, $%02X", mnemonics[opcode], extra, mem[addr++]);
148                 break;
149         case 4:                                                 // Immediate + indexed
150                 extra = mem[addr++];
151                 sprintf(instruction, "%s #$%02X, $%02X,X", mnemonics[opcode], extra, mem[addr++]);
152                 break;
153         }
154
155 //printf("D6[%s]\n", instruction);
156         WriteBytesToString(mem, pc, addr, byteString);
157         sprintf(buffer, "%s%s", byteString, instruction);
158
159         return (addr < pc ? addr - pc + 0x10000 : addr - pc);
160 }
161