convert cpu cycle counter to int64_t

This commit is contained in:
Jorj Bauer 2020-08-02 09:06:15 -04:00
parent 0c2cf3f8ff
commit fc3a360e7e
18 changed files with 67 additions and 70 deletions

View File

@ -172,7 +172,7 @@ void AppleKeyboard::keyReleased(uint8_t k)
} }
} }
void AppleKeyboard::maintainKeyboard(uint32_t cycleCount) void AppleKeyboard::maintainKeyboard(int64_t cycleCount)
{ {
if (anyKeyIsDown) { if (anyKeyIsDown) {
if (startRepeatTimer) { if (startRepeatTimer) {

View File

@ -13,7 +13,7 @@ class AppleKeyboard : public VMKeyboard {
virtual void keyDepressed(uint8_t k); virtual void keyDepressed(uint8_t k);
virtual void keyReleased(uint8_t k); virtual void keyReleased(uint8_t k);
virtual void maintainKeyboard(uint32_t cycleCount); virtual void maintainKeyboard(int64_t cycleCount);
protected: protected:
bool isVirtualKey(uint8_t kc); bool isVirtualKey(uint8_t kc);
@ -49,9 +49,9 @@ class AppleKeyboard : public VMKeyboard {
// repeatTimer is the cpu cycle count at which we would repeat again. // repeatTimer is the cpu cycle count at which we would repeat again.
// (It also has the rollover problem once every 82 minutes.) // (It also has the rollover problem once every 82 minutes.)
uint32_t startRepeatTimer; int64_t startRepeatTimer;
uint8_t keyThatIsRepeating; uint8_t keyThatIsRepeating;
uint32_t repeatTimer; int64_t repeatTimer;
}; };
#endif #endif

View File

@ -127,7 +127,7 @@ void AppleVM::triggerPaddleInCycles(uint8_t paddleNum,uint16_t cycleCount)
paddleCycleTrigger[paddleNum] = cycleCount + g_cpu->cycles; paddleCycleTrigger[paddleNum] = cycleCount + g_cpu->cycles;
} }
void AppleVM::cpuMaintenance(uint32_t cycles) void AppleVM::cpuMaintenance(int64_t cycles)
{ {
for (uint8_t i=0; i<2; i++) { for (uint8_t i=0; i<2; i++) {
if (paddleCycleTrigger[i] && cycles >= paddleCycleTrigger[i]) { if (paddleCycleTrigger[i] && cycles >= paddleCycleTrigger[i]) {

View File

@ -17,7 +17,7 @@ class AppleVM : public VM {
void Suspend(const char *fn); void Suspend(const char *fn);
void Resume(const char *fn); void Resume(const char *fn);
void cpuMaintenance(uint32_t cycles); void cpuMaintenance(int64_t cycles);
virtual void Reset(); virtual void Reset();
void Monitor(); void Monitor();

View File

@ -26,6 +26,9 @@
// 10 second delay before flushing // 10 second delay before flushing
#define FLUSHDELAY (1023000 * 10) #define FLUSHDELAY (1023000 * 10)
#define SPINFOREVER -2
#define NOTSPINNING -1
DiskII::DiskII(AppleMMU *mmu) DiskII::DiskII(AppleMMU *mmu)
{ {
this->mmu = mmu; this->mmu = mmu;
@ -39,11 +42,11 @@ DiskII::DiskII(AppleMMU *mmu)
readWriteLatch = 0x00; readWriteLatch = 0x00;
sequencer = 0; sequencer = 0;
dataRegister = 0; dataRegister = 0;
driveSpinupCycles[0] = driveSpinupCycles[1] = 0; driveSpinupCycles[0] = driveSpinupCycles[1] = 0; // CPU cycle number when the disk drive spins up
deliveredDiskBits[0] = deliveredDiskBits[1] = 0; deliveredDiskBits[0] = deliveredDiskBits[1] = 0;
disk[0] = disk[1] = NULL; disk[0] = disk[1] = NULL;
diskIsSpinningUntil[0] = diskIsSpinningUntil[1] = 0; diskIsSpinningUntil[0] = diskIsSpinningUntil[1] = -1;
flushAt[0] = flushAt[1] = 0; flushAt[0] = flushAt[1] = 0;
selectedDisk = 0; selectedDisk = 0;
} }
@ -54,7 +57,7 @@ DiskII::~DiskII()
bool DiskII::Serialize(int8_t fd) bool DiskII::Serialize(int8_t fd)
{ {
uint8_t buf[23] = { DISKIIMAGIC, uint8_t buf[27] = { DISKIIMAGIC,
readWriteLatch, readWriteLatch,
sequencer, sequencer,
dataRegister, dataRegister,
@ -87,13 +90,17 @@ bool DiskII::Serialize(int8_t fd)
buf[ptr++] = ((deliveredDiskBits[i] >> 16) & 0xFF); buf[ptr++] = ((deliveredDiskBits[i] >> 16) & 0xFF);
buf[ptr++] = ((deliveredDiskBits[i] >> 8) & 0xFF); buf[ptr++] = ((deliveredDiskBits[i] >> 8) & 0xFF);
buf[ptr++] = ((deliveredDiskBits[i] ) & 0xFF); buf[ptr++] = ((deliveredDiskBits[i] ) & 0xFF);
buf[ptr++] = (diskIsSpinningUntil[i] >> 56) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] >> 48) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] >> 40) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] >> 32) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] >> 24) & 0xFF; buf[ptr++] = (diskIsSpinningUntil[i] >> 24) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] >> 16) & 0xFF; buf[ptr++] = (diskIsSpinningUntil[i] >> 16) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] >> 8) & 0xFF; buf[ptr++] = (diskIsSpinningUntil[i] >> 8) & 0xFF;
buf[ptr++] = (diskIsSpinningUntil[i] ) & 0xFF; buf[ptr++] = (diskIsSpinningUntil[i] ) & 0xFF;
// Safety check: keeping the hard-coded 23 and comparing against ptr. // Safety check: keeping the hard-coded 27 and comparing against ptr.
// If we change the 23, also need to change the size of buf[] above // If we change the 27, also need to change the size of buf[] above
if (g_filemanager->write(fd, buf, 23) != ptr) { if (g_filemanager->write(fd, buf, 27) != ptr) {
return false; return false;
} }
@ -144,7 +151,7 @@ bool DiskII::Deserialize(int8_t fd)
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
uint8_t ptr = 0; uint8_t ptr = 0;
if (g_filemanager->read(fd, buf, 23) != 23) if (g_filemanager->read(fd, buf, 27) != 27)
return false; return false;
curHalfTrack[i] = buf[ptr++]; curHalfTrack[i] = buf[ptr++];
@ -173,6 +180,10 @@ bool DiskII::Deserialize(int8_t fd)
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++]; diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++]; diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++]; diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
diskIsSpinningUntil[i] <<= 8; diskIsSpinningUntil[i] |= buf[ptr++];
if (disk[i]) if (disk[i])
delete disk[i]; delete disk[i];
@ -228,12 +239,8 @@ void DiskII::Reset()
void DiskII::driveOff() void DiskII::driveOff()
{ {
if (diskIsSpinningUntil[selectedDisk] == -1) { if (diskIsSpinningUntil[selectedDisk] == SPINFOREVER) {
diskIsSpinningUntil[selectedDisk] = g_cpu->cycles + SPINDOWNDELAY; // 1 second lag diskIsSpinningUntil[selectedDisk] = g_cpu->cycles + SPINDOWNDELAY; // 1 second lag
if (diskIsSpinningUntil[selectedDisk] == -1 ||
diskIsSpinningUntil[selectedDisk] == 0)
diskIsSpinningUntil[selectedDisk] = 2; // fudge magic numbers; 0 is "off" and -1 is "forever".
// The drive-is-on-indicator is turned off later, when the disk // The drive-is-on-indicator is turned off later, when the disk
// actually spins down. // actually spins down.
} }
@ -247,13 +254,13 @@ void DiskII::driveOff()
void DiskII::driveOn() void DiskII::driveOn()
{ {
if (diskIsSpinningUntil[selectedDisk] != -1) { if (diskIsSpinningUntil[selectedDisk] != SPINFOREVER) {
// If the drive isn't already spinning, then start keeping track of how // If the drive isn't already spinning, then start keeping track of how
// many bits we've delivered (so we can honor the disk bit-delivery time // many bits we've delivered (so we can honor the disk bit-delivery time
// that might be in the Woz disk image). // that might be in the Woz disk image).
driveSpinupCycles[selectedDisk] = g_cpu->cycles; driveSpinupCycles[selectedDisk] = g_cpu->cycles;
deliveredDiskBits[selectedDisk] = 0; deliveredDiskBits[selectedDisk] = 0;
diskIsSpinningUntil[selectedDisk] = -1; // magic "forever" diskIsSpinningUntil[selectedDisk] = SPINFOREVER;
} }
// FIXME: does the sequencer get reset? Maybe if it's the selected disk? Or no? // FIXME: does the sequencer get reset? Maybe if it's the selected disk? Or no?
// sequencer = 0; // sequencer = 0;
@ -301,9 +308,6 @@ uint8_t DiskII::readSwitches(uint8_t s)
case 0x0C: // shift one read or write byte case 0x0C: // shift one read or write byte
readWriteLatch = readOrWriteByte(); readWriteLatch = readOrWriteByte();
if (readWriteLatch & 0x80) { if (readWriteLatch & 0x80) {
// static uint32_t lastC = 0;
// printf("%u: read data\n", g_cpu->cycles - lastC);
// lastC = g_cpu->cycles;
if (!(sequencer & 0x80)) { if (!(sequencer & 0x80)) {
// printf("SEQ RESET EARLY [1]\n"); // printf("SEQ RESET EARLY [1]\n");
} }
@ -478,17 +482,10 @@ bool DiskII::isWriteProtected()
int64_t DiskII::calcExpectedBits() int64_t DiskII::calcExpectedBits()
{ {
// If the disk isn't spinning, then it can't be expected to deliver data // If the disk isn't spinning, then it can't be expected to deliver data
if (!diskIsSpinningUntil[selectedDisk]) if (diskIsSpinningUntil[selectedDisk]==NOTSPINNING)
return 0; return 0;
// Handle potential messy counter rollover int64_t cyclesPassed = g_cpu->cycles - driveSpinupCycles[selectedDisk];
if (driveSpinupCycles[selectedDisk] > g_cpu->cycles) {
driveSpinupCycles[selectedDisk] = g_cpu->cycles-1;
if (driveSpinupCycles[selectedDisk] == 0) // avoid sitting on 0
driveSpinupCycles[selectedDisk]++;
}
uint32_t cyclesPassed = g_cpu->cycles - driveSpinupCycles[selectedDisk];
// This constant defines how fast the disk drive "spins". // This constant defines how fast the disk drive "spins".
// 4.0 is good for DOS 3.3 writes, and reads as 205ms in // 4.0 is good for DOS 3.3 writes, and reads as 205ms in
// Copy 2+'s drive speed verifier. // Copy 2+'s drive speed verifier.
@ -500,7 +497,7 @@ int64_t DiskII::calcExpectedBits()
// As-is, this won't read NIB files for some reason I haven't // As-is, this won't read NIB files for some reason I haven't
// fully understood; but if you slow the disk down to /5.0, // fully understood; but if you slow the disk down to /5.0,
// then they load? // then they load?
uint64_t expectedDiskBits = (float)cyclesPassed / 3.90; int64_t expectedDiskBits = (float)cyclesPassed / 3.90;
return expectedDiskBits - deliveredDiskBits[selectedDisk]; return expectedDiskBits - deliveredDiskBits[selectedDisk];
} }
@ -585,19 +582,19 @@ void DiskII::select(int8_t which)
return; return;
if (which != selectedDisk) { if (which != selectedDisk) {
if (diskIsSpinningUntil[selectedDisk] == -1) { if (diskIsSpinningUntil[selectedDisk] == SPINFOREVER) {
// FIXME: I'm not sure what the right behavior is here (read // FIXME: I'm not sure what the right behavior is here (read
// UTA2E and see if the state diagrams show the right // UTA2E and see if the state diagrams show the right
// behavior). This spins it down immediately based on something // behavior). This spins it down immediately based on something
// I read about the duoDisk not having both motors on // I read about the duoDisk not having both motors on
// simultaneously. // simultaneously.
diskIsSpinningUntil[selectedDisk] = 0; diskIsSpinningUntil[selectedDisk] = NOTSPINNING;
// FIXME: consume any disk bits that need to be consumed, and // FIXME: consume any disk bits that need to be consumed, and
// spin it down // spin it down
g_ui->drawOnOffUIElement(UIeDisk1_activity + selectedDisk, false); g_ui->drawOnOffUIElement(UIeDisk1_activity + selectedDisk, false);
// Spin up the other one though // Spin up the other one though
diskIsSpinningUntil[which] = -1; diskIsSpinningUntil[which] = SPINFOREVER;
g_ui->drawOnOffUIElement(UIeDisk1_activity + which, true); g_ui->drawOnOffUIElement(UIeDisk1_activity + which, true);
} }
@ -625,13 +622,13 @@ void DiskII::select(int8_t which)
uint8_t DiskII::readOrWriteByte() uint8_t DiskII::readOrWriteByte()
{ {
if (!disk[selectedDisk]) { if (!disk[selectedDisk]) {
//printf("reading from uninserted disk\n");
return 0xFF; return 0xFF;
} }
int32_t bitsToDeliver; int32_t bitsToDeliver;
if (diskIsSpinningUntil[selectedDisk] < g_cpu->cycles) { if (diskIsSpinningUntil[selectedDisk] != SPINFOREVER &&
diskIsSpinningUntil[selectedDisk] < g_cpu->cycles) {
// Uum, disk isn't spinning? // Uum, disk isn't spinning?
goto done; goto done;
} }
@ -740,15 +737,15 @@ void DiskII::loadROM(uint8_t *toWhere)
#endif #endif
} }
void DiskII::maintenance(uint32_t cycle) void DiskII::maintenance(int64_t cycle)
{ {
// Handle spin-down for the drive. Drives stay on for a second after // Handle spin-down for the drive. Drives stay on for a second after
// the stop was noticed. // the stop was noticed.
for (int i=0; i<2; i++) { for (int i=0; i<2; i++) {
if (diskIsSpinningUntil[i] && if (diskIsSpinningUntil[i] != SPINFOREVER &&
g_cpu->cycles > diskIsSpinningUntil[i]) { g_cpu->cycles > diskIsSpinningUntil[i]) {
// Stop the given disk drive spinning // Stop the given disk drive spinning
diskIsSpinningUntil[i] = 0; diskIsSpinningUntil[i] = NOTSPINNING;
// FIXME: consume any disk bits that need to be consumed, and spin it down // FIXME: consume any disk bits that need to be consumed, and spin it down
g_ui->drawOnOffUIElement(UIeDisk1_activity + i, false); g_ui->drawOnOffUIElement(UIeDisk1_activity + i, false);
} }

View File

@ -35,7 +35,7 @@ class DiskII : public Slot {
const char *DiskName(int8_t num); const char *DiskName(int8_t num);
void maintenance(uint32_t cycles); void maintenance(int64_t cycles);
uint8_t selectedDrive(); uint8_t selectedDrive();
uint8_t headPosition(uint8_t drive); uint8_t headPosition(uint8_t drive);
@ -66,18 +66,18 @@ private:
volatile int8_t curPhase[2]; volatile int8_t curPhase[2];
volatile uint8_t readWriteLatch; volatile uint8_t readWriteLatch;
volatile uint8_t sequencer, dataRegister; // diskII logic state sequencer vars volatile uint8_t sequencer, dataRegister; // diskII logic state sequencer vars
volatile uint64_t driveSpinupCycles[2]; volatile int64_t driveSpinupCycles[2];
volatile uint64_t deliveredDiskBits[2]; volatile int64_t deliveredDiskBits[2];
bool writeMode; bool writeMode;
bool writeProt; bool writeProt;
AppleMMU *mmu; AppleMMU *mmu;
volatile uint32_t diskIsSpinningUntil[2]; volatile int64_t diskIsSpinningUntil[2];
volatile int8_t selectedDisk; volatile int8_t selectedDisk;
volatile uint32_t flushAt[2]; volatile int64_t flushAt[2];
}; };
#endif #endif

2
cpu.h
View File

@ -183,7 +183,7 @@ class Cpu {
uint8_t y; uint8_t y;
uint8_t flags; uint8_t flags;
uint32_t cycles; int64_t cycles;
bool irqPending; bool irqPending;

View File

@ -90,7 +90,7 @@ void write(void *arg, uint16_t address, uint8_t v)
static void *cpu_thread(void *dummyptr) { static void *cpu_thread(void *dummyptr) {
struct timespec currentTime; struct timespec currentTime;
struct timespec nextCycleTime; struct timespec nextCycleTime;
uint32_t nextSpeakerCycle = 0; int64_t nextSpeakerCycle = 0;
#if 0 #if 0
int policy; int policy;

View File

@ -18,11 +18,11 @@ void LinuxSpeaker::begin()
{ {
} }
void LinuxSpeaker::toggle(uint32_t c) void LinuxSpeaker::toggle(int64_t c)
{ {
} }
void LinuxSpeaker::maintainSpeaker(uint32_t c, uint64_t microseconds) void LinuxSpeaker::maintainSpeaker(int64_t c, uint64_t microseconds)
{ {
} }

View File

@ -34,7 +34,7 @@ static int do_gettime(struct timespec *tp) {
// adds the number of nanoseconds that 'cycles' takes to *start and // adds the number of nanoseconds that 'cycles' takes to *start and
// returns it in *out // returns it in *out
static void timespec_add_cycles(struct timespec *start, static void timespec_add_cycles(struct timespec *start,
int32_t cycles, int64_t cycles,
struct timespec *out) struct timespec *out)
{ {
out->tv_sec = start->tv_sec; out->tv_sec = start->tv_sec;

View File

@ -9,8 +9,8 @@ class PhysicalSpeaker {
virtual void begin() = 0; virtual void begin() = 0;
virtual void toggle(uint32_t c) = 0; virtual void toggle(int64_t c) = 0;
virtual void maintainSpeaker(uint32_t c, uint64_t microseconds) = 0; virtual void maintainSpeaker(int64_t c, uint64_t microseconds) = 0;
virtual void beginMixing() = 0; virtual void beginMixing() = 0;
virtual void mixOutput(uint8_t v) = 0; virtual void mixOutput(uint8_t v) = 0;

View File

@ -258,7 +258,7 @@ int main(int argc, char *argv[])
g_speaker->begin(); g_speaker->begin();
uint32_t lastCycleCount = -1; int64_t lastCycleCount = -1;
while (1) { while (1) {
if (g_biosInterrupt) { if (g_biosInterrupt) {
@ -293,7 +293,7 @@ int main(int argc, char *argv[])
} }
static uint32_t usleepcycles = 16384*4; // step-down for display drawing. Dynamically updated based on FPS calculations. static int64_t usleepcycles = 16384*4; // step-down for display drawing. Dynamically updated based on FPS calculations.
if (g_vm->vmdisplay->needsRedraw()) { if (g_vm->vmdisplay->needsRedraw()) {
AiieRect what = g_vm->vmdisplay->getDirtyRect(); AiieRect what = g_vm->vmdisplay->getDirtyRect();
@ -409,7 +409,7 @@ void doDebugging()
g_display->debugMsg(buf); g_display->debugMsg(buf);
break; break;
case D_SHOWCYCLES: case D_SHOWCYCLES:
sprintf(buf, "%X", g_cpu->cycles); sprintf(buf, "%llX", g_cpu->cycles);
g_display->debugMsg(buf); g_display->debugMsg(buf);
break; break;
/* /*

View File

@ -29,7 +29,7 @@ static volatile uint32_t skippedSamples = 0;
#define SAMPLEBYTES sizeof(short) #define SAMPLEBYTES sizeof(short)
volatile uint8_t audioRunning = 0; volatile uint8_t audioRunning = 0;
volatile uint32_t lastFilledTime = 0; volatile int64_t lastFilledTime = 0;
// Debugging by writing a wav file with the sound output... // Debugging by writing a wav file with the sound output...
@ -157,11 +157,11 @@ void SDLSpeaker::begin()
SDL_PauseAudio(0); SDL_PauseAudio(0);
} }
void SDLSpeaker::toggle(uint32_t c) void SDLSpeaker::toggle(int64_t c)
{ {
pthread_mutex_lock(&togmutex); pthread_mutex_lock(&togmutex);
uint32_t expectedCycleNumber = (float)c * (float)44100 / (float)g_speed; int64_t expectedCycleNumber = (float)c * (float)44100 / (float)g_speed;
if (lastFilledTime == 0) { if (lastFilledTime == 0) {
lastFilledTime = expectedCycleNumber; lastFilledTime = expectedCycleNumber;
} }
@ -217,7 +217,7 @@ void SDLSpeaker::toggle(uint32_t c)
pthread_mutex_unlock(&togmutex); pthread_mutex_unlock(&togmutex);
} }
void SDLSpeaker::maintainSpeaker(uint32_t c, uint64_t microseconds) void SDLSpeaker::maintainSpeaker(int64_t c, uint64_t microseconds)
{ {
} }

View File

@ -12,8 +12,8 @@ class SDLSpeaker : public PhysicalSpeaker {
virtual void begin(); virtual void begin();
virtual void toggle(uint32_t c); virtual void toggle(int64_t c);
virtual void maintainSpeaker(uint32_t c, uint64_t microseconds); virtual void maintainSpeaker(int64_t c, uint64_t microseconds);
virtual void beginMixing(); virtual void beginMixing();
virtual void mixOutput(uint8_t v); virtual void mixOutput(uint8_t v);

View File

@ -28,7 +28,7 @@ static int do_gettime(struct timespec *tp) {
// adds the number of nanoseconds that 'cycles' takes to *start and // adds the number of nanoseconds that 'cycles' takes to *start and
// returns it in *out // returns it in *out
static void timespec_add_cycles(struct timespec *start, static void timespec_add_cycles(struct timespec *start,
int32_t cycles, int64_t cycles,
struct timespec *out) struct timespec *out)
{ {
out->tv_sec = start->tv_sec; out->tv_sec = start->tv_sec;

View File

@ -32,7 +32,7 @@ static volatile uint32_t skippedSamples; // Who knows where this will
// too long & restart all the // too long & restart all the
// constants) // constants)
static volatile uint8_t audioRunning = 0; // FIXME: needs constants abstracted static volatile uint8_t audioRunning = 0; // FIXME: needs constants abstracted
static volatile uint32_t lastFilledTime = 0; static volatile int64_t lastFilledTime = 0;
// how full do we want the audio buffer before we start it playing? // how full do we want the audio buffer before we start it playing?
#define AUDIO_WATERLEVEL 4096 #define AUDIO_WATERLEVEL 4096
@ -66,7 +66,7 @@ void TeensySpeaker::begin()
audioRunning = 0; audioRunning = 0;
} }
void TeensySpeaker::toggle(uint32_t c) void TeensySpeaker::toggle(int64_t c)
{ {
// Figure out when the last time was that we put data in the audio buffer; // Figure out when the last time was that we put data in the audio buffer;
// then figure out how many audio buffer cycles we have to fill from that // then figure out how many audio buffer cycles we have to fill from that
@ -74,7 +74,7 @@ void TeensySpeaker::toggle(uint32_t c)
__disable_irq(); __disable_irq();
// We expect to have filled to this cycle number... // We expect to have filled to this cycle number...
uint32_t expectedCycleNumber = (float)c * (float)AUDIO_SAMPLE_RATE_EXACT / (float)g_speed; int64_t expectedCycleNumber = (float)c * (float)AUDIO_SAMPLE_RATE_EXACT / (float)g_speed;
// Dynamically initialize the lastFilledTime based on the start time of the // Dynamically initialize the lastFilledTime based on the start time of the
// audio channel. // audio channel.
if (lastFilledTime == 0) if (lastFilledTime == 0)
@ -133,7 +133,7 @@ void TeensySpeaker::toggle(uint32_t c)
__enable_irq(); __enable_irq();
} }
void TeensySpeaker::maintainSpeaker(uint32_t c, uint64_t microseconds) void TeensySpeaker::maintainSpeaker(int64_t c, uint64_t microseconds)
{ {
begin(); // flush! Hack. FIXME. begin(); // flush! Hack. FIXME.
} }

View File

@ -18,9 +18,9 @@ class TeensySpeaker : public PhysicalSpeaker {
virtual void begin(); virtual void begin();
virtual void toggle(uint32_t c); virtual void toggle(int64_t c);
virtual void maintainSpeaker(); virtual void maintainSpeaker();
virtual void maintainSpeaker(uint32_t c, uint64_t microseconds); virtual void maintainSpeaker(int64_t c, uint64_t microseconds);
virtual void beginMixing(); virtual void beginMixing();
virtual void mixOutput(uint8_t v); virtual void mixOutput(uint8_t v);

View File

@ -9,7 +9,7 @@ class VMKeyboard {
virtual void keyDepressed(uint8_t k) = 0; virtual void keyDepressed(uint8_t k) = 0;
virtual void keyReleased(uint8_t k) = 0; virtual void keyReleased(uint8_t k) = 0;
virtual void maintainKeyboard(uint32_t cycleCount) = 0; virtual void maintainKeyboard(int64_t cycleCount) = 0;
}; };
#endif #endif