OPL2LPT: an AdLib sound card for the parallel port

Vincent Bernat

The AdLib sound card was the first popular sound card for IBM PC—before that, we were pampered by the sound of the PC speaker. Connected to an 8-bit ISA slot, it is powered by a Yamaha YM3812 chip, also known as OPL2. This chip can drive 9 sound channels whose characteristics can be fine-tuned through 244 write-only registers.

AdLib sound card
A copy of an AdLib sound card from Monotech. The OPL2 chip is in the lower right part. Notable differences with the original include the volume potentiometer and the metal film resistors—instead of carbon film resistors.

I had one but I am unable to locate it anymore. Models on eBay are quite rare and expensive. It is possible to build one yourself (either Sergey’s one or this faithful reproduction). However, you still need an ISA port. The limitless imagination of some hackers can still help here. For example, you can combine Sergey’s Xi 8088 processor board, with his ISA 8-bit backplane, his Super VGA card, and his XT-CF-Lite card to get your very own modernish IBM PC compatible. Alternatively, you can look at the AdLib sound card on a parallel port from Raphaël Assénat.

The OPL2LPT sound card#

Recently, the 8-Bit Guy released a video about an AdLib sound card for the parallel port, the OPL2LPT. While current motherboards don’t have a parallel port anymore, it’s easy to add a PCI-Express one. I bought a pre-soldered OPL2LPT and a few days later, it was in my milk box:

OPL2LPT sound card
The OPL2LPT sound card on an original “Day of the Tentacle” box to indicate scale.

Update (2018-03)

You can also buy a 3D-printed enclosure for the OPL2LPT. After writing this article, I have been offered one:

OPL2LPT enclosure
The OPL2LPT sound card in its 3D-printed enclosure on a “Monkey Island 4” box.

Update (2018-07)

The OPL3LPT is now available. It features a similar design but with an OPL3 chip.

The expected mode of operation for such a device is to plug it into an ISA parallel port (accessible through I/O port 0x378), load a DOS driver to intercept calls to AdLib’s address, and run some AdLib-compatible game. While correctly supported by Linux, the PCI-Express parallel port doesn’t operate like an ISA one. QEMU comes with a parallel port emulation but, due to timing issues, cannot correctly drive the OPL2LPT. However, VirtualBox emulation is good enough.1

On Linux, the OPL2LPT can be programmed almost like an actual AdLib. The following code writes a value to a register:

static void lpt_write(uint8_t data, uint8_t ctrl) {
  ieee1284_write_data(port, data);
  ieee1284_write_control(port, (ctrl | C1284_NINIT) ^ C1284_INVERTED);
  ieee1284_write_control(port,  ctrl                ^ C1284_INVERTED);
  ieee1284_write_control(port, (ctrl | C1284_NINIT) ^ C1284_INVERTED);
}

void opl_write(uint8_t reg, uint8_t value) {
  lpt_write(reg, C1284_NSELECTIN | C1284_NSTROBE);
  usleep(4); // 3.3 microseconds

  lpt_write(value, C1284_NSELECTIN);
  usleep(23);
}

To “natively” use the OPL2LPT, I have modified the following applications:

  • ScummVM, an emulator for classic point-and-click adventure games, including many Lucas­Arts games—patch2
  • QEMU, a quick generic emulator—patch with a minimal emulation for timers and hard-coded sleep delays 🙄
  • DOSBox, an x86 emulator bundled with DOSpatch with a complete emulation for timers and a dedicated working thread3

You can compare the results in the following video, with the introduction of Indiana Jones and the Last Crusade, released in 1989:4

  • 0:00, DOSBox with an emulated PC speaker
  • 0:58, DOSBox with an emulated AdLib
  • 1:51, VirtualBox with the OPL2LPT (on an emulated parallel port)
  • 2:42, patched ScummVM with the OPL2LPT (native)
  • 3:33, patched QEMU with the OPL2LPT (native)
  • 4:24, patched DOSBox with the OPL2LPT (native)
  • 5:17, patched DOSBox with an improved OPL3 emulator (Nuked OPL3)
  • 6:10, ScummVM with the CD track (FM Towns version)

I let you judge how good each option is! There are two ways to buy an OPL2LPT OPL3LPT: in Europe, from Serdashop or in North America, from The 8-Bit Guy.

Addendum#

Indiana Jones and the Fate of Atlantis#

Here is another video featuring Indiana Jones and the Fate of Atlantis, released in 1992, running in DOSBox with the OPL2LPT. It’s the second game using the iMUSE sound system: music is synchronized with actions and transitions are done seamlessly. Quite a feat at the time!

Monkey Island 2#

The first game featuring iMUSE is Monkey Island 2, released in 1991. The video below displays the first minutes of the game, running in DOSBox with the OPL2LPT.

Notably, at 5:33, when Guybrush is in Woodtick, a small town on Scabb Island, the music plays around a variation of a basic theme with a different instrument for each place without any interruption.

How the videos were recorded#

With a VGA adapter, many games use Mode 13h, a 256-color mode with a 320×200 resolution. On a 4:3 display, this mode doesn’t feature square pixels: they are stretched vertically by a factor of 1.2.

The above videos were recorded with FFmpeg (and edited with Blender). It packs a lot of useful filters making it easy to automate video capture. Here is an example:

FONT="font=Monkey Island 1991 refined:
      fontcolor=OrangeRed:
      fontsize=16:
      x=w-text_w-10"
ffmpeg -y \
  -thread_queue_size 64 \
  -f x11grab -draw_mouse 0 -r 30 -s 640x400 -i :0+844,102 \
  -thread_queue_size 64 \
  -f pulse -ac 1 -i default \
  -filter_complex "[0:v]pad=854:400:0:0,
       drawtext=${FONT}:y= 10:text=Indiana Jones 3,
       drawtext=${FONT}:y= 34:text=Intro,
       drawtext=${FONT}:y=100:text=DOSBox,
       drawtext=${FONT}:y=124:text=VGA,
       drawtext=${FONT}:y=148:text=PC speaker,
       scale=854:480:flags=neighbor[game];
       [1:a]volumedetect;
       [1:a]showwaves=s=214x100:colors=OrangeRed:scale=lin[waves];
       [1:a]showcqt=s=214x100[spectrum];
       [waves][spectrum]vstack[vis];
       [game][vis]overlay=x=640:y=280" \
  -pix_fmt yuv420p -c:v libx264 -qp 0 -preset ultrafast \
  indy3-dosbox-pcspkr.mkv

The interesting part is the filter_complex argument. The input video is padded from 640×400 to 854×400 as a first step to a 16:9 aspect ratio.5 Using The Secret Font of Monkey Island, some text is added to the right of the video. The result is then scaled to 854×480 to get the final aspect ratio while stretching pixels to the expected 1.2 factor. The video up to this point is sent to a stream named game. As a second step, from the input audio, we build two visualizations: a waveform and a spectrum. They are stacked vertically and the result is a stream named vis. The last step is to overlay the visualization stream over the gameplay stream.