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;
|
||||
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.
|
||||
-----------------------------------------------------*/
|
||||
|
||||
myPC = myAppData.end - 3;
|
||||
myPC = PC;
|
||||
uInt32 start_adr = read_adr();
|
||||
|
||||
if (myAppData.end == 0x7ff) /* 2K case */
|
||||
|
@ -134,8 +135,8 @@ uInt32 DiStella::disassemble(DisassemblyList& list, const char* datafile, bool a
|
|||
myPC = myAddressQueue.front();
|
||||
myPCBeg = myPC;
|
||||
myAddressQueue.pop();
|
||||
disasm(myPC, 1);
|
||||
for (int k = myPCBeg; k <= myPCEnd; k++)
|
||||
disasm(list, myPC, 1);
|
||||
for (uInt32 k = myPCBeg; k <= myPCEnd; k++)
|
||||
mark(k, REACHABLE);
|
||||
}
|
||||
|
||||
|
@ -147,10 +148,10 @@ uInt32 DiStella::disassemble(DisassemblyList& list, const char* datafile, bool a
|
|||
}
|
||||
|
||||
// Second pass
|
||||
disasm(myOffset, 2);
|
||||
disasm(list, myOffset, 2);
|
||||
|
||||
// Third pass
|
||||
disasm(myOffset, 3);
|
||||
disasm(list, myOffset, 3);
|
||||
|
||||
free(labels); /* 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 HEX2 uppercase << hex << setw(2) << setfill('0')
|
||||
|
@ -236,7 +237,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
uInt8 op, d1, opsrc;
|
||||
uInt32 ad;
|
||||
short amode;
|
||||
int i, bytes, labfound, addbranch;
|
||||
int bytes=0, labfound=0, addbranch=0;
|
||||
char linebuff[256],nextline[256], nextlinebytes[256];
|
||||
strcpy(linebuff,"");
|
||||
strcpy(nextline,"");
|
||||
|
@ -245,7 +246,6 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
|
||||
/* pc=myAppData.start; */
|
||||
myPC = distart - myOffset;
|
||||
//cerr << " ==> pc = " << pc << "(" << pass << ")" << endl;
|
||||
while(myPC <= myAppData.end)
|
||||
{
|
||||
if(check_bit(labels[myPC], GFX))
|
||||
|
@ -263,7 +263,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
myBuf << ".byte $" << HEX2 << (int)mem[myPC] << " ; ";
|
||||
showgfx(mem[myPC]);
|
||||
myBuf << " $" << HEX4 << myPC+myOffset;
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
}
|
||||
myPC++;
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
bytes++;
|
||||
if (bytes == 17)
|
||||
{
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
myBuf << " ' '.byte $" << HEX2 << (int)mem[myPC];
|
||||
bytes = 1;
|
||||
}
|
||||
|
@ -299,9 +299,9 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
|
||||
if (pass == 3)
|
||||
{
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
myBuf << " ' ' ";
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -321,7 +321,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
amode = ourLookup[op].addr_mode;
|
||||
if (myAppData.disp_data)
|
||||
{
|
||||
for (i = 0; i < ourCLength[amode]; i++)
|
||||
for (int i = 0; i < ourCLength[amode]; i++)
|
||||
if (pass == 3)
|
||||
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
|
||||
put recompilable object larger that original binary file */
|
||||
myBuf << ".byte $" << HEX2 << op;
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
|
||||
if (myPC == myAppData.end)
|
||||
{
|
||||
|
@ -387,7 +387,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
|
||||
op = mem[myPC++];
|
||||
myBuf << ".byte $" << HEX2 << (int)op;
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
}
|
||||
}
|
||||
myPCEnd = myAppData.end + myOffset;
|
||||
|
@ -411,7 +411,7 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
strcat(nextline,linebuff);
|
||||
|
||||
myBuf << nextline;
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
strcpy(nextline,"");
|
||||
strcpy(nextlinebytes,"");
|
||||
}
|
||||
|
@ -809,15 +809,15 @@ void DiStella::disasm(uInt32 distart, int pass)
|
|||
if (strlen(nextline) <= 15)
|
||||
{
|
||||
/* 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 << ";" << dec << (int)ourLookup[op].cycles << "'" << nextlinebytes;
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
if (op == 0x40 || op == 0x60)
|
||||
{
|
||||
myBuf << " ' ' ";
|
||||
addEntry();
|
||||
addEntry(list);
|
||||
}
|
||||
|
||||
strcpy(nextline,"");
|
||||
|
@ -916,23 +916,48 @@ void DiStella::showgfx(uInt8 c)
|
|||
{
|
||||
int i;
|
||||
|
||||
printf("|");
|
||||
myBuf << "|";
|
||||
for(i = 0;i < 8; i++)
|
||||
{
|
||||
if (c > 127)
|
||||
printf("X");
|
||||
myBuf << "X";
|
||||
else
|
||||
printf(" ");
|
||||
myBuf << " ";
|
||||
|
||||
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("");
|
||||
++myLineCount;
|
||||
}
|
||||
|
@ -1296,26 +1321,12 @@ int main(int ac, char* av[])
|
|||
DiStella dis;
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
|
|
@ -29,7 +29,8 @@
|
|||
|
||||
//// The following will go in CartDebug
|
||||
struct DisassemblyTag {
|
||||
int address;
|
||||
uInt16 address;
|
||||
string label;
|
||||
string disasm;
|
||||
string bytes;
|
||||
};
|
||||
|
@ -38,10 +39,13 @@
|
|||
|
||||
/**
|
||||
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
|
||||
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.
|
||||
exactly the same, except that generated data is now redirected to a
|
||||
DisassemblyList structure rather than being printed.
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -52,7 +56,7 @@ class DiStella
|
|||
~DiStella();
|
||||
|
||||
public:
|
||||
uInt32 disassemble(DisassemblyList& list, const char* datafile, bool autocode = true);
|
||||
uInt32 disassemble(DisassemblyList& list, uInt16 PC, const char* datafile, bool autocode = true);
|
||||
|
||||
private:
|
||||
// Marked bits
|
||||
|
@ -68,22 +72,22 @@ class DiStella
|
|||
REACHABLE = 1 << 4 /* disassemble-able code segments */
|
||||
};
|
||||
|
||||
// Indicate that a new line of disassembly has been performed
|
||||
// In the original Distella code, this indicated a new line to be printed.
|
||||
// Indicate that a new line of disassembly has been completed
|
||||
// In the original Distella code, this indicated a new line to be printed
|
||||
// Here, we add a new entry to the DisassemblyList
|
||||
void addEntry();
|
||||
void addEntry(DisassemblyList& list);
|
||||
|
||||
// These functions are part of the original Distella code
|
||||
uInt32 filesize(FILE *stream);
|
||||
uInt32 read_adr();
|
||||
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 check_bit(uInt8 bitflags, int i);
|
||||
void showgfx(uInt8 c);
|
||||
|
||||
private:
|
||||
ostringstream myBuf;
|
||||
stringstream myBuf;
|
||||
queue<uInt16> myAddressQueue;
|
||||
uInt32 myOffset, myPC, myPCBeg, myPCEnd, myLineCount;
|
||||
|
||||
|
|
Loading…
Reference in New Issue