1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-01-25 09:30:14 +00:00

Start edging towards proper video timing.

This commit is contained in:
Thomas Harte 2024-12-14 22:06:18 -05:00
parent 702b6d6567
commit b76104d145
3 changed files with 38 additions and 10 deletions

View File

@ -12,13 +12,18 @@
namespace Commodore::Plus4 {
struct BusController {
virtual void set_irq_line(bool) = 0;
virtual void set_ready_line(bool) = 0;
};
struct Interrupts {
public:
struct Delegate {
virtual void set_irq_line(bool) = 0;
};
Interrupts(BusController &delegate) : delegate_(delegate) {}
BusController &bus() {
return delegate_;
}
Interrupts(Delegate &delegate) : delegate_(delegate) {}
enum Flag {
Timer3 = 0x40,
@ -59,7 +64,7 @@ private:
}
}
Delegate &delegate_;
BusController &delegate_;
uint8_t status_;
uint8_t mask_;
bool last_set_ = false;

View File

@ -99,8 +99,8 @@ private:
};
class ConcreteMachine:
public BusController,
public CPU::MOS6502::BusHandler,
public Interrupts::Delegate,
public MachineTypes::MappedKeyboardMachine,
public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer,
@ -148,16 +148,26 @@ public:
const auto length = video_.cycle_length(operation == CPU::MOS6502::BusOperation::Ready);
// Update other subsystems.
// TODO: timers decrement at a 894 KHz rate for NTSC television systems, 884 KHZ for PAL systems.
// Probably a function of the speed register?
timers_subcycles_ += length;
const auto timers_cycles = timers_subcycles_.divide(Cycles(5));
const auto timers_cycles = timers_subcycles_.divide(video_.timer_cycle_length());
timers_.tick(timers_cycles.as<int>());
video_.run_for(length);
// Perform actual access.
if(address < 0xfd00 || address >= 0xff40) {
if(address < 0x0002) {
// TODO: 0x0000: data directions for parallel IO; 1 = output.
// TODO: 0x0001:
// b7 = serial data in;
// b6 = serial clock in and cassette write;
// b5 = [unconnected];
// b4 = cassette read;
// b3 = cassette motor, 1 = off;
// b2 = serial ATN out;
// b1 = serial clock out and cassette write;
// b0 = serial data out.
// printf("%04x: %02x %c\n", address, *value, isReadOperation(operation) ? 'r' : 'w');
} else if(address < 0xfd00 || address >= 0xff40) {
if(isReadOperation(operation)) {
*value = map_.read(address);
} else {
@ -277,6 +287,9 @@ private:
void set_irq_line(bool active) override {
m6502_.set_irq_line(active);
}
void set_ready_line(bool active) override {
m6502_.set_ready_line(active);
}
void page_rom() {
// TODO: allow other ROM selection. And no ROM?

View File

@ -127,6 +127,10 @@ public:
}
}
Cycles timer_cycle_length() const {
return is_ntsc_ ? Cycles(16) : Cycles(20);
}
// Outer clock is [NTSC or PAL] colour subcarrier * 2.
//
// 65 cycles = 64µs?
@ -400,6 +404,12 @@ private:
50, 96, 32, 9,
5, 41,
};
enum class FetchPhase {
Waiting,
FetchingCharacters,
FetchingAttributs,
} fetch_phase_ = FetchPhase::Waiting;
};
}