Let us posit that one has a need to obtain an image of the instrument ROM of an Ensoniq Soundscape S-2000, Elite, or OPUS sound card. There are two basic approaches: A) Desolder or cut off the ROM chip, plug into a PROM reader, extract the data; or B) Design and write software to read the ROM contents and leave the hardware intact. Method A) is crude but effective—very simple but potentially destroys the card. So let’s see how method B) might be done.
First it is necessary to understand the architecture of the Ensoniq Soundscape. This text will focus on the original S-2000 and Elite, with a brief note on the newer Opus and VIVO cards.
The S-2000 is a 16-bit sound card with an onboard synthesizer and instrument ROM. The card is compatible with Sound Blaster and AdLib (Yamaha OPL2/OPL3) standards, as well as MPU-401 and General MIDI, but the compatibility is implemented purely in software (firmware in fact). The S-2000 has four major chips, clearly seen in the above photo: Ensoniq ODIE (ES 5706), the system interface and control gate array; Ensoniq OTTO (ES 5506), the wavetable synthesizer chip; Analog Devices AD1848, the audio codec; and Motorola 68EC000, the OBP (On-Board Processor). There is also 128KB of DRAM for use by the OBP, and an instrument ROM with 1 or 2 MB of data (our target).
Much like it was the case with E-mu/Creative, Ensoniq’s sound cards were essentially the respective company’s cut-down synthesizers on an ISA card; in Ensoniq’s case it was the TS-10/TS-12. The Soundscape was clearly not intended for musicians (it was a consumer/gaming card) and therefore had no sampler functionality (no sample RAM), even though the OTTO synthesizer could have handled it without trouble.
Note: For reasons which are not clear, certain people think that just because a chip has ‘(C) SEQUOIA DEV GRP’ etched on it, it must be called “Sequoia”. Sequoia Development Group was in fact a company specialized in developing MIDI equipment and is known to have provided the firmware for the Logitech Soundman Wave card (Yamaha OPL4 synthesizer) or Samsung KS0164 and KS0165 synthesizer chips. The Ensoniq chip in question is clearly called ODIE.
Besides the instrument ROM, there is no other ROM on the Soundscape card. The OBP obviously needs some code to run; the firmware is uploaded into the RAM on the card by the host. There does not appear to be any way to read the ROM directly from the host (there’s no way to map it such that it would be accessible through memory or I/O space, and it does not appear to be accessible via DMA either). But the OBP firmware can and must access the instrument ROM, because the synthesizer chip has no direct understanding of the ROM; the OBP firmware reads the ROM to find out where and how the waveforms corresponding to specific instruments are stored, and directs the OTTO synthesizer chip to access the waveform data. In fact there are several OBP firmware versions corresponding to different instrument ROMs, and a miniature firmware module (SCOPE.COD) is used to read the ROM and report back to the host which actual firmware variant (SOUNDSCAPE.COx) it should upload.
The OBP firmware handles Sound Blaster emulation, AdLib emulation, as well as General MIDI. Thanks to this design, from the host side the S-2000 looks like a pure hardware implementation and doesn’t require any special TSRs or other software running on the host (unlike the later VIVO cards).
So all we need to do is write special firmware for the OBP, upload it to the card, and then communicate with it to obtain the ROM data. Should be easy, right? Well, perhaps not easy, but doable once we have the ODIE datasheet and some OSS/ALSA driver code which can upload the OBP firmware.
Custom OBP Firmware
As it turned out, writing the custom firmware was the easier part, even for someone with approximately zero knowledge of 68000 assembler. SCOPE.COD (part of the Soundscape driver package) proved to be an excellent example because it already accesses the ROM. There is one tiny wrinkle—for reasons that are not obvious, the OBP firmware files are byte-swapped. That means they must be un-swapped before any attempt to disassemble them, and the custom-built firmware image needs to be byte-swapped again before uploading to the OBP.
A brief attempt was made to extract the ROM contents via DMA. In theory it might be possible to have the OBP program ODIE to point at the instrument ROM and use DMA to transfer it to the host, but that didn’t work. Either some additional steps were needed or the ROM is actually not accessible to ODIE (entirely plausible, since ODIE doesn’t need it).
The working implementation uses a very simple approach: Read the ROM byte by byte and write it to ODIE’s host data communication register where the host can read it from. On both the OBP and host side there are status bits indicating whether the host data register is empty or full; that way we can implement simple and reliable transfer, with the OBP writing another byte once the data register becomes empty (i.e. host read it), and the host reading another byte once the data register becomes full (i.e. OBP wrote it). This is not blazingly fast, but dumping 2 MB of ROM this way still takes well under a minute on a 486 system.
For whatever reason, only every other byte contains ROM data, which means that odd bytes need to be skipped. And it is also worth mentioning that some higher-order address bits are ignored, which means the ROM is mapped multiple times into the OBP’s address space.
The EASy64K Editor/Assembler was used to assemble the custom firmware, SRecord version 1.64 was then used to convert it to binary and byte swap. Zero experience with Motorola 68000 assembly language proved to be of next to no consequence.
Host-Side ROM Extractor
Now for the host part. As mentioned above, the host side is far more complex, with several hundred lines of C code (compared to a handful of assembly instructions for the firmware).
The host tool runs under DOS for the sake of simplicity, and is written in 16-bit C. Using a 32-bit environment would be entirely possible but wouldn’t buy much. Using a “better” OS was rejected because it would only complicate the code and make much higher demands on the host system. The actual hardware used was an Alaris Cougar VLB board with a 66 MHz Intel 486 OverDrive processor and a CF to IDE adapter. The compiler used was Watcom C, primarily because it’s very easy to cross-compile from a Windows machine and do the bulk of development on a modern system (with the inevitable debugging and tweaks on the 486).
The host tool needs to detect an ODIE-based Soundscape card, perform basic initialization, set up host DMA controller, upload the firmware via DMA (potentially in multiple blocks), start the OBP, and communicate with the firmware using the host communication register.
There is a fair amount of code which needs to be in place before anything at all starts happening (never a good situation to be in). Fortunately it only took a few iterations to get to a point where the OBP firmware was successfully initialized—after crashing the host a few times due to incorrect programming of the host DMA controller.
The actual ROM dumping was quite easy and only needed proper observation of the empty/full status bits to reliably read a megabyte or two of data.
The completed ROM dumper is available here. It’s not particularly polished and has not been widely tested, but works on at least one system with several cards.
The Soundscape Opus (3000-series) is a lower cost OEM-only product. It has no provision for CD-ROM support but it does support PnP. The functionality of OTTO and ODIE appears to be integrated in a new chip called OPUS (likely ES 5530). Programming the OPUS chip is not significantly different from programming ODIE/OTTO. Instead of a separate DAC for the wavetable synth, everything is handled by an AD1845 codec. There is still a separate 68EC000 OBP and similar OBP firmware.
Adapting the ROM dumping tool for OPUS turned out to be trivial—all it took was adjusting the detection logic to accept the OPUS (the original detection failed because OPUS has more registers). The existing OBP firmware DMA upload logic worked just fine, and the firmware itself didn’t need any changes either.
The VIVO is a rather different beast. The 4000-series Soundscape VIVO uses a standalone OTTO synth again, but completely drops the OBP. What that means is that everything is run on the host CPU, using a rather clever patented technique which places a “TSR” into protected memory.
For the purpose of this project, the VIVO is a completely unrelated design because there’s no OBP, hence no OBP firmware. And also no documentation. On the other hand the VIVO uses the exact same instrument ROM as Opus, so there has been no real incentive to deal with the VIVO either.
It is worth noting that the VIVO is a clear evolutionary step between the original S-2000 and the 5000-series AudioPCI (one of the first PCI-based sound cards). The AudioPCI goes further and also drops the synthesizer chip, doing everything in software. But in principle the AudioPCI builds on the techniques pioneered by VIVO.
What does all this signify? Probably not much. Perhaps that a little bit of information can go a long way.