VOGONS


First post, by vorvek

User metadata
Rank Newbie
Rank
Newbie

I don't know where to post about this, I hope this is the right forum. I recently released a virtual cdrom driver for DOS that emulates CD-audio, kind of. I followed the SBEmu route, and used port trapping to mix the uncompressed audio from a .bin file into the stream of audio from an application. I made it this to solve a personal problem, as I seem to find only failing cd-rom drives that die on me after a few months or are too weak to read games consistently, or simply work poorly with CD-R. Or I'm trying to play an original disc that's scratched.

Anyway, here it is working with Quake in an Athlon 600:
https://youtu.be/d03dErJ5VU8

It also has multi-disc support with an image list file (one image location per line) that can then be accessed with ctrl+alt+1 to ctrl+alt+0. Max 10 images, but more than enough for The 7th Guest or Phantasmagoria.

The driver in question is released under GPL3 and can be found here: https://github.com/vorvek/uCDD

The video is a slightly older version, but size is similar. The driver takes around 8KB of conventional memory, ~30KB of UMB and loads most stuff in XMS. It requires a driver that can do port trapping, I developed it with JEMMEX as a base, but extended it to use HIMEM/EMM386. I think 386MAX is also compatible, as it seems to use an extended EMM386 API, or something very similar. I can't vouch for other EMM drivers. Of course, JEMM itself works too if you don't want to use the whole JEMMEX package.

Anyway, I developed it under my own toy emulator and 86box. I've only been able to test it in the Irongate Athlon 600 I have with me, with a few games (Quake, Tomb Raider, Screamer...). I'm sure there may be some games that don't work, or some combination of hardware where it doesn't work either. I probably wouldn't use it in anything slower than a Pentium.

The driver was originally written for SB16 and WSS, I extended it to work with SBPro and SB1.0/1.5/2.0. It taps the port and DMA you set in the BLASTER variable, alongside 530 for WSS. It requires setting the output with UCDDSET. It does sample rate conversion (so, if you have a SBPro it outputs Redbook audio at 22.05khz in stereo instead of 44.1khz in mono, for example) and it also traps the keyboard interrupts, to allow changing discs.

I will mention, I did get help from ChatGPT on various parts of the driver, as some people may have issues with that.

Reply 1 of 11, by davidmorom

User metadata
Rank Newbie
Rank
Newbie

This is a very interesting project! I've been doing some testing and I found the following results.

I did the tests on both 86Box (several machine configurations) and a MVP3 Socket 7 with an AMD K6-2 at 400MHz, 128MB and a SB16 Vibra16 CT4180. For the software I used MS-DOS 6.22 and Windows 9x DOS mode, with MSCDEX and SHSUCDX, HIMEM.SYS and EMM386.EXE. I got basically the same results in all cases.

Real mode games seem to work pretty well. I tested the CD versions of Loom and Monkey Island 1 and they seem to be perfectly playable. Only for this, this is a great project.

For 32 bits protected mode games the history is totally different. I was only able to get Quake working (which uses CWSDPMI.EXE), and although the demo mode works pretty good, navigating trough the menus makes the computer reboot randomly. But the main problem is with DOS/4GW games, I tested Tomb Raider and Carmagedon, and after running the installer or the main executable, the DOS/4GW banner is displayed, the computer hangs for several minutes and finally shows an error about being unable to access the CD-ROM or loading the executable.

How did you manage to get Tomb Raider and Screamer working? Maybe I'm miss configuring something, but I tested everything that came to my mind. I also tried with JEMMEX, JEMM386 and 386MAX, but I always get the message "The memory manager rejected the port-trap request" when trying to load the driver.

Thanks for your work!

Reply 2 of 11, by vorvek

User metadata
Rank Newbie
Rank
Newbie

Thank you for giving it a try!

I had gone away from the driver for a couple of days and there were way more failures left than I expected!

When it comes to JEMMEX, it only works (worked) with 5.86; 5.87pre1 changes the callback interface, so it wasn't compatible. I've added support for that version too.

I tested with Tomb Raider again, and it didn't work for me either. I think I may have broken it when I was trying to get the driver's memory footprint smaller, should have re-checked.
I've fixed the issue (A20 corruption and stack failure caused by interrupt re-entry) and Tomb Raider worked again. Then I went through another bunch of games looking for different DPMI hosts and found a whole lot of problems.

- Carmageddon (DOS4GW) had Redbook audio but not sfx because it uses a 3840 byte audio ring and uCDD required a power of two size. I removed the requirement and that fixed it, but then DOS4GW complained about an invalid opcode in the sound driver.
- Archimedean Dynasty (Causeway 3.25) loaded but then crashed in the menu, then I got the music working but again no SFX. Here the problem was a byte read from the DSP reset port that the driver had no handler for. Now it behaves correctly.
- Quarantine (w/DOS32A), Rayman (PMODE/W) and Street Fighter II Turbo (Borland 32RTM) exposed other issues that I still need to fix.

The 0.9.1 beta release is available here: https://github.com/vorvek/uCDD/releases/tag/v0.9.1 Other games I have not tested that weren't working may now work, too.

Reply 3 of 11, by vorvek

User metadata
Rank Newbie
Rank
Newbie

I found another problem while testing Archimedean Dynasty under Microsoft EMM386. Its port-trapping API cannot trap ports below 100h, which includes the DMA controller registers. When the game and uCDD share the physical 16-bit DMA channel, the game can overwrite uCDD’s DMA settings. In my test, this caused clicks and then a crash. SBEMU faces a very similar issue, and I don't really think there's a good way of solving it in the driver itself. So, the two workarounds:
* The same shared-DMA setup works under JEMMEX.
* With EMM386, using physical DMA 7 for uCDD and virtual DMA 5 for the game avoided the menu audio failure. uCDD’s settings in UCDDSET must match the physical card’s actual configuration. The game should instead match the virtual settings in BLASTER, which must be set before installing uCDD. Both audio streams still play through the same card.

In any case, I've corrected the interrupt timer after STI which had a problem in the previous versions, and made a couple of changes to the entry stack allocation. Latest version is here: https://github.com/vorvek/uCDD/releases/tag/v0.9.1a

Reply 4 of 11, by davidmorom

User metadata
Rank Newbie
Rank
Newbie

Great work! Now Quake doesn't reboot, and Tomb Raider and Carmageddon seems to be working quite well. I found issues with the following games:

  • Screamer, Screamer 2 and Screamer Rally: the three games ask for the CD just before reaching the main menu. Screamer 1 has an attract mode that seems to work fine, but after that it asks for the CD.
  • Pro Pinball The Web and Timeshock: both games show the message "error initialising cdrom routines" just after launch.

Reply 5 of 11, by vorvek

User metadata
Rank Newbie
Rank
Newbie

Thanks for testing!

The Screamer games stopped working because I was sending a valid-in-practice 26-byte READ LONG packet through MSCDEX function 1510h; uCDD insisted on 27 bytes and returned 810Ch (“bad request length”). It was a small fix, but exposed a different issue that made loads take a long time (even though the game itself run fine). When loading for the first time, these games malloc/free bigger and bigger memory chunks to see how much RAM they have available. The DPMI host uCDD used run on 4KB pages that it asked the EMM handler each time, so it was painfully slow, and the more memory, the worse it got. I tested in my Athlon 600 with 512 megs of RAM and it took nearly three minutes to move from the DOS4GW prompt to the attract demo. It's now fixed too, with a reusable pool of VCPI pages. This also works with JEMM/JEMMEX.

Pro Pinball failed because uCDD's DPMI host was missing a particular behavior. The games use INT 31h, AX=0300h with two protected-mode stack words, and the uCDD rejected any nonzero stack copy.

So, those 5 games now also work under uCDD!
Updated version is here: https://github.com/vorvek/uCDD/releases/tag/v0.9.1b

Reply 6 of 11, by MarmotaArmy

User metadata
Rank Newbie
Rank
Newbie

HI , this project is super interesting, thanks!
I know it's in early stages , do you have a guess of system requirements for a smooth operation? you think a 486 or 386 could handle the load?

Last edited by MarmotaArmy on 2026-09-23, 18:13. Edited 1 time in total.

Reply 7 of 11, by vorvek

User metadata
Rank Newbie
Rank
Newbie

At the moment I only have my Athlon 600 for testing, so I can't be sure, but I imagine a Pentium or thereabouts probably make a good baseline, since simply streaming audio takes around 800KB/s.

Reply 8 of 11, by davidmorom

User metadata
Rank Newbie
Rank
Newbie

Awesome progress one more time!

I found another problematic game, this time is a real mode one, the enhanced CD-ROM version of Battle Chess. Running the game in Sound Blaster mode (/SB switch) gives an error about DMA channel, in Sound Blaster Pro mode (/SBP switch) the game runs, but there is no sound at all, neither SFX effects nor CD-DA music. Also there is something weird with this CD image, UCDD refuses to mount it although the CUE doesn't have any PREGAP or any other unsupported flags. I had to regenerate the image by opening and saving it with UltraISO, maybe there is something wrong with the CUE parser or any other checks UCDD performs on the image file.

If you are interested in having more feedback, I have a lot of games I can test when I have some free time. Won't be an intensive test, just checking the game installs, runs, gets in game and sounds fine.

Thanks again for your work, this is becoming a great project with very big potential.

Reply 9 of 11, by vorvek

User metadata
Rank Newbie
Rank
Newbie

Did you save the original cue by any chance to see what could have caused the parser to fail?

I imagine you tried with EMM386, can you check with JEMMEX to see if the DMA error goes away? EMM386 can't trap ports under 100h, so it gets a bit tricky. With uCDD you basically get a "virtual" card the games talk to, and uCDD connects the IRQ/DMA with the real card with the settings you give it in UCDDSET. In JEMMEX I can trap the DMA ports, but in EMM386 they need to be different for the virtual and physical card. The problem is some games allow setting a low DMA and not a high DMA (eg, Screamer) so if you use UNISOUND like me, you may end up having to set up two different BLASTER vars before and after initializing the physical card. I'm looking to make the set up a bit cleaner and more easy to understand, maybe extending UCDDSET.

Reply 10 of 11, by davidmorom

User metadata
Rank Newbie
Rank
Newbie

I'm currently using JEMMEX with shared DMA config, but different IRQs (cause Tomb Raider crash if I use IRQ5 for both real and virtual card, but maybe this is already fixed). These are my current CONFIG and AUTOEXEC files:

DOS=HIGH,UMB
DEVICE=C:\JEMMEX\JEMMEX.EXE I=B000-B7FF
FILES=30
@ECHO OFF
PROMPT $p$g
PATH C:\DOS
SET TEMP=C:\DOS
LH KEYB SP,,C:\DOS\KEYBOARD.SYS

SET BLASTER=A220 I5 D1 H5 T6
C:\DOS\UNISOUND.COM

SET BLASTER=A220 I7 D1 H5 T6
LH C:\DOS\UCDD.EXE -install -ems
C:\DOS\SHSUCDX.COM /D:UCDD0001

With this configuration Battle Chess exposes the behaviour I commented on the previous post. The CUE file I have is the following (it is from eXoDOS v6):

FILE "CHESS.bin" BINARY
TRACK 01 MODE1/2352
INDEX 01 00:00:00
TRACK 02 AUDIO
INDEX 01 09:58:12
TRACK 03 AUDIO
INDEX 01 25:22:00
TRACK 04 AUDIO
INDEX 01 27:27:45
TRACK 05 AUDIO
INDEX 01 30:09:02
TRACK 06 AUDIO
INDEX 01 32:55:52
TRACK 07 AUDIO
INDEX 01 35:40:52
TRACK 08 AUDIO
INDEX 01 38:29:02
TRACK 09 AUDIO
INDEX 01 41:17:60
TRACK 10 AUDIO
INDEX 01 41:42:40
TRACK 11 AUDIO
INDEX 01 42:05:20
TRACK 12 AUDIO
INDEX 01 42:29:65
TRACK 13 AUDIO
INDEX 01 42:53:52
TRACK 14 AUDIO
INDEX 01 43:17:07
TRACK 15 AUDIO
INDEX 01 43:41:07
TRACK 16 AUDIO
INDEX 01 44:04:45
TRACK 17 AUDIO
INDEX 01 44:27:10
TRACK 18 AUDIO
INDEX 01 44:52:70
TRACK 19 AUDIO
INDEX 01 45:15:47
TRACK 20 AUDIO
INDEX 01 45:40:42
TRACK 21 AUDIO
INDEX 01 46:18:10
TRACK 22 AUDIO
INDEX 01 47:43:35

Funnily, if I change track 2 from "INDEX 01 09:58:12" to "INDEX 01 11:00:00", it can be mounted. Mounting the BIN without the CUE works also. Does UCDD perform some checking on the track boundaries?

Reply 11 of 11, by vorvek

User metadata
Rank Newbie
Rank
Newbie

Thanks for the CUE and configuration. Beta 0.9.1c addresses these issues:

For Battle Chess:
- The original CUE: was valid. uCDD rejected it because the disc’s filesystem reports a size extending into the audio tracks. That check is now fixed; the original image and track timings should now work.
- Sound Blaster mode: Fixed the DMA detection that caused the /SB error.
- Sound Blaster Pro mode: Fixed the missing effects, and as a bonus added support for the filtering bit. CD music playback is fixed too.
For Tomb Raider:
- I've fixed the startup problem when the physical and virtual cards both use IRQ5 under JEMMEX. Tomb Raider was writing directly into the real-mode interrupt vector. uCDD intercepted vector changes made through DOS and DPMI calls, but real-mode writes displaced uCDD's audio handler and reached the game's handler instead of the virtual mixer. The physical interrupt remained in service, but the mixer stopped progressing, and that caused the hang. With two different IRQs there was no collision, so everything seemed to work.

JEMMEX is now the default memory manager for the project, I'm downgrading EMM386 to best effort because it's proving to be a pain in the ass!

More reports like this would be very useful!