Mercurial > vba-clojure
diff src/gb/gbDis.cpp @ 17:75e5bb1e0aa1
going to now integrate the gb src tree since it has no dependencies
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 11:44:47 -0600 |
parents | f9f4f1b99eed |
children |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/gb/gbDis.cpp Sat Mar 03 11:44:47 2012 -0600 1.3 @@ -0,0 +1,239 @@ 1.4 +#include <cstdio> 1.5 +#include <cstring> 1.6 + 1.7 +#include "gbGlobals.h" 1.8 + 1.9 +typedef struct 1.10 +{ 1.11 + u8 mask; 1.12 + u8 value; 1.13 + char *mnen; 1.14 +} GBOPCODE; 1.15 + 1.16 +static char *registers[] = 1.17 +{ "B", "C", "D", "E", "H", "L", "(HL)", "A" }; 1.18 + 1.19 +static char *registers16[] = 1.20 +{ "BC", "DE", "HL", "SP", // for some operations 1.21 + "BC", "DE", "HL", "AF" }; // for push/pop 1.22 + 1.23 +static char *cond[] = 1.24 +{ "NZ", "Z", "NC", "C" }; 1.25 + 1.26 +static char hexDigits[16] = { 1.27 + '0', '1', '2', '3', '4', '5', '6', '7', 1.28 + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' 1.29 +}; 1.30 + 1.31 +static GBOPCODE opcodes[] = { 1.32 + { 0xff, 0x00, "NOP" }, 1.33 + { 0xcf, 0x01, "LD %R4,%W" }, 1.34 + { 0xff, 0x02, "LD (BC),A" }, 1.35 + { 0xcf, 0x03, "INC %R4" }, 1.36 + { 0xc7, 0x04, "INC %r3" }, 1.37 + { 0xc7, 0x05, "DEC %r3" }, 1.38 + { 0xc7, 0x06, "LD %r3,%B" }, 1.39 + { 0xff, 0x07, "RLCA" }, 1.40 + { 0xff, 0x08, "LD (%W),SP" }, 1.41 + { 0xcf, 0x09, "ADD HL,%R4" }, 1.42 + { 0xff, 0x0a, "LD A,(BC)" }, 1.43 + { 0xcf, 0x0b, "DEC %R4" }, 1.44 + { 0xff, 0x0f, "RRCA" }, 1.45 + { 0xff, 0x10, "STOP" }, 1.46 + { 0xff, 0x12, "LD (DE),A" }, 1.47 + { 0xff, 0x17, "RLA" }, 1.48 + { 0xff, 0x18, "JR %d" }, 1.49 + { 0xff, 0x1a, "LD A,(DE)" }, 1.50 + { 0xff, 0x1f, "RRA" }, 1.51 + { 0xe7, 0x20, "JR %c3,%d" }, 1.52 + { 0xff, 0x22, "LDI (HL),A" }, 1.53 + { 0xff, 0x27, "DAA" }, 1.54 + { 0xff, 0x2a, "LDI A,(HL)" }, 1.55 + { 0xff, 0x2f, "CPL" }, 1.56 + { 0xff, 0x32, "LDD (HL),A" }, 1.57 + { 0xff, 0x37, "SCF" }, 1.58 + { 0xff, 0x3a, "LDD A,(HL)" }, 1.59 + { 0xff, 0x3f, "CCF" }, 1.60 + { 0xff, 0x76, "HALT" }, 1.61 + { 0xc0, 0x40, "LD %r3,%r0" }, 1.62 + { 0xf8, 0x80, "ADD A,%r0" }, 1.63 + { 0xf8, 0x88, "ADC A,%r0" }, 1.64 + { 0xf8, 0x90, "SUB %r0" }, 1.65 + { 0xf8, 0x98, "SBC A,%r0" }, 1.66 + { 0xf8, 0xa0, "AND %r0" }, 1.67 + { 0xf8, 0xa8, "XOR %r0" }, 1.68 + { 0xf8, 0xb0, "OR %r0" }, 1.69 + { 0xf8, 0xb8, "CP %r0" }, 1.70 + { 0xe7, 0xc0, "RET %c3" }, 1.71 + { 0xcf, 0xc1, "POP %t4" }, 1.72 + { 0xe7, 0xc2, "JP %c3,%W" }, 1.73 + { 0xff, 0xc3, "JP %W" }, 1.74 + { 0xe7, 0xc4, "CALL %c3,%W" }, 1.75 + { 0xcf, 0xc5, "PUSH %t4" }, 1.76 + { 0xff, 0xc6, "ADD A,%B" }, 1.77 + { 0xc7, 0xc7, "RST %P" }, 1.78 + { 0xff, 0xc9, "RET" }, 1.79 + { 0xff, 0xcd, "CALL %W" }, 1.80 + { 0xff, 0xce, "ADC %B" }, 1.81 + { 0xff, 0xd6, "SUB %B" }, 1.82 + { 0xff, 0xd9, "RETI" }, 1.83 + { 0xff, 0xde, "SBC %B" }, 1.84 + { 0xff, 0xe0, "LD (FF%B),A" }, 1.85 + { 0xff, 0xe2, "LD (FF00h+C),A" }, 1.86 + { 0xff, 0xe6, "AND %B" }, 1.87 + { 0xff, 0xe8, "ADD SP,%D" }, 1.88 + { 0xff, 0xe9, "LD PC,HL" }, 1.89 + { 0xff, 0xea, "LD (%W),A" }, 1.90 + { 0xff, 0xee, "XOR %B" }, 1.91 + { 0xff, 0xf0, "LD A,(FF%B)" }, 1.92 + { 0xff, 0xf2, "LD A,(FF00h+C)" }, 1.93 + { 0xff, 0xf3, "DI" }, 1.94 + { 0xff, 0xf6, "OR %B" }, 1.95 + { 0xff, 0xf8, "LD HL,SP%D" }, 1.96 + { 0xff, 0xf9, "LD SP,HL" }, 1.97 + { 0xff, 0xfa, "LD A,(%W)" }, 1.98 + { 0xff, 0xfb, "EI" }, 1.99 + { 0xff, 0xfe, "CP %B" }, 1.100 + { 0x00, 0x00, "DB %B" } 1.101 +}; 1.102 + 1.103 +static GBOPCODE cbOpcodes[] = { 1.104 + { 0xf8, 0x00, "RLC %r0" }, 1.105 + { 0xf8, 0x08, "RRC %r0" }, 1.106 + { 0xf8, 0x10, "RL %r0" }, 1.107 + { 0xf8, 0x18, "RR %r0" }, 1.108 + { 0xf8, 0x20, "SLA %r0" }, 1.109 + { 0xf8, 0x28, "SRA %r0" }, 1.110 + { 0xf8, 0x30, "SWAP %r0" }, 1.111 + { 0xf8, 0x38, "SRL %r0" }, 1.112 + { 0xc0, 0x40, "BIT %b,%r0" }, 1.113 + { 0xc0, 0x80, "RES %b,%r0" }, 1.114 + { 0xc0, 0xc0, "SET %b,%r0" }, 1.115 + { 0x00, 0x00, "DB CBh,%B" } 1.116 +}; 1.117 + 1.118 +static char *addHex(char *p, u8 value) 1.119 +{ 1.120 + *p++ = hexDigits[value >> 4]; 1.121 + *p++ = hexDigits[value & 15]; 1.122 + return p; 1.123 +} 1.124 + 1.125 +static char *addHex16(char *p, u16 value) 1.126 +{ 1.127 + p = addHex(p, value>>8); 1.128 + return addHex(p, value & 255); 1.129 +} 1.130 + 1.131 +static char *addStr(char *p, char *s) 1.132 +{ 1.133 + while (*s) 1.134 + { 1.135 + *p++ = *s++; 1.136 + } 1.137 + return p; 1.138 +} 1.139 + 1.140 +int gbDis(char *buffer, u16 address) 1.141 +{ 1.142 + char *p = buffer; 1.143 + int instr = 1; 1.144 + u16 addr = address; 1.145 + sprintf(p, "%04x ", address); 1.146 + p += 12; 1.147 + 1.148 + u8 opcode = gbReadMemoryQuick(address); 1.149 + address++; 1.150 + char * mnen; 1.151 + GBOPCODE *op; 1.152 + if (opcode == 0xcb) 1.153 + { 1.154 + opcode = gbReadMemoryQuick(address); 1.155 + address++; 1.156 + instr++; 1.157 + op = cbOpcodes; 1.158 + } 1.159 + else 1.160 + { 1.161 + op = opcodes; 1.162 + } 1.163 + while (op->value != (opcode & op->mask)) 1.164 + op++; 1.165 + mnen = op->mnen; 1.166 + 1.167 + u8 b0, b1; 1.168 + s8 disp; 1.169 + int shift; 1.170 + 1.171 + while (*mnen) 1.172 + { 1.173 + if (*mnen == '%') 1.174 + { 1.175 + mnen++; 1.176 + switch (*mnen++) 1.177 + { 1.178 + case 'W': 1.179 + b0 = gbReadMemoryQuick(address); 1.180 + address++; 1.181 + b1 = gbReadMemoryQuick(address); 1.182 + address++; 1.183 + p = addHex16(p, b0|b1<<8); 1.184 + instr += 2; 1.185 + *p++ = 'h'; 1.186 + break; 1.187 + case 'B': 1.188 + p = addHex(p, gbReadMemoryQuick(address)); 1.189 + *p++ = 'h'; 1.190 + address++; 1.191 + instr++; 1.192 + break; 1.193 + case 'D': 1.194 + disp = gbReadMemoryQuick(address); 1.195 + if (disp >= 0) 1.196 + *p++ = '+'; 1.197 + p += sprintf(p, "%d", disp); 1.198 + instr++; 1.199 + break; 1.200 + case 'd': 1.201 + disp = gbReadMemoryQuick(address); 1.202 + address++; 1.203 + p = addHex16(p, address+disp); 1.204 + *p++ = 'h'; 1.205 + instr++; 1.206 + break; 1.207 + case 'b': 1.208 + // kind of a hack, but it works :-) 1.209 + *p++ = hexDigits[(opcode >> 3) & 7]; 1.210 + break; 1.211 + case 'r': 1.212 + shift = *mnen++ - '0'; 1.213 + p = addStr(p, registers[(opcode >> shift) & 7]); 1.214 + break; 1.215 + case 'R': 1.216 + shift = *mnen++ - '0'; 1.217 + p = addStr(p, registers16[(opcode >> shift) & 3]); 1.218 + break; 1.219 + case 't': 1.220 + shift = *mnen++ - '0'; 1.221 + p = addStr(p, registers16[4+((opcode >> shift) & 3)]); 1.222 + break; 1.223 + case 'P': 1.224 + p = addHex(p, ((opcode >> 3) & 7) * 8); 1.225 + break; 1.226 + case 'c': 1.227 + shift = *mnen++ - '0'; 1.228 + p = addStr(p, cond[(opcode >> shift) & 3]); 1.229 + break; 1.230 + } 1.231 + } 1.232 + else 1.233 + *p++ = *mnen++; 1.234 + } 1.235 + for (int i = 0; i < instr; i++) 1.236 + { 1.237 + u16 a = addr + i; 1.238 + addHex(buffer+5+i*2, gbReadMemoryQuick(a)); 1.239 + } 1.240 + *p = 0; 1.241 + return instr; 1.242 +}