VOGONS


First post, by cde

User metadata
Rank Member
Rank
Member

As noted by myself and others, feeding the VGA output from 320x200 games into a LCD most often leads to extra duplicated horizontal pixels which is due to LCD deciding to sample VGA as 720x400 instead of the correct 640x400; see this post for example pictures of the problem: Re: Widescreen monitors and 4:3 aspect ratio compatibility thread

In addition, 1280x1024 monitors drop frames @ 70 Hz and have an incorrect aspect ratio of 5:4, and some 1920x1080 monitor lack 4:3 aspect ratio correction. Using the DVI output of a card directly is not ideal either: the 60 Hz refresh rate is incorrect and some games internal mechanics, like Lotus III, depends on the vertical refresh rate for their timings. Furthermore, when using a 1920x1080 monitor, cards will directly output 1080p under DOS which is not desirable.

So looking for a solution, I found this rather cheap and effective hack. The idea is to trick the graphics card by replacing the monitor's EDID with my own EDID (stored on an I2C flash) that contains 1280x960 as the preferred resolution (here we're using the card's DVI output). This way, the graphics card directly upscales 320x200 into 1280x960, preserving the 4:3 aspect ratio, and using the correct vertical refresh frequency. By swapping the flash and rebooting, I can switch between 70 Hz and 60 Hz depending on whether a game uses 320x200 or 320x240/640x480/800x600.

I implemented this hack and it turns out the result works extremely well. I have mainly tested two graphics cards so far: a GeForce 6800 GT and a Radeon 9250. Both accept this custom resolution, and games run with the exact 4:3 aspect ratio, perfect pixel accuracy horizontally, and almost perfect accuracy vertically. So it's a great success and all the games I've tested so far including FPS such as Quake and DOOM work perfectly 😄 (the GeForce 6 series applies a slight blur however, so I do recommend the Radeon instead for a sharper image).

Now if you'd like to do this hack yourself, the prerequisites are as follows:

  • You need a monitor that accepts 1280x960@70 Hz without frame dropping and also provides a 1:1 image ratio option (the image is displayed "as-is", centered). The 144 Hz monitor I'm using is the AOC G2590PX and fits the criteria, so it's a good choice if you're looking for such a monitor.
  • You need to buy at least two 256 bytes (8 bit address) DIP8 I2C serial flash + DIP8 sockets : one for 70 Hz and one for 60 Hz. I'm presently using AT24C02C chips (ATMLU904 02CM PH 19041KR). Note that larger flash that do not use 8-bit addresses will not be compatible with the graphics card.
  • You need a way to program the serial flash. I'm using a TL866II+ which is supported under Linux by the minipro project (it's also useful to reprogram BIOS chips); an alternative would be to program the chip with the graphics card (eg. https://github.com/ChalkElec/write-edid/blob/ … r/write-edid.sh) but I haven't tried it
  • Finally, you need two identical DVI-HDMI cable (or HDMI cable + adapter) on which the surgery will be performed. The first cable will be sacrificed to determine (using a multimeter in continuity test mode) which wires carry the signals of interest.

The procedure to create this custom EDID cable is as follows:

  • As noted above, cut the first cable, and identify with the help of the DVI pinout + continuity tester the following wires: 14 (+5V), GND, 6 (DDC clock), 7 (DDC data): see https://en.wikipedia.org/wiki/Digital_Visual_Interface
  • Carefully remove a small portion the plastic outer layer with a cutter, while being very careful not to cut any wires underneath.
  • Gently scrape the plastic top of the 5V and GND cables and solder a wire for each of them, add scotch tape to avoid shorts. Do not cut the wires as they are needed by the monitor.
  • Cut the DDC clock and data cables. Leave the monitor side unconnected, and solder wires to the graphics (DVI) side, again using scotch tape.
  • Attach the DIP8 socket to the cable with glue, and solder pins 1 to 4 (A0, A1, A2 & GND) of the socket together to the cable's GND wire.
  • Solder the data wire to pin 5, clock to pin 6 and VCC to pin 8 (leaving pin 7 unconnected): https://www.hobbytronics.co.uk/image/data/tut … out-24LC256.png

Now program the AT24C02C flash, eg. using minipro or the equivalent Windows software . Attached to this post are custom 1280x960 EDIDs I made with a software called AW EDID Editor (https://www.analogway.com/americas/products/s … aw-edid-editor/) that I found easy to use and very powerful.

./minipro -p 24LC02 -w edid-1280x960\@70.bin

Place the flash chip on the cable (check the orientation), reboot and if everything works the monitor is now showing a 1280x960 image at the chosen vertical refresh frequency! Apply electrical tape to secure the part of the cable where the plastic has been removed. Below is my modified HDMI extension cable with a DVI adapter attached:

Hacked-HDMI-EDID-cable.png
Filename
Hacked-HDMI-EDID-cable.png
File size
985.63 KiB
Views
1376 views
File license
Public domain

Amusingly, it is even possible to run games at 120 Hz with the appropriate EDID, which I tested with a HD 4000 (Core i7 3770K). I had to first boot with the hacked cable above, but the screen remained black. By removing this extender cable and plugging in an unmodified HDMI cable the screen would correctly display the 1280x960@120 Hz outputted by the card (it's possible the hack reduced the signal integrity, causing problem with this high pixel clock). Some games such as Jazz Jackrabbit do indeed run twice as fast as they should (Jazz Jackrabbit uses 320x199@60 Hz). It's not very practical or useful but fun nonetheless 😆

What about older PCs that lack an AGP port? Well the Radeon 9250 is available in PCI form, so this could be a solution for these PCs.

Attachments

  • Filename
    edid-1280x960.zip
    File size
    801 Bytes
    Downloads
    75 downloads
    File license
    Public domain
Last edited by cde on 2020-11-13, 17:45. Edited 4 times in total.

Reply 1 of 5, by darry

User metadata
Rank l33t++
Rank
l33t++

That is very nice indeed.

It is similar to the approach I used in this thread 70Hz in pure DOS at 1600x1200 (or other) over DVI on an old card (FX5900) with modern monitor is possible .

The main difference is that I used a ready-made programmable EDID emulator, while you have effectively built your own, which is way cooler, potentially more flexible and likely much cheaper !

EDIT: Adding a switch to bypass the custom EDID or maybe add a switchable bank of EEPROMs would make this even better, IMHO .

EDIT: Unfortunately, my Radeon 9700 does not want to output 1280x960 in DOS, no matter what I try in the EDID . I am using an FX 5900 and an FX5900XT at 1600x1200@70Hz with reduced blanking with a doctored EDID .

Reply 3 of 5, by cde

User metadata
Rank Member
Rank
Member

For completeness' sake, here are attached the EDIDs for 1440x1080 and 1600x1200 (both 60 Hz and 70 Hz)

Attachments

  • Filename
    edid-1440x1080.zip
    File size
    544 Bytes
    Downloads
    65 downloads
    File license
    Public domain
  • Filename
    edid-1600x1200.zip
    File size
    544 Bytes
    Downloads
    64 downloads
    File license
    Public domain

Reply 4 of 5, by Lumpmoose

User metadata
Rank Newbie
Rank
Newbie

It's also possible to flash an EEPROM if you have a Raspberry Pi lying around. I would recommend this guide to setup I2C and install i2c-tools. Then use this guide to find the right flashing program and this section to flash an A24C02-style EEPROM.

The RPi has GPIO pins already setup for I2C:
GPIO-Pinout-Diagram-2.png

Check your EEPROM's data sheet, but for me:
RPi pin 6 (ground) to EEPROM pins 1-4 (A0, A1, A2, GND)
RPi pin 5 (SCL) to EEPROM pin 6 (SCL)
RPi pin 3 (SDA) to EEPROM pin 5 (SDA)
RPi pin 1 (3v3 power) to EEPROM pin 8 (Vcc)

I left pin 7 (WP) on my EEPROM unplugged most of the time. For my IC, setting WP to power enables write protection while setting it to ground (or unplugged) allows writes.

Here's my RPi hooked up:

rpi-eeprom.jpg
Filename
rpi-eeprom.jpg
File size
246.61 KiB
Views
1211 views
File license
CC-BY-4.0

I'm using HDMI breakout boards for more flexibility and to avoid splicing cables. If I ever get good results, I hope to solder everything to a perma-proto board with DIP switches to switch between EEPROMs and cable pass-through.

These are the commands I used to flash the EEPROM. Modify based on your bus number, address and file name:
Find your i2c bus number: i2cdetect -l
After plugging in your EEPROM to the GPIO, find your i2c address on bus 1: i2cdetect 1
Examine the EEPROM's contents: i2cdump 1 0x50
Set a bit to test writing: i2cset 1 0x50 0xa8 0xaa
Write an EDID to the EEPROM: ./eeprog -i ./edid.bin -w 0x00 -t 5 /dev/i2c-1 0x50

Unfortunately my 144hz gaming monitor (ASUS ROG PG279, native 2560x1440@144hz) doesn't support 70hz. It jumps from 60 to 85 at all resolutions. Which sucks because it's beautiful in real DOS (hooked to a Radeon 9250) and automatically pillarboxes narrower resolutions. I'm also trying EDIDs with my Dell 1901FP (native 1280x1024). It does support 70hz, but both 1280x960 and 1024x768 are at full screen. It also has a lot of ghosting with dark colors, so I don't know if the scaling is really the culprit vs. being a slow LCD.

When the 1901FP is plugged into a newer GeForce card in Windows 10, I can add a custom resolution of 1280x960@70hz. The monitor reads it as 1280x1024@70hz but letterboxes the image:

dell-1901fp.jpg
Filename
dell-1901fp.jpg
File size
199.94 KiB
Views
1211 views
File license
CC-BY-4.0

Is there any EDID setting that can get that letterbox in DOS, or is it a feature of my Nvidia graphics card in Windows? I've been playing around with the vertical border size in the detailed timing block, but the monitor never wakes up with that set. I don't know if that requires tweaking CVT numbers or if the vertical border is something unrelated. Maybe I just don't have the right LCD for 70hz DOS.

Reply 5 of 5, by cde

User metadata
Rank Member
Rank
Member

Thank you for the detailed explanation about flashing with the Raspberry Pi, Lumpmoose! It is appreciated 😀

I believe one could also flash the I2C flash using the graphics card itself and Linux, using https://github.com/ChalkElec/write-edid or https://github.com/bulletmark/edid-rw but I haven't tried it myself.

About breadboards, keep in mind they are meant to be used for low speed signals, typically < 10 MHz. In this case the signals are clocked much higher, so you could improve signal integrity by directly connecting together the differentials pairs of your breakout boards using short cables of the same length, and optionally shielding the with ground.

About your monitor, the manual mentions variable refresh rate is only supported on the DisplayPort input, not the HDMI input. I suggest trying an HDMI-DP adapter, this way there is a chance 70 Hz will be accepted.

About letterboxing, yes it is indeed a feature of NVIDIA drivers. It could be replicated under DOS but you need to reverse engineer them to understand and replicate the sequence of register writes that create this 1280x960 4:3 aspect ratio over 1280x1024. In addition, if one could identify how to change the refresh rate then you would get letterboxed 1280x960@70 Hz without any EDID hack which is ideal. I tried to do it with a 9600 Pro but did not succeed even though R300 has the radeon open-source Linux driver. You could have a look at the nouveau driver for NVIDIA cards but it seems like a difficult task.

EDIT: just to mention in case someone stumbles upon this thread that the OSSC + a monitor with a 4:3 option & accepting 70 Hz without frame dropping (here the AOC G2590PX) has completely solved my issues. For more details see Re: Widescreen monitors and 4:3 aspect ratio compatibility thread