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

Brought Typer into the new run_for orthodoxy, making it easier to clock consistently regardless of unit. Which necessitated adding a negative operator for WrappedInts.

This commit is contained in:
Thomas Harte 2017-07-27 21:53:45 -04:00
parent 92a3dfe44a
commit 968d2bb8ba
8 changed files with 21 additions and 19 deletions

View File

@ -98,6 +98,8 @@ template <class T> class WrappedInt {
inline T operator +(const T &rhs) const { return T(length_ + rhs.length_); }
inline T operator -(const T &rhs) const { return T(length_ - rhs.length_); }
inline T operator -() const { return T(- length_); }
inline bool operator <(const T &rhs) const { return length_ < rhs.length_; }
inline bool operator >(const T &rhs) const { return length_ > rhs.length_; }
inline bool operator <=(const T &rhs) const { return length_ <= rhs.length_; }

View File

@ -327,7 +327,7 @@ Cycles Machine::perform_bus_operation(CPU::MOS6502::BusOperation operation, uint
queue_next_display_interrupt();
}
if(typer_) typer_->update((int)cycles);
if(typer_) typer_->run_for(Cycles((int)cycles));
if(plus3_) plus3_->run_for(Cycles(4*(int)cycles));
if(shift_restart_counter_) {
shift_restart_counter_ -= cycles;

View File

@ -101,8 +101,8 @@ class Machine:
virtual void tape_did_change_interrupt_status(Tape *tape);
// for Utility::TypeRecipient
virtual int get_typer_delay();
virtual int get_typer_frequency();
virtual HalfCycles get_typer_delay();
virtual HalfCycles get_typer_frequency();
uint16_t *sequence_for_character(Utility::Typer *typer, char character);
private:

View File

@ -8,12 +8,12 @@
#include "Electron.hpp"
int Electron::Machine::get_typer_delay() {
return get_is_resetting() ? 625*25*128 : 0; // wait one second if resetting
HalfCycles Electron::Machine::get_typer_delay() {
return get_is_resetting() ? Cycles(625*25*128) : Cycles(0); // wait one second if resetting
}
int Electron::Machine::get_typer_frequency() {
return 625*128*2; // accept a new character every two frames
HalfCycles Electron::Machine::get_typer_frequency() {
return Cycles(625*128*2); // accept a new character every two frames
}
uint16_t *Electron::Machine::sequence_for_character(Utility::Typer *typer, char character) {

View File

@ -11,14 +11,14 @@
using namespace Utility;
Typer::Typer(const char *string, int delay, int frequency, Delegate *delegate) :
Typer::Typer(const char *string, HalfCycles delay, HalfCycles frequency, Delegate *delegate) :
counter_(-delay), frequency_(frequency), string_pointer_(0), delegate_(delegate), phase_(0) {
size_t string_size = strlen(string) + 3;
string_ = (char *)malloc(string_size);
snprintf(string_, string_size, "%c%s%c", Typer::BeginString, string, Typer::EndString);
}
void Typer::update(int duration) {
void Typer::run_for(HalfCycles duration) {
if(string_) {
if(counter_ < 0 && counter_ + duration >= 0) {
if(!type_next_character()) {

View File

@ -11,6 +11,7 @@
#include <memory>
#include "KeyboardMachine.hpp"
#include "../ClockReceiver/ClockReceiver.hpp"
namespace Utility {
@ -30,9 +31,9 @@ class Typer {
const uint16_t NotMapped = 0xfffe;
};
Typer(const char *string, int delay, int frequency, Delegate *delegate);
Typer(const char *string, HalfCycles delay, HalfCycles frequency, Delegate *delegate);
~Typer();
void update(int duration);
void run_for(HalfCycles duration);
bool type_next_character();
const char BeginString = 0x02; // i.e. ASCII start of text
@ -40,8 +41,8 @@ class Typer {
private:
char *string_;
int frequency_;
int counter_;
HalfCycles frequency_;
HalfCycles counter_;
int phase_;
Delegate *delegate_;
size_t string_pointer_;
@ -58,8 +59,8 @@ class TypeRecipient: public Typer::Delegate {
}
protected:
virtual int get_typer_delay() { return 0; }
virtual int get_typer_frequency() { return 0; }
virtual HalfCycles get_typer_delay() { return HalfCycles(0); }
virtual HalfCycles get_typer_frequency() { return HalfCycles(0); }
std::unique_ptr<Typer> typer_;
};

View File

@ -183,8 +183,7 @@ HalfCycles Machine::perform_machine_cycle(const CPU::Z80::PartialMachineCycle &c
default: break;
}
// This will lose some precision; TODO: bring inside the [Half]ClockReceiver domain.
if(typer_) typer_->update(cycle.length.as_int() / 2);
if(typer_) typer_->run_for(cycle.length);
return HalfCycles(0);
}

View File

@ -75,8 +75,8 @@ class Machine:
// for Utility::TypeRecipient::Delegate
uint16_t *sequence_for_character(Utility::Typer *typer, char character);
int get_typer_delay() { return 7000000; }
int get_typer_frequency() { return 390000; }
HalfCycles get_typer_delay() { return Cycles(7000000); }
HalfCycles get_typer_frequency() { return Cycles(390000); }
private:
std::shared_ptr<Video> video_;