1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +00:00

Adds emulation of the real-time clock.

This commit is contained in:
Thomas Harte 2019-05-08 00:12:19 -04:00
parent ce099a297a
commit 7e6d4f5a3e
3 changed files with 46 additions and 8 deletions

View File

@ -71,14 +71,14 @@ template <typename T> void MOS6522<T>::set_register(int address, uint8_t value)
// TODO: simplify below; trying to avoid improper logging of unimplemented warnings in input mode
if(value & 0x08) {
switch(value & 0x0e) {
default: LOG("Unimplemented control line mode " << int((value >> 1)&7)); break;
default: LOG("Unimplemented control CA2 line mode " << int((value >> 1)&7)); break;
case 0x0c: bus_handler_.set_control_line_output(Port::A, Line::Two, false); break;
case 0x0e: bus_handler_.set_control_line_output(Port::A, Line::Two, true); break;
}
}
if(value & 0x80) {
switch(value & 0xe0) {
default: LOG("Unimplemented control line mode " << int((value >> 5)&7)); break;
default: LOG("Unimplemented control CB2 line mode " << int((value >> 5)&7)); break;
case 0xc0: bus_handler_.set_control_line_output(Port::B, Line::Two, false); break;
case 0xe0: bus_handler_.set_control_line_output(Port::B, Line::Two, true); break;
}

View File

@ -11,6 +11,7 @@
#include <array>
#include "Video.hpp"
#include "RealTimeClock.hpp"
#include "../../CRTMachine.hpp"
@ -20,6 +21,12 @@
#include "../../Utility/MemoryPacker.hpp"
namespace {
const int CLOCK_RATE = 7833600;
}
namespace Apple {
namespace Macintosh {
@ -32,8 +39,8 @@ class ConcreteMachine:
mc68000_(*this),
video_(ram_.data()),
via_(via_port_handler_),
via_port_handler_(*this),
iwm_(7833600) {
via_port_handler_(*this, clock_),
iwm_(CLOCK_RATE) {
// Grab a copy of the ROM and convert it into big-endian data.
const auto roms = rom_fetcher("Macintosh", { "mac128k.rom" });
@ -44,7 +51,7 @@ class ConcreteMachine:
Memory::PackBigEndian16(*roms[0], rom_.data());
// The Mac runs at 7.8336mHz.
set_clock_rate(7833600.0);
set_clock_rate(double(CLOCK_RATE));
}
void set_scan_target(Outputs::Display::ScanTarget *scan_target) override {
@ -72,6 +79,19 @@ class ConcreteMachine:
// TODO: SCC is a divide-by-two.
// Consider updating the real-time clock.
real_time_clock_ += cycle.length;
auto ticks = real_time_clock_.divide_cycles(Cycles(CLOCK_RATE)).as_int();
while(ticks--) {
clock_.update();
// TODO: leave a delay between toggling the input rather than using this coupled hack.
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, true);
via_.set_control_line_input(MOS::MOS6522::Port::A, MOS::MOS6522::Line::Two, false);
}
// Update interrupt input. TODO: move this into a VIA/etc delegate callback?
mc68000_.set_interrupt_level( (via_.get_interrupt_line() ? 1 : 0) );
// A null cycle leaves nothing else to do.
if(cycle.operation) {
auto word_address = cycle.word_address();
@ -192,9 +212,13 @@ class ConcreteMachine:
}
private:
class Keyboard {
public:
};
class VIAPortHandler: public MOS::MOS6522::PortHandler {
public:
VIAPortHandler(ConcreteMachine &machine) : machine_(machine) {}
VIAPortHandler(ConcreteMachine &machine, RealTimeClock &clock) : machine_(machine), clock_(clock) {}
using Port = MOS::MOS6522::Port;
using Line = MOS::MOS6522::Line;
@ -232,7 +256,8 @@ class ConcreteMachine:
b1: clock's data-clock line
b0: clock's serial data line
*/
// printf("6522 B: %02x\n", value);
if(value & 0x4) clock_.abort();
else clock_.set_input(!!(value & 0x2), !!(value & 0x1));
break;
}
}
@ -245,16 +270,24 @@ class ConcreteMachine:
case Port::B:
// printf("6522 r B\n");
return 0x00;
return (clock_.get_data() ? 0x02 : 0x00);
}
}
void set_control_line_output(Port port, Line line, bool value) {
/*
Keyboard wiring (I believe):
CB2 = data
CB1 = clock
CA2 is used for receiving RTC interrupts.
*/
// printf("6522 line %c%d: %c\n", port ? 'B' : 'A', int(line), value ? 't' : 'f');
}
private:
ConcreteMachine &machine_;
RealTimeClock &clock_;
};
std::array<uint16_t, 32*1024> rom_;
@ -263,6 +296,8 @@ class ConcreteMachine:
CPU::MC68000::Processor<ConcreteMachine, true> mc68000_;
Video video_;
RealTimeClock clock_;
MOS::MOS6522::MOS6522<VIAPortHandler> via_;
VIAPortHandler via_port_handler_;
@ -271,6 +306,7 @@ class ConcreteMachine:
HalfCycles via_clock_;
HalfCycles time_since_video_update_;
HalfCycles time_since_iwm_update_;
HalfCycles real_time_clock_;
bool ROM_is_overlay_ = true;
};

View File

@ -1390,6 +1390,7 @@
4BCF1FA21DADC3DD0039D2E7 /* Oric.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Oric.cpp; path = Oric/Oric.cpp; sourceTree = "<group>"; };
4BCF1FA31DADC3DD0039D2E7 /* Oric.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = Oric.hpp; path = Oric/Oric.hpp; sourceTree = "<group>"; };
4BD060A51FE49D3C006E14BE /* Speaker.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Speaker.hpp; sourceTree = "<group>"; };
4BD0692B22828A2D00D2A54F /* RealTimeClock.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = RealTimeClock.hpp; sourceTree = "<group>"; };
4BD191D9219113B80042E144 /* OpenGL.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = OpenGL.hpp; sourceTree = "<group>"; };
4BD191F22191180E0042E144 /* ScanTarget.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ScanTarget.cpp; sourceTree = "<group>"; };
4BD191F32191180E0042E144 /* ScanTarget.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ScanTarget.hpp; sourceTree = "<group>"; };
@ -3070,6 +3071,7 @@
4BCE0058227CFFCA000CA200 /* Macintosh.cpp */,
4BCE005E227D39AB000CA200 /* Video.cpp */,
4BCE0059227CFFCA000CA200 /* Macintosh.hpp */,
4BD0692B22828A2D00D2A54F /* RealTimeClock.hpp */,
4BCE005F227D39AB000CA200 /* Video.hpp */,
);
path = Macintosh;