First pass at reorganizing the disassembler code. The entire functionality

will be integrated intp CpuDebug, which will also be merged with distella.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1914 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2009-12-17 21:07:56 +00:00
parent e8604d426a
commit 88df583c23
3 changed files with 125 additions and 154 deletions

View File

@ -126,96 +126,96 @@ int CpuDebug::disassemble(int address, string& result, EquateList& list)
// Are we looking at a read or write operation? // Are we looking at a read or write operation?
// It will determine what type of label to use // It will determine what type of label to use
bool isRead = (M6502::ourAccessModeTable[opcode] == M6502::Read); bool isRead = (M6502::AccessModeTable[opcode] == M6502::Read);
switch(M6502::ourAddressingModeTable[opcode]) switch(M6502::AddressModeTable[opcode])
{ {
case M6502::Absolute: case M6502::Absolute:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << " ; " << list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << " ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 3; count = 3;
break; break;
case M6502::AbsoluteX: case M6502::AbsoluteX:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << ",x ; " << list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << ",x ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 3; count = 3;
break; break;
case M6502::AbsoluteY: case M6502::AbsoluteY:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << ",y ; " << list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << ",y ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 3; count = 3;
break; break;
case M6502::Immediate: case M6502::Immediate:
buf << M6502::ourInstructionMnemonicTable[opcode] << " #$" buf << M6502::InstructionMnemonicTable[opcode] << " #$"
<< hex << setw(2) << setfill('0') << (int) mySystem.peek(address + 1) << " ; " << hex << setw(2) << setfill('0') << (int) mySystem.peek(address + 1) << " ; "
<< dec << M6502::ourInstructionProcessorCycleTable[opcode]; << dec << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
case M6502::Implied: case M6502::Implied:
buf << M6502::ourInstructionMnemonicTable[opcode] << " ; " buf << M6502::InstructionMnemonicTable[opcode] << " ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 1; count = 1;
break; break;
case M6502::Indirect: case M6502::Indirect:
buf << M6502::ourInstructionMnemonicTable[opcode] << " (" buf << M6502::InstructionMnemonicTable[opcode] << " ("
<< list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << ") ; " << list.getLabel(dpeek(mySystem, address + 1), isRead, 4) << ") ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 3; count = 3;
break; break;
case M6502::IndirectX: case M6502::IndirectX:
buf << M6502::ourInstructionMnemonicTable[opcode] << " (" buf << M6502::InstructionMnemonicTable[opcode] << " ("
<< list.getLabel(mySystem.peek(address + 1), isRead, 2) << ",x) ; " << list.getLabel(mySystem.peek(address + 1), isRead, 2) << ",x) ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
case M6502::IndirectY: case M6502::IndirectY:
buf << M6502::ourInstructionMnemonicTable[opcode] << " (" buf << M6502::InstructionMnemonicTable[opcode] << " ("
<< list.getLabel(mySystem.peek(address + 1), isRead, 2) << "),y ; " << list.getLabel(mySystem.peek(address + 1), isRead, 2) << "),y ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
case M6502::Relative: case M6502::Relative:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(address + 2 + ((Int16)(Int8)mySystem.peek(address + 1)), isRead, 4) << list.getLabel(address + 2 + ((Int16)(Int8)mySystem.peek(address + 1)), isRead, 4)
<< " ; " << M6502::ourInstructionProcessorCycleTable[opcode]; << " ; " << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
case M6502::Zero: case M6502::Zero:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(mySystem.peek(address + 1), isRead, 2) << " ; " << list.getLabel(mySystem.peek(address + 1), isRead, 2) << " ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
case M6502::ZeroX: case M6502::ZeroX:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(mySystem.peek(address + 1), isRead, 2) << ",x ; " << list.getLabel(mySystem.peek(address + 1), isRead, 2) << ",x ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
case M6502::ZeroY: case M6502::ZeroY:
buf << M6502::ourInstructionMnemonicTable[opcode] << " " buf << M6502::InstructionMnemonicTable[opcode] << " "
<< list.getLabel(mySystem.peek(address + 1), isRead, 2) << ",y ; " << list.getLabel(mySystem.peek(address + 1), isRead, 2) << ",y ; "
<< M6502::ourInstructionProcessorCycleTable[opcode]; << M6502::InstructionCycleTable[opcode];
count = 2; count = 2;
break; break;
default: default:
buf << "dc $" << hex << setw(2) << setfill('0') << (int) opcode << " ; " buf << "dc $" << hex << setw(2) << setfill('0') << (int) opcode << " ; "
<< dec << M6502::ourInstructionProcessorCycleTable[opcode]; << dec << M6502::InstructionCycleTable[opcode];
count = 1; count = 1;
break; break;
} }

View File

@ -50,7 +50,7 @@ M6502::M6502(uInt32 systemCyclesPerProcessorCycle)
// Compute the System Cycle table // Compute the System Cycle table
for(uInt32 t = 0; t < 256; ++t) for(uInt32 t = 0; t < 256; ++t)
{ {
myInstructionSystemCycleTable[t] = ourInstructionProcessorCycleTable[t] * myInstructionSystemCycleTable[t] = InstructionCycleTable[t] *
mySystemCyclesPerProcessorCycle; mySystemCyclesPerProcessorCycle;
} }
@ -418,6 +418,7 @@ bool M6502::load(Serializer& in)
return true; return true;
} }
#if 0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ostream& operator<<(ostream& out, const M6502::AddressingMode& mode) ostream& operator<<(ostream& out, const M6502::AddressingMode& mode)
{ {
@ -465,9 +466,78 @@ ostream& operator<<(ostream& out, const M6502::AddressingMode& mode)
} }
return out; return out;
} }
#endif
#ifdef DEBUGGER_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::attach(Debugger& debugger)
{
// Remember the debugger for this microprocessor
myDebugger = &debugger;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6502::AddressingMode M6502::ourAddressingModeTable[256] = { unsigned int M6502::addCondBreak(Expression *e, const string& name)
{
myBreakConds.push_back(e);
myBreakCondNames.push_back(name);
return myBreakConds.size() - 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::delCondBreak(unsigned int brk)
{
if(brk < myBreakConds.size())
{
delete myBreakConds[brk];
myBreakConds.remove_at(brk);
myBreakCondNames.remove_at(brk);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::clearCondBreaks()
{
for(uInt32 i = 0; i < myBreakConds.size(); i++)
delete myBreakConds[i];
myBreakConds.clear();
myBreakCondNames.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const StringList& M6502::getCondBreakNames() const
{
return myBreakCondNames;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int M6502::evalCondBreaks()
{
for(uInt32 i = 0; i < myBreakConds.size(); i++)
if(myBreakConds[i]->evaluate())
return i;
return -1; // no break hit
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::setBreakPoints(PackedBitArray *bp)
{
myBreakPoints = bp;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::setTraps(PackedBitArray *read, PackedBitArray *write)
{
myReadTraps = read;
myWriteTraps = write;
}
#endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6502::AddressingMode M6502::AddressModeTable[256] = {
Implied, IndirectX, Invalid, IndirectX, // 0x0? Implied, IndirectX, Invalid, IndirectX, // 0x0?
Zero, Zero, Zero, Zero, Zero, Zero, Zero, Zero,
Implied, Immediate, Implied, Immediate, Implied, Immediate, Implied, Immediate,
@ -550,7 +620,7 @@ M6502::AddressingMode M6502::ourAddressingModeTable[256] = {
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
M6502::AccessMode M6502::ourAccessModeTable[256] = { M6502::AccessMode M6502::AccessModeTable[256] = {
None, Read, None, Write, // 0x0? None, Read, None, Write, // 0x0?
None, Read, Write, Write, None, Read, Write, Write,
None, Read, Write, Read, None, Read, Write, Read,
@ -633,7 +703,7 @@ M6502::AccessMode M6502::ourAccessModeTable[256] = {
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt32 M6502::ourInstructionProcessorCycleTable[256] = { uInt32 M6502::InstructionCycleTable[256] = {
// 0 1 2 3 4 5 6 7 8 9 a b c d e f // 0 1 2 3 4 5 6 7 8 9 a b c d e f
7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, // 0 7, 6, 2, 8, 3, 3, 5, 5, 3, 2, 2, 2, 4, 4, 6, 6, // 0
2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1 2, 5, 2, 8, 4, 4, 6, 6, 2, 4, 2, 7, 4, 4, 7, 7, // 1
@ -654,7 +724,7 @@ uInt32 M6502::ourInstructionProcessorCycleTable[256] = {
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const char* M6502::ourInstructionMnemonicTable[256] = { const char* M6502::InstructionMnemonicTable[256] = {
"BRK", "ORA", "n/a", "slo", "nop", "ORA", "ASL", "slo", // 0x0? "BRK", "ORA", "n/a", "slo", "nop", "ORA", "ASL", "slo", // 0x0?
"PHP", "ORA", "ASLA", "anc", "nop", "ORA", "ASL", "slo", "PHP", "ORA", "ASLA", "anc", "nop", "ORA", "ASL", "slo",
@ -703,71 +773,3 @@ const char* M6502::ourInstructionMnemonicTable[256] = {
"BEQ", "SBC", "n/a", "isb", "nop", "SBC", "INC", "isb", // 0xF? "BEQ", "SBC", "n/a", "isb", "nop", "SBC", "INC", "isb", // 0xF?
"SED", "SBC", "nop", "isb", "nop", "SBC", "INC", "isb" "SED", "SBC", "nop", "isb", "nop", "SBC", "INC", "isb"
}; };
#ifdef DEBUGGER_SUPPORT
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::attach(Debugger& debugger)
{
// Remember the debugger for this microprocessor
myDebugger = &debugger;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unsigned int M6502::addCondBreak(Expression *e, const string& name)
{
myBreakConds.push_back(e);
myBreakCondNames.push_back(name);
return myBreakConds.size() - 1;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::delCondBreak(unsigned int brk)
{
if(brk < myBreakConds.size())
{
delete myBreakConds[brk];
myBreakConds.remove_at(brk);
myBreakCondNames.remove_at(brk);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::clearCondBreaks()
{
for(uInt32 i = 0; i < myBreakConds.size(); i++)
delete myBreakConds[i];
myBreakConds.clear();
myBreakCondNames.clear();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const StringList& M6502::getCondBreakNames() const
{
return myBreakCondNames;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int M6502::evalCondBreaks()
{
for(uInt32 i = 0; i < myBreakConds.size(); i++)
if(myBreakConds[i]->evaluate())
return i;
return -1; // no break hit
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::setBreakPoints(PackedBitArray *bp)
{
myBreakPoints = bp;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void M6502::setTraps(PackedBitArray *read, PackedBitArray *write)
{
myReadTraps = read;
myWriteTraps = write;
}
#endif

View File

@ -49,31 +49,9 @@ typedef Common::Array<Expression*> ExpressionList;
*/ */
class M6502 : public Serializable class M6502 : public Serializable
{ {
public: // The 6502 debugger class is a friend who needs special access
/**
The 6502 debugger class is a friend who needs special access
*/
friend class CpuDebug; friend class CpuDebug;
public:
/**
Enumeration of the 6502 addressing modes
*/
enum AddressingMode
{
Absolute, AbsoluteX, AbsoluteY, Immediate, Implied,
Indirect, IndirectX, IndirectY, Invalid, Relative,
Zero, ZeroX, ZeroY
};
/**
Enumeration of the 6502 access modes
*/
enum AccessMode
{
Read, Write, None
};
public: public:
/** /**
Create a new 6502 microprocessor with the specified cycle Create a new 6502 microprocessor with the specified cycle
@ -182,14 +160,6 @@ class M6502 : public Serializable
*/ */
uInt32 distinctAccesses() const { return myNumberOfDistinctAccesses; } uInt32 distinctAccesses() const { return myNumberOfDistinctAccesses; }
/**
Overload the ostream output operator for addressing modes.
@param out The stream to output the addressing mode to
@param mode The addressing mode to output
*/
friend ostream& operator<<(ostream& out, const AddressingMode& mode);
/** /**
Saves the current state of this device to the given Serializer. Saves the current state of this device to the given Serializer.
@ -213,25 +183,6 @@ class M6502 : public Serializable
*/ */
string name() const { return "M6502"; } string name() const { return "M6502"; }
public:
/**
Get the addressing mode of the specified instruction
@param opcode The opcode of the instruction
@return The addressing mode of the instruction
*/
AddressingMode addressingMode(uInt8 opcode) const
{ return ourAddressingModeTable[opcode]; }
/**
Get the access mode of the specified instruction
@param opcode The opcode of the instruction
@return The access mode of the instruction
*/
AccessMode accessMode(uInt8 opcode) const
{ return ourAccessModeTable[opcode]; }
#ifdef DEBUGGER_SUPPORT #ifdef DEBUGGER_SUPPORT
public: public:
/** /**
@ -364,22 +315,40 @@ class M6502 : public Serializable
#endif #endif
private: private:
/**
Enumeration of the 6502 addressing modes
*/
enum AddressingMode
{
Absolute, AbsoluteX, AbsoluteY, Immediate, Implied,
Indirect, IndirectX, IndirectY, Invalid, Relative,
Zero, ZeroX, ZeroY
};
/**
Enumeration of the 6502 access modes
*/
enum AccessMode
{
Read, Write, None
};
/// Addressing mode for each of the 256 opcodes /// Addressing mode for each of the 256 opcodes
/// This specifies how the opcode argument is addressed /// This specifies how the opcode argument is addressed
static AddressingMode ourAddressingModeTable[256]; static AddressingMode AddressModeTable[256];
/// Access mode for each of the 256 opcodes /// Access mode for each of the 256 opcodes
/// This specifies how the opcode will access its argument /// This specifies how the opcode will access its argument
static AccessMode ourAccessModeTable[256]; static AccessMode AccessModeTable[256];
/** /**
Table of instruction processor cycle times. In some cases additional Table of instruction processor cycle times. In some cases additional
cycles will be added during the execution of an instruction. cycles will be added during the execution of an instruction.
*/ */
static uInt32 ourInstructionProcessorCycleTable[256]; static uInt32 InstructionCycleTable[256];
/// Table of instruction mnemonics /// Table of instruction mnemonics
static const char* ourInstructionMnemonicTable[256]; static const char* InstructionMnemonicTable[256];
}; };
#endif #endif