Skip to content

Commit

Permalink
BIOS CMOS date/time interrupt calls now CPU idle in order for CPU tim…
Browse files Browse the repository at this point in the history
…e and RTC clock ticks to proceed normally, which fixes Pizza Tycoon [#4502]
  • Loading branch information
joncampbell123 committed Oct 6, 2023
1 parent 4784529 commit 54e5646
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ Next version:
shortcut triggers execution to stop whether in RUN or RUNWATCH mode.
- Fix SETCOLORS command didn't change color when output=ttf.(Issue #4503)
Also fixed the values reported were wrong. (maron2000)
- BIOS CMOS date/time functions will now idle the CPU 4 times after reading
or setting the clock to allow interrupts, CPU time, and RTC clock ticks
to proceed normally. This fixes "Pizza Tycoon" and allows it to continue
past the initial logo. (joncampbell123)

2023.09.01
- Disable by default message confirmation after snapshot and AVI video
Expand Down
42 changes: 31 additions & 11 deletions src/ints/bios.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2631,16 +2631,26 @@ static Bitu INT1A_Handler(void) {
reg_cl = ReadCmosByte(0x02); // minutes
reg_dh = ReadCmosByte(0x00); // seconds
reg_dl = ReadCmosByte(0x0b) & 0x01; // daylight saving time
/* 2023/10/06 - Let interrupts and CPU cycles catch up and the RTC clock a chance to tick. This is needed for
* "Pizza Tycoon" which appears to start by running in a loop reading time from the BIOS and writing
* time to INT 21h in a loop until the second value changes. */
for (unsigned int c=0;c < 4;c++) CALLBACK_Idle();
}
CALLBACK_SCF(false);
break;
case 0x03: // set RTC time
InitRtc(); // make sure BCD and no am/pm
WriteCmosByte(0x0b, ReadCmosByte(0x0b) | 0x80u); // prohibit updates
WriteCmosByte(0x04, reg_ch); // hours
WriteCmosByte(0x02, reg_cl); // minutes
WriteCmosByte(0x00, reg_dh); // seconds
WriteCmosByte(0x0b, (ReadCmosByte(0x0b) & 0x7eu) | (reg_dh & 0x01u)); // dst + implicitly allow updates
if (RtcUpdateDone()) { // make sure it's safe to read
WriteCmosByte(0x0b, ReadCmosByte(0x0b) | 0x80u); // prohibit updates
WriteCmosByte(0x04, reg_ch); // hours
WriteCmosByte(0x02, reg_cl); // minutes
WriteCmosByte(0x00, reg_dh); // seconds
WriteCmosByte(0x0b, (ReadCmosByte(0x0b) & 0x7eu) | (reg_dh & 0x01u)); // dst + implicitly allow updates
/* 2023/10/06 - Let interrupts and CPU cycles catch up and the RTC clock a chance to tick. This is needed for
* "Pizza Tycoon" which appears to start by running in a loop reading time from the BIOS and writing
* time to INT 21h in a loop until the second value changes. */
for (unsigned int c=0;c < 4;c++) CALLBACK_Idle();
}
break;
case 0x04: /* GET REAL-TIME ClOCK DATE (AT,XT286,PS) */
InitRtc(); // make sure BCD and no am/pm
Expand All @@ -2649,17 +2659,27 @@ static Bitu INT1A_Handler(void) {
reg_cl = ReadCmosByte(0x09); // year
reg_dh = ReadCmosByte(0x08); // month
reg_dl = ReadCmosByte(0x07); // day
/* 2023/10/06 - Let interrupts and CPU cycles catch up and the RTC clock a chance to tick. This is needed for
* "Pizza Tycoon" which appears to start by running in a loop reading time from the BIOS and writing
* time to INT 21h in a loop until the second value changes. */
for (unsigned int c=0;c < 4;c++) CALLBACK_Idle();
}
CALLBACK_SCF(false);
break;
case 0x05: // set RTC date
InitRtc(); // make sure BCD and no am/pm
WriteCmosByte(0x0b, ReadCmosByte(0x0b) | 0x80); // prohibit updates
WriteCmosByte(0x32, reg_ch); // century
WriteCmosByte(0x09, reg_cl); // year
WriteCmosByte(0x08, reg_dh); // month
WriteCmosByte(0x07, reg_dl); // day
WriteCmosByte(0x0b, (ReadCmosByte(0x0b) & 0x7f)); // allow updates
if (RtcUpdateDone()) { // make sure it's safe to read
WriteCmosByte(0x0b, ReadCmosByte(0x0b) | 0x80); // prohibit updates
WriteCmosByte(0x32, reg_ch); // century
WriteCmosByte(0x09, reg_cl); // year
WriteCmosByte(0x08, reg_dh); // month
WriteCmosByte(0x07, reg_dl); // day
WriteCmosByte(0x0b, (ReadCmosByte(0x0b) & 0x7f)); // allow updates
/* 2023/10/06 - Let interrupts and CPU cycles catch up and the RTC clock a chance to tick. This is needed for
* "Pizza Tycoon" which appears to start by running in a loop reading time from the BIOS and writing
* time to INT 21h in a loop until the second value changes. */
for (unsigned int c=0;c < 4;c++) CALLBACK_Idle();
}
break;
case 0x80: /* Pcjr Setup Sound Multiplexer */
LOG(LOG_BIOS,LOG_ERROR)("INT1A:80:Setup tandy sound multiplexer to %d",reg_al);
Expand Down

0 comments on commit 54e5646

Please sign in to comment.