mirror of https://github.com/stella-emu/stella.git
Further improvements to the DiStella class. The output is now properly
parsed into a DisassemblyList structure. For now, this is just being printed out again. The next change will be to pass this to RomWidget and have it displayed in the UI. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1929 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
231958dbdf
commit
898d16b863
|
@ -37,7 +37,8 @@ DiStella::~DiStella()
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt32 DiStella::disassemble(DisassemblyList& list, const char* datafile, bool autocode)
|
uInt32 DiStella::disassemble(DisassemblyList& list, uInt16 PC,
|
||||||
|
const char* datafile, bool autocode)
|
||||||
{
|
{
|
||||||
myLineCount = 0;
|
myLineCount = 0;
|
||||||
while(!myAddressQueue.empty())
|
while(!myAddressQueue.empty())
|
||||||
|
@ -78,7 +79,7 @@ uInt32 DiStella::disassemble(DisassemblyList& list, const char* datafile, bool a
|
||||||
Counter 3 bytes back from the final byte.
|
Counter 3 bytes back from the final byte.
|
||||||
-----------------------------------------------------*/
|
-----------------------------------------------------*/
|
||||||
|
|
||||||
myPC = myAppData.end - 3;
|
myPC = PC;
|
||||||
uInt32 start_adr = read_adr();
|
uInt32 start_adr = read_adr();
|
||||||
|
|
||||||
if (myAppData.end == 0x7ff) /* 2K case */
|
if (myAppData.end == 0x7ff) /* 2K case */
|
||||||
|
@ -134,8 +135,8 @@ uInt32 DiStella::disassemble(DisassemblyList& list, const char* datafile, bool a
|
||||||
myPC = myAddressQueue.front();
|
myPC = myAddressQueue.front();
|
||||||
myPCBeg = myPC;
|
myPCBeg = myPC;
|
||||||
myAddressQueue.pop();
|
myAddressQueue.pop();
|
||||||
disasm(myPC, 1);
|
disasm(list, myPC, 1);
|
||||||
for (int k = myPCBeg; k <= myPCEnd; k++)
|
for (uInt32 k = myPCBeg; k <= myPCEnd; k++)
|
||||||
mark(k, REACHABLE);
|
mark(k, REACHABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,10 +148,10 @@ uInt32 DiStella::disassemble(DisassemblyList& list, const char* datafile, bool a
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass
|
// Second pass
|
||||||
disasm(myOffset, 2);
|
disasm(list, myOffset, 2);
|
||||||
|
|
||||||
// Third pass
|
// Third pass
|
||||||
disasm(myOffset, 3);
|
disasm(list, myOffset, 3);
|
||||||
|
|
||||||
free(labels); /* Free dynamic memory before program ends */
|
free(labels); /* Free dynamic memory before program ends */
|
||||||
free(mem); /* Free dynamic memory before program ends */
|
free(mem); /* Free dynamic memory before program ends */
|
||||||
|
@ -228,7 +229,7 @@ int DiStella::file_load(const char* file)
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DiStella::disasm(uInt32 distart, int pass)
|
void DiStella::disasm(DisassemblyList& list, uInt32 distart, int pass)
|
||||||
{
|
{
|
||||||
#define HEX4 uppercase << hex << setw(4) << setfill('0')
|
#define HEX4 uppercase << hex << setw(4) << setfill('0')
|
||||||
#define HEX2 uppercase << hex << setw(2) << setfill('0')
|
#define HEX2 uppercase << hex << setw(2) << setfill('0')
|
||||||
|
@ -236,7 +237,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
uInt8 op, d1, opsrc;
|
uInt8 op, d1, opsrc;
|
||||||
uInt32 ad;
|
uInt32 ad;
|
||||||
short amode;
|
short amode;
|
||||||
int i, bytes, labfound, addbranch;
|
int bytes=0, labfound=0, addbranch=0;
|
||||||
char linebuff[256],nextline[256], nextlinebytes[256];
|
char linebuff[256],nextline[256], nextlinebytes[256];
|
||||||
strcpy(linebuff,"");
|
strcpy(linebuff,"");
|
||||||
strcpy(nextline,"");
|
strcpy(nextline,"");
|
||||||
|
@ -245,7 +246,6 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
|
|
||||||
/* pc=myAppData.start; */
|
/* pc=myAppData.start; */
|
||||||
myPC = distart - myOffset;
|
myPC = distart - myOffset;
|
||||||
//cerr << " ==> pc = " << pc << "(" << pass << ")" << endl;
|
|
||||||
while(myPC <= myAppData.end)
|
while(myPC <= myAppData.end)
|
||||||
{
|
{
|
||||||
if(check_bit(labels[myPC], GFX))
|
if(check_bit(labels[myPC], GFX))
|
||||||
|
@ -263,7 +263,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
myBuf << ".byte $" << HEX2 << (int)mem[myPC] << " ; ";
|
myBuf << ".byte $" << HEX2 << (int)mem[myPC] << " ; ";
|
||||||
showgfx(mem[myPC]);
|
showgfx(mem[myPC]);
|
||||||
myBuf << " $" << HEX4 << myPC+myOffset;
|
myBuf << " $" << HEX4 << myPC+myOffset;
|
||||||
addEntry();
|
addEntry(list);
|
||||||
}
|
}
|
||||||
myPC++;
|
myPC++;
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
bytes++;
|
bytes++;
|
||||||
if (bytes == 17)
|
if (bytes == 17)
|
||||||
{
|
{
|
||||||
addEntry();
|
addEntry(list);
|
||||||
myBuf << " ' '.byte $" << HEX2 << (int)mem[myPC];
|
myBuf << " ' '.byte $" << HEX2 << (int)mem[myPC];
|
||||||
bytes = 1;
|
bytes = 1;
|
||||||
}
|
}
|
||||||
|
@ -299,9 +299,9 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
|
|
||||||
if (pass == 3)
|
if (pass == 3)
|
||||||
{
|
{
|
||||||
addEntry();
|
addEntry(list);
|
||||||
myBuf << " ' ' ";
|
myBuf << " ' ' ";
|
||||||
addEntry();
|
addEntry(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -321,7 +321,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
amode = ourLookup[op].addr_mode;
|
amode = ourLookup[op].addr_mode;
|
||||||
if (myAppData.disp_data)
|
if (myAppData.disp_data)
|
||||||
{
|
{
|
||||||
for (i = 0; i < ourCLength[amode]; i++)
|
for (int i = 0; i < ourCLength[amode]; i++)
|
||||||
if (pass == 3)
|
if (pass == 3)
|
||||||
myBuf << HEX2 << (int)mem[myPC+i] << " ";
|
myBuf << HEX2 << (int)mem[myPC+i] << " ";
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
/* Line information is already printed; append .byte since last instruction will
|
/* Line information is already printed; append .byte since last instruction will
|
||||||
put recompilable object larger that original binary file */
|
put recompilable object larger that original binary file */
|
||||||
myBuf << ".byte $" << HEX2 << op;
|
myBuf << ".byte $" << HEX2 << op;
|
||||||
addEntry();
|
addEntry(list);
|
||||||
|
|
||||||
if (myPC == myAppData.end)
|
if (myPC == myAppData.end)
|
||||||
{
|
{
|
||||||
|
@ -387,7 +387,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
|
|
||||||
op = mem[myPC++];
|
op = mem[myPC++];
|
||||||
myBuf << ".byte $" << HEX2 << (int)op;
|
myBuf << ".byte $" << HEX2 << (int)op;
|
||||||
addEntry();
|
addEntry(list);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
myPCEnd = myAppData.end + myOffset;
|
myPCEnd = myAppData.end + myOffset;
|
||||||
|
@ -411,7 +411,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
strcat(nextline,linebuff);
|
strcat(nextline,linebuff);
|
||||||
|
|
||||||
myBuf << nextline;
|
myBuf << nextline;
|
||||||
addEntry();
|
addEntry(list);
|
||||||
strcpy(nextline,"");
|
strcpy(nextline,"");
|
||||||
strcpy(nextlinebytes,"");
|
strcpy(nextlinebytes,"");
|
||||||
}
|
}
|
||||||
|
@ -809,15 +809,15 @@ void DiStella::disasm(uInt32 distart, int pass)
|
||||||
if (strlen(nextline) <= 15)
|
if (strlen(nextline) <= 15)
|
||||||
{
|
{
|
||||||
/* Print spaces to align cycle count data */
|
/* Print spaces to align cycle count data */
|
||||||
for (int charcnt=0;charcnt<15-strlen(nextline);charcnt++)
|
for (uInt32 charcnt=0;charcnt<15-strlen(nextline);charcnt++)
|
||||||
myBuf << " ";
|
myBuf << " ";
|
||||||
}
|
}
|
||||||
myBuf << ";" << dec << (int)ourLookup[op].cycles << "'" << nextlinebytes;
|
myBuf << ";" << dec << (int)ourLookup[op].cycles << "'" << nextlinebytes;
|
||||||
addEntry();
|
addEntry(list);
|
||||||
if (op == 0x40 || op == 0x60)
|
if (op == 0x40 || op == 0x60)
|
||||||
{
|
{
|
||||||
myBuf << " ' ' ";
|
myBuf << " ' ' ";
|
||||||
addEntry();
|
addEntry(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(nextline,"");
|
strcpy(nextline,"");
|
||||||
|
@ -916,23 +916,48 @@ void DiStella::showgfx(uInt8 c)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
printf("|");
|
myBuf << "|";
|
||||||
for(i = 0;i < 8; i++)
|
for(i = 0;i < 8; i++)
|
||||||
{
|
{
|
||||||
if (c > 127)
|
if (c > 127)
|
||||||
printf("X");
|
myBuf << "X";
|
||||||
else
|
else
|
||||||
printf(" ");
|
myBuf << " ";
|
||||||
|
|
||||||
c = c << 1;
|
c = c << 1;
|
||||||
}
|
}
|
||||||
printf("|");
|
myBuf << "|";
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void DiStella::addEntry()
|
void DiStella::addEntry(DisassemblyList& list)
|
||||||
{
|
{
|
||||||
cout << myBuf.str() << endl;
|
const string& line = myBuf.str();
|
||||||
|
DisassemblyTag tag;
|
||||||
|
|
||||||
|
if(line[0] == ' ')
|
||||||
|
tag.address = 0;
|
||||||
|
else
|
||||||
|
myBuf >> setw(4) >> hex >> tag.address;
|
||||||
|
|
||||||
|
if(line[5] != ' ')
|
||||||
|
tag.label = line.substr(5, 5);
|
||||||
|
|
||||||
|
switch(line[11])
|
||||||
|
{
|
||||||
|
case ' ':
|
||||||
|
tag.disasm = " ";
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
tag.disasm = line.substr(11);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
tag.disasm = line.substr(11, 17);
|
||||||
|
tag.bytes = line.substr(29);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
list.push_back(tag);
|
||||||
|
|
||||||
myBuf.str("");
|
myBuf.str("");
|
||||||
++myLineCount;
|
++myLineCount;
|
||||||
}
|
}
|
||||||
|
@ -1296,26 +1321,12 @@ int main(int ac, char* av[])
|
||||||
DiStella dis;
|
DiStella dis;
|
||||||
DisassemblyList list;
|
DisassemblyList list;
|
||||||
|
|
||||||
int count = dis.disassemble(list, av[1]);
|
int count = dis.disassemble(list, 0xfff-3, av[1]);
|
||||||
|
|
||||||
#if 0
|
|
||||||
ostringstream buf;
|
|
||||||
int x = 0x0abc;
|
|
||||||
|
|
||||||
buf << uppercase << hex << setw(4) << setfill('0') << x << "'L" << setw(4) << setfill('0') << x << "'";
|
|
||||||
cout << buf.str() << endl;
|
|
||||||
buf.str("");
|
|
||||||
|
|
||||||
/*
|
|
||||||
printf("%.4X'L%.4X'", myPC+myOffset, myPC+myOffset);
|
|
||||||
else
|
|
||||||
printf("%.4X' '", myPC+myOffset);
|
|
||||||
*/
|
|
||||||
#endif
|
|
||||||
for(uInt32 i = 0; i < list.size(); ++i)
|
for(uInt32 i = 0; i < list.size(); ++i)
|
||||||
{
|
{
|
||||||
const DisassemblyTag& tag = list[i];
|
const DisassemblyTag& tag = list[i];
|
||||||
printf("%.4X | %s %s\n", tag.address, tag.disasm.c_str(), tag.bytes.c_str());
|
printf("%.4X|%5s|%s|%s|\n", tag.address, tag.label.c_str(), tag.disasm.c_str(), tag.bytes.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -29,7 +29,8 @@
|
||||||
|
|
||||||
//// The following will go in CartDebug
|
//// The following will go in CartDebug
|
||||||
struct DisassemblyTag {
|
struct DisassemblyTag {
|
||||||
int address;
|
uInt16 address;
|
||||||
|
string label;
|
||||||
string disasm;
|
string disasm;
|
||||||
string bytes;
|
string bytes;
|
||||||
};
|
};
|
||||||
|
@ -38,10 +39,13 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class is a wrapper around the Distella code. Much of the code remains
|
This class is a wrapper around the Distella code. Much of the code remains
|
||||||
exactly the same. All 7800-related stuff has been removed, as well as all
|
exactly the same, except that generated data is now redirected to a
|
||||||
commandline options. For now, the only configurable item is whether to
|
DisassemblyList structure rather than being printed.
|
||||||
automatically determine code vs. data sections (which is on by default).
|
|
||||||
Over time, some of the configurability of Distella may be added again.
|
All 7800-related stuff has been removed, as well as all commandline options.
|
||||||
|
For now, the only configurable item is whether to automatically determine
|
||||||
|
code vs. data sections (which is on by default). Over time, some of the
|
||||||
|
configurability of Distella may be added again.
|
||||||
|
|
||||||
@author Stephen Anthony
|
@author Stephen Anthony
|
||||||
*/
|
*/
|
||||||
|
@ -52,7 +56,7 @@ class DiStella
|
||||||
~DiStella();
|
~DiStella();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
uInt32 disassemble(DisassemblyList& list, const char* datafile, bool autocode = true);
|
uInt32 disassemble(DisassemblyList& list, uInt16 PC, const char* datafile, bool autocode = true);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Marked bits
|
// Marked bits
|
||||||
|
@ -68,22 +72,22 @@ class DiStella
|
||||||
REACHABLE = 1 << 4 /* disassemble-able code segments */
|
REACHABLE = 1 << 4 /* disassemble-able code segments */
|
||||||
};
|
};
|
||||||
|
|
||||||
// Indicate that a new line of disassembly has been performed
|
// Indicate that a new line of disassembly has been completed
|
||||||
// In the original Distella code, this indicated a new line to be printed.
|
// In the original Distella code, this indicated a new line to be printed
|
||||||
// Here, we add a new entry to the DisassemblyList
|
// Here, we add a new entry to the DisassemblyList
|
||||||
void addEntry();
|
void addEntry(DisassemblyList& list);
|
||||||
|
|
||||||
// These functions are part of the original Distella code
|
// These functions are part of the original Distella code
|
||||||
uInt32 filesize(FILE *stream);
|
uInt32 filesize(FILE *stream);
|
||||||
uInt32 read_adr();
|
uInt32 read_adr();
|
||||||
int file_load(const char* file);
|
int file_load(const char* file);
|
||||||
void disasm(uInt32 distart, int pass);
|
void disasm(DisassemblyList& list, uInt32 distart, int pass);
|
||||||
int mark(uInt32 address, MarkType bit);
|
int mark(uInt32 address, MarkType bit);
|
||||||
int check_bit(uInt8 bitflags, int i);
|
int check_bit(uInt8 bitflags, int i);
|
||||||
void showgfx(uInt8 c);
|
void showgfx(uInt8 c);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ostringstream myBuf;
|
stringstream myBuf;
|
||||||
queue<uInt16> myAddressQueue;
|
queue<uInt16> myAddressQueue;
|
||||||
uInt32 myOffset, myPC, myPCBeg, myPCEnd, myLineCount;
|
uInt32 myOffset, myPC, myPCBeg, myPCEnd, myLineCount;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue