mirror of https://github.com/bsnes-emu/bsnes.git
Update to v072r04 release.
(there was no r03 release posted to the WIP thread) byuu says: nall/snes/smp.hpp created, ~68 addressing modes compared to the CPU's ~27, ugh. All hooked up, you can step into / step over / trace the S-SMP now as well.
This commit is contained in:
parent
0730f847e5
commit
edac93b800
|
@ -1,13 +1,12 @@
|
||||||
#ifndef NALL_SNES_INFO_HPP
|
#ifndef NALL_SNES_CARTRIDGE_HPP
|
||||||
#define NALL_SNES_INFO_HPP
|
#define NALL_SNES_CARTRIDGE_HPP
|
||||||
|
|
||||||
namespace nall {
|
namespace nall {
|
||||||
|
|
||||||
class snes_information {
|
class SNESCartridge {
|
||||||
public:
|
public:
|
||||||
string xml_memory_map;
|
string xmlMemoryMap;
|
||||||
|
inline SNESCartridge(const uint8_t *data, unsigned size);
|
||||||
inline snes_information(const uint8_t *data, unsigned size);
|
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
inline void read_header(const uint8_t *data, unsigned size);
|
inline void read_header(const uint8_t *data, unsigned size);
|
||||||
|
@ -106,20 +105,20 @@ public:
|
||||||
bool has_st018;
|
bool has_st018;
|
||||||
};
|
};
|
||||||
|
|
||||||
snes_information::snes_information(const uint8_t *data, unsigned size) {
|
SNESCartridge::SNESCartridge(const uint8_t *data, unsigned size) {
|
||||||
read_header(data, size);
|
read_header(data, size);
|
||||||
|
|
||||||
string xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
string xml = "<?xml version='1.0' encoding='UTF-8'?>\n";
|
||||||
|
|
||||||
if(type == TypeBsx) {
|
if(type == TypeBsx) {
|
||||||
xml << "<cartridge/>";
|
xml << "<cartridge/>";
|
||||||
xml_memory_map = xml;
|
xmlMemoryMap = xml;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(type == TypeSufamiTurbo) {
|
if(type == TypeSufamiTurbo) {
|
||||||
xml << "<cartridge/>";
|
xml << "<cartridge/>";
|
||||||
xml_memory_map = xml;
|
xmlMemoryMap = xml;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,7 +128,7 @@ snes_information::snes_information(const uint8_t *data, unsigned size) {
|
||||||
xml << " <ram size='" << strhex(gameboy_ram_size(data, size)) << "'/>\n";
|
xml << " <ram size='" << strhex(gameboy_ram_size(data, size)) << "'/>\n";
|
||||||
}
|
}
|
||||||
xml << "</cartridge>\n";
|
xml << "</cartridge>\n";
|
||||||
xml_memory_map = xml;
|
xmlMemoryMap = xml;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,10 +517,10 @@ snes_information::snes_information(const uint8_t *data, unsigned size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
xml << "</cartridge>\n";
|
xml << "</cartridge>\n";
|
||||||
xml_memory_map = xml;
|
xmlMemoryMap = xml;
|
||||||
}
|
}
|
||||||
|
|
||||||
void snes_information::read_header(const uint8_t *data, unsigned size) {
|
void SNESCartridge::read_header(const uint8_t *data, unsigned size) {
|
||||||
type = TypeUnknown;
|
type = TypeUnknown;
|
||||||
mapper = LoROM;
|
mapper = LoROM;
|
||||||
dsp1_mapper = DSP1Unmapped;
|
dsp1_mapper = DSP1Unmapped;
|
||||||
|
@ -749,7 +748,7 @@ void snes_information::read_header(const uint8_t *data, unsigned size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned snes_information::find_header(const uint8_t *data, unsigned size) {
|
unsigned SNESCartridge::find_header(const uint8_t *data, unsigned size) {
|
||||||
unsigned score_lo = score_header(data, size, 0x007fc0);
|
unsigned score_lo = score_header(data, size, 0x007fc0);
|
||||||
unsigned score_hi = score_header(data, size, 0x00ffc0);
|
unsigned score_hi = score_header(data, size, 0x00ffc0);
|
||||||
unsigned score_ex = score_header(data, size, 0x40ffc0);
|
unsigned score_ex = score_header(data, size, 0x40ffc0);
|
||||||
|
@ -764,7 +763,7 @@ unsigned snes_information::find_header(const uint8_t *data, unsigned size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned snes_information::score_header(const uint8_t *data, unsigned size, unsigned addr) {
|
unsigned SNESCartridge::score_header(const uint8_t *data, unsigned size, unsigned addr) {
|
||||||
if(size < addr + 64) return 0; //image too small to contain header at this location?
|
if(size < addr + 64) return 0; //image too small to contain header at this location?
|
||||||
int score = 0;
|
int score = 0;
|
||||||
|
|
||||||
|
@ -845,7 +844,7 @@ unsigned snes_information::score_header(const uint8_t *data, unsigned size, unsi
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned snes_information::gameboy_ram_size(const uint8_t *data, unsigned size) {
|
unsigned SNESCartridge::gameboy_ram_size(const uint8_t *data, unsigned size) {
|
||||||
if(size < 512) return 0;
|
if(size < 512) return 0;
|
||||||
switch(data[0x0149]) {
|
switch(data[0x0149]) {
|
||||||
case 0x00: return 0 * 1024;
|
case 0x00: return 0 * 1024;
|
||||||
|
@ -858,7 +857,7 @@ unsigned snes_information::gameboy_ram_size(const uint8_t *data, unsigned size)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool snes_information::gameboy_has_rtc(const uint8_t *data, unsigned size) {
|
bool SNESCartridge::gameboy_has_rtc(const uint8_t *data, unsigned size) {
|
||||||
if(size < 512) return false;
|
if(size < 512) return false;
|
||||||
if(data[0x0147] == 0x0f ||data[0x0147] == 0x10) return true;
|
if(data[0x0147] == 0x0f ||data[0x0147] == 0x10) return true;
|
||||||
return false;
|
return false;
|
|
@ -40,7 +40,7 @@ struct SNESCPU {
|
||||||
|
|
||||||
static const OpcodeInfo opcodeInfo[256];
|
static const OpcodeInfo opcodeInfo[256];
|
||||||
|
|
||||||
static unsigned getOpcodeLength(uint8_t status, uint8_t opcode);
|
static unsigned getOpcodeLength(bool accum, bool index, uint8_t opcode);
|
||||||
static string disassemble(unsigned pc, bool accum, bool index, uint8_t opcode, uint8_t pl, uint8_t ph, uint8_t pb);
|
static string disassemble(unsigned pc, bool accum, bool index, uint8_t opcode, uint8_t pl, uint8_t ph, uint8_t pb);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -382,12 +382,12 @@ const SNESCPU::OpcodeInfo SNESCPU::opcodeInfo[256] = {
|
||||||
{ "sbc", LongX },
|
{ "sbc", LongX },
|
||||||
};
|
};
|
||||||
|
|
||||||
inline unsigned SNESCPU::getOpcodeLength(uint8_t status, uint8_t opcode) {
|
inline unsigned SNESCPU::getOpcodeLength(bool accum, bool index, uint8_t opcode) {
|
||||||
switch(opcodeInfo[opcode].mode) { default:
|
switch(opcodeInfo[opcode].mode) { default:
|
||||||
case Implied: return 1;
|
case Implied: return 1;
|
||||||
case Constant: return 2;
|
case Constant: return 2;
|
||||||
case AccumConstant: return 3 - (bool)(status & 0x20);
|
case AccumConstant: return 3 - accum;
|
||||||
case IndexConstant: return 3 - (bool)(status & 0x10);
|
case IndexConstant: return 3 - index;
|
||||||
case Direct: return 2;
|
case Direct: return 2;
|
||||||
case DirectX: return 2;
|
case DirectX: return 2;
|
||||||
case DirectY: return 2;
|
case DirectY: return 2;
|
||||||
|
|
|
@ -0,0 +1,639 @@
|
||||||
|
#ifndef NALL_SNES_SMP_HPP
|
||||||
|
#define NALL_SNES_SMP_HPP
|
||||||
|
|
||||||
|
namespace nall {
|
||||||
|
|
||||||
|
struct SNESSMP {
|
||||||
|
enum : unsigned {
|
||||||
|
Implied, //
|
||||||
|
TVector, //0
|
||||||
|
Direct, //$00
|
||||||
|
DirectRelative, //$00,+/-$00
|
||||||
|
ADirect, //a,$00
|
||||||
|
AAbsolute, //a,$0000
|
||||||
|
AIX, //a,(x)
|
||||||
|
AIDirectX, //a,($00+x)
|
||||||
|
AConstant, //a,#$00
|
||||||
|
DirectDirect, //$00,$00
|
||||||
|
CAbsoluteBit, //c,$0000:0
|
||||||
|
Absolute, //$0000
|
||||||
|
P, //p
|
||||||
|
AbsoluteA, //$0000,a
|
||||||
|
Relative, //+/-$00
|
||||||
|
ADirectX, //a,$00+x
|
||||||
|
AAbsoluteX, //a,$0000+x
|
||||||
|
AAbsoluteY, //a,$0000+y
|
||||||
|
AIDirectY, //a,($00)+y
|
||||||
|
DirectConstant, //$00,#$00
|
||||||
|
IXIY, //(x),(y)
|
||||||
|
DirectX, //$00+x
|
||||||
|
A, //a
|
||||||
|
X, //x
|
||||||
|
XAbsolute, //x,$0000
|
||||||
|
IAbsoluteX, //($0000+x)
|
||||||
|
CNAbsoluteBit, //c,!$0000:0
|
||||||
|
XDirect, //x,$00
|
||||||
|
PVector, //$ff00
|
||||||
|
YaDirect, //ya,$00
|
||||||
|
XA, //x,a
|
||||||
|
YAbsolute, //y,$0000
|
||||||
|
Y, //y
|
||||||
|
AX, //a,x
|
||||||
|
YDirect, //y,$00
|
||||||
|
YConstant, //y,#$00
|
||||||
|
XSp, //x,sp
|
||||||
|
YaX, //ya,x
|
||||||
|
IXPA, //(x)+,a
|
||||||
|
SpX, //sp,x
|
||||||
|
AIXP, //a,(x)+
|
||||||
|
DirectA, //$00,a
|
||||||
|
IXA, //(x),a
|
||||||
|
IDirectXA, //($00+x),a
|
||||||
|
XConstant, //x,#$00
|
||||||
|
AbsoluteX, //$0000,x
|
||||||
|
AbsoluteBitC, //$0000:0,c
|
||||||
|
DirectY, //$00,y
|
||||||
|
AbsoluteY, //$0000,y
|
||||||
|
Ya, //ya
|
||||||
|
DirectXA, //$00+x,a
|
||||||
|
AbsoluteXA, //$0000+x,a
|
||||||
|
AbsoluteYA, //$0000+y,a
|
||||||
|
IDirectYA, //($00)+y,a
|
||||||
|
DirectYX, //$00+y,x
|
||||||
|
DirectYa, //$00,ya
|
||||||
|
DirectXY, //$00+x,y
|
||||||
|
AY, //a,y
|
||||||
|
DirectXRelative, //$00+x,+/-$00
|
||||||
|
XDirectY, //x,$00+y
|
||||||
|
YDirectX, //y,$00+x
|
||||||
|
YA, //y,a
|
||||||
|
YRelative, //y,+/-$00
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OpcodeInfo {
|
||||||
|
char name[6];
|
||||||
|
unsigned mode;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const OpcodeInfo opcodeInfo[256];
|
||||||
|
|
||||||
|
static unsigned getOpcodeLength(uint8_t opcode);
|
||||||
|
static string disassemble(uint16_t pc, uint8_t opcode, uint8_t pl, uint8_t ph);
|
||||||
|
static string disassemble(uint16_t pc, bool p, uint8_t opcode, uint8_t pl, uint8_t ph);
|
||||||
|
};
|
||||||
|
|
||||||
|
const SNESSMP::OpcodeInfo SNESSMP::opcodeInfo[256] = {
|
||||||
|
//0x00 - 0x0f
|
||||||
|
{ "nop ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set0 ", Direct },
|
||||||
|
{ "bbs0 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "or ", ADirect },
|
||||||
|
{ "or ", AAbsolute },
|
||||||
|
{ "or ", AIX },
|
||||||
|
{ "or ", AIDirectX },
|
||||||
|
|
||||||
|
{ "or ", AConstant },
|
||||||
|
{ "or ", DirectDirect },
|
||||||
|
{ "or1 ", CAbsoluteBit },
|
||||||
|
{ "asl ", Direct },
|
||||||
|
|
||||||
|
{ "asl ", Absolute },
|
||||||
|
{ "push ", P },
|
||||||
|
{ "tset ", AbsoluteA },
|
||||||
|
{ "brk ", Implied },
|
||||||
|
|
||||||
|
//0x10 - 0x1f
|
||||||
|
{ "bpl ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr0 ", Direct },
|
||||||
|
{ "bbc0 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "or ", ADirectX },
|
||||||
|
{ "or ", AAbsoluteX },
|
||||||
|
{ "or ", AAbsoluteY },
|
||||||
|
{ "or ", AIDirectY },
|
||||||
|
|
||||||
|
{ "or ", DirectConstant },
|
||||||
|
{ "or ", IXIY },
|
||||||
|
{ "decw ", Direct },
|
||||||
|
{ "asl ", DirectX },
|
||||||
|
|
||||||
|
{ "asl ", A },
|
||||||
|
{ "dec ", X },
|
||||||
|
{ "cmp ", XAbsolute },
|
||||||
|
{ "jmp ", IAbsoluteX },
|
||||||
|
|
||||||
|
//0x20 - 0x2f
|
||||||
|
{ "clrp ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set1 ", Direct },
|
||||||
|
{ "bbs1 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "and ", ADirect },
|
||||||
|
{ "and ", AAbsolute },
|
||||||
|
{ "and ", AIX },
|
||||||
|
{ "and ", AIDirectX },
|
||||||
|
|
||||||
|
{ "and ", AConstant },
|
||||||
|
{ "and ", DirectDirect },
|
||||||
|
{ "or1 ", CNAbsoluteBit },
|
||||||
|
{ "rol ", Direct },
|
||||||
|
|
||||||
|
{ "rol ", Absolute },
|
||||||
|
{ "push ", A },
|
||||||
|
{ "cbne ", DirectRelative },
|
||||||
|
{ "bra ", Relative },
|
||||||
|
|
||||||
|
//0x30 - 0x3f
|
||||||
|
{ "bmi ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr1 ", Direct },
|
||||||
|
{ "bbc1 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "and ", ADirectX },
|
||||||
|
{ "and ", AAbsoluteX },
|
||||||
|
{ "and ", AAbsoluteY },
|
||||||
|
{ "and ", AIDirectY },
|
||||||
|
|
||||||
|
{ "and ", DirectConstant },
|
||||||
|
{ "and ", IXIY },
|
||||||
|
{ "incw ", Direct },
|
||||||
|
{ "rol ", DirectX },
|
||||||
|
|
||||||
|
{ "rol ", A },
|
||||||
|
{ "inc ", X },
|
||||||
|
{ "cmp ", XDirect },
|
||||||
|
{ "call ", Absolute },
|
||||||
|
|
||||||
|
//0x40 - 0x4f
|
||||||
|
{ "setp ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set2 ", Direct },
|
||||||
|
{ "bbs2 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "eor ", ADirect },
|
||||||
|
{ "eor ", AAbsolute },
|
||||||
|
{ "eor ", AIX },
|
||||||
|
{ "eor ", AIDirectX },
|
||||||
|
|
||||||
|
{ "eor ", AConstant },
|
||||||
|
{ "eor ", DirectDirect },
|
||||||
|
{ "and1 ", CAbsoluteBit },
|
||||||
|
{ "lsr ", Direct },
|
||||||
|
|
||||||
|
{ "lsr ", Absolute },
|
||||||
|
{ "push ", X },
|
||||||
|
{ "tclr ", AbsoluteA },
|
||||||
|
{ "pcall", PVector },
|
||||||
|
|
||||||
|
//0x50 - 0x5f
|
||||||
|
{ "bvc ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr2 ", Direct },
|
||||||
|
{ "bbc2 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "eor ", ADirectX },
|
||||||
|
{ "eor ", AAbsoluteX },
|
||||||
|
{ "eor ", AAbsoluteY },
|
||||||
|
{ "eor ", AIDirectY },
|
||||||
|
|
||||||
|
{ "eor ", DirectConstant },
|
||||||
|
{ "eor ", IXIY },
|
||||||
|
{ "cmpw ", YaDirect },
|
||||||
|
{ "lsr ", DirectX },
|
||||||
|
|
||||||
|
{ "lsr ", A },
|
||||||
|
{ "mov ", XA },
|
||||||
|
{ "cmp ", YAbsolute },
|
||||||
|
{ "jmp ", Absolute },
|
||||||
|
|
||||||
|
//0x60 - 0x6f
|
||||||
|
{ "clrc ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set3 ", Direct },
|
||||||
|
{ "bbs3 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "cmp ", ADirect },
|
||||||
|
{ "cmp ", AAbsolute },
|
||||||
|
{ "cmp ", AIX },
|
||||||
|
{ "cmp ", AIDirectX },
|
||||||
|
|
||||||
|
{ "cmp ", AConstant },
|
||||||
|
{ "cmp ", DirectDirect },
|
||||||
|
{ "and1 ", CNAbsoluteBit },
|
||||||
|
{ "ror ", Direct },
|
||||||
|
|
||||||
|
{ "ror ", Absolute },
|
||||||
|
{ "push ", Y },
|
||||||
|
{ "dbnz ", DirectRelative },
|
||||||
|
{ "ret ", Implied },
|
||||||
|
|
||||||
|
//0x70 - 0x7f
|
||||||
|
{ "bvs ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr3 ", Direct },
|
||||||
|
{ "bbc3 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "cmp ", ADirectX },
|
||||||
|
{ "cmp ", AAbsoluteX },
|
||||||
|
{ "cmp ", AAbsoluteY },
|
||||||
|
{ "cmp ", AIDirectY },
|
||||||
|
|
||||||
|
{ "cmp ", DirectConstant },
|
||||||
|
{ "cmp ", IXIY },
|
||||||
|
{ "addw ", YaDirect },
|
||||||
|
{ "ror ", DirectX },
|
||||||
|
|
||||||
|
{ "ror ", A },
|
||||||
|
{ "mov ", AX },
|
||||||
|
{ "cmp ", YDirect },
|
||||||
|
{ "reti ", Implied },
|
||||||
|
|
||||||
|
//0x80 - 0x8f
|
||||||
|
{ "setc ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set4 ", Direct },
|
||||||
|
{ "bbs4 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "adc ", ADirect },
|
||||||
|
{ "adc ", AAbsolute },
|
||||||
|
{ "adc ", AIX },
|
||||||
|
{ "adc ", AIDirectX },
|
||||||
|
|
||||||
|
{ "adc ", AConstant },
|
||||||
|
{ "adc ", DirectDirect },
|
||||||
|
{ "eor1 ", CAbsoluteBit },
|
||||||
|
{ "dec ", Direct },
|
||||||
|
|
||||||
|
{ "dec ", Absolute },
|
||||||
|
{ "mov ", YConstant },
|
||||||
|
{ "pop ", P },
|
||||||
|
{ "mov ", DirectConstant },
|
||||||
|
|
||||||
|
//0x90 - 0x9f
|
||||||
|
{ "bcc ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr4 ", Direct },
|
||||||
|
{ "bbc4 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "adc ", ADirectX },
|
||||||
|
{ "adc ", AAbsoluteX },
|
||||||
|
{ "adc ", AAbsoluteY },
|
||||||
|
{ "adc ", AIDirectY },
|
||||||
|
|
||||||
|
{ "adc ", DirectRelative },
|
||||||
|
{ "adc ", IXIY },
|
||||||
|
{ "subw ", YaDirect },
|
||||||
|
{ "dec ", DirectX },
|
||||||
|
|
||||||
|
{ "dec ", A },
|
||||||
|
{ "mov ", XSp },
|
||||||
|
{ "div ", YaX },
|
||||||
|
{ "xcn ", A },
|
||||||
|
|
||||||
|
//0xa0 - 0xaf
|
||||||
|
{ "ei ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set5 ", Direct },
|
||||||
|
{ "bbs5 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "sbc ", ADirect },
|
||||||
|
{ "sbc ", AAbsolute },
|
||||||
|
{ "sbc ", AIX },
|
||||||
|
{ "sbc ", AIDirectX },
|
||||||
|
|
||||||
|
{ "sbc ", AConstant },
|
||||||
|
{ "sbc ", DirectDirect },
|
||||||
|
{ "mov1 ", CAbsoluteBit },
|
||||||
|
{ "inc ", Direct },
|
||||||
|
|
||||||
|
{ "inc ", Absolute },
|
||||||
|
{ "cmp ", YConstant },
|
||||||
|
{ "pop ", A },
|
||||||
|
{ "mov ", IXPA },
|
||||||
|
|
||||||
|
//0xb0 - 0xbf
|
||||||
|
{ "bcs ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr5 ", Direct },
|
||||||
|
{ "bbc5 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "sbc ", ADirectX },
|
||||||
|
{ "sbc ", AAbsoluteX },
|
||||||
|
{ "sbc ", AAbsoluteY },
|
||||||
|
{ "sbc ", AIDirectY },
|
||||||
|
|
||||||
|
{ "sbc ", DirectConstant },
|
||||||
|
{ "sbc ", IXIY },
|
||||||
|
{ "movw ", YaDirect },
|
||||||
|
{ "inc ", DirectX },
|
||||||
|
|
||||||
|
{ "inc ", A },
|
||||||
|
{ "mov ", SpX },
|
||||||
|
{ "das ", A },
|
||||||
|
{ "mov ", AIXP },
|
||||||
|
|
||||||
|
//0xc0 - 0xcf
|
||||||
|
{ "di ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set6 ", Direct },
|
||||||
|
{ "bbs6 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "mov ", DirectA },
|
||||||
|
{ "mov ", AbsoluteA },
|
||||||
|
{ "mov ", IXA },
|
||||||
|
{ "mov ", IDirectXA },
|
||||||
|
|
||||||
|
{ "cmp ", XConstant },
|
||||||
|
{ "mov ", AbsoluteX },
|
||||||
|
{ "mov1 ", AbsoluteBitC },
|
||||||
|
{ "mov ", DirectY },
|
||||||
|
|
||||||
|
{ "mov ", AbsoluteY },
|
||||||
|
{ "mov ", XConstant },
|
||||||
|
{ "pop ", X },
|
||||||
|
{ "mul ", Ya },
|
||||||
|
|
||||||
|
//0xd0 - 0xdf
|
||||||
|
{ "bne ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr6 ", Relative },
|
||||||
|
{ "bbc6 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "mov ", DirectXA },
|
||||||
|
{ "mov ", AbsoluteXA },
|
||||||
|
{ "mov ", AbsoluteYA },
|
||||||
|
{ "mov ", IDirectYA },
|
||||||
|
|
||||||
|
{ "mov ", DirectX },
|
||||||
|
{ "mov ", DirectYX },
|
||||||
|
{ "movw ", DirectYa },
|
||||||
|
{ "mov ", DirectXY },
|
||||||
|
|
||||||
|
{ "dec ", Y },
|
||||||
|
{ "mov ", AY },
|
||||||
|
{ "cbne ", DirectXRelative },
|
||||||
|
{ "daa ", A },
|
||||||
|
|
||||||
|
//0xe0 - 0xef
|
||||||
|
{ "clrv ", Implied },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "set7 ", Direct },
|
||||||
|
{ "bbs7 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "mov ", ADirect },
|
||||||
|
{ "mov ", AAbsolute },
|
||||||
|
{ "mov ", AIX },
|
||||||
|
{ "mov ", AIDirectX },
|
||||||
|
|
||||||
|
{ "mov ", AConstant },
|
||||||
|
{ "mov ", XAbsolute },
|
||||||
|
{ "not1 ", CAbsoluteBit },
|
||||||
|
{ "mov ", YDirect },
|
||||||
|
|
||||||
|
{ "mov ", YAbsolute },
|
||||||
|
{ "notc ", Implied },
|
||||||
|
{ "pop ", Y },
|
||||||
|
{ "sleep", Implied },
|
||||||
|
|
||||||
|
//0xf0 - 0xff
|
||||||
|
{ "beq ", Relative },
|
||||||
|
{ "tcall", TVector },
|
||||||
|
{ "clr7 ", Direct },
|
||||||
|
{ "bbc7 ", DirectRelative },
|
||||||
|
|
||||||
|
{ "mov ", ADirectX },
|
||||||
|
{ "mov ", AAbsoluteX },
|
||||||
|
{ "mov ", AAbsoluteY },
|
||||||
|
{ "mov ", AIDirectY },
|
||||||
|
|
||||||
|
{ "mov ", XDirect },
|
||||||
|
{ "mov ", XDirectY },
|
||||||
|
{ "mov ", DirectDirect },
|
||||||
|
{ "mov ", YDirectX },
|
||||||
|
|
||||||
|
{ "inc ", Y },
|
||||||
|
{ "mov ", YA },
|
||||||
|
{ "dbz ", YRelative },
|
||||||
|
{ "stop ", Implied },
|
||||||
|
};
|
||||||
|
|
||||||
|
inline unsigned SNESSMP::getOpcodeLength(uint8_t opcode) {
|
||||||
|
switch(opcodeInfo[opcode].mode) { default:
|
||||||
|
case Implied: return 1; //
|
||||||
|
case TVector: return 1; //0
|
||||||
|
case Direct: return 2; //$00
|
||||||
|
case DirectRelative: return 3; //$00,+/-$00
|
||||||
|
case ADirect: return 2; //a,$00
|
||||||
|
case AAbsolute: return 3; //a,$0000
|
||||||
|
case AIX: return 1; //a,(x)
|
||||||
|
case AIDirectX: return 2; //a,($00+x)
|
||||||
|
case AConstant: return 2; //a,#$00
|
||||||
|
case DirectDirect: return 3; //$00,$00
|
||||||
|
case CAbsoluteBit: return 3; //c,$0000:0
|
||||||
|
case Absolute: return 3; //$0000
|
||||||
|
case P: return 1; //p
|
||||||
|
case AbsoluteA: return 3; //$0000,a
|
||||||
|
case Relative: return 2; //+/-$00
|
||||||
|
case ADirectX: return 2; //a,$00+x
|
||||||
|
case AAbsoluteX: return 3; //a,$0000+x
|
||||||
|
case AAbsoluteY: return 3; //a,$0000+y
|
||||||
|
case AIDirectY: return 2; //a,($00)+y
|
||||||
|
case DirectConstant: return 3; //$00,#$00
|
||||||
|
case IXIY: return 1; //(x),(y)
|
||||||
|
case DirectX: return 2; //$00+x
|
||||||
|
case A: return 1; //a
|
||||||
|
case X: return 1; //x
|
||||||
|
case XAbsolute: return 3; //x,$0000
|
||||||
|
case IAbsoluteX: return 3; //($0000+x)
|
||||||
|
case CNAbsoluteBit: return 3; //c,!$0000:0
|
||||||
|
case XDirect: return 2; //x,$00
|
||||||
|
case PVector: return 2; //$ff00
|
||||||
|
case YaDirect: return 2; //ya,$00
|
||||||
|
case XA: return 1; //x,a
|
||||||
|
case YAbsolute: return 3; //y,$0000
|
||||||
|
case Y: return 1; //y
|
||||||
|
case AX: return 1; //a,x
|
||||||
|
case YDirect: return 2; //y,$00
|
||||||
|
case YConstant: return 2; //y,#$00
|
||||||
|
case XSp: return 1; //x,sp
|
||||||
|
case YaX: return 1; //ya,x
|
||||||
|
case IXPA: return 1; //(x)+,a
|
||||||
|
case SpX: return 1; //sp,x
|
||||||
|
case AIXP: return 1; //a,(x)+
|
||||||
|
case DirectA: return 2; //$00,a
|
||||||
|
case IXA: return 1; //(x),a
|
||||||
|
case IDirectXA: return 2; //($00+x),a
|
||||||
|
case XConstant: return 2; //x,#$00
|
||||||
|
case AbsoluteX: return 3; //$0000,x
|
||||||
|
case AbsoluteBitC: return 3; //$0000:0,c
|
||||||
|
case DirectY: return 2; //$00,y
|
||||||
|
case AbsoluteY: return 3; //$0000,y
|
||||||
|
case Ya: return 1; //ya
|
||||||
|
case DirectXA: return 2; //$00+x,a
|
||||||
|
case AbsoluteXA: return 3; //$0000+x,a
|
||||||
|
case AbsoluteYA: return 3; //$0000+y,a
|
||||||
|
case IDirectYA: return 2; //($00)+y,a
|
||||||
|
case DirectYX: return 2; //$00+y,x
|
||||||
|
case DirectYa: return 2; //$00,ya
|
||||||
|
case DirectXY: return 2; //$00+x,y
|
||||||
|
case AY: return 1; //a,y
|
||||||
|
case DirectXRelative: return 3; //$00+x,+/-$00
|
||||||
|
case XDirectY: return 2; //x,$00+y
|
||||||
|
case YDirectX: return 2; //y,$00+x
|
||||||
|
case YA: return 1; //y,a
|
||||||
|
case YRelative: return 2; //y,+/-$00
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline string SNESSMP::disassemble(uint16_t pc, uint8_t opcode, uint8_t pl, uint8_t ph) {
|
||||||
|
string name = opcodeInfo[opcode].name;
|
||||||
|
unsigned mode = opcodeInfo[opcode].mode;
|
||||||
|
unsigned pa = (ph << 8) + pl;
|
||||||
|
|
||||||
|
if(mode == Implied) return name;
|
||||||
|
if(mode == TVector) return { name, " ", opcode >> 4 };
|
||||||
|
if(mode == Direct) return { name, " $", strhex<2>(pl) };
|
||||||
|
if(mode == DirectRelative) return { name, " $", strhex<2>(pl), ",$", strhex<4>(pc + 3 + (int8_t)ph) };
|
||||||
|
if(mode == ADirect) return { name, " a,$", strhex<2>(pl) };
|
||||||
|
if(mode == AAbsolute) return { name, " a,$", strhex<4>(pa) };
|
||||||
|
if(mode == AIX) return { name, "a,(x)" };
|
||||||
|
if(mode == AIDirectX) return { name, " a,($", strhex<2>(pl), "+x)" };
|
||||||
|
if(mode == AConstant) return { name, " a,#$", strhex<2>(pl) };
|
||||||
|
if(mode == DirectDirect) return { name, " $", strhex<2>(ph), ",$", strhex<2>(pl) };
|
||||||
|
if(mode == CAbsoluteBit) return { name, " c,$", strhex<4>(pa & 0x1fff), ":", pa >> 13 };
|
||||||
|
if(mode == Absolute) return { name, " $", strhex<4>(pa) };
|
||||||
|
if(mode == P) return { name, " p" };
|
||||||
|
if(mode == AbsoluteA) return { name, " $", strhex<4>(pa), ",a" };
|
||||||
|
if(mode == Relative) return { name, " $", strhex<4>(pc + 2 + (int8_t)pl) };
|
||||||
|
if(mode == ADirectX) return { name, " a,$", strhex<2>(pl), "+x" };
|
||||||
|
if(mode == AAbsoluteX) return { name, " a,$", strhex<4>(pa), "+x" };
|
||||||
|
if(mode == AAbsoluteY) return { name, " a,$", strhex<4>(pa), "+y" };
|
||||||
|
if(mode == AIDirectY) return { name, " a,($", strhex<2>(pl), ")+y" };
|
||||||
|
if(mode == DirectConstant) return { name, " $", strhex<2>(ph), ",#$", strhex<2>(pl) };
|
||||||
|
if(mode == IXIY) return { name, " (x),(y)" };
|
||||||
|
if(mode == DirectX) return { name, " $", strhex<2>(pl), "+x" };
|
||||||
|
if(mode == A) return { name, " a" };
|
||||||
|
if(mode == X) return { name, " x" };
|
||||||
|
if(mode == XAbsolute) return { name, " x,$", strhex<4>(pa) };
|
||||||
|
if(mode == IAbsoluteX) return { name, " ($", strhex<4>(pa), "+x)" };
|
||||||
|
if(mode == CNAbsoluteBit) return { name, " c,!$", strhex<4>(pa & 0x1fff), ":", pa >> 13 };
|
||||||
|
if(mode == XDirect) return { name, " x,$", strhex<2>(pl) };
|
||||||
|
if(mode == PVector) return { name, " $ff", strhex<2>(pl) };
|
||||||
|
if(mode == YaDirect) return { name, " ya,$", strhex<2>(pl) };
|
||||||
|
if(mode == XA) return { name, " x,a" };
|
||||||
|
if(mode == YAbsolute) return { name, " y,$", strhex<4>(pa) };
|
||||||
|
if(mode == Y) return { name, " y" };
|
||||||
|
if(mode == AX) return { name, " a,x" };
|
||||||
|
if(mode == YDirect) return { name, " y,$", strhex<2>(pl) };
|
||||||
|
if(mode == YConstant) return { name, " y,#$", strhex<2>(pl) };
|
||||||
|
if(mode == XSp) return { name, " x,sp" };
|
||||||
|
if(mode == YaX) return { name, " ya,x" };
|
||||||
|
if(mode == IXPA) return { name, " (x)+,a" };
|
||||||
|
if(mode == SpX) return { name, " sp,x" };
|
||||||
|
if(mode == AIXP) return { name, " a,(x)+" };
|
||||||
|
if(mode == DirectA) return { name, " $", strhex<2>(pl), ",a" };
|
||||||
|
if(mode == IXA) return { name, " (x),a" };
|
||||||
|
if(mode == IDirectXA) return { name, " ($", strhex<2>(pl), "+x),a" };
|
||||||
|
if(mode == XConstant) return { name, " x,#$", strhex<2>(pl) };
|
||||||
|
if(mode == AbsoluteX) return { name, " $", strhex<4>(pa), ",x" };
|
||||||
|
if(mode == AbsoluteBitC) return { name, " $", strhex<4>(pa & 0x1fff), ":", pa >> 13, ",c" };
|
||||||
|
if(mode == DirectY) return { name, " $", strhex<2>(pl), ",y" };
|
||||||
|
if(mode == AbsoluteY) return { name, " $", strhex<4>(pa), ",y" };
|
||||||
|
if(mode == Ya) return { name, " ya" };
|
||||||
|
if(mode == DirectXA) return { name, " $", strhex<2>(pl), "+x,a" };
|
||||||
|
if(mode == AbsoluteXA) return { name, " $", strhex<4>(pa), "+x,a" };
|
||||||
|
if(mode == AbsoluteYA) return { name, " $", strhex<4>(pa), "+y,a" };
|
||||||
|
if(mode == IDirectYA) return { name, " ($", strhex<2>(pl), ")+y,a" };
|
||||||
|
if(mode == DirectYX) return { name, " $", strhex<2>(pl), "+y,x" };
|
||||||
|
if(mode == DirectYa) return { name, " $", strhex<2>(pl), ",ya" };
|
||||||
|
if(mode == DirectXY) return { name, " $", strhex<2>(pl), "+x,y" };
|
||||||
|
if(mode == AY) return { name, " a,y" };
|
||||||
|
if(mode == DirectXRelative) return { name, " $", strhex<2>(pl), ",$", strhex<4>(pc + 3 + (int8_t)ph) };
|
||||||
|
if(mode == XDirectY) return { name, " x,$", strhex<2>(pl), "+y" };
|
||||||
|
if(mode == YDirectX) return { name, " y,$", strhex<2>(pl), "+x" };
|
||||||
|
if(mode == YA) return { name, " y,a" };
|
||||||
|
if(mode == YRelative) return { name, " y,$", strhex<4>(pc + 2 + (int8_t)pl) };
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
inline string SNESSMP::disassemble(uint16_t pc, bool p, uint8_t opcode, uint8_t pl, uint8_t ph) {
|
||||||
|
string name = opcodeInfo[opcode].name;
|
||||||
|
unsigned mode = opcodeInfo[opcode].mode;
|
||||||
|
unsigned pdl = (p << 8) + pl;
|
||||||
|
unsigned pdh = (p << 8) + ph;
|
||||||
|
unsigned pa = (ph << 8) + pl;
|
||||||
|
|
||||||
|
if(mode == Implied) return name;
|
||||||
|
if(mode == TVector) return { name, " ", opcode >> 4 };
|
||||||
|
if(mode == Direct) return { name, " $", strhex<3>(pdl) };
|
||||||
|
if(mode == DirectRelative) return { name, " $", strhex<3>(pdl), ",$", strhex<4>(pc + 3 + (int8_t)ph) };
|
||||||
|
if(mode == ADirect) return { name, " a,$", strhex<3>(pdl) };
|
||||||
|
if(mode == AAbsolute) return { name, " a,$", strhex<4>(pa) };
|
||||||
|
if(mode == AIX) return { name, "a,(x)" };
|
||||||
|
if(mode == AIDirectX) return { name, " a,($", strhex<3>(pdl), "+x)" };
|
||||||
|
if(mode == AConstant) return { name, " a,#$", strhex<2>(pl) };
|
||||||
|
if(mode == DirectDirect) return { name, " $", strhex<3>(pdh), ",$", strhex<3>(pdl) };
|
||||||
|
if(mode == CAbsoluteBit) return { name, " c,$", strhex<4>(pa & 0x1fff), ":", pa >> 13 };
|
||||||
|
if(mode == Absolute) return { name, " $", strhex<4>(pa) };
|
||||||
|
if(mode == P) return { name, " p" };
|
||||||
|
if(mode == AbsoluteA) return { name, " $", strhex<4>(pa), ",a" };
|
||||||
|
if(mode == Relative) return { name, " $", strhex<4>(pc + 2 + (int8_t)pl) };
|
||||||
|
if(mode == ADirectX) return { name, " a,$", strhex<3>(pdl), "+x" };
|
||||||
|
if(mode == AAbsoluteX) return { name, " a,$", strhex<4>(pa), "+x" };
|
||||||
|
if(mode == AAbsoluteY) return { name, " a,$", strhex<4>(pa), "+y" };
|
||||||
|
if(mode == AIDirectY) return { name, " a,($", strhex<3>(pdl), ")+y" };
|
||||||
|
if(mode == DirectConstant) return { name, " $", strhex<3>(pdh), ",#$", strhex<2>(pl) };
|
||||||
|
if(mode == IXIY) return { name, " (x),(y)" };
|
||||||
|
if(mode == DirectX) return { name, " $", strhex<3>(pdl), "+x" };
|
||||||
|
if(mode == A) return { name, " a" };
|
||||||
|
if(mode == X) return { name, " x" };
|
||||||
|
if(mode == XAbsolute) return { name, " x,$", strhex<4>(pa) };
|
||||||
|
if(mode == IAbsoluteX) return { name, " ($", strhex<4>(pa), "+x)" };
|
||||||
|
if(mode == CNAbsoluteBit) return { name, " c,!$", strhex<4>(pa & 0x1fff), ":", pa >> 13 };
|
||||||
|
if(mode == XDirect) return { name, " x,$", strhex<3>(pdl) };
|
||||||
|
if(mode == PVector) return { name, " $ff", strhex<2>(pl) };
|
||||||
|
if(mode == YaDirect) return { name, " ya,$", strhex<3>(pdl) };
|
||||||
|
if(mode == XA) return { name, " x,a" };
|
||||||
|
if(mode == YAbsolute) return { name, " y,$", strhex<4>(pa) };
|
||||||
|
if(mode == Y) return { name, " y" };
|
||||||
|
if(mode == AX) return { name, " a,x" };
|
||||||
|
if(mode == YDirect) return { name, " y,$", strhex<3>(pdl) };
|
||||||
|
if(mode == YConstant) return { name, " y,#$", strhex<2>(pl) };
|
||||||
|
if(mode == XSp) return { name, " x,sp" };
|
||||||
|
if(mode == YaX) return { name, " ya,x" };
|
||||||
|
if(mode == IXPA) return { name, " (x)+,a" };
|
||||||
|
if(mode == SpX) return { name, " sp,x" };
|
||||||
|
if(mode == AIXP) return { name, " a,(x)+" };
|
||||||
|
if(mode == DirectA) return { name, " $", strhex<3>(pdl), ",a" };
|
||||||
|
if(mode == IXA) return { name, " (x),a" };
|
||||||
|
if(mode == IDirectXA) return { name, " ($", strhex<3>(pdl), "+x),a" };
|
||||||
|
if(mode == XConstant) return { name, " x,#$", strhex<2>(pl) };
|
||||||
|
if(mode == AbsoluteX) return { name, " $", strhex<4>(pa), ",x" };
|
||||||
|
if(mode == AbsoluteBitC) return { name, " $", strhex<4>(pa & 0x1fff), ":", pa >> 13, ",c" };
|
||||||
|
if(mode == DirectY) return { name, " $", strhex<3>(pdl), ",y" };
|
||||||
|
if(mode == AbsoluteY) return { name, " $", strhex<4>(pa), ",y" };
|
||||||
|
if(mode == Ya) return { name, " ya" };
|
||||||
|
if(mode == DirectXA) return { name, " $", strhex<3>(pdl), "+x,a" };
|
||||||
|
if(mode == AbsoluteXA) return { name, " $", strhex<4>(pa), "+x,a" };
|
||||||
|
if(mode == AbsoluteYA) return { name, " $", strhex<4>(pa), "+y,a" };
|
||||||
|
if(mode == IDirectYA) return { name, " ($", strhex<3>(pdl), ")+y,a" };
|
||||||
|
if(mode == DirectYX) return { name, " $", strhex<3>(pdl), "+y,x" };
|
||||||
|
if(mode == DirectYa) return { name, " $", strhex<3>(pdl), ",ya" };
|
||||||
|
if(mode == DirectXY) return { name, " $", strhex<3>(pdl), "+x,y" };
|
||||||
|
if(mode == AY) return { name, " a,y" };
|
||||||
|
if(mode == DirectXRelative) return { name, " $", strhex<3>(pdl), ",$", strhex<4>(pc + 3 + (int8_t)ph) };
|
||||||
|
if(mode == XDirectY) return { name, " x,$", strhex<3>(pdl), "+y" };
|
||||||
|
if(mode == YDirectX) return { name, " y,$", strhex<3>(pdl), "+x" };
|
||||||
|
if(mode == YA) return { name, " y,a" };
|
||||||
|
if(mode == YRelative) return { name, " y,$", strhex<4>(pc + 2 + (int8_t)pl) };
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -5,7 +5,7 @@ static bool HexEditor_keyPress(GtkWidget *widget, GdkEventKey *event, HexEditor
|
||||||
void HexEditor::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
void HexEditor::create(Window &parent, unsigned x, unsigned y, unsigned width, unsigned height) {
|
||||||
object->widget = gtk_scrolled_window_new(0, 0);
|
object->widget = gtk_scrolled_window_new(0, 0);
|
||||||
widget->parent = &parent;
|
widget->parent = &parent;
|
||||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(object->widget), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(object->widget), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
|
||||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(object->widget), GTK_SHADOW_ETCHED_IN);
|
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(object->widget), GTK_SHADOW_ETCHED_IN);
|
||||||
gtk_widget_set_size_request(object->widget, width, height);
|
gtk_widget_set_size_request(object->widget, width, height);
|
||||||
object->subWidget = gtk_text_view_new();
|
object->subWidget = gtk_text_view_new();
|
||||||
|
|
|
@ -36,6 +36,11 @@ uint8 Debugger::read(Debugger::MemorySource source, unsigned addr) {
|
||||||
return bus.read(addr & 0xffffff);
|
return bus.read(addr & 0xffffff);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case MemorySource::APUBus: {
|
||||||
|
if((addr & 0xffc0) == 0xffc0) return smp.iplrom[addr & 0x3f];
|
||||||
|
return memory::apuram.read(addr & 0xffff);
|
||||||
|
} break;
|
||||||
|
|
||||||
case MemorySource::APURAM: {
|
case MemorySource::APURAM: {
|
||||||
return memory::apuram.read(addr & 0xffff);
|
return memory::apuram.read(addr & 0xffff);
|
||||||
} break;
|
} break;
|
||||||
|
|
|
@ -22,7 +22,7 @@ public:
|
||||||
bool step_cpu;
|
bool step_cpu;
|
||||||
bool step_smp;
|
bool step_smp;
|
||||||
|
|
||||||
enum class MemorySource : unsigned { CPUBus, APURAM, VRAM, OAM, CGRAM };
|
enum class MemorySource : unsigned { CPUBus, APUBus, APURAM, VRAM, OAM, CGRAM };
|
||||||
uint8 read(MemorySource, unsigned addr);
|
uint8 read(MemorySource, unsigned addr);
|
||||||
void write(MemorySource, unsigned addr, uint8 data);
|
void write(MemorySource, unsigned addr, uint8 data);
|
||||||
|
|
||||||
|
|
|
@ -16,12 +16,12 @@ public:
|
||||||
SMP();
|
SMP();
|
||||||
~SMP();
|
~SMP();
|
||||||
|
|
||||||
|
static const uint8 iplrom[64];
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#include "memory/memory.hpp"
|
#include "memory/memory.hpp"
|
||||||
#include "timing/timing.hpp"
|
#include "timing/timing.hpp"
|
||||||
|
|
||||||
static const uint8 iplrom[64];
|
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
//timing
|
//timing
|
||||||
unsigned clock_counter;
|
unsigned clock_counter;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
namespace Info {
|
namespace Info {
|
||||||
static const char Name[] = "bsnes";
|
static const char Name[] = "bsnes";
|
||||||
static const char Version[] = "072.02";
|
static const char Version[] = "072.04";
|
||||||
static const unsigned SerializerVersion = 14;
|
static const unsigned SerializerVersion = 14;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include <nall/filemap.hpp>
|
#include <nall/filemap.hpp>
|
||||||
#include <nall/input.hpp>
|
#include <nall/input.hpp>
|
||||||
#include <nall/ups.hpp>
|
#include <nall/ups.hpp>
|
||||||
#include <nall/snes/info.hpp>
|
#include <nall/snes/cartridge.hpp>
|
||||||
using namespace nall;
|
using namespace nall;
|
||||||
|
|
||||||
#include <ruby/ruby.hpp>
|
#include <ruby/ruby.hpp>
|
||||||
|
|
|
@ -107,7 +107,7 @@ bool Cartridge::loadCartridge(SNES::MappedRAM &memory, string &XML, const char *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(XML == "") XML = snes_information(data, size).xml_memory_map;
|
if(XML == "") XML = SNESCartridge(data, size).xmlMemoryMap;
|
||||||
memory.copy(data, size);
|
memory.copy(data, size);
|
||||||
delete[] data;
|
delete[] data;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -15,8 +15,14 @@ void Console::create() {
|
||||||
traceToDisk.setEnabled(false);
|
traceToDisk.setEnabled(false);
|
||||||
traceCPU.create(*this, x, y, 120, Style::CheckBoxHeight, "Trace S-CPU"); y += Style::CheckBoxHeight;
|
traceCPU.create(*this, x, y, 120, Style::CheckBoxHeight, "Trace S-CPU"); y += Style::CheckBoxHeight;
|
||||||
traceCPU.setChecked(true);
|
traceCPU.setChecked(true);
|
||||||
|
traceSMP.create(*this, x, y, 120, Style::CheckBoxHeight, "Trace S-SMP"); y += Style::CheckBoxHeight;
|
||||||
|
|
||||||
setGeometry(0, 0, 775, 338);
|
setGeometry(0, 0, 775, 338);
|
||||||
|
|
||||||
|
onClose = []() {
|
||||||
|
debugger.showConsole.setChecked(false);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Console::eventTraceCPU() {
|
void Console::eventTraceCPU() {
|
||||||
|
@ -28,3 +34,13 @@ void Console::eventTraceCPU() {
|
||||||
buffer.append(string(buffer == "" ? "" : "\n", text));
|
buffer.append(string(buffer == "" ? "" : "\n", text));
|
||||||
output.setText(buffer);
|
output.setText(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Console::eventTraceSMP() {
|
||||||
|
if(traceSMP.checked() == false) return;
|
||||||
|
if(traceToConsole.checked() == false) return;
|
||||||
|
|
||||||
|
char text[256];
|
||||||
|
SNES::smp.disassemble_opcode(text, SNES::smp.regs.pc);
|
||||||
|
buffer.append(string(buffer == "" ? "" : "\n", text));
|
||||||
|
output.setText(buffer);
|
||||||
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ struct Console : TopLevelWindow {
|
||||||
CheckBox traceToConsole;
|
CheckBox traceToConsole;
|
||||||
CheckBox traceToDisk;
|
CheckBox traceToDisk;
|
||||||
CheckBox traceCPU;
|
CheckBox traceCPU;
|
||||||
|
CheckBox traceSMP;
|
||||||
|
|
||||||
string buffer;
|
string buffer;
|
||||||
|
|
||||||
void create();
|
void create();
|
||||||
void eventTraceCPU();
|
void eventTraceCPU();
|
||||||
|
void eventTraceSMP();
|
||||||
};
|
};
|
||||||
|
|
||||||
extern Console console;
|
extern Console console;
|
||||||
|
|
|
@ -16,6 +16,11 @@ void CPUdebugger::create() {
|
||||||
|
|
||||||
setGeometry(0, 0, 490, 205);
|
setGeometry(0, 0, 490, 205);
|
||||||
|
|
||||||
|
onClose = []() {
|
||||||
|
debugger.showCPUDebugger.setChecked(false);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
stepInto.onTick = []() {
|
stepInto.onTick = []() {
|
||||||
SNES::debugger.step_cpu = true;
|
SNES::debugger.step_cpu = true;
|
||||||
debugger.debugMode = Debugger::DebugMode::StepIntoCPU;
|
debugger.debugMode = Debugger::DebugMode::StepIntoCPU;
|
||||||
|
@ -88,7 +93,7 @@ void CPUdebugger::eventStepInto() {
|
||||||
|
|
||||||
void CPUdebugger::eventStepOver() {
|
void CPUdebugger::eventStepOver() {
|
||||||
uint8_t opcode = read(SNES::cpu.regs.pc);
|
uint8_t opcode = read(SNES::cpu.regs.pc);
|
||||||
unsigned length = SNESCPU::getOpcodeLength(opcode, SNES::cpu.regs.p);
|
unsigned length = SNESCPU::getOpcodeLength(SNES::cpu.regs.p.m, SNES::cpu.regs.p.x, opcode);
|
||||||
SNES::cpu.regs.pc += length;
|
SNES::cpu.regs.pc += length;
|
||||||
refreshDisassembly();
|
refreshDisassembly();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,28 +2,57 @@
|
||||||
#if defined(DEBUGGER)
|
#if defined(DEBUGGER)
|
||||||
|
|
||||||
#include <nall/snes/cpu.hpp>
|
#include <nall/snes/cpu.hpp>
|
||||||
|
#include <nall/snes/smp.hpp>
|
||||||
|
|
||||||
#include "console.cpp"
|
#include "console.cpp"
|
||||||
#include "cpu/debugger.cpp"
|
#include "cpu/debugger.cpp"
|
||||||
|
#include "smp/debugger.cpp"
|
||||||
|
#include "tools/memory-editor.cpp"
|
||||||
Debugger debugger;
|
Debugger debugger;
|
||||||
|
|
||||||
void Debugger::create() {
|
void Debugger::create() {
|
||||||
console.create();
|
console.create();
|
||||||
cpuDebugger.create();
|
cpuDebugger.create();
|
||||||
|
smpDebugger.create();
|
||||||
|
memoryEditor.create();
|
||||||
|
|
||||||
Window::create(0, 0, 256, 256, "Debugger");
|
Window::create(0, 0, 256, 256, "Debugger");
|
||||||
application.addWindow(this, "Debugger", "160,160");
|
application.addWindow(this, "Debugger", "160,160");
|
||||||
|
|
||||||
unsigned x = 5, y = 5;
|
unsigned x = 5, y = 5;
|
||||||
enableDebugger.create(*this, x, y, 390, Style::CheckBoxHeight, "Enable debugger"); y += Style::CheckBoxHeight;
|
enableDebugger.create(*this, x, y, 240, Style::CheckBoxHeight, "Enable debugger"); y += Style::CheckBoxHeight;
|
||||||
showMemoryEditor.create(*this, x, y, 390, Style::CheckBoxHeight, "Memory editor"); y += Style::CheckBoxHeight;
|
showConsole.create(*this, x, y, 240, Style::CheckBoxHeight, "Console"); y += Style::CheckBoxHeight;
|
||||||
|
showCPUDebugger.create(*this, x, y, 240, Style::CheckBoxHeight, "CPU debugger"); y += Style::CheckBoxHeight;
|
||||||
|
showSMPDebugger.create(*this, x, y, 240, Style::CheckBoxHeight, "SMP debugger"); y += Style::CheckBoxHeight;
|
||||||
|
showMemoryEditor.create(*this, x, y, 240, Style::CheckBoxHeight, "Memory editor"); y += Style::CheckBoxHeight;
|
||||||
|
|
||||||
setGeometry(0, 0, 400, y);
|
//windows shown by default
|
||||||
|
showConsole.setChecked();
|
||||||
|
showCPUDebugger.setChecked();
|
||||||
|
showSMPDebugger.setChecked();
|
||||||
|
|
||||||
|
setGeometry(0, 0, 250, y);
|
||||||
|
|
||||||
enableDebugger.onTick = []() {
|
enableDebugger.onTick = []() {
|
||||||
debugger.enable(debugger.enableDebugger.checked());
|
debugger.enable(debugger.enableDebugger.checked());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
showConsole.onTick = []() {
|
||||||
|
console.setVisible(debugger.showConsole.checked());
|
||||||
|
};
|
||||||
|
|
||||||
|
showCPUDebugger.onTick = []() {
|
||||||
|
cpuDebugger.setVisible(debugger.showCPUDebugger.checked());
|
||||||
|
};
|
||||||
|
|
||||||
|
showSMPDebugger.onTick = []() {
|
||||||
|
smpDebugger.setVisible(debugger.showSMPDebugger.checked());
|
||||||
|
};
|
||||||
|
|
||||||
|
showMemoryEditor.onTick = []() {
|
||||||
|
memoryEditor.setVisible(debugger.showMemoryEditor.checked());
|
||||||
|
};
|
||||||
|
|
||||||
onClose = []() {
|
onClose = []() {
|
||||||
debugger.enable(false);
|
debugger.enable(false);
|
||||||
return true;
|
return true;
|
||||||
|
@ -32,8 +61,10 @@ void Debugger::create() {
|
||||||
|
|
||||||
void Debugger::setVisible(bool visible) {
|
void Debugger::setVisible(bool visible) {
|
||||||
Window::setVisible(visible);
|
Window::setVisible(visible);
|
||||||
console.setVisible(visible);
|
console.setVisible(showConsole.checked() & visible);
|
||||||
cpuDebugger.setVisible(visible);
|
cpuDebugger.setVisible(showCPUDebugger.checked() & visible);
|
||||||
|
smpDebugger.setVisible(showSMPDebugger.checked() & visible);
|
||||||
|
memoryEditor.setVisible(showMemoryEditor.checked() & visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Debugger::enable(bool state) {
|
void Debugger::enable(bool state) {
|
||||||
|
@ -56,8 +87,16 @@ void Debugger::run() {
|
||||||
if(debugMode == DebugMode::StepIntoCPU) {
|
if(debugMode == DebugMode::StepIntoCPU) {
|
||||||
if(SNES::debugger.break_event == SNES::Debugger::BreakEvent::CPUStep) {
|
if(SNES::debugger.break_event == SNES::Debugger::BreakEvent::CPUStep) {
|
||||||
debugMode = DebugMode::None;
|
debugMode = DebugMode::None;
|
||||||
cpuDebugger.eventStepInto();
|
|
||||||
console.eventTraceCPU();
|
console.eventTraceCPU();
|
||||||
|
cpuDebugger.eventStepInto();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(debugMode == DebugMode::StepIntoSMP) {
|
||||||
|
if(SNES::debugger.break_event == SNES::Debugger::BreakEvent::SMPStep) {
|
||||||
|
debugMode = DebugMode::None;
|
||||||
|
console.eventTraceSMP();
|
||||||
|
smpDebugger.eventStepInto();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,19 @@
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
#include "cpu/debugger.hpp"
|
#include "cpu/debugger.hpp"
|
||||||
|
#include "smp/debugger.hpp"
|
||||||
|
#include "tools/memory-editor.hpp"
|
||||||
|
|
||||||
struct Debugger : TopLevelWindow {
|
struct Debugger : TopLevelWindow {
|
||||||
enum class DebugMode : unsigned {
|
enum class DebugMode : unsigned {
|
||||||
None,
|
None,
|
||||||
StepIntoCPU,
|
StepIntoCPU,
|
||||||
|
StepIntoSMP,
|
||||||
} debugMode;
|
} debugMode;
|
||||||
|
|
||||||
CheckBox enableDebugger;
|
CheckBox enableDebugger;
|
||||||
|
CheckBox showConsole;
|
||||||
|
CheckBox showCPUDebugger;
|
||||||
|
CheckBox showSMPDebugger;
|
||||||
CheckBox showMemoryEditor;
|
CheckBox showMemoryEditor;
|
||||||
|
|
||||||
void create();
|
void create();
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
SMPDebugger smpDebugger;
|
||||||
|
|
||||||
|
void SMPDebugger::create() {
|
||||||
|
Window::create(0, 0, 256, 256, "SMP Debugger");
|
||||||
|
application.addWindow(this, "Debugger.SMPDebugger", "192,192");
|
||||||
|
|
||||||
|
unsigned x = 5, y = 5;
|
||||||
|
output.create(*this, x, y, 400, 200); x += 400 + 5;
|
||||||
|
output.setFont(application.monospaceFont);
|
||||||
|
output.setEditable(false);
|
||||||
|
|
||||||
|
stepInto.create(*this, x, y, 80, Style::ButtonHeight, "Step Into"); y += Style::ButtonHeight;
|
||||||
|
stepOver.create(*this, x, y, 80, Style::ButtonHeight, "Step Over"); y += Style::ButtonHeight;
|
||||||
|
proceed.create(*this, x, y, 80, Style::ButtonHeight, "Proceed"); y += Style::ButtonHeight;
|
||||||
|
proceed.setEnabled(false);
|
||||||
|
|
||||||
|
setGeometry(0, 0, 490, 205);
|
||||||
|
|
||||||
|
onClose = []() {
|
||||||
|
debugger.showSMPDebugger.setChecked(false);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
stepInto.onTick = []() {
|
||||||
|
SNES::debugger.step_smp = true;
|
||||||
|
debugger.debugMode = Debugger::DebugMode::StepIntoSMP;
|
||||||
|
};
|
||||||
|
|
||||||
|
stepOver.onTick = { &SMPDebugger::eventStepOver, this };
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMPDebugger::refreshDisassembly() {
|
||||||
|
uint16_t addr = SNES::smp.regs.pc;
|
||||||
|
uint8_t *usage = SNES::smp.usage;
|
||||||
|
|
||||||
|
signed offset[15];
|
||||||
|
foreach(n, offset) n = -1;
|
||||||
|
|
||||||
|
offset[7] = addr;
|
||||||
|
|
||||||
|
//reverse disassembly
|
||||||
|
for(signed n = 6; n >= 0; n--) {
|
||||||
|
signed base = offset[n + 1];
|
||||||
|
if(base == -1) break;
|
||||||
|
|
||||||
|
for(unsigned r = 1; r <= 3; r++) {
|
||||||
|
if(usage[(base - r) & 0xffff] & 0x20) {
|
||||||
|
offset[n] = base - r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//forward disassembly
|
||||||
|
for(signed n = 8; n <= 14; n++) {
|
||||||
|
signed base = offset[n - 1];
|
||||||
|
if(base == -1) break;
|
||||||
|
|
||||||
|
for(unsigned r = 1; r <= 3; r++) {
|
||||||
|
if(usage[(base + r) & 0xffff] & 0x20) {
|
||||||
|
offset[n] = base + r;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string buffer;
|
||||||
|
for(unsigned n = 0; n < 15; n++) {
|
||||||
|
buffer.append(n == 7 ? "> " : " ");
|
||||||
|
if(offset[n] == -1) {
|
||||||
|
buffer.append("...\n");
|
||||||
|
} else {
|
||||||
|
uint16_t addr = offset[n];
|
||||||
|
buffer.append(strhex<4>(addr));
|
||||||
|
buffer.append(" ");
|
||||||
|
string text = SNESSMP::disassemble(
|
||||||
|
addr, read(addr + 0), read(addr + 1), read(addr + 2)
|
||||||
|
);
|
||||||
|
|
||||||
|
buffer.append(text);
|
||||||
|
buffer.append("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer.rtrim<1>("\n");
|
||||||
|
output.setText(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMPDebugger::eventStepInto() {
|
||||||
|
SNES::debugger.step_smp = false;
|
||||||
|
refreshDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMPDebugger::eventStepOver() {
|
||||||
|
uint8_t opcode = read(SNES::smp.regs.pc);
|
||||||
|
unsigned length = SNESSMP::getOpcodeLength(opcode);
|
||||||
|
SNES::smp.regs.pc += length;
|
||||||
|
refreshDisassembly();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t SMPDebugger::read(uint16_t addr) {
|
||||||
|
return SNES::debugger.read(SNES::Debugger::MemorySource::APUBus, addr);
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
struct SMPDebugger : TopLevelWindow {
|
||||||
|
EditBox output;
|
||||||
|
Button stepInto;
|
||||||
|
Button stepOver;
|
||||||
|
Button proceed;
|
||||||
|
|
||||||
|
void create();
|
||||||
|
void refreshDisassembly();
|
||||||
|
void eventStepInto();
|
||||||
|
void eventStepOver();
|
||||||
|
|
||||||
|
uint8_t read(uint16_t addr);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern SMPDebugger smpDebugger;
|
|
@ -0,0 +1,78 @@
|
||||||
|
MemoryEditor memoryEditor;
|
||||||
|
|
||||||
|
void MemoryEditor::create() {
|
||||||
|
Window::create(0, 0, 256, 256, "Memory Editor");
|
||||||
|
application.addWindow(this, "Debugger.MemoryEditor", "192,192");
|
||||||
|
|
||||||
|
unsigned x = 5, y = 5;
|
||||||
|
editor.create(*this, x, y, 455, 210); x += 455 + 5;
|
||||||
|
editor.setFont(application.monospaceFont);
|
||||||
|
editor.setColumns(16);
|
||||||
|
editor.setRows(16);
|
||||||
|
|
||||||
|
sourceBox.create(*this, x, y, 80, Style::ComboBoxHeight); y += Style::ComboBoxHeight;
|
||||||
|
sourceBox.addItem("CPU");
|
||||||
|
sourceBox.addItem("APU");
|
||||||
|
sourceBox.addItem("VRAM");
|
||||||
|
sourceBox.addItem("OAM");
|
||||||
|
sourceBox.addItem("CGRAM");
|
||||||
|
|
||||||
|
gotoBox.create(*this, x, y, 80, Style::TextBoxHeight); y += Style::TextBoxHeight;
|
||||||
|
|
||||||
|
refreshButton.create(*this, x, y, 80, Style::ButtonHeight, "Refresh"); y += Style::ButtonHeight;
|
||||||
|
|
||||||
|
setGeometry(0, 0, 545, 220);
|
||||||
|
|
||||||
|
onClose = []() {
|
||||||
|
debugger.showMemoryEditor.setChecked(false);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
editor.onRead = { &MemoryEditor::read, this };
|
||||||
|
editor.onWrite = { &MemoryEditor::write, this };
|
||||||
|
|
||||||
|
sourceBox.onChange = []() {
|
||||||
|
switch(memoryEditor.sourceBox.selection()) {
|
||||||
|
case 0: memoryEditor.setSource(SNES::Debugger::MemorySource::CPUBus); break;
|
||||||
|
case 1: memoryEditor.setSource(SNES::Debugger::MemorySource::APURAM); break;
|
||||||
|
case 2: memoryEditor.setSource(SNES::Debugger::MemorySource::VRAM); break;
|
||||||
|
case 3: memoryEditor.setSource(SNES::Debugger::MemorySource::OAM); break;
|
||||||
|
case 4: memoryEditor.setSource(SNES::Debugger::MemorySource::CGRAM); break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
gotoBox.onChange = []() {
|
||||||
|
unsigned addr = strhex(memoryEditor.gotoBox.text());
|
||||||
|
memoryEditor.editor.setOffset(addr % memoryEditor.size);
|
||||||
|
memoryEditor.editor.update();
|
||||||
|
};
|
||||||
|
|
||||||
|
refreshButton.onTick = []() {
|
||||||
|
memoryEditor.editor.update();
|
||||||
|
};
|
||||||
|
|
||||||
|
setSource(SNES::Debugger::MemorySource::CPUBus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryEditor::setSource(SNES::Debugger::MemorySource source_) {
|
||||||
|
switch(source = source_) {
|
||||||
|
case SNES::Debugger::MemorySource::CPUBus: size = 1 << 24; break;
|
||||||
|
case SNES::Debugger::MemorySource::APURAM: size = 1 << 16; break;
|
||||||
|
case SNES::Debugger::MemorySource::VRAM: size = 1 << 16; break;
|
||||||
|
case SNES::Debugger::MemorySource::OAM: size = 544; break;
|
||||||
|
case SNES::Debugger::MemorySource::CGRAM: size = 512; break;
|
||||||
|
}
|
||||||
|
editor.setSize(size);
|
||||||
|
editor.setOffset(0);
|
||||||
|
editor.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t MemoryEditor::read(unsigned addr) {
|
||||||
|
if(SNES::cartridge.loaded() == false) return 0x00;
|
||||||
|
return SNES::debugger.read(source, addr % size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MemoryEditor::write(unsigned addr, uint8_t data) {
|
||||||
|
if(SNES::cartridge.loaded() == false) return;
|
||||||
|
SNES::debugger.write(source, addr % size, data);
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
struct MemoryEditor : TopLevelWindow {
|
||||||
|
HexEditor editor;
|
||||||
|
ComboBox sourceBox;
|
||||||
|
TextBox gotoBox;
|
||||||
|
Button refreshButton;
|
||||||
|
|
||||||
|
SNES::Debugger::MemorySource source;
|
||||||
|
unsigned size;
|
||||||
|
|
||||||
|
void create();
|
||||||
|
void setSource(SNES::Debugger::MemorySource source);
|
||||||
|
uint8_t read(unsigned addr);
|
||||||
|
void write(unsigned addr, uint8_t data);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MemoryEditor memoryEditor;
|
|
@ -248,7 +248,7 @@ bool Cartridge::loadCartridge(string &filename, string &xml, SNES::MappedRAM &me
|
||||||
xml.readfile(name);
|
xml.readfile(name);
|
||||||
} else {
|
} else {
|
||||||
//generate XML mapping from data via heuristics
|
//generate XML mapping from data via heuristics
|
||||||
xml = snes_information(data, size).xml_memory_map;
|
xml = SNESCartridge(data, size).xmlMemoryMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory.copy(data, size);
|
memory.copy(data, size);
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#include <nall/config.hpp>
|
#include <nall/config.hpp>
|
||||||
#include <nall/input.hpp>
|
#include <nall/input.hpp>
|
||||||
#include <nall/ups.hpp>
|
#include <nall/ups.hpp>
|
||||||
#include <nall/snes/info.hpp>
|
#include <nall/snes/cartridge.hpp>
|
||||||
#include "template/concept.hpp"
|
#include "template/concept.hpp"
|
||||||
#include "template/check-action.moc.hpp"
|
#include "template/check-action.moc.hpp"
|
||||||
#include "template/file-dialog.moc.hpp"
|
#include "template/file-dialog.moc.hpp"
|
||||||
|
|
Loading…
Reference in New Issue