First pass at integrating dasm '.sym' labels into the disassembly output.

For now, only the infrastructure is being modified.

Make disassembly output a little nicer by drawing a vertical line
separating disassembly text from the actual raw bytes.

Some changes to the SDL sound code initialization, which will (hopefully)
eventually lead to a fix for those users with ATI video drivers, and
not having sound after the first game has been played.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2039 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2010-06-03 12:41:49 +00:00
parent 0c1029076c
commit 88f7f656e6
7 changed files with 95 additions and 121 deletions

View File

@ -81,88 +81,76 @@ void SoundSDL::open()
myIsMuted = false;
myLastRegisterSetCycle = 0;
uInt32 fragsize = myOSystem->settings().getInt("fragsize");
Int32 frequency = myOSystem->settings().getInt("freq");
Int32 tiafreq = myOSystem->settings().getInt("tiafreq");
SDL_AudioSpec desired;
desired.freq = frequency;
#ifndef GP2X
desired.format = AUDIO_U8;
#else
desired.format = AUDIO_U16;
#endif
desired.channels = myNumChannels;
desired.samples = fragsize;
desired.callback = callback;
desired.userdata = (void*)this;
ostringstream buf;
if(SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
if(SDL_OpenAudio(&desired, &myHardwareSpec) < 0)
{
buf << "WARNING: Couldn't initialize SDL audio system! " << endl
buf << "WARNING: Couldn't open SDL audio system! " << endl
<< " " << SDL_GetError() << endl;
myOSystem->logMessage(buf.str(), 0);
return;
}
else
// Make sure the sample buffer isn't to big (if it is the sound code
// will not work so we'll need to disable the audio support)
if(((float)myHardwareSpec.samples / (float)myHardwareSpec.freq) >= 0.25)
{
uInt32 fragsize = myOSystem->settings().getInt("fragsize");
Int32 frequency = myOSystem->settings().getInt("freq");
Int32 tiafreq = myOSystem->settings().getInt("tiafreq");
buf << "WARNING: Sound device doesn't support realtime audio! Make "
<< "sure a sound" << endl
<< " server isn't running. Audio is disabled." << endl;
myOSystem->logMessage(buf.str(), 0);
SDL_AudioSpec desired;
desired.freq = frequency;
#ifndef GP2X
desired.format = AUDIO_U8;
#else
desired.format = AUDIO_U16;
#endif
desired.channels = myNumChannels;
desired.samples = fragsize;
desired.callback = callback;
desired.userdata = (void*)this;
if(SDL_OpenAudio(&desired, &myHardwareSpec) < 0)
{
buf << "WARNING: Couldn't open SDL audio system! " << endl
<< " " << SDL_GetError() << endl;
myOSystem->logMessage(buf.str(), 0);
return;
}
// Make sure the sample buffer isn't to big (if it is the sound code
// will not work so we'll need to disable the audio support)
if(((float)myHardwareSpec.samples / (float)myHardwareSpec.freq) >= 0.25)
{
buf << "WARNING: Sound device doesn't support realtime audio! Make "
<< "sure a sound" << endl
<< " server isn't running. Audio is disabled." << endl;
myOSystem->logMessage(buf.str(), 0);
SDL_CloseAudio();
return;
}
myIsInitializedFlag = true;
myIsMuted = false;
myFragmentSizeLogBase2 = log((double)myHardwareSpec.samples) / log(2.0);
// Now initialize the TIASound object which will actually generate sound
myTIASound.outputFrequency(myHardwareSpec.freq);
myTIASound.tiaFrequency(tiafreq);
myTIASound.channels(myHardwareSpec.channels);
bool clipvol = myOSystem->settings().getBool("clipvol");
myTIASound.clipVolume(clipvol);
// Adjust volume to that defined in settings
myVolume = myOSystem->settings().getInt("volume");
setVolume(myVolume);
// Show some info
buf << "Sound enabled:" << endl
<< " Volume: " << myVolume << endl
<< " Frag size: " << fragsize << endl
<< " Frequency: " << myHardwareSpec.freq << endl
<< " Format: " << myHardwareSpec.format << endl
<< " TIA Freq: " << tiafreq << endl
<< " Channels: " << myNumChannels << endl
<< " Clip volume: " << (int)clipvol << endl
<< endl;
myOSystem->logMessage(buf.str(), 1);
SDL_CloseAudio();
return;
}
myIsInitializedFlag = true;
myIsMuted = false;
myFragmentSizeLogBase2 = log((double)myHardwareSpec.samples) / log(2.0);
// Now initialize the TIASound object which will actually generate sound
myTIASound.outputFrequency(myHardwareSpec.freq);
myTIASound.tiaFrequency(tiafreq);
myTIASound.channels(myHardwareSpec.channels);
bool clipvol = myOSystem->settings().getBool("clipvol");
myTIASound.clipVolume(clipvol);
// Adjust volume to that defined in settings
myVolume = myOSystem->settings().getInt("volume");
setVolume(myVolume);
// Show some info
buf << "Sound enabled:" << endl
<< " Volume: " << myVolume << endl
<< " Frag size: " << fragsize << endl
<< " Frequency: " << myHardwareSpec.freq << endl
<< " Format: " << myHardwareSpec.format << endl
<< " TIA Freq: " << tiafreq << endl
<< " Channels: " << myNumChannels << endl
<< " Clip volume: " << (int)clipvol << endl
<< endl;
myOSystem->logMessage(buf.str(), 1);
}
// And start the SDL sound subsystem ...
if(myIsInitializedFlag)
{
SDL_PauseAudio(0);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -210,16 +198,13 @@ void SoundSDL::reset()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SoundSDL::setVolume(Int32 percent)
{
if(myIsInitializedFlag)
if(myIsInitializedFlag && (percent >= 0) && (percent <= 100))
{
if((percent >= 0) && (percent <= 100))
{
myOSystem->settings().setInt("volume", percent);
SDL_LockAudio();
myVolume = percent;
myTIASound.volume(percent);
SDL_UnlockAudio();
}
myOSystem->settings().setInt("volume", percent);
SDL_LockAudio();
myVolume = percent;
myTIASound.volume(percent);
SDL_UnlockAudio();
}
}
@ -395,11 +380,9 @@ void SoundSDL::callback(void* udata, uInt8* stream, int len)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SoundSDL::save(Serializer& out) const
{
const string& device = name();
try
{
out.putString(device);
out.putString(name());
uInt8 reg1 = 0, reg2 = 0, reg3 = 0, reg4 = 0, reg5 = 0, reg6 = 0;
@ -437,11 +420,9 @@ bool SoundSDL::save(Serializer& out) const
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SoundSDL::load(Serializer& in)
{
const string& device = name();
try
{
if(in.getString() != device)
if(in.getString() != name())
return false;
uInt8 reg1 = 0, reg2 = 0, reg3 = 0, reg4 = 0, reg5 = 0, reg6 = 0;
@ -530,9 +511,7 @@ void SoundSDL::RegWriteQueue::enqueue(const RegWrite& info)
// If an attempt is made to enqueue more than the queue can hold then
// we'll enlarge the queue's capacity.
if(mySize == myCapacity)
{
grow();
}
myBuffer[myTail] = info;
myTail = (myTail + 1) % myCapacity;

View File

@ -28,7 +28,7 @@
CartDebug::CartDebug(Debugger& dbg, Console& console, const RamAreaList& areas)
: DebuggerSystem(dbg, console),
myRWPortAddress(0),
myLabelLength(6) // longest pre-defined label
myLabelLength(5) // longest pre-defined label
{
// Zero-page RAM is always present
addRamArea(0x80, 128, 0, 0);
@ -90,7 +90,7 @@ const DebuggerState& CartDebug::getState()
{
myState.ram.clear();
for(uInt32 i = 0; i < myState.rport.size(); ++i)
myState.ram.push_back(read(myState.rport[i]));
myState.ram.push_back(peek(myState.rport[i]));
return myState;
}
@ -100,19 +100,7 @@ void CartDebug::saveOldState()
{
myOldState.ram.clear();
for(uInt32 i = 0; i < myOldState.rport.size(); ++i)
myOldState.ram.push_back(read(myOldState.rport[i]));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 CartDebug::read(uInt16 addr)
{
return mySystem.peek(addr);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CartDebug::write(uInt16 addr, uInt8 value)
{
mySystem.poke(addr, value);
myOldState.ram.push_back(peek(myOldState.rport[i]));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -253,7 +241,7 @@ bool CartDebug::fillDisassemblyList(uInt16 start, bool resolvedata, uInt16 searc
bool found = false;
myDisassembly.clear();
DiStella distella(myDisassembly, start, resolvedata, myLabelLength);
DiStella distella(*this, myDisassembly, start, resolvedata);
// Parts of the disassembly will be accessed later in different ways
// We place those parts in separate maps, to speed up access
@ -287,7 +275,7 @@ int CartDebug::addressToLine(uInt16 address) const
string CartDebug::disassemble(uInt16 start, uInt16 lines) const
{
DisassemblyList list;
DiStella distella(list, start, false);
DiStella distella(*this, list, start, false);
// Fill the string with disassembled data
start &= 0xFFF;

View File

@ -54,6 +54,7 @@ class CartDebug : public DebuggerSystem
uInt16 address;
string label;
string disasm;
string ccount;
string bytes;
};
typedef Common::Array<DisassemblyTag> DisassemblyList;
@ -71,8 +72,9 @@ class CartDebug : public DebuggerSystem
// The following assume that the given addresses are using the
// correct read/write port ranges; no checking will be done to
// confirm this.
uInt8 read(uInt16 address);
void write(uInt16 address, uInt8 value);
inline uInt8 peek(uInt16 addr) { return mySystem.peek(addr); }
inline uInt16 dpeek(uInt16 addr) { return mySystem.peek(addr) | (mySystem.peek(addr+1) << 8); }
inline void poke(uInt16 addr, uInt8 value) { mySystem.poke(addr, value); }
// Indicate that a read from write port has occurred at the specified
// address.

View File

@ -22,9 +22,10 @@
#include "DiStella.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DiStella::DiStella(CartDebug::DisassemblyList& list, uInt16 start,
bool resolvedata, uInt16 labellength)
: myList(list)
DiStella::DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
uInt16 start, bool resolvedata)
: myDbg(dbg),
myList(list)
{
while(!myAddressQueue.empty())
myAddressQueue.pop();

View File

@ -46,13 +46,13 @@ class DiStella
/**
Disassemble the current state of the System from the given start address.
@param dbg The CartDebug instance containing all label information
@param list The results of the disassembly are placed here
@param start The address at which to start disassembly
@param resolvedata If enabled, try to determine code vs. data sections
@param labellength The maximum length of a label
*/
DiStella(CartDebug::DisassemblyList& list, uInt16 start, bool resolvedata = true,
uInt16 labellength = 6);
DiStella(const CartDebug& dbg, CartDebug::DisassemblyList& list,
uInt16 start, bool resolvedata = true);
~DiStella();
@ -79,9 +79,10 @@ class DiStella
void disasm(uInt32 distart, int pass);
int mark(uInt32 address, MarkType bit);
void showgfx(uInt8 c);
inline int check_bit(uInt8 bitflags, int i) { return (bitflags & i); }
inline int check_bit(uInt8 bitflags, int i) const { return (bitflags & i); }
private:
const CartDebug& myDbg;
CartDebug::DisassemblyList& myList;
stringstream myDisasmBuf;
queue<uInt16> myAddressQueue;

View File

@ -170,9 +170,9 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
value = myRamGrid->getSelectedValue();
// Attempt the write, and revert if it didn't succeed
uInt8 oldval = dbg.read(state.rport[addr]);
dbg.write(state.wport[addr], value);
uInt8 newval = dbg.read(state.rport[addr]);
uInt8 oldval = dbg.peek(state.rport[addr]);
dbg.poke(state.wport[addr], value);
uInt8 newval = dbg.peek(state.rport[addr]);
if(value != newval)
{
myRamGrid->setValue(addr - myCurrentRamBank*128, newval, false);
@ -202,12 +202,12 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
case kRevertCmd:
for(uInt32 i = 0; i < myOldValueList.size(); ++i)
dbg.write(state.wport[i], myOldValueList[i]);
dbg.poke(state.wport[i], myOldValueList[i]);
fillGrid(true);
break;
case kUndoCmd:
dbg.write(state.wport[myUndoAddress], myUndoValue);
dbg.poke(state.wport[myUndoAddress], myUndoValue);
myUndoButton->setEnabled(false);
fillGrid(false);
break;
@ -432,7 +432,7 @@ string RamWidget::doCompare(const string& str)
}
int addr = mySearchAddr[i];
if(dbg.read(state.rport[addr]) == searchVal)
if(dbg.peek(state.rport[addr]) == searchVal)
{
tempAddrList.push_back(addr);
tempValueList.push_back(searchVal);

View File

@ -70,7 +70,7 @@ RomListWidget::RomListWidget(GuiObject* boss, const GUI::Font& font,
const int fontWidth = font.getMaxCharWidth(),
numchars = w / fontWidth;
_labelWidth = BSPF_max(16, int(0.35 * (numchars - 12))) * fontWidth;
_labelWidth = BSPF_max(16, int(0.35 * (numchars - 12))) * fontWidth - 1;
_bytesWidth = 12 * fontWidth;
//////////////////////////////////////////////////////
@ -413,16 +413,16 @@ void RomListWidget::drawWidget(bool hilite)
int i, pos, xpos, ypos, len = dlist.size();
int deltax;
const GUI::Rect& r = getEditRect();
const GUI::Rect& l = getLineRect();
// Draw a thin frame around the list and to separate columns
s.hLine(_x, _y, _x + _w - 1, kColor);
s.hLine(_x, _y + _h - 1, _x + _w - 1, kShadowColor);
s.vLine(_x, _y, _y + _h - 1, kColor);
s.vLine(_x + CheckboxWidget::boxSize() + 5, _y, _y + _h - 1, kColor);
// Draw the list items
const GUI::Rect& r = getEditRect();
const GUI::Rect& l = getLineRect();
int large_disasmw = _w - l.x() - _labelWidth,
small_disasmw = large_disasmw - r.width();
xpos = _x + CheckboxWidget::boxSize() + 10; ypos = _y + 2;
@ -462,6 +462,9 @@ void RomListWidget::drawWidget(bool hilite)
s.drawString(_font, dlist[pos].disasm, xpos + _labelWidth, ypos,
small_disasmw, kTextColor);
// Draw separator
s.vLine(_x + r.x() - 7, ypos, ypos + _fontHeight - 1, kColor);
// Draw bytes
{
if (_selectedItem == pos && _editMode)