1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-01 14:29:51 +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 <cstdint>
#include <cstdio>
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:
CRTC6845(T &bus_handler) : bus_handler_(bus_handler) {}
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) {
@ -34,13 +53,18 @@ class CRTC6845 {
void set_register(uint8_t value) {
registers_[selected_register_] = value;
if(!selected_register_) printf("Horizontal total: %d\n", value);
}
private:
T &bus_handler_;
BusState bus_state_;
uint8_t registers_[16];
int selected_register_;
};
}
}
#endif /* CRTC6845_hpp */

View File

@ -10,7 +10,9 @@
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
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);
set_wait_line(clock_offset_ >= HalfCycles(2));
// Update the CRTC on the final two cycles of the clock period;
// this gives properly serialised memory accesses without having
// to emulate a buffer.
crtc_offset_ += cycle.length;
while(crtc_offset_ >= HalfCycles(8)) {
crtc_.run_for(Cycles(2));
crtc_offset_ -= HalfCycles(8);
}
// Update the CRTC once every eight half cycles; aiming for half-cycle 4 as
// per the initial seed to the crtc_counter_, but any time in the final four
// will do as it's safe to conclude that nobody else has touched video RAM
// during that whole window
crtc_counter_ += cycle.length;
int crtc_cycles = crtc_counter_.divide(HalfCycles(8)).as_int();
if(crtc_cycles) crtc_.run_for(Cycles(1));
// Stop now if no action is strictly required.
if(!cycle.is_terminal()) return HalfCycles(0);

View File

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