1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-03 11:30:02 +00:00

Corrected CRTC timing, gave it someone to talk to and a means with which to talk.

This commit is contained in:
Thomas Harte 2017-07-31 20:14:46 -04:00
parent 68ceeab610
commit e28829bd1b
3 changed files with 45 additions and 12 deletions

View File

@ -12,12 +12,31 @@
#include "../../ClockReceiver/ClockReceiver.hpp" #include "../../ClockReceiver/ClockReceiver.hpp"
#include <cstdint> #include <cstdint>
#include <cstdio>
namespace Motorola { namespace Motorola {
namespace CRTC {
class CRTC6845 { struct BusState {
bool display_enable;
bool hsync;
bool vsync;
bool cursor;
uint16_t refresh_address;
uint16_t row_address;
};
template <class T> class CRTC6845 {
public: public:
CRTC6845(T &bus_handler) : bus_handler_(bus_handler) {}
void run_for(Cycles cycles) { void run_for(Cycles cycles) {
int cyles_remaining = cycles.as_int();
while(cyles_remaining--) {
// TODO: update state (!)
bus_handler_.perform_bus_cycle(bus_state_);
}
} }
void select_register(uint8_t r) { void select_register(uint8_t r) {
@ -34,13 +53,18 @@ class CRTC6845 {
void set_register(uint8_t value) { void set_register(uint8_t value) {
registers_[selected_register_] = value; registers_[selected_register_] = value;
if(!selected_register_) printf("Horizontal total: %d\n", value);
} }
private: private:
T &bus_handler_;
BusState bus_state_;
uint8_t registers_[16]; uint8_t registers_[16];
int selected_register_; int selected_register_;
}; };
}
} }
#endif /* CRTC6845_hpp */ #endif /* CRTC6845_hpp */

View File

@ -10,7 +10,9 @@
using namespace AmstradCPC; using namespace AmstradCPC;
Machine::Machine() { Machine::Machine() :
crtc_counter_(HalfCycles(4)), // This starts the CRTC exactly out of phase with the memory accesses
crtc_(crtc_bus_handler_) {
// primary clock is 4Mhz // primary clock is 4Mhz
set_clock_rate(4000000); set_clock_rate(4000000);
} }
@ -20,14 +22,13 @@ HalfCycles Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &c
clock_offset_ = (clock_offset_ + cycle.length) & HalfCycles(7); clock_offset_ = (clock_offset_ + cycle.length) & HalfCycles(7);
set_wait_line(clock_offset_ >= HalfCycles(2)); set_wait_line(clock_offset_ >= HalfCycles(2));
// Update the CRTC on the final two cycles of the clock period; // Update the CRTC once every eight half cycles; aiming for half-cycle 4 as
// this gives properly serialised memory accesses without having // per the initial seed to the crtc_counter_, but any time in the final four
// to emulate a buffer. // will do as it's safe to conclude that nobody else has touched video RAM
crtc_offset_ += cycle.length; // during that whole window
while(crtc_offset_ >= HalfCycles(8)) { crtc_counter_ += cycle.length;
crtc_.run_for(Cycles(2)); int crtc_cycles = crtc_counter_.divide(HalfCycles(8)).as_int();
crtc_offset_ -= HalfCycles(8); if(crtc_cycles) crtc_.run_for(Cycles(1));
}
// Stop now if no action is strictly required. // Stop now if no action is strictly required.
if(!cycle.is_terminal()) return HalfCycles(0); if(!cycle.is_terminal()) return HalfCycles(0);

View File

@ -24,6 +24,11 @@ enum ROMType: uint8_t {
AMSDOS AMSDOS
}; };
struct CRTCBusHandler {
inline void perform_bus_cycle(const Motorola::CRTC::BusState &state) {
}
};
class Machine: class Machine:
public CPU::Z80::Processor<Machine>, public CPU::Z80::Processor<Machine>,
public CRTMachine::Machine, public CRTMachine::Machine,
@ -48,9 +53,12 @@ class Machine:
private: private:
std::shared_ptr<Outputs::CRT::CRT> crt_; std::shared_ptr<Outputs::CRT::CRT> crt_;
Motorola::CRTC6845 crtc_;
CRTCBusHandler crtc_bus_handler_;
Motorola::CRTC::CRTC6845<CRTCBusHandler> crtc_;
HalfCycles clock_offset_; HalfCycles clock_offset_;
HalfCycles crtc_offset_; HalfCycles crtc_counter_;
uint8_t ram_[65536]; uint8_t ram_[65536];
std::vector<uint8_t> os_, basic_; std::vector<uint8_t> os_, basic_;