Okay, here's the second attempt at a patch for the midnight rollover problem.
See my previous post for details on what it does.
The problem was that if a program read the time at exactly midnight, as a
BBS might as part of it's busy loop, it could return a negative tick value,
crashing the program or the entire emulator.
It now checks to make sure the return value is valid, in case the clock has
slipped a tick or two, and there are less than 1573040 ticks per day.
Both BBSes I run under dosemu survived the midnight rollover with this patch
tonight, so I think it works.
If someone actually tries this, please let me know if it works for them.
This is against 0.98.4... I imagine it should work on the 0.99 series, unless
the software interrupts have been completely rewritten.
diff -urN dosemu-0.98.4/src/base/async/int.c local-dosemu-0.98.4/src/base/async/int.c
--- dosemu-0.98.4/src/base/async/int.c Mon Nov 9 14:06:14 1998
+++ local-dosemu-0.98.4/src/base/async/int.c Sat Jan 2 18:40:28 1999
@@ -791,25 +791,31 @@
IBM and many clone BIOSes set the flag for AL rather than incrementing
it, leading to loss of a day if two consecutive midnights pass
without a request for the time (e.g. if the system is on but idle)
+ This appears to be irrelevant, because int8 sets the overflow flag,
+ so it can never be more than one here.
-> since the midnight flag is cleared, if an application calls this
-> function after midnight before DOS does, DOS will not receive the
-> midnight flag and will fail to advance the date
*/
case 0: /* read time counter */
+
+ /* has the midnight passed? Check and adjust offset. TICK_OVERFLOW_ADDR is set
+in int8. */
+ if (*(u_char *) TICK_OVERFLOW_ADDR) {
+ g_printf("TIMER: midnight overflow - adjusting offset.\n");
+ usr_delta_ticks -= 1573040; /* Adjust time base delta by a day. */
+ }
+
+ last_ticks = sys_base_ticks + usr_delta_ticks + (pic_sys_time >> 16);
/* it works because pic_sys_time has a zero reference. It doesn't
* account for timer speedups, but any decent DOS program should
* call back the original int8 at the 18.2 Hz rate... */
- last_ticks = sys_base_ticks + usr_delta_ticks + (pic_sys_time >> 16);
- /* has the midnight passed? */
- if (last_ticks > 1573040) {
- *(u_char *) (TICK_OVERFLOW_ADDR) += 0x1;
- last_ticks -= 1573040;
- }
+ if(last_ticks < 0) last_ticks = 0; /* Make sure return value is valid */
+
LO(ax) = *(u_char *) (TICK_OVERFLOW_ADDR);
LWORD(ecx) = (last_ticks >> 16) & 0xffff;
LWORD(edx) = last_ticks & 0xffff;
- g_printf("TIMER: read timer = %lu\n", last_ticks);
+ g_printf("TIMER: read timer = %lu overflow = %d\n", last_ticks, *(u_char
+*)TICK_OVERFLOW_ADDR);
set_ticks(last_ticks); /* set_ticks is in rtc.c */
break;
--
/// Stefan Hudson <[EMAIL PROTECTED]>
__ /// Senior Network Administrator - Monterey Bay Internet
\\\/// http://www.mbay.net/ - Email: [EMAIL PROTECTED]
\XX/ Voice: 831-642-6100 Fax: 831-642-6101 Modem: 831-642-6102