1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-16 18:30:32 +00:00

With a slight tweak to the informal protocol used for 6502 memory access cycles, ensured the wait strobe actually halts the CPU, to give a more accurate linking of machine time to real time.

This commit is contained in:
Thomas Harte 2015-07-26 15:55:19 -04:00
parent 8efd449834
commit cd0a62d21e
6 changed files with 22 additions and 12 deletions

View File

@ -108,9 +108,10 @@ void Machine::output_state(OutputState state, uint8_t *pixel)
} }
} }
void Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) int Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value)
{ {
uint8_t returnValue = 0xff; uint8_t returnValue = 0xff;
int cycle_count = 1;
output_pixels(3); output_pixels(3);
@ -141,9 +142,8 @@ void Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t ad
case 1: _vBlankEnabled = !!(*value & 0x02); break; case 1: _vBlankEnabled = !!(*value & 0x02); break;
case 2: { case 2: {
const int cyclesToRunFor = _horizontalTimer; cycle_count = _horizontalTimer / 3;
_piaTimerValue -= cyclesToRunFor; output_pixels(3 * cycle_count);
output_pixels(cyclesToRunFor);
} break; } break;
case 3: _horizontalTimer = 227; break; case 3: _horizontalTimer = 227; break;
@ -177,7 +177,9 @@ void Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t ad
*value = returnValue; *value = returnValue;
} }
_piaTimerValue--; _piaTimerValue -= cycle_count;
return cycle_count;
} }
void Machine::set_rom(size_t length, const uint8_t *data) void Machine::set_rom(size_t length, const uint8_t *data)

View File

@ -21,7 +21,7 @@ class Machine: public CPU6502::Processor<Machine> {
Machine(); Machine();
void perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value);
void set_rom(size_t length, const uint8_t *data); void set_rom(size_t length, const uint8_t *data);

View File

@ -40,7 +40,7 @@
// get the shader ready, set the clear colour // get the shader ready, set the clear colour
[self.openGLContext makeCurrentContext]; [self.openGLContext makeCurrentContext];
glClearColor(1.0, 0.0, 0.0, 1.0); glClearColor(0.0, 0.0, 0.0, 1.0);
[self prepareShader]; [self prepareShader];
// Activate the display link // Activate the display link
@ -100,6 +100,9 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
{ {
_crtFrame = crtFrame; _crtFrame = crtFrame;
[self setNeedsDisplay:YES]; [self setNeedsDisplay:YES];
[self.openGLContext makeCurrentContext];
glBufferData(GL_ARRAY_BUFFER, _crtFrame->number_of_runs * sizeof(GLushort) * 8, _crtFrame->runs, GL_DYNAMIC_DRAW);
} }
#pragma mark - Frame output #pragma mark - Frame output

View File

@ -368,6 +368,7 @@ template <class T> class Processor {
bool _is_jammed; bool _is_jammed;
JamHandler *_jam_handler; JamHandler *_jam_handler;
int _cycles_left_to_run;
public: public:
Processor() Processor()
@ -376,6 +377,7 @@ template <class T> class Processor {
_scheduledPrograms[0] = _scheduledPrograms[1] = _scheduledPrograms[2] = _scheduledPrograms[3] = nullptr; _scheduledPrograms[0] = _scheduledPrograms[1] = _scheduledPrograms[2] = _scheduledPrograms[3] = nullptr;
_is_jammed = false; _is_jammed = false;
_jam_handler = nullptr; _jam_handler = nullptr;
_cycles_left_to_run = 0;
} }
void run_for_cycles(int number_of_cycles) void run_for_cycles(int number_of_cycles)
@ -402,8 +404,9 @@ template <class T> class Processor {
} }
checkSchedule(); checkSchedule();
_cycles_left_to_run += number_of_cycles;
while(number_of_cycles) { while(_cycles_left_to_run > 0) {
const MicroOp cycle = _scheduledPrograms[_scheduleProgramsReadPointer][_scheduleProgramProgramCounter]; const MicroOp cycle = _scheduledPrograms[_scheduleProgramsReadPointer][_scheduleProgramProgramCounter];
_scheduleProgramProgramCounter++; _scheduleProgramProgramCounter++;
@ -835,8 +838,8 @@ template <class T> class Processor {
} }
if (_nextBusOperation != BusOperation::None) { if (_nextBusOperation != BusOperation::None) {
static_cast<T *>(this)->perform_bus_operation(_nextBusOperation, _busAddress, _busValue); _cycles_left_to_run -= static_cast<T *>(this)->perform_bus_operation(_nextBusOperation, _busAddress, _busValue);
number_of_cycles--; _nextBusOperation = BusOperation::None; _nextBusOperation = BusOperation::None;
} }
} }
} }

View File

@ -17,13 +17,15 @@ AllRAMProcessor::AllRAMProcessor()
reset(); reset();
} }
void AllRAMProcessor::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value) int AllRAMProcessor::perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value)
{ {
if(isReadOperation(operation)) { if(isReadOperation(operation)) {
*value = _memory[address]; *value = _memory[address];
} else { } else {
_memory[address] = *value; _memory[address] = *value;
} }
return 1;
} }
void AllRAMProcessor::set_data_at_address(uint16_t startAddress, size_t length, const uint8_t *data) void AllRAMProcessor::set_data_at_address(uint16_t startAddress, size_t length, const uint8_t *data)

View File

@ -19,7 +19,7 @@ class AllRAMProcessor: public Processor<AllRAMProcessor> {
AllRAMProcessor(); AllRAMProcessor();
void perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value); int perform_bus_operation(CPU6502::BusOperation operation, uint16_t address, uint8_t *value);
void set_data_at_address(uint16_t startAddress, size_t length, const uint8_t *data); void set_data_at_address(uint16_t startAddress, size_t length, const uint8_t *data);