mirror of https://github.com/stella-emu/stella.git
Revamped the result on floating pins for TIA reads. Previously, this was
controlled by 'tiafloat', which has now been removed. Now, all undriven pins take on the last value on the databus. This fixes a bug in those reads where bit 6 or bits 6 & 7 are also undriven (previously, these bits would always be zero, and only bits 0-5 were from lastdatabus. Added new commandline argument 'tiadriven', which defaults to false. In this default case, relevant bits take on values from the databus. If true, relevant bits still take on databus values, but some are randomly driven high as well. This helps to expose bugs when developers assume the values for undriven/floating bits. Added 'uimessages' commandline argument and associated UI item. When disabled, messages which are normally shown in-game are disabled. Certain messages which indicate a serious error are still shown, however. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1900 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
f1e88a2d48
commit
00f8ffb686
|
@ -1927,7 +1927,8 @@ bool EventHandler::enterDebugMode()
|
|||
{
|
||||
myOSystem->debugger().setQuitState();
|
||||
setEventState(S_EMULATE);
|
||||
myOSystem->frameBuffer().showMessage("Debugger window too large");
|
||||
myOSystem->frameBuffer().showMessage("Debugger window too large",
|
||||
kBottomCenter, true);
|
||||
return false;
|
||||
}
|
||||
myOverlay->reStack();
|
||||
|
@ -1935,7 +1936,8 @@ bool EventHandler::enterDebugMode()
|
|||
myOSystem->sound().mute(true);
|
||||
myEvent->clear();
|
||||
#else
|
||||
myOSystem->frameBuffer().showMessage("Debugger unsupported");
|
||||
myOSystem->frameBuffer().showMessage("Debugger unsupported",
|
||||
kBottomCenter, true);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
|
|
@ -271,8 +271,12 @@ void FrameBuffer::update()
|
|||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void FrameBuffer::showMessage(const string& message, MessagePosition position,
|
||||
uInt32 color)
|
||||
bool force, uInt32 color)
|
||||
{
|
||||
// Only show messages if they've been enabled
|
||||
if(!(force || myOSystem->settings().getBool("uimessages")))
|
||||
return;
|
||||
|
||||
// Erase old messages on the screen
|
||||
if(myMsg.counter > 0)
|
||||
{
|
||||
|
|
|
@ -127,10 +127,12 @@ class FrameBuffer
|
|||
|
||||
@param message The message to be shown
|
||||
@param position Onscreen position for the message
|
||||
@param force Force showing this message, even if messages are disabled
|
||||
@param color Color of text in the message
|
||||
*/
|
||||
void showMessage(const string& message,
|
||||
MessagePosition position = kBottomCenter,
|
||||
bool force = false,
|
||||
uInt32 color = kTextColorHi);
|
||||
|
||||
/**
|
||||
|
|
|
@ -437,7 +437,8 @@ fallback:
|
|||
if(ret)
|
||||
{
|
||||
setFramerate(60);
|
||||
myFrameBuffer->showMessage("OpenGL mode failed, fallback to software", kMiddleCenter);
|
||||
myFrameBuffer->showMessage("OpenGL mode failed, fallback to software",
|
||||
kMiddleCenter, true);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -57,6 +57,7 @@ Settings::Settings(OSystem* osystem)
|
|||
setInternal("palette", "standard");
|
||||
setInternal("colorloss", "false");
|
||||
setInternal("timing", "sleep");
|
||||
setInternal("uimessages", "true");
|
||||
|
||||
// TV filter options
|
||||
setInternal("tv_tex", "off");
|
||||
|
@ -114,7 +115,7 @@ Settings::Settings(OSystem* osystem)
|
|||
// Misc options
|
||||
setInternal("autoslot", "false");
|
||||
setInternal("showinfo", "false");
|
||||
setInternal("tiafloat", "true");
|
||||
setInternal("tiadriven", "false");
|
||||
setInternal("avoxport", "");
|
||||
setInternal("stats", "false");
|
||||
setInternal("audiofirst", "true");
|
||||
|
@ -289,7 +290,6 @@ void Settings::validate()
|
|||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void Settings::usage()
|
||||
{
|
||||
#ifndef MAC_OSX
|
||||
cout << endl
|
||||
<< "Stella version " << STELLA_VERSION << endl
|
||||
<< endl
|
||||
|
@ -339,6 +339,7 @@ void Settings::usage()
|
|||
<< " -colorloss <1|0> Enable PAL color-loss effect\n"
|
||||
<< " -framerate <number> Display the given number of frames per second (0 to auto-calculate)\n"
|
||||
<< " -timing <sleep|busy> Use the given type of wait between frames\n"
|
||||
<< " -uimessages <1|0> Show onscreen UI messages for different events\n"
|
||||
<< endl
|
||||
#ifdef SOUND_SUPPORT
|
||||
<< " -sound <1|0> Enable sound generation\n"
|
||||
|
@ -395,7 +396,7 @@ void Settings::usage()
|
|||
<< " -holdselect Start the emulator with the Game Select switch held down\n"
|
||||
<< " -holdbutton0 Start the emulator with the left joystick button held down\n"
|
||||
<< " -stats <1|0> Overlay console info during emulation\n"
|
||||
<< " -tiafloat <1|0> Set unused TIA pins floating on a read/peek\n"
|
||||
<< " -tiadriven <1|0> Drive unused TIA pins randomly value on a read/peek\n"
|
||||
<< endl
|
||||
<< " -bs <arg> Sets the 'Cartridge.Type' (bankswitch) property\n"
|
||||
<< " -type <arg> Same as using -bs\n"
|
||||
|
@ -415,7 +416,6 @@ void Settings::usage()
|
|||
<< " -ppblend <arg> Sets the 'Display.PPBlend' property\n"
|
||||
#endif
|
||||
<< endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -169,9 +169,8 @@ void TIA::reset()
|
|||
myDumpEnabled = false;
|
||||
myDumpDisabledCycle = 0;
|
||||
|
||||
// The mask indicates which pins should be driven high
|
||||
// If a pin is floating (the default), then its mask value is 0
|
||||
myOutputPinsMask = mySettings.getBool("tiafloat") ? 0x00 : 0x3F;
|
||||
// Should undriven pins be randomly driven high or low?
|
||||
myTIAPinsDriven = mySettings.getBool("tiadriven");
|
||||
|
||||
myFrameCounter = 0;
|
||||
myScanlineCountForLastFrame = 0;
|
||||
|
@ -1162,83 +1161,93 @@ uInt8 TIA::peek(uInt16 addr)
|
|||
// Update frame to current color clock before we look at anything!
|
||||
updateFrame(mySystem->cycles() * 3);
|
||||
|
||||
uInt8 value = 0x00;
|
||||
// If pins are undriven, we start with the last databus value
|
||||
// Otherwise, there is some randomness injected into the mix
|
||||
uInt8 value = myTIAPinsDriven ? mySystem->getDataBusState(0xFF) :
|
||||
mySystem->getDataBusState();
|
||||
uInt16 collision = myCollision & (uInt16)myCollisionEnabledMask;
|
||||
|
||||
switch(addr & 0x000f)
|
||||
{
|
||||
case CXM0P:
|
||||
value = ((collision & Cx_M0P1) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_M0P1) ? 0x80 : 0x00) |
|
||||
((collision & Cx_M0P0) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case CXM1P:
|
||||
value = ((collision & Cx_M1P0) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_M1P0) ? 0x80 : 0x00) |
|
||||
((collision & Cx_M1P1) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case CXP0FB:
|
||||
value = ((collision & Cx_P0PF) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_P0PF) ? 0x80 : 0x00) |
|
||||
((collision & Cx_P0BL) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case CXP1FB:
|
||||
value = ((collision & Cx_P1PF) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_P1PF) ? 0x80 : 0x00) |
|
||||
((collision & Cx_P1BL) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case CXM0FB:
|
||||
value = ((collision & Cx_M0PF) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_M0PF) ? 0x80 : 0x00) |
|
||||
((collision & Cx_M0BL) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case CXM1FB:
|
||||
value = ((collision & Cx_M1PF) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_M1PF) ? 0x80 : 0x00) |
|
||||
((collision & Cx_M1BL) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case CXBLPF:
|
||||
value = (collision & Cx_BLPF) ? 0x80 : 0x00;
|
||||
value = (value & 0x7F) | ((collision & Cx_BLPF) ? 0x80 : 0x00);
|
||||
break;
|
||||
|
||||
case CXPPMM:
|
||||
value = ((collision & Cx_P0P1) ? 0x80 : 0x00) |
|
||||
value = (value & 0x3F) |
|
||||
((collision & Cx_P0P1) ? 0x80 : 0x00) |
|
||||
((collision & Cx_M0M1) ? 0x40 : 0x00);
|
||||
break;
|
||||
|
||||
case INPT0:
|
||||
value = dumpedInputPort(myConsole.controller(Controller::Left).read(Controller::Nine));
|
||||
value = (value & 0x7F) |
|
||||
dumpedInputPort(myConsole.controller(Controller::Left).read(Controller::Nine));
|
||||
break;
|
||||
|
||||
case INPT1:
|
||||
value = dumpedInputPort(myConsole.controller(Controller::Left).read(Controller::Five));
|
||||
value = (value & 0x7F) |
|
||||
dumpedInputPort(myConsole.controller(Controller::Left).read(Controller::Five));
|
||||
break;
|
||||
|
||||
case INPT2:
|
||||
value = dumpedInputPort(myConsole.controller(Controller::Right).read(Controller::Nine));
|
||||
value = (value & 0x7F) |
|
||||
dumpedInputPort(myConsole.controller(Controller::Right).read(Controller::Nine));
|
||||
break;
|
||||
|
||||
case INPT3:
|
||||
value = dumpedInputPort(myConsole.controller(Controller::Right).read(Controller::Five));
|
||||
value = (value & 0x7F) |
|
||||
dumpedInputPort(myConsole.controller(Controller::Right).read(Controller::Five));
|
||||
break;
|
||||
|
||||
case INPT4:
|
||||
value = myConsole.controller(Controller::Left).read(Controller::Six) ? 0x80 : 0x00;
|
||||
value = (value & 0x7F) |
|
||||
(myConsole.controller(Controller::Left).read(Controller::Six) ? 0x80 : 0x00);
|
||||
break;
|
||||
|
||||
case INPT5:
|
||||
value = myConsole.controller(Controller::Right).read(Controller::Six) ? 0x80 : 0x00;
|
||||
value = (value & 0x7F) |
|
||||
(myConsole.controller(Controller::Right).read(Controller::Six) ? 0x80 : 0x00);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// On certain CMOS EPROM chips the unused TIA pins on a read are not
|
||||
// floating but pulled high. Programmers might want to check their
|
||||
// games for compatibility, so we make this optional.
|
||||
value |= ((mySystem->getDataBusState() | myOutputPinsMask) & 0x3F);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
|
|
@ -562,9 +562,9 @@ class TIA : public Device
|
|||
bool myHMOVEBlankEnabled;
|
||||
bool myAllowHMOVEBlanks;
|
||||
|
||||
// Indicates if unused TIA pins are floating on a peek
|
||||
// Otherwise, they're forced high
|
||||
uInt8 myOutputPinsMask;
|
||||
// Indicates if unused TIA pins are randomly driven high or low
|
||||
// Otherwise, they take on the value previously on the databus
|
||||
bool myTIAPinsDriven;
|
||||
|
||||
// Bitmap of the objects that should be considered while drawing
|
||||
uInt8 myEnabledObjects;
|
||||
|
|
|
@ -518,10 +518,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
|
|||
}
|
||||
else
|
||||
instance().frameBuffer().showMessage(
|
||||
"Error creating console (screen too small)", kMiddleCenter);
|
||||
"Error creating console (screen too small)", kMiddleCenter, true);
|
||||
}
|
||||
else
|
||||
instance().frameBuffer().showMessage("Not a valid ROM file", kMiddleCenter);
|
||||
instance().frameBuffer().showMessage("Not a valid ROM file",
|
||||
kMiddleCenter, true);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -214,6 +214,12 @@ VideoDialog::VideoDialog(OSystem* osystem, DialogContainer* parent,
|
|||
wid.push_back(myGrabmouseCheckbox);
|
||||
ypos += lineHeight + 4;
|
||||
|
||||
// Show UI messages onscreen
|
||||
myUIMessagesCheckbox = new CheckboxWidget(myTab, font, xpos, ypos,
|
||||
"Show UI messages");
|
||||
wid.push_back(myUIMessagesCheckbox);
|
||||
ypos += lineHeight + 4;
|
||||
|
||||
// Center window (in windowed mode)
|
||||
myCenterCheckbox = new CheckboxWidget(myTab, font, xpos, ypos,
|
||||
"Center window (*)");
|
||||
|
@ -413,6 +419,9 @@ void VideoDialog::loadConfig()
|
|||
// Grab mouse
|
||||
myGrabmouseCheckbox->setState(instance().settings().getBool("grabmouse"));
|
||||
|
||||
// Show UI messages
|
||||
myUIMessagesCheckbox->setState(instance().settings().getBool("uimessages"));
|
||||
|
||||
// Center window
|
||||
myCenterCheckbox->setState(instance().settings().getBool("center"));
|
||||
|
||||
|
@ -508,6 +517,9 @@ void VideoDialog::saveConfig()
|
|||
instance().settings().setBool("grabmouse", myGrabmouseCheckbox->getState());
|
||||
instance().frameBuffer().setCursorState();
|
||||
|
||||
// Show UI messages
|
||||
instance().settings().setBool("uimessages", myUIMessagesCheckbox->getState());
|
||||
|
||||
// Center window
|
||||
instance().settings().setBool("center", myCenterCheckbox->getState());
|
||||
|
||||
|
@ -552,6 +564,7 @@ void VideoDialog::setDefaults()
|
|||
myGLStretchCheckbox->setState(false);
|
||||
myUseVSyncCheckbox->setState(true);
|
||||
myGrabmouseCheckbox->setState(false);
|
||||
myUIMessagesCheckbox->setState(true);
|
||||
myCenterCheckbox->setState(true);
|
||||
myFastSCBiosCheckbox->setState(false);
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ class VideoDialog : public Dialog
|
|||
CheckboxWidget* myColorLossCheckbox;
|
||||
CheckboxWidget* myGLStretchCheckbox;
|
||||
CheckboxWidget* myUseVSyncCheckbox;
|
||||
CheckboxWidget* myUIMessagesCheckbox;
|
||||
CheckboxWidget* myCenterCheckbox;
|
||||
CheckboxWidget* myGrabmouseCheckbox;
|
||||
CheckboxWidget* myFastSCBiosCheckbox;
|
||||
|
|
Loading…
Reference in New Issue