npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

ds4qb-web

v2.0.0

Published

Extensions for v86 to emulate the DS4QB audio library

Readme

ds4qb-web

Release NPM Version License: MIT

Implementation of the DS4QB, DS4QB2, and DS4QB++ audio protocol for DOS games running in the V86 in-browser PC emulator.

What is it?

DS4QB ("DirectSound for QB") and its family (DS4QB2 and DS4QB++) were sound libraries for DOS games which used unusual methods (the DOS clipboard API and the legacy DMA controller) to communicate with a Win9X audio server.

ds4qb-web is a browser-based server for the DS4QB protocols, allowing these games to be easily played in a browser with a DOS guest OS. It leverages v86, Howler.js, and chiptune3.js.

Try it out

A gallery of nearly 30 DS4QB games and apps: Link

A sample project using Vite and TypeScript: Open in StackBlitz

Features

  • Enables audio for DS4QB, DS4QB2, and DS4QB++ games in the browser
  • .MOD, .WAV, .MP3 support with volume, fading and panning
  • Bundler-friendly distribution with TypeScript and ESM support
  • Automatically installs and runs .zip packed games
  • Options to configure mouse, EMS

Getting Started

ds4qb-web needs a few files for the emulator to use

  • An X86 BIOS image - seabios is a free open source one
  • An X86 VGA BIOS image - I recommend Bochs since seabios has some bugs that affect QBasic
  • A floppy disk image containing a DOS BOOT disk. You can find FreeDOS boot disks here.
    • For DS4QB1 support, needs to contian CLIPEMU.COM.
    • For mouse support, needs to contain MOUSE.COM.
    • For EMS support, needs to contain EMSMAGIC.EXE.

Since V86 isn't distributed via npm, it must be available in the global object:

<!-- put this before your own code -->
<script src="libv86.js"></script>

After that, add an HTML element to use as the screen:

<div id="screen_container">
    <div style="white-space: pre; font: 14px monospace; line-height: 14px"></div>
    <canvas style="display: none"></canvas>
</div>

And start the emulator with the attachDs4qb function:

import { attachDs4qb } from 'ds4qb-web';

attachDs4qb(V86, {
    // ds4qb-web options:
    content: { url: "url_to_game.zip" },
    autoExe: "MYGAME.EXE",

    // v86 options
    screenContainer: document.getElementById('screen_container'),
    bios: { url: "url_to_bios.img" },
    vgaBios: { url: "url_to_vgabios.img" },
    fdaImageFile: { url: "url_to_dos_disk.img" }
    v86WasmUrl: { url: "url_to_v86.wasm" }
})

API Documentation

attachDs4qb Function

ds4qb-web is a single function to initialize and start an emulator

attachDs4qb(V86: function, options: DS4QBOptions): Promise<UInt8Array>

| Parameter | Type | Description | | --------- | ------------ | ----------------------------------------------- | | V86 | function | The constructor for V86 (it is not distributed via npm, so it must be imported by user and passed manually) | | options | DS4QBOptions | Configuration options. See below for details |

The function returns the generated FAT disk image containing the .zip contents, as a byte array.

DS4QBOptions Type:

The attachDs4qb options parameter is an object with a mix of V86 options and ds4qb-web options

ds4qb-web options:

| Property Name | Type | Description | | --------------- | ------------- | ------------------------------------------ | | content | FileReference | .zip file containing the DOS app to run | | protocol | string | Library: 'ds4qb', 'ds4qb2', or 'ds4qb++' | | autoExe? | string | Shell command to start the app (optional) | | ds4qbDatPath? | string | Path to DS4QB2.dat (optional) | | configPath? | string | Path to SOUNDSYS.CFG (optional) | | workingDir? | string | "Root" path to use for audio file paths | | addMouse? | boolean | Runs MOUSE.COM at start if true (optional) | | addEms? | boolean | Runs EMSMAGIC at start if true (optional) |

v86 options: | Property Name | Type | Description | | --------------- | ------------- | ------------------------------------------ | | screenContainer | HTMLElement | HTML container with a canvas for screen | | biosFile | V86FileSource | x86 BIOS image | | vgaBiosFile | V86FileSource | x86 VGA BIOS image | | fdaImageFile | V86FileSource | DOS boot disk image | | v86WasmUrl | string | URL to V86 WASM file |

FileReference Type

Refers to a file by URL, an ArrayBuffer with the file, or a UInt8Array to the file.

{ url: string } // Pass a URL to the file
{ array: Uint8Array } // Pass a typed array to the file
{ array: ArrayBuffer } // Pass an array buffer to the file

V86FileSource Type

V86 accepts files as either a URL or an ArrayBuffer with the file

{ url: string } // Pass a URL to the file
{ array: ArrayBuffer } // Pass an array buffer to the file

Contributing

If you want to contribute, please contact me because that means you're one of the dozen people who remember this library and we probably knew each other.