Closed ytrezq closed 5 years ago
Of course, you can modify the LDT, like it is also done in V86 mode, but that doesn't help you in any way. There is no V86 in long mode and therefore, you cannot trap IN/OUT/INT calls (and other privileged instructions). So I don't get what you want here.
The only thing you can try is to use VT-x. I did an NTVDM implementation with HAXM (https://github.com/intel/haxm), but it doesn't really help you, as on every call to emulated hardware (like i.e. VGA), you trap a VM exit, have to go back to usermode to emulate the adapter, and then enter VT-x mode again. Same goes for BOPs (there are quite a lot of it on NTVDM). This is so slow that it isn't benificial at all and slows down the performance to a crawl (at least concerining output), so due to the amount of these calls, you are better off with the emulated CPU (as you don't have these very expensive mode transitions). If you are interested, i can share my HAXM code, which at least works in real mode and in text mode only (with some optimizations i.e. loop unrolling, reversed framebuffer copy). You can use it as a starting point if you want to go this route and optimize it. If you want to work on it, let me know.
PS: NTVDM on x86 didn't support graphics mode in windowed state for a reason...
@leecher1337 No. my point is doing it like on 64 bits Linux. That is, without the vm86 mode. Please see https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/arch/x86/Kconfig#n1212 : This option is required by programs like Wine to run 16‑bit protected mode legacy code on x86 processors.
They also clearly state it : The vm86 option is unrelated to 16-bit protected mode and is not needed to run most 16-bit programs under Wine
Though this restricts to programs that can run under protected mode (most 16 bits installers). This approach can be lighter at run time than Vt-X.
The problem with Intel Haxm is it prevents running Hyper‑V and breaks compatibility with bash on Windows thus preventing to run Linux binaries at the same time (and also requires hard reboot to enable).
But DOS is real mode, what's your point? And this project is NOT about running WIN16 programs, use WineVDM for it. This is about running DOS programs.
@leecher1337 Sine Ntvdm is used for 16‑bits Windows, I just thought you were planning to add the feature one day.
There are few programs that were able to perform above 640Kb addressing and were using https://en.wikipedia.org/wiki/DOS_Protected_Mode_Interface designed before the vm86 feature exists (allowing protected mode on 80286 for the first versions). Wine on Linux also uses this (hence the term most 16‑bits programs but not all
in Kconfig).
You’d be surprised with the number of ᴅᴏꜱ programs that can runs in 80286 protected mode even without being written for a specific dos extender (despite computers with more than 1Mb of memory being rare at that time). Many Dos programs of today were written after 1985. They were even ᴅᴏꜱ version designed only for protected mode : https://en.wikipedia.org/wiki/Concurrent_DOS_286
Win16 support cannot be added. This is due to some technical design reasons of Wow64 (i.e. occupying the Wow16 pointers in TEB). This means that the task scheduler on 64bit Windows cannot handle Wow16 and without integration into the process scheduler, the whole NTVDM just crashes randomly when trying to run 16bit applications. I have a load of patches here that were a few months of work which reconstruct 16bit Windows support in NTVDM, but it all ends up in random crashes due to the lack of scheduler integration. If you are interested, I can upload the patchset and you can play around with it.
DPMI is well-known and also integrated into NTVDM (see dpmi folder in source tree). But that doesn't mean that DOS programs can just happily run on your Windows machine without interference. They are all designed to have direct access to your hardware and if you allow them to acces your hardware directly (i.e. by adjusting IO access mask), you most probably will crash Windows. Imagine that the DOS application will directly access the IO ports of your VGA card, i.e. to show a TUI. You wouldn't be too happy about it, as it would interfere with your Windows driver for instance. That's what the V86 mode is for. It generates an exception when the program tries to do this, go back to the monitor, the monitor takes care about it and then it can continue execution on the CPU.
So I still don't get why you are still focusing on memory access, memory access is not the sole point for V86 mode.
DPMI is well-known and also integrated into NTVDM (see dpmi folder in source tree). But that doesn't mean that DOS programs can just happily run on your Windows machine without interference. They are all designed to have direct access to your hardware and if you allow them to acces your hardware directly (i.e. by adjusting IO access mask), you most probably will crash Windows. Imagine that the DOS application will directly access the IO ports of your VGA card, i.e. to show a TUI. You wouldn't be too happy about it, as it would interfere with your Windows driver for instance. That's what the V86 mode is for. It generates an exception when the program tries to do this, go back to the monitor, the monitor takes care about it and then it can continue execution on the CPU.
@leecher1337 But it will works for the few that don’t. And as stated previously Wine (at least on Linux) does just this with ᴅᴏꜱ programs too (and yes Wine crash on many ᴅᴏꜱ programs). But I enjoyed the compile time speed up for my ɴᴇᴄ calculator 3 years ago :) I think I understand you about Filesystems access, and I’ll bring the way it’s done in this thread.
Well, just make your own fork and make a version, that can run some obscure DOS-programs, if you feel like it, We are all awaiting your BOPping-Implementation with much interest ;-)
The proper way to use 16 bits segment for addressing included on 32 bit is not to use Vm86 mode but the Local Descriptor Table.
On Linux winedvm does just that for Win16 applications but it uses the
modify_ldt()
Linux system call.It should be possible to that on Windows through something like
NtSetInformationProcess(,ProcessLdtInformation
I think cygwin also provides a wrapper for this function.