From d6e983b08da60e90c434da6d8efadbc2f1fcc932 Mon Sep 17 00:00:00 2001 From: ripsaw8080 Date: Mon, 1 May 2017 15:32:29 +0000 Subject: [PATCH] Handle errant IRQs as a real BIOS does. Fixes Tandy DAC in Chuck Yeager's Air Combat. Also remove r3263 workaround, as it's no longer needed. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@4009 --- include/bios.h | 1 + src/cpu/callback.cpp | 5 +---- src/ints/bios.cpp | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/bios.h b/include/bios.h index 4915a52a..08c8fc43 100644 --- a/include/bios.h +++ b/include/bios.h @@ -61,6 +61,7 @@ #define BIOS_VDU_CONTROL 0x465 #define BIOS_VDU_COLOR_REGISTER 0x466 /* 0x467-0x468 is reserved */ +#define BIOS_LAST_UNEXPECTED_IRQ 0x46b #define BIOS_TIMER 0x46c #define BIOS_24_HOURS_FLAG 0x470 #define BIOS_KEYBOARD_FLAGS 0x471 diff --git a/src/cpu/callback.cpp b/src/cpu/callback.cpp index 609db80b..e1e3d949 100644 --- a/src/cpu/callback.cpp +++ b/src/cpu/callback.cpp @@ -33,7 +33,7 @@ CallBack_Handler CallBack_Handlers[CB_MAX]; char* CallBack_Description[CB_MAX]; -static Bitu call_stop,call_idle,call_default,call_default2; +static Bitu call_stop,call_idle,call_default; Bitu call_priv_io; static Bitu illegal_handler(void) { @@ -575,8 +575,6 @@ void CALLBACK_Init(Section* /*sec*/) { /* Default handlers for unhandled interrupts that have to be non-null */ call_default=CALLBACK_Allocate(); CALLBACK_Setup(call_default,&default_handler,CB_IRET,"default"); - call_default2=CALLBACK_Allocate(); - CALLBACK_Setup(call_default2,&default_handler,CB_IRET,"default"); /* Only setup default handler for first part of interrupt table */ for (Bit16u ct=0;ct<0x60;ct++) { @@ -597,7 +595,6 @@ void CALLBACK_Init(Section* /*sec*/) { } // setup a few interrupt handlers that point to bios IRETs by default - real_writed(0,0x0e*4,CALLBACK_RealPointer(call_default2)); //design your own railroad real_writed(0,0x66*4,CALLBACK_RealPointer(call_default)); //war2d real_writed(0,0x67*4,CALLBACK_RealPointer(call_default)); real_writed(0,0x68*4,CALLBACK_RealPointer(call_default)); diff --git a/src/ints/bios.cpp b/src/ints/bios.cpp index 40d6ce9e..2cf70a54 100644 --- a/src/ints/bios.cpp +++ b/src/ints/bios.cpp @@ -963,6 +963,28 @@ static Bitu INT15_Handler(void) { return CBRET_NONE; } +static Bitu Default_IRQ_Handler(void) { + IO_WriteB(0x20,0x0b); + Bit8u master_isr=IO_ReadB(0x20); + if (master_isr) { + IO_WriteB(0xa0,0x0b); + Bit8u slave_isr=IO_ReadB(0xa0); + if (slave_isr) { + IO_WriteB(0xa1,IO_ReadB(0xa1)|slave_isr); + IO_WriteB(0xa0,0x20); + } else IO_WriteB(0x21,IO_ReadB(0x21)|(master_isr&~4)); + IO_WriteB(0x20,0x20); +#if C_DEBUG + Bit16u irq=0,isr=master_isr; + if (slave_isr) isr=slave_isr<<8; + while (isr>>=1) irq++; + LOG(LOG_BIOS,LOG_WARN)("Unexpected IRQ %u",irq); +#endif + } else master_isr=0xff; + mem_writeb(BIOS_LAST_UNEXPECTED_IRQ,master_isr); + return CBRET_NONE; +} + static Bitu Reboot_Handler(void) { // switch to text mode, notify user (let's hope INT10 still works) const char* const text = "\n\n Reboot requested, quitting now."; @@ -1099,6 +1121,16 @@ public: CALLBACK_Setup(call_irq2,NULL,CB_IRET_EOI_PIC1,Real2Phys(BIOS_DEFAULT_IRQ2_LOCATION),"irq 2 bios"); RealSetVec(0x0a,BIOS_DEFAULT_IRQ2_LOCATION); + /* Default IRQ handler */ + Bitu call_irq_default=CALLBACK_Allocate(); + CALLBACK_Setup(call_irq_default,&Default_IRQ_Handler,CB_IRET,"irq default"); + RealSetVec(0x0b,CALLBACK_RealPointer(call_irq_default)); // IRQ 3 + RealSetVec(0x0c,CALLBACK_RealPointer(call_irq_default)); // IRQ 4 + RealSetVec(0x0d,CALLBACK_RealPointer(call_irq_default)); // IRQ 5 + RealSetVec(0x0f,CALLBACK_RealPointer(call_irq_default)); // IRQ 7 + RealSetVec(0x72,CALLBACK_RealPointer(call_irq_default)); // IRQ 10 + RealSetVec(0x73,CALLBACK_RealPointer(call_irq_default)); // IRQ 11 + // INT 05h: Print Screen // IRQ1 handler calls it when PrtSc key is pressed; does nothing unless hooked phys_writeb(Real2Phys(BIOS_DEFAULT_INT5_LOCATION),0xcf);