mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-27 01:31:42 +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 "../../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 */
|
||||||
|
@ -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);
|
||||||
|
@ -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_;
|
||||||
|
Loading…
Reference in New Issue
Block a user