diff --git a/Machines/Atari2600.cpp b/Machines/Atari2600.cpp index 93a815035..873946ae7 100644 --- a/Machines/Atari2600.cpp +++ b/Machines/Atari2600.cpp @@ -218,8 +218,8 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add case 0x01: _vBlankEnabled = !!(*value & 0x02); break; case 0x02: { - cycle_count += ((_horizontalTimer+4) / 3); - output_pixels(_horizontalTimer+4); + cycle_count += ((_horizontalTimer+1) / 3); + output_pixels(_horizontalTimer+1); } break; case 0x03: _horizontalTimer = 227; break; @@ -244,8 +244,15 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add case 0x13: _missilePosition[1] = _horizontalTimer; break; case 0x14: _ballPosition = _horizontalTimer; break; - case 0x1b: _playerGraphics[0] = *value; break; - case 0x1c: _playerGraphics[1] = *value; break; + case 0x1b: + case 0x1c: { + int index = (address & 0x3f) - 0x1b; + _playerGraphicsLatch[index] = *value; + if(!(_playerGraphicsLatchEnable[index]&1)) + _playerGraphics[index] = _playerGraphicsLatch[index]; + if(_playerGraphicsLatchEnable[index^1]&1) + _playerGraphics[index^1] = _playerGraphicsLatch[index^1]; + } break; case 0x1d: _missileGraphicsEnable[0] = *value; break; case 0x1e: _missileGraphicsEnable[1] = *value; break; case 0x1f: _ballGraphicsEnable = *value; break; @@ -256,6 +263,10 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add case 0x23: _missileMotion[1] = *value; break; case 0x24: _ballMotion = *value; break; + case 0x25: _playerGraphicsLatchEnable[0] = *value; break; + case 0x26: _playerGraphicsLatchEnable[1] = *value; break; + case 0x27: _ballGraphicsEnableDelay = *value; break; + case 0x2a: _playerPosition[0] += (int8_t)_playerMotion[0] >> 4; _playerPosition[1] += (int8_t)_playerMotion[1] >> 4; diff --git a/Machines/Atari2600.hpp b/Machines/Atari2600.hpp index 8bd92e717..d6e162d83 100644 --- a/Machines/Atari2600.hpp +++ b/Machines/Atari2600.hpp @@ -39,18 +39,32 @@ class Machine: public CPU6502::Processor { unsigned int _piaTimerShift; uint8_t _piaTimerStatus; - // graphics registers + // playfield registers uint8_t _playfield[3], _playfieldControl; - uint8_t _playerColour[2]; uint8_t _playfieldColour; uint8_t _backgroundColour; - uint8_t _playerAndMissileSize[2]; + + // player registers + uint8_t _playerColour[2]; uint8_t _playerReflection[2]; - uint8_t _playerGraphics[2]; + uint8_t _playerGraphicsLatch[2], _playerGraphics[2]; + uint8_t _playerPosition[2]; + uint8_t _playerMotion[2]; + uint8_t _playerGraphicsLatchEnable[2]; + + // player + missile registers + uint8_t _playerAndMissileSize[2]; + + // missile registers uint8_t _missileGraphicsEnable[2]; + uint8_t _missilePosition[2]; + uint8_t _missileMotion[2]; + + // ball registers uint8_t _ballGraphicsEnable; - uint8_t _playerPosition[2], _missilePosition[2], _ballPosition; - uint8_t _playerMotion[2], _missileMotion[2], _ballMotion; + uint8_t _ballPosition; + uint8_t _ballMotion; + uint8_t _ballGraphicsEnableDelay; // graphics output int32_t _horizontalTimer;