mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-26 09:29:45 +00:00
Corrected CRTC timing, gave it someone to talk to and a means with which to talk.
This commit is contained in:
parent
68ceeab610
commit
e28829bd1b
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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_;
|
||||
|
Loading…
Reference in New Issue
Block a user