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