-
Notifications
You must be signed in to change notification settings - Fork 1
/
vdp_waitvint.c
51 lines (41 loc) · 1.57 KB
/
vdp_waitvint.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include "vdp.h"
unsigned char gSaveIntCnt; // console interrupt count byte
// returns non-zero if interrupt already fired (ie: we are late)
unsigned char vdpwaitvint() {
unsigned char ret = 0;
// wait for a vertical interrupt to occur (enables interrupts - first call may not wait)
// to avoid a race on the return condition, we reproduce VDP_INT_ENABLE here
// check if we missed one first
if (vdpLimi&0x80) {
vdpLimi = 0;
my_nmi();
ret = 1;
}
// wait for the interrupt to run (if we missed it, it ran already and this won't wait)
if (!ret) {
// set the enable flag
__asm__("\tpush hl\n\tld hl,#_vdpLimi\n\tset 0,(hl)\n\tpop hl");
// this countdown should be unnecessary. But if the user has
// messed with the interrupt flags or status register, or
// just a simple emulator bug like Classic99 seems to have,
// then continue anyway rather than hanging. My math is weird,
// so I'm just testing against emulation and then adding 100% fudge
unsigned int cnt = 2048; // 1024 seemed to be enough for SSA, so double that
while (VDP_INT_COUNTER == gSaveIntCnt) {
if (--cnt == 0) {
// we're stuck - clear the VDP and exit
// TODO: maybe we should make a debug version of this that includes the screen
// color change so users can tell if something is wrong and it's not just running slow
//VDP_SET_REGISTER(7,3);
VDP_STATUS_MIRROR = VDPST;
break;
}
}
// turn the interrupt flag back off
VDP_INT_DISABLE;
}
// remember the new value
gSaveIntCnt=VDP_INT_COUNTER;
// back to caller
return ret;
}