1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-29 00:29:34 +00:00

Fixed best-effort updater actually to run, finally moved clock rate announcement into the C++ side of things, started working on a mechanism to allow clock rate to be updated.

This commit is contained in:
Thomas Harte 2016-06-16 20:39:46 -04:00
parent 1921a6c469
commit 00a9f1bf24
11 changed files with 31 additions and 43 deletions

View File

@ -68,6 +68,8 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine {
virtual Outputs::CRT::CRT *get_crt() { return _crt; }
virtual Outputs::Speaker *get_speaker() { return &_speaker; }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
virtual double get_clock_rate() { return 1194720; }
// TODO: different rate for PAL
private:
uint8_t *_rom, *_romPages[4], _ram[128];

View File

@ -23,6 +23,16 @@ class Machine {
virtual Outputs::Speaker *get_speaker() = 0;
virtual void run_for_cycles(int number_of_cycles) = 0;
virtual double get_clock_rate() = 0;
class Delegate {
public:
virtual void machine_did_change_clock_rate(Machine *machine) = 0;
};
void set_delegate(Delegate *delegate) { this->delegate = delegate; }
protected:
Delegate *delegate;
};
}

View File

@ -165,6 +165,7 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine, T
virtual Outputs::CRT::CRT *get_crt() { return _crt.get(); }
virtual Outputs::Speaker *get_speaker() { return &_speaker; }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
virtual double get_clock_rate() { return 2000000; }
// to satisfy Tape::Delegate
virtual void tape_did_change_interrupt_status(Tape *tape);

View File

@ -108,6 +108,8 @@ class Machine: public CPU6502::Processor<Machine>, public CRTMachine::Machine, p
virtual Outputs::CRT::CRT *get_crt() { return _mos6560->get_crt(); }
virtual Outputs::Speaker *get_speaker() { return _mos6560->get_speaker(); }
virtual void run_for_cycles(int number_of_cycles) { CPU6502::Processor<Machine>::run_for_cycles(number_of_cycles); }
virtual double get_clock_rate() { return 1022727; }
// TODO: or 1108405 for PAL; see http://www.antimon.org/dl/c64/code/stable.txt
// to satisfy MOS::MOS6522::Delegate
virtual void mos6522_did_change_interrupt_status(void *mos6522);

View File

@ -16,11 +16,6 @@ class Atari2600Document: MachineDocument {
}
// MARK: NSDocument overrides
override init() {
super.init()
self.bestEffortUpdater.clockRate = 1194720
}
override class func autosavesInPlace() -> Bool {
return true
}

View File

@ -27,8 +27,6 @@ class ElectronDocument: MachineDocument {
override func windowControllerDidLoadNib(aController: NSWindowController) {
super.windowControllerDidLoadNib(aController)
self.bestEffortUpdater.clockRate = 2000000
if let os = rom("os"), basic = rom("basic") {
self.electron.setOSROM(os)
self.electron.setBASICROM(basic)

View File

@ -33,8 +33,8 @@ class MachineDocument: NSDocument, CSOpenGLViewDelegate, CSOpenGLViewResponderDe
optionsPanel?.setIsVisible(true)
}
var audioQueue: CSAudioQueue! = nil
lazy var bestEffortUpdater: CSBestEffortUpdater = {
private var audioQueue: CSAudioQueue! = nil
private lazy var bestEffortUpdater: CSBestEffortUpdater = {
let updater = CSBestEffortUpdater()
updater.delegate = self
return updater
@ -58,6 +58,8 @@ class MachineDocument: NSDocument, CSOpenGLViewDelegate, CSOpenGLViewResponderDe
self.machine().audioQueue = self.audioQueue
self.machine().setAudioSamplingRate(selectedSamplingRate)
}
self.bestEffortUpdater.clockRate = self.machine().clockRate
}
override func close() {
@ -74,36 +76,6 @@ class MachineDocument: NSDocument, CSOpenGLViewDelegate, CSOpenGLViewResponderDe
final func bestEffortUpdater(bestEffortUpdater: CSBestEffortUpdater!, runForCycles cycles: UInt, didSkipPreviousUpdate: Bool) {
runForNumberOfCycles(Int32(cycles))
}
// var intendedCyclesPerSecond: Int64 = 0
// private var cycleCountError: Int64 = 0
// private var lastTime: CVTimeStamp?
// private var skippedFrames = 0
// final func openGLView(view: CSOpenGLView, didUpdateToTime time: CVTimeStamp, didSkipPreviousUpdate : Bool, frequency : Double) {
// if let lastTime = lastTime {
// // perform (time passed in seconds) * (intended cycles per second), converting and
// // maintaining an error count to deal with underflow
// let videoTimeScale64 = Int64(time.videoTimeScale)
// let videoTimeCount = ((time.videoTime - lastTime.videoTime) * intendedCyclesPerSecond) + cycleCountError
// cycleCountError = videoTimeCount % videoTimeScale64
// var numberOfCycles = videoTimeCount / videoTimeScale64
//
// // if the emulation has fallen behind then silently limit the request;
// // some actions e.g. the host computer waking after sleep may give us a
// // prohibitive backlog
// if didSkipPreviousUpdate {
// skippedFrames++
// } else {
// skippedFrames = 0
// }
//
// // run for at most three frames up to and until that causes overshoots in the
// // permitted processing window for at least four consecutive frames, in which
// // case limit to one
// numberOfCycles = min(numberOfCycles, Int64(Double(intendedCyclesPerSecond) * frequency * ((skippedFrames > 4) ? 3.0 : 1.0)))
// runForNumberOfCycles(Int32(numberOfCycles))
// }
// lastTime = time
// }
// MARK: Utilities for children
func dataForResource(name : String, ofType type: String, inDirectory directory: String) -> NSData? {

View File

@ -18,8 +18,6 @@ class Vic20Document: MachineDocument {
// MARK: NSDocument overrides
override init() {
super.init()
self.bestEffortUpdater.clockRate = 1022727
// TODO: or 1108405 for PAL; see http://www.antimon.org/dl/c64/code/stable.txt
if let kernel = rom("kernel-ntsc"), basic = rom("basic"), characters = rom("characters-english") {
vic20.setKernelROM(kernel)

View File

@ -10,6 +10,11 @@
#import "CSOpenGLView.h"
#import "CSAudioQueue.h"
@class CSMachine;
@protocol CSMachineDelegate
- (void)machineDidChangeClockRate:(CSMachine *)machine;
@end
@interface CSMachine : NSObject
- (void)runForNumberOfCycles:(int)numberOfCycles;
@ -22,5 +27,7 @@
@property (nonatomic, strong) CSAudioQueue *audioQueue;
@property (nonatomic, readonly) CSOpenGLView *view;
@property (nonatomic, weak) id<CSMachineDelegate> delegate;
@property (nonatomic, readonly) double clockRate;
@end

View File

@ -88,4 +88,8 @@ struct SpeakerDelegate: public Outputs::Speaker::Delegate {
self.machine->get_crt()->draw_frame((unsigned int)pixelSize.width, (unsigned int)pixelSize.height, onlyIfDirty ? true : false);
}
- (double)clockRate {
return self.machine->get_clock_rate();
}
@end

View File

@ -47,9 +47,8 @@
NSUInteger integerCyclesToRunFor = (NSUInteger)cyclesToRunFor;
[self.delegate bestEffortUpdater:self runForCycles:integerCyclesToRunFor didSkipPreviousUpdate:_hasSkipped];
_previousTimeInterval = timeInterval;
}
_previousTimeInterval = timeInterval;
_hasSkipped = NO;
OSAtomicTestAndClear(processingMask, &_updateIsOngoing);
});