mirror of
https://github.com/InvisibleUp/uvmac.git
synced 2024-06-09 22:29:32 +00:00
More PROGMAIN cleanup
This commit is contained in:
parent
ae159cb2d7
commit
4b9e429c82
2
Makefile
2
Makefile
|
@ -1,7 +1,7 @@
|
||||||
# Makefile
|
# Makefile
|
||||||
# Currently only builds Mac Plus emulator for Windows x64
|
# Currently only builds Mac Plus emulator for Windows x64
|
||||||
|
|
||||||
CC := clang
|
CC := gcc
|
||||||
CCFLAGS := -O2 -Wall -Wmissing-prototypes -Wno-uninitialized -Wundef -Wstrict-prototypes -Icfg/ -Isrc/
|
CCFLAGS := -O2 -Wall -Wmissing-prototypes -Wno-uninitialized -Wundef -Wstrict-prototypes -Icfg/ -Isrc/
|
||||||
|
|
||||||
.PHONY: linux windows clean
|
.PHONY: linux windows clean
|
||||||
|
|
301
src/PROGMAIN.c
301
src/PROGMAIN.c
|
@ -67,6 +67,7 @@ typedef struct DevMethods {
|
||||||
void (*reset)(void);
|
void (*reset)(void);
|
||||||
void (*starttick)(void);
|
void (*starttick)(void);
|
||||||
void (*endtick)(void);
|
void (*endtick)(void);
|
||||||
|
void (*subtick)(int);
|
||||||
void (*timebegin)(void);
|
void (*timebegin)(void);
|
||||||
void (*timeend)(void);
|
void (*timeend)(void);
|
||||||
} DevMethods_t;
|
} DevMethods_t;
|
||||||
|
@ -78,6 +79,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -87,6 +89,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -96,6 +99,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = Memory_Reset,
|
.reset = Memory_Reset,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -105,6 +109,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = ICT_Zap,
|
.reset = ICT_Zap,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -114,6 +119,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = IWM_Reset,
|
.reset = IWM_Reset,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -123,6 +129,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = SCC_Reset,
|
.reset = SCC_Reset,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -132,6 +139,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = SCSI_Reset,
|
.reset = SCSI_Reset,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -141,6 +149,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = VIA1_Zap,
|
.reset = VIA1_Zap,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = VIA1_ExtraTimeBegin,
|
.timebegin = VIA1_ExtraTimeBegin,
|
||||||
.timeend = VIA1_ExtraTimeEnd,
|
.timeend = VIA1_ExtraTimeEnd,
|
||||||
},
|
},
|
||||||
|
@ -150,6 +159,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = EmVIA2 ? VIA2_Zap : NULL,
|
.reset = EmVIA2 ? VIA2_Zap : NULL,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = EmVIA2 ? VIA2_ExtraTimeBegin : NULL,
|
.timebegin = EmVIA2 ? VIA2_ExtraTimeBegin : NULL,
|
||||||
.timeend = EmVIA2 ? VIA2_ExtraTimeEnd : NULL,
|
.timeend = EmVIA2 ? VIA2_ExtraTimeEnd : NULL,
|
||||||
},
|
},
|
||||||
|
@ -159,6 +169,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = Sony_Reset,
|
.reset = Sony_Reset,
|
||||||
.starttick = Sony_Update,
|
.starttick = Sony_Update,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -168,6 +179,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = Extn_Reset,
|
.reset = Extn_Reset,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -177,6 +189,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = m68k_reset,
|
.reset = m68k_reset,
|
||||||
.starttick = NULL,
|
.starttick = NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -186,6 +199,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = Mouse_Update,
|
.starttick = Mouse_Update,
|
||||||
.endtick = Mouse_EndTickNotify,
|
.endtick = Mouse_EndTickNotify,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -195,6 +209,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = EmClassicKbrd ? KeyBoard_Update : NULL,
|
.starttick = EmClassicKbrd ? KeyBoard_Update : NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -204,6 +219,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = EmADB ? ADB_Update : NULL,
|
.starttick = EmADB ? ADB_Update : NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -222,6 +238,7 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = EmVidCard ? Vid_Update : NULL,
|
.starttick = EmVidCard ? Vid_Update : NULL,
|
||||||
.endtick = NULL,
|
.endtick = NULL,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
@ -231,9 +248,30 @@ const DevMethods_t DEVICES[] = {
|
||||||
.reset = NULL,
|
.reset = NULL,
|
||||||
.starttick = Sixtieth_PulseNtfy, // VBlank interrupt
|
.starttick = Sixtieth_PulseNtfy, // VBlank interrupt
|
||||||
.endtick = Screen_EndTickNotify,
|
.endtick = Screen_EndTickNotify,
|
||||||
|
.subtick = NULL,
|
||||||
.timebegin = NULL,
|
.timebegin = NULL,
|
||||||
.timeend = NULL,
|
.timeend = NULL,
|
||||||
},
|
},
|
||||||
|
// ASC
|
||||||
|
{
|
||||||
|
.init = NULL,
|
||||||
|
.reset = NULL,
|
||||||
|
.starttick = NULL,
|
||||||
|
.endtick = NULL,
|
||||||
|
.subtick = EmASC ? ASC_SubTick : NULL,
|
||||||
|
.timebegin = NULL,
|
||||||
|
.timeend = NULL
|
||||||
|
},
|
||||||
|
// Sound (non-ASC)
|
||||||
|
{
|
||||||
|
.init = NULL,
|
||||||
|
.reset = NULL,
|
||||||
|
.starttick = NULL,
|
||||||
|
.endtick = NULL,
|
||||||
|
.subtick = (SoundEnabled && (CurEmMd != kEmMd_PB100)) ? MacSound_SubTick : NULL,
|
||||||
|
.timebegin = NULL,
|
||||||
|
.timeend = NULL
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
LOCALPROC EmulatedHardwareZap(void)
|
LOCALPROC EmulatedHardwareZap(void)
|
||||||
|
@ -252,11 +290,7 @@ LOCALPROC DoMacReset(void)
|
||||||
|
|
||||||
LOCALPROC InterruptReset_Update(void)
|
LOCALPROC InterruptReset_Update(void)
|
||||||
{
|
{
|
||||||
SetInterruptButton(false);
|
SetInterruptButton(false); // don't keep held over 1/60 sec
|
||||||
/*
|
|
||||||
in case has been set. so only stays set
|
|
||||||
for 60th of a second.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (WantMacInterrupt) {
|
if (WantMacInterrupt) {
|
||||||
SetInterruptButton(true);
|
SetInterruptButton(true);
|
||||||
|
@ -270,20 +304,10 @@ LOCALPROC InterruptReset_Update(void)
|
||||||
|
|
||||||
LOCALPROC SubTickNotify(int SubTick)
|
LOCALPROC SubTickNotify(int SubTick)
|
||||||
{
|
{
|
||||||
#if 0
|
int i;
|
||||||
dbglog_writeCStr("ending sub tick ");
|
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
||||||
dbglog_writeNum(SubTick);
|
if (DEVICES[i].subtick != NULL) { DEVICES[i].subtick(SubTick); }
|
||||||
dbglog_writeReturn();
|
}
|
||||||
#endif
|
|
||||||
#if EmASC
|
|
||||||
ASC_SubTick(SubTick);
|
|
||||||
#else
|
|
||||||
#if SoundEnabled && (CurEmMd != kEmMd_PB100)
|
|
||||||
MacSound_SubTick(SubTick);
|
|
||||||
#else
|
|
||||||
UnusedParam(SubTick);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CyclesScaledPerTick (130240UL * ClockMult * kCycleScale)
|
#define CyclesScaledPerTick (130240UL * ClockMult * kCycleScale)
|
||||||
|
@ -320,9 +344,7 @@ LOCALPROC SubTickTaskEnd(void)
|
||||||
LOCALPROC SixtiethSecondNotify(void)
|
LOCALPROC SixtiethSecondNotify(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
#if dbglog_HAVE && 0
|
// Begin new frame
|
||||||
dbglog_WriteNote("begin new Sixtieth");
|
|
||||||
#endif
|
|
||||||
InterruptReset_Update();
|
InterruptReset_Update();
|
||||||
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
||||||
if (DEVICES[i].starttick != NULL) { DEVICES[i].starttick(); }
|
if (DEVICES[i].starttick != NULL) { DEVICES[i].starttick(); }
|
||||||
|
@ -338,29 +360,23 @@ LOCALPROC SixtiethEndNotify(void)
|
||||||
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
||||||
if (DEVICES[i].endtick != NULL) { DEVICES[i].endtick(); }
|
if (DEVICES[i].endtick != NULL) { DEVICES[i].endtick(); }
|
||||||
}
|
}
|
||||||
#if dbglog_HAVE && 0
|
// End frame
|
||||||
dbglog_WriteNote("end Sixtieth");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCALPROC ExtraTimeBeginNotify(void)
|
LOCALPROC ExtraTimeBeginNotify(void)
|
||||||
{
|
{
|
||||||
#if 0
|
int i;
|
||||||
dbglog_writeCStr("begin extra time");
|
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
||||||
dbglog_writeReturn();
|
if (DEVICES[i].timebegin != NULL) { DEVICES[i].timebegin(); }
|
||||||
#endif
|
}
|
||||||
VIA1_ExtraTimeBegin();
|
|
||||||
if (_EmVIA2) { VIA2_ExtraTimeBegin(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCALPROC ExtraTimeEndNotify(void)
|
LOCALPROC ExtraTimeEndNotify(void)
|
||||||
{
|
{
|
||||||
VIA1_ExtraTimeEnd();
|
int i;
|
||||||
if (_EmVIA2) { VIA2_ExtraTimeEnd(); }
|
for ( i = 0; i < ARRAY_SIZE(DEVICES); i++ ) {
|
||||||
#if 0
|
if (DEVICES[i].timeend != NULL) { DEVICES[i].timeend(); }
|
||||||
dbglog_writeCStr("end extra time");
|
}
|
||||||
dbglog_writeReturn();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBALPROC EmulationReserveAlloc(void)
|
GLOBALPROC EmulationReserveAlloc(void)
|
||||||
|
@ -439,61 +455,35 @@ LOCALPROC ICT_DoTask(int taskid)
|
||||||
|
|
||||||
LOCALPROC ICT_DoCurrentTasks(void)
|
LOCALPROC ICT_DoCurrentTasks(void)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i;
|
||||||
uimr m = ICTactive;
|
uimr m;
|
||||||
|
|
||||||
while (0 != m) {
|
// For each ICT...
|
||||||
if (0 != (m & 1)) {
|
for (m = ICTactive, i = 0; m != 0; m >>=1, i += 1) {
|
||||||
if (i >= kNumICTs) {
|
// If no ICT here, continue
|
||||||
/* shouldn't happen */
|
if (0 == (m & 1)) { continue; }
|
||||||
ICTactive &= ((1 << kNumICTs) - 1);
|
if (ICTwhen[i] != NextiCount) { continue; }
|
||||||
m = 0;
|
|
||||||
} else if (ICTwhen[i] == NextiCount) {
|
|
||||||
ICTactive &= ~ (1 << i);
|
|
||||||
#ifdef _VIA_Debug
|
|
||||||
fprintf(stderr, "doing task %d, %d\n", NextiCount, i);
|
|
||||||
#endif
|
|
||||||
ICT_DoTask(i);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
A Task may set the time of
|
A Task may set the time of any task, including
|
||||||
any task, including itself.
|
itself. But it cannot set any task to execute
|
||||||
But it cannot set any task
|
immediately, so one pass is sufficient.
|
||||||
to execute immediately, so
|
*/
|
||||||
one pass is sufficient.
|
ICTactive &= ~(1 << i); // Clear active bit
|
||||||
*/
|
ICT_DoTask(i);
|
||||||
}
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
m >>= 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCALFUNC uint32_t ICT_DoGetNext(uint32_t maxn)
|
LOCALFUNC uint32_t ICT_DoGetNext(uint32_t maxn)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i;
|
||||||
uimr m = ICTactive;
|
uimr m;
|
||||||
uint32_t v = maxn;
|
uint32_t v = maxn;
|
||||||
|
|
||||||
while (0 != m) {
|
for (m = ICTactive, i = 0; m != 0; m >>=1, i += 1) {
|
||||||
if (0 != (m & 1)) {
|
uint32_t d = ICTwhen[i] - NextiCount;
|
||||||
if (i >= kNumICTs) {
|
if (0 == (m & 1)) { continue; }
|
||||||
/* shouldn't happen */
|
if (d < v) { v = d; }
|
||||||
m = 0;
|
|
||||||
} else {
|
|
||||||
uint32_t d = ICTwhen[i] - NextiCount;
|
|
||||||
/* at this point d must be > 0 */
|
|
||||||
if (d < v) {
|
|
||||||
#ifdef _VIA_Debug
|
|
||||||
fprintf(stderr, "coming task %d, %d, %d\n",
|
|
||||||
NextiCount, i, d);
|
|
||||||
#endif
|
|
||||||
v = d;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++i;
|
|
||||||
m >>= 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return v;
|
return v;
|
||||||
|
@ -506,16 +496,6 @@ LOCALPROC m68k_go_nCycles_1(uint32_t n)
|
||||||
do {
|
do {
|
||||||
ICT_DoCurrentTasks();
|
ICT_DoCurrentTasks();
|
||||||
n2 = ICT_DoGetNext(n);
|
n2 = ICT_DoGetNext(n);
|
||||||
#if dbglog_HAVE && 0
|
|
||||||
dbglog_StartLine();
|
|
||||||
dbglog_writeCStr("before m68k_go_nCycles, NextiCount:");
|
|
||||||
dbglog_writeHex(NextiCount);
|
|
||||||
dbglog_writeCStr(", n2:");
|
|
||||||
dbglog_writeHex(n2);
|
|
||||||
dbglog_writeCStr(", n:");
|
|
||||||
dbglog_writeHex(n);
|
|
||||||
dbglog_writeReturn();
|
|
||||||
#endif
|
|
||||||
NextiCount += n2;
|
NextiCount += n2;
|
||||||
m68k_go_nCycles(n2);
|
m68k_go_nCycles(n2);
|
||||||
n = StopiCount - NextiCount;
|
n = StopiCount - NextiCount;
|
||||||
|
@ -527,30 +507,21 @@ LOCALVAR uint32_t ExtraSubTicksToDo = 0;
|
||||||
LOCALPROC DoEmulateOneTick(void)
|
LOCALPROC DoEmulateOneTick(void)
|
||||||
{
|
{
|
||||||
#if EnableAutoSlow
|
#if EnableAutoSlow
|
||||||
{
|
uint32_t NewQuietTime = QuietTime + 1;
|
||||||
uint32_t NewQuietTime = QuietTime + 1;
|
uint32_t NewQuietSubTicks = QuietSubTicks + kNumSubTicks;
|
||||||
|
|
||||||
if (NewQuietTime > QuietTime) {
|
if (NewQuietTime > QuietTime) {
|
||||||
/* if not overflow */
|
/* if not overflow */
|
||||||
QuietTime = NewQuietTime;
|
QuietTime = NewQuietTime;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
if (NewQuietSubTicks > QuietSubTicks) {
|
||||||
#if EnableAutoSlow
|
/* if not overflow */
|
||||||
{
|
QuietSubTicks = NewQuietSubTicks;
|
||||||
uint32_t NewQuietSubTicks = QuietSubTicks + kNumSubTicks;
|
|
||||||
|
|
||||||
if (NewQuietSubTicks > QuietSubTicks) {
|
|
||||||
/* if not overflow */
|
|
||||||
QuietSubTicks = NewQuietSubTicks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SixtiethSecondNotify();
|
SixtiethSecondNotify();
|
||||||
|
|
||||||
m68k_go_nCycles_1(CyclesScaledPerTick);
|
m68k_go_nCycles_1(CyclesScaledPerTick);
|
||||||
|
|
||||||
SixtiethEndNotify();
|
SixtiethEndNotify();
|
||||||
|
|
||||||
if ((uint8_t) -1 == SpeedValue) {
|
if ((uint8_t) -1 == SpeedValue) {
|
||||||
|
@ -587,29 +558,22 @@ LOCALFUNC bool MoreSubTicksToDo(void)
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
DoEmulateExtraTime is used for anything over emulation speed of 1x. It
|
||||||
|
periodically calls ExtraTimeNotOver and stops when this returns false
|
||||||
|
(or it is finished with emulating the extra time).
|
||||||
|
*/
|
||||||
LOCALPROC DoEmulateExtraTime(void)
|
LOCALPROC DoEmulateExtraTime(void)
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
DoEmulateExtraTime is used for
|
|
||||||
anything over emulation speed
|
|
||||||
of 1x. It periodically calls
|
|
||||||
ExtraTimeNotOver and stops
|
|
||||||
when this returns false (or it
|
|
||||||
is finished with emulating the
|
|
||||||
extra time).
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (MoreSubTicksToDo()) {
|
if (MoreSubTicksToDo()) {
|
||||||
ExtraTimeBeginNotify();
|
ExtraTimeBeginNotify();
|
||||||
do {
|
do {
|
||||||
#if EnableAutoSlow
|
#if EnableAutoSlow
|
||||||
{
|
uint32_t NewQuietSubTicks = QuietSubTicks + 1;
|
||||||
uint32_t NewQuietSubTicks = QuietSubTicks + 1;
|
|
||||||
|
|
||||||
if (NewQuietSubTicks > QuietSubTicks) {
|
if (NewQuietSubTicks > QuietSubTicks) {
|
||||||
/* if not overflow */
|
/* if not overflow */
|
||||||
QuietSubTicks = NewQuietSubTicks;
|
QuietSubTicks = NewQuietSubTicks;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
m68k_go_nCycles_1(CyclesScaledPerSubTick);
|
m68k_go_nCycles_1(CyclesScaledPerSubTick);
|
||||||
|
@ -619,85 +583,66 @@ LOCALPROC DoEmulateExtraTime(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
The number of ticks that have been emulated so far.
|
||||||
|
That is, the number of times "DoEmulateOneTick" has been called.
|
||||||
|
*/
|
||||||
LOCALVAR uint32_t CurEmulatedTime = 0;
|
LOCALVAR uint32_t CurEmulatedTime = 0;
|
||||||
/*
|
|
||||||
The number of ticks that have been
|
|
||||||
emulated so far.
|
|
||||||
|
|
||||||
That is, the number of times
|
/*
|
||||||
"DoEmulateOneTick" has been called.
|
The general idea is to call DoEmulateOneTick once per tick.
|
||||||
*/
|
|
||||||
|
|
||||||
|
But if emulation is lagging, we'll try to catch up by calling
|
||||||
|
DoEmulateOneTick multiple times, unless we're too far behind, in
|
||||||
|
which case we forget it.
|
||||||
|
|
||||||
|
If emulating one tick takes longer than a tick we don't want to sit
|
||||||
|
here forever. So the maximum number of calls to DoEmulateOneTick is
|
||||||
|
determined at the beginning, rather than just calling DoEmulateOneTick
|
||||||
|
until CurEmulatedTime >= TrueEmulatedTime.
|
||||||
|
*/
|
||||||
LOCALPROC RunEmulatedTicksToTrueTime(void)
|
LOCALPROC RunEmulatedTicksToTrueTime(void)
|
||||||
{
|
{
|
||||||
/*
|
int8_t lag = OnTrueTime - CurEmulatedTime;
|
||||||
The general idea is to call DoEmulateOneTick
|
|
||||||
once per tick.
|
|
||||||
|
|
||||||
But if emulation is lagging, we'll try to
|
if (lag > 0) {
|
||||||
catch up by calling DoEmulateOneTick multiple
|
|
||||||
times, unless we're too far behind, in
|
|
||||||
which case we forget it.
|
|
||||||
|
|
||||||
If emulating one tick takes longer than
|
|
||||||
a tick we don't want to sit here
|
|
||||||
forever. So the maximum number of calls
|
|
||||||
to DoEmulateOneTick is determined at
|
|
||||||
the beginning, rather than just
|
|
||||||
calling DoEmulateOneTick until
|
|
||||||
CurEmulatedTime >= TrueEmulatedTime.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int8_t n = OnTrueTime - CurEmulatedTime;
|
|
||||||
|
|
||||||
if (n > 0) {
|
|
||||||
DoEmulateOneTick();
|
DoEmulateOneTick();
|
||||||
++CurEmulatedTime;
|
CurEmulatedTime += 1;
|
||||||
|
|
||||||
DoneWithDrawingForTick();
|
DoneWithDrawingForTick();
|
||||||
|
|
||||||
if (n > 8) {
|
if (lag > 8) {
|
||||||
/* emulation not fast enough */
|
/* emulation not fast enough */
|
||||||
n = 8;
|
lag = 8;
|
||||||
CurEmulatedTime = OnTrueTime - n;
|
CurEmulatedTime = OnTrueTime - lag;
|
||||||
|
} else {
|
||||||
|
lag -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ExtraTimeNotOver() && (--n > 0)) {
|
while (ExtraTimeNotOver() && (lag > 0)) {
|
||||||
/* lagging, catch up */
|
/* Missed vblank due to lag; catch up */
|
||||||
|
|
||||||
EmVideoDisable = true;
|
EmVideoDisable = true;
|
||||||
|
DoEmulateOneTick();
|
||||||
do {
|
CurEmulatedTime += 1;
|
||||||
DoEmulateOneTick();
|
lag -= 1;
|
||||||
++CurEmulatedTime;
|
|
||||||
} while (ExtraTimeNotOver()
|
|
||||||
&& (--n > 0));
|
|
||||||
|
|
||||||
EmVideoDisable = false;
|
EmVideoDisable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
EmLagTime = n;
|
EmLagTime = lag;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOCALPROC MainEventLoop(void)
|
LOCALPROC MainEventLoop(void)
|
||||||
{
|
{
|
||||||
for (; ; ) {
|
while (true) {
|
||||||
WaitForNextTick();
|
WaitForNextTick();
|
||||||
if (ForceMacOff) {
|
if (ForceMacOff) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RunEmulatedTicksToTrueTime();
|
RunEmulatedTicksToTrueTime();
|
||||||
|
|
||||||
DoEmulateExtraTime();
|
DoEmulateExtraTime();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GLOBALPROC ProgramMain(void)
|
GLOBALPROC ProgramMain(void)
|
||||||
{
|
{
|
||||||
if (InitEmulation())
|
if (InitEmulation() == false) {return;}
|
||||||
{
|
MainEventLoop();
|
||||||
MainEventLoop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user