viti95 / FastDoom

Doom port for DOS, optimized to be as fast as possible!
527 stars 33 forks source link

keep memory FLAT(SS=DS) during interrupt for DPMI mode. #178

Closed crazii closed 9 months ago

crazii commented 9 months ago

A DOS protected mode program uses FLAT model (CS=DS=SS=ES) like a win32 one, but it's not always true when in interrupts when a DPMI host is used, as the DPMI spec requires a Locked Protected Mode Stack (LPMS) for DPMI client interrupt handling.

DOS32A will provide a good stack segment(SS=DS) for interrupts when it gains full control of protected mode interfaces (i.e. entered PM from real mode or via VCPI), but it doesn't do that for DPMI mode. That's probably why it prefers VCPI over DPMI when both are available.

OpenWatcom may use EBP as a base register to access DGROUP data, when some conditions are met (few function parameters so they are passed by registers and local variables are optimized out using GPRs so that a function stack frame isn't needed). Normally this is OK, since [EBP] equals SS:[EBP] and equals DS:[EBP] for FLAT model, but will be problematic in interrupt handler when a DPMI host is used.

The best way to solve that is to add an extra wrapper to DOS32A to switch stack for interrupt handlers for DPMI mode, like the _go32 api for DJGPP. But I'm not ready to touch dos32a yet for now, so the current method is used.

There might be other workarounds, i.e. force establishing a stack frame for specific functions, using #pragma aux somefunction __frame; so that EBP is forced as a stack frame base. but it's much less convenient because the calling trees are complicated, every function that get called directly/indirectly from a interrupt handler will need that.

I guess FastDoom doesn't like win9x for the same reason, but it will (or get more close to) be better now.

Other interrupt handlers might also needs this, including the DPMI real mode callbacks functions, but currently there's no case of using EBP so they're safe for now.

viti95 commented 9 months ago

I've tested this on emulators and my "SBEMU" laptop, and seems to be working fine. I'll try asap on older 386/486 and if it runs ok I'll merge this PR. Thanks!!

viti95 commented 9 months ago

Checked on older hardware, everything is working fine! Huge thanks!

crazii commented 9 months ago

No problem. I tested FastDoom with SBEMU on my laptop and it works, but I didn't test it with real HW, glad it works too. I'm glad that both of them work together.