mirror of https://github.com/stella-emu/stella.git
Added emulation of D6 (interrupt flag) to the Interrupt Flag register
of the RIOT chip. This flag is related to the edge-detect circuitry, and set on active transition of PA7 pin, cleared upon reading from TIMINT (but only *after* its result is included in the TIMINT read). git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2553 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
06854e7877
commit
faa78ad56a
|
@ -14,9 +14,16 @@
|
||||||
|
|
||||||
3.7.2 to 3.8: (xxx xx, 2012)
|
3.7.2 to 3.8: (xxx xx, 2012)
|
||||||
|
|
||||||
|
* Note: because of TIA/RIOT changes, the state file format has changed
|
||||||
|
again, and old state files will not work with this release.
|
||||||
|
|
||||||
* Improved handling of 'illegal' VSYNC signals, which sometimes created
|
* Improved handling of 'illegal' VSYNC signals, which sometimes created
|
||||||
'short' frames that caused massive flickering.
|
'short' frames that caused massive flickering.
|
||||||
|
|
||||||
|
* Improved emulation of RIOT chip, in particular the behaviour of
|
||||||
|
reading from TIMINT. Also, D6 of the Interrupt Flag register is now
|
||||||
|
properly set on active transition of the PA7 pin.
|
||||||
|
|
||||||
* The ROM properties database now uses 'Auto' instead of 'Auto-select'
|
* The ROM properties database now uses 'Auto' instead of 'Auto-select'
|
||||||
everywhere. This makes for less typing when running from the
|
everywhere. This makes for less typing when running from the
|
||||||
commandline.
|
commandline.
|
||||||
|
|
|
@ -65,6 +65,7 @@ class Controller : public Serializable
|
||||||
/**
|
/**
|
||||||
Riot debug class needs special access to the underlying controller state
|
Riot debug class needs special access to the underlying controller state
|
||||||
*/
|
*/
|
||||||
|
friend class M6532;
|
||||||
friend class RiotDebug;
|
friend class RiotDebug;
|
||||||
friend class CompuMate;
|
friend class CompuMate;
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
#include "Snapshot.hxx"
|
#include "Snapshot.hxx"
|
||||||
#include "Sound.hxx"
|
#include "Sound.hxx"
|
||||||
#include "StateManager.hxx"
|
#include "StateManager.hxx"
|
||||||
#include "Switches.hxx"
|
#include "M6532.hxx"
|
||||||
#include "MouseControl.hxx"
|
#include "MouseControl.hxx"
|
||||||
|
|
||||||
#include "EventHandler.hxx"
|
#include "EventHandler.hxx"
|
||||||
|
@ -955,9 +955,7 @@ void EventHandler::poll(uInt64 time)
|
||||||
// related to emulation
|
// related to emulation
|
||||||
if(myState == S_EMULATE)
|
if(myState == S_EMULATE)
|
||||||
{
|
{
|
||||||
myOSystem->console().controller(Controller::Left).update();
|
myOSystem->console().riot().update();
|
||||||
myOSystem->console().controller(Controller::Right).update();
|
|
||||||
myOSystem->console().switches().update();
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// Now check if the StateManager should be saving or loading state
|
// Now check if the StateManager should be saving or loading state
|
||||||
|
|
|
@ -64,6 +64,9 @@ void M6532::reset()
|
||||||
// Zero the interrupt flag register and mark D7 as invalid
|
// Zero the interrupt flag register and mark D7 as invalid
|
||||||
myInterruptFlag = 0x00;
|
myInterruptFlag = 0x00;
|
||||||
myTimerFlagValid = false;
|
myTimerFlagValid = false;
|
||||||
|
|
||||||
|
// Edge-detect set to negative (high to low)
|
||||||
|
myEdgeDetectPositive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -78,6 +81,29 @@ void M6532::systemCyclesReset()
|
||||||
myConsole.controller(Controller::Right).systemCyclesReset();
|
myConsole.controller(Controller::Right).systemCyclesReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void M6532::update()
|
||||||
|
{
|
||||||
|
Controller& port0 = myConsole.controller(Controller::Left);
|
||||||
|
Controller& port1 = myConsole.controller(Controller::Right);
|
||||||
|
|
||||||
|
// Get current PA7 state
|
||||||
|
bool prevPA7 = port0.myDigitalPinState[Controller::Four];
|
||||||
|
|
||||||
|
// Update entire port state
|
||||||
|
port0.update();
|
||||||
|
port1.update();
|
||||||
|
myConsole.switches().update();
|
||||||
|
|
||||||
|
// Get new PA7 state
|
||||||
|
bool currPA7 = port0.myDigitalPinState[Controller::Four];
|
||||||
|
|
||||||
|
// PA7 Flag is set on active transition in appropriate direction
|
||||||
|
if((!myEdgeDetectPositive && prevPA7 && !currPA7) ||
|
||||||
|
(myEdgeDetectPositive && !prevPA7 && currPA7))
|
||||||
|
myInterruptFlag |= PA7Bit;
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void M6532::install(System& system)
|
void M6532::install(System& system)
|
||||||
{
|
{
|
||||||
|
@ -181,7 +207,10 @@ uInt8 M6532::peek(uInt16 addr)
|
||||||
myInterruptFlag |= TimerBit;
|
myInterruptFlag |= TimerBit;
|
||||||
myTimerFlagValid = true;
|
myTimerFlagValid = true;
|
||||||
}
|
}
|
||||||
return myInterruptFlag;
|
// PA7 Flag is always cleared after accessing TIMINT
|
||||||
|
uInt8 result = myInterruptFlag;
|
||||||
|
myInterruptFlag &= ~PA7Bit;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -208,10 +237,17 @@ bool M6532::poke(uInt16 addr, uInt8 value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// A2 distinguishes I/O registers from the timer
|
// A2 distinguishes I/O registers from the timer
|
||||||
|
// A2 = 1 is write to timer
|
||||||
|
// A2 = 0 is write to I/O
|
||||||
if((addr & 0x04) != 0)
|
if((addr & 0x04) != 0)
|
||||||
{
|
{
|
||||||
if((addr & 0x10) != 0) // TIMxT (x = 1, 8, 64, 1024)
|
// A4 = 1 is write to TIMxT (x = 1, 8, 64, 1024)
|
||||||
setTimerRegister(value, addr & 0x03);
|
// A4 = 0 is write to edge detect control
|
||||||
|
if((addr & 0x10) != 0)
|
||||||
|
setTimerRegister(value, addr & 0x03); // A1A0 determines interval
|
||||||
|
else {
|
||||||
|
myEdgeDetectPositive = addr & 0x01; // A0 determines direction
|
||||||
|
cerr << "myEdgeDetectPositive: " << myEdgeDetectPositive << endl; }
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -303,7 +339,6 @@ bool M6532::save(Serializer& out) const
|
||||||
{
|
{
|
||||||
out.putString(name());
|
out.putString(name());
|
||||||
|
|
||||||
// Output the RAM
|
|
||||||
out.putByteArray(myRAM, 128);
|
out.putByteArray(myRAM, 128);
|
||||||
|
|
||||||
out.putInt(myTimer);
|
out.putInt(myTimer);
|
||||||
|
@ -314,8 +349,10 @@ bool M6532::save(Serializer& out) const
|
||||||
out.putByte(myDDRB);
|
out.putByte(myDDRB);
|
||||||
out.putByte(myOutA);
|
out.putByte(myOutA);
|
||||||
out.putByte(myOutB);
|
out.putByte(myOutB);
|
||||||
|
|
||||||
out.putByte(myInterruptFlag);
|
out.putByte(myInterruptFlag);
|
||||||
out.putBool(myTimerFlagValid);
|
out.putBool(myTimerFlagValid);
|
||||||
|
out.putBool(myEdgeDetectPositive);
|
||||||
out.putByteArray(myOutTimer, 4);
|
out.putByteArray(myOutTimer, 4);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
@ -335,7 +372,6 @@ bool M6532::load(Serializer& in)
|
||||||
if(in.getString() != name())
|
if(in.getString() != name())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Input the RAM
|
|
||||||
in.getByteArray(myRAM, 128);
|
in.getByteArray(myRAM, 128);
|
||||||
|
|
||||||
myTimer = in.getInt();
|
myTimer = in.getInt();
|
||||||
|
@ -346,8 +382,10 @@ bool M6532::load(Serializer& in)
|
||||||
myDDRB = in.getByte();
|
myDDRB = in.getByte();
|
||||||
myOutA = in.getByte();
|
myOutA = in.getByte();
|
||||||
myOutB = in.getByte();
|
myOutB = in.getByte();
|
||||||
|
|
||||||
myInterruptFlag = in.getByte();
|
myInterruptFlag = in.getByte();
|
||||||
myTimerFlagValid = in.getBool();
|
myTimerFlagValid = in.getBool();
|
||||||
|
myEdgeDetectPositive = in.getBool();
|
||||||
in.getByteArray(myOutTimer, 4);
|
in.getByteArray(myOutTimer, 4);
|
||||||
}
|
}
|
||||||
catch(...)
|
catch(...)
|
||||||
|
|
|
@ -30,16 +30,13 @@ class Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class models the M6532 RAM-I/O-Timer (aka RIOT) chip in the 2600
|
This class models the M6532 RAM-I/O-Timer (aka RIOT) chip in the 2600
|
||||||
console. Note that only the functionality used by the console is
|
console. Note that since the M6507 CPU doesn't contain an interrupt line,
|
||||||
emulated here; several aspects of the chip are completely ignored:
|
the following functionality relating to the RIOT IRQ line is not emulated:
|
||||||
|
|
||||||
- Pin 25 (IRQ) is not connected at all, therefore all related
|
- A3 to enable/disable interrupt from timer to IRQ
|
||||||
items are ignored (A3 determining IRQ enable/disable, etc).
|
- A1 to enable/disable interrupt from PA7 to IRQ
|
||||||
|
|
||||||
- D6 of the Interrupt Flag is ignored, including PA7 interrupt flag (A1)
|
@author Bradford W. Mott and Stephen Anthony
|
||||||
and negative/positive edge-detection (A0)
|
|
||||||
|
|
||||||
@author Bradford W. Mott
|
|
||||||
@version $Id$
|
@version $Id$
|
||||||
*/
|
*/
|
||||||
class M6532 : public Device
|
class M6532 : public Device
|
||||||
|
@ -77,6 +74,11 @@ class M6532 : public Device
|
||||||
*/
|
*/
|
||||||
void systemCyclesReset();
|
void systemCyclesReset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update the entire digital and analog pin state of ports A and B.
|
||||||
|
*/
|
||||||
|
void update();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Install 6532 in the specified system. Invoked by the system
|
Install 6532 in the specified system. Invoked by the system
|
||||||
when the 6532 is attached to it.
|
when the 6532 is attached to it.
|
||||||
|
@ -189,6 +191,10 @@ class M6532 : public Device
|
||||||
// If it isn't valid, it will be updated as required
|
// If it isn't valid, it will be updated as required
|
||||||
bool myTimerFlagValid;
|
bool myTimerFlagValid;
|
||||||
|
|
||||||
|
// Used to determine whether an active transition on PA7 has occurred
|
||||||
|
// True is positive edge-detect, false is negative edge-detect
|
||||||
|
bool myEdgeDetectPositive;
|
||||||
|
|
||||||
// Last value written to the timer registers
|
// Last value written to the timer registers
|
||||||
uInt8 myOutTimer[4];
|
uInt8 myOutTimer[4];
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#include "StateManager.hxx"
|
#include "StateManager.hxx"
|
||||||
|
|
||||||
#define STATE_HEADER "03070102state"
|
#define STATE_HEADER "03070103state"
|
||||||
#define MOVIE_HEADER "03030000movie"
|
#define MOVIE_HEADER "03030000movie"
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
Loading…
Reference in New Issue