1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-09 17:29:36 +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;
int cycle_count = 1;
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 2: {
const int cyclesToRunFor = _horizontalTimer;
_piaTimerValue -= cyclesToRunFor;
output_pixels(cyclesToRunFor);
cycle_count = _horizontalTimer / 3;
output_pixels(3 * cycle_count);
} break;
case 3: _horizontalTimer = 227; break;
@ -177,7 +177,9 @@ void Machine::perform_bus_operation(CPU6502::BusOperation operation, uint16_t ad
*value = returnValue;
}
_piaTimerValue--;
_piaTimerValue -= cycle_count;
return cycle_count;
}
void Machine::set_rom(size_t length, const uint8_t *data)

View File

@ -21,7 +21,7 @@ class Machine: public CPU6502::Processor<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);

View File

@ -40,7 +40,7 @@
// get the shader ready, set the clear colour
[self.openGLContext makeCurrentContext];
glClearColor(1.0, 0.0, 0.0, 1.0);
glClearColor(0.0, 0.0, 0.0, 1.0);
[self prepareShader];
// Activate the display link
@ -100,6 +100,9 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt
{
_crtFrame = crtFrame;
[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

View File

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

View File

@ -17,13 +17,15 @@ AllRAMProcessor::AllRAMProcessor()
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)) {
*value = _memory[address];
} else {
_memory[address] = *value;
}
return 1;
}
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();
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);