Bring in SB16/WSS support (bufferless SB DSP, AD1848, SB mixer, IRQ/DMA configuration) and 0.12 fixed-point volume scaling from wss-sb16, and combine with stereo OPL3 pipeline and lock-free SPSC audio FIFO from sb16_merge.
Conflict resolutions:
- volctrl.h: use 0.12 scale from wss-sb16 (no int64_t)
- sbplay.cpp: keep stereo opl_resample_tick() with clamp16 before resampler buffers; lock-free SPSC FIFO reads with stereo volume; add sbdsp_process() from wss-sb16
- pgusinit.c: use wss-sb16's full BLASTER parser (A/I/D/H/T fields)
Adds ymfm as a new OPL synthesis backend alongside the existing emu8950
implementation, selectable at compile time via USE_YMFM_OPL / USE_YMF3812.
- ymf262 (OPL3): 18-channel true stereo via data[0]/data[1] (L1/R1)
- ym3812 (OPL2): mono, duplicated to both channels
- Pre-generation buffer (128 samples) for cache-efficient synthesis
- Stereo FIFO pipeline in sbplay: interleaved L/R pairs, proper resampling
from 49716 Hz to 44100 Hz via Q16.16 phase accumulator
- OPL3 bank 2 port handling in SOUND_SB path (ports +0xA/+0xB) and
SOUND_OPL path (port mask widened to 0x3fc, case 2/3 added)
- opl_addr widened to uint16_t to carry the 0x100 bank 2 flag
- OPL3 bank 2 status read port (oplBasePort+2) added to IOR handler
- Panning bits default to 0x30 (L1+R1) for 0xC0-0xC8 regs when unset,
preventing channels from going silent after newflag (reg 0x105) is set
- pgusinit: BLASTER T type now accepts T3-T6 (adds SB16 OPL3 / AWE32)
- Removed OPL cmd buffer drain spin-wait from IOR path (timer regs are
handled on core 0, no drain needed)
Restoration of prior pgusinit functionality:
- Case insensitive command line switches
- Bail out if there are errors detecting the card
- Bail out on firmware mismatch, but allow flashing new firmware
More QoL improvements:
- Generic paging interface that detects rows on screen
- /? and /?? are paged
- /cdlist uses new paging interface
More clean up to main(). I am finding there is some overlap with the term "mode" which indicates the global card mode (ex. SB_MODE, GUS_MODE, etc) as well as register modes communicating with PicoGUS. The next commit I will probably spend some time distinguishing these two types for clarity.
Refactored the inline argument commands into functions that iterate through a command table. This should help make input commands more robust and easier to expand.
It also allows for default values when setting options. For example if the user wants a default value for the OPL port, they can use "/oplport default".
Since /sbport and /gusport always check the environment for SET BLASTER and SET ULTRASND, I added the function for pgusinit to retrieve these values from the environment directly. This could open up environment parsing for other variables in the autoexec.bat.
The commands should behave exactly as I did when they were inline to start, but can now easily be expanding.
- Fix memory leak when changing images (file handle not freed)
- Longer max file length limit (127 chars)
- Better errors when USB not present
- Fix polling of CD status register when listing images
- Add ability to load image by name
- Many weird edge cases with image loading state fixed