cpu: get blarg CPU instruction test 6 passing
Its been too long since a checkin, but here's some of the improvements: - Support for diffing with other emulators - Better disassmbed output - New CPU instructions implemented - Lots of CPU fixes
This commit is contained in:
158
src/gb_disas.c
158
src/gb_disas.c
@@ -1,6 +1,11 @@
|
||||
/*TODO: This is hacky and has some bugs but whatever*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "gb_disas.h"
|
||||
|
||||
static const char *opcodes[256] = {
|
||||
//0
|
||||
@@ -244,7 +249,7 @@ static const char *opcodes[256] = {
|
||||
//14
|
||||
"LDH (a8),A",
|
||||
"POP HL",
|
||||
"LD (C),A",
|
||||
"LD (0xff00 + C),A",
|
||||
"*UNDEF*",
|
||||
"*UNDEF*",
|
||||
"PUSH HL",
|
||||
@@ -261,7 +266,7 @@ static const char *opcodes[256] = {
|
||||
//15
|
||||
"LDH A,(a8)",
|
||||
"POP AF",
|
||||
"LD A,(C)",
|
||||
"LD A,(0xff00 + C)",
|
||||
"DI",
|
||||
"*UNDEF*",
|
||||
"PUSH AF",
|
||||
@@ -277,6 +282,151 @@ static const char *opcodes[256] = {
|
||||
"RST 38H"
|
||||
};
|
||||
|
||||
const char * gb_byte_to_opcode(unsigned char byte) {
|
||||
return opcodes[(int) byte];
|
||||
static const char *ioreg[] = {
|
||||
[0] = "P1",
|
||||
[1] = "SB",
|
||||
[2] = "SC",
|
||||
[4] = "DIV",
|
||||
[5] = "TIMA",
|
||||
[6] = "TMA",
|
||||
[7] = "TAC",
|
||||
[0x0f] = "IF",
|
||||
[0x10] = "NR 10",
|
||||
[0x11] = "NR 11",
|
||||
[0x12] = "NR 12",
|
||||
[0x13] = "NR 13",
|
||||
[0x14] = "NR 14",
|
||||
[0x16] = "NR 21",
|
||||
[0x17] = "NR 22",
|
||||
[0x18] = "NR 23",
|
||||
[0x19] = "NR 24",
|
||||
[0x1A] = "NR 30",
|
||||
[0x1B] = "NR 31",
|
||||
[0x1C] = "NR 32",
|
||||
[0x1D] = "NR 33",
|
||||
[0x1E] = "NR 34",
|
||||
[0x20] = "NR 41",
|
||||
[0x21] = "NR 42",
|
||||
[0x22] = "NR 43",
|
||||
[0x23] = "NR 44",
|
||||
[0x24] = "NR 50",
|
||||
[0x25] = "NR 51",
|
||||
[0x26] = "NR 52",
|
||||
[0x30] = "WavePatternRam[0x0]",
|
||||
[0x31] = "WavePatternRam[0x1]",
|
||||
[0x32] = "WavePatternRam[0x2]",
|
||||
[0x33] = "WavePatternRam[0x3]",
|
||||
[0x34] = "WavePatternRam[0x4]",
|
||||
[0x35] = "WavePatternRam[0x5]",
|
||||
[0x36] = "WavePatternRam[0x6]",
|
||||
[0x37] = "WavePatternRam[0x7]",
|
||||
[0x38] = "WavePatternRam[0x8]",
|
||||
[0x39] = "WavePatternRam[0x9]",
|
||||
[0x3A] = "WavePatternRam[0xA]",
|
||||
[0x3B] = "WavePatternRam[0xB]",
|
||||
[0x3C] = "WavePatternRam[0xC]",
|
||||
[0x3D] = "WavePatternRam[0xD]",
|
||||
[0x3E] = "WavePatternRam[0xE]",
|
||||
[0x3F] = "WavePatternRam[0xF]",
|
||||
[0x40] = "LCDC",
|
||||
[0x41] = "STAT",
|
||||
[0x42] = "SCY",
|
||||
[0x43] = "SCX",
|
||||
[0x44] = "LC",
|
||||
[0x45] = "LYC",
|
||||
[0x46] = "DMA",
|
||||
[0x47] = "BGP",
|
||||
[0x48] = "OBP0",
|
||||
[0x49] = "OBP1",
|
||||
[0x4A] = "WY",
|
||||
[0x4B] = "WX",
|
||||
[0xFF] = "IE",
|
||||
};
|
||||
|
||||
|
||||
static const char *ioreg_str(uint16_t addr)
|
||||
{
|
||||
unsigned int offset;
|
||||
|
||||
if (addr > 0xff00) {
|
||||
offset = addr & 0xff;
|
||||
if (ioreg[offset] != NULL) {
|
||||
return ioreg[offset];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *gb_byte_to_opcode(uint16_t *addr, gb_byte_fetch_fn fetch, void *opaque)
|
||||
{
|
||||
char *buf = malloc(32);
|
||||
uint8_t inst = fetch(opaque, (*addr)++);
|
||||
const char *immediate;
|
||||
uint8_t val;
|
||||
size_t len;
|
||||
const char *opcode = opcodes[inst];
|
||||
|
||||
/* TODO: DRY this code up a bit */
|
||||
|
||||
if (inst == 0xcb) {
|
||||
/* CB-prefix instruction */
|
||||
/* TODO: Right now, this does almost nothing */
|
||||
strncpy(buf, opcode, 32);
|
||||
(*addr)++;
|
||||
|
||||
} else if ((immediate = strstr(opcode, "d8")) != NULL) {
|
||||
uint8_t val = fetch(opaque, (*addr)++);
|
||||
len = immediate - opcode;
|
||||
strncpy(buf, opcode, len);
|
||||
snprintf(buf + len, 32 - len, "0x%02x", val);
|
||||
strncat(buf, opcode + len + strlen("d8"), 32);
|
||||
|
||||
} else if ((immediate = strstr(opcode, "a8")) != NULL) {
|
||||
uint16_t val = ((uint16_t)fetch(opaque, (*addr)++)) + 0xff00;
|
||||
len = immediate - opcode;
|
||||
strncpy(buf, opcode, len);
|
||||
if (ioreg_str(val)) {
|
||||
snprintf(buf + len, 32 - len, "0x%04x=%s", val, ioreg_str(val));
|
||||
} else {
|
||||
snprintf(buf + len, 32 - len, "0x%04x", val);
|
||||
}
|
||||
strncat(buf, opcode + len + strlen("a8"), 32);
|
||||
|
||||
} else if ((immediate = strstr(opcode, "r8")) != NULL) {
|
||||
int16_t val = fetch(opaque, (*addr)++);
|
||||
if (val & (1 << 7)) {
|
||||
val |= 0xFF00;
|
||||
}
|
||||
len = immediate - opcode;
|
||||
strncpy(buf, opcode, len);
|
||||
snprintf(buf + len, 32 - len, "0x%04x", *addr + val);
|
||||
strncat(buf, opcode + len + strlen("r8"), 32);
|
||||
|
||||
} else if ((immediate = strstr(opcode, "d16")) != NULL) {
|
||||
uint16_t val = fetch(opaque, (*addr)++);
|
||||
val |= ((uint16_t) fetch(opaque, (*addr)++)) << 8;
|
||||
len = immediate - opcode;
|
||||
strncpy(buf, opcode, len);
|
||||
if (ioreg_str(val)) {
|
||||
snprintf(buf + len, 32 - len, "0x%04x=%s", val, ioreg_str(val));
|
||||
} else {
|
||||
snprintf(buf + len, 32 - len, "0x%04x", val);
|
||||
}
|
||||
strncat(buf, opcode + len + strlen("a16"), 32);
|
||||
|
||||
} else if ((immediate = strstr(opcode, "a16")) != NULL) {
|
||||
uint16_t val = fetch(opaque, (*addr)++);
|
||||
val |= ((uint16_t) fetch(opaque, (*addr)++)) << 8;
|
||||
len = immediate - opcode;
|
||||
strncpy(buf, opcode, len);
|
||||
snprintf(buf + len, 32 - len, "0x%04x", val);
|
||||
strncat(buf, opcode + len + strlen("a16"), 32);
|
||||
|
||||
} else {
|
||||
strncpy(buf, opcode, 32);
|
||||
}
|
||||
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user