Skip to content
Snippets Groups Projects
Commit ee45c14b authored by Rob Swindell's avatar Rob Swindell :speech_balloon:
Browse files

Fix (loss of) carrier detect reporting in Virtual UART driver

So Hobo and I have noticed that Global War was leaving game lock (*.LOK) files behind when he disconnected while in the game (e.g. due to the game not responding or something). 
This was happening because GWAR was not recognizing the loss of connection ("carrier detect" or DCD) and SBBS would ungracefully terminate the process after 5 seconds of being disconnected, thus the game lock files would remain and requiring manual clean-up.

I discovered that if I changed the WAR.CFG file to use FOSSIL instead of UART, Global War would then correctly recognize the loss of carrier and exit gracefully (and not leave any .LOK files behind). So... I suspected an issue with the Virtual UART driver. It turns out, that a program that relies on the modem status register change interrupt (and doesn't "poll" the UART MSR register) might never know that the "carrier" was lost. This is fixed by waiting on the hungup_event in the interrupt_thread and deasserting DCD in the "virtual" MSR register and asserting the MSR change interrupt to notify the program that it has in fact changed. Good thing for WaitForMultipleObjects(). Uh huh.
parent 4bd6f5f6
No related branches found
No related tags found
No related merge requests found
......@@ -192,8 +192,17 @@ void set_interrupt_pending(BYTE intr, BOOL assert)
void _cdecl interrupt_thread(void *arg)
{
HANDLE handles[] = {interrupt_event, hungup_event};
while(1) {
if(WaitForSingleObject(interrupt_event,INFINITE)!=WAIT_OBJECT_0)
DWORD handle_count = (uart_msr_reg & UART_MSR_DCD) ? 2 : 1;
DWORD result = WaitForMultipleObjects(handle_count, handles, /* waitAll */FALSE, INFINITE);
if(result == WAIT_OBJECT_0 + 1) {
lprintf(LOG_DEBUG, "Hangup detected in " __FUNCTION__);
uart_msr_reg &=~ UART_MSR_DCD;
assert_interrupt(UART_IER_MODEM_STATUS);
continue;
}
if(result != WAIT_OBJECT_0)
break;
if((uart_ier_reg&pending_interrupts) != 0) {
lprintf(LOG_DEBUG,"VDDSimulateInterrupt (pending: %02X) - IER: %02X"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment