1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-29 12:50:28 +00:00

Made an attempt to switch to a hardware-accurate object timer model. Without yet perfect success.

This commit is contained in:
Thomas Harte 2015-08-10 00:20:18 +01:00
parent cd67e31e64
commit a4e52cc4db
2 changed files with 37 additions and 10 deletions

View File

@ -113,7 +113,7 @@ void Machine::get_output_pixel(uint8_t *pixel, int offset)
// get the ball proposed colour // get the ball proposed colour
uint8_t ballPixel; uint8_t ballPixel;
int ballIndex = _ballCounter - 4; int ballIndex = _ballCounter;
int ballSize = 1 << ((_playfieldControl >> 4)&3); int ballSize = 1 << ((_playfieldControl >> 4)&3);
ballPixel = (ballIndex >= 0 && ballIndex < ballSize && (_ballGraphicsEnable&2)) ? 1 : 0; ballPixel = (ballIndex >= 0 && ballIndex < ballSize && (_ballGraphicsEnable&2)) ? 1 : 0;
@ -143,6 +143,31 @@ void Machine::output_pixels(int count)
{ {
OutputState state; OutputState state;
// update hmove
if (_hMoveFlags) {
if (_hMoveFlags&1) _playerCounter[0] = (_playerCounter[0]+1)%160;
if (_hMoveFlags&2) _playerCounter[1] = (_playerCounter[1]+1)%160;
if (_hMoveFlags&4) _missileCounter[0] = (_missileCounter[0]+1)%160;
if (_hMoveFlags&8) _missileCounter[1] = (_missileCounter[1]+1)%160;
if (_hMoveFlags&16) _ballCounter = (_ballCounter+1)%160;
if ((_hMoveCounter^8^(_playerMotion[0] >> 4)) == 0xf) _hMoveFlags &= ~1;
if ((_hMoveCounter^8^(_playerMotion[1] >> 4)) == 0xf) _hMoveFlags &= ~2;
if ((_hMoveCounter^8^(_missileMotion[0] >> 4)) == 0xf) _hMoveFlags &= ~4;
if ((_hMoveCounter^8^(_missileMotion[1] >> 4)) == 0xf) _hMoveFlags &= ~8;
if ((_hMoveCounter^8^(_ballMotion >> 4)) == 0xf) _hMoveFlags &= ~16;
_hMoveCounter ++;
// _playerCounter[0] = (_playerCounter[0] + 160 - 8^(_playerMotion[0] >> 4))%160;
// _playerCounter[1] = (_playerCounter[1] + 160 - 8^(_playerMotion[1] >> 4))%160;
// _missileCounter[0] = (_missileCounter[0] + 160 - 8^(_missileMotion[0] >> 4))%160;
// _missileCounter[1] = (_missileCounter[1] + 160 - 8^(_missileMotion[1] >> 4))%160;
// _ballCounter = (_ballCounter + 160 + 8^(_ballMotion >> 4))%160;
} /*else {
_hMoveCounter --;
}*/
// logic: if in vsync, output that; otherwise if in vblank then output that; // logic: if in vsync, output that; otherwise if in vblank then output that;
// otherwise output a pixel // otherwise output a pixel
if(_vSyncEnabled) { if(_vSyncEnabled) {
@ -160,7 +185,7 @@ void Machine::output_pixels(int count)
// guesses, until I can find information: 26 cycles blank, 16 sync, 40 blank, 160 pixels // guesses, until I can find information: 26 cycles blank, 16 sync, 40 blank, 160 pixels
if(_horizontalTimer >= start_of_sync) state = OutputState::Blank; if(_horizontalTimer >= start_of_sync) state = OutputState::Blank;
else if (_horizontalTimer >= end_of_sync) state = OutputState::Sync; else if (_horizontalTimer >= end_of_sync) state = OutputState::Sync;
else if (_horizontalTimer >= 160) state = OutputState::Blank; else if (_horizontalTimer >= (_vBlankExtend ? 152 : 160)) state = OutputState::Blank;
else { else {
if(_vBlankEnabled) { if(_vBlankEnabled) {
state = OutputState::Blank; state = OutputState::Blank;
@ -184,16 +209,18 @@ void Machine::output_pixels(int count)
if(state == OutputState::Pixel) if(state == OutputState::Pixel)
{ {
_vBlankExtend = false;
_crt->allocate_write_area(160); _crt->allocate_write_area(160);
_outputBuffer = _crt->get_write_target_for_buffer(0); _outputBuffer = _crt->get_write_target_for_buffer(0);
} }
} }
if(state == OutputState::Pixel && _outputBuffer) if(state == OutputState::Pixel)
{ {
get_output_pixel(&_outputBuffer[_lastOutputStateDuration * 4], 159 - _horizontalTimer); if(_outputBuffer)
get_output_pixel(&_outputBuffer[_lastOutputStateDuration * 4], 159 - _horizontalTimer);
// incrmeent all graphics counters // increment all graphics counters
_playerCounter[0] = (_playerCounter[0]+1)%160; _playerCounter[0] = (_playerCounter[0]+1)%160;
_playerCounter[1] = (_playerCounter[1]+1)%160; _playerCounter[1] = (_playerCounter[1]+1)%160;
_missileCounter[0] = (_missileCounter[0]+1)%160; _missileCounter[0] = (_missileCounter[0]+1)%160;
@ -319,11 +346,9 @@ int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t add
// case 0x28: _missilePosition[0] = _playerPosition[0]; break; // case 0x28: _missilePosition[0] = _playerPosition[0]; break;
case 0x2a: case 0x2a:
_playerCounter[0] = (_playerCounter[0] + 160 + ((int8_t)_playerMotion[0] >> 4))%160; _vBlankExtend = true;
_playerCounter[1] = (_playerCounter[1] + 160 + ((int8_t)_playerMotion[1] >> 4))%160; _hMoveCounter = 0;
_missileCounter[0] = (_missileCounter[0] + 160 + ((int8_t)_missileMotion[0] >> 4))%160; _hMoveFlags = 0x1f;
_missileCounter[1] = (_missileCounter[1] + 160 + ((int8_t)_missileMotion[1] >> 4))%160;
_ballCounter = (_ballCounter + 160 + ((int8_t)_ballMotion >> 4))%160;
break; break;
case 0x2b: _playerMotion[0] = _playerMotion[1] = _missileMotion[0] = _missileMotion[1] = _ballMotion = 0; break; case 0x2b: _playerMotion[0] = _playerMotion[1] = _missileMotion[0] = _missileMotion[1] = _ballMotion = 0; break;
} }

View File

@ -71,6 +71,8 @@ class Machine: public CPU6502::Processor<Machine> {
// graphics output // graphics output
int32_t _horizontalTimer; int32_t _horizontalTimer;
bool _vSyncEnabled, _vBlankEnabled; bool _vSyncEnabled, _vBlankEnabled;
bool _vBlankExtend;
uint8_t _hMoveCounter, _hMoveFlags;
enum OutputState { enum OutputState {
Sync, Sync,