jhhoward / WolfensteinCGA

Wolfenstein 3D with a CGA renderer
325 stars 10 forks source link

Feature request: Hercules support (and some other notes) #2

Open monotech opened 1 year ago

monotech commented 1 year ago

This is awesome! Thanks!

Would it be very hard to add monochrome Hercules support? (720x348 with dithering) I can test on real hardware if needed.

In the interest of minimizing space used on vintage hard disks (often only 10-30MB on 8088 PCs), could you add to the Readme the files that are always required, and the files that are optional for different graphics modes? What is XSWAP.WL6 for?

The timedemo uses your currently saved window size setting. Perhaps this should be ignored for benchmark standardization (or another command line option to force it to use the saved window size). Standardization of sound device used may be good too (PC speaker or no sound).

I remember some hack to run the game on a 286, but even a 10MHz 286 needed a postage stamp window (it was VGA though). Here's some benchmarks, running the timedemo with maximum window size, and 630K free conventional memory on both systems: NuXT (9.55MHz V20), Trident TVGA9000i: 5.8 FPS (18.7 FPS with minimum window size) NuXT (9.55MHz V20), IBM EGA card: 4.5 FPS (18.4 FPS with minimum window size) NuXT (9.55MHz V20), IBM CGA card: 5.5 FPS (19.2 FPS with minimum window size) IBM 5150 (4.77MHz 8088), IBM CGA card: 1.7 FPS (3.8 FPS with minimum window size)

I notice quite a bit of HDD activity throughout the timedemo. Both systems have 630K free conventional memory and are running off a CF card connected to an XT-IDE Rev2.

viti95 commented 1 year ago

Maybe it's also a good idea alter the Hercules mode to render at 640x400, it's possible by modifying the MC6845 registers (FastDoom does this). This way the resolution is basically twice the original 320x200, and thus much easier to dither.

jhhoward commented 1 year ago

@monotech Hercules is something I can look into!

Your question about the different files: each video mode has a different set of the textures, sprites and 2D images reduced to the relevant palette. CSWAP, CGAHEAD, CGAGRAPH = CGA RGB mode LSWAP, LCDHEAD, LCDGRAPH = LCD inverse mono mode TSWAP, TGAHEAD, TGAGRAPH = Tandy mode XSWAP.WL, COMHEAD, COMGRAPH = Composite CGA mode

I will have to update the readme to make this clear, since as you mentioned disk space is sometimes at a premium on these old machines.

It is quite useful to have the timedemo use your current config as it's possible to compare the impact of different sound devices, for example. Perhaps I could add another benchmark option which has full screen and no sound as a 'standardised' benchmark. Thanks for sharing the performance on your different setups, it's really interesting to see how the different configurations perform! The Wolfenstein engine streams data from disk when it is needed, e.g. only loads a texture when it is going to be drawn. This will be why you will see disk activity whilst playing.

@viti95 I don't have a Hercules setup, but from what I've read online the 640x400 mode doesn't work with all cards / displays. Do you have any feedback from FastDoom users on this?

viti95 commented 1 year ago

Well Hercules + 386/486 is not very common, so I don't have many reports of it not working properly. Just one report of the Tidalwave TM6310 doing weird things in this mode. Maybe it's a monitor issue, but don't really know.

https://user-images.githubusercontent.com/8323882/147149813-c13409a0-9b0a-423a-86e1-f4905fac7234.jpg

FavoritoHJS commented 1 year ago

The primary thing that could worry me about 640x400 is that its hsync and vsync frequencies might be out of range for what the monitor expects. Time for calculating I guess...

NOTE: Raw HTML table ahead!

Mode H-Params V-Params Notes
HTotalR0*16
HDispR1*16
HBlankR0-R1*16
HSyncR3*16
VTotalR4*4+R5
VDispR6*4
VBlank(R4-R6*4)+R5
720x350 848 720 128 112 366 348 18 51,6Hz with 310368 pixels per frame @ 16MHz... did I skip some scanlines?

Actually 348 lines due to char sizing limitations

Taken from seasip.info

640x400 832 640 196 112 420 400 20 45,8Hz with 349440 pixels per frame @ 16MHz. Slightly different horizontal timings.
640x200 832 640 196 112 210 200 10(!) 91,6Hz with 174720 pixels per frame @ 16MHz. Cut-off VSync. VERY UNSTABLE!

As you can see, the timings don't quite match. I fear some monitors will be thrown off by this... though considering how generous the original timings were (basically all of blank time is retrace time!) I'm not sure of the gravity of that.

Since 640x400 is a decidedly non-standard mode, monitors might have problems with bits being hidden behind the bezel, as they are set up to have 350 lines be enough to fill the screen, not 400 -- in fact you can see a bit of this in the capture viti95 made, as the bottom of the status bar is cropped. To counteract this, it might be a good idea to add screen adjusting options by adding or substracting an user-given value to R2 "HSync Pos." and R7 "VSync Pos."... of course after verifying the values are in bounds (though some monitors might be able to move further by not checking this -- a whole 16 lines of vsync seems overkill...)

PS: Notepad++ really does not like end tag omission, even when that's perfectly acceptable. I blame UDL. PPS: Since only one in 4 scanlines is affected, starting from halfway down the image, I fear the Tidalwave TM6310 you mention has bad VRAM... If FastDoom makes use of both banks, that would also explain why it went unnoticed, since most software only uses one.

EDIT: Added removed 640x200 tweakmode

jhhoward commented 1 year ago

I've been experimenting with Hercules modes for 720x348, 640x400 and 640x200. All resolutions work in an emulator, but when it comes to real hardware, only 720x348 is working properly. 640x200 just completely fails to display at all. 640x400 has visible issues with the second frame buffer partially visible on the right side of the screen, and the bottom chunk of the screen cut off.

Here is a photo of 640x400 for reference: image

I haven't uploaded binaries but if you sync to this change and compile yourself, you can try out the experimental Hercules modes: 5769fdf8dbdf235491c5a9def61208a1b1eb4f26

Run with the command line 'hercules' for 640x400 and 'hercules720' for 720x348

The 720x348 mode is currently letterboxed and looks squashed, but I'm going to see if I can vertically stretch to look better by doubling every other horizontal line. This would effectively be 640x300 centered in a 720x348 mode.

viti95 commented 1 year ago

Avoid the 640x200 Hercules mode, my monitor started doing really weird noises when I tried it. Never got it to work at all on any compatible Hercules card (not even in the original one). Only works on emulators. In fact I removed all references from FastDoom code to avoid any issues.

BTW what Hercules video card are you using?

monotech commented 1 year ago

I may be mistaken, but I wouldn't expect real hardware to be capable of running hercules graphics mode at anything higher than W x 348. Most MDA monitors can only handle 50Hz Vsync and ~18kHz Hsync with little deviation and a possibility of damage to 'dumb' monitors like the IBM 5151. Unless interlacing is possible?

viti95 commented 1 year ago

This is FastDoom running Hercules 640x400 mode, on my original IBM 5151 display. It works, I've tested multiple compatible video cards. No issues nor strange sounds.

https://youtu.be/ILM0uayHQmA

Edit: Maybe 640x400 mode doesn't work properly using two video pages, in FastDoom i'm using only one because is faster when using differential copies to the screen.

Edit 2: Fun fact, I also modified Super Mario 64 to run on Hercules 640x400 mode

https://youtu.be/4qXImwCfZco

FavoritoHJS commented 1 year ago

I've been experimenting with Hercules modes for 720x348, 640x400 and 640x200. [...] 640x200 just completely fails to display at all. 640x400 has visible issues with the second frame buffer partially visible on the right side of the screen, and the bottom chunk of the screen cut off.

The problem with the 640x200 mode is probably that VSync happens too often (guessing 90Hz), so many monitors can't quite catch a break and display the screen as intended.

EDIT: Also, there isn't enough time in vblank to have a full sync pulse! Sync requires 16 lines in VBlank but only 10 are provided. This can't be good! Also updated the table I posted earlier with timings.

The bottom chunk being cut off is as I expect, as when the monitor is getting MDA-like signals it probably expects MDA-like timings -- 720 pixels and 350 lines, not 640 and 400.

The repeating screen is odd... I wonder if the internal CRTC doesn't quite support a visible area smaller than all the characters, since that's pretty much how the default timings worked, or if the code isn't sending that properly...

FavoritoHJS commented 1 year ago

Very stupid idea: I suspect that, by using an EGA's fast pixel clock on CGA monitor timings, you could get something like 800x200, which would allow for very fine dithering... though I wonder how an average monitors handles that, as many monitors would have trouble resolving such fine detail, potentially giving a different color than expected as colors are mixed as raw voltages that do not map linearly to screen brightness, instead of a "duty cycle" that does.