DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/sblaster.cpp
00001 /*
00002  *  Copyright (C) 2002-2020  The DOSBox Team
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License along
00015  *  with this program; if not, write to the Free Software Foundation, Inc.,
00016  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  */
00018 /* TODO: I noticed a "bug" on a SB16 ViBRA where if you use single-cycle DMA
00019  *       playback with DSP 4.xx commands with the FIFO enabled, the card seems
00020  *       to buffer through the FIFO, play the block, and then when the DSP
00021  *       block completes, doesn't play what remains in the FIFO and stops
00022  *       immediately. So, if you do very small DSP block single-cycle transfers
00023  *       using the SB16 0xB0-0xCF DSP commands, the audio will play fast because
00024  *       the last 16-32 samples are being skipped, effectively.
00025  *
00026  *       I also noticed (related to this) that Creative's documentation only
00027  *       lists using 0xB0/0xC0 for single-cycle playback, OR using 0xB6/0xC6
00028  *       for autoinit playback, in other words either single-cycle without FIFO
00029  *       or autoinit with FIFO.
00030  *
00031  *       Also noticed is that the DSP "nag" mode in my test program can interrupt
00032  *       the SB16's DSP chip at the right time (with auto-init DMA) that it can
00033  *       cause the DSP to drop a byte and effectively cause stereo left/right
00034  *       swapping. It can also cause 16-bit DMA to halt.
00035  *
00036  *       As usual, expect this to be a dosbox.conf option --Jonathan C. */
00037 
00038 /* FIXME: Sound Blaster 16 hardware has a FIFO between the ISA BUS and DSP.
00039  *        Could we update this code to read through a FIFO instead? How big is this
00040  *        FIFO anyway, and which cards have it? Would it also be possible to eliminate
00041  *        the need for sb.dma.min? */
00042 
00043 #if defined(_MSC_VER)
00044 # pragma warning(disable:4244) /* const fmath::local::uint64_t to double possible loss of data */
00045 # pragma warning(disable:4305) /* truncation from double to float */
00046 # pragma warning(disable:4065) /* switch without case */
00047 #endif
00048 
00049 #include <iomanip>
00050 #include <sstream>
00051 #include <stdlib.h>
00052 #include <string.h>
00053 #include <math.h> 
00054 #include "dosbox.h"
00055 #include "inout.h"
00056 #include "mixer.h"
00057 #include "dma.h"
00058 #include "pic.h"
00059 #include "bios.h"
00060 #include "hardware.h"
00061 #include "control.h"
00062 #include "setup.h"
00063 #include "support.h"
00064 #include "shell.h"
00065 using namespace std;
00066 
00067 void MIDI_RawOutByte(Bit8u data);
00068 bool MIDI_Available(void);
00069 
00070 #define SB_PIC_EVENTS 0
00071 
00072 #define DSP_MAJOR 3
00073 #define DSP_MINOR 1
00074 
00075 #define MIXER_INDEX 0x04
00076 #define MIXER_DATA 0x05
00077 
00078 #define DSP_RESET 0x06
00079 #define DSP_READ_DATA 0x0A
00080 #define DSP_WRITE_DATA 0x0C
00081 #define DSP_WRITE_STATUS 0x0C
00082 #define DSP_READ_STATUS 0x0E
00083 #define DSP_ACK_16BIT 0x0f
00084 
00085 #define DSP_NO_COMMAND 0
00086 
00087 #define DMA_BUFSIZE 1024
00088 #define DSP_BUFSIZE 64
00089 #define DSP_DACSIZE 512
00090 
00091 //Should be enough for sound generated in millisecond blocks
00092 #define SB_SH   14
00093 #define SB_SH_MASK  ((1 << SB_SH)-1)
00094 
00095 enum {DSP_S_RESET,DSP_S_RESET_WAIT,DSP_S_NORMAL,DSP_S_HIGHSPEED};
00096 enum SB_TYPES {SBT_NONE=0,SBT_1=1,SBT_PRO1=2,SBT_2=3,SBT_PRO2=4,SBT_16=6,SBT_GB=7}; /* TODO: Need SB 2.0 vs SB 2.01 */
00097 enum REVEAL_SC_TYPES {RSC_NONE=0,RSC_SC400=1};
00098 enum SB_IRQS {SB_IRQ_8,SB_IRQ_16,SB_IRQ_MPU};
00099 enum ESS_TYPES {ESS_NONE=0,ESS_688=1};
00100 
00101 enum DSP_MODES {
00102     MODE_NONE,
00103     MODE_DAC,
00104     MODE_DMA,
00105     MODE_DMA_PAUSE,
00106     MODE_DMA_MASKED,
00107     MODE_DMA_REQUIRE_IRQ_ACK        /* Sound Blaster 16 style require IRQ ack to resume DMA */
00108 };
00109 
00110 enum DMA_MODES {
00111     DSP_DMA_NONE,
00112     DSP_DMA_2,DSP_DMA_3,DSP_DMA_4,DSP_DMA_8,
00113     DSP_DMA_16,DSP_DMA_16_ALIASED
00114 };
00115 
00116 enum {
00117     PLAY_MONO,PLAY_STEREO
00118 };
00119 
00120 struct SB_INFO {
00121     Bitu freq;
00122     Bit8u timeconst;
00123     Bitu dma_dac_srcrate;
00124     struct {
00125         bool stereo,sign,autoinit;
00126         bool force_autoinit;
00127         DMA_MODES mode_assigned;
00128         DMA_MODES mode;
00129         Bitu rate,mul;
00130         Bitu total,left,min;
00131         Bit64u start;
00132         union {
00133             Bit8u  b8[DMA_BUFSIZE];
00134             Bit16s b16[DMA_BUFSIZE];
00135         } buf;
00136         Bitu bits;
00137         DmaChannel * chan;
00138         Bitu remain_size;
00139     } dma;
00140     bool freq_derived_from_tc;      // if set, sb.freq was derived from SB/SBpro time constant
00141     bool def_enable_speaker;        // start emulation with SB speaker enabled
00142     bool enable_asp;
00143     bool speaker;
00144     bool midi;
00145     bool vibra;
00146     bool emit_blaster_var;
00147     bool sbpro_stereo_bit_strict_mode; /* if set, stereo bit in mixer can only be set if emulating a Pro. if clear, SB16 can too */
00148     bool sample_rate_limits; /* real SB hardware has limits on the sample rate */
00149     bool single_sample_dma;
00150     bool directdac_warn_speaker_off; /* if set, warn if DSP command 0x10 is being used while the speaker is turned off */
00151     bool dma_dac_mode; /* some very old DOS demos "play" sound by setting the DMA terminal count to 0.
00152                   normally that would mean the DMA controller transmitting the same byte at the sample rate,
00153                   except that the program creates sound by overwriting that byte periodically.
00154                   on actual hardware this happens to work (though with kind of a gritty sound to it),
00155                   The DMA emulation here does not handle that well. */
00156     bool goldplay;
00157     bool goldplay_stereo;
00158     bool write_status_must_return_7f; // WRITE_STATUS (port base+0xC) must return 0x7F or 0xFF if set. Some very early demos rely on it.
00159     bool busy_cycle_always;
00160     bool ess_playback_mode;
00161     bool no_filtering;
00162     Bit8u sc400_cfg;
00163     Bit8u time_constant;
00164     Bit8u sc400_dsp_major,sc400_dsp_minor;
00165     Bit8u sc400_jumper_status_1;
00166     Bit8u sc400_jumper_status_2;
00167     DSP_MODES mode;
00168     SB_TYPES type;
00169     REVEAL_SC_TYPES reveal_sc_type; // Reveal SC400 type
00170     ESS_TYPES ess_type; // ESS chipset emulation, to be set only if type == SBT_PRO2
00171     bool ess_extended_mode;
00172     int min_dma_user;
00173     int busy_cycle_hz;
00174     int busy_cycle_duty_percent;
00175     int busy_cycle_io_hack;
00176     double busy_cycle_last_check;
00177     double busy_cycle_last_poll;
00178     struct {
00179         bool pending_8bit;
00180         bool pending_16bit;
00181     } irq;
00182     struct {
00183         Bit8u state;
00184         Bit8u last_cmd;
00185         Bit8u cmd;
00186         Bit8u cmd_len;
00187         Bit8u cmd_in_pos;
00188         Bit8u cmd_in[DSP_BUFSIZE];
00189         struct {
00190             Bit8u lastval;
00191             Bit8u data[DSP_BUFSIZE];
00192             Bitu pos,used;
00193         } in,out;
00194         Bit8u test_register;
00195         Bitu write_busy;
00196         bool highspeed;
00197         bool require_irq_ack;
00198         bool instant_direct_dac;
00199         bool force_goldplay;
00200         bool midi_rwpoll_mode; // DSP command 0x34/0x35 MIDI Read Poll & Write Poll (0x35 with interrupt)
00201         bool midi_read_interrupt;
00202         bool midi_read_with_timestamps;
00203         unsigned int dsp_write_busy_time; /* when you write to the DSP, how long it signals "busy" */
00204     } dsp;
00205     struct {
00206         Bit16s last;
00207         double dac_t,dac_pt;
00208     } dac;
00209     struct {
00210         Bit8u index;
00211         Bit8u dac[2],fm[2],cda[2],master[2],lin[2];
00212         Bit8u mic;
00213         bool stereo;
00214         bool enabled;
00215         bool filtered;
00216         bool sbpro_stereo; /* Game or OS is attempting SB Pro type stereo */
00217         Bit8u unhandled[0x48];
00218     } mixer;
00219     struct {
00220         Bit8u reference;
00221         Bits stepsize;
00222         bool haveref;
00223     } adpcm;
00224     struct {
00225         Bitu base;
00226         Bitu irq;
00227         Bit8u dma8,dma16;
00228         bool sb_io_alias;
00229     } hw;
00230     struct {
00231         Bit8u valadd;
00232         Bit8u valxor;
00233     } e2;
00234     MixerChannel * chan;
00235 };
00236 
00237 static SB_INFO sb;
00238 
00239 static char const * const copyright_string="COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
00240 
00241 // number of bytes in input for commands (sb/sbpro)
00242 static Bit8u const DSP_cmd_len_sb[256] = {
00243   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x00
00244 //  1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0,  // 0x10
00245   1,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x10 Wari hack
00246   0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x20
00247   0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0,  // 0x30
00248 
00249   1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0,  // 0x40
00250   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x50
00251   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x60
00252   0,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x70
00253 
00254   2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x80
00255   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x90
00256   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xa0
00257   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xb0
00258 
00259   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xc0
00260   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xd0
00261   1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xe0
00262   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0   // 0xf0
00263 };
00264 
00265 // number of bytes in input for commands (sb/sbpro compatible Reveal SC400)
00266 static Bit8u const DSP_cmd_len_sc400[256] = {
00267   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x00
00268 //  1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0,  // 0x10
00269   1,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x10 Wari hack
00270   0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x20
00271   0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0,  // 0x30
00272 
00273   1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0,  // 0x40
00274   1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x50
00275   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,2,0,  // 0x60
00276   0,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x70
00277 
00278   2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x80
00279   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x90
00280   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xa0
00281   3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3,  // 0xb0
00282 
00283   3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3,  // 0xc0
00284   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xd0
00285   1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xe0
00286   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0   // 0xf0
00287 };
00288 
00289 // number of bytes in input for commands (sbpro2 compatible ESS)
00290 static Bit8u const DSP_cmd_len_ess[256] = {
00291   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x00
00292 //  1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0,  // 0x10
00293   1,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x10 Wari hack
00294   0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x20
00295   0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0,  // 0x30
00296 
00297   1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0,  // 0x40
00298   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x50
00299   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x60
00300   0,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x70
00301 
00302   2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x80
00303   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x90
00304   1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,  // 0xa0   ESS write register commands (0xA0-0xBF). Note this overlap with SB16 is
00305   1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,  // 0xb0   why ESS chipsets cannot emulate SB16 playback/record commands.
00306 
00307   1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xc0   ESS additional commands.
00308   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xd0
00309   1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xe0
00310   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0   // 0xf0
00311 };
00312 
00313 // number of bytes in input for commands (sb16)
00314 static Bit8u const DSP_cmd_len_sb16[256] = {
00315   0,0,0,0, 1,2,0,0, 1,0,0,0, 0,0,2,1,  // 0x00
00316 //  1,0,0,0, 2,0,2,2, 0,0,0,0, 0,0,0,0,  // 0x10
00317   1,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x10 Wari hack
00318   0,0,0,0, 2,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x20
00319   0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0,  // 0x30
00320 
00321   1,2,2,0, 0,0,0,0, 2,0,0,0, 0,0,0,0,  // 0x40
00322   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x50
00323   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x60
00324   0,0,0,0, 2,2,2,2, 0,0,0,0, 0,0,0,0,  // 0x70
00325 
00326   2,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x80
00327   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0x90
00328   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xa0
00329   3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3,  // 0xb0
00330 
00331   3,3,3,3, 3,3,3,3, 3,3,3,3, 3,3,3,3,  // 0xc0
00332   0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xd0
00333   1,0,1,0, 1,0,0,0, 0,0,0,0, 0,0,0,0,  // 0xe0
00334   0,0,0,0, 0,0,0,0, 0,1,2,0, 0,0,0,0   // 0xf0
00335 };
00336 
00337 static unsigned char ESSregs[0x20] = {0}; /* 0xA0-0xBF */
00338 
00339 static unsigned char &ESSreg(uint8_t reg) {
00340     assert(reg >= 0xA0 && reg <= 0xBF);
00341     return ESSregs[reg-0xA0];
00342 }
00343 
00344 static Bit8u ASP_regs[256];
00345 static Bit8u ASP_mode = 0x00;
00346 
00347 #ifndef max
00348 #define max(a,b) ((a)>(b)?(a):(b))
00349 #endif
00350 #ifndef min
00351 #define min(a,b) ((a)<(b)?(a):(b))
00352 #endif
00353 
00354 static void DSP_ChangeMode(DSP_MODES mode);
00355 static void CheckDMAEnd();
00356 static void DMA_DAC_Event(Bitu);
00357 static void END_DMA_Event(Bitu);
00358 static void DMA_Silent_Event(Bitu val);
00359 static void GenerateDMASound(Bitu size);
00360 
00361 static void DSP_SetSpeaker(bool how) {
00362     if (sb.speaker==how) return;
00363     sb.speaker=how;
00364     if (sb.type==SBT_16) return;
00365     sb.chan->Enable(how);
00366     if (sb.speaker) {
00367         PIC_RemoveEvents(DMA_Silent_Event);
00368         CheckDMAEnd();
00369     } else {
00370         
00371     }
00372 }
00373 
00374 /* NTS: Using some old Creative Sound Blaster 16 ViBRA PnP cards as reference,
00375  *      the card will send IRQ 9 if the IRQ is configured to either "2" or "9".
00376  *      Whichever value is written will be read back. The reason for this has
00377  *      to do with the pin on the ISA bus connector that used to signal IRQ 2
00378  *      on PC/XT hardware, but was wired to fire IRQ 9 instead on PC/AT hardware
00379  *      because of the IRQ 8-15 -> IRQ 2 cascade on AT hardware.
00380  *
00381  *      There's not much to change here, because PIC_ActivateIRQ was modified
00382  *      to remap IRQ 2 -> IRQ 9 for us *if* emulating AT hardware.
00383  *
00384  *      --Jonathan C. */
00385 static INLINE void SB_RaiseIRQ(SB_IRQS type) {
00386     LOG(LOG_SB,LOG_NORMAL)("Raising IRQ");
00387 
00388     if (sb.ess_playback_mode) {
00389         if (!(ESSreg(0xB1) & 0x40)) // if ESS playback, and IRQ disabled, do not fire
00390             return;
00391     }
00392 
00393     switch (type) {
00394     case SB_IRQ_8:
00395         if (sb.irq.pending_8bit) {
00396 //          LOG_MSG("SB: 8bit irq pending");
00397             return;
00398         }
00399         sb.irq.pending_8bit=true;
00400         PIC_ActivateIRQ(sb.hw.irq);
00401         break;
00402     case SB_IRQ_16:
00403         if (sb.irq.pending_16bit) {
00404 //          LOG_MSG("SB: 16bit irq pending");
00405             return;
00406         }
00407         sb.irq.pending_16bit=true;
00408         PIC_ActivateIRQ(sb.hw.irq);
00409         break;
00410     default:
00411         break;
00412     }
00413 }
00414 
00415 static INLINE void DSP_FlushData(void) {
00416     sb.dsp.out.used=0;
00417     sb.dsp.out.pos=0;
00418 }
00419 
00420 static double last_dma_callback = 0.0f;
00421 
00422 static void DSP_DMA_CallBack(DmaChannel * chan, DMAEvent event) {
00423     if (chan!=sb.dma.chan || event==DMA_REACHED_TC) return;
00424     else if (event==DMA_MASKED) {
00425         if (sb.mode==MODE_DMA) {
00426             //Catch up to current time, but don't generate an IRQ!
00427             //Fixes problems with later sci games.
00428             double t = PIC_FullIndex() - last_dma_callback;
00429             Bitu s = static_cast<Bitu>(sb.dma.rate * t / 1000.0f);
00430             if (s > sb.dma.min) {
00431                 LOG(LOG_SB,LOG_NORMAL)("limiting amount masked to sb.dma.min");
00432                 s = sb.dma.min;
00433             }
00434             Bitu min_size = sb.dma.mul >> SB_SH;
00435             if (!min_size) min_size = 1;
00436             min_size *= 2;
00437             if (sb.dma.left > min_size) {
00438                 if (s > (sb.dma.left-min_size)) s = sb.dma.left - min_size;
00439                 GenerateDMASound(s);
00440             }
00441             sb.mode=MODE_DMA_MASKED;
00442             LOG(LOG_SB,LOG_NORMAL)("DMA masked,stopping output, left %d",chan->currcnt);
00443         }
00444     } else if (event==DMA_TRANSFEREND) {
00445         if (sb.mode==MODE_DMA) sb.mode=MODE_DMA_MASKED;
00446     } else if (event==DMA_UNMASKED) {
00447         if (sb.mode==MODE_DMA_MASKED && sb.dma.mode!=DSP_DMA_NONE) {
00448             DSP_ChangeMode(MODE_DMA);
00449             CheckDMAEnd();
00450             LOG(LOG_SB,LOG_NORMAL)("DMA unmasked,starting output, auto %d block %d",chan->autoinit,chan->basecnt);
00451         }
00452     }
00453 }
00454 
00455 #define MIN_ADAPTIVE_STEP_SIZE 0
00456 #define MAX_ADAPTIVE_STEP_SIZE 32767
00457 #define DC_OFFSET_FADE 254
00458 
00459 static INLINE Bit8u decode_ADPCM_4_sample(Bit8u sample,Bit8u & reference,Bits& scale) {
00460     static const Bit8s scaleMap[64] = {
00461         0,  1,  2,  3,  4,  5,  6,  7,  0,  -1,  -2,  -3,  -4,  -5,  -6,  -7,
00462         1,  3,  5,  7,  9, 11, 13, 15, -1,  -3,  -5,  -7,  -9, -11, -13, -15,
00463         2,  6, 10, 14, 18, 22, 26, 30, -2,  -6, -10, -14, -18, -22, -26, -30,
00464         4, 12, 20, 28, 36, 44, 52, 60, -4, -12, -20, -28, -36, -44, -52, -60
00465     };
00466     static const Bit8u adjustMap[64] = {
00467           0, 0, 0, 0, 0, 16, 16, 16,
00468           0, 0, 0, 0, 0, 16, 16, 16,
00469         240, 0, 0, 0, 0, 16, 16, 16,
00470         240, 0, 0, 0, 0, 16, 16, 16,
00471         240, 0, 0, 0, 0, 16, 16, 16,
00472         240, 0, 0, 0, 0, 16, 16, 16,
00473         240, 0, 0, 0, 0,  0,  0,  0,
00474         240, 0, 0, 0, 0,  0,  0,  0
00475     };
00476 
00477     Bits samp = sample + scale;
00478 
00479     if ((samp < 0) || (samp > 63)) { 
00480         LOG(LOG_SB,LOG_ERROR)("Bad ADPCM-4 sample");
00481         if(samp < 0 ) samp =  0;
00482         if(samp > 63) samp = 63;
00483     }
00484 
00485     Bits ref = reference + scaleMap[samp];
00486     if (ref > 0xff) reference = 0xff;
00487     else if (ref < 0x00) reference = 0x00;
00488     else reference = (Bit8u)(ref&0xff);
00489     scale = (scale + adjustMap[samp]) & 0xff;
00490     
00491     return reference;
00492 }
00493 
00494 static INLINE Bit8u decode_ADPCM_2_sample(Bit8u sample,Bit8u & reference,Bits& scale) {
00495     static const Bit8s scaleMap[24] = {
00496         0,  1,  0,  -1,  1,  3,  -1,  -3,
00497         2,  6, -2,  -6,  4, 12,  -4, -12,
00498         8, 24, -8, -24, 16, 48, -16, -48
00499     };
00500     static const Bit8u adjustMap[24] = {
00501           0, 4,   0, 4,
00502         252, 4, 252, 4, 252, 4, 252, 4,
00503         252, 4, 252, 4, 252, 4, 252, 4,
00504         252, 0, 252, 0
00505     };
00506 
00507     Bits samp = sample + scale;
00508     if ((samp < 0) || (samp > 23)) {
00509         LOG(LOG_SB,LOG_ERROR)("Bad ADPCM-2 sample");
00510         if(samp < 0 ) samp =  0;
00511         if(samp > 23) samp = 23;
00512     }
00513 
00514     Bits ref = reference + scaleMap[samp];
00515     if (ref > 0xff) reference = 0xff;
00516     else if (ref < 0x00) reference = 0x00;
00517     else reference = (Bit8u)(ref&0xff);
00518     scale = (scale + adjustMap[samp]) & 0xff;
00519 
00520     return reference;
00521 }
00522 
00523 INLINE Bit8u decode_ADPCM_3_sample(Bit8u sample,Bit8u & reference,Bits& scale) {
00524     static const Bit8s scaleMap[40] = { 
00525         0,  1,  2,  3,  0,  -1,  -2,  -3,
00526         1,  3,  5,  7, -1,  -3,  -5,  -7,
00527         2,  6, 10, 14, -2,  -6, -10, -14,
00528         4, 12, 20, 28, -4, -12, -20, -28,
00529         5, 15, 25, 35, -5, -15, -25, -35
00530     };
00531     static const Bit8u adjustMap[40] = {
00532           0, 0, 0, 8,   0, 0, 0, 8,
00533         248, 0, 0, 8, 248, 0, 0, 8,
00534         248, 0, 0, 8, 248, 0, 0, 8,
00535         248, 0, 0, 8, 248, 0, 0, 8,
00536         248, 0, 0, 0, 248, 0, 0, 0
00537     };
00538 
00539     Bits samp = sample + scale;
00540     if ((samp < 0) || (samp > 39)) {
00541         LOG(LOG_SB,LOG_ERROR)("Bad ADPCM-3 sample");
00542         if(samp < 0 ) samp =  0;
00543         if(samp > 39) samp = 39;
00544     }
00545 
00546     Bits ref = reference + scaleMap[samp];
00547     if (ref > 0xff) reference = 0xff;
00548     else if (ref < 0x00) reference = 0x00;
00549     else reference = (Bit8u)(ref&0xff);
00550     scale = (scale + adjustMap[samp]) & 0xff;
00551 
00552     return reference;
00553 }
00554 
00555 void SB_OnEndOfDMA(void) {
00556     bool was_irq=false;
00557 
00558     PIC_RemoveEvents(END_DMA_Event);
00559     if (sb.ess_type == ESS_NONE && sb.reveal_sc_type == RSC_NONE && sb.dma.mode >= DSP_DMA_16) {
00560         was_irq = sb.irq.pending_16bit;
00561         SB_RaiseIRQ(SB_IRQ_16);
00562     }
00563     else {
00564         was_irq = sb.irq.pending_8bit;
00565         SB_RaiseIRQ(SB_IRQ_8);
00566     }
00567 
00568     if (!sb.dma.autoinit) {
00569         sb.dsp.highspeed = false;
00570         LOG(LOG_SB,LOG_NORMAL)("Single cycle transfer ended");
00571         sb.mode=MODE_NONE;
00572         sb.dma.mode=DSP_DMA_NONE;
00573 
00574         if (sb.ess_playback_mode) {
00575             LOG(LOG_SB,LOG_NORMAL)("ESS DMA stop");
00576             ESSreg(0xB8) &= ~0x01; // automatically stop DMA (right?)
00577             if (sb.dma.chan) sb.dma.chan->Clear_Request();
00578         }
00579     } else {
00580         sb.dma.left=sb.dma.total;
00581         if (!sb.dma.left) {
00582             LOG(LOG_SB,LOG_NORMAL)("Auto-init transfer with 0 size");
00583             sb.dsp.highspeed = false;
00584             sb.mode=MODE_NONE;
00585         }
00586         else if (sb.dsp.require_irq_ack && was_irq) {
00587             /* Sound Blaster 16 behavior: If you do not acknowledge the IRQ, and the card goes to signal another IRQ, the DSP halts playback.
00588              * This is different from previous cards (and clone hardware) that continue playing whether or not you acknowledge the IRQ. */
00589             LOG(LOG_SB,LOG_WARN)("DMA ended when previous IRQ had not yet been acked");
00590             sb.mode=MODE_DMA_REQUIRE_IRQ_ACK;
00591         }
00592     }
00593 }
00594 
00595 static void GenerateDMASound(Bitu size) {
00596     Bitu read=0;Bitu done=0;Bitu i=0;
00597 
00598     // don't read if the DMA channel is masked
00599     if (sb.dma.chan->masked) return;
00600 
00601     if (sb.dma_dac_mode) return;
00602 
00603     if(sb.dma.autoinit) {
00604         if (sb.dma.left <= size) size = sb.dma.left;
00605     } else {
00606         if (sb.dma.left <= sb.dma.min) 
00607             size = sb.dma.left;
00608     }
00609 
00610     if (size > DMA_BUFSIZE) {
00611         /* Maybe it's time to consider rendering intervals based on what the mixer wants rather than odd 1ms DMA packet calculations... */
00612         LOG(LOG_SB,LOG_WARN)("Whoah! GenerateDMASound asked to render too much audio (%u > %u). Read could have overrun the DMA buffer!",(unsigned int)size,DMA_BUFSIZE);
00613         size = DMA_BUFSIZE;
00614     }
00615 
00616     switch (sb.dma.mode) {
00617     case DSP_DMA_2:
00618         read=sb.dma.chan->Read(size,sb.dma.buf.b8);
00619         if (read && sb.adpcm.haveref) {
00620             sb.adpcm.haveref=false;
00621             sb.adpcm.reference=sb.dma.buf.b8[0];
00622             sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE;
00623             i++;
00624         }
00625         for (;i<read;i++) {
00626             MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 6) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize);
00627             MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 4) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize);
00628             MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 2) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize);
00629             MixTemp[done++]=decode_ADPCM_2_sample((sb.dma.buf.b8[i] >> 0) & 0x3,sb.adpcm.reference,sb.adpcm.stepsize);
00630         }
00631         sb.chan->AddSamples_m8(done,MixTemp);
00632         break;
00633     case DSP_DMA_3:
00634         read=sb.dma.chan->Read(size,sb.dma.buf.b8);
00635         if (read && sb.adpcm.haveref) {
00636             sb.adpcm.haveref=false;
00637             sb.adpcm.reference=sb.dma.buf.b8[0];
00638             sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE;
00639             i++;
00640         }
00641         for (;i<read;i++) {
00642             MixTemp[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[i] >> 5) & 0x7,sb.adpcm.reference,sb.adpcm.stepsize);
00643             MixTemp[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[i] >> 2) & 0x7,sb.adpcm.reference,sb.adpcm.stepsize);
00644             MixTemp[done++]=decode_ADPCM_3_sample((sb.dma.buf.b8[i] & 0x3) << 1,sb.adpcm.reference,sb.adpcm.stepsize);
00645         }
00646         sb.chan->AddSamples_m8(done,MixTemp);
00647         break;
00648     case DSP_DMA_4:
00649         read=sb.dma.chan->Read(size,sb.dma.buf.b8);
00650         if (read && sb.adpcm.haveref) {
00651             sb.adpcm.haveref=false;
00652             sb.adpcm.reference=sb.dma.buf.b8[0];
00653             sb.adpcm.stepsize=MIN_ADAPTIVE_STEP_SIZE;
00654             i++;
00655         }
00656         for (;i<read;i++) {
00657             MixTemp[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[i] >> 4,sb.adpcm.reference,sb.adpcm.stepsize);
00658             MixTemp[done++]=decode_ADPCM_4_sample(sb.dma.buf.b8[i]& 0xf,sb.adpcm.reference,sb.adpcm.stepsize);
00659         }
00660         sb.chan->AddSamples_m8(done,MixTemp);
00661         break;
00662     case DSP_DMA_8:
00663         if (sb.dma.stereo) {
00664             read=sb.dma.chan->Read(size,&sb.dma.buf.b8[sb.dma.remain_size]);
00665             Bitu total=read+sb.dma.remain_size;
00666             if (!sb.dma.sign)  sb.chan->AddSamples_s8(total>>1,sb.dma.buf.b8);
00667             else sb.chan->AddSamples_s8s(total>>1,(Bit8s*)sb.dma.buf.b8); 
00668             if (total&1) {
00669                 sb.dma.remain_size=1;
00670                 sb.dma.buf.b8[0]=sb.dma.buf.b8[total-1];
00671             } else sb.dma.remain_size=0;
00672         } else {
00673             read=sb.dma.chan->Read(size,sb.dma.buf.b8);
00674             if (!sb.dma.sign) sb.chan->AddSamples_m8(read,sb.dma.buf.b8);
00675             else sb.chan->AddSamples_m8s(read,(Bit8s *)sb.dma.buf.b8);
00676         }
00677         break;
00678     case DSP_DMA_16:
00679     case DSP_DMA_16_ALIASED:
00680         if (sb.dma.stereo) {
00681             /* In DSP_DMA_16_ALIASED mode temporarily divide by 2 to get number of 16-bit
00682                samples, because 8-bit DMA Read returns byte size, while in DSP_DMA_16 mode
00683                16-bit DMA Read returns word size */
00684             read=sb.dma.chan->Read(size,(Bit8u *)&sb.dma.buf.b16[sb.dma.remain_size]) 
00685                 >> (sb.dma.mode==DSP_DMA_16_ALIASED ? 1:0);
00686             Bitu total=read+sb.dma.remain_size;
00687 #if defined(WORDS_BIGENDIAN)
00688             if (sb.dma.sign) sb.chan->AddSamples_s16_nonnative(total>>1,sb.dma.buf.b16);
00689             else sb.chan->AddSamples_s16u_nonnative(total>>1,(Bit16u *)sb.dma.buf.b16);
00690 #else
00691             if (sb.dma.sign) sb.chan->AddSamples_s16(total>>1,sb.dma.buf.b16);
00692             else sb.chan->AddSamples_s16u(total>>1,(Bit16u *)sb.dma.buf.b16);
00693 #endif
00694             if (total&1) {
00695                 sb.dma.remain_size=1;
00696                 sb.dma.buf.b16[0]=sb.dma.buf.b16[total-1];
00697             } else sb.dma.remain_size=0;
00698         } else {
00699             read=sb.dma.chan->Read(size,(Bit8u *)sb.dma.buf.b16) 
00700                 >> (sb.dma.mode==DSP_DMA_16_ALIASED ? 1:0);
00701 #if defined(WORDS_BIGENDIAN)
00702             if (sb.dma.sign) sb.chan->AddSamples_m16_nonnative(read,sb.dma.buf.b16);
00703             else sb.chan->AddSamples_m16u_nonnative(read,(Bit16u *)sb.dma.buf.b16);
00704 #else
00705             if (sb.dma.sign) sb.chan->AddSamples_m16(read,sb.dma.buf.b16);
00706             else sb.chan->AddSamples_m16u(read,(Bit16u *)sb.dma.buf.b16);
00707 #endif
00708         }
00709         //restore buffer length value to byte size in aliased mode
00710         if (sb.dma.mode==DSP_DMA_16_ALIASED) read=read<<1;
00711         break;
00712     default:
00713         LOG_MSG("Unhandled dma mode %d",sb.dma.mode);
00714         sb.mode=MODE_NONE;
00715         return;
00716     }
00717     sb.dma.left-=read;
00718     if (!sb.dma.left) SB_OnEndOfDMA();
00719 }
00720 
00721 static void DMA_Silent_Event(Bitu val) {
00722     if (sb.dma.left<val) val=sb.dma.left;
00723     Bitu read=sb.dma.chan->Read(val,sb.dma.buf.b8);
00724     sb.dma.left-=read;
00725     if (!sb.dma.left) {
00726         if (sb.dma.mode >= DSP_DMA_16) SB_RaiseIRQ(SB_IRQ_16);
00727         else SB_RaiseIRQ(SB_IRQ_8);
00728         if (sb.dma.autoinit) sb.dma.left=sb.dma.total;
00729         else {
00730             sb.mode=MODE_NONE;
00731             sb.dma.mode=sb.dma.mode_assigned=DSP_DMA_NONE;
00732         }
00733     }
00734     if (sb.dma.left) {
00735         Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left;
00736         float delay=(bigger*1000.0f)/sb.dma.rate;
00737         PIC_AddEvent(DMA_Silent_Event,delay,bigger);
00738     }
00739 
00740 }
00741 
00742 #include <assert.h>
00743 
00744 void updateSoundBlasterFilter(Bitu rate);
00745 
00746 static void DMA_DAC_Event(Bitu val) {
00747     (void)val;//UNUSED
00748     unsigned char tmp[4];
00749     Bitu read,expct;
00750     signed int L,R;
00751     Bit16s out[2];
00752 
00753     if (sb.dma.chan->masked) {
00754         PIC_AddEvent(DMA_DAC_Event,1000.0 / sb.dma_dac_srcrate);
00755         return;
00756     }
00757     if (!sb.dma.left)
00758         return;
00759 
00760     /* Fix for 1994 Demoscene entry myth_dw: The demo's Sound Blaster Pro initialization will start DMA with
00761      * count == 1 or 2 (triggering Goldplay mode) but will change the DMA initial counter when it begins
00762      * normal playback. If goldplay stereo hack is enabled and we do not catch this case, the first 0.5 seconds
00763      * of music will play twice as fast. */
00764     if (sb.dma.chan != NULL &&
00765         sb.dma.chan->basecnt < ((sb.dma.mode==DSP_DMA_16_ALIASED?2:1)*((sb.dma.stereo || sb.mixer.sbpro_stereo)?2:1))/*size of one sample in DMA counts*/)
00766         sb.single_sample_dma = 1;
00767     else
00768         sb.single_sample_dma = 0;
00769 
00770     if (!sb.single_sample_dma) {
00771         // WARNING: This assumes Sound Blaster Pro emulation!
00772         LOG(LOG_SB,LOG_NORMAL)("Goldplay mode unexpectedly switched off, normal DMA playback follows"); 
00773         sb.dma_dac_mode = 0;
00774         sb.dma_dac_srcrate = sb.freq / (sb.mixer.stereo ? 2 : 1);
00775         sb.chan->SetFreq(sb.dma_dac_srcrate);
00776         updateSoundBlasterFilter(sb.dma_dac_srcrate);
00777         return;
00778     }
00779 
00780     /* NTS: chan->Read() deals with DMA unit transfers.
00781      *      for 8-bit DMA, read/expct is in bytes, for 16-bit DMA, read/expct is in 16-bit words */
00782     expct = (sb.dma.stereo ? 2u : 1u) * (sb.dma.mode == DSP_DMA_16_ALIASED ? 2u : 1u);
00783     read = sb.dma.chan->Read(expct,tmp);
00784     //if (read != expct)
00785     //      LOG_MSG("DMA read was not sample aligned. Sound may swap channels or become static. On real hardware the same may happen unless audio is prepared specifically.\n");
00786 
00787     if (sb.dma.mode == DSP_DMA_16 || sb.dma.mode == DSP_DMA_16_ALIASED) {
00788         L = (int16_t)host_readw(&tmp[0]);
00789         if (!sb.dma.sign) L ^= 0x8000;
00790         if (sb.dma.stereo) {
00791             R = (int16_t)host_readw(&tmp[2]);
00792             if (!sb.dma.sign) R ^= 0x8000;
00793         }
00794         else {
00795             R = L;
00796         }
00797     }
00798     else {
00799         L = tmp[0];
00800         if (!sb.dma.sign) L ^= 0x80;
00801         L = (int16_t)(L << 8);
00802         if (sb.dma.stereo) {
00803             R = tmp[1];
00804             if (!sb.dma.sign) R ^= 0x80;
00805             R = (int16_t)(R << 8);
00806         }
00807         else {
00808             R = L;
00809         }
00810     }
00811 
00812     if (sb.dma.stereo) {
00813         out[0]=L;
00814         out[1]=R;
00815         sb.chan->AddSamples_s16(1,out);
00816     }
00817     else {
00818         out[0]=L;
00819         sb.chan->AddSamples_m16(1,out);
00820     }
00821 
00822     /* NTS: The reason we check this is that sometimes the various "checks" performed by
00823        -        *      setup/configuration tools will setup impossible playback scenarios to test
00824        -        *      the card that would result in read > sb.dma.left. If read > sb.dma.left then
00825        -        *      the subtraction below would drive sb.dma.left below zero and the IRQ would
00826        -        *      never fire, and the test program would fail to detect SB16 emulation.
00827        -        *
00828        -        *      Bugfix for "Extreme Assault" that allows the game to detect Sound Blaster 16
00829        -        *      hardware. "Extreme Assault"'s SB16 test appears to configure a DMA transfer
00830        -        *      of 1 byte then attempt to play 16-bit signed stereo PCM (4 bytes) which prior
00831        -        *      to this fix would falsely trigger Goldplay then cause sb.dma.left to underrun
00832        -        *      and fail to fire the IRQ. */
00833     if (sb.dma.left >= read)
00834         sb.dma.left -= read;
00835     else
00836         sb.dma.left = 0;
00837 
00838     if (!sb.dma.left) {
00839         SB_OnEndOfDMA();
00840         if (sb.dma_dac_mode) PIC_AddEvent(DMA_DAC_Event,1000.0 / sb.dma_dac_srcrate);
00841     }
00842     else {
00843         PIC_AddEvent(DMA_DAC_Event,1000.0 / sb.dma_dac_srcrate);
00844     }
00845 }
00846 
00847 static void END_DMA_Event(Bitu val) {
00848     GenerateDMASound(val);
00849 }
00850 
00851 static void CheckDMAEnd(void) {
00852     if (!sb.dma.left) return;
00853     if (!sb.speaker && sb.type!=SBT_16) {
00854         Bitu bigger=(sb.dma.left > sb.dma.min) ? sb.dma.min : sb.dma.left;
00855         float delay=(bigger*1000.0f)/sb.dma.rate;
00856         PIC_AddEvent(DMA_Silent_Event,delay,bigger);
00857         LOG(LOG_SB,LOG_NORMAL)("Silent DMA Transfer scheduling IRQ in %.3f milliseconds",delay);
00858     } else if (sb.dma.left<sb.dma.min) {
00859         float delay=(sb.dma.left*1000.0f)/sb.dma.rate;
00860         LOG(LOG_SB,LOG_NORMAL)("Short transfer scheduling IRQ in %.3f milliseconds",delay); 
00861         PIC_AddEvent(END_DMA_Event,delay,sb.dma.left);
00862     }
00863 }
00864 
00865 static void DSP_ChangeMode(DSP_MODES mode) {
00866     if (sb.mode==mode) return;
00867     else sb.chan->FillUp();
00868     sb.mode=mode;
00869 }
00870 
00871 static void DSP_RaiseIRQEvent(Bitu /*val*/) {
00872     SB_RaiseIRQ(SB_IRQ_8);
00873 }
00874 
00875 static void DSP_DoDMATransfer(DMA_MODES mode,Bitu freq,bool stereo,bool dontInitLeft=false) {
00876     char const * type;
00877 
00878     sb.mode=MODE_DMA_MASKED;
00879 
00880     /* Explanation: A handful of ancient DOS demos (in the 1990-1992 timeframe) were written to output
00881      *              sound using the timer interrupt (IRQ 0) at a fixed rate to a device, usually the
00882      *              PC speaker or LPT1 DAC. When SoundBlaster came around, the programmers decided
00883      *              apparently to treat the Sound Blaster in the same way, so many of these early
00884      *              demos (especially those using GoldPlay) used either Direct DAC output or a hacked
00885      *              form of DMA single-cycle 8-bit output.
00886      *
00887      *              The way the hacked DMA mode works, is that the Sound Blaster is told the transfer
00888      *              length is 65536 or some other large value. Then, the DMA controller is programmed
00889      *              to point at a specific byte (or two bytes for stereo) and the counter value for
00890      *              that DMA channel is set to 0 (or 1 for stereo). This means that as the Sound Blaster 
00891      *              fetches bytes to play, the DMA controller ends up sending the same byte value
00892      *              over and over again. However, the demo has the timer running at the desired sample
00893      *              rate (IRQ 0) and the interrupt routine is modifying the byte to reflect the latest
00894      *              sample output. In this way, the demo renders audio whenever it feels like it and
00895      *              the Sound Blaster gets audio at the rate it works best with.
00896      *
00897      *              It's worth noting the programmers may have done this because DMA playback is the
00898      *              only way to get SB Pro stereo output working.
00899      *
00900      *              The problem here in DOSBox is that the DMA block-transfer code here is not precise
00901      *              enough to handle that properly. When you run such a program in DOSBox 0.74 and
00902      *              earlier, you get a low-frequency digital "rumble" that kinda-sorta sounds like
00903      *              what the demo is playing (the same byte value repeated over and over again, 
00904      *              remember?). The only way to properly render such output, is to read the memory
00905      *              value at the sample rate and buffer it for output.
00906      *
00907      * This fixes Sound Blaster output in:
00908      *    Twilight Zone - Buttman (1992) [SB and SB Pro modes]
00909      *    Triton - Crystal Dream (1992) [SB and SB Pro modes]
00910      *    The Jungly (1992) [SB and SB Pro modes]
00911      */
00912     if (sb.dma.chan != NULL &&
00913         sb.dma.chan->basecnt < ((mode==DSP_DMA_16_ALIASED?2:1)*((stereo || sb.mixer.sbpro_stereo)?2:1))/*size of one sample in DMA counts*/)
00914         sb.single_sample_dma = 1;
00915     else
00916         sb.single_sample_dma = 0;
00917 
00918     sb.dma_dac_srcrate=freq;
00919     if (sb.dsp.force_goldplay || (sb.goldplay && sb.freq > 0 && sb.single_sample_dma))
00920         sb.dma_dac_mode=1;
00921     else
00922         sb.dma_dac_mode=0;
00923 
00924     /* explanation: the purpose of Goldplay stereo mode is to compensate for the fact
00925      * that demos using this method of playback know to set the SB Pro stereo bit, BUT,
00926      * apparently did not know that they needed to double the sample rate when
00927      * computing the DSP time constant. Such demos sound "OK" on Sound Blaster Pro but
00928      * have audible aliasing artifacts because of this. The Goldplay Stereo hack
00929      * detects this condition and doubles the sample rate to better capture what the
00930      * demo is *trying* to do. NTS: sb.freq is the raw sample rate given by the
00931      * program, before it is divided by two for stereo.
00932      *
00933      * Of course, some demos like Crystal Dream take the approach of just setting the
00934      * sample rate to the max supported by the card and then letting it's timer interrupt
00935      * define the sample rate. So of course anything below 44.1KHz sounds awful. */
00936     if (sb.dma_dac_mode && sb.goldplay_stereo && (stereo || sb.mixer.sbpro_stereo) && sb.single_sample_dma)
00937         sb.dma_dac_srcrate = sb.freq;
00938 
00939     sb.chan->FillUp();
00940 
00941     if (!dontInitLeft)
00942         sb.dma.left=sb.dma.total;
00943 
00944     sb.dma.mode=sb.dma.mode_assigned=mode;
00945     sb.dma.stereo=stereo;
00946     sb.irq.pending_8bit=false;
00947     sb.irq.pending_16bit=false;
00948     switch (mode) {
00949     case DSP_DMA_2:
00950         type="2-bits ADPCM";
00951         sb.dma.mul=(1 << SB_SH)/4;
00952         break;
00953     case DSP_DMA_3:
00954         type="3-bits ADPCM";
00955         sb.dma.mul=(1 << SB_SH)/3;
00956         break;
00957     case DSP_DMA_4:
00958         type="4-bits ADPCM";
00959         sb.dma.mul=(1 << SB_SH)/2;
00960         break;
00961     case DSP_DMA_8:
00962         type="8-bits PCM";
00963         sb.dma.mul=(1 << SB_SH);
00964         break;
00965     case DSP_DMA_16_ALIASED:
00966         type="16-bits(aliased) PCM";
00967         sb.dma.mul=(1 << SB_SH)*2;
00968         break;
00969     case DSP_DMA_16:
00970         type="16-bits PCM";
00971         sb.dma.mul=(1 << SB_SH);
00972         break;
00973     default:
00974         LOG(LOG_SB,LOG_ERROR)("DSP:Illegal transfer mode %d",mode);
00975         return;
00976     }
00977     if (sb.dma.stereo) sb.dma.mul*=2;
00978     sb.dma.rate=(sb.dma_dac_srcrate*sb.dma.mul) >> SB_SH;
00979     sb.dma.min=((Bitu)sb.dma.rate*(Bitu)(sb.min_dma_user >= 0 ? sb.min_dma_user : /*default*/3))/1000u;
00980     if (sb.dma_dac_mode && sb.goldplay_stereo && (stereo || sb.mixer.sbpro_stereo) && sb.single_sample_dma) {
00981 //        LOG(LOG_SB,LOG_DEBUG)("Goldplay stereo hack. freq=%u rawfreq=%u dacrate=%u",(unsigned int)freq,(unsigned int)sb.freq,(unsigned int)sb.dma_dac_srcrate);
00982         sb.chan->SetFreq(sb.dma_dac_srcrate);
00983         updateSoundBlasterFilter(freq); /* BUT, you still filter like the actual sample rate */
00984     }
00985     else {
00986         sb.chan->SetFreq(freq);
00987         updateSoundBlasterFilter(freq);
00988     }
00989     sb.dma.mode=sb.dma.mode_assigned=mode;
00990     PIC_RemoveEvents(DMA_DAC_Event);
00991     PIC_RemoveEvents(END_DMA_Event);
00992 
00993     if (sb.dma_dac_mode)
00994         PIC_AddEvent(DMA_DAC_Event,1000.0 / sb.dma_dac_srcrate);
00995 
00996     if (sb.dma.chan != NULL) {
00997         sb.dma.chan->Register_Callback(DSP_DMA_CallBack);
00998     }
00999     else {
01000         LOG(LOG_SB,LOG_WARN)("DMA transfer initiated with no channel assigned");
01001     }
01002 
01003 #if (C_DEBUG)
01004     LOG(LOG_SB,LOG_NORMAL)("DMA Transfer:%s %s %s freq %d rate %d size %d gold %d",
01005         type,
01006         sb.dma.stereo ? "Stereo" : "Mono",
01007         sb.dma.autoinit ? "Auto-Init" : "Single-Cycle",
01008         (int)freq,(int)sb.dma.rate,(int)sb.dma.total,
01009         (int)sb.dma_dac_mode
01010     );
01011 #else
01012     (void)type;
01013 #endif
01014 }
01015 
01016 static Bit8u DSP_RateLimitedFinalTC_Old() {
01017     if (sb.sample_rate_limits) { /* enforce speed limits documented by Creative */
01018         /* commands that invoke this call use the DSP time constant, so use the DSP
01019          * time constant to constrain rate */
01020         unsigned int u_limit=212;/* 23KHz */
01021 
01022         /* NTS: We skip the SB16 commands because those are handled by another function */
01023         if ((sb.dsp.cmd&0xFE) == 0x74 || sb.dsp.cmd == 0x7D) { /* 4-bit ADPCM */
01024             u_limit = 172; /* 12KHz */
01025         }
01026         else if ((sb.dsp.cmd&0xFE) == 0x76) { /* 2.6-bit ADPCM */
01027             if (sb.type == SBT_2) u_limit = 172; /* 12KHz */
01028             else u_limit = 179; /* 13KHz */
01029         }
01030         else if ((sb.dsp.cmd&0xFE) == 0x16) { /* 2-bit ADPCM */
01031             if (sb.type == SBT_2) u_limit = 189; /* 15KHz */
01032             else u_limit = 165; /* 11KHz */
01033         }
01034         else if (sb.type == SBT_16) /* Sound Blaster 16. Highspeed commands are treated like an alias to normal DSP commands */
01035             u_limit = sb.vibra ? 234/*46KHz*/ : 233/*44.1KHz*/;
01036         else if (sb.type == SBT_2) /* Sound Blaster 2.0 */
01037             u_limit = (sb.dsp.highspeed ? 233/*44.1KHz*/ : 210/*22.5KHz*/);
01038         else
01039             u_limit = (sb.dsp.highspeed ? 233/*44.1KHz*/ : 212/*22.5KHz*/);
01040 
01041         /* NTS: Don't forget: Sound Blaster Pro "stereo" is programmed with a time constant divided by
01042          *      two times the sample rate, which is what we get back here. That's why here we don't need
01043          *      to consider stereo vs mono. */
01044         if (sb.timeconst > u_limit) return u_limit;
01045     }
01046 
01047     return sb.timeconst;
01048 }
01049 
01050 static unsigned int DSP_RateLimitedFinalSB16Freq_New(unsigned int freq) {
01051     // sample rate was set by SB16 DSP command 0x41/0x42, not SB/SBpro command 0x40 (unusual case)
01052     if (sb.sample_rate_limits) { /* enforce speed limits documented by Creative */
01053         unsigned int u_limit,l_limit=4000; /* NTS: Recording vs playback is not considered because DOSBox only emulates playback */
01054 
01055         if (sb.vibra) u_limit = 46000;
01056         else u_limit = 44100;
01057 
01058         if (freq < l_limit)
01059             freq = l_limit;
01060         if (freq > u_limit)
01061             freq = u_limit;
01062     }
01063 
01064     return freq;
01065 }
01066 
01067 static void DSP_PrepareDMA_Old(DMA_MODES mode,bool autoinit,bool sign,bool hispeed) {
01068     if (sb.dma.force_autoinit)
01069         autoinit = true;
01070 
01071     sb.dma.total=1u+(unsigned int)sb.dsp.in.data[0]+(unsigned int)(sb.dsp.in.data[1] << 8u);
01072     sb.dma.autoinit=autoinit;
01073     sb.dsp.highspeed=hispeed;
01074     sb.dma.sign=sign;
01075 
01076     /* BUGFIX: There is code out there that uses SB16 sample rate commands mixed with SB/SBPro
01077      *         playback commands. In order to handle these cases properly we need to use the
01078      *         SB16 sample rate if that is what was given to us, else the sample rate will
01079      *         come out wrong.
01080      *
01081      *         Test cases:
01082      *
01083      *         #1: Silpheed (vogons user newrisingsun amatorial patch)
01084      */
01085     if (sb.freq_derived_from_tc) {
01086         // sample rate was set by SB/SBpro command 0x40 Set Time Constant (very common case)
01087         /* BUGFIX: Instead of direct rate-limiting the DSP time constant, keep the original
01088          *         value written intact and rate-limit a copy. Bugfix for Optic Nerve and
01089          *         sbtype=sbpro2. On initialization the demo first sends DSP command 0x14
01090          *         with a 2-byte playback interval, then sends command 0x91 to begin
01091          *         playback. Rate-limiting the copy means the 45454Hz time constant written
01092          *         by the demo stays intact despite being limited to 22050Hz during the first
01093          *         DSP block (command 0x14). */
01094         Bit8u final_tc = DSP_RateLimitedFinalTC_Old();
01095         sb.freq = (256000000ul / (65536ul - ((unsigned long)final_tc << 8ul)));
01096     }
01097     else {
01098         LOG(LOG_SB,LOG_DEBUG)("Guest is using non-SB16 playback commands after using SB16 commands to set sample rate");
01099         sb.freq = DSP_RateLimitedFinalSB16Freq_New(sb.freq);
01100     }
01101 
01102     sb.dma_dac_mode=0;
01103     sb.ess_playback_mode = false;
01104     sb.dma.chan=GetDMAChannel(sb.hw.dma8);
01105     DSP_DoDMATransfer(mode,sb.freq / (sb.mixer.stereo ? 2 : 1),sb.mixer.stereo);
01106 }
01107 
01108 static void DSP_PrepareDMA_New(DMA_MODES mode,Bitu length,bool autoinit,bool stereo) {
01109     if (sb.dma.force_autoinit)
01110         autoinit = true;
01111 
01112     /* apparently SB16 hardware allows 0xBx-0xCx 4.xx DSP commands to interrupt
01113      * a previous SB16 playback command, DSP "nag" style. The difference is that
01114      * if you do that you risk exploiting DMA and timing glitches in the chip that
01115      * can cause funny things to happen, like causing 16-bit PCM to stop, or causing
01116      * 8-bit stereo PCM to swap left/right channels because the host is using auto-init
01117      * DMA and you interrupted the DSP chip when it fetched the L channel before it
01118      * had a chance to latch it and begin loading the R channel. */
01119     if (sb.mode == MODE_DMA) {
01120         if (!autoinit) sb.dma.total=length;
01121         sb.dma.left=sb.dma.total;
01122         sb.dma.autoinit=autoinit;
01123         return;
01124     }
01125 
01126     sb.dsp.highspeed = false;
01127     sb.freq = DSP_RateLimitedFinalSB16Freq_New(sb.freq);
01128     sb.timeconst = (65536 - (256000000 / sb.freq)) >> 8;
01129     sb.freq_derived_from_tc = false;
01130 
01131     Bitu freq=sb.freq;
01132     //equal length if data format and dma channel are both 16-bit or 8-bit
01133     sb.dma_dac_mode=0;
01134     sb.dma.total=length;
01135     sb.dma.autoinit=autoinit;
01136     sb.ess_playback_mode = false;
01137     if (mode==DSP_DMA_16) {
01138         if (sb.hw.dma16 == 0xff || sb.hw.dma16 == sb.hw.dma8) { /* 16-bit DMA not assigned or same as 8-bit channel */
01139             sb.dma.chan=GetDMAChannel(sb.hw.dma8);
01140             mode=DSP_DMA_16_ALIASED;
01141             //UNDOCUMENTED:
01142             //In aliased mode sample length is written to DSP as number of
01143             //16-bit samples so we need double 8-bit DMA buffer length
01144             sb.dma.total<<=1;
01145         }
01146         else if (sb.hw.dma16 >= 4) { /* 16-bit DMA assigned to 16-bit DMA channel */
01147             sb.dma.chan=GetDMAChannel(sb.hw.dma16);
01148         }
01149         else {
01150             /* Nope. According to one ViBRA PnP card I have on hand, asking the
01151              * card to do 16-bit DMA over 8-bit DMA only works if they are the
01152              * same channel, otherwise, the card doesn't seem to carry out any
01153              * DMA fetching. */
01154             sb.dma.chan=NULL;
01155             return;
01156         }
01157     } else {
01158         sb.dma.chan=GetDMAChannel(sb.hw.dma8);
01159     }
01160 
01161     DSP_DoDMATransfer(mode,freq,stereo);
01162 }
01163 
01164 
01165 static void DSP_AddData(Bit8u val) {
01166     if (sb.dsp.out.used<DSP_BUFSIZE) {
01167         Bitu start=sb.dsp.out.used+sb.dsp.out.pos;
01168         if (start>=DSP_BUFSIZE) start-=DSP_BUFSIZE;
01169         sb.dsp.out.data[start]=val;
01170         sb.dsp.out.used++;
01171     } else {
01172         LOG(LOG_SB,LOG_ERROR)("DSP:Data Output buffer full");
01173     }
01174 }
01175 
01176 static void DSP_BusyComplete(Bitu /*val*/) {
01177     sb.dsp.write_busy = 0;
01178 }
01179 
01180 static void DSP_FinishReset(Bitu /*val*/) {
01181     DSP_FlushData();
01182     DSP_AddData(0xaa);
01183     sb.dsp.state=DSP_S_NORMAL;
01184 }
01185 
01186 static void DSP_Reset(void) {
01187     LOG(LOG_SB,LOG_NORMAL)("DSP:Reset");
01188     PIC_DeActivateIRQ(sb.hw.irq);
01189 
01190     DSP_ChangeMode(MODE_NONE);
01191     DSP_FlushData();
01192     sb.dsp.cmd=DSP_NO_COMMAND;
01193     sb.dsp.cmd_len=0;
01194     sb.dsp.in.pos=0;
01195     sb.dsp.out.pos=0;
01196     sb.dsp.write_busy=0;
01197     sb.ess_extended_mode = false;
01198     sb.ess_playback_mode = false;
01199     sb.single_sample_dma = 0;
01200     sb.dma_dac_mode = 0;
01201     sb.directdac_warn_speaker_off = true;
01202     PIC_RemoveEvents(DSP_FinishReset);
01203     PIC_RemoveEvents(DSP_BusyComplete);
01204 
01205     sb.dma.left=0;
01206     sb.dma.total=0;
01207     sb.dma.stereo=false;
01208     sb.dma.sign=false;
01209     sb.dma.autoinit=false;
01210     sb.dma.mode=sb.dma.mode_assigned=DSP_DMA_NONE;
01211     sb.dma.remain_size=0;
01212     if (sb.dma.chan) sb.dma.chan->Clear_Request();
01213 
01214     sb.dsp.midi_rwpoll_mode = false;
01215     sb.dsp.midi_read_interrupt = false;
01216     sb.dsp.midi_read_with_timestamps = false;
01217 
01218     sb.freq=22050;
01219     sb.freq_derived_from_tc=true;
01220     sb.time_constant=45;
01221     sb.dac.last=0;
01222     sb.e2.valadd=0xaa;
01223     sb.e2.valxor=0x96;
01224     sb.dsp.highspeed=0;
01225     sb.irq.pending_8bit=false;
01226     sb.irq.pending_16bit=false;
01227     sb.chan->SetFreq(22050);
01228     updateSoundBlasterFilter(22050);
01229 //  DSP_SetSpeaker(false);
01230     PIC_RemoveEvents(END_DMA_Event);
01231     PIC_RemoveEvents(DMA_DAC_Event);
01232 }
01233 
01234 static void DSP_DoReset(Bit8u val) {
01235     if (((val&1)!=0) && (sb.dsp.state!=DSP_S_RESET)) {
01236 //TODO Get out of highspeed mode
01237         DSP_Reset();
01238         sb.dsp.state=DSP_S_RESET;
01239     } else if (((val&1)==0) && (sb.dsp.state==DSP_S_RESET)) {   // reset off
01240         sb.dsp.state=DSP_S_RESET_WAIT;
01241         PIC_RemoveEvents(DSP_FinishReset);
01242         PIC_AddEvent(DSP_FinishReset,20.0f/1000.0f,0);  // 20 microseconds
01243     }
01244     sb.dsp.write_busy = 0;
01245 }
01246 
01247 static void DSP_E2_DMA_CallBack(DmaChannel * /*chan*/, DMAEvent event) {
01248     if (event==DMA_UNMASKED) {
01249         Bit8u val = sb.e2.valadd;
01250         DmaChannel * chan=GetDMAChannel(sb.hw.dma8);
01251         chan->Register_Callback(0);
01252         chan->Write(1,&val);
01253     }
01254 }
01255 
01256 Bitu DEBUG_EnableDebugger(void);
01257 
01258 static void DSP_SC400_E6_DMA_CallBack(DmaChannel * /*chan*/, DMAEvent event) {
01259     if (event==DMA_UNMASKED) {
01260         static const char *string = "\x01\x02\x04\x08\x10\x20\x40\x80"; /* Confirmed response via DMA from actual Reveal SC400 card */
01261         DmaChannel * chan=GetDMAChannel(sb.hw.dma8);
01262         LOG(LOG_SB,LOG_DEBUG)("SC400 returning DMA test pattern on DMA channel=%u",sb.hw.dma8);
01263         chan->Register_Callback(0);
01264         chan->Write(8,(Bit8u*)string);
01265         chan->Clear_Request();
01266         if (!chan->tcount) LOG(LOG_SB,LOG_DEBUG)("SC400 warning: DMA did not reach terminal count");
01267         SB_RaiseIRQ(SB_IRQ_8);
01268     }
01269 }
01270 
01271 static void DSP_ADC_CallBack(DmaChannel * /*chan*/, DMAEvent event) {
01272     if (event!=DMA_UNMASKED) return;
01273     Bit8u val=128;
01274     DmaChannel * ch=GetDMAChannel(sb.hw.dma8);
01275     while (sb.dma.left--) {
01276         ch->Write(1,&val);
01277     }
01278     SB_RaiseIRQ(SB_IRQ_8);
01279     ch->Register_Callback(0);
01280 }
01281 
01282 static void DSP_ChangeRate(Bitu freq) {
01283         if (sb.freq!=freq && sb.dma.mode!=DSP_DMA_NONE) {
01284                 sb.chan->FillUp();
01285                 sb.chan->SetFreq(freq / (sb.mixer.stereo ? 2 : 1));
01286                 sb.dma.rate=(freq*sb.dma.mul) >> SB_SH;
01287                 sb.dma.min=(sb.dma.rate*3)/1000;
01288         }
01289         sb.freq=freq;
01290 }
01291 
01292 Bitu DEBUG_EnableDebugger(void);
01293 
01294 #define DSP_SB16_ONLY if (sb.type != SBT_16) { LOG(LOG_SB,LOG_ERROR)("DSP:Command %2X requires SB16",sb.dsp.cmd); break; }
01295 #define DSP_SB2_ABOVE if (sb.type <= SBT_1) { LOG(LOG_SB,LOG_ERROR)("DSP:Command %2X requires SB2 or above",sb.dsp.cmd); break; } 
01296 
01297 static unsigned int ESS_DMATransferCount() {
01298     unsigned int r;
01299 
01300     r = (unsigned int)ESSreg(0xA5) << 8U;
01301     r |= (unsigned int)ESSreg(0xA4);
01302 
01303     /* the 16-bit counter is a "two's complement" of the DMA count because it counts UP to 0 and triggers IRQ on overflow */
01304     return 0x10000U-r;
01305 }
01306 
01307 static void ESS_StartDMA() {
01308     LOG(LOG_SB,LOG_DEBUG)("ESS DMA start");
01309     sb.dma_dac_mode = 0;
01310     sb.dma.chan = GetDMAChannel(sb.hw.dma8);
01311     // FIXME: Which bit(s) are responsible for signalling stereo?
01312     //        Is it bit 3 of the Analog Control?
01313     //        Is it bit 3/6 of the Audio Control 1?
01314     //        Is it both?
01315     // NTS: ESS chipsets always use the 8-bit DMA channel, even for 16-bit PCM.
01316     // NTS: ESS chipsets also do not cap the sample rate, though if you drive them
01317     //      too fast the ISA bus will effectively cap the sample rate at some
01318     //      rate above 48KHz to 60KHz anyway.
01319     DSP_DoDMATransfer(
01320         (ESSreg(0xB7/*Audio Control 1*/)&4)?DSP_DMA_16_ALIASED:DSP_DMA_8,
01321         sb.freq,(ESSreg(0xA8/*Analog control*/)&3)==1?1:0/*stereo*/,true/*don't change dma.left*/);
01322     sb.ess_playback_mode = true;
01323 }
01324 
01325 static void ESS_StopDMA() {
01326     // DMA stop
01327     DSP_ChangeMode(MODE_NONE);
01328     if (sb.dma.chan) sb.dma.chan->Clear_Request();
01329     PIC_RemoveEvents(END_DMA_Event);
01330     PIC_RemoveEvents(DMA_DAC_Event);
01331 }
01332 
01333 static void ESS_UpdateDMATotal() {
01334     sb.dma.total = ESS_DMATransferCount();
01335 }
01336 
01337 static void ESS_CheckDMAEnable() {
01338     bool dma_en = (ESSreg(0xB8) & 1)?true:false;
01339 
01340     // if the DRQ is disabled, do not start
01341     if (!(ESSreg(0xB2) & 0x40))
01342         dma_en = false;
01343     // HACK: DOSBox does not yet support recording
01344     if (ESSreg(0xB8) & 8/*ADC mode*/)
01345         dma_en = false;
01346     if (ESSreg(0xB8) & 2/*DMA read*/)
01347         dma_en = false;
01348 
01349     if (dma_en) {
01350         if (sb.mode != MODE_DMA) ESS_StartDMA();
01351     }
01352     else {
01353         if (sb.mode == MODE_DMA) ESS_StopDMA();
01354     }
01355 }
01356 
01357 static void ESSUpdateFilterFromSB(void) {
01358     if (sb.freq >= 22050)
01359         ESSreg(0xA1) = 256 - (795500UL / sb.freq);
01360     else
01361         ESSreg(0xA1) = 128 - (397700UL / sb.freq);
01362 
01363     unsigned int freq = ((sb.freq * 4) / (5 * 2)); /* 80% of 1/2 the sample rate */
01364     ESSreg(0xA2) = 256 - (7160000 / (freq * 82));
01365 }
01366 
01367 static void ESS_DoWrite(uint8_t reg,uint8_t data) {
01368     uint8_t chg;
01369 
01370     LOG(LOG_SB,LOG_DEBUG)("ESS register write reg=%02xh val=%02xh",reg,data);
01371 
01372     switch (reg) {
01373         case 0xA1: /* Extended Mode Sample Rate Generator */
01374             ESSreg(reg) = data;
01375             if (data & 0x80)
01376                 sb.freq = 795500UL / (256ul - data);
01377             else
01378                 sb.freq = 397700UL / (128ul - data);
01379 
01380             sb.freq_derived_from_tc = false;
01381             if (sb.mode == MODE_DMA) {
01382                 ESS_StopDMA();
01383                 ESS_StartDMA();
01384             }
01385             break;
01386         case 0xA2: /* Filter divider (effectively, a hardware lowpass filter under S/W control) */
01387             ESSreg(reg) = data;
01388             updateSoundBlasterFilter(sb.freq);
01389             break;
01390         case 0xA4: /* DMA Transfer Count Reload (low) */
01391         case 0xA5: /* DMA Transfer Count Reload (high) */
01392             ESSreg(reg) = data;
01393             ESS_UpdateDMATotal();
01394             if (sb.dma.left == 0) sb.dma.left = sb.dma.total;
01395             break;
01396         case 0xA8: /* Analog Control */
01397             /* bits 7:5   0                  Reserved. Always write 0
01398              * bit  4     1                  Reserved. Always write 1
01399              * bit  3     Record monitor     1=Enable record monitor
01400              *            enable
01401              * bit  2     0                  Reserved. Always write 0
01402              * bits 1:0   Stereo/mono select 00=Reserved
01403              *                               01=Stereo
01404              *                               10=Mono
01405              *                               11=Reserved */
01406             chg = ESSreg(reg) ^ data;
01407             ESSreg(reg) = data;
01408             if (chg & 0x3) {
01409                 if (sb.mode == MODE_DMA) {
01410                     ESS_StopDMA();
01411                     ESS_StartDMA();
01412                 }
01413             }
01414             break;
01415         case 0xB1: /* Legacy Audio Interrupt Control */
01416             chg = ESSreg(reg) ^ data;
01417             ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable
01418             if (chg & 0x40) ESS_CheckDMAEnable();
01419             break;
01420         case 0xB2: /* DRQ Control */
01421             chg = ESSreg(reg) ^ data;
01422             ESSreg(reg) = (ESSreg(reg) & 0x0F) + (data & 0xF0); // lower 4 bits not writeable
01423             if (chg & 0x40) ESS_CheckDMAEnable();
01424             break;
01425         case 0xB5: /* DAC Direct Access Holding (low) */
01426         case 0xB6: /* DAC Direct Access Holding (high) */
01427             ESSreg(reg) = data;
01428             break;
01429         case 0xB7: /* Audio 1 Control 1 */
01430             /* bit  7     Enable FIFO to/from codec
01431              * bit  6     Opposite from bit 3               Must be set opposite to bit 3
01432              * bit  5     FIFO signed mode                  1=Data is signed twos-complement   0=Data is unsigned
01433              * bit  4     Reserved                          Always write 1
01434              * bit  3     FIFO stereo mode                  1=Data is stereo
01435              * bit  2     FIFO 16-bit mode                  1=Data is 16-bit
01436              * bit  1     Reserved                          Always write 0
01437              * bit  0     Generate load signal */
01438             chg = ESSreg(reg) ^ data;
01439             ESSreg(reg) = data;
01440             sb.dma.sign = (data&0x20)?1:0;
01441             if (chg & 0x04) ESS_UpdateDMATotal();
01442             if (chg & 0x0C) {
01443                 if (sb.mode == MODE_DMA) {
01444                     ESS_StopDMA();
01445                     ESS_StartDMA();
01446                 }
01447             }
01448             break;
01449         case 0xB8: /* Audio 1 Control 2 */
01450             /* bits 7:4   reserved
01451              * bit  3     CODEC mode         1=first DMA converter in ADC mode
01452              *                               0=first DMA converter in DAC mode
01453              * bit  2     DMA mode           1=auto-initialize mode
01454              *                               0=normal DMA mode
01455              * bit  1     DMA read enable    1=first DMA is read (for ADC)
01456              *                               0=first DMA is write (for DAC)
01457              * bit  0     DMA xfer enable    1=DMA is allowed to proceed */
01458             data &= 0xF;
01459             chg = ESSreg(reg) ^ data;
01460             ESSreg(reg) = data;
01461 
01462             /* FIXME: This is a guess */
01463             if (chg & 1) sb.dma.left = sb.dma.total;
01464 
01465             sb.dma.autoinit = (data >> 2) & 1;
01466             if (chg & 0xB) ESS_CheckDMAEnable();
01467             break;
01468         case 0xB9: /* Audio 1 Transfer Type */
01469         case 0xBA: /* Left Channel ADC Offset Adjust */
01470         case 0xBB: /* Right Channel ADC Offset Adjust */
01471             ESSreg(reg) = data;
01472             break;
01473     }
01474 }
01475 
01476 static uint8_t ESS_DoRead(uint8_t reg) {
01477     LOG(LOG_SB,LOG_DEBUG)("ESS register read reg=%02xh",reg);
01478 
01479     switch (reg) {
01480         default:
01481             return ESSreg(reg);
01482     }
01483 
01484     return 0xFF;
01485 }
01486 
01487 int MPU401_GetIRQ();
01488 
01489 /* SB16 cards have a 256-byte block of 8051 internal RAM accessible through DSP commands 0xF9 (Read) and 0xFA (Write) */
01490 static unsigned char sb16_8051_mem[256];
01491 
01492 /* The SB16 ASP appears to have a mystery 2KB RAM block that is accessible through register 0x83 of the ASP.
01493  * This array represents the initial contents as seen on my SB16 non-PnP ASP chip (version ID 0x10). */
01494 static unsigned int sb16asp_ram_contents_index = 0;
01495 static unsigned char sb16asp_ram_contents[2048];
01496 
01497 static void sb16asp_write_current_RAM_byte(const uint8_t r) {
01498     sb16asp_ram_contents[sb16asp_ram_contents_index] = r;
01499 }
01500 
01501 static uint8_t sb16asp_read_current_RAM_byte(void) {
01502     return sb16asp_ram_contents[sb16asp_ram_contents_index];
01503 }
01504 
01505 static void sb16asp_next_RAM_byte(void) {
01506     if ((++sb16asp_ram_contents_index) >= 2048)
01507         sb16asp_ram_contents_index = 0;
01508 }
01509 
01510 /* Demo notes for fixing:
01511  *
01512  *  - "Buttman"'s intro uses a timer and DSP command 0x10 to play the sound effects even in Pro mode.
01513  *    It doesn't use DMA + IRQ until the music starts.
01514  */
01515 
01516 static void DSP_DoCommand(void) {
01517     if (sb.ess_type != ESS_NONE && sb.dsp.cmd >= 0xA0 && sb.dsp.cmd <= 0xCF) {
01518         // ESS overlap with SB16 commands. Handle it here, not mucking up the switch statement.
01519 
01520         if (sb.dsp.cmd < 0xC0) { // write ESS register   (cmd=register data[0]=value to write)
01521             if (sb.ess_extended_mode)
01522                 ESS_DoWrite(sb.dsp.cmd,sb.dsp.in.data[0]);
01523         }
01524         else if (sb.dsp.cmd == 0xC0) { // read ESS register   (data[0]=register to read)
01525             DSP_FlushData();
01526             if (sb.ess_extended_mode && sb.dsp.in.data[0] >= 0xA0 && sb.dsp.in.data[0] <= 0xBF)
01527                 DSP_AddData(ESS_DoRead(sb.dsp.in.data[0]));
01528         }
01529         else if (sb.dsp.cmd == 0xC6 || sb.dsp.cmd == 0xC7) { // set(0xC6) clear(0xC7) extended mode
01530             sb.ess_extended_mode = (sb.dsp.cmd == 0xC6);
01531         }
01532         else {
01533             LOG(LOG_SB,LOG_DEBUG)("ESS: Unknown command %02xh",sb.dsp.cmd);
01534         }
01535 
01536         sb.dsp.last_cmd=sb.dsp.cmd;
01537         sb.dsp.cmd=DSP_NO_COMMAND;
01538         sb.dsp.cmd_len=0;
01539         sb.dsp.in.pos=0;
01540         return;
01541     }
01542 
01543     if (sb.type == SBT_16) {
01544         // FIXME: This is a guess! See also [https://github.com/joncampbell123/dosbox-x/issues/1044#issuecomment-480024957]
01545         sb16_8051_mem[0x20] = sb.dsp.last_cmd; /* cur_cmd */
01546     }
01547 
01548     // TODO: There are more SD16 ASP commands we can implement, by name even, with microcode download,
01549     //       using as reference the Linux kernel driver code:
01550     //
01551     //       http://lxr.free-electrons.com/source/sound/isa/sb/sb16_csp.c
01552 
01553 //  LOG_MSG("DSP Command %X",sb.dsp.cmd);
01554     switch (sb.dsp.cmd) {
01555     case 0x04:
01556         if (sb.type == SBT_16) {
01557             /* SB16 ASP set mode register */
01558             ASP_mode = sb.dsp.in.data[0];
01559 
01560             // bit 7: if set, enables bit 3 and memory access.
01561             // bit 3: if set, and bit 7 is set, register 0x83 can be used to read/write ASP internal memory. if clear, register 0x83 contains chip version ID
01562             // bit 2: if set, memory index is reset to 0. doesn't matter if memory access or not.
01563             // bit 1: if set, writing register 0x83 increments memory index. doesn't matter if memory access or not.
01564             // bit 0: if set, reading register 0x83 increments memory index. doesn't matter if memory access or not.
01565             if (ASP_mode&4)
01566                 sb16asp_ram_contents_index = 0;
01567 
01568             LOG(LOG_SB,LOG_DEBUG)("SB16ASP set mode register to %X",sb.dsp.in.data[0]);
01569         } else {
01570             /* DSP Status SB 2.0/pro version. NOT SB16. */
01571             DSP_FlushData();
01572             if (sb.type == SBT_2) DSP_AddData(0x88);
01573             else if ((sb.type == SBT_PRO1) || (sb.type == SBT_PRO2)) DSP_AddData(0x7b);
01574             else DSP_AddData(0xff);         //Everything enabled
01575         }
01576         break;
01577     case 0x05:  /* SB16 ASP set codec parameter */
01578         LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (set codec parameter) value=0x%02x parameter=0x%02x",
01579             sb.dsp.cmd,sb.dsp.in.data[0],sb.dsp.in.data[1]);
01580         break;
01581     case 0x08:  /* SB16 ASP get version */
01582         if (sb.type == SBT_16) {
01583             switch (sb.dsp.in.data[0]) {
01584                 case 0x03:
01585                     LOG(LOG_SB,LOG_DEBUG)("DSP SB16ASP command %X sub %X (get chip version)",sb.dsp.cmd,sb.dsp.in.data[0]);
01586 
01587                     if (sb.enable_asp)
01588                         DSP_AddData(0x10);  // version ID
01589                     else
01590                         DSP_AddData(0xFF);  // NTS: This is what a SB16 ViBRA PnP card with no ASP returns when queried in this way
01591                     break;
01592                 default:
01593                     LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X sub %X",sb.dsp.cmd,sb.dsp.in.data[0]);
01594                     break;
01595             }
01596         } else {
01597             LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X sub %X",sb.dsp.cmd,sb.dsp.in.data[0]);
01598         }
01599         break;
01600     case 0x0e:  /* SB16 ASP set register */
01601         if (sb.type == SBT_16) {
01602             if (sb.enable_asp) {
01603                 ASP_regs[sb.dsp.in.data[0]] = sb.dsp.in.data[1];
01604 
01605                 if (sb.dsp.in.data[0] == 0x83) {
01606                     if ((ASP_mode&0x88) == 0x88) { // bit 3 and bit 7 must be set
01607                         // memory access mode
01608                         if (ASP_mode & 4) // NTS: As far as I can tell...
01609                             sb16asp_ram_contents_index = 0;
01610 
01611                         // log it, write it
01612                         LOG(LOG_SB,LOG_DEBUG)("SB16 ASP write internal RAM byte index=0x%03x val=0x%02x",sb16asp_ram_contents_index,sb.dsp.in.data[1]);
01613                         sb16asp_write_current_RAM_byte(sb.dsp.in.data[1]);
01614 
01615                         if (ASP_mode & 2) // if bit 1 of the mode is set, memory index increment on write
01616                             sb16asp_next_RAM_byte();
01617                     }
01618                     else {
01619                         // unknown. nothing, I assume?
01620                         LOG(LOG_SB,LOG_WARN)("SB16 ASP set register 0x83 not implemented for non-memory mode (unknown behavior)\n");
01621                     }
01622                 }
01623                 else {
01624                     LOG(LOG_SB,LOG_DEBUG)("SB16 ASP set register reg=0x%02x val=0x%02x",sb.dsp.in.data[0],sb.dsp.in.data[1]);
01625                 }
01626             }
01627             else {
01628                 LOG(LOG_SB,LOG_DEBUG)("SB16 ASP set register reg=0x%02x val=0x%02x ignored, ASP not enabled",sb.dsp.in.data[0],sb.dsp.in.data[1]);
01629             }
01630         } else {
01631             LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (set register)",sb.dsp.cmd);
01632         }
01633         break;
01634     case 0x0f:  /* SB16 ASP get register */
01635         if (sb.type == SBT_16) {
01636             // FIXME: We have to emulate this whether or not ASP emulation is enabled. Windows 98 SB16 driver requires this.
01637             //        The question is: What does actual hardware do here exactly?
01638             if (sb.enable_asp && sb.dsp.in.data[0] == 0x83) {
01639                 if ((ASP_mode&0x88) == 0x88) { // bit 3 and bit 7 must be set
01640                     // memory access mode
01641                     if (ASP_mode & 4) // NTS: As far as I can tell...
01642                         sb16asp_ram_contents_index = 0;
01643 
01644                     // log it, read it
01645                     ASP_regs[0x83] = sb16asp_read_current_RAM_byte();
01646                     LOG(LOG_SB,LOG_DEBUG)("SB16 ASP read internal RAM byte index=0x%03x => val=0x%02x",sb16asp_ram_contents_index,ASP_regs[0x83]);
01647 
01648                     if (ASP_mode & 1) // if bit 0 of the mode is set, memory index increment on read
01649                         sb16asp_next_RAM_byte();
01650                 }
01651                 else {
01652                     // chip version ID
01653                     ASP_regs[0x83] = 0x10;
01654                 }
01655             }
01656             else {
01657                 LOG(LOG_SB,LOG_DEBUG)("SB16 ASP get register reg=0x%02x, returning 0x%02x",sb.dsp.in.data[0],ASP_regs[sb.dsp.in.data[0]]);
01658             }
01659 
01660             DSP_AddData(ASP_regs[sb.dsp.in.data[0]]);
01661         } else {
01662             LOG(LOG_SB,LOG_NORMAL)("DSP Unhandled SB16ASP command %X (get register)",sb.dsp.cmd);
01663         }
01664         break;
01665     case 0x10:  /* Direct DAC */
01666         DSP_ChangeMode(MODE_DAC);
01667 
01668         /* just in case something is trying to play direct DAC audio while the speaker is turned off... */
01669         if (!sb.speaker && sb.directdac_warn_speaker_off) {
01670             LOG(LOG_SB,LOG_DEBUG)("DSP direct DAC sample written while speaker turned off. Program should use DSP command 0xD1 to turn it on.");
01671             sb.directdac_warn_speaker_off = false;
01672         }
01673 
01674         sb.freq = 22050;
01675         sb.freq_derived_from_tc = true;
01676         sb.dac.dac_pt = sb.dac.dac_t;
01677         sb.dac.dac_t = PIC_FullIndex();
01678         {
01679             double dt = sb.dac.dac_t - sb.dac.dac_pt; // time in milliseconds since last direct DAC output
01680             double rt = 1000 / dt; // estimated sample rate according to dt
01681             int s,sc = 1;
01682 
01683             // cap rate estimate to sanity. <= 1KHz means rendering once per timer tick in DOSBox,
01684             // so there's no point below that rate in additional rendering.
01685             if (rt < 1000) rt = 1000;
01686 
01687             // FIXME: What does the ESS AudioDrive do to it's filter/sample rate divider registers when emulating this Sound Blaster command?
01688             ESSreg(0xA1) = 128 - (397700 / 22050);
01689             ESSreg(0xA2) = 256 - (7160000 / (82 * ((4 * 22050) / 10)));
01690 
01691             // Direct DAC playback could be thought of as application-driven 8-bit output up to 23KHz.
01692             // The sound card isn't given any hint what the actual sample rate is, only that it's given
01693             // instruction when to change the 8-bit value being output to the DAC which is why older DOS
01694             // games using this method tend to sound "grungy" compared to DMA playback. We recreate the
01695             // effect here by asking the mixer to do it's linear interpolation as if at 23KHz while
01696             // rendering the audio at whatever rate the DOS game is giving it to us.
01697             sb.chan->SetFreq((Bitu)(rt * 0x100),0x100);
01698             updateSoundBlasterFilter(sb.freq);
01699 
01700             // avoid popping/crackling artifacts through the mixer by ensuring the render output is prefilled enough
01701             if (sb.chan->msbuffer_o < 40/*FIXME: ask the mixer code!*/) sc += 2/*FIXME: use mixer rate / rate math*/;
01702 
01703             // do it
01704             for (s=0;s < sc;s++) sb.chan->AddSamples_m8(1,(Bit8u*)(&sb.dsp.in.data[0]));
01705         }
01706         break;
01707     case 0x24:  /* Singe Cycle 8-Bit DMA ADC */
01708         sb.dma.left=sb.dma.total=1u+(unsigned int)sb.dsp.in.data[0]+((unsigned int)sb.dsp.in.data[1] << 8u);
01709         sb.dma.sign=false;
01710         LOG(LOG_SB,LOG_ERROR)("DSP:Faked ADC for %d bytes",(int)sb.dma.total);
01711         GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_ADC_CallBack);
01712         break;
01713     case 0x91:  /* Singe Cycle 8-Bit DMA High speed DAC */
01714         DSP_SB2_ABOVE;
01715         /* fall through */
01716     case 0x14:  /* Singe Cycle 8-Bit DMA DAC */
01717     case 0x15:  /* Wari hack. Waru uses this one instead of 0x14, but some weird stuff going on there anyway */
01718         /* Note: 0x91 is documented only for DSP ver.2.x and 3.x, not 4.x */
01719         DSP_PrepareDMA_Old(DSP_DMA_8,false,false,/*hispeed*/(sb.dsp.cmd&0x80)!=0);
01720         break;
01721     case 0x90:  /* Auto Init 8-bit DMA High Speed */
01722     case 0x1c:  /* Auto Init 8-bit DMA */
01723         DSP_SB2_ABOVE; /* Note: 0x90 is documented only for DSP ver.2.x and 3.x, not 4.x */
01724         DSP_PrepareDMA_Old(DSP_DMA_8,true,false,/*hispeed*/(sb.dsp.cmd&0x80)!=0);
01725         break;
01726     case 0x38:  /* Write to SB MIDI Output */
01727         if (sb.midi == true) MIDI_RawOutByte(sb.dsp.in.data[0]);
01728         break;
01729     case 0x40:  /* Set Timeconstant */
01730         DSP_ChangeRate(256000000ul / (65536ul - ((unsigned int)sb.dsp.in.data[0] << 8u)));
01731         sb.timeconst=sb.dsp.in.data[0];
01732         sb.freq_derived_from_tc=true;
01733 
01734         if (sb.ess_type != ESS_NONE) ESSUpdateFilterFromSB();
01735         break;
01736     case 0x41:  /* Set Output Samplerate */
01737     case 0x42:  /* Set Input Samplerate */
01738         if (sb.reveal_sc_type == RSC_SC400) {
01739             /* Despite reporting itself as Sound Blaster Pro compatible, the Reveal SC400 supports some SB16 commands like this one */
01740         }
01741         else {
01742             DSP_SB16_ONLY;
01743         }
01744 
01745         DSP_ChangeRate(((unsigned int)sb.dsp.in.data[0] << 8u) | (unsigned int)sb.dsp.in.data[1]);
01746         sb.freq_derived_from_tc=false;
01747         sb16_8051_mem[0x13] = sb.freq & 0xffu;                  // rate low
01748         sb16_8051_mem[0x14] = (sb.freq >> 8u) & 0xffu;          // rate high
01749         break;
01750     case 0x48:  /* Set DMA Block Size */
01751         DSP_SB2_ABOVE;
01752         //TODO Maybe check limit for new irq?
01753         sb.dma.total=1u+(unsigned int)sb.dsp.in.data[0]+((unsigned int)sb.dsp.in.data[1] << 8u);
01754         break;
01755     case 0x75:  /* 075h : Single Cycle 4-bit ADPCM Reference */
01756         sb.adpcm.haveref=true;
01757     case 0x74:  /* 074h : Single Cycle 4-bit ADPCM */   
01758         DSP_PrepareDMA_Old(DSP_DMA_4,false,false,false);
01759         break;
01760     case 0x77:  /* 077h : Single Cycle 3-bit(2.6bit) ADPCM Reference*/
01761         sb.adpcm.haveref=true;
01762     case 0x76:  /* 074h : Single Cycle 3-bit(2.6bit) ADPCM */
01763         DSP_PrepareDMA_Old(DSP_DMA_3,false,false,false);
01764         break;
01765     case 0x7d:  /* Auto Init 4-bit ADPCM Reference */
01766         DSP_SB2_ABOVE;
01767         sb.adpcm.haveref=true;
01768         DSP_PrepareDMA_Old(DSP_DMA_4,true,false,false);
01769         break;
01770     case 0x7f:  /* Auto Init 3-bit(2.6bit) ADPCM Reference */
01771         DSP_SB2_ABOVE;
01772         sb.adpcm.haveref=true;
01773         DSP_PrepareDMA_Old(DSP_DMA_3,true,false,false);
01774         break;
01775     case 0x1f:  /* Auto Init 2-bit ADPCM Reference */
01776         DSP_SB2_ABOVE;
01777         sb.adpcm.haveref=true;
01778         DSP_PrepareDMA_Old(DSP_DMA_2,true,false,false);
01779         break;
01780     case 0x17:  /* 017h : Single Cycle 2-bit ADPCM Reference*/
01781         sb.adpcm.haveref=true;
01782     case 0x16:  /* 074h : Single Cycle 2-bit ADPCM */
01783         DSP_PrepareDMA_Old(DSP_DMA_2,false,false,false);
01784         break;
01785     case 0x80:  /* Silence DAC */
01786         PIC_AddEvent(&DSP_RaiseIRQEvent,
01787             (1000.0f*(1+sb.dsp.in.data[0]+(sb.dsp.in.data[1] << 8))/sb.freq));
01788         break;
01789     case 0xb0:  case 0xb1:  case 0xb2:  case 0xb3:  case 0xb4:  case 0xb5:  case 0xb6:  case 0xb7:
01790     case 0xb8:  case 0xb9:  case 0xba:  case 0xbb:  case 0xbc:  case 0xbd:  case 0xbe:  case 0xbf:
01791     case 0xc0:  case 0xc1:  case 0xc2:  case 0xc3:  case 0xc4:  case 0xc5:  case 0xc6:  case 0xc7:
01792     case 0xc8:  case 0xc9:  case 0xca:  case 0xcb:  case 0xcc:  case 0xcd:  case 0xce:  case 0xcf:
01793 /* The low 5 bits DO have specific meanings:
01794 
01795  Bx - Program 16-bit DMA mode digitized sound I/O
01796       Command sequence:  Command, Mode, Lo(Length-1), Hi(Length-1)
01797        Command:
01798         ╔════╤════╤════╤════╤═══════╤══════╤═══════╤════╗
01799         ║ D7 │ D6 │ D5 │ D4 │  D3   │  D2  │  D1   │ D0 ║
01800         ╠════╪════╪════╪════╪═══════╪══════╪═══════╪════╣
01801         ║  1 │  0 │  1 │  1 │  A/D  │  A/I │ FIFO  │  0 ║
01802         ╚════╧════╧════╧════┼───────┼──────┼───────┼════╝
01803                             │ 0=D/A │ 0=SC │ 0=off │
01804                             │ 1=A/D │ 1=AI │ 1=on  │
01805                             └───────┴──────┴───────┘
01806        Common commands:
01807          B8 - 16-bit single-cycle input
01808          B0 - 16-bit single-cycle output
01809          BE - 16-bit auto-initialized input
01810          B6 - 16-bit auto-initialized output
01811 
01812        Mode:
01813         ╔════╤════╤══════════╤════════════╤════╤════╤════╤════╗
01814         ║ D7 │ D6 │    D5    │     D4     │ D3 │ D2 │ D1 │ D0 ║
01815         ╠════╪════╪══════════╪════════════╪════╪════╪════╪════╣
01816         ║  0 │  0 │  Stereo  │   Signed   │  0 │  0 │  0 │  0 ║
01817         ╚════╧════┼──────────┼────────────┼════╧════╧════╧════╝
01818                   │ 0=Mono   │ 0=unsigned │
01819                   │ 1=Stereo │ 1=signed   │
01820                   └──────────┴────────────┘
01821 
01822  Cx - Program 8-bit DMA mode digitized sound I/O
01823       Same procedure as 16-bit sound I/O using command Bx
01824        Common commands:
01825          C8 - 8-bit single-cycle input
01826          C0 - 8-bit single-cycle output
01827          CE - 8-bit auto-initialized input
01828          C6 - 8-bit auto-initialized output
01829 
01830   Note that this code makes NO attempt to distinguish recording vs playback commands, which
01831   is responsible for some failures such as [https://github.com/joncampbell123/dosbox-x/issues/1589]
01832 */
01833         if (sb.reveal_sc_type == RSC_SC400) {
01834             /* Despite reporting itself as Sound Blaster Pro, the Reveal SC400 cards do support *some* SB16 DSP commands! */
01835             /* BUT, it only recognizes a subset of this range. */
01836             if (sb.dsp.cmd == 0xBE || sb.dsp.cmd == 0xB6 ||
01837                 sb.dsp.cmd == 0xCE || sb.dsp.cmd == 0xC6) {
01838                 /* OK! */
01839             }
01840             else {
01841                 LOG(LOG_SB,LOG_DEBUG)("SC400: SB16 playback command not recognized");
01842                 break;
01843             }
01844         }
01845         else {
01846             DSP_SB16_ONLY;
01847         }
01848 
01849         /* Generic 8/16 bit DMA */
01850 //      DSP_SetSpeaker(true);       //SB16 always has speaker enabled
01851         sb.dma.sign=(sb.dsp.in.data[0] & 0x10) > 0;
01852         DSP_PrepareDMA_New((sb.dsp.cmd & 0x10) ? DSP_DMA_16 : DSP_DMA_8,
01853             1u+(unsigned int)sb.dsp.in.data[1]+((unsigned int)sb.dsp.in.data[2] << 8u),
01854             (sb.dsp.cmd & 0x4)>0,
01855             (sb.dsp.in.data[0] & 0x20) > 0
01856         );
01857         break;
01858     case 0xd5:  /* Halt 16-bit DMA */
01859         DSP_SB16_ONLY;
01860     case 0xd0:  /* Halt 8-bit DMA */
01861         sb.chan->FillUp();
01862 //      DSP_ChangeMode(MODE_NONE);
01863 //      Games sometimes already program a new dma before stopping, gives noise
01864         if (sb.mode==MODE_NONE) {
01865             // possibly different code here that does not switch to MODE_DMA_PAUSE
01866         }
01867         sb.mode=MODE_DMA_PAUSE;
01868         PIC_RemoveEvents(END_DMA_Event);
01869         PIC_RemoveEvents(DMA_DAC_Event);
01870         break;
01871     case 0xd1:  /* Enable Speaker */
01872         sb.chan->FillUp();
01873         DSP_SetSpeaker(true);
01874         break;
01875     case 0xd3:  /* Disable Speaker */
01876         sb.chan->FillUp();
01877         DSP_SetSpeaker(false);
01878 
01879         /* There are demoscene productions that reinitialize sound between parts.
01880          * But instead of stopping playback, then starting it again, the demo leaves
01881          * DMA running through RAM and expects the "DSP Disable Speaker" command to
01882          * prevent the arbitrary contents of RAM from coming out the sound card as static
01883          * while it loads data. The problem is, DSP enable/disable speaker commands don't
01884          * do anything on Sound Blaster 16 cards. This is why such demos run fine when
01885          * sbtype=sbpro2, but emit static/noise between demo parts when sbtype=sb16.
01886          * The purpose of this warning is to clue the user on in this fact and suggest
01887          * a fix.
01888          *
01889          * Demoscene productions known to have this bug/problem with sb16:
01890          * - "Saga" by Dust (1993)                       noise/static between demo parts
01891          * - "Facts of life" by Witan (1992)             noise/static during star wars scroller at the beginning
01892          */
01893         if (sb.type == SBT_16 && sb.mode == MODE_DMA)
01894             LOG(LOG_MISC,LOG_WARN)("SB16 warning: DSP Disable Speaker command used while DMA is running, which has no effect on audio output on SB16 hardware. Audible noise/static may occur. You can eliminate the noise by setting sbtype=sbpro2");
01895 
01896         break;
01897     case 0xd8:  /* Speaker status */
01898         DSP_SB2_ABOVE;
01899         DSP_FlushData();
01900         if (sb.speaker) DSP_AddData(0xff);
01901         else DSP_AddData(0x00);
01902         break;
01903     case 0xd6:  /* Continue DMA 16-bit */
01904         DSP_SB16_ONLY;
01905     case 0xd4:  /* Continue DMA 8-bit*/
01906         sb.chan->FillUp();
01907         if (sb.mode==MODE_DMA_PAUSE) {
01908             sb.mode=MODE_DMA_MASKED;
01909             if (sb.dma.chan!=NULL) sb.dma.chan->Register_Callback(DSP_DMA_CallBack);
01910         }
01911         break;
01912     case 0x47:  /* Continue Autoinitialize 16-bit */
01913     case 0x45:  /* Continue Autoinitialize 8-bit */
01914         DSP_SB16_ONLY;
01915         sb.chan->FillUp();
01916         sb.dma.autoinit=true; // No. This DSP command does not resume DMA playback
01917         break;
01918     case 0xd9:  /* Exit Autoinitialize 16-bit */
01919         DSP_SB16_ONLY;
01920     case 0xda:  /* Exit Autoinitialize 8-bit */
01921         DSP_SB2_ABOVE;
01922         /* Set mode to single transfer so it ends with current block */
01923         sb.dma.autoinit=false;      //Should stop itself
01924         sb.chan->FillUp();
01925         break;
01926     case 0xe0:  /* DSP Identification - SB2.0+ */
01927         DSP_FlushData();
01928         DSP_AddData(~sb.dsp.in.data[0]);
01929         break;
01930     case 0xe1:  /* Get DSP Version */
01931         DSP_FlushData();
01932         switch (sb.type) {
01933         case SBT_1:
01934             DSP_AddData(0x1);DSP_AddData(0x05);break;
01935         case SBT_2:
01936             DSP_AddData(0x2);DSP_AddData(0x1);break;
01937         case SBT_PRO1:
01938             DSP_AddData(0x3);DSP_AddData(0x0);break;
01939         case SBT_PRO2:
01940             if (sb.ess_type != ESS_NONE) {
01941                 DSP_AddData(0x3);DSP_AddData(0x1);
01942             }
01943             else if (sb.reveal_sc_type == RSC_SC400) { // SC400 cards report as v3.5 by default, but there is a DSP command to change the version!
01944                 DSP_AddData(sb.sc400_dsp_major);DSP_AddData(sb.sc400_dsp_minor);
01945             }
01946             else {
01947                 DSP_AddData(0x3);DSP_AddData(0x2);
01948             }
01949             break;
01950         case SBT_16:
01951             if (sb.vibra) {
01952                 DSP_AddData(4); /* SB16 ViBRA DSP 4.13 */
01953                 DSP_AddData(13);
01954             }
01955             else {
01956                 DSP_AddData(4); /* SB16 DSP 4.05 */
01957                 DSP_AddData(5);
01958             }
01959             break;
01960         default:
01961             break;
01962         }
01963         break;
01964     case 0xe2:  /* Weird DMA identification write routine */
01965         {
01966             LOG(LOG_SB,LOG_NORMAL)("DSP Function 0xe2");
01967             sb.e2.valadd += sb.dsp.in.data[0] ^ sb.e2.valxor;
01968             sb.e2.valxor = (sb.e2.valxor >> 2u) | (sb.e2.valxor << 6u);
01969             GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_E2_DMA_CallBack);
01970         }
01971         break;
01972     case 0xe3:  /* DSP Copyright */
01973         {
01974             DSP_FlushData();
01975             if (sb.ess_type != ESS_NONE) {
01976                 /* ESS chips do not return copyright string */
01977                 DSP_AddData(0);
01978             }
01979             else if (sb.reveal_sc_type == RSC_SC400) {
01980                 static const char *gallant = "SC-6000";
01981 
01982                 /* NTS: Yes, this writes the terminating NUL as well. Not a bug. */
01983                 for (size_t i=0;i<=strlen(gallant);i++) {
01984                     DSP_AddData((Bit8u)gallant[i]);
01985                 }
01986             }
01987             else if (sb.type <= SBT_PRO2) {
01988                 /* Sound Blaster DSP 2.0: No copyright string observed. */
01989                 /* Sound Blaster Pro DSP 3.1: No copyright string observed. */
01990                 /* I have yet to observe if a Sound Blaster Pro DSP 3.2 (SBT_PRO2) returns a copyright string. */
01991                 /* no response */
01992             }
01993             else {
01994                 /* NTS: Yes, this writes the terminating NUL as well. Not a bug. */
01995                 for (size_t i=0;i<=strlen(copyright_string);i++) {
01996                     DSP_AddData((Bit8u)copyright_string[i]);
01997                 }
01998             }
01999         }
02000         break;
02001     case 0xe4:  /* Write Test Register */
02002         sb.dsp.test_register=sb.dsp.in.data[0];
02003         break;
02004     case 0xe7:  /* ESS detect/read config */
02005         if (sb.ess_type != ESS_NONE) {
02006             DSP_FlushData();
02007             DSP_AddData(0x68);
02008             DSP_AddData(0x80 | 0x04/*ESS 688 version*/);
02009         }
02010         break;
02011     case 0xe8:  /* Read Test Register */
02012         DSP_FlushData();
02013         DSP_AddData(sb.dsp.test_register);
02014         break;
02015     case 0xf2:  /* Trigger 8bit IRQ */
02016         //Small delay in order to emulate the slowness of the DSP, fixes Llamatron 2012 and Lemmings 3D
02017         PIC_AddEvent(&DSP_RaiseIRQEvent,0.01f); 
02018         break;
02019     case 0xf3:   /* Trigger 16bit IRQ */
02020         DSP_SB16_ONLY; 
02021         SB_RaiseIRQ(SB_IRQ_16);
02022         break;
02023     case 0xf8:  /* Undocumented, pre-SB16 only */
02024         DSP_FlushData();
02025         DSP_AddData(0);
02026         break;
02027     case 0x30: case 0x31: case 0x32: case 0x33:
02028         LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented MIDI I/O command %2X",sb.dsp.cmd);
02029         break;
02030     case 0x34: /* MIDI Read Poll & Write Poll */
02031         DSP_SB2_ABOVE;
02032         LOG(LOG_SB,LOG_DEBUG)("DSP:Entering MIDI Read/Write Poll mode");
02033         sb.dsp.midi_rwpoll_mode = true;
02034         break;
02035     case 0x35: /* MIDI Read Interrupt & Write Poll */
02036         DSP_SB2_ABOVE;
02037         LOG(LOG_SB,LOG_DEBUG)("DSP:Entering MIDI Read Interrupt/Write Poll mode");
02038         sb.dsp.midi_rwpoll_mode = true;
02039         sb.dsp.midi_read_interrupt = true;
02040         break;
02041     case 0x37: /* MIDI Read Timestamp Interrupt & Write Poll */
02042         DSP_SB2_ABOVE;
02043         LOG(LOG_SB,LOG_DEBUG)("DSP:Entering MIDI Read Timstamp Interrupt/Write Poll mode");
02044         sb.dsp.midi_rwpoll_mode = true;
02045         sb.dsp.midi_read_interrupt = true;
02046         sb.dsp.midi_read_with_timestamps = true;
02047         break;
02048     case 0x20:
02049         DSP_AddData(0x7f);   // fake silent input for Creative parrot
02050         break;
02051     case 0x2c:
02052     case 0x98: case 0x99: /* Documented only for DSP 2.x and 3.x */
02053     case 0xa0: case 0xa8: /* Documented only for DSP 3.x */
02054         LOG(LOG_SB,LOG_ERROR)("DSP:Unimplemented input command %2X",sb.dsp.cmd);
02055         break;
02056     case 0x88: /* Reveal SC400 ??? (used by TESTSC.EXE) */
02057         if (sb.reveal_sc_type != RSC_SC400) break;
02058         /* ??? */
02059         break;
02060     case 0xE6: /* Reveal SC400 DMA test */
02061         if (sb.reveal_sc_type != RSC_SC400) break;
02062         GetDMAChannel(sb.hw.dma8)->Register_Callback(DSP_SC400_E6_DMA_CallBack);
02063         sb.dsp.out.lastval = 0x80;
02064         sb.dsp.out.used = 0;
02065         break;
02066     case 0x50: /* Reveal SC400 write configuration */
02067         if (sb.reveal_sc_type != RSC_SC400) break;
02068         sb.sc400_cfg = sb.dsp.in.data[0];
02069 
02070         switch (sb.dsp.in.data[0]&3) {
02071             case 0: sb.hw.dma8 = (Bit8u)(-1); break;
02072             case 1: sb.hw.dma8 =  0u; break;
02073             case 2: sb.hw.dma8 =  1u; break;
02074             case 3: sb.hw.dma8 =  3u; break;
02075         }
02076         sb.hw.dma16 = sb.hw.dma8;
02077         switch ((sb.dsp.in.data[0]>>3)&7) {
02078             case 0: sb.hw.irq =  (Bit8u)(-1); break;
02079             case 1: sb.hw.irq =  7u; break;
02080             case 2: sb.hw.irq =  9u; break;
02081             case 3: sb.hw.irq = 10u; break;
02082             case 4: sb.hw.irq = 11u; break;
02083             case 5: sb.hw.irq =  5u; break;
02084             case 6: sb.hw.irq =  (Bit8u)(-1); break;
02085             case 7: sb.hw.irq =  (Bit8u)(-1); break;
02086         }
02087         {
02088             int irq;
02089 
02090             if (sb.dsp.in.data[0]&0x04) /* MPU IRQ enable bit */
02091                 irq = (sb.dsp.in.data[0]&0x80) ? 9 : 5;
02092             else
02093                 irq = -1;
02094 
02095             if (irq != MPU401_GetIRQ())
02096                 LOG(LOG_SB,LOG_WARN)("SC400 warning: MPU401 emulation does not yet support changing the IRQ through configuration commands");
02097         }
02098 
02099         LOG(LOG_SB,LOG_DEBUG)("SC400: New configuration byte %02x irq=%d dma=%d",
02100             sb.dsp.in.data[0],(int)sb.hw.irq,(int)sb.hw.dma8);
02101 
02102         break;
02103     case 0x58: /* Reveal SC400 read configuration */
02104         if (sb.reveal_sc_type != RSC_SC400) break;
02105         DSP_AddData(sb.sc400_jumper_status_1);
02106         DSP_AddData(sb.sc400_jumper_status_2);
02107         DSP_AddData(sb.sc400_cfg);
02108         break;
02109     case 0x6E: /* Reveal SC400 SBPRO.EXE set DSP version */
02110         if (sb.reveal_sc_type != RSC_SC400) break;
02111         sb.sc400_dsp_major = sb.dsp.in.data[0];
02112         sb.sc400_dsp_minor = sb.dsp.in.data[1];
02113         LOG(LOG_SB,LOG_DEBUG)("SC400: DSP version changed to %u.%u",
02114             sb.sc400_dsp_major,sb.sc400_dsp_minor);
02115         break;
02116     case 0xfa:  /* SB16 8051 memory write */
02117         if (sb.type == SBT_16) {
02118             sb16_8051_mem[sb.dsp.in.data[0]] = sb.dsp.in.data[1];
02119             LOG(LOG_SB,LOG_NORMAL)("SB16 8051 memory write %x byte %x",sb.dsp.in.data[0],sb.dsp.in.data[1]);
02120         } else {
02121             LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled (undocumented) command %2X",sb.dsp.cmd);
02122         }
02123         break;
02124     case 0xf9:  /* SB16 8051 memory read */
02125         if (sb.type == SBT_16) {
02126             DSP_AddData(sb16_8051_mem[sb.dsp.in.data[0]]);
02127             LOG(LOG_SB,LOG_NORMAL)("SB16 8051 memory read %x, got byte %x",sb.dsp.in.data[0],sb16_8051_mem[sb.dsp.in.data[0]]);
02128         } else {
02129             LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled (undocumented) command %2X",sb.dsp.cmd);
02130         }
02131         break;
02132     default:
02133         LOG(LOG_SB,LOG_ERROR)("DSP:Unhandled (undocumented) command %2X",sb.dsp.cmd);
02134         break;
02135     }
02136 
02137     if (sb.type == SBT_16) {
02138         // FIXME: This is a guess! See also [https://github.com/joncampbell123/dosbox-x/issues/1044#issuecomment-480024957]
02139         sb16_8051_mem[0x30] = sb.dsp.last_cmd; /* last_cmd */
02140     }
02141 
02142     sb.dsp.last_cmd=sb.dsp.cmd;
02143     sb.dsp.cmd=DSP_NO_COMMAND;
02144     sb.dsp.cmd_len=0;
02145     sb.dsp.in.pos=0;
02146 }
02147 
02148 static bool DSP_busy_cycle_active() {
02149     /* NTS: Busy cycle happens on SB16 at all times, or on earlier cards, only when the DSP is
02150      *      fetching/writing data via the ISA DMA channel. So a non-auto-init DSP block that's
02151      *      just finished fetching ISA DMA and is playing from the FIFO doesn't count.
02152      *
02153      *      sb.dma.left >= sb.dma.min condition causes busy cycle to stop 3ms early (by default).
02154      *      This helps realism.
02155      *
02156      *      This also helps Crystal Dream, which uses the busy cycle to detect when the Sound
02157      *      Blaster is about to finish playing the DSP block and therefore needs the same 3ms
02158      *      "dmamin" hack to reissue another playback command without any audible hiccups in
02159      *      the audio. */
02160     return (sb.mode == MODE_DMA && (sb.dma.autoinit || sb.dma.left >= sb.dma.min)) || sb.busy_cycle_always;
02161 }
02162 
02163 static bool DSP_busy_cycle() {
02164     double now;
02165     int t;
02166 
02167     if (!DSP_busy_cycle_active()) return false;
02168     if (sb.busy_cycle_duty_percent <= 0 || sb.busy_cycle_hz <= 0) return false;
02169 
02170     /* NTS: DOSBox's I/O emulation doesn't yet attempt to accurately match ISA bus speeds or
02171      *      consider ISA bus cycles, but to emulate SB16 behavior we have to "time" it so
02172      *      that 8 consecutive I/O reads eventually see a transition from busy to not busy
02173      *      (or the other way around). So what this hack does is it uses accurate timing
02174      *      to determine where in the cycle we are, but if this function is called repeatedly
02175      *      through I/O access, we switch to incrementing a counter to ensure busy/not busy
02176      *      transition happens in 8 I/O cycles.
02177      *
02178      *      Without this hack, the CPU cycles count becomes a major factor in how many I/O
02179      *      reads are required for busy/not busy to happen. If you set cycles count high
02180      *      enough, more than 8 is required, and the SNDSB test code will have issues with
02181      *      direct DAC mode again.
02182      *
02183      *      This isn't 100% accurate, but it's the best DOSBox-X can do for now to mimick
02184      *      SB16 DSP behavior. */
02185 
02186     now = PIC_FullIndex();
02187     if (now >= (sb.busy_cycle_last_check+0.02/*ms*/))
02188         sb.busy_cycle_io_hack = (int)(fmod((now / 1000) * sb.busy_cycle_hz,1.0) * 16);
02189 
02190     sb.busy_cycle_last_check = now;
02191     t = ((sb.busy_cycle_io_hack % 16) * 100) / 16; /* HACK: DOSBox's I/O is not quite ISA bus speeds or related to it */
02192     if (t < sb.busy_cycle_duty_percent) return true;
02193     return false;
02194 }
02195 
02196 static void DSP_DoWrite(Bit8u val) {
02197     if (sb.dsp.write_busy || (sb.dsp.highspeed && sb.type != SBT_16 && sb.ess_type == ESS_NONE && sb.reveal_sc_type == RSC_NONE)) {
02198         LOG(LOG_SB,LOG_WARN)("DSP:Command write %2X ignored, DSP not ready. DOS game or OS is not polling status",val);
02199         return;
02200     }
02201 
02202     /* NTS: We allow the user to set busy wait time == 0 aka "instant gratification mode".
02203      *      We also assume that if they do that, some DOS programs might be timing sensitive
02204      *      enough to freak out when DSP commands and data are accepted immediately */
02205     {
02206         unsigned int delay = sb.dsp.dsp_write_busy_time;
02207 
02208         if (sb.dsp.instant_direct_dac) {
02209             delay = 0;
02210         }
02211         /* Part of enforcing sample rate limits is to make sure to emulate that the
02212          * Direct DAC output command 0x10 is "busy" long enough to effectively rate
02213          * limit output to 23KHz. */
02214         else if (sb.sample_rate_limits) {
02215             unsigned int limit = 23000; /* documented max sample rate for SB16/SBPro and earlier */
02216 
02217             if (sb.type == SBT_16 && sb.vibra)
02218                 limit = 23000; /* DSP maxes out at 46KHz not 44.1KHz on ViBRA cards */
02219 
02220             if (sb.dsp.cmd == DSP_NO_COMMAND && val == 0x10/*DSP direct DAC, command*/)
02221                 delay = (625000000UL / limit) - sb.dsp.dsp_write_busy_time;
02222         }
02223 
02224         if (delay > 0) {
02225             sb.dsp.write_busy = 1;
02226             PIC_RemoveEvents(DSP_BusyComplete);
02227             PIC_AddEvent(DSP_BusyComplete,(double)delay / 1000000);
02228         }
02229 
02230 //      LOG(LOG_SB,LOG_NORMAL)("DSP:Command %02x delay %u",val,delay);
02231     }
02232 
02233     if (sb.dsp.midi_rwpoll_mode) {
02234         // DSP writes in this mode go to the MIDI port
02235 //      LOG(LOG_SB,LOG_DEBUG)("DSP MIDI read/write poll mode: sending 0x%02x",val);
02236         if (sb.midi == true) MIDI_RawOutByte(val);
02237         return;
02238     }
02239 
02240     switch (sb.dsp.cmd) {
02241         case DSP_NO_COMMAND:
02242             sb.dsp.cmd=val;
02243             if (sb.type == SBT_16)
02244                 sb.dsp.cmd_len=DSP_cmd_len_sb16[val];
02245             else if (sb.ess_type != ESS_NONE) 
02246                 sb.dsp.cmd_len=DSP_cmd_len_ess[val];
02247             else if (sb.reveal_sc_type != RSC_NONE)
02248                 sb.dsp.cmd_len=DSP_cmd_len_sc400[val];
02249             else
02250                 sb.dsp.cmd_len=DSP_cmd_len_sb[val];
02251 
02252             sb.dsp.in.pos=0;
02253             if (!sb.dsp.cmd_len) DSP_DoCommand();
02254             break;
02255         default:
02256             sb.dsp.in.data[sb.dsp.in.pos]=val;
02257             sb.dsp.in.pos++;
02258             if (sb.dsp.in.pos>=sb.dsp.cmd_len) DSP_DoCommand();
02259     }
02260 }
02261 
02262 static Bit8u DSP_ReadData(void) {
02263 /* Static so it repeats the last value on succesive reads (JANGLE DEMO) */
02264     if (sb.dsp.out.used) {
02265         sb.dsp.out.lastval=sb.dsp.out.data[sb.dsp.out.pos];
02266         sb.dsp.out.pos++;
02267         if (sb.dsp.out.pos>=DSP_BUFSIZE) sb.dsp.out.pos-=DSP_BUFSIZE;
02268         sb.dsp.out.used--;
02269     }
02270     return sb.dsp.out.lastval;
02271 }
02272 
02273 //The soundblaster manual says 2.0 Db steps but we'll go for a bit less
02274 static float calc_vol(Bit8u amount) {
02275     Bit8u count = 31 - amount;
02276     float db = static_cast<float>(count);
02277     if (sb.type == SBT_PRO1 || sb.type == SBT_PRO2) {
02278         if (count) {
02279             if (count < 16) db -= 1.0f;
02280             else if (count > 16) db += 1.0f;
02281             if (count == 24) db += 2.0f;
02282             if (count > 27) return 0.0f; //turn it off.
02283         }
02284     } else { //Give the rest, the SB16 scale, as we don't have data.
02285         db *= 2.0f;
02286         if (count > 20) db -= 1.0f;
02287     }
02288     return (float) pow (10.0f,-0.05f * db);
02289 }
02290 static void CTMIXER_UpdateVolumes(void) {
02291     if (!sb.mixer.enabled) return;
02292 
02293     sb.chan->FillUp();
02294 
02295     MixerChannel * chan;
02296     float m0 = calc_vol(sb.mixer.master[0]);
02297     float m1 = calc_vol(sb.mixer.master[1]);
02298     chan = MIXER_FindChannel("SB");
02299     if (chan) chan->SetVolume(m0 * calc_vol(sb.mixer.dac[0]), m1 * calc_vol(sb.mixer.dac[1]));
02300     chan = MIXER_FindChannel("FM");
02301     if (chan) chan->SetVolume(m0 * calc_vol(sb.mixer.fm[0]) , m1 * calc_vol(sb.mixer.fm[1]) );
02302     chan = MIXER_FindChannel("CDAUDIO");
02303     if (chan) chan->SetVolume(m0 * calc_vol(sb.mixer.cda[0]), m1 * calc_vol(sb.mixer.cda[1]));
02304 }
02305 
02306 static void CTMIXER_Reset(void) {
02307     sb.mixer.filtered=0; // Creative Documentation: filtered bit 0 by default
02308     sb.mixer.fm[0]=
02309     sb.mixer.fm[1]=
02310     sb.mixer.cda[0]=
02311     sb.mixer.cda[1]=
02312     sb.mixer.dac[0]=
02313     sb.mixer.dac[1]=31;
02314     sb.mixer.master[0]=
02315     sb.mixer.master[1]=31;
02316     CTMIXER_UpdateVolumes();
02317 }
02318 
02319 #define SETPROVOL(_WHICH_,_VAL_)                                        \
02320     _WHICH_[0]=   ((((_VAL_) & 0xf0) >> 3)|(sb.type==SBT_16 ? 1:3));    \
02321     _WHICH_[1]=   ((((_VAL_) & 0x0f) << 1)|(sb.type==SBT_16 ? 1:3));    \
02322 
02323 #define MAKEPROVOL(_WHICH_)                                                                                     \
02324         ((((_WHICH_[0] & 0x1e) << 3) | ((_WHICH_[1] & 0x1e) >> 1)) |    \
02325                 ((sb.type==SBT_PRO1 || sb.type==SBT_PRO2) ? 0x11:0))
02326 
02327 // TODO: Put out the various hardware listed here, do some listening tests to confirm the emulation is accurate.
02328 void updateSoundBlasterFilter(Bitu rate) {
02329     /* "No filtering" option for those who don't want it, or are used to the way things sound in plain vanilla DOSBox */
02330     if (sb.no_filtering) {
02331         sb.chan->SetLowpassFreq(0/*off*/);
02332         sb.chan->SetSlewFreq(0/*normal linear interpolation*/);
02333         return;
02334     }
02335 
02336     /* different sound cards filter their output differently */
02337     if (sb.ess_type != ESS_NONE) { // ESS AudioDrive. Tested against real hardware (ESS 688) by Jonathan C.
02338         /* ESS AudioDrive lets the driver decide what the cutoff/rolloff to use */
02339         /* "The ratio of the roll-off frequency to the clock frequency is 1:82. In other words,
02340          * first determine the desired roll off frequency by taking 80% of the sample rate
02341          * divided by 2, the multiply by 82 to find the desired filter clock frequency"
02342          *
02343          * Try to approximate the ESS's filter by undoing the calculation then feeding our own lowpass filter with it.
02344          *
02345          * This implementation is matched aginst real hardware by ear, even though the reference hardware is a
02346          * laptop with a cheap tinny amplifier */
02347         Bit64u filter_raw = (Bit64u)7160000ULL / (256u - ESSreg(0xA2));
02348         Bit64u filter_hz = (filter_raw * (Bit64u)11) / (Bit64u)(82 * 4); /* match lowpass by ear compared to real hardware */
02349 
02350         if ((filter_hz * 2) > sb.freq)
02351             sb.chan->SetSlewFreq(filter_hz * 2 * sb.chan->freq_d_orig);
02352         else
02353             sb.chan->SetSlewFreq(0);
02354 
02355         sb.chan->SetLowpassFreq(filter_hz,/*order*/8);
02356     }
02357     else if (sb.type == SBT_16 || // Sound Blaster 16 (DSP 4.xx). Tested against real hardware (CT4180 ViBRA 16C PnP) by Jonathan C.
02358         sb.reveal_sc_type == RSC_SC400) { // Reveal SC400 (DSP 3.5). Tested against real hardware by Jonathan C.
02359         // My notes: The DSP automatically applies filtering at low sample rates. But the DSP has to know
02360         //           what the sample rate is to filter. If you use direct DAC output (DSP command 0x10)
02361         //           then no filtering is applied and the sound comes out grungy, just like older Sound
02362         //           Blaster cards.
02363         //
02364         //           I can also confirm the SB16's reputation for hiss and noise is true, it's noticeable
02365         //           with earbuds and the mixer volume at normal levels. --Jonathan C.
02366         if (sb.mode == MODE_DAC) {
02367             sb.chan->SetLowpassFreq(23000);
02368             sb.chan->SetSlewFreq(23000 * sb.chan->freq_d_orig);
02369         }
02370         else {
02371             sb.chan->SetLowpassFreq(rate/2,1);
02372             sb.chan->SetSlewFreq(0/*normal linear interpolation*/);
02373         }
02374     }
02375     else if (sb.type == SBT_PRO1 || sb.type == SBT_PRO2) { // Sound Blaster Pro (DSP 3.x). Tested against real hardware (CT1600) by Jonathan C.
02376         sb.chan->SetSlewFreq(23000 * sb.chan->freq_d_orig);
02377         if (sb.mixer.filtered/*setting the bit means to bypass the lowpass filter*/)
02378             sb.chan->SetLowpassFreq(23000); // max sample rate 46000Hz. slew rate filter does the rest of the filtering for us.
02379         else
02380             sb.chan->SetLowpassFreq(3800); // NOT documented by Creative, guess based on listening tests with a CT1600, and documented Input filter freqs
02381     }
02382     else if (sb.type == SBT_1 || sb.type == SBT_2) { // Sound Blaster DSP 1.x and 2.x (not Pro). Tested against real hardware (CT1350B) by Jonathan C.
02383         /* As far as I can tell the DAC outputs sample-by-sample with no filtering whatsoever, aside from the limitations of analog audio */
02384         sb.chan->SetSlewFreq(23000 * sb.chan->freq_d_orig);
02385         sb.chan->SetLowpassFreq(23000);
02386     }
02387 }
02388 
02389 static void DSP_ChangeStereo(bool stereo) {
02390     if (!sb.dma.stereo && stereo) {
02391         sb.chan->SetFreq(sb.freq/2);
02392         updateSoundBlasterFilter(sb.freq/2);
02393         sb.dma.mul*=2;
02394         sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH;
02395         sb.dma.min=((Bitu)sb.dma.rate*(Bitu)(sb.min_dma_user >= 0 ? sb.min_dma_user : /*default*/3))/1000u;
02396     } else if (sb.dma.stereo && !stereo) {
02397         sb.chan->SetFreq(sb.freq);
02398         updateSoundBlasterFilter(sb.freq);
02399         sb.dma.mul/=2;
02400         sb.dma.rate=(sb.freq*sb.dma.mul) >> SB_SH;
02401         sb.dma.min=((Bitu)sb.dma.rate*(Bitu)(sb.min_dma_user >= 0 ? sb.min_dma_user : /*default*/3))/1000;
02402     }
02403     sb.dma.stereo=stereo;
02404 }
02405 
02406 static inline uint8_t expand16to32(const uint8_t t) {
02407     /* 4-bit -> 5-bit expansion.
02408      *
02409      * 0 -> 0
02410      * 1 -> 2
02411      * 2 -> 4
02412      * 3 -> 6
02413      * ....
02414      * 7 -> 14
02415      * 8 -> 17
02416      * 9 -> 19
02417      * 10 -> 21
02418      * 11 -> 23
02419      * ....
02420      * 15 -> 31 */
02421     return (t << 1) | (t >> 3);
02422 }
02423 
02424 static unsigned char pc98_mixctl_reg = 0x14;
02425 
02426 /* Sound Blaster Pro 2 (CT1600) notes:
02427  *
02428  * - Registers 0x40-0xFF do nothing written and read back 0xFF.
02429  * - Registers 0x00-0x3F are almost exact mirrors of registers 0x00-0x0F, but not quite
02430  * - Registers 0x00-0x1F are exact mirrors of 0x00-0x1F
02431  * - Registers 0x20-0x3F are exact mirrors of 0x20-0x2F which are.... non functional shadow copies of 0x00-0x0F (???)
02432  * - Register 0x0E is mirrored at 0x0F, 0x1E, 0x1F. Reading 0x00, 0x01, 0x10, 0x11 also reads register 0x0E.
02433  * - Writing 0x00, 0x01, 0x10, 0x11 resets the mixer as expected.
02434  * - Register 0x0E is 0x11 on reset, which defaults to mono and lowpass filter enabled.
02435  * - See screenshot for mixer registers on hardware or mixer reset, file 'CT1600 Sound Blaster Pro 2 mixer register dump hardware and mixer reset state.png' */
02436 static void CTMIXER_Write(Bit8u val) {
02437     switch (sb.mixer.index) {
02438     case 0x00:      /* Reset */
02439         CTMIXER_Reset();
02440         LOG(LOG_SB,LOG_WARN)("Mixer reset value %x",val);
02441         break;
02442     case 0x02:      /* Master Volume (SB2 Only) */
02443         SETPROVOL(sb.mixer.master,(val&0xf)|(val<<4));
02444         CTMIXER_UpdateVolumes();
02445         break;
02446     case 0x04:      /* DAC Volume (SBPRO) */
02447         SETPROVOL(sb.mixer.dac,val);
02448         CTMIXER_UpdateVolumes();
02449         break;
02450     case 0x06:      /* FM output selection, Somewhat obsolete with dual OPL SBpro + FM volume (SB2 Only) */
02451         //volume controls both channels
02452         SETPROVOL(sb.mixer.fm,(val&0xf)|(val<<4));
02453         CTMIXER_UpdateVolumes();
02454         if(val&0x60) LOG(LOG_SB,LOG_WARN)("Turned FM one channel off. not implemented %X",val);
02455         //TODO Change FM Mode if only 1 fm channel is selected
02456         break;
02457     case 0x08:      /* CDA Volume (SB2 Only) */
02458         SETPROVOL(sb.mixer.cda,(val&0xf)|(val<<4));
02459         CTMIXER_UpdateVolumes();
02460         break;
02461     case 0x0a:      /* Mic Level (SBPRO) or DAC Volume (SB2): 2-bit, 3-bit on SB16 */
02462         if (sb.type==SBT_2) {
02463             sb.mixer.dac[0]=sb.mixer.dac[1]=((val & 0x6) << 2)|3;
02464             CTMIXER_UpdateVolumes();
02465         } else {
02466             sb.mixer.mic=((val & 0x7) << 2)|(sb.type==SBT_16?1:3);
02467         }
02468         break;
02469     case 0x0e:      /* Output/Stereo Select */
02470         /* Real CT1600 notes:
02471          *
02472          * This register only allows changing bits 1 and 5. Each nibble can be 1 or 3, therefore on readback it will always be 0x11, 0x13, 0x31, or 0x11.
02473          * This register is also mirrored at 0x0F, 0x1E, 0x1F. On read this register also appears over 0x00, 0x01, 0x10, 0x11, though writing that register
02474          * resets the mixer as expected. */
02475         /* only allow writing stereo bit if Sound Blaster Pro OR if a SB16 and user says to allow it */
02476         if ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) || (sb.type == SBT_16 && !sb.sbpro_stereo_bit_strict_mode))
02477             sb.mixer.stereo=(val & 0x2) > 0;
02478 
02479         sb.mixer.sbpro_stereo=(val & 0x2) > 0;
02480         sb.mixer.filtered=(val & 0x20) > 0;
02481         DSP_ChangeStereo(sb.mixer.stereo);
02482         updateSoundBlasterFilter(sb.freq);
02483 
02484         /* help the user out if they leave sbtype=sb16 and then wonder why their DOS game is producing scratchy monural audio. */
02485         if (sb.type == SBT_16 && sb.sbpro_stereo_bit_strict_mode && (val&0x2) != 0)
02486             LOG(LOG_SB,LOG_WARN)("Mixer stereo/mono bit is set. This is Sound Blaster Pro style Stereo which is not supported by sbtype=sb16, consider using sbtype=sbpro2 instead.");
02487         break;
02488     case 0x14:      /* Audio 1 Play Volume (ESS 688) */
02489         if (sb.ess_type != ESS_NONE) {
02490             sb.mixer.dac[0]=expand16to32((val>>4)&0xF);
02491             sb.mixer.dac[1]=expand16to32(val&0xF);
02492             CTMIXER_UpdateVolumes();
02493         }
02494         break;
02495     case 0x22:      /* Master Volume (SBPRO) */
02496         SETPROVOL(sb.mixer.master,val);
02497         CTMIXER_UpdateVolumes();
02498         break;
02499     case 0x26:      /* FM Volume (SBPRO) */
02500         SETPROVOL(sb.mixer.fm,val);
02501         CTMIXER_UpdateVolumes();
02502         break;
02503     case 0x28:      /* CD Audio Volume (SBPRO) */
02504         SETPROVOL(sb.mixer.cda,val);
02505         CTMIXER_UpdateVolumes();
02506         break;
02507     case 0x2e:      /* Line-in Volume (SBPRO) */
02508         SETPROVOL(sb.mixer.lin,val);
02509         break;
02510     //case 0x20:        /* Master Volume Left (SBPRO) ? */
02511     case 0x30:      /* Master Volume Left (SB16) */
02512         if (sb.type==SBT_16) {
02513             sb.mixer.master[0]=val>>3;
02514             CTMIXER_UpdateVolumes();
02515         }
02516         break;
02517     //case 0x21:        /* Master Volume Right (SBPRO) ? */
02518     case 0x31:      /* Master Volume Right (SB16) */
02519         if (sb.type==SBT_16) {
02520             sb.mixer.master[1]=val>>3;
02521             CTMIXER_UpdateVolumes();
02522         }
02523         break;
02524     case 0x32:      /* DAC Volume Left (SB16) */
02525                 /* Master Volume (ESS 688) */
02526         if (sb.type==SBT_16) {
02527             sb.mixer.dac[0]=val>>3;
02528             CTMIXER_UpdateVolumes();
02529         }
02530         else if (sb.ess_type != ESS_NONE) {
02531             sb.mixer.master[0]=expand16to32((val>>4)&0xF);
02532             sb.mixer.master[1]=expand16to32(val&0xF);
02533             CTMIXER_UpdateVolumes();
02534         }
02535         break;
02536     case 0x33:      /* DAC Volume Right (SB16) */
02537         if (sb.type==SBT_16) {
02538             sb.mixer.dac[1]=val>>3;
02539             CTMIXER_UpdateVolumes();
02540         }
02541         break;
02542     case 0x34:      /* FM Volume Left (SB16) */
02543         if (sb.type==SBT_16) {
02544             sb.mixer.fm[0]=val>>3;
02545             CTMIXER_UpdateVolumes();
02546         }
02547                 break;
02548     case 0x35:      /* FM Volume Right (SB16) */
02549         if (sb.type==SBT_16) {
02550             sb.mixer.fm[1]=val>>3;
02551             CTMIXER_UpdateVolumes();
02552         }
02553         break;
02554     case 0x36:      /* CD Volume Left (SB16) */
02555                 /* FM Volume (ESS 688) */
02556         if (sb.type==SBT_16) {
02557             sb.mixer.cda[0]=val>>3;
02558             CTMIXER_UpdateVolumes();
02559         }
02560         else if (sb.ess_type != ESS_NONE) {
02561             sb.mixer.fm[0]=expand16to32((val>>4)&0xF);
02562             sb.mixer.fm[1]=expand16to32(val&0xF);
02563             CTMIXER_UpdateVolumes();
02564         }
02565         break;
02566     case 0x37:      /* CD Volume Right (SB16) */
02567         if (sb.type==SBT_16) {
02568             sb.mixer.cda[1]=val>>3;
02569             CTMIXER_UpdateVolumes();
02570         }
02571         break;
02572     case 0x38:      /* Line-in Volume Left (SB16) */
02573                 /* AuxA (CD) Volume Register (ESS 688) */
02574         if (sb.type==SBT_16)
02575             sb.mixer.lin[0]=val>>3;
02576         else if (sb.ess_type != ESS_NONE) {
02577             sb.mixer.cda[0]=expand16to32((val>>4)&0xF);
02578             sb.mixer.cda[1]=expand16to32(val&0xF);
02579             CTMIXER_UpdateVolumes();
02580         }
02581         break;
02582     case 0x39:      /* Line-in Volume Right (SB16) */
02583         if (sb.type==SBT_16) sb.mixer.lin[1]=val>>3;
02584         break;
02585     case 0x3a:
02586         if (sb.type==SBT_16) sb.mixer.mic=val>>3;
02587         break;
02588     case 0x3e:      /* Line Volume (ESS 688) */
02589         if (sb.ess_type != ESS_NONE) {
02590             sb.mixer.lin[0]=expand16to32((val>>4)&0xF);
02591             sb.mixer.lin[1]=expand16to32(val&0xF);
02592         }
02593         break;
02594     case 0x80:      /* IRQ Select */
02595         if (sb.type==SBT_16 && !sb.vibra) { /* ViBRA PnP cards do not allow reconfiguration by this byte */
02596             sb.hw.irq=0xff;
02597             if (IS_PC98_ARCH) {
02598                 if (val & 0x1) sb.hw.irq=3;
02599                 else if (val & 0x2) sb.hw.irq=10;
02600                 else if (val & 0x4) sb.hw.irq=12;
02601                 else if (val & 0x8) sb.hw.irq=5;
02602 
02603                 // NTS: Real hardware stores only the low 4 bits. The upper 4 bits will always read back 1111.
02604                 //      The value read back will always be Fxh where x contains the 4 bits checked here.
02605             }
02606             else {
02607                 if (val & 0x1) sb.hw.irq=2;
02608                 else if (val & 0x2) sb.hw.irq=5;
02609                 else if (val & 0x4) sb.hw.irq=7;
02610                 else if (val & 0x8) sb.hw.irq=10;
02611             }
02612         }
02613         break;
02614     case 0x81:      /* DMA Select */
02615         if (sb.type==SBT_16 && !sb.vibra) { /* ViBRA PnP cards do not allow reconfiguration by this byte */
02616             sb.hw.dma8=0xff;
02617             sb.hw.dma16=0xff;
02618             if (IS_PC98_ARCH) {
02619                 pc98_mixctl_reg = (unsigned char)val ^ 0x14;
02620 
02621                 if (val & 0x1) sb.hw.dma8=0;
02622                 else if (val & 0x2) sb.hw.dma8=3;
02623 
02624                 // NTS: On real hardware, only bits 0 and 1 are writeable. bits 2 and 4 seem to act oddly in response to
02625                 //      bytes written:
02626                 //
02627                 //      write 0x00          read 0x14
02628                 //      write 0x01          read 0x15
02629                 //      write 0x02          read 0x16
02630                 //      write 0x03          read 0x17
02631                 //      write 0x04          read 0x10
02632                 //      write 0x05          read 0x11
02633                 //      write 0x06          read 0x12
02634                 //      write 0x07          read 0x13
02635                 //      write 0x08          read 0x1C
02636                 //      write 0x09          read 0x1D
02637                 //      write 0x0A          read 0x1E
02638                 //      write 0x0B          read 0x1F
02639                 //      write 0x0C          read 0x18
02640                 //      write 0x0D          read 0x19
02641                 //      write 0x0E          read 0x1A
02642                 //      write 0x0F          read 0x1B
02643                 //      write 0x10          read 0x04
02644                 //      write 0x11          read 0x05
02645                 //      write 0x12          read 0x06
02646                 //      write 0x13          read 0x07
02647                 //      write 0x14          read 0x00
02648                 //      write 0x15          read 0x01
02649                 //      write 0x16          read 0x02
02650                 //      write 0x17          read 0x03
02651                 //      write 0x18          read 0x0C
02652                 //      write 0x19          read 0x0D
02653                 //      write 0x1A          read 0x0E
02654                 //      write 0x1B          read 0x0F
02655                 //      write 0x1C          read 0x08
02656                 //      write 0x1D          read 0x09
02657                 //      write 0x1E          read 0x0A
02658                 //      write 0x1F          read 0x0B
02659                 //
02660                 //      This pattern repeats for any 5 bit value in bits [4:0] i.e. 0x20 will read back 0x34.
02661             }
02662             else {
02663                 if (val & 0x1) sb.hw.dma8=0;
02664                 else if (val & 0x2) sb.hw.dma8=1;
02665                 else if (val & 0x8) sb.hw.dma8=3;
02666                 if (val & 0x20) sb.hw.dma16=5;
02667                 else if (val & 0x40) sb.hw.dma16=6;
02668                 else if (val & 0x80) sb.hw.dma16=7;
02669             }
02670             LOG(LOG_SB,LOG_NORMAL)("Mixer select dma8:%x dma16:%x",sb.hw.dma8,sb.hw.dma16);
02671         }
02672         break;
02673     default:
02674 
02675         if( ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */
02676              (sb.type == SBT_16 && sb.mixer.index >= 0x3b && sb.mixer.index <= 0x47)) /* New SB16 registers */
02677             sb.mixer.unhandled[sb.mixer.index] = val;
02678         LOG(LOG_SB,LOG_WARN)("MIXER:Write %X to unhandled index %X",val,sb.mixer.index);
02679     }
02680 }
02681 
02682 static Bit8u CTMIXER_Read(void) {
02683     Bit8u ret = 0;
02684 
02685 //  if ( sb.mixer.index< 0x80) LOG_MSG("Read mixer %x",sb.mixer.index);
02686     switch (sb.mixer.index) {
02687     case 0x00:      /* RESET */
02688         return 0x00;
02689     case 0x02:      /* Master Volume (SB2 Only) */
02690         return ((sb.mixer.master[1]>>1) & 0xe);
02691     case 0x22:      /* Master Volume (SBPRO) */
02692         return  MAKEPROVOL(sb.mixer.master);
02693     case 0x04:      /* DAC Volume (SBPRO) */
02694         return MAKEPROVOL(sb.mixer.dac);
02695     case 0x06:      /* FM Volume (SB2 Only) + FM output selection */
02696         return ((sb.mixer.fm[1]>>1) & 0xe);
02697     case 0x08:      /* CD Volume (SB2 Only) */
02698         return ((sb.mixer.cda[1]>>1) & 0xe);
02699     case 0x0a:      /* Mic Level (SBPRO) or Voice (SB2 Only) */
02700         if (sb.type==SBT_2) return (sb.mixer.dac[0]>>2);
02701         else return ((sb.mixer.mic >> 2) & (sb.type==SBT_16 ? 7:6));
02702     case 0x0e:      /* Output/Stereo Select */
02703         return 0x11|(sb.mixer.stereo ? 0x02 : 0x00)|(sb.mixer.filtered ? 0x20 : 0x00);
02704     case 0x14:      /* Audio 1 Play Volume (ESS 688) */
02705         if (sb.ess_type != ESS_NONE) return ((sb.mixer.dac[0] << 3) & 0xF0) + (sb.mixer.dac[1] >> 1);
02706         break;
02707     case 0x26:      /* FM Volume (SBPRO) */
02708         return MAKEPROVOL(sb.mixer.fm);
02709     case 0x28:      /* CD Audio Volume (SBPRO) */
02710         return MAKEPROVOL(sb.mixer.cda);
02711     case 0x2e:      /* Line-IN Volume (SBPRO) */
02712         return MAKEPROVOL(sb.mixer.lin);
02713     case 0x30:      /* Master Volume Left (SB16) */
02714         if (sb.type==SBT_16) return sb.mixer.master[0]<<3;
02715         ret=0xa;
02716         break;
02717     case 0x31:      /* Master Volume Right (S16) */
02718         if (sb.type==SBT_16) return sb.mixer.master[1]<<3;
02719         ret=0xa;
02720         break;
02721     case 0x32:      /* DAC Volume Left (SB16) */
02722                 /* Master Volume (ESS 688) */
02723         if (sb.type==SBT_16) return sb.mixer.dac[0]<<3;
02724         if (sb.ess_type != ESS_NONE) return ((sb.mixer.master[0] << 3) & 0xF0) + (sb.mixer.master[1] >> 1);
02725         ret=0xa;
02726         break;
02727     case 0x33:      /* DAC Volume Right (SB16) */
02728         if (sb.type==SBT_16) return sb.mixer.dac[1]<<3;
02729         ret=0xa;
02730         break;
02731     case 0x34:      /* FM Volume Left (SB16) */
02732         if (sb.type==SBT_16) return sb.mixer.fm[0]<<3;
02733         ret=0xa;
02734         break;
02735     case 0x35:      /* FM Volume Right (SB16) */
02736         if (sb.type==SBT_16) return sb.mixer.fm[1]<<3;
02737         ret=0xa;
02738         break;
02739     case 0x36:      /* CD Volume Left (SB16) */
02740                 /* FM Volume (ESS 688) */
02741         if (sb.type==SBT_16) return sb.mixer.cda[0]<<3;
02742         if (sb.ess_type != ESS_NONE) return ((sb.mixer.fm[0] << 3) & 0xF0) + (sb.mixer.fm[1] >> 1);
02743         ret=0xa;
02744         break;
02745     case 0x37:      /* CD Volume Right (SB16) */
02746         if (sb.type==SBT_16) return sb.mixer.cda[1]<<3;
02747         ret=0xa;
02748         break;
02749     case 0x38:      /* Line-in Volume Left (SB16) */
02750                 /* AuxA (CD) Volume Register (ESS 688) */
02751         if (sb.type==SBT_16) return sb.mixer.lin[0]<<3;
02752         if (sb.ess_type != ESS_NONE) return ((sb.mixer.cda[0] << 3) & 0xF0) + (sb.mixer.cda[1] >> 1);
02753         ret=0xa;
02754         break;
02755     case 0x39:      /* Line-in Volume Right (SB16) */
02756         if (sb.type==SBT_16) return sb.mixer.lin[1]<<3;
02757         ret=0xa;
02758         break;
02759     case 0x3a:      /* Mic Volume (SB16) */
02760         if (sb.type==SBT_16) return sb.mixer.mic<<3;
02761         ret=0xa;
02762         break;
02763     case 0x3e:      /* Line Volume (ESS 688) */
02764         if (sb.ess_type != ESS_NONE) return ((sb.mixer.lin[0] << 3) & 0xF0) + (sb.mixer.lin[1] >> 1);
02765         break;
02766     case 0x80:      /* IRQ Select */
02767         ret=0;
02768         if (IS_PC98_ARCH) {
02769             switch (sb.hw.irq) {
02770                 case 3:  return 0xF1; // upper 4 bits always 1111
02771                 case 10: return 0xF2;
02772                 case 12: return 0xF4;
02773                 case 5:  return 0xF8;
02774             }
02775         }
02776         else {
02777             switch (sb.hw.irq) {
02778                 case 2:  return 0x1;
02779                 case 5:  return 0x2;
02780                 case 7:  return 0x4;
02781                 case 10: return 0x8;
02782             }
02783         }
02784         break;
02785     case 0x81:      /* DMA Select */
02786         ret=0;
02787         if (IS_PC98_ARCH) {
02788             switch (sb.hw.dma8) {
02789                 case 0:ret|=0x1;break;
02790                 case 3:ret|=0x2;break;
02791             }
02792 
02793             // there's some strange behavior on the PC-98 version of the card
02794             ret |= (pc98_mixctl_reg & (~3u));
02795         }
02796         else {
02797             switch (sb.hw.dma8) {
02798                 case 0:ret|=0x1;break;
02799                 case 1:ret|=0x2;break;
02800                 case 3:ret|=0x8;break;
02801             }
02802             switch (sb.hw.dma16) {
02803                 case 5:ret|=0x20;break;
02804                 case 6:ret|=0x40;break;
02805                 case 7:ret|=0x80;break;
02806             }
02807         }
02808         return ret;
02809     case 0x82:      /* IRQ Status */
02810         return  (sb.irq.pending_8bit ? 0x1 : 0) |
02811                 (sb.irq.pending_16bit ? 0x2 : 0) | 
02812                 ((sb.type == SBT_16) ? 0x20 : 0);
02813     default:
02814         if (    ((sb.type == SBT_PRO1 || sb.type == SBT_PRO2) && sb.mixer.index==0x0c) || /* Input control on SBPro */
02815             (sb.type == SBT_16 && sb.mixer.index >= 0x3b && sb.mixer.index <= 0x47)) /* New SB16 registers */
02816             ret = sb.mixer.unhandled[sb.mixer.index];
02817         else
02818             ret=0xa;
02819         LOG(LOG_SB,LOG_WARN)("MIXER:Read from unhandled index %X",sb.mixer.index);
02820     }
02821 
02822     return ret;
02823 }
02824 
02825 
02826 static Bitu read_sb(Bitu port,Bitu /*iolen*/) {
02827     if (!IS_PC98_ARCH) {
02828         /* All Creative hardware prior to Sound Blaster 16 appear to alias most of the I/O ports.
02829          * This has been confirmed on a Sound Blaster 2.0 and a Sound Blaster Pro (v3.1).
02830          * DSP aliasing is also faithfully emulated by the ESS AudioDrive. */
02831         if (sb.hw.sb_io_alias) {
02832             if ((port-sb.hw.base) == DSP_ACK_16BIT && sb.ess_type != ESS_NONE)
02833                 { } /* ESS AudioDrive does not alias DSP STATUS (0x22E) as seen on real hardware */
02834             else if ((port-sb.hw.base) < MIXER_INDEX || (port-sb.hw.base) > MIXER_DATA)
02835                 port &= ~1u;
02836         }
02837     }
02838 
02839     switch (((port-sb.hw.base) >> (IS_PC98_ARCH ? 8u : 0u)) & 0xFu) {
02840     case MIXER_INDEX:
02841         return sb.mixer.index;
02842     case MIXER_DATA:
02843         return CTMIXER_Read();
02844     case DSP_READ_DATA:
02845         return DSP_ReadData();
02846     case DSP_READ_STATUS:
02847         //TODO See for high speed dma :)
02848         if (sb.irq.pending_8bit)  {
02849             sb.irq.pending_8bit=false;
02850             PIC_DeActivateIRQ(sb.hw.irq);
02851         }
02852 
02853         if (sb.mode == MODE_DMA_REQUIRE_IRQ_ACK)
02854             sb.mode = MODE_DMA;
02855 
02856         if (sb.ess_type == ESS_NONE && (sb.type == SBT_1 || sb.type == SBT_2 || sb.type == SBT_PRO1 || sb.type == SBT_PRO2))
02857             return sb.dsp.out.used ? 0xAA : 0x2A; /* observed return values on SB 2.0---any significance? */
02858         else
02859             return sb.dsp.out.used ? 0xFF : 0x7F; /* normal return values */
02860         break;
02861     case DSP_ACK_16BIT:
02862         if (sb.ess_type == ESS_NONE && sb.type == SBT_16) {
02863             if (sb.irq.pending_16bit)  {
02864                 sb.irq.pending_16bit=false;
02865                 PIC_DeActivateIRQ(sb.hw.irq);
02866             }
02867 
02868             if (sb.mode == MODE_DMA_REQUIRE_IRQ_ACK)
02869                 sb.mode = MODE_DMA;
02870         }
02871         break;
02872     case DSP_WRITE_STATUS:
02873         switch (sb.dsp.state) {
02874             /* FIXME: On a SB 2.0 card I own, the port will usually read either 0x2A or 0xAA,
02875              *        rather than 0x7F or 0xFF. Is there any significance to that? */
02876         case DSP_S_NORMAL: {
02877             bool busy = false;
02878 
02879             /* NTS: DSP "busy cycle" is independent of whether the DSP is actually
02880              *      busy (executing a command) or highspeed mode. On SB16 hardware,
02881              *      writing a DSP command during the busy cycle means that the command
02882              *      is remembered, but not acted on until the DSP leaves it's busy
02883              *      cycle. */
02884             sb.busy_cycle_io_hack++; /* NTS: busy cycle I/O timing hack! */
02885             if (DSP_busy_cycle())
02886                 busy = true;
02887             else if (sb.dsp.write_busy || (sb.dsp.highspeed && sb.type != SBT_16 && sb.ess_type == ESS_NONE && sb.reveal_sc_type == RSC_NONE))
02888                 busy = true;
02889 
02890             if (!sb.write_status_must_return_7f && sb.ess_type == ESS_NONE && (sb.type == SBT_2 || sb.type == SBT_PRO1 || sb.type == SBT_PRO2))
02891                 return busy ? 0xAA : 0x2A; /* observed return values on SB 2.0---any significance? */
02892             else
02893                 return busy ? 0xFF : 0x7F; /* normal return values */
02894             
02895             } break;
02896         case DSP_S_RESET:
02897         case DSP_S_RESET_WAIT:
02898             return 0xff;
02899         }
02900         return 0xff;
02901     case DSP_RESET:
02902         return 0xff;
02903     default:
02904         LOG(LOG_SB,LOG_NORMAL)("Unhandled read from SB Port %4X",(int)port);
02905         break;
02906     }
02907     return 0xff;
02908 }
02909 
02910 static void write_sb(Bitu port,Bitu val,Bitu /*iolen*/) {
02911     /* All Creative hardware prior to Sound Blaster 16 appear to alias most of the I/O ports.
02912      * This has been confirmed on a Sound Blaster 2.0 and a Sound Blaster Pro (v3.1).
02913      * DSP aliasing is also faithfully emulated by the ESS AudioDrive. */
02914     if (!IS_PC98_ARCH) {
02915         if (sb.hw.sb_io_alias) {
02916             if ((port-sb.hw.base) == DSP_ACK_16BIT && sb.ess_type != ESS_NONE)
02917                 { } /* ESS AudioDrive does not alias DSP STATUS (0x22E) as seen on real hardware */
02918             else if ((port-sb.hw.base) < MIXER_INDEX || (port-sb.hw.base) > MIXER_DATA)
02919                 port &= ~1u;
02920         }
02921     }
02922 
02923     Bit8u val8=(Bit8u)(val&0xff);
02924     switch (((port-sb.hw.base) >> (IS_PC98_ARCH ? 8u : 0u)) & 0xFu) {
02925     case DSP_RESET:
02926         DSP_DoReset(val8);
02927         break;
02928     case DSP_WRITE_DATA:
02929         /* FIXME: We need to emulate behavior where either the DSP command is delayed (busy cycle)
02930          *        and then acted on, or we need to emulate the DSP ignoring the byte because a
02931          *        command is in progress */
02932         DSP_DoWrite(val8);
02933         break;
02934     case MIXER_INDEX:
02935         sb.mixer.index=val8;
02936         break;
02937     case MIXER_DATA:
02938         CTMIXER_Write(val8);
02939         break;
02940     default:
02941         LOG(LOG_SB,LOG_NORMAL)("Unhandled write to SB Port %4X",(int)port);
02942         break;
02943     }
02944 }
02945 
02946 static void adlib_gusforward(Bitu /*port*/,Bitu val,Bitu /*iolen*/) {
02947     adlib_commandreg=(Bit8u)(val&0xff);
02948 }
02949 
02950 bool SB_Get_Address(Bitu& sbaddr, Bitu& sbirq, Bitu& sbdma) {
02951     sbaddr=0;
02952     sbirq =0;
02953     sbdma =0;
02954     if (sb.type == SBT_NONE) return false;
02955     else {
02956         sbaddr=sb.hw.base;
02957         sbirq =sb.hw.irq;
02958         sbdma = sb.hw.dma8;
02959         return true;
02960     }
02961 }
02962 
02963 static void SBLASTER_CallBack(Bitu len) {
02964     sb.directdac_warn_speaker_off = true;
02965 
02966     switch (sb.mode) {
02967     case MODE_NONE:
02968     case MODE_DMA_PAUSE:
02969     case MODE_DMA_MASKED:
02970     case MODE_DMA_REQUIRE_IRQ_ACK:
02971         sb.chan->AddSilence();
02972         break;
02973     case MODE_DAC:
02974         sb.mode = MODE_NONE;
02975         break;
02976     case MODE_DMA:
02977         len*=sb.dma.mul;
02978         if (len&SB_SH_MASK) len+=1 << SB_SH;
02979         len>>=SB_SH;
02980         if (len>sb.dma.left) len=sb.dma.left;
02981         GenerateDMASound(len);
02982         break;
02983     }
02984 }
02985 
02986 #define ISAPNP_COMPATIBLE(id) \
02987     ISAPNP_SMALL_TAG(3,4), \
02988     ( (id)        & 0xFF), \
02989     (((id) >>  8) & 0xFF), \
02990     (((id) >> 16) & 0xFF), \
02991     (((id) >> 24) & 0xFF)
02992 
02993 #if 0
02994 static const unsigned char ViBRA_sysdev[] = {
02995     ISAPNP_IO_RANGE(
02996             0x01,                   /* decodes 16-bit ISA addr */
02997             0x220,0x280,                /* min-max range I/O port */
02998             0x20,0x10),             /* align=0x20 length=0x10 */
02999     ISAPNP_IO_RANGE(
03000             0x01,                   /* decodes 16-bit ISA addr */
03001             0x300,0x330,                /* min-max range I/O port */
03002             0x10,0x4),              /* align=0x10 length=0x4 */
03003     ISAPNP_IO_RANGE(
03004             0x01,                   /* decodes 16-bit ISA addr */
03005             0x388,0x38C,                /* min-max range I/O port */
03006             0x4,0x4),               /* align=0x4 length=0x4 */
03007     ISAPNP_IRQ(
03008             (1 << 5) |
03009             (1 << 7) |
03010             (1 << 9) |
03011             (1 << 10) |
03012             (1 << 11),              /* IRQ 5,7,9,10,11 */
03013             0x09),                  /* HTE=1 LTL=1 */
03014     ISAPNP_DMA(
03015             (1 << 0) |
03016             (1 << 1) |
03017             (1 << 3),               /* DMA 0,1,3 */
03018             0x01),                  /* 8/16-bit */
03019     ISAPNP_DMA(
03020             (1 << 0) |
03021             (1 << 1) |
03022             (1 << 3) |
03023             (1 << 5) |
03024             (1 << 6) |
03025             (1 << 7),               /* DMA 0,1,3,5,6,7 */
03026             0x01),                  /* 8/16-bit */
03027     ISAPNP_COMPATIBLE(ISAPNP_ID('C','T','L',0x0,0x0,0x0,0x1)),  /* <- Windows 95 doesn't know CTL0070 but does know CTL0001, this hack causes Win95 to offer it's internal driver as an option */
03028     ISAPNP_END
03029 };
03030 #endif
03031 
03032 class ViBRA_PnP : public ISAPnPDevice {
03033     public:
03034         ViBRA_PnP() : ISAPnPDevice() {
03035             resource_ident = 0;
03036             host_writed(ident+0,ISAPNP_ID('C','T','L',0x0,0x0,0x7,0x0)); /* CTL0070: ViBRA C */
03037             host_writed(ident+4,0xFFFFFFFFUL);
03038             checksum_ident();
03039 
03040             alloc(256 - 9/*ident*/); // Real ViBRA hardware acts as if PNP data is read from a 256-byte ROM
03041 
03042             // this template taken from a real Creative ViBRA16C card
03043             begin_write_res();
03044             write_ISAPnP_version(/*version*/1,0,/*vendor*/0x10);
03045             write_Identifier_String("Creative ViBRA16C PnP");
03046 
03047             write_Logical_Device_ID('C','T','L',0x0,0x0,0x0,0x1); // CTL0001
03048             write_Identifier_String("Audio");
03049 
03050             write_Dependent_Function_Start(ISAPnPDevice::DependentFunctionConfig::PreferredDependentConfiguration);
03051             write_IRQ_Format(
03052                 ISAPnPDevice::irq2mask(5));
03053             write_DMA_Format(
03054                 ISAPnPDevice::dma2mask(1),
03055                 DMATransferType_8bitOnly,
03056                 false,/*not a bus master*/
03057                 true,/*byte mode */
03058                 false,/*word mode*/
03059                 DMASpeedSupported_Compat);
03060             write_DMA_Format(
03061                 ISAPnPDevice::dma2mask(5),
03062                 DMATransferType_16bitOnly,
03063                 false,/*not a bus master*/
03064                 false,/*byte mode */
03065                 true,/*word mode*/
03066                 DMASpeedSupported_Compat);
03067             write_IO_Port(/*min*/0x220,/*max*/0x220,/*count*/0x10,/*align*/0x01);
03068             write_IO_Port(/*min*/0x330,/*max*/0x330,/*count*/0x02,/*align*/0x01);
03069             write_IO_Port(/*min*/0x388,/*max*/0x388,/*count*/0x04,/*align*/0x01);
03070 
03071             write_Dependent_Function_Start(ISAPnPDevice::DependentFunctionConfig::AcceptableDependentConfiguration,true);
03072             write_IRQ_Format(
03073                 ISAPnPDevice::irq2mask(5,7,9,10));
03074             write_DMA_Format(
03075                 ISAPnPDevice::dma2mask(1,3),
03076                 DMATransferType_8bitOnly,
03077                 false,/*not a bus master*/
03078                 true,/*byte mode */
03079                 false,/*word mode*/
03080                 DMASpeedSupported_Compat);
03081             write_DMA_Format(
03082                 ISAPnPDevice::dma2mask(5,7),
03083                 DMATransferType_16bitOnly,
03084                 false,/*not a bus master*/
03085                 false,/*byte mode */
03086                 true,/*word mode*/
03087                 DMASpeedSupported_Compat);
03088             write_IO_Port(/*min*/0x220,/*max*/0x280,/*count*/0x10,/*align*/0x20);
03089             write_IO_Port(/*min*/0x300,/*max*/0x330,/*count*/0x02,/*align*/0x30);
03090             write_IO_Port(/*min*/0x388,/*max*/0x388,/*count*/0x04,/*align*/0x01);
03091 
03092             write_Dependent_Function_Start(ISAPnPDevice::DependentFunctionConfig::AcceptableDependentConfiguration,true);
03093             write_IRQ_Format(
03094                 ISAPnPDevice::irq2mask(5,7,9,10));
03095             write_DMA_Format(
03096                 ISAPnPDevice::dma2mask(1,3),
03097                 DMATransferType_8bitOnly,
03098                 false,/*not a bus master*/
03099                 true,/*byte mode */
03100                 false,/*word mode*/
03101                 DMASpeedSupported_Compat);
03102             write_DMA_Format(
03103                 ISAPnPDevice::dma2mask(5,7),
03104                 DMATransferType_16bitOnly,
03105                 false,/*not a bus master*/
03106                 false,/*byte mode */
03107                 true,/*word mode*/
03108                 DMASpeedSupported_Compat);
03109             write_IO_Port(/*min*/0x220,/*max*/0x280,/*count*/0x10,/*align*/0x20);
03110             write_IO_Port(/*min*/0x300,/*max*/0x330,/*count*/0x02,/*align*/0x30);
03111 
03112             write_Dependent_Function_Start(ISAPnPDevice::DependentFunctionConfig::SubOptimalDependentConfiguration);
03113             write_IRQ_Format(
03114                 ISAPnPDevice::irq2mask(5,7,9,10));
03115             write_DMA_Format(
03116                 ISAPnPDevice::dma2mask(1,3),
03117                 DMATransferType_8bitOnly,
03118                 false,/*not a bus master*/
03119                 true,/*byte mode */
03120                 false,/*word mode*/
03121                 DMASpeedSupported_Compat);
03122             write_DMA_Format(
03123                 ISAPnPDevice::dma2mask(5,7),
03124                 DMATransferType_16bitOnly,
03125                 false,/*not a bus master*/
03126                 false,/*byte mode */
03127                 true,/*word mode*/
03128                 DMASpeedSupported_Compat);
03129             write_IO_Port(/*min*/0x220,/*max*/0x280,/*count*/0x10,/*align*/0x20);
03130 
03131             write_Dependent_Function_Start(ISAPnPDevice::DependentFunctionConfig::SubOptimalDependentConfiguration);
03132             write_IRQ_Format(
03133                 ISAPnPDevice::irq2mask(5,7,9,10));
03134             write_DMA_Format(
03135                 ISAPnPDevice::dma2mask(1,3),
03136                 DMATransferType_8bitOnly,
03137                 false,/*not a bus master*/
03138                 true,/*byte mode */
03139                 false,/*word mode*/
03140                 DMASpeedSupported_Compat);
03141             write_IO_Port(/*min*/0x220,/*max*/0x280,/*count*/0x10,/*align*/0x20);
03142             write_IO_Port(/*min*/0x300,/*max*/0x330,/*count*/0x02,/*align*/0x30);
03143             write_IO_Port(/*min*/0x388,/*max*/0x388,/*count*/0x04,/*align*/0x01);
03144 
03145             write_Dependent_Function_Start(ISAPnPDevice::DependentFunctionConfig::SubOptimalDependentConfiguration);
03146             write_IRQ_Format(
03147                 ISAPnPDevice::irq2mask(5,7,9,10));
03148             write_DMA_Format(
03149                 ISAPnPDevice::dma2mask(1,3),
03150                 DMATransferType_8bitOnly,
03151                 false,/*not a bus master*/
03152                 true,/*byte mode */
03153                 false,/*word mode*/
03154                 DMASpeedSupported_Compat);
03155             write_IO_Port(/*min*/0x220,/*max*/0x280,/*count*/0x10,/*align*/0x20);
03156 
03157             write_End_Dependent_Functions();
03158 
03159             // NTS: DOSBox-X as coded now always has a joystick port at 0x201 even if no joystick
03160             write_Logical_Device_ID('C','T','L',0x7,0x0,0x0,0x1); // CTL7001
03161             write_Compatible_Device_ID('P','N','P',0xB,0x0,0x2,0xF); // PNPB02F
03162             write_Identifier_String("Game");
03163             write_IO_Port(/*min*/0x200,/*max*/0x200,/*count*/0x08);
03164 
03165             end_write_res();        // END
03166         }
03167         void select_logical_device(Bitu val) {
03168             logical_device = val;
03169         }
03170         uint8_t read(Bitu addr) {
03171             uint8_t ret = 0xFF;
03172             if (logical_device == 0) {
03173                 switch (addr) {
03174                     case 0x60: case 0x61:   /* I/O [0] sound blaster */
03175                         ret = sb.hw.base >> ((addr & 1) ? 0 : 8);
03176                         break;
03177                     case 0x62: case 0x63:   /* I/O [1] MPU */
03178                         ret = 0x330 >> ((addr & 1) ? 0 : 8); /* FIXME: What I/O port really IS the MPU on? */
03179                         break;
03180                     case 0x64: case 0x65:   /* I/O [1] OPL-3 */
03181                         ret = 0x388 >> ((addr & 1) ? 0 : 8); /* FIXME */
03182                         break;
03183                     case 0x70: /* IRQ[0] */
03184                         ret = sb.hw.irq;
03185                         break;
03186                         /* TODO: 0x71 IRQ mode */
03187                     case 0x74: /* DMA[0] */
03188                         ret = sb.hw.dma8;
03189                         break;
03190                     case 0x75: /* DMA[1] */
03191                         ret = sb.hw.dma16 == 0xFF ? sb.hw.dma8 : sb.hw.dma16;
03192                         break;
03193 
03194                 }
03195             }
03196             else if (logical_device == 1) {
03197                 switch (addr) {
03198                     case 0x60: case 0x61:   /* I/O [0] gameport */
03199                         ret = 0x200 >> ((addr & 1) ? 0 : 8);
03200                         break;
03201                 }
03202             }
03203 
03204             return ret;
03205         }
03206         void write(Bitu addr,Bitu val) {
03207             if (logical_device == 0) {
03208                 switch (addr) {
03209                     case 0x30:  /* activate range */
03210                         /* TODO: set flag to ignore writes/return 0xFF when "deactivated". setting bit 0 activates, clearing deactivates */
03211                         break;
03212                     case 0x60: case 0x61:   /* I/O [0] sound blaster */
03213                         /* TODO: on-the-fly changing */
03214                         //LOG_MSG("ISA PnP Warning: Sound Blaster I/O port changing not implemented yet\n");
03215                         break;
03216                     case 0x62: case 0x63:   /* I/O [1] MPU */
03217                         /* TODO: on-the-fly changing */
03218                         //LOG_MSG("ISA PnP Warning: MPU I/O port changing not implemented yet\n");
03219                         break;
03220                     case 0x64: case 0x65:   /* I/O [1] OPL-3 */
03221                         /* TODO: on-the-fly changing */
03222                         //LOG_MSG("ISA PnP Warning: OPL-3 I/O port changing not implemented yet\n");
03223                         break;
03224                     case 0x70: /* IRQ[0] */
03225                         if (val & 0xF)
03226                             sb.hw.irq = val;
03227                         else
03228                             sb.hw.irq = 0xFF;
03229                         break;
03230                     case 0x74: /* DMA[0] */
03231                         if ((val & 7) == 4)
03232                             sb.hw.dma8 = 0xFF;
03233                         else
03234                             sb.hw.dma8 = val & 7;
03235                         break;
03236                     case 0x75: /* DMA[1] */
03237                         if ((val & 7) == 4)
03238                             sb.hw.dma16 = 0xFF;
03239                         else
03240                             sb.hw.dma16 = val & 7;
03241                         break;
03242 
03243                 }
03244             }
03245             else if (logical_device == 1) {
03246                 switch (addr) {
03247                     case 0x60: case 0x61:   /* I/O [0] gameport */
03248                         /* TODO: on-the-fly changing */
03249                         //LOG_MSG("ISA PnP Warning: Gameport I/O port changing not implemented yet\n");
03250                         break;
03251                 }
03252             }
03253         }
03254 };
03255 
03256 bool JOYSTICK_IsEnabled(Bitu which);
03257 extern void HARDOPL_Init(Bitu hardwareaddr, Bitu sbbase, bool isCMS);
03258 
03259 class SBLASTER: public Module_base {
03260 private:
03261     /* Data */
03262     IO_ReadHandleObject ReadHandler[0x10];
03263     IO_WriteHandleObject WriteHandler[0x10];
03264     AutoexecObject autoexecline;
03265     MixerObject MixerChan;
03266     OPL_Mode oplmode;
03267 
03268     /* Support Functions */
03269     void Find_Type_And_Opl(Section_prop* config,SB_TYPES& type, OPL_Mode& opl_mode){
03270         sb.vibra = false;
03271         sb.ess_type = ESS_NONE;
03272         sb.reveal_sc_type = RSC_NONE;
03273         sb.ess_extended_mode = false;
03274         const char * sbtype=config->Get_string("sbtype");
03275         if (!strcasecmp(sbtype,"sb1")) type=SBT_1;
03276         else if (!strcasecmp(sbtype,"sb2")) type=SBT_2;
03277         else if (!strcasecmp(sbtype,"sbpro1")) type=SBT_PRO1;
03278         else if (!strcasecmp(sbtype,"sbpro2")) type=SBT_PRO2;
03279         else if (!strcasecmp(sbtype,"sb16vibra")) type=SBT_16;
03280         else if (!strcasecmp(sbtype,"sb16")) type=SBT_16;
03281         else if (!strcasecmp(sbtype,"gb")) type=SBT_GB;
03282         else if (!strcasecmp(sbtype,"none")) type=SBT_NONE;
03283         else if (!strcasecmp(sbtype,"ess688")) {
03284             type=SBT_PRO2;
03285             sb.ess_type=ESS_688;
03286             LOG(LOG_SB,LOG_DEBUG)("ESS 688 emulation enabled.");
03287             LOG(LOG_SB,LOG_WARN)("ESS 688 emulation is EXPERIMENTAL at this time and should not yet be used for normal gaming");
03288         }
03289         else if (!strcasecmp(sbtype,"reveal_sc400")) {
03290             type=SBT_PRO2;
03291             sb.reveal_sc_type=RSC_SC400;
03292             LOG(LOG_SB,LOG_DEBUG)("Reveal SC400 emulation enabled.");
03293             LOG(LOG_SB,LOG_WARN)("Reveal SC400 emulation is EXPERIMENTAL at this time and should not yet be used for normal gaming.");
03294             LOG(LOG_SB,LOG_WARN)("Additional WARNING: This code only emulates the Sound Blaster portion of the card. Attempting to use the Windows Sound System part of the card (i.e. the Voyetra/SC400 Windows drivers) will not work!");
03295         }
03296         else type=SBT_16;
03297 
03298         if (type == SBT_16) {
03299             /* NTS: mainline DOSBox forces the type to SBT_PRO2 if !IS_EGAVGA_ARCH or no secondary DMA controller.
03300              *      I'd rather take the approach that, if the user wants to emulate a bizarre unusual setup like
03301              *      sticking a Sound Blaster 16 in an 8-bit machine, they are free to do so on the understanding
03302              *      it won't work properly (and emulation will show what happens). I also believe that tying
03303              *      8-bit vs 16-bit system type to the *video card* was a really dumb move. */
03304             if (!SecondDMAControllerAvailable()) {
03305                 LOG(LOG_SB,LOG_WARN)("Sound Blaster 16 enabled on a system without 16-bit DMA. Don't expect this setup to work properly! To improve compatability please edit your dosbox.conf and change sbtype to sbpro2 instead, or else enable the secondary DMA controller.");
03306             }
03307         }
03308 
03309         /* SB16 Vibra cards are Plug & Play */
03310         if (!IS_PC98_ARCH) {
03311             if (!strcasecmp(sbtype,"sb16vibra")) {
03312                 ISA_PNP_devreg(new ViBRA_PnP());
03313                 sb.vibra = true;
03314             }
03315         }
03316 
03317         /* OPL/CMS Init */
03318         const char * omode=config->Get_string("oplmode");
03319         if (!strcasecmp(omode,"none")) opl_mode=OPL_none;   
03320         else if (!strcasecmp(omode,"cms")) opl_mode=OPL_cms;
03321         else if (!strcasecmp(omode,"opl2")) opl_mode=OPL_opl2;
03322         else if (!strcasecmp(omode,"dualopl2")) opl_mode=OPL_dualopl2;
03323         else if (!strcasecmp(omode,"opl3")) opl_mode=OPL_opl3;
03324         else if (!strcasecmp(omode,"opl3gold")) opl_mode=OPL_opl3gold;
03325         else if (!strcasecmp(omode,"hardware")) opl_mode=OPL_hardware;
03326         else if (!strcasecmp(omode,"hardwaregb")) opl_mode=OPL_hardwareCMS;
03327         /* Else assume auto */
03328         else {
03329             switch (type) {
03330             case SBT_NONE:
03331                 opl_mode=OPL_none;
03332                 break;
03333             case SBT_GB:
03334                 opl_mode=OPL_cms;
03335                 break;
03336             case SBT_1:
03337             case SBT_2:
03338                 opl_mode=OPL_opl2;
03339                 break;
03340             case SBT_PRO1:
03341                 opl_mode=OPL_dualopl2;
03342                 break;
03343             case SBT_PRO2:
03344             case SBT_16:
03345                 opl_mode=OPL_opl3;
03346                 break;
03347             }
03348         }
03349 
03350         if (IS_PC98_ARCH) {
03351             if (opl_mode != OPL_none) {
03352                 if (opl_mode != OPL_opl3) {
03353                     LOG(LOG_SB,LOG_WARN)("Only OPL3 is allowed in PC-98 mode");
03354                     opl_mode = OPL_opl3;
03355                 }
03356             }
03357 
03358             /* card type MUST be SB16.
03359              * Creative did not release any other Sound Blaster for PC-98 as far as I know. */
03360             if (sb.type != SBT_16) {
03361                 LOG(LOG_SB,LOG_ERROR)("Only Sound Blaster 16 is allowed in PC-98 mode");
03362                 sb.type = SBT_NONE;
03363             }
03364         }
03365     }
03366 public:
03367     SBLASTER(Section* configuration):Module_base(configuration) {
03368         bool bv;
03369         string s;
03370         Bitu i;
03371         int si;
03372 
03373         Section_prop * section=static_cast<Section_prop *>(configuration);
03374 
03375         sb.hw.base=(unsigned int)section->Get_hex("sbbase");
03376 
03377         if (IS_PC98_ARCH) {
03378             if (sb.hw.base >= 0x220 && sb.hw.base <= 0x2E0) /* translate IBM PC to PC-98 (220h -> D2h) */
03379                 sb.hw.base = 0xD0 + ((sb.hw.base >> 4u) & 0xFu);
03380         }
03381         else {
03382             if (sb.hw.base >= 0xD2 && sb.hw.base <= 0xDE) /* translate PC-98 to IBM PC (D2h -> 220h) */
03383                 sb.hw.base = 0x200 + ((sb.hw.base & 0xFu) << 4u);
03384         }
03385 
03386         sb.goldplay=section->Get_bool("goldplay");
03387         sb.min_dma_user=section->Get_int("mindma");
03388         sb.goldplay_stereo=section->Get_bool("goldplay stereo");
03389         sb.emit_blaster_var=section->Get_bool("blaster environment variable");
03390         sb.sample_rate_limits=section->Get_bool("sample rate limits");
03391         sb.sbpro_stereo_bit_strict_mode=section->Get_bool("stereo control with sbpro only");
03392         sb.hw.sb_io_alias=section->Get_bool("io port aliasing");
03393         sb.busy_cycle_hz=section->Get_int("dsp busy cycle rate");
03394         sb.busy_cycle_duty_percent=section->Get_int("dsp busy cycle duty");
03395         sb.dsp.instant_direct_dac=section->Get_bool("instant direct dac");
03396         sb.dsp.force_goldplay=section->Get_bool("force goldplay");
03397         sb.dma.force_autoinit=section->Get_bool("force dsp auto-init");
03398         sb.no_filtering=section->Get_bool("disable filtering");
03399         sb.def_enable_speaker=section->Get_bool("enable speaker");
03400         sb.enable_asp=section->Get_bool("enable asp");
03401 
03402         if (!sb.goldplay && sb.dsp.force_goldplay) {
03403             sb.goldplay = true;
03404             LOG_MSG("force goldplay = true but goldplay = false, enabling Goldplay mode anyway");
03405         }
03406 
03407         /* Explanation: If the user set this option, the write status port must return 0x7F or 0xFF.
03408          *              Else, we're free to return whatever with bit 7 to indicate busy.
03409          *              The reason for this setting is that there exist some very early DOS demoscene productions
03410          *              that assume the I/O port returns 0x7F or 0xFF, and will have various problems if that
03411          *              is not the case.
03412          *
03413          *              Overload by Hysteria (1992):
03414          *                 - This demo's Sound Blaster routines use the unusual space-saving assembly language
03415          *                   trick of reading port 22Ch to wait for bit 7 to clear (which is normal), then
03416          *                   using the value it read (left over from AL) as the byte to sum it's audio output
03417          *                   to before sending out to the DAC. This is why, if the write status port returns
03418          *                   a different value like 0x2A, the audio crackes with saturation errors.
03419          *
03420          *                   Overload's Sound Blaster output code:
03421          *
03422          *                   090D:5F50  EC                  in   al,dx
03423          *                   090D:5F51  A880                test al,80
03424          *                   090D:5F53  75FB                jne  00005F50 ($-5)         (no jmp)
03425          *                   090D:5F55  FEC0                inc  al
03426          *                   ; various code to render and sum audio samples to AL
03427          *                   090D:5FC7  EE                  out  dx,al
03428          *
03429          *                   Notice it assumes AL is 0x7F and it assumes (++AL) == 0x80.
03430          *
03431          *                   It's also funny to note the demo's readme file mentions this problem with Sound
03432          *                   Blaster Pro:
03433          *
03434          *                   "I have been told this works with the soundblaster however, this demo does
03435          *                   not seem to work the soundblaster pro.
03436          *
03437          *                   If the music sounds bad and you want to know what it really sounds like
03438          *                   let me know and I can send you the MOD format of the music.
03439          *
03440          *                   dmw@sioux.ee.ufl.edu"
03441          *
03442          */
03443         sb.write_status_must_return_7f=section->Get_bool("dsp write buffer status must return 0x7f or 0xff");
03444 
03445         sb.dsp.midi_rwpoll_mode = false;
03446         sb.dsp.midi_read_interrupt = false;
03447         sb.dsp.midi_read_with_timestamps = false;
03448 
03449         sb.busy_cycle_last_check=0;
03450         sb.busy_cycle_io_hack=0;
03451 
03452         si=section->Get_int("irq");
03453         sb.hw.irq=(si >= 0) ? (unsigned int)si : 0xFF;
03454 
03455         if (IS_PC98_ARCH) {
03456             if (sb.hw.irq == 7) /* IRQ 7 is not valid on PC-98 (that's cascade interrupt) */
03457                 sb.hw.irq = 5;
03458         }
03459 
03460         si=section->Get_int("dma");
03461         sb.hw.dma8=(si >= 0) ? (unsigned int)si : 0xFF;
03462 
03463         si=section->Get_int("hdma");
03464         sb.hw.dma16=(si >= 0) ? (unsigned int)si : 0xFF;
03465 
03466         if (IS_PC98_ARCH) {
03467             if (sb.hw.dma8 > 3)
03468                 sb.hw.dma8 = 3;
03469             if (sb.hw.dma8 == 1) /* DMA 1 is not usable for SB on PC-98? */
03470                 sb.hw.dma8 = 3;
03471             if (sb.hw.dma16 > 3)
03472                 sb.hw.dma16 = sb.hw.dma8;
03473 
03474             LOG_MSG("PC-98: Final SB16 resources are DMA8=%u DMA16=%u\n",sb.hw.dma8,sb.hw.dma16);
03475 
03476             sb.dma.chan=GetDMAChannel(sb.hw.dma8);
03477             if (sb.dma.chan == NULL) LOG_MSG("PC-98: SB16 is unable to obtain DMA channel");
03478         }
03479 
03480         /* some DOS games/demos support Sound Blaster, and expect the IRQ to fire, but
03481          * make no attempt to unmask the IRQ (perhaps the programmer forgot). This option
03482          * is needed for Public NMI "jump" demo in order for music to continue playing. */
03483         bv=section->Get_bool("pic unmask irq");
03484         if (bv && sb.hw.irq != 0xFF) {
03485             LOG_MSG("Sound blaster: unmasking IRQ at startup as requested.");
03486             PIC_SetIRQMask(sb.hw.irq,false);
03487         }
03488 
03489         if (sb.hw.irq == 0xFF || sb.hw.dma8 == 0xFF) {
03490             LOG(LOG_SB,LOG_WARN)("IRQ and 8-bit DMA not assigned, disabling BLASTER variable");
03491             sb.emit_blaster_var = false;
03492         }
03493 
03494         sb.mixer.enabled=section->Get_bool("sbmixer");
03495         sb.mixer.stereo=false;
03496 
03497         bv=section->Get_bool("pre-set sbpro stereo");
03498         if (bv) {
03499             LOG_MSG("Sound blaster: setting SB Pro mixer 'stereo' bit as instructed.");
03500             sb.mixer.stereo=true;
03501         }
03502 
03503         Find_Type_And_Opl(section,sb.type,oplmode);
03504         bool isCMSpassthrough = false;
03505     
03506         switch (oplmode) {
03507         case OPL_none:
03508             if (!IS_PC98_ARCH)
03509                 WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
03510             break;
03511         case OPL_cms:
03512             assert(!IS_PC98_ARCH);
03513             WriteHandler[0].Install(0x388,adlib_gusforward,IO_MB);
03514             CMS_Init(section);
03515             break;
03516         case OPL_opl2:
03517             assert(!IS_PC98_ARCH);
03518             CMS_Init(section);
03519             // fall-through
03520         case OPL_dualopl2:
03521             assert(!IS_PC98_ARCH);
03522         case OPL_opl3:
03523         case OPL_opl3gold:
03524             OPL_Init(section,oplmode);
03525             break;
03526         case OPL_hardwareCMS:
03527             assert(!IS_PC98_ARCH);
03528             isCMSpassthrough = true;
03529         case OPL_hardware:
03530             assert(!IS_PC98_ARCH);
03531             Bitu base = (unsigned int)section->Get_hex("hardwarebase");
03532             HARDOPL_Init(base, sb.hw.base, isCMSpassthrough);
03533             break;
03534         }
03535         if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
03536 
03537         sb.chan=MixerChan.Install(&SBLASTER_CallBack,22050,"SB");
03538         sb.dac.dac_pt = sb.dac.dac_t = 0;
03539         sb.dsp.state=DSP_S_NORMAL;
03540         sb.dsp.out.lastval=0xaa;
03541         sb.dma.chan=NULL;
03542 
03543         for (i=4;i<=0xf;i++) {
03544             if (i==8 || i==9) continue;
03545             //Disable mixer ports for lower soundblaster
03546             if ((sb.type==SBT_1 || sb.type==SBT_2) && (i==4 || i==5)) continue; 
03547             ReadHandler[i].Install(sb.hw.base+(IS_PC98_ARCH ? ((i+0x20u) << 8u) : i),read_sb,IO_MB);
03548             WriteHandler[i].Install(sb.hw.base+(IS_PC98_ARCH ? ((i+0x20u) << 8u) : i),write_sb,IO_MB);
03549         }
03550 
03551         // NTS: Unknown/undefined registers appear to return the register index you requested rather than the actual contents,
03552         //      according to real SB16 CSP/ASP hardware (chip version id 0x10).
03553         //
03554         //      Registers 0x00-0x1F are defined. Registers 0x80-0x83 are defined.
03555         for (i=0;i<256;i++) ASP_regs[i] = i;
03556         for (i=0x00;i < 0x20;i++) ASP_regs[i] = 0;
03557         for (i=0x80;i < 0x84;i++) ASP_regs[i] = 0;
03558         ASP_regs[5] = 0x01;
03559         ASP_regs[9] = 0xf8;
03560 
03561         DSP_Reset();
03562         CTMIXER_Reset();
03563 
03564         // The documentation does not specify if SB gets initialized with the speaker enabled
03565         // or disabled. Real SBPro2 has it disabled. 
03566         sb.speaker=false;
03567         // On SB16 the speaker flag does not affect actual speaker state.
03568         if (sb.type == SBT_16 || sb.ess_type != ESS_NONE || sb.reveal_sc_type != RSC_NONE) sb.chan->Enable(true);
03569         else sb.chan->Enable(false);
03570 
03571         if (sb.def_enable_speaker)
03572             DSP_SetSpeaker(true);
03573 
03574         s=section->Get_string("dsp require interrupt acknowledge");
03575         if (s == "true" || s == "1" || s == "on")
03576             sb.dsp.require_irq_ack = 1;
03577         else if (s == "false" || s == "0" || s == "off")
03578             sb.dsp.require_irq_ack = 0;
03579         else /* auto */
03580             sb.dsp.require_irq_ack = (sb.type == SBT_16) ? 1 : 0; /* Yes if SB16, No otherwise */
03581 
03582         si=section->Get_int("dsp write busy delay"); /* in nanoseconds */
03583         if (si >= 0) sb.dsp.dsp_write_busy_time = (unsigned int)si;
03584         else sb.dsp.dsp_write_busy_time = 1000; /* FIXME: How long is the DSP busy on real hardware? */
03585 
03586         /* Sound Blaster (1.x and 2x) and Sound Blaster Pro (3.1) have the I/O port aliasing.
03587          * The aliasing is also faithfully emulated by the ESS AudioDrive. */
03588         switch (sb.type) {
03589             case SBT_1: /* guess */
03590             case SBT_2: /* verified on real hardware */
03591             case SBT_GB: /* FIXME: Right?? */
03592             case SBT_PRO1: /* verified on real hardware */
03593             case SBT_PRO2: /* guess */
03594                 break;
03595             default:
03596                 sb.hw.sb_io_alias=false;
03597                 break;
03598         }
03599 
03600         /* auto-pick busy cycle */
03601         /* NOTE: SB16 cards appear to run a DSP busy cycle at all times.
03602          *       SB2 cards (and Pro?) appear to run a DSP busy cycle only when playing audio through DMA. */
03603         if (sb.busy_cycle_hz < 0) {
03604             if (sb.type == SBT_16) /* Guess: Pentium PCI-ISA SYSCLK=8.333MHz  /  (6 cycles per 8-bit I/O read  x  16 reads from DSP status) = about 86.805KHz? */
03605                 sb.busy_cycle_hz = 8333333 / 6 / 16;
03606             else /* Guess ???*/
03607                 sb.busy_cycle_hz = 8333333 / 6 / 16;
03608         }
03609 
03610         if (sb.ess_type != ESS_NONE) {
03611             uint8_t t;
03612 
03613             /* legacy audio interrupt control */
03614             t = 0x80;/*game compatible IRQ*/
03615             switch (sb.hw.irq) {
03616                 case 5:     t |= 0x5; break;
03617                 case 7:     t |= 0xA; break;
03618                 case 10:    t |= 0xF; break;
03619             }
03620             ESSreg(0xB1) = t;
03621 
03622             /* DRQ control */
03623             t = 0x80;/*game compatible DRQ */
03624             switch (sb.hw.dma8) {
03625                 case 0:     t |= 0x5; break;
03626                 case 1:     t |= 0xA; break;
03627                 case 3:     t |= 0xF; break;
03628             }
03629             ESSreg(0xB2) = t;
03630         }
03631 
03632         /* first configuration byte returned by 0x58.
03633          *
03634          * bits 7-5: ???
03635          * bit    4: Windows Sound System (Crystal Semiconductor CS4231A) I/O base port (1=0xE80  0=0x530)
03636          * bits 3-2: ???
03637          * bit    1: gameport disable (1=disabled 0=enabled)
03638          * bit    0: jumper assigns Sound Blaster base port 240h (right??) */
03639         sb.sc400_jumper_status_1 = 0x2C + ((sb.hw.base == 0x240) ? 0x1 : 0x0);
03640         if (!JOYSTICK_IsEnabled(0) && !JOYSTICK_IsEnabled(1)) sb.sc400_jumper_status_1 += 0x02; // set bit 1
03641         /* second configuration byte returned by 0x58.
03642          *
03643          * bits 7-5: 110b ???
03644          * bits 4-0: bits 8-4 of the CD-ROM I/O port base. For example, to put the CD-ROM controller at 0x230 you would set this to 0x3.
03645          *           TESTSC.EXE ignores the value unless it represents one of the supported base I/O ports for the CD-ROM, which are:
03646          *
03647          *           0x03 -> 0x230
03648          *           0x05 -> 0x250
03649          *           0x11 -> 0x310
03650          *           0x12 -> 0x320
03651          *           0x13 -> 0x330
03652          *           0x14 -> 0x340
03653          *           0x15 -> 0x350
03654          *           0x16 -> 0x360
03655          *
03656          *           TODO: The CD-ROM interface is said to be designed for Panasonic or Goldstar CD-ROM drives. Can we emulate that someday,
03657          *                 and allow the user to configure the base I/O port? */
03658         sb.sc400_jumper_status_2 = 0xC0 | (((sb.hw.base + 0x10) >> 4) & 0xF);
03659 
03660         sb.sc400_dsp_major = 3;
03661         sb.sc400_dsp_minor = 5;
03662         sb.sc400_cfg = 0;
03663         /* bit 7:    MPU IRQ select  (1=IRQ 9  0=IRQ 5)
03664          * bit 6:    ???
03665          * bit 5-3:  IRQ select
03666          * bit 2:    MPU IRQ enable
03667          * bit 1-0:  DMA select */
03668         switch (sb.hw.dma8) {
03669             case 0: sb.sc400_cfg |= (1 << 0); break;
03670             case 1: sb.sc400_cfg |= (2 << 0); break;
03671             case 3: sb.sc400_cfg |= (3 << 0); break;
03672         }
03673         switch (sb.hw.irq) {
03674             case 5: sb.sc400_cfg |= (5 << 3); break;
03675             case 7: sb.sc400_cfg |= (1 << 3); break;
03676             case 9: sb.sc400_cfg |= (2 << 3); break;
03677             case 10:sb.sc400_cfg |= (3 << 3); break;
03678             case 11:sb.sc400_cfg |= (4 << 3); break;
03679         }
03680         switch (MPU401_GetIRQ()) { // SC400: bit 7 and bit 2 control MPU IRQ
03681             case 5: sb.sc400_cfg |= (0 << 7) + (1 << 2); break; // bit 7=0 bit 2=1   MPU IRQ 5
03682             case 9: sb.sc400_cfg |= (1 << 7) + (1 << 2); break; // bit 7=1 bit 2=1   MPU IRQ 9
03683             default: break;                     // bit 7=0 bit 2=0   MPU IRQ disabled
03684         }
03685 
03686         if (sb.reveal_sc_type != RSC_NONE) {
03687             // SC400 cards always use 8-bit DMA even for 16-bit PCM
03688             if (sb.hw.dma16 != sb.hw.dma8) {
03689                 LOG(LOG_SB,LOG_DEBUG)("SC400: DMA is always 8-bit, setting 16-bit == 8-bit");
03690                 sb.hw.dma16 = sb.hw.dma8;
03691             }
03692         }
03693 
03694         si = section->Get_int("dsp busy cycle always");
03695         if (si >= 0) sb.busy_cycle_always= (si > 0) ? true : false;
03696         else if (sb.type == SBT_16) sb.busy_cycle_always = true;
03697         else sb.busy_cycle_always = false;
03698 
03699         /* auto-pick busy duty cycle */
03700         if (sb.busy_cycle_duty_percent < 0 || sb.busy_cycle_duty_percent > 100)
03701             sb.busy_cycle_duty_percent = 50; /* seems about right */
03702 
03703         if (sb.hw.irq != 0 && sb.hw.irq != 0xFF) {
03704             s = section->Get_string("irq hack");
03705             if (!s.empty() && s != "none") {
03706                 LOG(LOG_SB,LOG_NORMAL)("Sound Blaster emulation: Assigning IRQ hack '%s' as instruced",s.c_str());
03707                 PIC_Set_IRQ_hack((int)sb.hw.irq,PIC_parse_IRQ_hack_string(s.c_str()));
03708             }
03709         }
03710 
03711         // ASP emulation
03712         if (sb.enable_asp && sb.type != SBT_16) {
03713             LOG(LOG_SB,LOG_WARN)("ASP emulation requires you to select SB16 emulation");
03714             sb.enable_asp = false;
03715         }
03716 
03717         // SB16 non-PNP ASP RAM content observation.
03718         // Contrary to my initial impression, it looks like the RAM is mostly 0xFF
03719         // with some random bits flipped because no initialization is done at hardware power-on.
03720         memset(sb16asp_ram_contents,0xFF,2048);
03721         for (i=0;i < (2048 * 8);i++) {
03722             if (((unsigned int)rand() & 31) == 0)
03723                 sb16asp_ram_contents[i>>3] ^= 1 << (i & 7);
03724         }
03725 
03726 /* Reference: Command 0xF9 result map taken from Sound Blaster 16 with DSP 4.4 and ASP chip version ID 0x10:
03727  *
03728  * ASP> F9 result map:
03729 00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff 07 
03730 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03731 20: f9 00 00 00 00 aa 96 00 00 00 00 00 00 00 00 00 
03732 30: f9 00 00 00 00 00 00 38 00 00 00 00 00 00 00 00 
03733 40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03734 50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03735 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03736 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03737 80: 00 19 0a 00 00 00 00 00 00 00 00 00 00 00 00 00 
03738 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03739 a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03740 b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03741 c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03742 d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03743 e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03744 f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
03745 ASP> 
03746  * End reference */
03747         memset(sb16_8051_mem,0x00,256);
03748         sb16_8051_mem[0x0E] = 0xFF;
03749         sb16_8051_mem[0x0F] = 0x07;
03750         sb16_8051_mem[0x37] = 0x38;
03751 
03752         if (sb.enable_asp)
03753             LOG(LOG_SB,LOG_WARN)("ASP emulation at this stage is extremely limited and only covers DSP command responses.");
03754 
03755         /* Soundblaster midi interface */
03756         if (!MIDI_Available()) sb.midi = false;
03757         else sb.midi = true;
03758     }   
03759 
03760     void DOS_Shutdown() { /* very likely, we're booting into a guest OS where our environment variable has no meaning anymore */
03761         autoexecline.Uninstall();
03762     }
03763 
03764     void DOS_Startup() {
03765         if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
03766 
03767         if (sb.emit_blaster_var) {
03768             // Create set blaster line
03769             ostringstream temp;
03770             if (IS_PC98_ARCH)
03771                 temp << "@SET BLASTER=A" << setw(2) << hex << sb.hw.base;
03772             else
03773                 temp << "@SET BLASTER=A" << setw(3) << hex << sb.hw.base;
03774 
03775             if (sb.hw.irq != 0xFF) temp << " I" << dec << (Bitu)sb.hw.irq;
03776             if (sb.hw.dma8 != 0xFF) temp << " D" << (Bitu)sb.hw.dma8;
03777             if (sb.type==SBT_16 && sb.hw.dma16 != 0xFF) temp << " H" << (Bitu)sb.hw.dma16;
03778             temp << " T" << static_cast<unsigned int>(sb.type) << ends;
03779 
03780             autoexecline.Install(temp.str());
03781         }
03782     }
03783     
03784     ~SBLASTER() {
03785         switch (oplmode) {
03786         case OPL_none:
03787             break;
03788         case OPL_cms:
03789             CMS_ShutDown(m_configuration);
03790             break;
03791         case OPL_opl2:
03792             CMS_ShutDown(m_configuration);
03793             // fall-through
03794         case OPL_dualopl2:
03795         case OPL_opl3:
03796         case OPL_opl3gold:
03797             OPL_ShutDown(m_configuration);
03798             break;
03799         default:
03800             break;
03801         }
03802         if (sb.type==SBT_NONE || sb.type==SBT_GB) return;
03803         DSP_Reset(); // Stop everything 
03804     }   
03805 }; //End of SBLASTER class
03806 
03807 extern void HWOPL_Cleanup();
03808 
03809 static SBLASTER* test = NULL;
03810 
03811 void SBLASTER_DOS_Shutdown() {
03812     if (test != NULL) test->DOS_Shutdown();
03813 }
03814 
03815 void SBLASTER_ShutDown(Section* /*sec*/) {
03816     if (test != NULL) {
03817         delete test;    
03818         test = NULL;
03819     }
03820     HWOPL_Cleanup();
03821 }
03822 
03823 void SBLASTER_OnReset(Section *sec) {
03824     (void)sec;//UNUSED
03825     SBLASTER_DOS_Shutdown();
03826 
03827     if (test != NULL) {
03828         delete test;    
03829         test = NULL;
03830     }
03831     HWOPL_Cleanup();
03832 
03833     if (test == NULL) {
03834         LOG(LOG_MISC,LOG_DEBUG)("Allocating Sound Blaster emulation");
03835         test = new SBLASTER(control->GetSection("sblaster"));
03836     }
03837 }
03838 
03839 void SBLASTER_DOS_Exit(Section *sec) {
03840     (void)sec;//UNUSED
03841     SBLASTER_DOS_Shutdown();
03842 }
03843 
03844 void SBLASTER_DOS_Boot(Section *sec) {
03845     (void)sec;//UNUSED
03846     if (test != NULL) test->DOS_Startup();
03847 }
03848 
03849 void SBLASTER_Init() {
03850     LOG(LOG_MISC,LOG_DEBUG)("Initializing Sound Blaster emulation");
03851 
03852     AddExitFunction(AddExitFunctionFuncPair(SBLASTER_ShutDown),true);
03853     AddVMEventFunction(VM_EVENT_RESET,AddVMEventFunctionFuncPair(SBLASTER_OnReset));
03854     AddVMEventFunction(VM_EVENT_DOS_EXIT_BEGIN,AddVMEventFunctionFuncPair(SBLASTER_DOS_Exit));
03855     AddVMEventFunction(VM_EVENT_DOS_SURPRISE_REBOOT,AddVMEventFunctionFuncPair(SBLASTER_DOS_Exit));
03856     AddVMEventFunction(VM_EVENT_DOS_EXIT_REBOOT_BEGIN,AddVMEventFunctionFuncPair(SBLASTER_DOS_Exit));
03857     AddVMEventFunction(VM_EVENT_DOS_INIT_SHELL_READY,AddVMEventFunctionFuncPair(SBLASTER_DOS_Boot));
03858 }
03859 
03860 // save state support
03861 void *DMA_DAC_Event_PIC_Event = (void*)((uintptr_t)DMA_DAC_Event);
03862 void *DMA_Silent_Event_PIC_Event = (void*)((uintptr_t)DMA_Silent_Event);
03863 void *DSP_FinishReset_PIC_Event = (void*)((uintptr_t)DSP_FinishReset);
03864 void *DSP_RaiseIRQEvent_PIC_Event = (void*)((uintptr_t)DSP_RaiseIRQEvent);
03865 void *END_DMA_Event_PIC_Event = (void*)((uintptr_t)END_DMA_Event);
03866 
03867 void *SB_DSP_DMA_CallBack_Func = (void*)((uintptr_t)DSP_DMA_CallBack);
03868 void *SB_DSP_ADC_CallBack_Func = (void*)((uintptr_t)DSP_ADC_CallBack);
03869 void *SB_DSP_E2_DMA_CallBack_Func = (void*)((uintptr_t)DSP_E2_DMA_CallBack);
03870 
03871 
03872 void POD_Save_Sblaster( std::ostream& stream )
03873 {
03874         const char pod_name[32] = "SBlaster";
03875 
03876         if( stream.fail() ) return;
03877         if( !test ) return;
03878         if( !sb.chan ) return;
03879 
03880 
03881         WRITE_POD( &pod_name, pod_name );
03882         
03883 
03884         //*******************************************
03885         //*******************************************
03886         //*******************************************
03887 
03888         Bit8u dma_idx;
03889 
03890 
03891         dma_idx = 0xff;
03892         for( int lcv=0; lcv<8; lcv++ ) {
03893                 if( sb.dma.chan == GetDMAChannel(lcv) ) { dma_idx = lcv; break; }
03894         }
03895 
03896         // *******************************************
03897         // *******************************************
03898         // *******************************************
03899 
03900         // - near-pure data
03901         WRITE_POD( &sb, sb );
03902 
03903         // - pure data
03904         WRITE_POD( &ASP_regs, ASP_regs );
03905         //WRITE_POD( &ASP_init_in_progress, ASP_init_in_progress );
03906     WRITE_POD( &last_dma_callback, last_dma_callback );
03907 
03908 
03909 
03910         // - reloc ptr
03911         WRITE_POD( &dma_idx, dma_idx );
03912 
03913         // *******************************************
03914         // *******************************************
03915         // *******************************************
03916 
03917         sb.chan->SaveState(stream);
03918 }
03919 
03920 
03921 void POD_Load_Sblaster( std::istream& stream )
03922 {
03923         char pod_name[32] = {0};
03924 
03925         if( stream.fail() ) return;
03926         if( !test ) return;
03927         if( !sb.chan ) return;
03928 
03929 
03930         // error checking
03931         READ_POD( &pod_name, pod_name );
03932         if( strcmp( pod_name, "SBlaster" ) ) {
03933                 stream.clear( std::istream::failbit | std::istream::badbit );
03934                 return;
03935         }
03936 
03937         //************************************************
03938         //************************************************
03939         //************************************************
03940 
03941         Bit8u dma_idx;
03942         MixerChannel *mixer_old;
03943 
03944         
03945         // save static ptr
03946         mixer_old = sb.chan;
03947 
03948         //*******************************************
03949         //*******************************************
03950         //*******************************************
03951 
03952         // - near-pure data
03953         READ_POD( &sb, sb );
03954 
03955         // - pure data
03956         READ_POD( &ASP_regs, ASP_regs );
03957         //READ_POD( &ASP_init_in_progress, ASP_init_in_progress );
03958     READ_POD( &last_dma_callback, last_dma_callback );
03959 
03960 
03961 
03962         // - reloc ptr
03963         READ_POD( &dma_idx, dma_idx );
03964 
03965         //*******************************************
03966         //*******************************************
03967         //*******************************************
03968 
03969         sb.dma.chan = NULL;
03970         if( dma_idx != 0xff ) sb.dma.chan = GetDMAChannel(dma_idx);
03971 
03972         //*******************************************
03973         //*******************************************
03974         //*******************************************
03975 
03976         // restore static ptr
03977         sb.chan = mixer_old;
03978 
03979 
03980         sb.chan->LoadState(stream);
03981 }