Merge pull request #3985 from finalpatch/lf/idle

Support DPMI idle (INT 2FH Function 1680H) and DOS idle (INT 28H)
This commit is contained in:
Jonathan Campbell
2023-02-06 20:46:17 -08:00
committed by GitHub
6 changed files with 45 additions and 7 deletions

View File

@@ -27,7 +27,7 @@ extern CallBack_Handler CallBack_Handlers[];
enum { CB_RETN,CB_RETF,CB_RETF8,CB_IRET,CB_IRETD,CB_IRET_STI,CB_IRET_EOI_PIC1,
CB_IRQ0,CB_IRQ1,CB_IRQ1_BREAK,CB_IRQ9,CB_IRQ12,CB_IRQ12_RET,CB_MOUSE,
/*CB_INT28,*/CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET,
CB_INT28,CB_INT29,CB_INT16,CB_HOOKABLE,CB_TDE_IRET,CB_IPXESR,CB_IPXESR_RET,
CB_INT21,CB_INT13,CB_VESA_WAIT,CB_VESA_PM,CB_IRET_EOI_PIC2,CB_CPM,
CB_RETF_STI,CB_RETF_CLI,CB_INT6F_ATOK};

View File

@@ -569,11 +569,11 @@ Bitu CALLBACK_SetupExtra(Bitu callback, Bitu type, PhysPt physAddress, bool use_
for (uint8_t i=0;i<=0x0b;i++) phys_writeb(physAddress+0x02+i,0x90);
phys_writew(physAddress+0x0e,(uint16_t)0xedeb); //jmp callback
return (use_cb?0x10:0x0c);
/*case CB_INT28: // DOS idle
case CB_INT28: // DOS idle
phys_writeb(physAddress+0x00,(uint8_t)0xFB); // STI
phys_writeb(physAddress+0x01,(uint8_t)0xF4); // HLT
phys_writeb(physAddress+0x02,(uint8_t)0xcf); // An IRET Instruction
return (0x04);*/
return (0x04);
case CB_INT29: // fast console output
if (IS_PC98_ARCH) LOG_MSG("WARNING: CB_INT29 callback setup not appropriate for PC-98 mode (INT 10h no longer BIOS call)");
if (use_cb) {

View File

@@ -721,7 +721,29 @@ bool device_CON::Read(uint8_t * data,uint16_t * size) {
continue;
}
reg_ah=(IS_EGAVGA_ARCH)?0x10:0x0;
const uint8_t int16_poll_function=(IS_EGAVGA_ARCH)?0x11:0x1;
const uint8_t int16_read_function=(IS_EGAVGA_ARCH)?0x10:0x0;
static const bool idle_enabled = ((Section_prop*)control->GetSection("dos"))->Get_bool("dos idle api");
if (idle_enabled) {
// Poll the keyboard until there is a key-press ready to read. If there
// is no input (ZF=0) then call INT 28h to release the rest of our
// timeslice to host system.
while (true) {
reg_ah=int16_poll_function;
if (IS_PC98_ARCH)
INT16_Handler_Wrap();
else
CALLBACK_RunRealInt(0x16);
if (GETFLAG(ZF) == 0) {
break;
} else {
CALLBACK_RunRealInt(0x28);
}
}
}
reg_ah=int16_read_function;
/* FIXME: PC-98 emulation should eventually use CONIO emulation that
* better emulates the actual platform. The purpose of this

View File

@@ -4262,7 +4262,11 @@ public:
callback[4].Install(DOS_27Handler,CB_IRET,"DOS Int 27");
callback[4].Set_RealVec(0x27);
callback[5].Install(NULL,CB_IRET/*CB_INT28*/,"DOS idle");
if (section->Get_bool("dos idle api")) {
callback[5].Install(NULL,CB_INT28,"DOS idle");
} else {
callback[5].Install(NULL,CB_IRET,"DOS idle");
}
callback[5].Set_RealVec(0x28);
if (IS_PC98_ARCH) {

View File

@@ -25,6 +25,7 @@
#include "dos_inc.h"
#include "control.h"
#include "support.h"
#include "cpu.h"
#include <array>
#include <cstring>
@@ -396,8 +397,15 @@ static bool DOS_MultiplexFunctions(void) {
return false;
}
case 0x1680: /* RELEASE CURRENT VIRTUAL MACHINE TIME-SLICE */
//TODO Maybe do some idling but could screw up other systems :)
return true; //So no warning in the debugger anymore
{
static const bool idle_enabled = ((Section_prop*)control->GetSection("dos"))->Get_bool("dos idle api");
if (idle_enabled) {
CPU_STI();
CPU_HLT(reg_eip);
reg_al = 0;
}
return true;
}
case 0x1689: /* Kernel IDLE CALL */
case 0x168f: /* Close awareness crap */
/* Removing warning */

View File

@@ -4503,6 +4503,10 @@ void DOSBOX_SetupConfigSections(void) {
Pbool->Set_help("If set, DOS APIs for communications with the Windows clipboard will be enabled for shared clipboard communications.");
Pbool->SetBasic(true);
Pbool = secprop->Add_bool("dos idle api",Property::Changeable::OnlyAtStart,true);
Pbool->Set_help("If set, DOSBox-X can lower the host system's CPU load when a supported guest program is idle.");
Pbool->SetBasic(true);
secprop=control->AddSection_prop("ipx",&Null_Init,true);
Pbool = secprop->Add_bool("ipx",Property::Changeable::WhenIdle, false);
Pbool->Set_help("Enable ipx over UDP/IP emulation.");