diff src/gb/gbDis.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
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 10:31:27 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 +}