mirror of
https://github.com/JorjBauer/aiie.git
synced 2024-12-26 23:29:21 +00:00
convert cpu cycle counter to int64_t
This commit is contained in:
parent
0c2cf3f8ff
commit
fc3a360e7e
@ -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) {
|
||||||
|
@ -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
|
||||||
|
@ -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]) {
|
||||||
|
@ -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();
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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
2
cpu.h
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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;
|
||||||
/*
|
/*
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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.
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user