1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-25 04:29:09 +00:00

Rethought, hopefully perfecting, sprite timing.

This commit is contained in:
Thomas Harte 2016-05-30 19:56:36 -04:00
parent 8b342f77a9
commit 3fc80ea01f
2 changed files with 20 additions and 21 deletions

View File

@ -110,10 +110,6 @@ void Machine::update_timers(int mask)
_objectCounterPointer = (_objectCounterPointer + 1)%number_of_recorded_counters; _objectCounterPointer = (_objectCounterPointer + 1)%number_of_recorded_counters;
ObjectCounter *oneClockAgo = _objectCounter[(_objectCounterPointer - 1 + number_of_recorded_counters)%number_of_recorded_counters]; ObjectCounter *oneClockAgo = _objectCounter[(_objectCounterPointer - 1 + number_of_recorded_counters)%number_of_recorded_counters];
ObjectCounter *twoClocksAgo = _objectCounter[(_objectCounterPointer - 2 + number_of_recorded_counters)%number_of_recorded_counters]; ObjectCounter *twoClocksAgo = _objectCounter[(_objectCounterPointer - 2 + number_of_recorded_counters)%number_of_recorded_counters];
// ObjectCounter *threeClocksAgo = _objectCounter[(_objectCounterPointer - 3 + number_of_recorded_counters)%number_of_recorded_counters];
// ObjectCounter *fourClocksAgo = _objectCounter[(_objectCounterPointer - 4 + number_of_recorded_counters)%number_of_recorded_counters];
// ObjectCounter *fiveClocksAgo = _objectCounter[(_objectCounterPointer - 5 + number_of_recorded_counters)%number_of_recorded_counters];
// ObjectCounter *sixClocksAgo = _objectCounter[(_objectCounterPointer - 6 + number_of_recorded_counters)%number_of_recorded_counters];
ObjectCounter *now = _objectCounter[_objectCounterPointer]; ObjectCounter *now = _objectCounter[_objectCounterPointer];
// grab the background now, for application in four clocks // grab the background now, for application in four clocks
@ -325,6 +321,13 @@ void Machine::output_pixels(unsigned int count)
{ {
update_timers(_hMoveFlags); update_timers(_hMoveFlags);
} }
if(_upcomingEvents[_upcomingEventsPointer].updates & Event::Action::ResetCounter)
{
_objectCounter[_objectCounterPointer][_upcomingEvents[_upcomingEventsPointer].counter].count = 0;
}
// zero out current update event, progress to next
_upcomingEvents[_upcomingEventsPointer].updates = 0; _upcomingEvents[_upcomingEventsPointer].updates = 0;
_upcomingEventsPointer = (_upcomingEventsPointer + 1)%number_of_upcoming_events; _upcomingEventsPointer = (_upcomingEventsPointer + 1)%number_of_upcoming_events;
@ -342,13 +345,11 @@ void Machine::output_pixels(unsigned int count)
_nextPlayfieldOutput = _playfield[(_horizontalTimer - 64) >> 2]; _nextPlayfieldOutput = _playfield[(_horizontalTimer - 64) >> 2];
} }
// if vsync is enabled, output the opposite of the automatic hsync output // if vsync is enabled, output the opposite of the automatic hsync output;
// also honour the vertical blank flag
if(_vSyncEnabled) { if(_vSyncEnabled) {
effective_state = (effective_state = OutputState::Sync) ? OutputState::Blank : OutputState::Sync; effective_state = (effective_state = OutputState::Sync) ? OutputState::Blank : OutputState::Sync;
} } else if(_vBlankEnabled && effective_state == OutputState::Pixel) {
// honour the vertical blank flag
if(_vBlankEnabled && effective_state == OutputState::Pixel) {
effective_state = OutputState::Blank; effective_state = OutputState::Blank;
} }
@ -388,7 +389,6 @@ void Machine::output_pixels(unsigned int count)
{ {
_stateByTime = _stateByExtendTime[0]; _stateByTime = _stateByExtendTime[0];
set_ready_line(false); set_ready_line(false);
// printf("\n");
} }
} }
} }
@ -409,7 +409,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
cycles_run_for = distance_to_end_of_ready; cycles_run_for = distance_to_end_of_ready;
} }
output_pixels(2); output_pixels(cycles_run_for);
if(operation != CPU6502::BusOperation::Ready) { if(operation != CPU6502::BusOperation::Ready) {
@ -485,10 +485,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
case 0x01: _vBlankEnabled = !!(*value & 0x02); break; case 0x01: _vBlankEnabled = !!(*value & 0x02); break;
case 0x02: case 0x02:
// printf("%d\n", _horizontalTimer); if(_horizontalTimer) set_ready_line(true);
// printf("W");
// if(_horizontalTimer)
set_ready_line(true);
break; break;
case 0x03: case 0x03:
// Reset is delayed by four cycles. // Reset is delayed by four cycles.
@ -576,7 +573,8 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
case 0x10: case 0x11: case 0x12: case 0x13: case 0x10: case 0x11: case 0x12: case 0x13:
case 0x14: case 0x14:
_objectCounter[_objectCounterPointer][decodedAddress - 0x10].count = 0; _upcomingEvents[(_upcomingEventsPointer + 4)%number_of_upcoming_events].updates |= Event::Action::ResetCounter;
_upcomingEvents[(_upcomingEventsPointer + 4)%number_of_upcoming_events].counter = decodedAddress - 0x10;
break; break;
case 0x1c: case 0x1c:
@ -607,6 +605,7 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
case 0x28: case 0x28:
case 0x29: case 0x29:
{ {
// TODO: this should properly mean setting a flag and propagating later, I think?
int index = decodedAddress - 0x28; int index = decodedAddress - 0x28;
if(!(*value&0x02) && _missileGraphicsReset[index]) if(!(*value&0x02) && _missileGraphicsReset[index])
{ {
@ -705,8 +704,6 @@ unsigned int Machine::perform_bus_operation(CPU6502::BusOperation operation, uin
_piaTimerStatus |= 0xc0; _piaTimerStatus |= 0xc0;
} }
output_pixels(cycles_run_for - 2);
return cycles_run_for / 3; return cycles_run_for / 3;
} }

View File

@ -65,15 +65,17 @@ class Machine: public CPU6502::Processor<Machine> {
struct Event { struct Event {
enum Action { enum Action {
Playfield = 1 << 0, Playfield = 1 << 0,
ResetCounter = 1 << 1,
HMoveSetup = 1 << 1, HMoveSetup = 1 << 2,
HMoveCompare = 1 << 2, HMoveCompare = 1 << 3,
HMoveDecrement = 1 << 3, HMoveDecrement = 1 << 4,
}; };
int updates; int updates;
OutputState state; OutputState state;
uint8_t playfieldPixel; uint8_t playfieldPixel;
int counter;
Event() : updates(0), playfieldPixel(0) {} Event() : updates(0), playfieldPixel(0) {}
} _upcomingEvents[number_of_upcoming_events]; } _upcomingEvents[number_of_upcoming_events];