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:
stephena 2012-09-16 17:32:45 +00:00
parent 06854e7877
commit faa78ad56a
6 changed files with 68 additions and 18 deletions

View File

@ -14,9 +14,16 @@
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
'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'
everywhere. This makes for less typing when running from the
commandline.

View File

@ -65,6 +65,7 @@ class Controller : public Serializable
/**
Riot debug class needs special access to the underlying controller state
*/
friend class M6532;
friend class RiotDebug;
friend class CompuMate;

View File

@ -42,7 +42,7 @@
#include "Snapshot.hxx"
#include "Sound.hxx"
#include "StateManager.hxx"
#include "Switches.hxx"
#include "M6532.hxx"
#include "MouseControl.hxx"
#include "EventHandler.hxx"
@ -955,9 +955,7 @@ void EventHandler::poll(uInt64 time)
// related to emulation
if(myState == S_EMULATE)
{
myOSystem->console().controller(Controller::Left).update();
myOSystem->console().controller(Controller::Right).update();
myOSystem->console().switches().update();
myOSystem->console().riot().update();
#if 0
// Now check if the StateManager should be saving or loading state

View File

@ -64,6 +64,9 @@ void M6532::reset()
// Zero the interrupt flag register and mark D7 as invalid
myInterruptFlag = 0x00;
myTimerFlagValid = false;
// Edge-detect set to negative (high to low)
myEdgeDetectPositive = false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -78,6 +81,29 @@ void M6532::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)
{
@ -181,7 +207,10 @@ uInt8 M6532::peek(uInt16 addr)
myInterruptFlag |= TimerBit;
myTimerFlagValid = true;
}
return myInterruptFlag;
// PA7 Flag is always cleared after accessing TIMINT
uInt8 result = myInterruptFlag;
myInterruptFlag &= ~PA7Bit;
return result;
}
default:
@ -208,10 +237,17 @@ bool M6532::poke(uInt16 addr, uInt8 value)
}
// 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 & 0x10) != 0) // TIMxT (x = 1, 8, 64, 1024)
setTimerRegister(value, addr & 0x03);
// A4 = 1 is write to TIMxT (x = 1, 8, 64, 1024)
// 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
{
@ -303,7 +339,6 @@ bool M6532::save(Serializer& out) const
{
out.putString(name());
// Output the RAM
out.putByteArray(myRAM, 128);
out.putInt(myTimer);
@ -314,8 +349,10 @@ bool M6532::save(Serializer& out) const
out.putByte(myDDRB);
out.putByte(myOutA);
out.putByte(myOutB);
out.putByte(myInterruptFlag);
out.putBool(myTimerFlagValid);
out.putBool(myEdgeDetectPositive);
out.putByteArray(myOutTimer, 4);
}
catch(...)
@ -335,7 +372,6 @@ bool M6532::load(Serializer& in)
if(in.getString() != name())
return false;
// Input the RAM
in.getByteArray(myRAM, 128);
myTimer = in.getInt();
@ -346,8 +382,10 @@ bool M6532::load(Serializer& in)
myDDRB = in.getByte();
myOutA = in.getByte();
myOutB = in.getByte();
myInterruptFlag = in.getByte();
myTimerFlagValid = in.getBool();
myEdgeDetectPositive = in.getBool();
in.getByteArray(myOutTimer, 4);
}
catch(...)

View File

@ -30,16 +30,13 @@ class Settings;
/**
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
emulated here; several aspects of the chip are completely ignored:
console. Note that since the M6507 CPU doesn't contain an interrupt line,
the following functionality relating to the RIOT IRQ line is not emulated:
- Pin 25 (IRQ) is not connected at all, therefore all related
items are ignored (A3 determining IRQ enable/disable, etc).
- A3 to enable/disable interrupt from timer to IRQ
- A1 to enable/disable interrupt from PA7 to IRQ
- D6 of the Interrupt Flag is ignored, including PA7 interrupt flag (A1)
and negative/positive edge-detection (A0)
@author Bradford W. Mott
@author Bradford W. Mott and Stephen Anthony
@version $Id$
*/
class M6532 : public Device
@ -77,6 +74,11 @@ class M6532 : public Device
*/
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
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
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
uInt8 myOutTimer[4];

View File

@ -30,7 +30,7 @@
#include "StateManager.hxx"
#define STATE_HEADER "03070102state"
#define STATE_HEADER "03070103state"
#define MOVIE_HEADER "03030000movie"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -