diff --git a/Makefile b/Makefile index d75b636..380d60f 100644 --- a/Makefile +++ b/Makefile @@ -23,9 +23,10 @@ compile = \ ) \ ) +all: library; + include gameboy/Makefile -all: library; set-static: $(eval fpic := ) diff --git a/gameboy/cartridge/cartridge.cpp b/gameboy/cartridge/cartridge.cpp index 8186297..6cb2d54 100755 --- a/gameboy/cartridge/cartridge.cpp +++ b/gameboy/cartridge/cartridge.cpp @@ -16,14 +16,14 @@ namespace GameBoy { #include "serialization.cpp" Cartridge cartridge; -void Cartridge::load(const string &xml, uint8_t *data, unsigned size) { +void Cartridge::load(const string &xml, const uint8_t *data, const unsigned size) { //uint32_t crc = crc32_calculate(data, size); //print("CRC32 = ", hex<4>(crc), "\n"); romdata = new uint8[romsize = size]; memcpy(romdata, data, size); - info.mapper = Mapper::Unknown; + info.mapper.i = Mapper::Unknown; info.ram = false; info.battery = false; info.rtc = false; @@ -37,14 +37,14 @@ void Cartridge::load(const string &xml, uint8_t *data, unsigned size) { if(head.name == "cartridge") { foreach(attr, head.attribute) { if(attr.name == "mapper") { - if(attr.content == "none") info.mapper = Mapper::MBC0; - if(attr.content == "MBC1") info.mapper = Mapper::MBC1; - if(attr.content == "MBC2") info.mapper = Mapper::MBC2; - if(attr.content == "MBC3") info.mapper = Mapper::MBC3; - if(attr.content == "MBC5") info.mapper = Mapper::MBC5; - if(attr.content == "MMM01") info.mapper = Mapper::MMM01; - if(attr.content == "HuC1") info.mapper = Mapper::HuC1; - if(attr.content == "HuC3") info.mapper = Mapper::HuC3; + if(attr.content == "none") info.mapper.i = Mapper::MBC0; + if(attr.content == "MBC1") info.mapper.i = Mapper::MBC1; + if(attr.content == "MBC2") info.mapper.i = Mapper::MBC2; + if(attr.content == "MBC3") info.mapper.i = Mapper::MBC3; + if(attr.content == "MBC5") info.mapper.i = Mapper::MBC5; + if(attr.content == "MMM01") info.mapper.i = Mapper::MMM01; + if(attr.content == "HuC1") info.mapper.i = Mapper::HuC1; + if(attr.content == "HuC3") info.mapper.i = Mapper::HuC3; } if(attr.name == "rtc") info.rtc = (attr.content == "true" ? true : false); @@ -117,7 +117,7 @@ void Cartridge::power() { void Cartridge::map() { MMIO *mapper = 0; - switch(info.mapper) { default: + switch(info.mapper.i) { default: case Mapper::MBC0: mapper = &mbc0; break; case Mapper::MBC1: mapper = &mbc1; break; case Mapper::MBC2: mapper = &mbc2; break; diff --git a/gameboy/cartridge/cartridge.hpp b/gameboy/cartridge/cartridge.hpp index 2ce22a9..a964ff1 100755 --- a/gameboy/cartridge/cartridge.hpp +++ b/gameboy/cartridge/cartridge.hpp @@ -8,16 +8,31 @@ struct Cartridge : property { #include "huc1/huc1.hpp" #include "huc3/huc3.hpp" - enum Mapper : unsigned { - MBC0, - MBC1, - MBC2, - MBC3, - MBC5, - MMM01, - HuC1, - HuC3, - Unknown, + //enum Mapper : unsigned { + // MBC0, + // MBC1, + // MBC2, + // MBC3, + // MBC5, + // MMM01, + // HuC1, + // HuC3, + // Unknown, + //}; + // + + struct Mapper { + enum e { + MBC0, + MBC1, + MBC2, + MBC3, + MBC5, + MMM01, + HuC1, + HuC3, + Unknown, + } i; }; struct Information { @@ -41,7 +56,7 @@ struct Cartridge : property { uint8_t *ramdata; unsigned ramsize; - void load(const string &xml, uint8_t *data, unsigned size); + void load(const string &xml, const uint8_t *data, const unsigned size); void unload(); uint8 rom_read(unsigned addr); diff --git a/gameboy/cpu/core/disassembler.cpp b/gameboy/cpu/core/disassembler.cpp index dbcee7e..f046551 100755 --- a/gameboy/cpu/core/disassembler.cpp +++ b/gameboy/cpu/core/disassembler.cpp @@ -6,13 +6,15 @@ string CPU::disassemble(uint16 pc) { output[79] = 0; string opcode = disassemble_opcode(pc); - string registers = { - " AF:", hex<4>(r[AF]), - " BC:", hex<4>(r[BC]), - " DE:", hex<4>(r[DE]), - " HL:", hex<4>(r[HL]), - " SP:", hex<4>(r[SP]) - }; + + // Terrible hack is terrible. :( Gief vartemplates! + string registers = string( + string(string(" AF:"), hex<4>(r[AF])), + string(string(" BC:"), hex<4>(r[BC])), + string(string(" DE:"), hex<4>(r[DE])), + string(string(" HL:"), hex<4>(r[HL])), + string(string(" SP:"), hex<4>(r[SP])) + ); memcpy(output + 0, hex<4>(pc), 4); memcpy(output + 6, opcode, opcode.length()); @@ -28,262 +30,262 @@ string CPU::disassemble_opcode(uint16 pc) { uint8 p2 = bus.read(pc + 3); switch(opcode) { - case 0x00: return { "nop" }; - case 0x01: return { "ld bc,$", hex<2>(p1), hex<2>(p0) }; - case 0x02: return { "ld (bc),a" }; - case 0x03: return { "inc bc" }; - case 0x04: return { "inc b" }; - case 0x05: return { "dec b" }; - case 0x06: return { "ld b,$", hex<2>(p0) }; - case 0x07: return { "rlc a" }; - case 0x08: return { "ld ($", hex<2>(p1), hex<2>(p0), "),sp" }; - case 0x09: return { "add hl,bc" }; - case 0x0a: return { "ld a,(bc)" }; - case 0x0b: return { "dec bc" }; - case 0x0c: return { "inc c" }; - case 0x0d: return { "dec c" }; - case 0x0e: return { "ld c,$", hex<2>(p0) }; - case 0x0f: return { "rrc a" }; - case 0x10: return { "stop" }; - case 0x11: return { "ld de,$", hex<2>(p1), hex<2>(p0) }; - case 0x12: return { "ld (de),a" }; - case 0x13: return { "inc de" }; - case 0x14: return { "inc d" }; - case 0x15: return { "dec d" }; - case 0x16: return { "ld d,$", hex<2>(p0) }; - case 0x17: return { "rl a" }; - case 0x18: return { "jr $", hex<4>(r[PC] + 2 + (int8)p0) }; - case 0x19: return { "add hl,de" }; - case 0x1a: return { "ld a,(de)" }; - case 0x1b: return { "dec de" }; - case 0x1c: return { "inc e" }; - case 0x1d: return { "dec e" }; - case 0x1e: return { "ld e,$", hex<2>(p0) }; - case 0x1f: return { "rr a" }; - case 0x20: return { "jr nz,$", hex<4>(r[PC] + 2 + (int8)p0) }; - case 0x21: return { "ld hl,$", hex<2>(p1), hex<2>(p0) }; - case 0x22: return { "ldi (hl),a" }; - case 0x23: return { "inc hl" }; - case 0x24: return { "inc h" }; - case 0x25: return { "dec h" }; - case 0x26: return { "ld h,$", hex<2>(p0) }; - case 0x27: return { "daa" }; - case 0x28: return { "jr z,$", hex<4>(r[PC] + 2 + (int8)p0) }; - case 0x29: return { "add hl,hl" }; - case 0x2a: return { "ldi a,(hl)" }; - case 0x2b: return { "dec hl" }; - case 0x2c: return { "inc l" }; - case 0x2d: return { "dec l" }; - case 0x2e: return { "ld l,$", hex<2>(p0) }; - case 0x2f: return { "cpl" }; - case 0x30: return { "jr nc,$", hex<4>(r[PC] + 2 + (int8)p0) }; - case 0x31: return { "ld sp,$", hex<2>(p1), hex<2>(p0) }; - case 0x32: return { "ldd (hl),a" }; - case 0x33: return { "inc sp" }; - case 0x34: return { "inc (hl)" }; - case 0x35: return { "dec (hl)" }; - case 0x36: return { "ld (hl),$", hex<2>(p0) }; - case 0x37: return { "scf" }; - case 0x38: return { "jr c,$", hex<4>(r[PC] + 2 + (int8)p0) }; - case 0x39: return { "add hl,sp" }; - case 0x3a: return { "ldd a,(hl)" }; - case 0x3b: return { "dec sp" }; - case 0x3c: return { "inc a" }; - case 0x3d: return { "dec a" }; - case 0x3e: return { "ld a,$", hex<2>(p0) }; - case 0x3f: return { "ccf" }; - case 0x40: return { "ld b,b" }; - case 0x41: return { "ld b,c" }; - case 0x42: return { "ld b,d" }; - case 0x43: return { "ld b,e" }; - case 0x44: return { "ld b,h" }; - case 0x45: return { "ld b,l" }; - case 0x46: return { "ld b,(hl)" }; - case 0x47: return { "ld b,a" }; - case 0x48: return { "ld c,b" }; - case 0x49: return { "ld c,c" }; - case 0x4a: return { "ld c,d" }; - case 0x4b: return { "ld c,e" }; - case 0x4c: return { "ld c,h" }; - case 0x4d: return { "ld c,l" }; - case 0x4e: return { "ld c,(hl)" }; - case 0x4f: return { "ld c,a" }; - case 0x50: return { "ld d,b" }; - case 0x51: return { "ld d,c" }; - case 0x52: return { "ld d,d" }; - case 0x53: return { "ld d,e" }; - case 0x54: return { "ld d,h" }; - case 0x55: return { "ld d,l" }; - case 0x56: return { "ld d,(hl)" }; - case 0x57: return { "ld d,a" }; - case 0x58: return { "ld e,b" }; - case 0x59: return { "ld e,c" }; - case 0x5a: return { "ld e,d" }; - case 0x5b: return { "ld e,e" }; - case 0x5c: return { "ld e,h" }; - case 0x5d: return { "ld e,l" }; - case 0x5e: return { "ld e,(hl)" }; - case 0x5f: return { "ld e,a" }; - case 0x60: return { "ld h,b" }; - case 0x61: return { "ld h,c" }; - case 0x62: return { "ld h,d" }; - case 0x63: return { "ld h,e" }; - case 0x64: return { "ld h,h" }; - case 0x65: return { "ld h,l" }; - case 0x66: return { "ld h,(hl)" }; - case 0x67: return { "ld h,a" }; - case 0x68: return { "ld l,b" }; - case 0x69: return { "ld l,c" }; - case 0x6a: return { "ld l,d" }; - case 0x6b: return { "ld l,e" }; - case 0x6c: return { "ld l,h" }; - case 0x6d: return { "ld l,l" }; - case 0x6e: return { "ld l,(hl)" }; - case 0x6f: return { "ld l,a" }; - case 0x70: return { "ld (hl),b" }; - case 0x71: return { "ld (hl),c" }; - case 0x72: return { "ld (hl),d" }; - case 0x73: return { "ld (hl),e" }; - case 0x74: return { "ld (hl),h" }; - case 0x75: return { "ld (hl),l" }; - case 0x76: return { "halt" }; - case 0x77: return { "ld (hl),a" }; - case 0x78: return { "ld a,b" }; - case 0x79: return { "ld a,c" }; - case 0x7a: return { "ld a,d" }; - case 0x7b: return { "ld a,e" }; - case 0x7c: return { "ld a,h" }; - case 0x7d: return { "ld a,l" }; - case 0x7e: return { "ld a,(hl)" }; - case 0x7f: return { "ld a,a" }; - case 0x80: return { "add a,b" }; - case 0x81: return { "add a,c" }; - case 0x82: return { "add a,d" }; - case 0x83: return { "add a,e" }; - case 0x84: return { "add a,h" }; - case 0x85: return { "add a,l" }; - case 0x86: return { "add a,(hl)" }; - case 0x87: return { "add a,a" }; - case 0x88: return { "adc a,b" }; - case 0x89: return { "adc a,c" }; - case 0x8a: return { "adc a,d" }; - case 0x8b: return { "adc a,e" }; - case 0x8c: return { "adc a,h" }; - case 0x8d: return { "adc a,l" }; - case 0x8e: return { "adc a,(hl)" }; - case 0x8f: return { "adc a,a" }; - case 0x90: return { "sub a,b" }; - case 0x91: return { "sub a,c" }; - case 0x92: return { "sub a,d" }; - case 0x93: return { "sub a,e" }; - case 0x94: return { "sub a,h" }; - case 0x95: return { "sub a,l" }; - case 0x96: return { "sub a,(hl)" }; - case 0x97: return { "sub a,a" }; - case 0x98: return { "sbc a,b" }; - case 0x99: return { "sbc a,c" }; - case 0x9a: return { "sbc a,d" }; - case 0x9b: return { "sbc a,e" }; - case 0x9c: return { "sbc a,h" }; - case 0x9d: return { "sbc a,l" }; - case 0x9e: return { "sbc a,(hl)" }; - case 0x9f: return { "sbc a,a" }; - case 0xa0: return { "and a,b" }; - case 0xa1: return { "and a,c" }; - case 0xa2: return { "and a,d" }; - case 0xa3: return { "and a,e" }; - case 0xa4: return { "and a,h" }; - case 0xa5: return { "and a,l" }; - case 0xa6: return { "and a,(hl)" }; - case 0xa7: return { "and a,a" }; - case 0xa8: return { "xor a,b" }; - case 0xa9: return { "xor a,c" }; - case 0xaa: return { "xor a,d" }; - case 0xab: return { "xor a,e" }; - case 0xac: return { "xor a,h" }; - case 0xad: return { "xor a,l" }; - case 0xae: return { "xor a,(hl)" }; - case 0xaf: return { "xor a,a" }; - case 0xb0: return { "or a,b" }; - case 0xb1: return { "or a,c" }; - case 0xb2: return { "or a,d" }; - case 0xb3: return { "or a,e" }; - case 0xb4: return { "or a,h" }; - case 0xb5: return { "or a,l" }; - case 0xb6: return { "or a,(hl)" }; - case 0xb7: return { "or a,a" }; - case 0xb8: return { "cp a,b" }; - case 0xb9: return { "cp a,c" }; - case 0xba: return { "cp a,d" }; - case 0xbb: return { "cp a,e" }; - case 0xbc: return { "cp a,h" }; - case 0xbd: return { "cp a,l" }; - case 0xbe: return { "cp a,(hl)" }; - case 0xbf: return { "cp a,a" }; - case 0xc0: return { "ret nz" }; - case 0xc1: return { "pop bc" }; - case 0xc2: return { "jp nz,$", hex<2>(p1), hex<2>(p0) }; - case 0xc3: return { "jp $", hex<2>(p1), hex<2>(p0) }; - case 0xc4: return { "call nz,$", hex<2>(p1), hex<2>(p0) }; - case 0xc5: return { "push bc" }; - case 0xc6: return { "add a,$", hex<2>(p0) }; - case 0xc7: return { "rst $0000" }; - case 0xc8: return { "ret z" }; - case 0xc9: return { "ret" }; - case 0xca: return { "jp z,$", hex<2>(p1), hex<2>(p0) }; + case 0x00: return string( "nop" ); + case 0x01: return string( "ld bc,$", hex<2>(p1), hex<2>(p0) ); + case 0x02: return string( "ld (bc),a" ); + case 0x03: return string( "inc bc" ); + case 0x04: return string( "inc b" ); + case 0x05: return string( "dec b" ); + case 0x06: return string( "ld b,$", hex<2>(p0) ); + case 0x07: return string( "rlc a" ); + case 0x08: return string( "ld ($", hex<2>(p1), hex<2>(p0), "),sp" ); + case 0x09: return string( "add hl,bc" ); + case 0x0a: return string( "ld a,(bc)" ); + case 0x0b: return string( "dec bc" ); + case 0x0c: return string( "inc c" ); + case 0x0d: return string( "dec c" ); + case 0x0e: return string( "ld c,$", hex<2>(p0) ); + case 0x0f: return string( "rrc a" ); + case 0x10: return string( "stop" ); + case 0x11: return string( "ld de,$", hex<2>(p1), hex<2>(p0) ); + case 0x12: return string( "ld (de),a" ); + case 0x13: return string( "inc de" ); + case 0x14: return string( "inc d" ); + case 0x15: return string( "dec d" ); + case 0x16: return string( "ld d,$", hex<2>(p0) ); + case 0x17: return string( "rl a" ); + case 0x18: return string( "jr $", hex<4>(r[PC] + 2 + (int8)p0) ); + case 0x19: return string( "add hl,de" ); + case 0x1a: return string( "ld a,(de)" ); + case 0x1b: return string( "dec de" ); + case 0x1c: return string( "inc e" ); + case 0x1d: return string( "dec e" ); + case 0x1e: return string( "ld e,$", hex<2>(p0) ); + case 0x1f: return string( "rr a" ); + case 0x20: return string( "jr nz,$", hex<4>(r[PC] + 2 + (int8)p0) ); + case 0x21: return string( "ld hl,$", hex<2>(p1), hex<2>(p0) ); + case 0x22: return string( "ldi (hl),a" ); + case 0x23: return string( "inc hl" ); + case 0x24: return string( "inc h" ); + case 0x25: return string( "dec h" ); + case 0x26: return string( "ld h,$", hex<2>(p0) ); + case 0x27: return string( "daa" ); + case 0x28: return string( "jr z,$", hex<4>(r[PC] + 2 + (int8)p0) ); + case 0x29: return string( "add hl,hl" ); + case 0x2a: return string( "ldi a,(hl)" ); + case 0x2b: return string( "dec hl" ); + case 0x2c: return string( "inc l" ); + case 0x2d: return string( "dec l" ); + case 0x2e: return string( "ld l,$", hex<2>(p0) ); + case 0x2f: return string( "cpl" ); + case 0x30: return string( "jr nc,$", hex<4>(r[PC] + 2 + (int8)p0) ); + case 0x31: return string( "ld sp,$", hex<2>(p1), hex<2>(p0) ); + case 0x32: return string( "ldd (hl),a" ); + case 0x33: return string( "inc sp" ); + case 0x34: return string( "inc (hl)" ); + case 0x35: return string( "dec (hl)" ); + case 0x36: return string( "ld (hl),$", hex<2>(p0) ); + case 0x37: return string( "scf" ); + case 0x38: return string( "jr c,$", hex<4>(r[PC] + 2 + (int8)p0) ); + case 0x39: return string( "add hl,sp" ); + case 0x3a: return string( "ldd a,(hl)" ); + case 0x3b: return string( "dec sp" ); + case 0x3c: return string( "inc a" ); + case 0x3d: return string( "dec a" ); + case 0x3e: return string( "ld a,$", hex<2>(p0) ); + case 0x3f: return string( "ccf" ); + case 0x40: return string( "ld b,b" ); + case 0x41: return string( "ld b,c" ); + case 0x42: return string( "ld b,d" ); + case 0x43: return string( "ld b,e" ); + case 0x44: return string( "ld b,h" ); + case 0x45: return string( "ld b,l" ); + case 0x46: return string( "ld b,(hl)" ); + case 0x47: return string( "ld b,a" ); + case 0x48: return string( "ld c,b" ); + case 0x49: return string( "ld c,c" ); + case 0x4a: return string( "ld c,d" ); + case 0x4b: return string( "ld c,e" ); + case 0x4c: return string( "ld c,h" ); + case 0x4d: return string( "ld c,l" ); + case 0x4e: return string( "ld c,(hl)" ); + case 0x4f: return string( "ld c,a" ); + case 0x50: return string( "ld d,b" ); + case 0x51: return string( "ld d,c" ); + case 0x52: return string( "ld d,d" ); + case 0x53: return string( "ld d,e" ); + case 0x54: return string( "ld d,h" ); + case 0x55: return string( "ld d,l" ); + case 0x56: return string( "ld d,(hl)" ); + case 0x57: return string( "ld d,a" ); + case 0x58: return string( "ld e,b" ); + case 0x59: return string( "ld e,c" ); + case 0x5a: return string( "ld e,d" ); + case 0x5b: return string( "ld e,e" ); + case 0x5c: return string( "ld e,h" ); + case 0x5d: return string( "ld e,l" ); + case 0x5e: return string( "ld e,(hl)" ); + case 0x5f: return string( "ld e,a" ); + case 0x60: return string( "ld h,b" ); + case 0x61: return string( "ld h,c" ); + case 0x62: return string( "ld h,d" ); + case 0x63: return string( "ld h,e" ); + case 0x64: return string( "ld h,h" ); + case 0x65: return string( "ld h,l" ); + case 0x66: return string( "ld h,(hl)" ); + case 0x67: return string( "ld h,a" ); + case 0x68: return string( "ld l,b" ); + case 0x69: return string( "ld l,c" ); + case 0x6a: return string( "ld l,d" ); + case 0x6b: return string( "ld l,e" ); + case 0x6c: return string( "ld l,h" ); + case 0x6d: return string( "ld l,l" ); + case 0x6e: return string( "ld l,(hl)" ); + case 0x6f: return string( "ld l,a" ); + case 0x70: return string( "ld (hl),b" ); + case 0x71: return string( "ld (hl),c" ); + case 0x72: return string( "ld (hl),d" ); + case 0x73: return string( "ld (hl),e" ); + case 0x74: return string( "ld (hl),h" ); + case 0x75: return string( "ld (hl),l" ); + case 0x76: return string( "halt" ); + case 0x77: return string( "ld (hl),a" ); + case 0x78: return string( "ld a,b" ); + case 0x79: return string( "ld a,c" ); + case 0x7a: return string( "ld a,d" ); + case 0x7b: return string( "ld a,e" ); + case 0x7c: return string( "ld a,h" ); + case 0x7d: return string( "ld a,l" ); + case 0x7e: return string( "ld a,(hl)" ); + case 0x7f: return string( "ld a,a" ); + case 0x80: return string( "add a,b" ); + case 0x81: return string( "add a,c" ); + case 0x82: return string( "add a,d" ); + case 0x83: return string( "add a,e" ); + case 0x84: return string( "add a,h" ); + case 0x85: return string( "add a,l" ); + case 0x86: return string( "add a,(hl)" ); + case 0x87: return string( "add a,a" ); + case 0x88: return string( "adc a,b" ); + case 0x89: return string( "adc a,c" ); + case 0x8a: return string( "adc a,d" ); + case 0x8b: return string( "adc a,e" ); + case 0x8c: return string( "adc a,h" ); + case 0x8d: return string( "adc a,l" ); + case 0x8e: return string( "adc a,(hl)" ); + case 0x8f: return string( "adc a,a" ); + case 0x90: return string( "sub a,b" ); + case 0x91: return string( "sub a,c" ); + case 0x92: return string( "sub a,d" ); + case 0x93: return string( "sub a,e" ); + case 0x94: return string( "sub a,h" ); + case 0x95: return string( "sub a,l" ); + case 0x96: return string( "sub a,(hl)" ); + case 0x97: return string( "sub a,a" ); + case 0x98: return string( "sbc a,b" ); + case 0x99: return string( "sbc a,c" ); + case 0x9a: return string( "sbc a,d" ); + case 0x9b: return string( "sbc a,e" ); + case 0x9c: return string( "sbc a,h" ); + case 0x9d: return string( "sbc a,l" ); + case 0x9e: return string( "sbc a,(hl)" ); + case 0x9f: return string( "sbc a,a" ); + case 0xa0: return string( "and a,b" ); + case 0xa1: return string( "and a,c" ); + case 0xa2: return string( "and a,d" ); + case 0xa3: return string( "and a,e" ); + case 0xa4: return string( "and a,h" ); + case 0xa5: return string( "and a,l" ); + case 0xa6: return string( "and a,(hl)" ); + case 0xa7: return string( "and a,a" ); + case 0xa8: return string( "xor a,b" ); + case 0xa9: return string( "xor a,c" ); + case 0xaa: return string( "xor a,d" ); + case 0xab: return string( "xor a,e" ); + case 0xac: return string( "xor a,h" ); + case 0xad: return string( "xor a,l" ); + case 0xae: return string( "xor a,(hl)" ); + case 0xaf: return string( "xor a,a" ); + case 0xb0: return string( "or a,b" ); + case 0xb1: return string( "or a,c" ); + case 0xb2: return string( "or a,d" ); + case 0xb3: return string( "or a,e" ); + case 0xb4: return string( "or a,h" ); + case 0xb5: return string( "or a,l" ); + case 0xb6: return string( "or a,(hl)" ); + case 0xb7: return string( "or a,a" ); + case 0xb8: return string( "cp a,b" ); + case 0xb9: return string( "cp a,c" ); + case 0xba: return string( "cp a,d" ); + case 0xbb: return string( "cp a,e" ); + case 0xbc: return string( "cp a,h" ); + case 0xbd: return string( "cp a,l" ); + case 0xbe: return string( "cp a,(hl)" ); + case 0xbf: return string( "cp a,a" ); + case 0xc0: return string( "ret nz" ); + case 0xc1: return string( "pop bc" ); + case 0xc2: return string( "jp nz,$", hex<2>(p1), hex<2>(p0) ); + case 0xc3: return string( "jp $", hex<2>(p1), hex<2>(p0) ); + case 0xc4: return string( "call nz,$", hex<2>(p1), hex<2>(p0) ); + case 0xc5: return string( "push bc" ); + case 0xc6: return string( "add a,$", hex<2>(p0) ); + case 0xc7: return string( "rst $0000" ); + case 0xc8: return string( "ret z" ); + case 0xc9: return string( "ret" ); + case 0xca: return string( "jp z,$", hex<2>(p1), hex<2>(p0) ); case 0xcb: return disassemble_opcode_cb(pc + 1); - case 0xcc: return { "call z,$", hex<2>(p1), hex<2>(p0) }; - case 0xcd: return { "call $", hex<2>(p1), hex<2>(p0) }; - case 0xce: return { "adc a,$", hex<2>(p0) }; - case 0xcf: return { "rst $0008" }; - case 0xd0: return { "ret nc" }; - case 0xd1: return { "pop de" }; - case 0xd2: return { "jp nc,$", hex<2>(p1), hex<2>(p0) }; - case 0xd3: return { "xx" }; - case 0xd4: return { "call nc,$", hex<2>(p1), hex<2>(p0) }; - case 0xd5: return { "push de" }; - case 0xd6: return { "sub a,$", hex<2>(p0) }; - case 0xd7: return { "rst $0010" }; - case 0xd8: return { "ret c" }; - case 0xd9: return { "reti" }; - case 0xda: return { "jp c,$", hex<2>(p1), hex<2>(p0) }; - case 0xdb: return { "xx" }; - case 0xdc: return { "call c,$", hex<2>(p1), hex<2>(p0) }; - case 0xdd: return { "xx" }; - case 0xde: return { "sbc a,$", hex<2>(p0) }; - case 0xdf: return { "rst $0018" }; - case 0xe0: return { "ld ($ff", hex<2>(p0), "),a" }; - case 0xe1: return { "pop hl" }; - case 0xe2: return { "ld ($ff00+c),a" }; - case 0xe3: return { "xx" }; - case 0xe4: return { "xx" }; - case 0xe5: return { "push hl" }; - case 0xe6: return { "and a,$", hex<2>(p0) }; - case 0xe7: return { "rst $0020" }; - case 0xe8: return { "add sp,$", hex<4>((int8)p0) }; - case 0xe9: return { "jp hl" }; - case 0xea: return { "ld ($", hex<2>(p1), hex<2>(p0), "),a" }; - case 0xeb: return { "xx" }; - case 0xec: return { "xx" }; - case 0xed: return { "xx" }; - case 0xee: return { "xor a,$", hex<2>(p0) }; - case 0xef: return { "rst $0028" }; - case 0xf0: return { "ld a,($ff", hex<2>(p0), ")" }; - case 0xf1: return { "pop af" }; - case 0xf2: return { "ld a,($ff00+c)" }; - case 0xf3: return { "di" }; - case 0xf4: return { "xx" }; - case 0xf5: return { "push af" }; - case 0xf6: return { "or a,$", hex<2>(p0) }; - case 0xf7: return { "rst $0030" }; - case 0xf8: return { "ld hl,sp+$", hex<4>((int8)p0) }; - case 0xf9: return { "ld sp,hl" }; - case 0xfa: return { "ld a,($", hex<2>(p1), hex<2>(p0), ")" }; - case 0xfb: return { "ei" }; - case 0xfc: return { "xx" }; - case 0xfd: return { "xx" }; - case 0xfe: return { "cp a,$", hex<2>(p0) }; - case 0xff: return { "rst $0038" }; + case 0xcc: return string( "call z,$", hex<2>(p1), hex<2>(p0) ); + case 0xcd: return string( "call $", hex<2>(p1), hex<2>(p0) ); + case 0xce: return string( "adc a,$", hex<2>(p0) ); + case 0xcf: return string( "rst $0008" ); + case 0xd0: return string( "ret nc" ); + case 0xd1: return string( "pop de" ); + case 0xd2: return string( "jp nc,$", hex<2>(p1), hex<2>(p0) ); + case 0xd3: return string( "xx" ); + case 0xd4: return string( "call nc,$", hex<2>(p1), hex<2>(p0) ); + case 0xd5: return string( "push de" ); + case 0xd6: return string( "sub a,$", hex<2>(p0) ); + case 0xd7: return string( "rst $0010" ); + case 0xd8: return string( "ret c" ); + case 0xd9: return string( "reti" ); + case 0xda: return string( "jp c,$", hex<2>(p1), hex<2>(p0) ); + case 0xdb: return string( "xx" ); + case 0xdc: return string( "call c,$", hex<2>(p1), hex<2>(p0) ); + case 0xdd: return string( "xx" ); + case 0xde: return string( "sbc a,$", hex<2>(p0) ); + case 0xdf: return string( "rst $0018" ); + case 0xe0: return string( "ld ($ff", hex<2>(p0), "),a" ); + case 0xe1: return string( "pop hl" ); + case 0xe2: return string( "ld ($ff00+c),a" ); + case 0xe3: return string( "xx" ); + case 0xe4: return string( "xx" ); + case 0xe5: return string( "push hl" ); + case 0xe6: return string( "and a,$", hex<2>(p0) ); + case 0xe7: return string( "rst $0020" ); + case 0xe8: return string( "add sp,$", hex<4>((int8)p0) ); + case 0xe9: return string( "jp hl" ); + case 0xea: return string( "ld ($", hex<2>(p1), hex<2>(p0), "),a" ); + case 0xeb: return string( "xx" ); + case 0xec: return string( "xx" ); + case 0xed: return string( "xx" ); + case 0xee: return string( "xor a,$", hex<2>(p0) ); + case 0xef: return string( "rst $0028" ); + case 0xf0: return string( "ld a,($ff", hex<2>(p0), ")" ); + case 0xf1: return string( "pop af" ); + case 0xf2: return string( "ld a,($ff00+c)" ); + case 0xf3: return string( "di" ); + case 0xf4: return string( "xx" ); + case 0xf5: return string( "push af" ); + case 0xf6: return string( "or a,$", hex<2>(p0) ); + case 0xf7: return string( "rst $0030" ); + case 0xf8: return string( "ld hl,sp+$", hex<4>((int8)p0) ); + case 0xf9: return string( "ld sp,hl" ); + case 0xfa: return string( "ld a,($", hex<2>(p1), hex<2>(p0), ")" ); + case 0xfb: return string( "ei" ); + case 0xfc: return string( "xx" ); + case 0xfd: return string( "xx" ); + case 0xfe: return string( "cp a,$", hex<2>(p0) ); + case 0xff: return string( "rst $0038" ); } return ""; @@ -296,262 +298,262 @@ string CPU::disassemble_opcode_cb(uint16 pc) { uint8 p2 = bus.read(pc + 3); switch(opcode) { - case 0x00: return { "rlc b" }; - case 0x01: return { "rlc c" }; - case 0x02: return { "rlc d" }; - case 0x03: return { "rlc e" }; - case 0x04: return { "rlc h" }; - case 0x05: return { "rlc l" }; - case 0x06: return { "rlc (hl)" }; - case 0x07: return { "rlc a" }; - case 0x08: return { "rrc b" }; - case 0x09: return { "rrc c" }; - case 0x0a: return { "rrc d" }; - case 0x0b: return { "rrc e" }; - case 0x0c: return { "rrc h" }; - case 0x0d: return { "rrc l" }; - case 0x0e: return { "rrc (hl)" }; - case 0x0f: return { "rrc a" }; - case 0x10: return { "rl b" }; - case 0x11: return { "rl c" }; - case 0x12: return { "rl d" }; - case 0x13: return { "rl e" }; - case 0x14: return { "rl h" }; - case 0x15: return { "rl l" }; - case 0x16: return { "rl (hl)" }; - case 0x17: return { "rl a" }; - case 0x18: return { "rr b" }; - case 0x19: return { "rr c" }; - case 0x1a: return { "rr d" }; - case 0x1b: return { "rr e" }; - case 0x1c: return { "rr h" }; - case 0x1d: return { "rr l" }; - case 0x1e: return { "rr (hl)" }; - case 0x1f: return { "rr a" }; - case 0x20: return { "sla b" }; - case 0x21: return { "sla c" }; - case 0x22: return { "sla d" }; - case 0x23: return { "sla e" }; - case 0x24: return { "sla h" }; - case 0x25: return { "sla l" }; - case 0x26: return { "sla (hl)" }; - case 0x27: return { "sla a" }; - case 0x28: return { "sra b" }; - case 0x29: return { "sra c" }; - case 0x2a: return { "sra d" }; - case 0x2b: return { "sra e" }; - case 0x2c: return { "sra h" }; - case 0x2d: return { "sra l" }; - case 0x2e: return { "sra (hl)" }; - case 0x2f: return { "sra a" }; - case 0x30: return { "swap b" }; - case 0x31: return { "swap c" }; - case 0x32: return { "swap d" }; - case 0x33: return { "swap e" }; - case 0x34: return { "swap h" }; - case 0x35: return { "swap l" }; - case 0x36: return { "swap (hl)" }; - case 0x37: return { "swap a" }; - case 0x38: return { "srl b" }; - case 0x39: return { "srl c" }; - case 0x3a: return { "srl d" }; - case 0x3b: return { "srl e" }; - case 0x3c: return { "srl h" }; - case 0x3d: return { "srl l" }; - case 0x3e: return { "srl (hl)" }; - case 0x3f: return { "srl a" }; - case 0x40: return { "bit 0,b" }; - case 0x41: return { "bit 0,c" }; - case 0x42: return { "bit 0,d" }; - case 0x43: return { "bit 0,e" }; - case 0x44: return { "bit 0,h" }; - case 0x45: return { "bit 0,l" }; - case 0x46: return { "bit 0,(hl)" }; - case 0x47: return { "bit 0,a" }; - case 0x48: return { "bit 1,b" }; - case 0x49: return { "bit 1,c" }; - case 0x4a: return { "bit 1,d" }; - case 0x4b: return { "bit 1,e" }; - case 0x4c: return { "bit 1,h" }; - case 0x4d: return { "bit 1,l" }; - case 0x4e: return { "bit 1,(hl)" }; - case 0x4f: return { "bit 1,a" }; - case 0x50: return { "bit 2,b" }; - case 0x51: return { "bit 2,c" }; - case 0x52: return { "bit 2,d" }; - case 0x53: return { "bit 2,e" }; - case 0x54: return { "bit 2,h" }; - case 0x55: return { "bit 2,l" }; - case 0x56: return { "bit 2,(hl)" }; - case 0x57: return { "bit 2,a" }; - case 0x58: return { "bit 3,b" }; - case 0x59: return { "bit 3,c" }; - case 0x5a: return { "bit 3,d" }; - case 0x5b: return { "bit 3,e" }; - case 0x5c: return { "bit 3,h" }; - case 0x5d: return { "bit 3,l" }; - case 0x5e: return { "bit 3,(hl)" }; - case 0x5f: return { "bit 3,a" }; - case 0x60: return { "bit 4,b" }; - case 0x61: return { "bit 4,c" }; - case 0x62: return { "bit 4,d" }; - case 0x63: return { "bit 4,e" }; - case 0x64: return { "bit 4,h" }; - case 0x65: return { "bit 4,l" }; - case 0x66: return { "bit 4,(hl)" }; - case 0x67: return { "bit 4,a" }; - case 0x68: return { "bit 5,b" }; - case 0x69: return { "bit 5,c" }; - case 0x6a: return { "bit 5,d" }; - case 0x6b: return { "bit 5,e" }; - case 0x6c: return { "bit 5,h" }; - case 0x6d: return { "bit 5,l" }; - case 0x6e: return { "bit 5,(hl)" }; - case 0x6f: return { "bit 5,a" }; - case 0x70: return { "bit 6,b" }; - case 0x71: return { "bit 6,c" }; - case 0x72: return { "bit 6,d" }; - case 0x73: return { "bit 6,e" }; - case 0x74: return { "bit 6,h" }; - case 0x75: return { "bit 6,l" }; - case 0x76: return { "bit 6,(hl)" }; - case 0x77: return { "bit 6,a" }; - case 0x78: return { "bit 7,b" }; - case 0x79: return { "bit 7,c" }; - case 0x7a: return { "bit 7,d" }; - case 0x7b: return { "bit 7,e" }; - case 0x7c: return { "bit 7,h" }; - case 0x7d: return { "bit 7,l" }; - case 0x7e: return { "bit 7,(hl)" }; - case 0x7f: return { "bit 7,a" }; - case 0x80: return { "res 0,b" }; - case 0x81: return { "res 0,c" }; - case 0x82: return { "res 0,d" }; - case 0x83: return { "res 0,e" }; - case 0x84: return { "res 0,h" }; - case 0x85: return { "res 0,l" }; - case 0x86: return { "res 0,(hl)" }; - case 0x87: return { "res 0,a" }; - case 0x88: return { "res 1,b" }; - case 0x89: return { "res 1,c" }; - case 0x8a: return { "res 1,d" }; - case 0x8b: return { "res 1,e" }; - case 0x8c: return { "res 1,h" }; - case 0x8d: return { "res 1,l" }; - case 0x8e: return { "res 1,(hl)" }; - case 0x8f: return { "res 1,a" }; - case 0x90: return { "res 2,b" }; - case 0x91: return { "res 2,c" }; - case 0x92: return { "res 2,d" }; - case 0x93: return { "res 2,e" }; - case 0x94: return { "res 2,h" }; - case 0x95: return { "res 2,l" }; - case 0x96: return { "res 2,(hl)" }; - case 0x97: return { "res 2,a" }; - case 0x98: return { "res 3,b" }; - case 0x99: return { "res 3,c" }; - case 0x9a: return { "res 3,d" }; - case 0x9b: return { "res 3,e" }; - case 0x9c: return { "res 3,h" }; - case 0x9d: return { "res 3,l" }; - case 0x9e: return { "res 3,(hl)" }; - case 0x9f: return { "res 3,a" }; - case 0xa0: return { "res 4,b" }; - case 0xa1: return { "res 4,c" }; - case 0xa2: return { "res 4,d" }; - case 0xa3: return { "res 4,e" }; - case 0xa4: return { "res 4,h" }; - case 0xa5: return { "res 4,l" }; - case 0xa6: return { "res 4,(hl)" }; - case 0xa7: return { "res 4,a" }; - case 0xa8: return { "res 5,b" }; - case 0xa9: return { "res 5,c" }; - case 0xaa: return { "res 5,d" }; - case 0xab: return { "res 5,e" }; - case 0xac: return { "res 5,h" }; - case 0xad: return { "res 5,l" }; - case 0xae: return { "res 5,(hl)" }; - case 0xaf: return { "res 5,a" }; - case 0xb0: return { "res 6,b" }; - case 0xb1: return { "res 6,c" }; - case 0xb2: return { "res 6,d" }; - case 0xb3: return { "res 6,e" }; - case 0xb4: return { "res 6,h" }; - case 0xb5: return { "res 6,l" }; - case 0xb6: return { "res 6,(hl)" }; - case 0xb7: return { "res 6,a" }; - case 0xb8: return { "res 7,b" }; - case 0xb9: return { "res 7,c" }; - case 0xba: return { "res 7,d" }; - case 0xbb: return { "res 7,e" }; - case 0xbc: return { "res 7,h" }; - case 0xbd: return { "res 7,l" }; - case 0xbe: return { "res 7,(hl)" }; - case 0xbf: return { "res 7,a" }; - case 0xc0: return { "set 0,b" }; - case 0xc1: return { "set 0,c" }; - case 0xc2: return { "set 0,d" }; - case 0xc3: return { "set 0,e" }; - case 0xc4: return { "set 0,h" }; - case 0xc5: return { "set 0,l" }; - case 0xc6: return { "set 0,(hl)" }; - case 0xc7: return { "set 0,a" }; - case 0xc8: return { "set 1,b" }; - case 0xc9: return { "set 1,c" }; - case 0xca: return { "set 1,d" }; - case 0xcb: return { "set 1,e" }; - case 0xcc: return { "set 1,h" }; - case 0xcd: return { "set 1,l" }; - case 0xce: return { "set 1,(hl)" }; - case 0xcf: return { "set 1,a" }; - case 0xd0: return { "set 2,b" }; - case 0xd1: return { "set 2,c" }; - case 0xd2: return { "set 2,d" }; - case 0xd3: return { "set 2,e" }; - case 0xd4: return { "set 2,h" }; - case 0xd5: return { "set 2,l" }; - case 0xd6: return { "set 2,(hl)" }; - case 0xd7: return { "set 2,a" }; - case 0xd8: return { "set 3,b" }; - case 0xd9: return { "set 3,c" }; - case 0xda: return { "set 3,d" }; - case 0xdb: return { "set 3,e" }; - case 0xdc: return { "set 3,h" }; - case 0xdd: return { "set 3,l" }; - case 0xde: return { "set 3,(hl)" }; - case 0xdf: return { "set 3,a" }; - case 0xe0: return { "set 4,b" }; - case 0xe1: return { "set 4,c" }; - case 0xe2: return { "set 4,d" }; - case 0xe3: return { "set 4,e" }; - case 0xe4: return { "set 4,h" }; - case 0xe5: return { "set 4,l" }; - case 0xe6: return { "set 4,(hl)" }; - case 0xe7: return { "set 4,a" }; - case 0xe8: return { "set 5,b" }; - case 0xe9: return { "set 5,c" }; - case 0xea: return { "set 5,d" }; - case 0xeb: return { "set 5,e" }; - case 0xec: return { "set 5,h" }; - case 0xed: return { "set 5,l" }; - case 0xee: return { "set 5,(hl)" }; - case 0xef: return { "set 5,a" }; - case 0xf0: return { "set 6,b" }; - case 0xf1: return { "set 6,c" }; - case 0xf2: return { "set 6,d" }; - case 0xf3: return { "set 6,e" }; - case 0xf4: return { "set 6,h" }; - case 0xf5: return { "set 6,l" }; - case 0xf6: return { "set 6,(hl)" }; - case 0xf7: return { "set 6,a" }; - case 0xf8: return { "set 7,b" }; - case 0xf9: return { "set 7,c" }; - case 0xfa: return { "set 7,d" }; - case 0xfb: return { "set 7,e" }; - case 0xfc: return { "set 7,h" }; - case 0xfd: return { "set 7,l" }; - case 0xfe: return { "set 7,(hl)" }; - case 0xff: return { "set 7,a" }; + case 0x00: return string( "rlc b" ); + case 0x01: return string( "rlc c" ); + case 0x02: return string( "rlc d" ); + case 0x03: return string( "rlc e" ); + case 0x04: return string( "rlc h" ); + case 0x05: return string( "rlc l" ); + case 0x06: return string( "rlc (hl)" ); + case 0x07: return string( "rlc a" ); + case 0x08: return string( "rrc b" ); + case 0x09: return string( "rrc c" ); + case 0x0a: return string( "rrc d" ); + case 0x0b: return string( "rrc e" ); + case 0x0c: return string( "rrc h" ); + case 0x0d: return string( "rrc l" ); + case 0x0e: return string( "rrc (hl)" ); + case 0x0f: return string( "rrc a" ); + case 0x10: return string( "rl b" ); + case 0x11: return string( "rl c" ); + case 0x12: return string( "rl d" ); + case 0x13: return string( "rl e" ); + case 0x14: return string( "rl h" ); + case 0x15: return string( "rl l" ); + case 0x16: return string( "rl (hl)" ); + case 0x17: return string( "rl a" ); + case 0x18: return string( "rr b" ); + case 0x19: return string( "rr c" ); + case 0x1a: return string( "rr d" ); + case 0x1b: return string( "rr e" ); + case 0x1c: return string( "rr h" ); + case 0x1d: return string( "rr l" ); + case 0x1e: return string( "rr (hl)" ); + case 0x1f: return string( "rr a" ); + case 0x20: return string( "sla b" ); + case 0x21: return string( "sla c" ); + case 0x22: return string( "sla d" ); + case 0x23: return string( "sla e" ); + case 0x24: return string( "sla h" ); + case 0x25: return string( "sla l" ); + case 0x26: return string( "sla (hl)" ); + case 0x27: return string( "sla a" ); + case 0x28: return string( "sra b" ); + case 0x29: return string( "sra c" ); + case 0x2a: return string( "sra d" ); + case 0x2b: return string( "sra e" ); + case 0x2c: return string( "sra h" ); + case 0x2d: return string( "sra l" ); + case 0x2e: return string( "sra (hl)" ); + case 0x2f: return string( "sra a" ); + case 0x30: return string( "swap b" ); + case 0x31: return string( "swap c" ); + case 0x32: return string( "swap d" ); + case 0x33: return string( "swap e" ); + case 0x34: return string( "swap h" ); + case 0x35: return string( "swap l" ); + case 0x36: return string( "swap (hl)" ); + case 0x37: return string( "swap a" ); + case 0x38: return string( "srl b" ); + case 0x39: return string( "srl c" ); + case 0x3a: return string( "srl d" ); + case 0x3b: return string( "srl e" ); + case 0x3c: return string( "srl h" ); + case 0x3d: return string( "srl l" ); + case 0x3e: return string( "srl (hl)" ); + case 0x3f: return string( "srl a" ); + case 0x40: return string( "bit 0,b" ); + case 0x41: return string( "bit 0,c" ); + case 0x42: return string( "bit 0,d" ); + case 0x43: return string( "bit 0,e" ); + case 0x44: return string( "bit 0,h" ); + case 0x45: return string( "bit 0,l" ); + case 0x46: return string( "bit 0,(hl)" ); + case 0x47: return string( "bit 0,a" ); + case 0x48: return string( "bit 1,b" ); + case 0x49: return string( "bit 1,c" ); + case 0x4a: return string( "bit 1,d" ); + case 0x4b: return string( "bit 1,e" ); + case 0x4c: return string( "bit 1,h" ); + case 0x4d: return string( "bit 1,l" ); + case 0x4e: return string( "bit 1,(hl)" ); + case 0x4f: return string( "bit 1,a" ); + case 0x50: return string( "bit 2,b" ); + case 0x51: return string( "bit 2,c" ); + case 0x52: return string( "bit 2,d" ); + case 0x53: return string( "bit 2,e" ); + case 0x54: return string( "bit 2,h" ); + case 0x55: return string( "bit 2,l" ); + case 0x56: return string( "bit 2,(hl)" ); + case 0x57: return string( "bit 2,a" ); + case 0x58: return string( "bit 3,b" ); + case 0x59: return string( "bit 3,c" ); + case 0x5a: return string( "bit 3,d" ); + case 0x5b: return string( "bit 3,e" ); + case 0x5c: return string( "bit 3,h" ); + case 0x5d: return string( "bit 3,l" ); + case 0x5e: return string( "bit 3,(hl)" ); + case 0x5f: return string( "bit 3,a" ); + case 0x60: return string( "bit 4,b" ); + case 0x61: return string( "bit 4,c" ); + case 0x62: return string( "bit 4,d" ); + case 0x63: return string( "bit 4,e" ); + case 0x64: return string( "bit 4,h" ); + case 0x65: return string( "bit 4,l" ); + case 0x66: return string( "bit 4,(hl)" ); + case 0x67: return string( "bit 4,a" ); + case 0x68: return string( "bit 5,b" ); + case 0x69: return string( "bit 5,c" ); + case 0x6a: return string( "bit 5,d" ); + case 0x6b: return string( "bit 5,e" ); + case 0x6c: return string( "bit 5,h" ); + case 0x6d: return string( "bit 5,l" ); + case 0x6e: return string( "bit 5,(hl)" ); + case 0x6f: return string( "bit 5,a" ); + case 0x70: return string( "bit 6,b" ); + case 0x71: return string( "bit 6,c" ); + case 0x72: return string( "bit 6,d" ); + case 0x73: return string( "bit 6,e" ); + case 0x74: return string( "bit 6,h" ); + case 0x75: return string( "bit 6,l" ); + case 0x76: return string( "bit 6,(hl)" ); + case 0x77: return string( "bit 6,a" ); + case 0x78: return string( "bit 7,b" ); + case 0x79: return string( "bit 7,c" ); + case 0x7a: return string( "bit 7,d" ); + case 0x7b: return string( "bit 7,e" ); + case 0x7c: return string( "bit 7,h" ); + case 0x7d: return string( "bit 7,l" ); + case 0x7e: return string( "bit 7,(hl)" ); + case 0x7f: return string( "bit 7,a" ); + case 0x80: return string( "res 0,b" ); + case 0x81: return string( "res 0,c" ); + case 0x82: return string( "res 0,d" ); + case 0x83: return string( "res 0,e" ); + case 0x84: return string( "res 0,h" ); + case 0x85: return string( "res 0,l" ); + case 0x86: return string( "res 0,(hl)" ); + case 0x87: return string( "res 0,a" ); + case 0x88: return string( "res 1,b" ); + case 0x89: return string( "res 1,c" ); + case 0x8a: return string( "res 1,d" ); + case 0x8b: return string( "res 1,e" ); + case 0x8c: return string( "res 1,h" ); + case 0x8d: return string( "res 1,l" ); + case 0x8e: return string( "res 1,(hl)" ); + case 0x8f: return string( "res 1,a" ); + case 0x90: return string( "res 2,b" ); + case 0x91: return string( "res 2,c" ); + case 0x92: return string( "res 2,d" ); + case 0x93: return string( "res 2,e" ); + case 0x94: return string( "res 2,h" ); + case 0x95: return string( "res 2,l" ); + case 0x96: return string( "res 2,(hl)" ); + case 0x97: return string( "res 2,a" ); + case 0x98: return string( "res 3,b" ); + case 0x99: return string( "res 3,c" ); + case 0x9a: return string( "res 3,d" ); + case 0x9b: return string( "res 3,e" ); + case 0x9c: return string( "res 3,h" ); + case 0x9d: return string( "res 3,l" ); + case 0x9e: return string( "res 3,(hl)" ); + case 0x9f: return string( "res 3,a" ); + case 0xa0: return string( "res 4,b" ); + case 0xa1: return string( "res 4,c" ); + case 0xa2: return string( "res 4,d" ); + case 0xa3: return string( "res 4,e" ); + case 0xa4: return string( "res 4,h" ); + case 0xa5: return string( "res 4,l" ); + case 0xa6: return string( "res 4,(hl)" ); + case 0xa7: return string( "res 4,a" ); + case 0xa8: return string( "res 5,b" ); + case 0xa9: return string( "res 5,c" ); + case 0xaa: return string( "res 5,d" ); + case 0xab: return string( "res 5,e" ); + case 0xac: return string( "res 5,h" ); + case 0xad: return string( "res 5,l" ); + case 0xae: return string( "res 5,(hl)" ); + case 0xaf: return string( "res 5,a" ); + case 0xb0: return string( "res 6,b" ); + case 0xb1: return string( "res 6,c" ); + case 0xb2: return string( "res 6,d" ); + case 0xb3: return string( "res 6,e" ); + case 0xb4: return string( "res 6,h" ); + case 0xb5: return string( "res 6,l" ); + case 0xb6: return string( "res 6,(hl)" ); + case 0xb7: return string( "res 6,a" ); + case 0xb8: return string( "res 7,b" ); + case 0xb9: return string( "res 7,c" ); + case 0xba: return string( "res 7,d" ); + case 0xbb: return string( "res 7,e" ); + case 0xbc: return string( "res 7,h" ); + case 0xbd: return string( "res 7,l" ); + case 0xbe: return string( "res 7,(hl)" ); + case 0xbf: return string( "res 7,a" ); + case 0xc0: return string( "set 0,b" ); + case 0xc1: return string( "set 0,c" ); + case 0xc2: return string( "set 0,d" ); + case 0xc3: return string( "set 0,e" ); + case 0xc4: return string( "set 0,h" ); + case 0xc5: return string( "set 0,l" ); + case 0xc6: return string( "set 0,(hl)" ); + case 0xc7: return string( "set 0,a" ); + case 0xc8: return string( "set 1,b" ); + case 0xc9: return string( "set 1,c" ); + case 0xca: return string( "set 1,d" ); + case 0xcb: return string( "set 1,e" ); + case 0xcc: return string( "set 1,h" ); + case 0xcd: return string( "set 1,l" ); + case 0xce: return string( "set 1,(hl)" ); + case 0xcf: return string( "set 1,a" ); + case 0xd0: return string( "set 2,b" ); + case 0xd1: return string( "set 2,c" ); + case 0xd2: return string( "set 2,d" ); + case 0xd3: return string( "set 2,e" ); + case 0xd4: return string( "set 2,h" ); + case 0xd5: return string( "set 2,l" ); + case 0xd6: return string( "set 2,(hl)" ); + case 0xd7: return string( "set 2,a" ); + case 0xd8: return string( "set 3,b" ); + case 0xd9: return string( "set 3,c" ); + case 0xda: return string( "set 3,d" ); + case 0xdb: return string( "set 3,e" ); + case 0xdc: return string( "set 3,h" ); + case 0xdd: return string( "set 3,l" ); + case 0xde: return string( "set 3,(hl)" ); + case 0xdf: return string( "set 3,a" ); + case 0xe0: return string( "set 4,b" ); + case 0xe1: return string( "set 4,c" ); + case 0xe2: return string( "set 4,d" ); + case 0xe3: return string( "set 4,e" ); + case 0xe4: return string( "set 4,h" ); + case 0xe5: return string( "set 4,l" ); + case 0xe6: return string( "set 4,(hl)" ); + case 0xe7: return string( "set 4,a" ); + case 0xe8: return string( "set 5,b" ); + case 0xe9: return string( "set 5,c" ); + case 0xea: return string( "set 5,d" ); + case 0xeb: return string( "set 5,e" ); + case 0xec: return string( "set 5,h" ); + case 0xed: return string( "set 5,l" ); + case 0xee: return string( "set 5,(hl)" ); + case 0xef: return string( "set 5,a" ); + case 0xf0: return string( "set 6,b" ); + case 0xf1: return string( "set 6,c" ); + case 0xf2: return string( "set 6,d" ); + case 0xf3: return string( "set 6,e" ); + case 0xf4: return string( "set 6,h" ); + case 0xf5: return string( "set 6,l" ); + case 0xf6: return string( "set 6,(hl)" ); + case 0xf7: return string( "set 6,a" ); + case 0xf8: return string( "set 7,b" ); + case 0xf9: return string( "set 7,c" ); + case 0xfa: return string( "set 7,d" ); + case 0xfb: return string( "set 7,e" ); + case 0xfc: return string( "set 7,h" ); + case 0xfd: return string( "set 7,l" ); + case 0xfe: return string( "set 7,(hl)" ); + case 0xff: return string( "set 7,a" ); } return ""; diff --git a/gameboy/cpu/cpu.cpp b/gameboy/cpu/cpu.cpp index e234857..bcf18f3 100755 --- a/gameboy/cpu/cpu.cpp +++ b/gameboy/cpu/cpu.cpp @@ -15,8 +15,8 @@ void CPU::Main() { void CPU::main() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::CPU) { - scheduler.sync = Scheduler::SynchronizeMode::All; + if(scheduler.sync.i == Scheduler::SynchronizeMode::CPU) { + scheduler.sync.i = Scheduler::SynchronizeMode::All; scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } @@ -27,7 +27,7 @@ void CPU::main() { } } -void CPU::interrupt_raise(CPU::Interrupt id) { +void CPU::interrupt_raise(CPU::Interrupt::e id) { switch(id) { case Interrupt::Vblank: status.interrupt_request_vblank = 1; break; case Interrupt::Stat : status.interrupt_request_stat = 1; break; diff --git a/gameboy/cpu/cpu.hpp b/gameboy/cpu/cpu.hpp index d84568b..132425d 100755 --- a/gameboy/cpu/cpu.hpp +++ b/gameboy/cpu/cpu.hpp @@ -5,12 +5,22 @@ struct CPU : Processor, MMIO { bool trace; - enum class Interrupt : unsigned { - Vblank, - Stat, - Timer, - Serial, - Joypad, + //enum class Interrupt : unsigned { + // Vblank, + // Stat, + // Timer, + // Serial, + // Joypad, + //}; + + struct Interrupt { + enum e { + Vblank, + Stat, + Timer, + Serial, + Joypad, + } i; }; struct Status { @@ -63,7 +73,7 @@ struct CPU : Processor, MMIO { static void Main(); void main(); - void interrupt_raise(Interrupt id); + void interrupt_raise(Interrupt::e id); void interrupt_test(); void interrupt_exec(uint16 pc); void power(); diff --git a/gameboy/lcd/lcd.cpp b/gameboy/lcd/lcd.cpp index 7d6ce88..e9a9266 100755 --- a/gameboy/lcd/lcd.cpp +++ b/gameboy/lcd/lcd.cpp @@ -13,7 +13,7 @@ void LCD::Main() { void LCD::main() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { + if(scheduler.sync.i == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } @@ -30,7 +30,7 @@ void LCD::add_clocks(unsigned clocks) { if(status.lx >= 456) scanline(); cpu.clock -= clocks; - if(cpu.clock <= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) { + if(cpu.clock <= 0 && scheduler.sync.i != Scheduler::SynchronizeMode::All) { co_switch(scheduler.active_thread = cpu.thread); } } diff --git a/gameboy/scheduler/scheduler.cpp b/gameboy/scheduler/scheduler.cpp index 14bd733..88611a8 100755 --- a/gameboy/scheduler/scheduler.cpp +++ b/gameboy/scheduler/scheduler.cpp @@ -10,8 +10,8 @@ void Scheduler::enter() { co_switch(active_thread); } -void Scheduler::exit(ExitReason reason) { - exit_reason = reason; +void Scheduler::exit(ExitReason::e reason) { + exit_reason.i = reason; active_thread = co_active(); co_switch(host_thread); } @@ -27,7 +27,7 @@ void Scheduler::init() { } Scheduler::Scheduler() { - exit_reason = ExitReason::UnknownEvent; + exit_reason.i = ExitReason::UnknownEvent; host_thread = 0; active_thread = 0; } diff --git a/gameboy/scheduler/scheduler.hpp b/gameboy/scheduler/scheduler.hpp index ccdb78e..da9d7c8 100755 --- a/gameboy/scheduler/scheduler.hpp +++ b/gameboy/scheduler/scheduler.hpp @@ -1,13 +1,16 @@ struct Scheduler : property { - enum class SynchronizeMode : unsigned { None, CPU, All } sync; - enum class ExitReason : unsigned { UnknownEvent, StepEvent, FrameEvent, SynchronizeEvent }; - readonly exit_reason; + //enum class SynchronizeMode : unsigned { None, CPU, All } sync; + //enum class ExitReason : unsigned { UnknownEvent, StepEvent, FrameEvent, SynchronizeEvent }; + struct SynchronizeMode { enum e { None, CPU, All } i; } sync; + struct ExitReason { enum e { UnknownEvent, StepEvent, FrameEvent, SynchronizeEvent } i; }; + + ExitReason exit_reason; cothread_t host_thread; cothread_t active_thread; void enter(); - void exit(ExitReason); + void exit(ExitReason::e); void swapto(Processor&); void init(); diff --git a/gameboy/system/system.cpp b/gameboy/system/system.cpp index 29ac155..7949bb4 100755 --- a/gameboy/system/system.cpp +++ b/gameboy/system/system.cpp @@ -9,15 +9,15 @@ namespace GameBoy { System system; void System::run() { - scheduler.sync = Scheduler::SynchronizeMode::None; + scheduler.sync.i = Scheduler::SynchronizeMode::None; scheduler.enter(); - if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) { + if(scheduler.exit_reason.i == Scheduler::ExitReason::FrameEvent) { } } void System::runtosave() { - scheduler.sync = Scheduler::SynchronizeMode::CPU; + scheduler.sync.i = Scheduler::SynchronizeMode::CPU; runthreadtosave(); scheduler.active_thread = lcd.thread; @@ -27,8 +27,8 @@ void System::runtosave() { void System::runthreadtosave() { while(true) { scheduler.enter(); - if(scheduler.exit_reason() == Scheduler::ExitReason::SynchronizeEvent) break; - if(scheduler.exit_reason() == Scheduler::ExitReason::FrameEvent) { + if(scheduler.exit_reason.i == Scheduler::ExitReason::SynchronizeEvent) break; + if(scheduler.exit_reason.i == Scheduler::ExitReason::FrameEvent) { } } } diff --git a/gameboy/system/system.hpp b/gameboy/system/system.hpp index 40ff657..3be9460 100755 --- a/gameboy/system/system.hpp +++ b/gameboy/system/system.hpp @@ -1,7 +1,11 @@ class Interface; -enum class Input : unsigned { - Up, Down, Left, Right, B, A, Select, Start, +//enum class Input : unsigned { +// Up, Down, Left, Right, B, A, Select, Start, +//}; + +struct Input { + enum e { Up, Down, Left, Right, B, A, Select, Start, }; }; struct System : MMIO { diff --git a/nall/varint.hpp b/nall/varint.hpp index 5d51584..a5f1636 100644 --- a/nall/varint.hpp +++ b/nall/varint.hpp @@ -110,7 +110,7 @@ namespace nall { inline void bits(unsigned bits) { mask = (1ULL << (bits - 1)) + ((1ULL << (bits - 1)) - 1); data &= mask; } inline varuintmax_t() : data(0), mask(~0ULL) {} - inline varuintmax_t(const uintmax_t i) : data(i), + inline varuintmax_t(const uintmax_t i) : data(i), mask(~0ULL) {} }; } diff --git a/snes/Makefile b/snes/Makefile index 860d1e7..96c1527 100644 --- a/snes/Makefile +++ b/snes/Makefile @@ -32,6 +32,8 @@ endif obj/libsnes.o: $(snes)/libsnes/libsnes.cpp $(snes)/libsnes/* +obj/libco.o : libco/libco.c libco/* + obj/snes-system.o : $(snes)/system/system.cpp $(call rwildcard,$(snes)/system/) $(call rwildcard,$(snes)/video/) obj/snes-memory.o : $(snes)/memory/memory.cpp $(call rwildcard,$(snes)/memory/) obj/snes-cpucore.o : $(snes)/cpu/core/core.cpp $(call rwildcard,$(snes)/cpu/core/) diff --git a/snes/cartridge/xml.cpp b/snes/cartridge/xml.cpp index 3b0d734..5edb1e2 100644 --- a/snes/cartridge/xml.cpp +++ b/snes/cartridge/xml.cpp @@ -95,7 +95,7 @@ void Cartridge::xml_parse_ram(xml_element &root) { } void Cartridge::xml_parse_icd2(xml_element &root) { - if(mode != Mode::SuperGameBoy) return; + if(mode.i != Mode::SuperGameBoy) return; icd2.revision = 1; foreach(attr, root.attribute) { @@ -227,7 +227,7 @@ void Cartridge::xml_parse_sa1(xml_element &root) { void Cartridge::xml_parse_necdsp(xml_element &root) { has_necdsp = true; - necdsp.revision = NECDSP::Revision::uPD7725; + necdsp.revision.i = NECDSP::Revision::uPD7725; necdsp.frequency = 8000000; for(unsigned n = 0; n < 16384; n++) necdsp.programROM[n] = 0x000000; @@ -238,8 +238,8 @@ void Cartridge::xml_parse_necdsp(xml_element &root) { foreach(attr, root.attribute) { if(attr.name == "revision") { - if(attr.content == "upd7725" ) necdsp.revision = NECDSP::Revision::uPD7725; - if(attr.content == "upd96050") necdsp.revision = NECDSP::Revision::uPD96050; + if(attr.content == "upd7725" ) necdsp.revision.i = NECDSP::Revision::uPD7725; + if(attr.content == "upd96050") necdsp.revision.i = NECDSP::Revision::uPD96050; } else if(attr.name == "frequency") { necdsp.frequency = decimal(attr.content); } else if(attr.name == "program") { @@ -249,12 +249,12 @@ void Cartridge::xml_parse_necdsp(xml_element &root) { } } - unsigned promsize = (necdsp.revision == NECDSP::Revision::uPD7725 ? 2048 : 16384); - unsigned dromsize = (necdsp.revision == NECDSP::Revision::uPD7725 ? 1024 : 2048); + unsigned promsize = (necdsp.revision.i == NECDSP::Revision::uPD7725 ? 2048 : 16384); + unsigned dromsize = (necdsp.revision.i == NECDSP::Revision::uPD7725 ? 1024 : 2048); unsigned filesize = promsize * 3 + dromsize * 2; file fp; - if(fp.open(string(dir(basename()), program), file::mode::read)) { + if(fp.open(string(dir(basename()), program), file::mode_read)) { if(fp.size() == filesize) { for(unsigned n = 0; n < promsize; n++) necdsp.programROM[n] = fp.readm(3); for(unsigned n = 0; n < dromsize; n++) necdsp.dataROM[n] = fp.readm(2); @@ -312,8 +312,8 @@ void Cartridge::xml_parse_necdsp(xml_element &root) { } else if(sha256 != "" && sha256 != programhash) { system.interface->message(string( "Warning: NEC DSP program ", program, " SHA256 is incorrect.\n\n" - "Expected:\n", xml_hash, "\n\n" - "Actual:\n", rom_hash + "Expected:\n", sha256, "\n\n" + "Actual:\n", programhash )); } } @@ -401,7 +401,7 @@ void Cartridge::xml_parse_srtc(xml_element &root) { foreach(node, root.element) { if(node.name == "map") { - Mapping m(strc); + Mapping m(srtc); foreach(attr, node.attribute) { if (attr.name == "address") xml_parse_address(m, attr.content); } diff --git a/snes/chip/icd2/icd2.cpp b/snes/chip/icd2/icd2.cpp index 8c7ccfc..f960cb5 100644 --- a/snes/chip/icd2/icd2.cpp +++ b/snes/chip/icd2/icd2.cpp @@ -12,7 +12,7 @@ void ICD2::Enter() { icd2.enter(); } void ICD2::enter() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { + if(scheduler.sync.i == Scheduler::SynchronizeMode::All) { GameBoy::system.runtosave(); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } diff --git a/snes/chip/necdsp/disassembler.cpp b/snes/chip/necdsp/disassembler.cpp index c28aaa1..a97ebdd 100644 --- a/snes/chip/necdsp/disassembler.cpp +++ b/snes/chip/necdsp/disassembler.cpp @@ -1,7 +1,7 @@ #ifdef NECDSP_CPP string NECDSP::disassemble(uint14 ip) { - string output = { hex<4>(ip), " " }; + string output = string(hex<4>(ip), " "); uint24 opcode = programROM[ip]; uint2 type = opcode >> 22; diff --git a/snes/chip/necdsp/necdsp.cpp b/snes/chip/necdsp/necdsp.cpp index fed7775..2bc3a8d 100644 --- a/snes/chip/necdsp/necdsp.cpp +++ b/snes/chip/necdsp/necdsp.cpp @@ -12,7 +12,7 @@ void NECDSP::Enter() { necdsp.enter(); } void NECDSP::enter() { while(true) { - if(scheduler.sync == Scheduler::SynchronizeMode::All) { + if(scheduler.sync.i == Scheduler::SynchronizeMode::All) { scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); } @@ -254,14 +254,14 @@ void NECDSP::enable() { } void NECDSP::power() { - if(revision == Revision::uPD7725) { + if(revision.i == Revision::uPD7725) { regs.pc.bits(11); regs.rp.bits(10); regs.dp.bits( 8); dpmask = 0x000000, dptest = 0xffffff; //uPD7725 not mapped to SNES bus } - if(revision == Revision::uPD96050) { + if(revision.i == Revision::uPD96050) { regs.pc.bits(14); regs.rp.bits(11); regs.dp.bits(11); diff --git a/snes/chip/necdsp/necdsp.hpp b/snes/chip/necdsp/necdsp.hpp index 9ea8222..679c3cb 100644 --- a/snes/chip/necdsp/necdsp.hpp +++ b/snes/chip/necdsp/necdsp.hpp @@ -1,6 +1,7 @@ class NECDSP : public Coprocessor, public Memory { public: - enum class Revision : unsigned { uPD7725, uPD96050 } revision; + //enum class Revision : unsigned { uPD7725, uPD96050 } revision; + struct Revision { enum e { uPD7725, uPD96050 } i; } revision; unsigned frequency; unsigned drmask, drtest; unsigned srmask, srtest; diff --git a/snes/libsnes/libsnes.cpp b/snes/libsnes/libsnes.cpp index d772b04..77a08eb 100644 --- a/snes/libsnes/libsnes.cpp +++ b/snes/libsnes/libsnes.cpp @@ -175,12 +175,21 @@ bool snes_load_cartridge_super_game_boy( const char *rom_xml, const uint8_t *rom_data, unsigned rom_size, const char *dmg_xml, const uint8_t *dmg_data, unsigned dmg_size ) { + + string xmlrom, xmldmg; snes_cheat_reset(); - if(rom_data) SNES::memory::cartrom.copy(rom_data, rom_size); - string xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; - if(dmg_data) SNES::memory::gbrom.copy(dmg_data, dmg_size); - string xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : SNESCartridge(dmg_data, dmg_size).xmlMemoryMap; - SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, lstring(xmlrom, xmldmg)); + + if (rom_data) { + xmlrom = (rom_xml && *rom_xml) ? string(rom_xml) : SNESCartridge(rom_data, rom_size).xmlMemoryMap; + SNES::memory::cartrom.copy(rom_data, rom_size); + } + + if (dmg_data) { + xmldmg = (dmg_xml && *dmg_xml) ? string(dmg_xml) : GameBoyCartridge(dmg_data, dmg_size).xml; + GameBoy::cartridge.load(xmldmg, dmg_data, dmg_size); + } + + SNES::cartridge.load(SNES::Cartridge::Mode::SuperGameBoy, string(xmlrom, "")); SNES::system.power(); return true; } @@ -215,12 +224,10 @@ uint8_t* snes_get_memory_data(unsigned id) { return SNES::memory::stBram.data(); case SNES_MEMORY_GAME_BOY_RAM: if(SNES::cartridge.mode.i != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbram.data(); + return GameBoy::cartridge.ramdata; case SNES_MEMORY_GAME_BOY_RTC: if(SNES::cartridge.mode.i != SNES::Cartridge::Mode::SuperGameBoy) break; - SNES::supergameboy.save(); - return SNES::memory::gbrtc.data(); + return 0; // FIXME: Where is this stored? } return 0; @@ -255,12 +262,11 @@ unsigned snes_get_memory_size(unsigned id) { break; case SNES_MEMORY_GAME_BOY_RAM: if(SNES::cartridge.mode.i != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbram.size(); + size = GameBoy::cartridge.ramsize; break; case SNES_MEMORY_GAME_BOY_RTC: if(SNES::cartridge.mode.i != SNES::Cartridge::Mode::SuperGameBoy) break; - size = SNES::memory::gbrtc.size(); - break; + size = 0; // FIXME: Where is this stored? } if(size == -1U) size = 0; diff --git a/snes/system/system.cpp b/snes/system/system.cpp index b0882e0..55b0039 100644 --- a/snes/system/system.cpp +++ b/snes/system/system.cpp @@ -156,7 +156,7 @@ void System::power() { if(cartridge.mode.i == Cartridge::Mode::SuperGameBoy) cpu.coprocessors.append(&icd2); if(cartridge.has_superfx()) cpu.coprocessors.append(&superfx); if(cartridge.has_sa1()) cpu.coprocessors.append(&sa1); - if(cartridge.has_upd77c25()) cpu.coprocessors.append(&necdsp); + if(cartridge.has_necdsp()) cpu.coprocessors.append(&necdsp); if(cartridge.has_msu1()) cpu.coprocessors.append(&msu1); if(cartridge.has_serial()) cpu.coprocessors.append(&serial);