Add wsync, vsync and vblank, fix bugs and connect the dots -> main loop + tv mode detection work.

This commit is contained in:
Christian Speckner 2016-11-15 21:16:36 +01:00
parent 70dc29f077
commit 6d76d65d82
5 changed files with 65 additions and 15 deletions

View File

@ -55,7 +55,7 @@ vector<DelayQueueMember::Entry>::const_iterator DelayQueueMember::begin() const
vector<DelayQueueMember::Entry>::const_iterator DelayQueueMember::end() const
{
return myEntries.end();
return (mySize < myEntries.size() - 1) ? (myEntries.begin() + mySize) : myEntries.end();
}
void DelayQueueMember::clear()

View File

@ -44,16 +44,21 @@ FrameManager::FrameManager()
reset();
}
void FrameManager::setOnFrameCompleteHandler(FrameManager::frameCompletionHandler handler)
{
myOnFrameComplete = handler;
void FrameManager::setHandlers(
FrameManager::callback frameStartCallback,
FrameManager::callback frameCompleteCallback
) {
myOnFrameStart = frameStartCallback;
myOnFrameComplete = frameCompleteCallback;
}
void FrameManager::reset()
{
myMode = TvMode::pal;
setTvMode(TvMode::ntsc);
setState(State::waitForVsyncStart);
myState = State::waitForVsyncStart;
myCurrentFrameTotalLines = 0;
myLineInState = 0;
myLinesWithoutVsync = 0;
myWaitForVsync = true;
@ -89,7 +94,7 @@ void FrameManager::nextLine()
break;
case State::frame:
if (myLineInState >= myFrameLines + Metrics::visibleOverscan) {
if (myLineInState >= myKernelLines + Metrics::visibleOverscan) {
finalizeFrame();
}
@ -105,6 +110,8 @@ void FrameManager::nextLine()
default:
throw runtime_error("frame manager: invalid state");
}
if (myWaitForVsync) myLinesWithoutVsync++;
}
void FrameManager::setVblank(bool vblank)
@ -195,8 +202,12 @@ void FrameManager::setTvMode(FrameManager::TvMode mode)
void FrameManager::setState(FrameManager::State state)
{
if (myState == state) return;
myState = state;
myLineInState = 0;
if (myState == State::frame && myOnFrameStart) myOnFrameStart();
}
void FrameManager::finalizeFrame()

View File

@ -33,7 +33,7 @@ class FrameManager {
pal, ntsc
};
typedef std::function<void()> frameCompletionHandler;
typedef std::function<void()> callback;
public:
@ -41,7 +41,7 @@ class FrameManager {
public:
void setOnFrameCompleteHandler(frameCompletionHandler);
void setHandlers(callback frameStartCallback, callback frameCompletionCallback);
void reset();
@ -81,7 +81,8 @@ class FrameManager {
private:
frameCompletionHandler myOnFrameComplete;
callback myOnFrameStart;
callback myOnFrameComplete;
TvMode myMode;
State myState;

View File

@ -29,7 +29,8 @@ TIA::TIA(Console& console, Sound& sound, Settings& settings)
mySettings(settings),
myDelayQueue(10, 20)
{
myFrameManager.setOnFrameCompleteHandler(
myFrameManager.setHandlers(
[this] () {onFrameStart();},
[this] () {onFrameComplete();}
);
@ -62,7 +63,7 @@ void TIA::reset()
void TIA::systemCyclesReset()
{
uInt32 cycles = mySystem->cycles();
const uInt32 cycles = mySystem->cycles();
myLastCycle -= cycles;
mySound.adjustCycleCounter(-cycles);
@ -100,16 +101,32 @@ bool TIA::load(Serializer& in)
return true;
}
// TODO: stub
uInt8 TIA::peek(uInt16 address)
{
updateEmulation();
return 0;
}
// TODO: stub
bool TIA::poke(uInt16 address, uInt8 value)
{
return false;
updateEmulation();
switch (address & 0x3F) {
case WSYNC:
mySystem->incrementCycles((227 - myHctr) / 3);
break;
case VSYNC:
myFrameManager.setVsync(value & 0x02);
break;
case VBLANK:
myFrameManager.setVblank(value & 0x02);
break;
}
return true;
}
// TODO: stub
@ -130,7 +147,9 @@ bool TIA::loadDisplay(Serializer& in)
// TODO: stub
void TIA::update()
{}
{
mySystem->m6502().execute(25000);
}
uInt8* TIA::currentFrameBuffer() const
{
@ -256,6 +275,14 @@ bool TIA::toggleJitter(uInt8 mode)
void TIA::setJitterRecoveryFactor(Int32 f)
{}
void TIA::updateEmulation() {
const uInt32 cycles = mySystem->cycles();
cycle(3 * (cycles - myLastCycle));
myLastCycle = cycles;
}
void TIA::cycle(uInt32 colorClocks)
{
for (uInt32 i = 0; i < colorClocks; i++) {
@ -304,6 +331,8 @@ void TIA::tickHblank()
}
if (++myHblankCtr >= 68) myHstate = HState::frame;
myHctr++;
}
void TIA::tickHframe()
@ -360,6 +389,11 @@ void TIA::onFrameComplete()
mySystem->m6502().stop();
}
void TIA::onFrameStart()
{
myCurrentFrameBuffer.swap(myPreviousFrameBuffer);
}
// TODO: stub
void TIA::delayedWrite(uInt8 address, uInt8 value)
{}

View File

@ -124,6 +124,8 @@ class TIA : public AbstractTIA {
private:
void updateEmulation();
void cycle(uInt32 colorClocks);
void tickMovement();
@ -140,6 +142,8 @@ class TIA : public AbstractTIA {
void onFrameComplete();
void onFrameStart();
void delayedWrite(uInt8 address, uInt8 value);
private: