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)
|
||||
|
||||
* 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.
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(...)
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
|
||||
#include "StateManager.hxx"
|
||||
|
||||
#define STATE_HEADER "03070102state"
|
||||
#define STATE_HEADER "03070103state"
|
||||
#define MOVIE_HEADER "03030000movie"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
Loading…
Reference in New Issue