1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-22 11:29:20 +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 { namespace Commodore::Plus4 {
struct BusController {
virtual void set_irq_line(bool) = 0;
virtual void set_ready_line(bool) = 0;
};
struct Interrupts { struct Interrupts {
public: public:
struct Delegate { Interrupts(BusController &delegate) : delegate_(delegate) {}
virtual void set_irq_line(bool) = 0; BusController &bus() {
}; return delegate_;
}
Interrupts(Delegate &delegate) : delegate_(delegate) {}
enum Flag { enum Flag {
Timer3 = 0x40, Timer3 = 0x40,
@ -59,7 +64,7 @@ private:
} }
} }
Delegate &delegate_; BusController &delegate_;
uint8_t status_; uint8_t status_;
uint8_t mask_; uint8_t mask_;
bool last_set_ = false; bool last_set_ = false;

View File

@ -99,8 +99,8 @@ private:
}; };
class ConcreteMachine: class ConcreteMachine:
public BusController,
public CPU::MOS6502::BusHandler, public CPU::MOS6502::BusHandler,
public Interrupts::Delegate,
public MachineTypes::MappedKeyboardMachine, public MachineTypes::MappedKeyboardMachine,
public MachineTypes::TimedMachine, public MachineTypes::TimedMachine,
public MachineTypes::ScanProducer, public MachineTypes::ScanProducer,
@ -148,16 +148,26 @@ public:
const auto length = video_.cycle_length(operation == CPU::MOS6502::BusOperation::Ready); const auto length = video_.cycle_length(operation == CPU::MOS6502::BusOperation::Ready);
// Update other subsystems. // 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; 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>()); timers_.tick(timers_cycles.as<int>());
video_.run_for(length); video_.run_for(length);
// Perform actual access. // 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)) { if(isReadOperation(operation)) {
*value = map_.read(address); *value = map_.read(address);
} else { } else {
@ -277,6 +287,9 @@ private:
void set_irq_line(bool active) override { void set_irq_line(bool active) override {
m6502_.set_irq_line(active); m6502_.set_irq_line(active);
} }
void set_ready_line(bool active) override {
m6502_.set_ready_line(active);
}
void page_rom() { void page_rom() {
// TODO: allow other ROM selection. And no 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. // Outer clock is [NTSC or PAL] colour subcarrier * 2.
// //
// 65 cycles = 64µs? // 65 cycles = 64µs?
@ -400,6 +404,12 @@ private:
50, 96, 32, 9, 50, 96, 32, 9,
5, 41, 5, 41,
}; };
enum class FetchPhase {
Waiting,
FetchingCharacters,
FetchingAttributs,
} fetch_phase_ = FetchPhase::Waiting;
}; };
} }