Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multitasking MS-DOS 4.0 issue #120

Closed
Vutshi opened this issue Jun 9, 2024 · 26 comments
Closed

Multitasking MS-DOS 4.0 issue #120

Vutshi opened this issue Jun 9, 2024 · 26 comments
Assignees
Labels
bug Something isn't working

Comments

@Vutshi
Copy link

Vutshi commented Jun 9, 2024

Describe the bug
There is a deviation of MartyPC from QEMU and real hardware (clone of XT) on this strange version of MS-DOS. I ran a simple game, and it does not start, only showing a blue bar on the screen.

To Reproduce
Steps to reproduce the behavior:

  1. Boot MS-DOS 4.0M (image attached)
  2. Execute PACKMAN.COM
  3. MartyPC is stuck at the vertical blue bar.
    martyPC_pacman

Expected behavior
In QEMU and on real hardware, one can play this Soviet clone of Pacman and even switch between different tasks using Alt. However, the OS is very buggy.
QEMU_pacman

Environment (please complete the following information):

  • macOS 13.6.7 (22G720)
  • 2,3 GHz Quad-Core Intel Core i7
  • Intel Iris Plus Graphics
  • Rust 1.78.0

Build info

  • MartyPC 0.2.1 (also applies to 0.2.0)

Image
MSDOS400M-DISK1+game.img.zip

@Vutshi Vutshi added the bug Something isn't working label Jun 9, 2024
@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

Thanks for the report. The blue bar you're seeing is a debug view of the hblank area - eventually I need to hide that unless you have the 'debug' aperture selected, but the game is setting up a screen geometry that MartyPC isn't happy about. It looks like it is set up for low resolution mode, but the clock divisor is left for high resolution mode.

I note that the game runs fine in DOS 3.3. Games typically set up video modes via BIOS calls, or directly via setting the CRTC registers. DOS usually doesn't have anything to do with it - unless DOS 4.0M has to have its own video routines for the task-switching functionality.

I have considered before that my logic for when to adjust the clock divisor may be incorrect. I attempted some changes to that logic to derive it from the programmed CRTC registers, but that broke more things than it fixed. I may have to do a bit more research there.

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

I also note that if you try it a few times in a row, occasionally it does run properly.

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

you can see the issue here when it is not working, the 'hires text' bit of the mode register is set:
image

the high res text bit will override the 'graphics' mode bit so we stay in hires text mode, with the full 14Mhz dot clock - but the CRTC registers have been programmed to only display half the screen width, which is why we get to see the hblank period debug stripe.

image

When the game is running properly the hires text bit is cleared.

This bit is what I use to determine the character clock.

@Vutshi
Copy link
Author

Vutshi commented Jun 11, 2024

I also note that if you try it a few times in a row, occasionally it does run properly.

Oh, I never managed to be lucky enough to run it properly in MS-DOS 4.0M on MartyPC. In MS-DOS 3.3 it always works well as you noticed already.

I also have another version of this game as an .EXE file. The .COM version included with the DOS image seems to be just a wrapped .EXE with some minor changes (it supports another port for joystick). The point is that the .EXE version works funny in this MS-DOS 4.0M even in QEMU (I don't know about real hardware in this case). So this DOS is doing something unusual.

@Vutshi
Copy link
Author

Vutshi commented Jun 11, 2024

Btw, I don't see External Registers in Video Card Viewer. How do you turn it on?

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

Took another look at the schematic. The character clock is derived here:
image

either the LCLK (low resolution character clock, used in 40 col and graphics mode) or the HCLK (high resolution character clock) is selected based on the value of the HRES bit from the mode register. So that checks out. Correspondingly, either the 14Mhz or 7Mhz dot clock is selected from the same bit.

It doesn't surprise me that it might work on another emulator - QEMU is not known for slavish adherence to hardware quirks. Most emulators work out screen geometry from what is programmed into the CRTC registers - QEMU would see a low resolution mode, it will display a low resolution mode. It is not bothering to clock the CGA card tick for tick like MartyPC does.

But if you say this works on hardware, then that's puzzling. I'll need to try it on my 5150 and probe the output of the HIRES pin coming out of the mode register chip. If it's high, well, that's going to be puzzling, as it would conflict with the schematic. If its low, but high in MartyPC, there may be some other reason the mode register isn't being updated properly.

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

Btw, I don't see External Registers in Video Card Viewer. How do you turn it on?

I actually added it just now while debugging this. :D

@Vutshi
Copy link
Author

Vutshi commented Jun 11, 2024

But if you say this works on hardware, then that's puzzling.

Yes, it works on a clone of XT. I don't have a real 5150.

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

Technically, setting both the 'hires text' and 'graphics mode' bits is not a valid combination. We know what that does on the original IBM CGA card - but the behavior may not be the same on clones. A clone CGA could decide to have the graphics bit take priority - which in this case, would probably make it work.

@fuel-pcbox
Copy link

fuel-pcbox commented Jun 11, 2024

@Vutshi Try it in 86Box, it's much more accurate to real old PC hardware than QEMU is. It's not quite as accurate as MartyPC is, but it should give a better idea of whether or not this is a MartyPC bug.

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

It works in 86box, but i don't know if they're handling that invalid bit combination in an accurate way.

image

this was one of the discoveries made during the development of Area 5150, and they used it to be able to control the overscan color in text mode

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

To keep Area 5150 compatibility by default, I can't change the default behavior, but I suppose I could add a 'clone' boolean flag to the CGA card configuration overlay, that would switch the priority of the hires text and graphics bits, maybe even expose it as checkbox when you're operating a CGA.

The other option is another CRTC-based hack that would try to ignore the hires text bit if a lowres mode is programmed into the CRTC registers, but I've been burned before trying to add logic that the card simply doesn't have. Custom video modes deviate from the defaults by quite a bit, so detecting what is a low res mode and what isn't based just the horizontal total register isn't as trivial as it sounds, and you risk breaking more than you fix.

@Vutshi
Copy link
Author

Vutshi commented Jun 11, 2024

I would say it is better for MartyPC to do what IBM XT does and don’t bother with the clones, there are too many of them.

@Vutshi
Copy link
Author

Vutshi commented Jun 11, 2024

Do you understand why the invalid bit combination affects only the game running in MS-DOS 4.0M?

@dbalsom
Copy link
Owner

dbalsom commented Jun 11, 2024

The mode register is only set to the invalid state in MS-DOS 4.0M.

DOS 4.0M:
[2024-06-11T14:05:55Z DEBUG marty_core::devices::cga] Write to CGA mode register: 00000000
[2024-06-11T14:05:55Z DEBUG marty_core::devices::cga] Write to CGA mode register: 11001111

DOS 3.3:
[2024-06-11T14:07:44Z DEBUG marty_core::devices::cga] Write to CGA mode register: 00000000
[2024-06-11T14:07:44Z DEBUG marty_core::devices::cga] Write to CGA mode register: 00101010

@Vutshi
Copy link
Author

Vutshi commented Jun 11, 2024

MS-DOS 4.0M is strange indeed. I wonder why do they set this invalid configuration…
Maybe it explains why my Book8088 was unable to even boot this DOS. It somehow doesn’t recognize it as bootable.

@Vutshi
Copy link
Author

Vutshi commented Jun 13, 2024

DOS 4.0M:
[2024-06-11T14:05:55Z DEBUG marty_core::devices::cga] Write to CGA mode register: 00000000
[2024-06-11T14:05:55Z DEBUG marty_core::devices::cga] Write to CGA mode register: 11001111

DOS 3.3:
[2024-06-11T14:07:44Z DEBUG marty_core::devices::cga] Write to CGA mode register: 00000000
[2024-06-11T14:07:44Z DEBUG marty_core::devices::cga] Write to CGA mode register: 00101010

I am curious about when the write of 11001111 to port 0x3D8 happens in DOS-4.0M. I monitor the byte value at 0x465 (CGA mode in the BIOS data area) and see the following:

  • During the start of the game, DOS-5.0 writes the value 0x2A (00101010) to byte 0x465 and to port 0x3d8. After that, the game runs properly without altering the CGA mode byte 0x465.
martyPC_dos5
  • On the other hand, DOS-4.0M writes the value 0x01 to byte 0x465 and to port 0x3D8. After that, the blue bar appears. Where does the value 11001111 come from, and why is another incorrect value, 0x01, being written by a BIOS routine...
martyPC_dos4M

@Vutshi
Copy link
Author

Vutshi commented Jun 13, 2024

Furthermore, the game does a correct int 10h call to switch the CGA mode in DOS-4.0M:
Screenshot 2024-06-13 at 16 36 13

Then something goes wrong as shown in the previous comment.

@dbalsom
Copy link
Owner

dbalsom commented Jun 16, 2024

what is the address of the INT 10h handler when it is called? (look at the IVT table viewer, entry 16)
if it is not in the F000 segment it has been overridden

edit: it is
image

the original int 10h bios routine is at F000:F065. breakpoint on that, and we eventually arrive at it when AH==0 and AL==4 which should set up CGA 320x200 graphics mode. So far the mode register looks ok

so why is it getting trashed?

@dbalsom
Copy link
Owner

dbalsom commented Jun 16, 2024

something very weird is going on. if i set a breakpoint on the CGA card's handle_mode_register() call, i never see that invalid write, and the game starts up normally

EDIT: Does this only happen under GLaBIOS??

@Vutshi
Copy link
Author

Vutshi commented Jun 16, 2024

Does this only happen under GLaBIOS??

I don’t know. I’ve never tried anything but the GlaBIOS.

@dbalsom
Copy link
Owner

dbalsom commented Jun 16, 2024

I think it's a bug in GLaBIOS. Working with the author to confirm.

EDIT: confirmed and fixed. Basically, GLaBIOS would load the mode byte parameter from the wrong memory location if the int 10h vector was overridden due to a missing segment prefix on XLAT.

@Vutshi
Copy link
Author

Vutshi commented Jun 17, 2024

I see. It never even occurred to me that the BIOS might be faulty. I’ll keep that in mind if I encounter another bug.

@Vutshi
Copy link
Author

Vutshi commented Jun 17, 2024

Many mysteries are resolved at once. I checked the original IBM BIOS, and it works well with DOS-4.0M and Pac-Man. However, Sergey Kiselev's BIOS doesn't boot this DOS, which explains my Book8088's behavior.

@dbalsom
Copy link
Owner

dbalsom commented Jun 17, 2024

Thanks to 640KB for the rapid turnaround, I've committed fixed GLaBIOS ROMS here:
b01561c

Thanks again for the report.

@dbalsom dbalsom closed this as completed Jun 17, 2024
@Vutshi
Copy link
Author

Vutshi commented Jun 17, 2024

This is cool. Thank you. So now MartyPC has a newer GLaBIOS than the upstream ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants