mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +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:
parent
1921a6c469
commit
00a9f1bf24
@ -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];
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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? {
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user