From aebf636528d2ec05fb2f93727a31acb2dc8075fc Mon Sep 17 00:00:00 2001 From: Thomas Harte Date: Mon, 10 Aug 2015 16:55:16 +0100 Subject: [PATCH] Ensured the PIA timer resumes its normal tick rate after being read; fixed those spaces that had crept in where tabs should be. --- Machines/Atari2600.cpp | 56 +++++++++++++++++++++++++----------------- Machines/Atari2600.hpp | 4 +-- Outputs/CRT.cpp | 12 ++++----- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/Machines/Atari2600.cpp b/Machines/Atari2600.cpp index 9dcd509f3..24e95a5eb 100644 --- a/Machines/Atari2600.cpp +++ b/Machines/Atari2600.cpp @@ -145,10 +145,10 @@ void Machine::output_pixels(int count) // update hmove if (!(_horizontalTimer&3) && _hMoveFlags) { - for(int c = 0; c < 5; c++) { - if ((_hMoveCounter^8^(_objectMotion[c] >> 4)) == 0xf) _hMoveFlags &= ~(1 << c); - if (_hMoveFlags&(1 << c)) _objectCounter[c] = (_objectCounter[c]+1)%160; - } + for(int c = 0; c < 5; c++) { + if ((_hMoveCounter^8^(_objectMotion[c] >> 4)) == 0xf) _hMoveFlags &= ~(1 << c); + if (_hMoveFlags&(1 << c)) _objectCounter[c] = (_objectCounter[c]+1)%160; + } _hMoveCounter = (_hMoveCounter-1)&0xf; } @@ -206,8 +206,8 @@ void Machine::output_pixels(int count) get_output_pixel(&_outputBuffer[_lastOutputStateDuration * 4], 159 - _horizontalTimer); // increment all graphics counters - for(int c = 0; c < 5; c++) - _objectCounter[c] = (_objectCounter[c]+1)%160; + for(int c = 0; c < 5; c++) + _objectCounter[c] = (_objectCounter[c]+1)%160; } // assumption here: signed shifts right; otherwise it's just @@ -266,7 +266,7 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add case 0x07: returnValue &= 0x3f; break; // player / player, missile / missile collisions } } else { - const uint16_t decodedAddress = address & 0x3f; + const uint16_t decodedAddress = address & 0x3f; switch(decodedAddress) { case 0x00: _vSyncEnabled = !!(*value & 0x02); break; case 0x01: _vBlankEnabled = !!(*value & 0x02); break; @@ -328,10 +328,10 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add case 0x28: case 0x29: - if (!(*value&0x02) && _missileGraphicsReset[decodedAddress - 0x28]&0x02) - _objectCounter[decodedAddress - 0x26] = _objectCounter[decodedAddress - 0x28]; // TODO: +3 for normal, +6 for double, +10 for quad - _missileGraphicsReset[decodedAddress - 0x28] = *value; - break; + if (!(*value&0x02) && _missileGraphicsReset[decodedAddress - 0x28]&0x02) + _objectCounter[decodedAddress - 0x26] = _objectCounter[decodedAddress - 0x28]; // TODO: +3 for normal, +6 for double, +10 for quad + _missileGraphicsReset[decodedAddress - 0x28] = *value; + break; case 0x2a: _vBlankExtend = true; @@ -339,12 +339,12 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add _hMoveFlags = 0x1f; break; case 0x2b: - _objectMotion[0] = - _objectMotion[1] = - _objectMotion[2] = - _objectMotion[3] = - _objectMotion[4] = 0; - break; + _objectMotion[0] = + _objectMotion[1] = + _objectMotion[2] = + _objectMotion[3] = + _objectMotion[4] = 0; + break; } } // printf("Uncaught TIA %04x\n", address); @@ -354,15 +354,25 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add if ((address&0x1280) == 0x280) { if(isReadOperation(operation)) { switch(address & 0xf) { - case 0x04: returnValue &= _piaTimerValue >> _piaTimerShift; break; - case 0x05: returnValue &= _piaTimerStatus; _piaTimerStatus &= ~0x40; break; + case 0x04: + returnValue &= _piaTimerValue >> _piaTimerShift; + + if(_writtenPiaTimerShift != _piaTimerShift) { + _piaTimerShift = _writtenPiaTimerShift; + _piaTimerValue <<= _writtenPiaTimerShift; + } + break; + case 0x05: + returnValue &= _piaTimerStatus; + _piaTimerStatus &= ~0x40; + break; } } else { switch(address & 0x0f) { - case 0x04: _piaTimerShift = 0; _piaTimerValue = *value << 0; _piaTimerStatus &= ~0xc0; break; - case 0x05: _piaTimerShift = 3; _piaTimerValue = *value << 3; _piaTimerStatus &= ~0xc0; break; - case 0x06: _piaTimerShift = 6; _piaTimerValue = *value << 6; _piaTimerStatus &= ~0xc0; break; - case 0x07: _piaTimerShift = 10; _piaTimerValue = *value << 10; _piaTimerStatus &= ~0xc0; break; + case 0x04: _writtenPiaTimerShift = _piaTimerShift = 0; _piaTimerValue = *value << 0; _piaTimerStatus &= ~0xc0; break; + case 0x05: _writtenPiaTimerShift = _piaTimerShift = 3; _piaTimerValue = *value << 3; _piaTimerStatus &= ~0xc0; break; + case 0x06: _writtenPiaTimerShift = _piaTimerShift = 6; _piaTimerValue = *value << 6; _piaTimerStatus &= ~0xc0; break; + case 0x07: _writtenPiaTimerShift = _piaTimerShift = 10; _piaTimerValue = *value << 10; _piaTimerStatus &= ~0xc0; break; } } // printf("Uncaught PIA %04x\n", address); diff --git a/Machines/Atari2600.hpp b/Machines/Atari2600.hpp index 7f5c3a86e..9520b5143 100644 --- a/Machines/Atari2600.hpp +++ b/Machines/Atari2600.hpp @@ -37,7 +37,7 @@ class Machine: public CPU6502::Processor { // the timer unsigned int _piaTimerValue; - unsigned int _piaTimerShift; + unsigned int _piaTimerShift, _writtenPiaTimerShift; uint8_t _piaTimerStatus; // playfield registers @@ -67,7 +67,7 @@ class Machine: public CPU6502::Processor { bool _vSyncEnabled, _vBlankEnabled; bool _vBlankExtend; uint8_t _hMoveCounter, _hMoveFlags; - uint8_t _objectCounter[5], _objectMotion[5]; + uint8_t _objectCounter[5], _objectMotion[5]; enum OutputState { Sync, diff --git a/Outputs/CRT.cpp b/Outputs/CRT.cpp index 28c8eb203..00276015d 100644 --- a/Outputs/CRT.cpp +++ b/Outputs/CRT.cpp @@ -101,14 +101,14 @@ CRT::SyncEvent CRT::get_next_vertical_sync_event(bool vsync_is_requested, int cy SyncEvent proposedEvent = SyncEvent::None; int proposedSyncTime = cycles_to_run_for; - // will an acceptable vertical sync be triggered? - if (vsync_is_requested && !_is_in_vsync) { + // will an acceptable vertical sync be triggered? + if (vsync_is_requested && !_is_in_vsync) { if (_sync_capacitor_charge_level >= _sync_capacitor_charge_threshold) {// && _rasterPosition.y >= (kCRTFixedPointRange * 7) >> 3) { proposedSyncTime = 0; proposedEvent = SyncEvent::StartVSync; _did_detect_vsync = true; } - } + } // have we overrun the maximum permitted number of horizontal syncs for this frame? if (!_is_in_vsync) { @@ -346,21 +346,21 @@ void CRT::output_sync(int number_of_cycles) void CRT::output_blank(int number_of_cycles) { - bool _vsync_requested = _is_receiving_sync; + bool _vsync_requested = _is_receiving_sync; _is_receiving_sync = false; advance_cycles(number_of_cycles, false, _vsync_requested, false, Type::Blank, nullptr); } void CRT::output_level(int number_of_cycles, const char *type) { - bool _vsync_requested = _is_receiving_sync; + bool _vsync_requested = _is_receiving_sync; _is_receiving_sync = false; advance_cycles(number_of_cycles, false, _vsync_requested, false, Type::Level, type); } void CRT::output_data(int number_of_cycles, const char *type) { - bool _vsync_requested = _is_receiving_sync; + bool _vsync_requested = _is_receiving_sync; _is_receiving_sync = false; advance_cycles(number_of_cycles, false, _vsync_requested, false, Type::Data, type); }