How it Works
Sound effects on the PC speaker operate by toggling the PC speaker in and out. This is done in the game's code by writing 0 or 1 directly to the PC speaker port 0x61. Depending on how quickly the direction of the speaker is toggled affects how quickly it physically moves and thus the frequency (tone) of the generated sound. Faster toggling (high frequency) results in higher-pitched sounds while slower toggling (low frequency) results in lower-pitched sounds. When U3 runs on faster computers (or a DOSBOX virtual machine with higher cycles) the code executes far more quickly than intended which results in sounds that are higher-frequency and shorter duration. If the virtual machine is fast enough, the code may execute so quickly that sound effects are nearly inaudible.
The way to remedy this is to pace the sound effect code against the system timer so that the speaker is toggled at a constant interval (and therefore constant frequency) on any system. The first timer (timer 0) is capable of sending an interrupt request at regular intervals. This is normally used to update the system clock at a frequency of 18.2 Hz, but it can be reprogrammed to run at custom frequencies as needed and invoke custom interrupt routines. The SFXTIMED.DRV works by reprogramming the timer to generate an interrupt at approx 104 kHz. The driver then uses 'hlt' instructions to wait for interrupts as needed within loops that manipulate the speaker.
There are two sound effects however that are exceptions to this convention. Both "invalid action" and "invalid command" play a constant tone, rather than the static-like or phased audio that is heard in other sound effects. For these effects, the SFXTIMED.DRV uses timer 2, which does not generate interrupts but interfaces with the PC speaker directly to produce sound at constant frequencies. This is a bit easier to program as you do not need the CPU to manually toggle the speaker in these cases.
Types of Sound Effects
Standard Sound Effects
- invalid action - played when the character cannot move in the requested direction
- invalid command - played when an invalid command is issued in the command window
- spell - used for the casting of spells, moongates, and combat victory tunes
- force field - stepping on force field
- attack - attack "swing" sound
- trap - affected by a trap
- fire - stepping in fire
- damage - the giving or receiving of damage
- movement - walking sound
- aoe spell - random sound effect that introduces AOE spells
- whirlpool - falling into a whirlpool
Additional Sound Effects
- intro - phasing in of the Exodus / Ultima III title
- dragon breath - dragon frying a party in the intro animation