mirror of https://github.com/nmlgc/ReC98.git
[Platform] [PC-98] VSync: Retrigger the VSync interrupt after INT 18h
Well, that didn't take long. Unlike *debugging* this issue after you encounter it on real hardware… Part of P0232, funded by [Anonymous].
This commit is contained in:
parent
df0672762b
commit
f1108b5548
|
@ -6,6 +6,7 @@
|
||||||
volatile uint16_t vsync_count_16;
|
volatile uint16_t vsync_count_16;
|
||||||
volatile uint32_t vsync_count_32;
|
volatile uint32_t vsync_count_32;
|
||||||
static void interrupt (*vsync_callback_old)(...);
|
static void interrupt (*vsync_callback_old)(...);
|
||||||
|
static void interrupt (*int18h)(...);
|
||||||
bool vsync_active;
|
bool vsync_active;
|
||||||
|
|
||||||
static void interrupt vsync_intfunc(...)
|
static void interrupt vsync_intfunc(...)
|
||||||
|
@ -16,14 +17,30 @@ static void interrupt vsync_intfunc(...)
|
||||||
_outportb_(0x64, _AL); // VSync interrupt trigger
|
_outportb_(0x64, _AL); // VSync interrupt trigger
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some real-hardware BIOS implementations of certain INT 18h functions (in
|
||||||
|
// particular the gaiji upload function, AH=14h) seem to return with the VSync
|
||||||
|
// interrupt trigger disabled, causing any successive delay loop based on our
|
||||||
|
// VSync counters to deadlock. This is quite awful to debug, especially because
|
||||||
|
// no emulator replicates this nuisance, as of February 2023...
|
||||||
|
// This workaround of retriggering INT 0Ah ourselves, was taken from
|
||||||
|
// master.lib's VSYNC.ASM, and the CRTBIOS_COOK handler in particular.
|
||||||
|
static void interrupt vsync_retrigger_after_int18h(...)
|
||||||
|
{
|
||||||
|
int18h();
|
||||||
|
_outportb_(0x64, _AL); // VSync interrupt trigger
|
||||||
|
}
|
||||||
|
|
||||||
void __cdecl vsync_init(void)
|
void __cdecl vsync_init(void)
|
||||||
{
|
{
|
||||||
if(vsync_active) {
|
if(vsync_active) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
disable();
|
disable();
|
||||||
|
|
||||||
vsync_callback_old = getvect(0x0A);
|
vsync_callback_old = getvect(0x0A);
|
||||||
|
int18h = getvect(0x18);
|
||||||
setvect(0x0A, vsync_intfunc);
|
setvect(0x0A, vsync_intfunc);
|
||||||
|
setvect(0x18, vsync_retrigger_after_int18h);
|
||||||
|
|
||||||
// Disable all interrupts from 0x08 to 0x0F except for 0x0A
|
// Disable all interrupts from 0x08 to 0x0F except for 0x0A
|
||||||
_outportb_(0x02, (_inportb_(0x02) & 0xFB));
|
_outportb_(0x02, (_inportb_(0x02) & 0xFB));
|
||||||
|
@ -45,6 +62,7 @@ void __cdecl vsync_exit(void)
|
||||||
_outportb_(0x02, (_inportb_(0x02) | 0x04));
|
_outportb_(0x02, (_inportb_(0x02) | 0x04));
|
||||||
|
|
||||||
setvect(0x0A, vsync_callback_old);
|
setvect(0x0A, vsync_callback_old);
|
||||||
|
setvect(0x18, int18h);
|
||||||
enable();
|
enable();
|
||||||
vsync_active = false;
|
vsync_active = false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue