1 // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
2 // Copyright (C) 1999-2003 Forgotten
3 // Copyright (C) 2004 Forgotten and the VBA development team
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2, or(at your option)
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software Foundation,
17 // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #include "../System.h"
23 #include "gbGlobals.h"
31 #define GB_READ(x) gbMemoryMap[(x)>>12][(x)&0xfff]
33 static char *registers
[] =
34 { "B", "C", "D", "E", "H", "L", "(HL)", "A" };
36 static char *registers16
[] =
37 { "BC", "DE", "HL", "SP", // for some operations
38 "BC", "DE", "HL", "AF" }; // for push/pop
41 { "NZ", "Z", "NC", "C" };
43 static char hexDigits
[16] = {
44 '0', '1', '2', '3', '4', '5', '6', '7',
45 '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
48 static GBOPCODE opcodes
[] = {
49 { 0xff, 0x00, "NOP" },
50 { 0xcf, 0x01, "LD %R4,%W" },
51 { 0xff, 0x02, "LD (BC),A" },
52 { 0xcf, 0x03, "INC %R4" },
53 { 0xc7, 0x04, "INC %r3" },
54 { 0xc7, 0x05, "DEC %r3" },
55 { 0xc7, 0x06, "LD %r3,%B" },
56 { 0xff, 0x07, "RLCA" },
57 { 0xff, 0x08, "LD (%W),SP" },
58 { 0xcf, 0x09, "ADD HL,%R4" },
59 { 0xff, 0x0a, "LD A,(BC)" },
60 { 0xcf, 0x0b, "DEC %R4" },
61 { 0xff, 0x0f, "RRCA" },
62 { 0xff, 0x10, "STOP" },
63 { 0xff, 0x12, "LD (DE),A" },
64 { 0xff, 0x17, "RLA" },
65 { 0xff, 0x18, "JR %d" },
66 { 0xff, 0x1a, "LD A,(DE)" },
67 { 0xff, 0x1f, "RRA" },
68 { 0xe7, 0x20, "JR %c3,%d" },
69 { 0xff, 0x22, "LDI (HL),A" },
70 { 0xff, 0x27, "DAA" },
71 { 0xff, 0x2a, "LDI A,(HL)" },
72 { 0xff, 0x2f, "CPL" },
73 { 0xff, 0x32, "LDD (HL),A" },
74 { 0xff, 0x37, "SCF" },
75 { 0xff, 0x3a, "LDD A,(HL)" },
76 { 0xff, 0x3f, "CCF" },
77 { 0xff, 0x76, "HALT" },
78 { 0xc0, 0x40, "LD %r3,%r0" },
79 { 0xf8, 0x80, "ADD A,%r0" },
80 { 0xf8, 0x88, "ADC A,%r0" },
81 { 0xf8, 0x90, "SUB %r0" },
82 { 0xf8, 0x98, "SBC A,%r0" },
83 { 0xf8, 0xa0, "AND %r0" },
84 { 0xf8, 0xa8, "XOR %r0" },
85 { 0xf8, 0xb0, "OR %r0" },
86 { 0xf8, 0xb8, "CP %r0" },
87 { 0xe7, 0xc0, "RET %c3" },
88 { 0xcf, 0xc1, "POP %t4" },
89 { 0xe7, 0xc2, "JP %c3,%W" },
90 { 0xff, 0xc3, "JP %W" },
91 { 0xe7, 0xc4, "CALL %c3,%W" },
92 { 0xcf, 0xc5, "PUSH %t4" },
93 { 0xff, 0xc6, "ADD A,%B" },
94 { 0xc7, 0xc7, "RST %P" },
95 { 0xff, 0xc9, "RET" },
96 { 0xff, 0xcd, "CALL %W" },
97 { 0xff, 0xce, "ADC %B" },
98 { 0xff, 0xd6, "SUB %B" },
99 { 0xff, 0xd9, "RETI" },
100 { 0xff, 0xde, "SBC %B" },
101 { 0xff, 0xe0, "LD (FF%B),A" },
102 { 0xff, 0xe2, "LD (FF00h+C),A" },
103 { 0xff, 0xe6, "AND %B" },
104 { 0xff, 0xe8, "ADD SP,%D" },
105 { 0xff, 0xe9, "LD PC,HL" },
106 { 0xff, 0xea, "LD (%W),A" },
107 { 0xff, 0xee, "XOR %B" },
108 { 0xff, 0xf0, "LD A,(FF%B)" },
109 { 0xff, 0xf2, "LD A,(FF00h+C)" },
110 { 0xff, 0xf3, "DI" },
111 { 0xff, 0xf6, "OR %B" },
112 { 0xff, 0xf8, "LD HL,SP%D" },
113 { 0xff, 0xf9, "LD SP,HL" },
114 { 0xff, 0xfa, "LD A,(%W)" },
115 { 0xff, 0xfb, "EI" },
116 { 0xff, 0xfe, "CP %B" },
117 { 0x00, 0x00, "DB %B" }
120 static GBOPCODE cbOpcodes
[] = {
121 { 0xf8, 0x00, "RLC %r0" },
122 { 0xf8, 0x08, "RRC %r0" },
123 { 0xf8, 0x10, "RL %r0" },
124 { 0xf8, 0x18, "RR %r0" },
125 { 0xf8, 0x20, "SLA %r0" },
126 { 0xf8, 0x28, "SRA %r0" },
127 { 0xf8, 0x30, "SWAP %r0" },
128 { 0xf8, 0x38, "SRL %r0" },
129 { 0xc0, 0x40, "BIT %b,%r0" },
130 { 0xc0, 0x80, "RES %b,%r0" },
131 { 0xc0, 0xc0, "SET %b,%r0" },
132 { 0x00, 0x00, "DB CBh,%B" }
135 static char *addHex(char *p
, u8 value
)
137 *p
++ = hexDigits
[value
>> 4];
138 *p
++ = hexDigits
[value
& 15];
142 static char *addHex16(char *p
, u16 value
)
144 p
= addHex(p
, value
>>8);
145 return addHex(p
, value
& 255);
148 static char *addStr(char *p
, char *s
)
156 int gbDis(char *buffer
, u16 address
)
161 sprintf(p
, "%04x ", address
);
164 u8 opcode
= GB_READ(address
);
169 opcode
= GB_READ(address
);
176 while(op
->value
!= (opcode
& op
->mask
)) op
++;
188 b0
= GB_READ(address
);
190 b1
= GB_READ(address
);
192 p
= addHex16(p
, b0
|b1
<<8);
197 p
= addHex(p
, GB_READ(address
));
203 disp
= GB_READ(address
);
206 p
+= sprintf(p
, "%d", disp
);
210 disp
= GB_READ(address
);
212 p
= addHex16(p
, address
+disp
);
217 // kind of a hack, but it works :-)
218 *p
++ = hexDigits
[(opcode
>> 3) & 7];
221 shift
= *mnen
++ - '0';
222 p
= addStr(p
, registers
[(opcode
>> shift
) & 7]);
225 shift
= *mnen
++ - '0';
226 p
= addStr(p
, registers16
[(opcode
>> shift
) & 3]);
229 shift
= *mnen
++ - '0';
230 p
= addStr(p
, registers16
[4+((opcode
>> shift
) & 3)]);
233 p
= addHex(p
, ((opcode
>> 3) & 7) * 8);
236 shift
= *mnen
++ - '0';
237 p
= addStr(p
, cond
[(opcode
>> shift
) & 3]);
243 for(int i
= 0; i
< instr
; i
++) {
245 addHex(buffer
+5+i
*2, GB_READ(a
));