In the interest of catching up, here is the second blog that is long overdue. I want to talk about the DreamBlaster S2P from Serdaco. I received mine over a year ago, and it actually was an early prototype.
The DreamBlaster S2P is based on the DreamBlaster S2 WaveBlaster module. It uses a Dream SAM2695 synthesizer chip. This chip has two MIDI interfaces. The regular DreamBlaster S2 uses the standard serial MIDI interface. The DreamBlaster S2P makes use of the special parallel interface, which allows you to send MIDI data one byte at a time over a parallel bus, such as an ISA bus, or in this case a printer port. It uses a similar approach to the OPL2LPT and OPL3LPT.
When I got it, it was still in the early stages of development, and nobody managed to get it to work properly yet. I tried a few things to see if I could get it working, but sadly it didn’t work. As it turned out, a patch wire was required. Pdewacht got it to work eventually, and he modified SoftMPU to support the DreamBlaster S2P. Based on his working code, I could get mine to work as well. In the final version that is now available, the problem with the patch wire is fixed in the design. A reset button was added to the design as well.
So what can you do with it? Well, the most obvious use case for now, is to use SoftMPU to play games with General MIDI support over an MPU-401 interface. This requires a 386 or better CPU. This is a very early video made by Serdaco when the device was working with SoftMPU for the first time:
The SAM2695 also has an MT-32-compatible mode, and I added a patch to support it in SoftMPU. Here are two early videos I made, to demonstrate.
The first video is an early test, where I use my own MIDI player with a captured MIDI file from Monkey Island (a game with MT-32 music, not General MIDI). First you hear it in General MIDI mode, then you hear it in MT-32 mode:
Pay no attention to the haphazard timing, it was still an early version of the MIDI playback routine. What you can hear is how the instruments sound very wrong in General MIDI mode. In MT-32 mode, the instruments sound much more like how the composer intended.
The second video is with my modified SoftMPU, running the actual game in MT-32 mode:
Also, like with the OPL2LPT, it is possible to patch native support into games. This means you will not need SoftMPU, so you also will not need a 386 or higher if the game does not require it. It can also work with protected mode games, which SoftMPU does not currently support. You can find S2PPATCH here. It currently works with DOOM and other games using the same sound engine (Heretic, Hexen, Raptor: Call of the Shadows, etc.), and with games that use the Miles Audio Interface Library, both 16-bit and 32-bit.
However, I think the most interesting application of this device would be with newly written games, demos and other software. The same goes for the OPL2LPT and OPL3LPT. If you write new software, and you already want to support MIDI/OPL2/OPL3 music, it is trivial to add native support for these devices. You will not need SoftMPU, and you will not require a 386. The parallel port protocol is very simple, and takes barely more CPU time than a regular ISA device. So even on an 8088 at 4.77 MHz, these devices are a very realistic target, when used natively.
So I decided to add support for the DreamBlaster S2P to my MIDI player, and tried it on an 8088:
That worked quite well. All the complex timing is precalculated into a simple stream of delay values, adjusted for the PIT resolution, and blobs of MIDI data to send directly to the interface. No problem for an 8088.
So I decided to see if I could go even more low-end. I fine-tuned my assembly-optimized player routines, so they could run on my 128k IBM PCjr:
Even that works fine! It actually streams the data from floppy, because the MIDI file was too large to fit in memory. If you listen closely, you can hear the floppy drive reading the next bit of data. Because the PCjr does not have a DMA controller, it actually pauses the music for a bit. On a regular PC, the read would have happened in the background, and the music would continue playing. I suppose there are only two ways to avoid that: making smaller MIDI files, or using compression to be able to fit everything into memory, and decompress on the fly.
Basically, as far as sound devices for oldskool machines go, I would say that the DreamBlaster S2P is by far the best option on the market. It is cheap, and its sound quality is well above FM synthesis, comparable with General MIDI devices such as the Roland Sound Canvas. And because it is a complete synthesizer chip with built-in MIDI interpreter, it also has an extremely low CPU load for playing music. Much lower than an FM chip. So you have low cost, ease of use, good quality and light on resources. That is a tough act to follow.
Also perhaps good to point out: although these devices come from the DOS scene, they can obviously be used on any machine with a standard Centronics parallel port implementation. In fact, you could probably adapt the interface to various other bus types quite easily as well. All you need is an 8-bit parallel data bus (write-only is enough), and a few control lines that you can toggle (2 to 4 lines is enough). I can imagine a simple adapter for a Commodore 64 userport for example.
To help others to support the Serdaco LPT interfaces, I dediced to make my routines available, in a simple Serdaco SDK. This contains some C and ASM code to initialize the devices and send data to them. It should make it very easy for people developing their own games and demos to add support for these devices.
I have actually had this idea of an oldskool DOS SDK for much longer. I have collected a reasonable amount of code for low-level hardware access on early PCs during my travels. The current Serdaco SDK is a subset of that. I want to release a bigger SDK at some point, which also includes support for regular OPL2, OPL3, SAA1099 (C/MS and GameBlaster), SN76489 (PCjr and Tandy), Sound Blaster, IBM Music Feature Card, Roland MPU-401, CGA, EGA, VGA, MDA, Hercules and related stuff.
I am basically trying to model this somewhat after the Amiga NDK. This is a collection of headers for C and ASM for the Amiga, with definitions for all the custom chipset registers and flags, and also the Kickstart and WorkBench libraries. I want to do the same, but for DOS-based PCs. It should bridge the gap between reading some technical manuals and getting the proper values for registers and such in actual code. I also want to include some basic helper functions and example code, so people can experiment with some code that is known to work on real hardware, and get up and running more quickly. I hope it will also aid the problem of people only developing on emulators, and creating code that doesn’t actually work on real hardware.
Pingback: Just keeping it real at Revision 2019 | Scali's OpenBlog™
Pingback: Retro programming, what is it? | Scali's OpenBlog™