leecher1337 / ntvdmx64

Run Microsoft Windows NTVDM (DOS) on 64bit Editions
823 stars 81 forks source link

WPS 3.0 For DOS unabled to show the Chinese input method toolbar. #255

Open happymimimix opened 7 months ago

happymimimix commented 7 months ago

As described, the Chinese input method toolbar that supposed to appear on the bottom of the screen is not showing. Please fix this, if possible? image

Also I would like to ask if using Tame DOS on Windows 10 22H2 would be possible? If yes, how?

happymimimix commented 7 months ago

WPS_v3.0_CD.zip

Here is the installer, if you need it.

leecher1337 commented 7 months ago

Weird, the program uses SVGA mode 12h (640x480x16). With SVGATEST, the mode shows just fine:

image

However in WPS 3.0, lower part of video memory seems to be blanked. I wonder why...

leecher1337 commented 7 months ago

It seems to me that the problem is related to the video memory layout as specified by the Memory Map Select MISC-Register:

Works (SVGATEST sample above):

yoda> dump_EGA_CPU
rame=1 wmode=0 rot=0 s/r=0000 s/re=0000 sr=0 func=0 bp=0 pe=1
EGA memory is 0xa0000->0xaffff plane offset is 0x8101000
set/reset value: 0 sr_nmask: 0xffffffff sr_masked_val: 0
bit_prot=0xffffffff,data_and=0xffffffff,data_xor=0,latch_xor=0xffffffff
handlers are of type 0

Cuts off Video memory (WPS 3.0):

yoda> dump_EGA_CPU
rame=1 wmode=0 rot=0 s/r=0000 s/re=0000 sr=0 func=0 bp=0 pe=0
EGA memory is 0xa0000->0xbffff plane offset is 0x8101000
set/reset value: 0 sr_nmask: 0xffffffff sr_masked_val: 0
bit_prot=0xffffffff,data_and=0xffffffff,data_xor=0,latch_xor=0xffffffff
handlers are of type 0

I wonder if this a bug in the original CVIDC or just in my reconstruction, hmmm...

leecher1337 commented 7 months ago

Looking at the SPDOS.COM (Super Chinese System), which causes the switch to the wrong memory area, we can see:

seg000:9E7A                 test    al, 8
seg000:9E7C                 jz      short loc_19E77
seg000:9E7E                 mov     dx, 3CEh
seg000:9E81                 mov     al, 6
seg000:9E83                 out     dx, al          ; EGA: graph 1 and 2 addr reg:
seg000:9E83                                         ; miscellaneous graphics control.Data bits:
seg000:9E83                                         ; 0: 1=graphics; 0=enable char gen (text)
seg000:9E83                                         ; 1: 1=chain odd maps after even maps
seg000:9E83                                         ; 2: memory mapping for CPU
seg000:9E83                                         ;    00=a000H (128K);   01=a000H (64K)
seg000:9E83                                         ;    10=b000H (32K MDA);11=b800H (32K CGA)
seg000:9E84                 inc     dx
seg000:9E85                 mov     al, 1
seg000:9E87                 out     dx, al          ; EGA port: graphics controller data register

So by writing the value 1 to the Port, it sets the "Memory Map Select" to 00 and therefore causes a wrong memory area to be selected, as Mode 12h, which the application is in, should always be 01 (just the 64kb area is used to draw the planes). The NTVDM VGA emulation doesn't like this at all when there is a wrong memory area selected. I wonder why SPDOS.COM does this?

You could patch spdos.com to make a mov al, 5 instead of a mov al, 1 and it should work. As long as it's not known why spdos.com does it, there is also no point in patching ntvdm, as the purpose of the change in the memory map is still unknown.

leecher1337 commented 7 months ago

This article states that the behaviour of memory maping mode 0 is not really defined:

Note that there's one value, 00b, that maps the entire A0000h-BFFFFh range to video memory. Unfortunately, what happens when you access memory in the region B0000h-BFFFFh with this value selected doesn't seem to be well defined in actual hardware.

One possible implementation is that access to B0000h-BFFFFh simply wraps around to A0000h-BFFFFh, that is, CPU address bit 16 (A16) is simply ingored by the VGA card. So a write to address B8000h (and A8000h) would map to VGA address 8000h, right in the middle of mode 13h frame buffer. The other is that the A16 bit is decoded and allows access to SuperVGA memory (> 256kb). So a write to address B8000h would map to SVGA address 18000h, which is outside the mode 13h frame buffer.

Therefore it may be the best solution to just ignore this mode alltogether in the VGA emulation.

happymimimix commented 6 months ago

Looking at the SPDOS.COM (Super Chinese System), which causes the switch to the wrong memory area, we can see:

seg000:9E7A                 test    al, 8
seg000:9E7C                 jz      short loc_19E77
seg000:9E7E                 mov     dx, 3CEh
seg000:9E81                 mov     al, 6
seg000:9E83                 out     dx, al          ; EGA: graph 1 and 2 addr reg:
seg000:9E83                                         ; miscellaneous graphics control.Data bits:
seg000:9E83                                         ; 0: 1=graphics; 0=enable char gen (text)
seg000:9E83                                         ; 1: 1=chain odd maps after even maps
seg000:9E83                                         ; 2: memory mapping for CPU
seg000:9E83                                         ;    00=a000H (128K);   01=a000H (64K)
seg000:9E83                                         ;    10=b000H (32K MDA);11=b800H (32K CGA)
seg000:9E84                 inc     dx
seg000:9E85                 mov     al, 1
seg000:9E87                 out     dx, al          ; EGA port: graphics controller data register

So by writing the value 1 to the Port, it sets the "Memory Map Select" to 00 and therefore causes a wrong memory area to be selected, as Mode 12h, which the application is in, should always be 01 (just the 64kb area is used to draw the planes). The NTVDM VGA emulation doesn't like this at all when there is a wrong memory area selected. I wonder why SPDOS.COM does this?

You could patch spdos.com to make a mov al, 5 instead of a mov al, 1 and it should work. As long as it's not known why spdos.com does it, there is also no point in patching ntvdm, as the purpose of the change in the memory map is still unknown.

WOW! You are really a pro at reverse engineering! This is insane. Would you like to join the development of one of my projects? The aim is to make an operating system with the crazy compatibility and easy to use of windows, at the same time the freedom of Linux. aka Lindows! But I'm having troubles removing some of the stupid limitations in Windows such as the checksum verification of winload.exe and ntoskrnl.exe. Also the signature verification and all sorts of integrity checks of some of the critical system components. Again, I don't mind reverse engineering and patching any of the system files. In fact, this is how the whole project is going to work. I just want to bring the freedom that every Windows user supposed to have back no matther what absurd methods we use. Such as I used a symbolic link that points to C:\System Volume Information to hack the writing limitation to that folder.

Add me on discord if you are interested. My username: happy_mimimix.

happymimimix commented 5 months ago

@leecher1337 I recompiled the latest version of NTVDM x64 and installed on my device, now WPS 3.0's window just got the bottom half completely chopped off! Still no input method toolbar! image

happymimimix commented 4 months ago

@leecher1337

leecher1337 commented 3 months ago

image

happymimimix commented 2 months ago

image

You sure you didn't touch the exe files of wps 3.0? You really sure they were all the original ones? Cus, in my case the bottom half of the screen just went from blank to completely disappear.

My system is Windows 10 LTSC 2021. I built mine wth windows sandbox cus it just won't compile for some reason on my host no matter what I do. Also I installed the ccpu chk build, is that where the problem occurs?

Note: I haven't yet had a chance to build it once again recently, the above is a more detailed description of the situation I got when I posted this on June 26th:

@leecher1337 I recompiled the latest version of NTVDM x64 and installed on my device, now WPS 3.0's window just got the bottom half completely chopped off! Still no input method toolbar! image

Maybe I shall let you have a look at the binaries that I've built and perhaps you can help me debug it?

happymimimix commented 2 months ago

@leecher1337 The latest ntvdmx64 build worked fine with WPS 3.0, thanks! However, the exact same problem happened again with another version of that software: WPS NT 1.0, which is slightly newer. image Not sure if that's a screen mode issue once again, please check. Thank you.

happymimimix commented 2 months ago

Also, another wired glitch with WPS 3.0: https://github.com/user-attachments/assets/bfadc3c6-0882-4c20-81e2-1f226d605267

happymimimix commented 2 months ago

WPS_NewTech_1.0.haozip01.zip WPS_NewTech_1.0.haozip02.zip Oh sorry, I forgot to give you this, the newer version of WPS. @leecher1337 The issue is not fully fixed yet, please have another look.

leecher1337 commented 2 months ago

@happymimimix Are you sure the .zip files are OK? I got errors when trying to extract them.

leecher1337 commented 2 months ago

Nevertheless, I was able to extract the most important files and got it to run. I have the full image here:

image

But one thing I noticed is that the Window size does not fit correctly, graphics goes beyond the size of the displayed window.

leecher1337 commented 2 months ago

Ok, I figured it out, it depends on the way you start the application. The WPSNT.BAT bust be executed within the DOS context, not within the NT context, because it calls various programs. One of them is spdos which changes the screenmode to 640x480. However after exiting (it loads as TSR), the console gets reset back (which is intentional behaviour) and thus reset the text screen. However wps.exe expects the screen to be in the correct mode upon startup, otherwise, it will just set 400 scanlines instead of 480 leading to the cut-off.

Long story short, the resolution is to run the wpsnt.bat with:

command /C

so that it gets executed purely in DOS context. You can thus simply make a start.bat file containing:

command /C WPSNT.BAT

and it should work as expected: image

Still, there is this console reset problem with shelling out to DOS that you demonstrated above, not sure if this can be remedied, may also be related to console interaction (as running non-DOS commands invokes the normal cmd.exe shell which is not compatible with the chosen screen-mode and thus starts the application in a new window. If you run i.e. edit.com, a real DOS application, it will run correctly within the window).

happymimimix commented 2 months ago

@happymimimix Are you sure the .zip files are OK? I got errors when trying to extract them.

I used a debloated 2345haozip made by qiuquan to create them. They are a very special type of split archive files that can only be read by 2345 haozip. Sorry I forgot to tell you about that. I did that because github has a limit to the file types you can upload in comments, which is very annoying and very dumb. What this file type does is that it tricks the platform to think they are just multiple normal non-split zip files, not one big archive been split into multiple files. Besides this, I don't really know what else I could do to overcome this stupid file type limit. I tried changing the extension before but that sadly doesn't work, github would actually look into the file and verify its header.

You can get this program here: http://www.qiuquan.org/compress/haozip.html

happymimimix commented 2 months ago

Ok, I figured it out, it depends on the way you start the application. The WPSNT.BAT bust be executed within the DOS context, not within the NT context, because it calls various programs. One of them is spdos which changes the screenmode to 640x480. However after exiting (it loads as TSR), the console gets reset back (which is intentional behaviour) and thus reset the text screen. However wps.exe expects the screen to be in the correct mode upon startup, otherwise, it will just set 400 scanlines instead of 480 leading to the cut-off.

Long story short, the resolution is to run the wpsnt.bat with:

command /C

so that it gets executed purely in DOS context. You can thus simply make a start.bat file containing:

command /C WPSNT.BAT

and it should work as expected: image

Still, there is this console reset problem with shelling out to DOS that you demonstrated above, not sure if this can be remedied, may also be related to console interaction (as running non-DOS commands invokes the normal cmd.exe shell which is not compatible with the chosen screen-mode and thus starts the application in a new window. If you run i.e. edit.com, a real DOS application, it will run correctly within the window).

I ran command.com, then type cd \ && WPSNT.BAT. Still couldn't get the bottom half to show. I have new console mode enabled in cmd so of course I can't just double click on that bat file. Windows fall back to legacy console whenever a dos program is being called so it shouldn't be a problem to leave new console enabled, and all of the other msdos apps that I have in my collection worked perfectly fine! It's just these buggy chinese software that can't work well.

In the case of WPS 3.0, the expected behavior of DOS command is that it would capture the output of command line apps and draw them onto the screen. Because SPDOS is running in graphics mode not text mode. So to make the dos console functions the same as they were in text mode just added support for chinese characters, spdos would capture the output of dos programs and draw the text in graphics mode. For now, not only the text capturing is not functioning, it also make the screen size go wrong once again!

leecher1337 commented 2 months ago

I ran command.com, then type cd \ && WPSNT.BAT. Still couldn't get the bottom half to show.

That won't work, I tested it. Instead, run command /c wpsnt.bat

happymimimix commented 2 months ago

I ran command.com, then type cd \ && WPSNT.BAT. Still couldn't get the bottom half to show.

That won't work, I tested it. Instead, run command /c wpsnt.bat

What about the text capturing thing then? Do I have to install a real DOS VM for that?
Is there any possibility for ntvdm to emulate that behavior?

happymimimix commented 2 months ago

Also I can't use dos box for that cus it would hang when I open it.

happymimimix commented 2 months ago

I ran command.com, then type cd \ && WPSNT.BAT. Still couldn't get the bottom half to show.

That won't work, I tested it. Instead, run command /c wpsnt.bat

And have you found the reason why running command.com first won't work? But command /c wpsnt.bat works fine?

leecher1337 commented 2 months ago

And have you found the reason why running command.com first won't work? But command /c wpsnt.bat works fine?

I already tried to explain it. This is working as intended. It is due to the design of the Windows Commandline-Integration. If you run via command /c, the .bat file is being processed by command.com within a pure DOS session. If you run the .bat directly, it is being processed by cmd.exe When cmd.exe executes a command, it runs it (in the case of DOS applications, it calls the NTVDM to take over) and afterwards, it resets back the console and executes the next command. The reset of the console (as in switching back from Video output to streaming I/O) also resets back the graphics mode previously set. As the spdos system sets the screen mode with the correct height first, but then exits (so that next command in .bat gets executed), the exit resets back the console. When wpsdos.exe is started, it doesn't set the video mode again on its own but takes the current screen height when entering graphics mode and due to the reset to streaming I/O, it is only 400 lines in height and not 480 which leads to a cut-off. So the solution is to execute it purely within the DOS context by using command /C

On a real 32bit-Machine, this behaviour isn't an issue, as switching to graphics mode automatically forces the ntvdm to switch to fullscreen and all video output is then being directed directly to the VGA card, so there is no reset of the console when in fullscreen mode. (i.E. the code for disable_stream_io() is not called in fullscreen):

#if defined(NTVDM) && !defined(X86GFX)
    if (stream_io_enabled && getAH()!= 0x0E &&  getAX() != 0x13FF)
        disable_stream_io();
#endif 

Now if you are running command.com and starting the .bat from the prompt, it takes default execution behaviour which is "run cmd.exe with my command as a parameter" which then does the same as it would do when you just directly execute the .bat file.

At least, that's my opinion on what's happening there.

Also check the comments in softpc.new/host/src/nt_event.c about the mode change dilemma.

What about the text capturing thing then?

What do you want to capture?

leecher1337 commented 2 months ago

If you want to have the DOS shell at least open the commands within the same window and not within a seperate window (so not to use cmd.exe), you can alter your start.bat file:

set COMSPEC=C:\windows\system32\command.com
command /c wpsnt.bat

It will still mess up your video mode after executing a command on DOS shell, though.

happymimimix commented 2 months ago

And have you found the reason why running command.com first won't work? But command /c wpsnt.bat works fine?

I already tried to explain it. This is working as intended. It is due to the design of the Windows Commandline-Integration. If you run via command /c, the .bat file is being processed by command.com within a pure DOS session. If you run the .bat directly, it is being processed by cmd.exe When cmd.exe executes a command, it runs it (in the case of DOS applications, it calls the NTVDM to take over) and afterwards, it resets back the console and executes the next command. The reset of the console (as in switching back from Video output to streaming I/O) also resets back the graphics mode previously set. As the spdos system sets the screen mode with the correct height first, but then exits (so that next command in .bat gets executed), the exit resets back the console. When wpsdos.exe is started, it doesn't set the video mode again on its own but takes the current screen height when entering graphics mode and due to the reset to streaming I/O, it is only 400 lines in height and not 480 which leads to a cut-off. So the solution is to execute it purely within the DOS context by using command /C

On a real 32bit-Machine, this behaviour isn't an issue, as switching to graphics mode automatically forces the ntvdm to switch to fullscreen and all video output is then being directed directly to the VGA card, so there is no reset of the console when in fullscreen mode. (i.E. the code for disable_stream_io() is not called in fullscreen):

#if defined(NTVDM) && !defined(X86GFX)
    if (stream_io_enabled && getAH()!= 0x0E &&  getAX() != 0x13FF)
        disable_stream_io();
#endif 

Now if you are running command.com and starting the .bat from the prompt, it takes default execution behaviour which is "run cmd.exe with my command as a parameter" which then does the same as it would do when you just directly execute the .bat file.

At least, that's my opinion on what's happening there.

Also check the comments in softpc.new/host/src/nt_event.c about the mode change dilemma.

This is a very really ridiculous and totally unreasonable behavior! Why would command.com hand the bat execution over to cmd.exe and then let cmd.exe call ntvdm when command.com itself is running in NTVDM? So, I wonder if it's possible to somehow prevent command.com from calling cmd.exe when running bat scripts?

What about the text capturing thing then?

What do you want to capture?

I have already answered it here: https://github.com/leecher1337/ntvdmx64/issues/255#issuecomment-2352879853

In the case of WPS 3.0, the expected behavior of DOS command is that it would capture the output of command line apps and draw them onto the screen. Because SPDOS is running in graphics mode not text mode. So to make the dos console functions the same as they were in text mode just added support for chinese characters, spdos would capture the output of dos programs and draw the text in graphics mode. For now, not only the text capturing is not functioning, it also make the screen size go wrong once again!

leecher1337 commented 2 months ago

This is a very really ridiculous and totally unreasonable behavior! Why would command.com hand the bat execution over to cmd.exe and then let cmd.exe call ntvdm when command.com itself is running in NTVDM? So, I wonder if it's possible to somehow prevent command.com from calling cmd.exe when running bat scripts?

The behaviour makes sense, because DOS cannot execute WIN32 executables and the ability to mix DOS and Win32 applications ans let them interact via pipes is one of the key advantages of the NTVDM compared with isolated emulators. So cmd.exe is a 32bit process that can execute both 32bit executables (hand over to the application) and 16bit applications (queue application for execution by NTVDM that can fetch the task with GetNextVDMCommand() API and then either execute within a new session or the currently running session).

However, as I told already wrote, you can modify the behaviour by setting COMSPEC accordingly.

To verify that it is correct behaviour, I also ran the WPSNT on the original 32bit NTVDM, which doesn't seem to be supported at all due to running in V86 mode:

image

So in order to verify correct operation in terms of the functionality designed by the Microsoft engineers, in emulated video mode, one has to resort to run NTVDM on Windows NT on the PPC and as it can be seen, behaviour is consitent there (as soon as the console is in a special video mode and not in standard I/O mode, applications are executed in a seperate window within a normal unmodified console and one gets switched back after execution of the command):

image

In the case of WPS 3.0, the expected behavior of DOS command is that it would capture the output of command line apps and draw them onto the screen. Because SPDOS is running in graphics mode not text mode. So to make the dos console functions the same as they were in text mode just added support for chinese characters, spdos would capture the output of dos programs and draw the text in graphics mode. For now, not only the text capturing is not functioning, it also make the screen size go wrong once again!

If you are executing i.e. the "dir" command, this is not a DOS command but a WIN32 command from cmd.exe (otherwise, it wouldn't support long filenames etc.). WIN32 applications can interact via pipes and directly with the other applications, but they don't know anything about DOS and screen modes of the current DOS console etc. So if you want to capture their output, either set comspec to command.com, like shown above, or make the following experiment:

Write a litte program that takes stdin and writes the characters out via video BIOS TTY function: image

If you name this file - say cat.com, you can then issue dir | cat and you'll get the output of the Win32 application on your DOS console (this is just a simple example, the code above of course will never halt and hang, but after all, it's just for demonstration purposes to show the capabilities of pipe redirection).

happymimimix commented 2 months ago

ted behavior of DOS command is that it would capture the output of command line apps and draw them onto the screen. Because SPDOS is running in graphics mode not text mode. So to make the dos console functions the same as they were in text mode just added suppor

Thanks very much for you explanation. But how should I set comspec to command.com? Is that an environment variable or an .ini file that I need to modify or an registry key?

leecher1337 commented 2 months ago

Thanks very much for you explanation. But how should I set comspec to command.com? Is that an environment variable or an .ini file that I need to modify or an registry key?

https://github.com/leecher1337/ntvdmx64/issues/255#issuecomment-2359448269

Just create a - say - run.bat file containing the lines mentioned. Then, instead of running command /C wpsnt.bat or just wpsnt.bat, run this newly created file run.bat

You will still have the issue of video mode change when running a dos command in the subshell (and no proper scrolling of the console due to video mode) from wpsnt, but you can at least check if chinese output gets interpreted correctly by the wpdos system.

happymimimix commented 2 months ago

Thanks very much for you explanation. But how should I set comspec to command.com? Is that an environment variable or an .ini file that I need to modify or an registry key?

#255 (comment)

Just create a - say - run.bat file containing the lines mentioned. Then, instead of running command /C wpsnt.bat or just wpsnt.bat, run this newly created file run.bat

You will still have the issue of video mode change when running a dos command in the subshell (and no proper scrolling of the console due to video mode) from wpsnt, but you can at least check if chinese output gets interpreted correctly by the wpdos system.

Then in that bat I put command.com /C WPSNT.bat is that correct?

leecher1337 commented 2 months ago

Then in that bat I put command.com /C WPSNT.bat is that correct?

You put the following 2 lines in the .bat, as already linked in the comment above:

set COMSPEC=C:\windows\system32\command.com
command /c wpsnt.bat
happymimimix commented 2 months ago

Then in that bat I put command.com /C WPSNT.bat is that correct?

You put the following 2 lines in the .bat, as already linked in the comment above:

set COMSPEC=C:\windows\system32\command.com
command /c wpsnt.bat

Thanks I'll try that.

happymimimix commented 2 months ago

Just tested that, it worked perfectly fine! image Now I got all three different versions of WPS working perfectly fine with NTVDM! What's ironic about this is that DOS BOX hangs whenever I tries to run any one of these WPS for dos versions. IDK why dos box does that while NTVDM handles them perfectly. Perhaps due to the use of the undocumented screen mode?

image The fact that you're allowed to run a 32bit console program in NTVDM is amazing and I think this convenience is well over the frustration of running WPS NT with command.com /C

happymimimix commented 2 months ago

Hold on, here's something I didn't notice a moment ago: The screen mode fix for WPS 3.0 seems to be breaking UCDOS 7.0! image Before you fix the screen mode, UCDOS can work with other western dos applications without any issue in the previous version of NTVDM. But now the screen is just completely blank.

I apologize for another interruption but please have another look at this @leecher1337

leecher1337 commented 3 weeks ago

So I installed latest ntvdmx64 build, installed UCDOS 7.0 from https://vetusware.com/download/UCDOS%207.0%207.0%20CN/?id=11654 and then went to c:\UCDOS, ran ucdos, then ran wps and it worked without issues here. How to reproduce the hang?

happymimimix commented 3 weeks ago

So I installed latest ntvdmx64 build, installed UCDOS 7.0 from https://vetusware.com/download/UCDOS%207.0%207.0%20CN/?id=11654 and then went to c:\UCDOS, ran ucdos, then ran wps and it worked without issues here. How to reproduce the hang?

No, it's not WPS. Other western softwares like microsoft works. UCDOS supposed to provide chinese characters support for these software as well and it does work before you fix the screen cut off issue for WPS 3.0 but now it just show a completely blank screen.