mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Start sketching out an RP5C01.
This commit is contained in:
parent
3bc38d35c9
commit
48a4355592
100
Components/RP5C01/RP5C01.cpp
Normal file
100
Components/RP5C01/RP5C01.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
//
|
||||||
|
// RP5C01.cpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 14/01/2023.
|
||||||
|
// Copyright © 2023 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "RP5C01.hpp"
|
||||||
|
|
||||||
|
using namespace Ricoh::RP5C01;
|
||||||
|
|
||||||
|
RP5C01::RP5C01(HalfCycles clock_rate) : clock_rate_(clock_rate) {}
|
||||||
|
|
||||||
|
void RP5C01::run_for(HalfCycles cycles) {
|
||||||
|
sub_seconds_ += cycles;
|
||||||
|
|
||||||
|
// Guess: this happens so rarely (i.e. once a second, ordinarily) that
|
||||||
|
// it's not worth worrying about the branch prediction consequences.
|
||||||
|
//
|
||||||
|
// ... and ditto all the conditionals below, which will be very rarely reached.
|
||||||
|
if(sub_seconds_ < clock_rate_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto elapsed_seconds = int(sub_seconds_.as_integral() / clock_rate_.as_integral());
|
||||||
|
sub_seconds_ %= clock_rate_;
|
||||||
|
|
||||||
|
// Update time within day.
|
||||||
|
seconds_ += elapsed_seconds;
|
||||||
|
|
||||||
|
constexpr int day_length = 60 * 60 * 24;
|
||||||
|
if(seconds_ < day_length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const int elapsed_days = seconds_ / day_length;
|
||||||
|
seconds_ %= day_length;
|
||||||
|
|
||||||
|
// Day of the week doesn't aggregate upwards.
|
||||||
|
day_of_the_week_ = (day_of_the_week_ + elapsed_days) % 7;
|
||||||
|
|
||||||
|
// Assumed for now: day and month run from 0.
|
||||||
|
// A leap year count of 0 implies a leap year.
|
||||||
|
// TODO: verify.
|
||||||
|
day_ += elapsed_days;
|
||||||
|
while(true) {
|
||||||
|
int month_length = 1;
|
||||||
|
switch(month_) {
|
||||||
|
case 0: month_length = 31; break;
|
||||||
|
case 1: month_length = 28 + !leap_year_; break;
|
||||||
|
case 2: month_length = 31; break;
|
||||||
|
case 3: month_length = 30; break;
|
||||||
|
case 4: month_length = 31; break;
|
||||||
|
case 5: month_length = 30; break;
|
||||||
|
case 6: month_length = 31; break;
|
||||||
|
case 7: month_length = 31; break;
|
||||||
|
case 8: month_length = 30; break;
|
||||||
|
case 9: month_length = 31; break;
|
||||||
|
case 10: month_length = 30; break;
|
||||||
|
case 11: month_length = 31; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(day_ < month_length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
day_ -= month_length;
|
||||||
|
++month_;
|
||||||
|
|
||||||
|
if(month_ == 12) {
|
||||||
|
month_ = 0;
|
||||||
|
++year_;
|
||||||
|
leap_year_ = (leap_year_ + 1) & 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs a write of @c value to @c address.
|
||||||
|
void RP5C01::write(int address, uint8_t value) {
|
||||||
|
// Registers D–F don't depend on the mode.
|
||||||
|
if(address >= 0xd) {
|
||||||
|
switch(address) {
|
||||||
|
default: break;
|
||||||
|
case 0xd:
|
||||||
|
timer_enabled_ = value & 0x8;
|
||||||
|
alarm_enabled_ = value & 0x4;
|
||||||
|
mode_ = value & 0x3;
|
||||||
|
break;
|
||||||
|
case 0xe:
|
||||||
|
// Test register; unclear what is supposed to happen.
|
||||||
|
break;
|
||||||
|
case 0xf:
|
||||||
|
one_hz_on_ = !(value & 0x8);
|
||||||
|
sixteen_hz_on_ = !(value & 0x4);
|
||||||
|
// TODO: timer reset on bit 1, alarm reset on bit 0
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
62
Components/RP5C01/RP5C01.hpp
Normal file
62
Components/RP5C01/RP5C01.hpp
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// RP5C01.hpp
|
||||||
|
// Clock Signal
|
||||||
|
//
|
||||||
|
// Created by Thomas Harte on 14/01/2023.
|
||||||
|
// Copyright © 2023 Thomas Harte. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef RP5C01_hpp
|
||||||
|
#define RP5C01_hpp
|
||||||
|
|
||||||
|
#include "../../ClockReceiver/ClockReceiver.hpp"
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace Ricoh {
|
||||||
|
namespace RP5C01 {
|
||||||
|
|
||||||
|
class RP5C01 {
|
||||||
|
public:
|
||||||
|
RP5C01(HalfCycles clock_rate);
|
||||||
|
|
||||||
|
/// @returns the result of a read from @c address.
|
||||||
|
uint8_t read(int address);
|
||||||
|
|
||||||
|
/// Performs a write of @c value to @c address.
|
||||||
|
void write(int address, uint8_t value);
|
||||||
|
|
||||||
|
/// Advances time.
|
||||||
|
void run_for(HalfCycles);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::array<uint8_t, 26> ram_;
|
||||||
|
|
||||||
|
HalfCycles sub_seconds_;
|
||||||
|
const HalfCycles clock_rate_;
|
||||||
|
|
||||||
|
// Contains the seconds, minutes and hours fields.
|
||||||
|
int seconds_ = 0;
|
||||||
|
|
||||||
|
// Calendar entries.
|
||||||
|
int day_of_the_week_ = 0;
|
||||||
|
int day_ = 0;
|
||||||
|
int month_ = 0;
|
||||||
|
int year_ = 1988;
|
||||||
|
int leap_year_ = 0;
|
||||||
|
|
||||||
|
// Other flags.
|
||||||
|
bool timer_enabled_ = false;
|
||||||
|
bool alarm_enabled_ = false;
|
||||||
|
int mode_ = 0;
|
||||||
|
bool one_hz_on_ = false;
|
||||||
|
bool sixteen_hz_on_ = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#endif /* RP5C01_hpp */
|
@ -1064,6 +1064,8 @@
|
|||||||
4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */; };
|
4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */; };
|
||||||
4BF0BC68297108D600CCA2B5 /* MemorySlotHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */; };
|
4BF0BC68297108D600CCA2B5 /* MemorySlotHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */; };
|
||||||
4BF0BC69297108D600CCA2B5 /* MemorySlotHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */; };
|
4BF0BC69297108D600CCA2B5 /* MemorySlotHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */; };
|
||||||
|
4BF0BC712973318E00CCA2B5 /* RP5C01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC6F2973318E00CCA2B5 /* RP5C01.cpp */; };
|
||||||
|
4BF0BC722973318E00CCA2B5 /* RP5C01.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF0BC6F2973318E00CCA2B5 /* RP5C01.cpp */; };
|
||||||
4BF437EE209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; };
|
4BF437EE209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; };
|
||||||
4BF437EF209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; };
|
4BF437EF209D0F7E008CBD6B /* SegmentParser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */; };
|
||||||
4BF701A026FFD32300996424 /* AmigaBlitterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BF7019F26FFD32300996424 /* AmigaBlitterTests.mm */; };
|
4BF701A026FFD32300996424 /* AmigaBlitterTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BF7019F26FFD32300996424 /* AmigaBlitterTests.mm */; };
|
||||||
@ -2211,6 +2213,8 @@
|
|||||||
4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DigitalPhaseLockedLoopBridge.mm; sourceTree = "<group>"; };
|
4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DigitalPhaseLockedLoopBridge.mm; sourceTree = "<group>"; };
|
||||||
4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DPLLTests.swift; sourceTree = "<group>"; };
|
4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DPLLTests.swift; sourceTree = "<group>"; };
|
||||||
4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MemorySlotHandler.cpp; sourceTree = "<group>"; };
|
4BF0BC67297108D100CCA2B5 /* MemorySlotHandler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = MemorySlotHandler.cpp; sourceTree = "<group>"; };
|
||||||
|
4BF0BC6F2973318E00CCA2B5 /* RP5C01.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RP5C01.cpp; sourceTree = "<group>"; };
|
||||||
|
4BF0BC702973318E00CCA2B5 /* RP5C01.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = RP5C01.hpp; sourceTree = "<group>"; };
|
||||||
4BF40A5525424C770033EA39 /* LanguageCardSwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LanguageCardSwitches.hpp; sourceTree = "<group>"; };
|
4BF40A5525424C770033EA39 /* LanguageCardSwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LanguageCardSwitches.hpp; sourceTree = "<group>"; };
|
||||||
4BF40A5A254263140033EA39 /* AuxiliaryMemorySwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AuxiliaryMemorySwitches.hpp; sourceTree = "<group>"; };
|
4BF40A5A254263140033EA39 /* AuxiliaryMemorySwitches.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = AuxiliaryMemorySwitches.hpp; sourceTree = "<group>"; };
|
||||||
4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentParser.cpp; sourceTree = "<group>"; };
|
4BF437EC209D0F7E008CBD6B /* SegmentParser.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = SegmentParser.cpp; sourceTree = "<group>"; };
|
||||||
@ -4579,6 +4583,7 @@
|
|||||||
4B302181208A550100773308 /* DiskII */,
|
4B302181208A550100773308 /* DiskII */,
|
||||||
4B4B1A39200198C900A0F866 /* KonamiSCC */,
|
4B4B1A39200198C900A0F866 /* KonamiSCC */,
|
||||||
4BC23A212467600E001A6030 /* OPx */,
|
4BC23A212467600E001A6030 /* OPx */,
|
||||||
|
4BF0BC6E2973318E00CCA2B5 /* RP5C01 */,
|
||||||
4B0ACBFF237756EC008902D0 /* Serial */,
|
4B0ACBFF237756EC008902D0 /* Serial */,
|
||||||
4BB0A6582044FD3000FB3688 /* SN76489 */,
|
4BB0A6582044FD3000FB3688 /* SN76489 */,
|
||||||
);
|
);
|
||||||
@ -4948,6 +4953,15 @@
|
|||||||
path = Formats;
|
path = Formats;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
4BF0BC6E2973318E00CCA2B5 /* RP5C01 */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
4BF0BC6F2973318E00CCA2B5 /* RP5C01.cpp */,
|
||||||
|
4BF0BC702973318E00CCA2B5 /* RP5C01.hpp */,
|
||||||
|
);
|
||||||
|
path = RP5C01;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
4BF660691F281573002CB053 /* ClockReceiver */ = {
|
4BF660691F281573002CB053 /* ClockReceiver */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -5630,6 +5644,7 @@
|
|||||||
4B5B37322777C7FC0047F238 /* IPF.cpp in Sources */,
|
4B5B37322777C7FC0047F238 /* IPF.cpp in Sources */,
|
||||||
4B894519201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
|
4B894519201967B4007DE474 /* ConfidenceCounter.cpp in Sources */,
|
||||||
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */,
|
4B055AEE1FAE9BBF0060FFFF /* Keyboard.cpp in Sources */,
|
||||||
|
4BF0BC722973318E00CCA2B5 /* RP5C01.cpp in Sources */,
|
||||||
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
|
4B055AED1FAE9BA20060FFFF /* Z80Storage.cpp in Sources */,
|
||||||
4B1B88BC202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */,
|
4B1B88BC202E2EC100B67DFF /* MultiKeyboardMachine.cpp in Sources */,
|
||||||
4BC890D4230F86020025A55A /* DirectAccessDevice.cpp in Sources */,
|
4BC890D4230F86020025A55A /* DirectAccessDevice.cpp in Sources */,
|
||||||
@ -5983,6 +5998,7 @@
|
|||||||
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
|
4B83348A1F5DB94B0097E338 /* IRQDelegatePortHandler.cpp in Sources */,
|
||||||
4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */,
|
4B8DD3862634D37E00B3C866 /* SNA.cpp in Sources */,
|
||||||
4B4DEC06252BFA56004583AC /* 65816Base.cpp in Sources */,
|
4B4DEC06252BFA56004583AC /* 65816Base.cpp in Sources */,
|
||||||
|
4BF0BC712973318E00CCA2B5 /* RP5C01.cpp in Sources */,
|
||||||
4B894524201967B4007DE474 /* Tape.cpp in Sources */,
|
4B894524201967B4007DE474 /* Tape.cpp in Sources */,
|
||||||
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */,
|
4B7136891F78725F008B8ED9 /* Shifter.cpp in Sources */,
|
||||||
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */,
|
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user