symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/sb16.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * QEMU Soundblaster 16 emulation
       
     3  *
       
     4  * Copyright (c) 2003-2005 Vassili Karpov (malc)
       
     5  *
       
     6  * Permission is hereby granted, free of charge, to any person obtaining a copy
       
     7  * of this software and associated documentation files (the "Software"), to deal
       
     8  * in the Software without restriction, including without limitation the rights
       
     9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       
    10  * copies of the Software, and to permit persons to whom the Software is
       
    11  * furnished to do so, subject to the following conditions:
       
    12  *
       
    13  * The above copyright notice and this permission notice shall be included in
       
    14  * all copies or substantial portions of the Software.
       
    15  *
       
    16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
       
    17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
       
    18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
       
    19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
       
    20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
       
    21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
       
    22  * THE SOFTWARE.
       
    23  */
       
    24 #include "hw.h"
       
    25 #include "audiodev.h"
       
    26 #include "audio/audio.h"
       
    27 #include "isa.h"
       
    28 #include "qemu-timer.h"
       
    29 
       
    30 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
       
    31 
       
    32 /* #define DEBUG */
       
    33 /* #define DEBUG_SB16_MOST */
       
    34 
       
    35 #ifdef DEBUG
       
    36 #define ldebug(...) dolog (__VA_ARGS__)
       
    37 #else
       
    38 #define ldebug(...)
       
    39 #endif
       
    40 
       
    41 #define IO_READ_PROTO(name)                             \
       
    42     uint32_t name (void *opaque, uint32_t nport)
       
    43 #define IO_WRITE_PROTO(name)                                    \
       
    44     void name (void *opaque, uint32_t nport, uint32_t val)
       
    45 
       
    46 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
       
    47 
       
    48 static struct {
       
    49     int ver_lo;
       
    50     int ver_hi;
       
    51     int irq;
       
    52     int dma;
       
    53     int hdma;
       
    54     int port;
       
    55 } conf = {5, 4, 5, 1, 5, 0x220};
       
    56 
       
    57 typedef struct SB16State {
       
    58     QEMUSoundCard card;
       
    59     qemu_irq *pic;
       
    60     int irq;
       
    61     int dma;
       
    62     int hdma;
       
    63     int port;
       
    64     int ver;
       
    65 
       
    66     int in_index;
       
    67     int out_data_len;
       
    68     int fmt_stereo;
       
    69     int fmt_signed;
       
    70     int fmt_bits;
       
    71     audfmt_e fmt;
       
    72     int dma_auto;
       
    73     int block_size;
       
    74     int fifo;
       
    75     int freq;
       
    76     int time_const;
       
    77     int speaker;
       
    78     int needed_bytes;
       
    79     int cmd;
       
    80     int use_hdma;
       
    81     int highspeed;
       
    82     int can_write;
       
    83 
       
    84     int v2x6;
       
    85 
       
    86     uint8_t csp_param;
       
    87     uint8_t csp_value;
       
    88     uint8_t csp_mode;
       
    89     uint8_t csp_regs[256];
       
    90     uint8_t csp_index;
       
    91     uint8_t csp_reg83[4];
       
    92     int csp_reg83r;
       
    93     int csp_reg83w;
       
    94 
       
    95     uint8_t in2_data[10];
       
    96     uint8_t out_data[50];
       
    97     uint8_t test_reg;
       
    98     uint8_t last_read_byte;
       
    99     int nzero;
       
   100 
       
   101     int left_till_irq;
       
   102 
       
   103     int dma_running;
       
   104     int bytes_per_second;
       
   105     int align;
       
   106     int audio_free;
       
   107     SWVoiceOut *voice;
       
   108 
       
   109     QEMUTimer *aux_ts;
       
   110     /* mixer state */
       
   111     int mixer_nreg;
       
   112     uint8_t mixer_regs[256];
       
   113 } SB16State;
       
   114 
       
   115 static void SB_audio_callback (void *opaque, int free);
       
   116 
       
   117 static int magic_of_irq (int irq)
       
   118 {
       
   119     switch (irq) {
       
   120     case 5:
       
   121         return 2;
       
   122     case 7:
       
   123         return 4;
       
   124     case 9:
       
   125         return 1;
       
   126     case 10:
       
   127         return 8;
       
   128     default:
       
   129         dolog ("bad irq %d\n", irq);
       
   130         return 2;
       
   131     }
       
   132 }
       
   133 
       
   134 static int irq_of_magic (int magic)
       
   135 {
       
   136     switch (magic) {
       
   137     case 1:
       
   138         return 9;
       
   139     case 2:
       
   140         return 5;
       
   141     case 4:
       
   142         return 7;
       
   143     case 8:
       
   144         return 10;
       
   145     default:
       
   146         dolog ("bad irq magic %d\n", magic);
       
   147         return -1;
       
   148     }
       
   149 }
       
   150 
       
   151 #if 0
       
   152 static void log_dsp (SB16State *dsp)
       
   153 {
       
   154     ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
       
   155             dsp->fmt_stereo ? "Stereo" : "Mono",
       
   156             dsp->fmt_signed ? "Signed" : "Unsigned",
       
   157             dsp->fmt_bits,
       
   158             dsp->dma_auto ? "Auto" : "Single",
       
   159             dsp->block_size,
       
   160             dsp->freq,
       
   161             dsp->time_const,
       
   162             dsp->speaker);
       
   163 }
       
   164 #endif
       
   165 
       
   166 static void speaker (SB16State *s, int on)
       
   167 {
       
   168     s->speaker = on;
       
   169     /* AUD_enable (s->voice, on); */
       
   170 }
       
   171 
       
   172 static void control (SB16State *s, int hold)
       
   173 {
       
   174     int dma = s->use_hdma ? s->hdma : s->dma;
       
   175     s->dma_running = hold;
       
   176 
       
   177     ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
       
   178 
       
   179     if (hold) {
       
   180         DMA_hold_DREQ (dma);
       
   181         AUD_set_active_out (s->voice, 1);
       
   182     }
       
   183     else {
       
   184         DMA_release_DREQ (dma);
       
   185         AUD_set_active_out (s->voice, 0);
       
   186     }
       
   187 }
       
   188 
       
   189 static void aux_timer (void *opaque)
       
   190 {
       
   191     SB16State *s = opaque;
       
   192     s->can_write = 1;
       
   193     qemu_irq_raise (s->pic[s->irq]);
       
   194 }
       
   195 
       
   196 #define DMA8_AUTO 1
       
   197 #define DMA8_HIGH 2
       
   198 
       
   199 static void continue_dma8 (SB16State *s)
       
   200 {
       
   201     if (s->freq > 0) {
       
   202         struct audsettings as;
       
   203 
       
   204         s->audio_free = 0;
       
   205 
       
   206         as.freq = s->freq;
       
   207         as.nchannels = 1 << s->fmt_stereo;
       
   208         as.fmt = s->fmt;
       
   209         as.endianness = 0;
       
   210 
       
   211         s->voice = AUD_open_out (
       
   212             &s->card,
       
   213             s->voice,
       
   214             "sb16",
       
   215             s,
       
   216             SB_audio_callback,
       
   217             &as
       
   218             );
       
   219     }
       
   220 
       
   221     control (s, 1);
       
   222 }
       
   223 
       
   224 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
       
   225 {
       
   226     s->fmt = AUD_FMT_U8;
       
   227     s->use_hdma = 0;
       
   228     s->fmt_bits = 8;
       
   229     s->fmt_signed = 0;
       
   230     s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
       
   231     if (-1 == s->time_const) {
       
   232         if (s->freq <= 0)
       
   233             s->freq = 11025;
       
   234     }
       
   235     else {
       
   236         int tmp = (256 - s->time_const);
       
   237         s->freq = (1000000 + (tmp / 2)) / tmp;
       
   238     }
       
   239 
       
   240     if (dma_len != -1) {
       
   241         s->block_size = dma_len << s->fmt_stereo;
       
   242     }
       
   243     else {
       
   244         /* This is apparently the only way to make both Act1/PL
       
   245            and SecondReality/FC work
       
   246 
       
   247            Act1 sets block size via command 0x48 and it's an odd number
       
   248            SR does the same with even number
       
   249            Both use stereo, and Creatives own documentation states that
       
   250            0x48 sets block size in bytes less one.. go figure */
       
   251         s->block_size &= ~s->fmt_stereo;
       
   252     }
       
   253 
       
   254     s->freq >>= s->fmt_stereo;
       
   255     s->left_till_irq = s->block_size;
       
   256     s->bytes_per_second = (s->freq << s->fmt_stereo);
       
   257     /* s->highspeed = (mask & DMA8_HIGH) != 0; */
       
   258     s->dma_auto = (mask & DMA8_AUTO) != 0;
       
   259     s->align = (1 << s->fmt_stereo) - 1;
       
   260 
       
   261     if (s->block_size & s->align) {
       
   262         dolog ("warning: misaligned block size %d, alignment %d\n",
       
   263                s->block_size, s->align + 1);
       
   264     }
       
   265 
       
   266     ldebug ("freq %d, stereo %d, sign %d, bits %d, "
       
   267             "dma %d, auto %d, fifo %d, high %d\n",
       
   268             s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
       
   269             s->block_size, s->dma_auto, s->fifo, s->highspeed);
       
   270 
       
   271     continue_dma8 (s);
       
   272     speaker (s, 1);
       
   273 }
       
   274 
       
   275 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
       
   276 {
       
   277     s->use_hdma = cmd < 0xc0;
       
   278     s->fifo = (cmd >> 1) & 1;
       
   279     s->dma_auto = (cmd >> 2) & 1;
       
   280     s->fmt_signed = (d0 >> 4) & 1;
       
   281     s->fmt_stereo = (d0 >> 5) & 1;
       
   282 
       
   283     switch (cmd >> 4) {
       
   284     case 11:
       
   285         s->fmt_bits = 16;
       
   286         break;
       
   287 
       
   288     case 12:
       
   289         s->fmt_bits = 8;
       
   290         break;
       
   291     }
       
   292 
       
   293     if (-1 != s->time_const) {
       
   294 #if 1
       
   295         int tmp = 256 - s->time_const;
       
   296         s->freq = (1000000 + (tmp / 2)) / tmp;
       
   297 #else
       
   298         /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
       
   299         s->freq = 1000000 / ((255 - s->time_const));
       
   300 #endif
       
   301         s->time_const = -1;
       
   302     }
       
   303 
       
   304     s->block_size = dma_len + 1;
       
   305     s->block_size <<= (s->fmt_bits == 16);
       
   306     if (!s->dma_auto) {
       
   307         /* It is clear that for DOOM and auto-init this value
       
   308            shouldn't take stereo into account, while Miles Sound Systems
       
   309            setsound.exe with single transfer mode wouldn't work without it
       
   310            wonders of SB16 yet again */
       
   311         s->block_size <<= s->fmt_stereo;
       
   312     }
       
   313 
       
   314     ldebug ("freq %d, stereo %d, sign %d, bits %d, "
       
   315             "dma %d, auto %d, fifo %d, high %d\n",
       
   316             s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
       
   317             s->block_size, s->dma_auto, s->fifo, s->highspeed);
       
   318 
       
   319     if (16 == s->fmt_bits) {
       
   320         if (s->fmt_signed) {
       
   321             s->fmt = AUD_FMT_S16;
       
   322         }
       
   323         else {
       
   324             s->fmt = AUD_FMT_U16;
       
   325         }
       
   326     }
       
   327     else {
       
   328         if (s->fmt_signed) {
       
   329             s->fmt = AUD_FMT_S8;
       
   330         }
       
   331         else {
       
   332             s->fmt = AUD_FMT_U8;
       
   333         }
       
   334     }
       
   335 
       
   336     s->left_till_irq = s->block_size;
       
   337 
       
   338     s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
       
   339     s->highspeed = 0;
       
   340     s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
       
   341     if (s->block_size & s->align) {
       
   342         dolog ("warning: misaligned block size %d, alignment %d\n",
       
   343                s->block_size, s->align + 1);
       
   344     }
       
   345 
       
   346     if (s->freq) {
       
   347         struct audsettings as;
       
   348 
       
   349         s->audio_free = 0;
       
   350 
       
   351         as.freq = s->freq;
       
   352         as.nchannels = 1 << s->fmt_stereo;
       
   353         as.fmt = s->fmt;
       
   354         as.endianness = 0;
       
   355 
       
   356         s->voice = AUD_open_out (
       
   357             &s->card,
       
   358             s->voice,
       
   359             "sb16",
       
   360             s,
       
   361             SB_audio_callback,
       
   362             &as
       
   363             );
       
   364     }
       
   365 
       
   366     control (s, 1);
       
   367     speaker (s, 1);
       
   368 }
       
   369 
       
   370 static inline void dsp_out_data (SB16State *s, uint8_t val)
       
   371 {
       
   372     ldebug ("outdata %#x\n", val);
       
   373     if ((size_t) s->out_data_len < sizeof (s->out_data)) {
       
   374         s->out_data[s->out_data_len++] = val;
       
   375     }
       
   376 }
       
   377 
       
   378 static inline uint8_t dsp_get_data (SB16State *s)
       
   379 {
       
   380     if (s->in_index) {
       
   381         return s->in2_data[--s->in_index];
       
   382     }
       
   383     else {
       
   384         dolog ("buffer underflow\n");
       
   385         return 0;
       
   386     }
       
   387 }
       
   388 
       
   389 static void command (SB16State *s, uint8_t cmd)
       
   390 {
       
   391     ldebug ("command %#x\n", cmd);
       
   392 
       
   393     if (cmd > 0xaf && cmd < 0xd0) {
       
   394         if (cmd & 8) {
       
   395             dolog ("ADC not yet supported (command %#x)\n", cmd);
       
   396         }
       
   397 
       
   398         switch (cmd >> 4) {
       
   399         case 11:
       
   400         case 12:
       
   401             break;
       
   402         default:
       
   403             dolog ("%#x wrong bits\n", cmd);
       
   404         }
       
   405         s->needed_bytes = 3;
       
   406     }
       
   407     else {
       
   408         s->needed_bytes = 0;
       
   409 
       
   410         switch (cmd) {
       
   411         case 0x03:
       
   412             dsp_out_data (s, 0x10); /* s->csp_param); */
       
   413             goto warn;
       
   414 
       
   415         case 0x04:
       
   416             s->needed_bytes = 1;
       
   417             goto warn;
       
   418 
       
   419         case 0x05:
       
   420             s->needed_bytes = 2;
       
   421             goto warn;
       
   422 
       
   423         case 0x08:
       
   424             /* __asm__ ("int3"); */
       
   425             goto warn;
       
   426 
       
   427         case 0x0e:
       
   428             s->needed_bytes = 2;
       
   429             goto warn;
       
   430 
       
   431         case 0x09:
       
   432             dsp_out_data (s, 0xf8);
       
   433             goto warn;
       
   434 
       
   435         case 0x0f:
       
   436             s->needed_bytes = 1;
       
   437             goto warn;
       
   438 
       
   439         case 0x10:
       
   440             s->needed_bytes = 1;
       
   441             goto warn;
       
   442 
       
   443         case 0x14:
       
   444             s->needed_bytes = 2;
       
   445             s->block_size = 0;
       
   446             break;
       
   447 
       
   448         case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
       
   449             dma_cmd8 (s, DMA8_AUTO, -1);
       
   450             break;
       
   451 
       
   452         case 0x20:              /* Direct ADC, Juice/PL */
       
   453             dsp_out_data (s, 0xff);
       
   454             goto warn;
       
   455 
       
   456         case 0x35:
       
   457             dolog ("0x35 - MIDI command not implemented\n");
       
   458             break;
       
   459 
       
   460         case 0x40:
       
   461             s->freq = -1;
       
   462             s->time_const = -1;
       
   463             s->needed_bytes = 1;
       
   464             break;
       
   465 
       
   466         case 0x41:
       
   467             s->freq = -1;
       
   468             s->time_const = -1;
       
   469             s->needed_bytes = 2;
       
   470             break;
       
   471 
       
   472         case 0x42:
       
   473             s->freq = -1;
       
   474             s->time_const = -1;
       
   475             s->needed_bytes = 2;
       
   476             goto warn;
       
   477 
       
   478         case 0x45:
       
   479             dsp_out_data (s, 0xaa);
       
   480             goto warn;
       
   481 
       
   482         case 0x47:                /* Continue Auto-Initialize DMA 16bit */
       
   483             break;
       
   484 
       
   485         case 0x48:
       
   486             s->needed_bytes = 2;
       
   487             break;
       
   488 
       
   489         case 0x74:
       
   490             s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
       
   491             dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
       
   492             break;
       
   493 
       
   494         case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
       
   495             s->needed_bytes = 2;
       
   496             dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
       
   497             break;
       
   498 
       
   499         case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
       
   500             s->needed_bytes = 2;
       
   501             dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
       
   502             break;
       
   503 
       
   504         case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
       
   505             s->needed_bytes = 2;
       
   506             dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
       
   507             break;
       
   508 
       
   509         case 0x7d:
       
   510             dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
       
   511             dolog ("not implemented\n");
       
   512             break;
       
   513 
       
   514         case 0x7f:
       
   515             dolog (
       
   516                 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
       
   517                 );
       
   518             dolog ("not implemented\n");
       
   519             break;
       
   520 
       
   521         case 0x80:
       
   522             s->needed_bytes = 2;
       
   523             break;
       
   524 
       
   525         case 0x90:
       
   526         case 0x91:
       
   527             dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
       
   528             break;
       
   529 
       
   530         case 0xd0:              /* halt DMA operation. 8bit */
       
   531             control (s, 0);
       
   532             break;
       
   533 
       
   534         case 0xd1:              /* speaker on */
       
   535             speaker (s, 1);
       
   536             break;
       
   537 
       
   538         case 0xd3:              /* speaker off */
       
   539             speaker (s, 0);
       
   540             break;
       
   541 
       
   542         case 0xd4:              /* continue DMA operation. 8bit */
       
   543             /* KQ6 (or maybe Sierras audblst.drv in general) resets
       
   544                the frequency between halt/continue */
       
   545             continue_dma8 (s);
       
   546             break;
       
   547 
       
   548         case 0xd5:              /* halt DMA operation. 16bit */
       
   549             control (s, 0);
       
   550             break;
       
   551 
       
   552         case 0xd6:              /* continue DMA operation. 16bit */
       
   553             control (s, 1);
       
   554             break;
       
   555 
       
   556         case 0xd9:              /* exit auto-init DMA after this block. 16bit */
       
   557             s->dma_auto = 0;
       
   558             break;
       
   559 
       
   560         case 0xda:              /* exit auto-init DMA after this block. 8bit */
       
   561             s->dma_auto = 0;
       
   562             break;
       
   563 
       
   564         case 0xe0:              /* DSP identification */
       
   565             s->needed_bytes = 1;
       
   566             break;
       
   567 
       
   568         case 0xe1:
       
   569             dsp_out_data (s, s->ver & 0xff);
       
   570             dsp_out_data (s, s->ver >> 8);
       
   571             break;
       
   572 
       
   573         case 0xe2:
       
   574             s->needed_bytes = 1;
       
   575             goto warn;
       
   576 
       
   577         case 0xe3:
       
   578             {
       
   579                 int i;
       
   580                 for (i = sizeof (e3) - 1; i >= 0; --i)
       
   581                     dsp_out_data (s, e3[i]);
       
   582             }
       
   583             break;
       
   584 
       
   585         case 0xe4:              /* write test reg */
       
   586             s->needed_bytes = 1;
       
   587             break;
       
   588 
       
   589         case 0xe7:
       
   590             dolog ("Attempt to probe for ESS (0xe7)?\n");
       
   591             break;
       
   592 
       
   593         case 0xe8:              /* read test reg */
       
   594             dsp_out_data (s, s->test_reg);
       
   595             break;
       
   596 
       
   597         case 0xf2:
       
   598         case 0xf3:
       
   599             dsp_out_data (s, 0xaa);
       
   600             s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
       
   601             qemu_irq_raise (s->pic[s->irq]);
       
   602             break;
       
   603 
       
   604         case 0xf9:
       
   605             s->needed_bytes = 1;
       
   606             goto warn;
       
   607 
       
   608         case 0xfa:
       
   609             dsp_out_data (s, 0);
       
   610             goto warn;
       
   611 
       
   612         case 0xfc:              /* FIXME */
       
   613             dsp_out_data (s, 0);
       
   614             goto warn;
       
   615 
       
   616         default:
       
   617             dolog ("Unrecognized command %#x\n", cmd);
       
   618             break;
       
   619         }
       
   620     }
       
   621 
       
   622     if (!s->needed_bytes) {
       
   623         ldebug ("\n");
       
   624     }
       
   625 
       
   626  exit:
       
   627     if (!s->needed_bytes) {
       
   628         s->cmd = -1;
       
   629     }
       
   630     else {
       
   631         s->cmd = cmd;
       
   632     }
       
   633     return;
       
   634 
       
   635  warn:
       
   636     dolog ("warning: command %#x,%d is not truly understood yet\n",
       
   637            cmd, s->needed_bytes);
       
   638     goto exit;
       
   639 
       
   640 }
       
   641 
       
   642 static uint16_t dsp_get_lohi (SB16State *s)
       
   643 {
       
   644     uint8_t hi = dsp_get_data (s);
       
   645     uint8_t lo = dsp_get_data (s);
       
   646     return (hi << 8) | lo;
       
   647 }
       
   648 
       
   649 static uint16_t dsp_get_hilo (SB16State *s)
       
   650 {
       
   651     uint8_t lo = dsp_get_data (s);
       
   652     uint8_t hi = dsp_get_data (s);
       
   653     return (hi << 8) | lo;
       
   654 }
       
   655 
       
   656 static void complete (SB16State *s)
       
   657 {
       
   658     int d0, d1, d2;
       
   659     ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
       
   660             s->cmd, s->in_index, s->needed_bytes);
       
   661 
       
   662     if (s->cmd > 0xaf && s->cmd < 0xd0) {
       
   663         d2 = dsp_get_data (s);
       
   664         d1 = dsp_get_data (s);
       
   665         d0 = dsp_get_data (s);
       
   666 
       
   667         if (s->cmd & 8) {
       
   668             dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
       
   669                    s->cmd, d0, d1, d2);
       
   670         }
       
   671         else {
       
   672             ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
       
   673                     s->cmd, d0, d1, d2);
       
   674             dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
       
   675         }
       
   676     }
       
   677     else {
       
   678         switch (s->cmd) {
       
   679         case 0x04:
       
   680             s->csp_mode = dsp_get_data (s);
       
   681             s->csp_reg83r = 0;
       
   682             s->csp_reg83w = 0;
       
   683             ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
       
   684             break;
       
   685 
       
   686         case 0x05:
       
   687             s->csp_param = dsp_get_data (s);
       
   688             s->csp_value = dsp_get_data (s);
       
   689             ldebug ("CSP command 0x05: param=%#x value=%#x\n",
       
   690                     s->csp_param,
       
   691                     s->csp_value);
       
   692             break;
       
   693 
       
   694         case 0x0e:
       
   695             d0 = dsp_get_data (s);
       
   696             d1 = dsp_get_data (s);
       
   697             ldebug ("write CSP register %d <- %#x\n", d1, d0);
       
   698             if (d1 == 0x83) {
       
   699                 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
       
   700                 s->csp_reg83[s->csp_reg83r % 4] = d0;
       
   701                 s->csp_reg83r += 1;
       
   702             }
       
   703             else {
       
   704                 s->csp_regs[d1] = d0;
       
   705             }
       
   706             break;
       
   707 
       
   708         case 0x0f:
       
   709             d0 = dsp_get_data (s);
       
   710             ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
       
   711                     d0, s->csp_regs[d0], s->csp_mode);
       
   712             if (d0 == 0x83) {
       
   713                 ldebug ("0x83[%d] -> %#x\n",
       
   714                         s->csp_reg83w,
       
   715                         s->csp_reg83[s->csp_reg83w % 4]);
       
   716                 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
       
   717                 s->csp_reg83w += 1;
       
   718             }
       
   719             else {
       
   720                 dsp_out_data (s, s->csp_regs[d0]);
       
   721             }
       
   722             break;
       
   723 
       
   724         case 0x10:
       
   725             d0 = dsp_get_data (s);
       
   726             dolog ("cmd 0x10 d0=%#x\n", d0);
       
   727             break;
       
   728 
       
   729         case 0x14:
       
   730             dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
       
   731             break;
       
   732 
       
   733         case 0x40:
       
   734             s->time_const = dsp_get_data (s);
       
   735             ldebug ("set time const %d\n", s->time_const);
       
   736             break;
       
   737 
       
   738         case 0x42:              /* FT2 sets output freq with this, go figure */
       
   739 #if 0
       
   740             dolog ("cmd 0x42 might not do what it think it should\n");
       
   741 #endif
       
   742         case 0x41:
       
   743             s->freq = dsp_get_hilo (s);
       
   744             ldebug ("set freq %d\n", s->freq);
       
   745             break;
       
   746 
       
   747         case 0x48:
       
   748             s->block_size = dsp_get_lohi (s) + 1;
       
   749             ldebug ("set dma block len %d\n", s->block_size);
       
   750             break;
       
   751 
       
   752         case 0x74:
       
   753         case 0x75:
       
   754         case 0x76:
       
   755         case 0x77:
       
   756             /* ADPCM stuff, ignore */
       
   757             break;
       
   758 
       
   759         case 0x80:
       
   760             {
       
   761                 int freq, samples, bytes;
       
   762                 int64_t ticks;
       
   763 
       
   764                 freq = s->freq > 0 ? s->freq : 11025;
       
   765                 samples = dsp_get_lohi (s) + 1;
       
   766                 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
       
   767                 ticks = (bytes * ticks_per_sec) / freq;
       
   768                 if (ticks < ticks_per_sec / 1024) {
       
   769                     qemu_irq_raise (s->pic[s->irq]);
       
   770                 }
       
   771                 else {
       
   772                     if (s->aux_ts) {
       
   773                         qemu_mod_timer (
       
   774                             s->aux_ts,
       
   775                             qemu_get_clock (vm_clock) + ticks
       
   776                             );
       
   777                     }
       
   778                 }
       
   779                 ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
       
   780             }
       
   781             break;
       
   782 
       
   783         case 0xe0:
       
   784             d0 = dsp_get_data (s);
       
   785             s->out_data_len = 0;
       
   786             ldebug ("E0 data = %#x\n", d0);
       
   787             dsp_out_data (s, ~d0);
       
   788             break;
       
   789 
       
   790         case 0xe2:
       
   791             d0 = dsp_get_data (s);
       
   792             ldebug ("E2 = %#x\n", d0);
       
   793             break;
       
   794 
       
   795         case 0xe4:
       
   796             s->test_reg = dsp_get_data (s);
       
   797             break;
       
   798 
       
   799         case 0xf9:
       
   800             d0 = dsp_get_data (s);
       
   801             ldebug ("command 0xf9 with %#x\n", d0);
       
   802             switch (d0) {
       
   803             case 0x0e:
       
   804                 dsp_out_data (s, 0xff);
       
   805                 break;
       
   806 
       
   807             case 0x0f:
       
   808                 dsp_out_data (s, 0x07);
       
   809                 break;
       
   810 
       
   811             case 0x37:
       
   812                 dsp_out_data (s, 0x38);
       
   813                 break;
       
   814 
       
   815             default:
       
   816                 dsp_out_data (s, 0x00);
       
   817                 break;
       
   818             }
       
   819             break;
       
   820 
       
   821         default:
       
   822             dolog ("complete: unrecognized command %#x\n", s->cmd);
       
   823             return;
       
   824         }
       
   825     }
       
   826 
       
   827     ldebug ("\n");
       
   828     s->cmd = -1;
       
   829     return;
       
   830 }
       
   831 
       
   832 static void legacy_reset (SB16State *s)
       
   833 {
       
   834     struct audsettings as;
       
   835 
       
   836     s->freq = 11025;
       
   837     s->fmt_signed = 0;
       
   838     s->fmt_bits = 8;
       
   839     s->fmt_stereo = 0;
       
   840 
       
   841     as.freq = s->freq;
       
   842     as.nchannels = 1;
       
   843     as.fmt = AUD_FMT_U8;
       
   844     as.endianness = 0;
       
   845 
       
   846     s->voice = AUD_open_out (
       
   847         &s->card,
       
   848         s->voice,
       
   849         "sb16",
       
   850         s,
       
   851         SB_audio_callback,
       
   852         &as
       
   853         );
       
   854 
       
   855     /* Not sure about that... */
       
   856     /* AUD_set_active_out (s->voice, 1); */
       
   857 }
       
   858 
       
   859 static void reset (SB16State *s)
       
   860 {
       
   861     qemu_irq_lower (s->pic[s->irq]);
       
   862     if (s->dma_auto) {
       
   863         qemu_irq_raise (s->pic[s->irq]);
       
   864         qemu_irq_lower (s->pic[s->irq]);
       
   865     }
       
   866 
       
   867     s->mixer_regs[0x82] = 0;
       
   868     s->dma_auto = 0;
       
   869     s->in_index = 0;
       
   870     s->out_data_len = 0;
       
   871     s->left_till_irq = 0;
       
   872     s->needed_bytes = 0;
       
   873     s->block_size = -1;
       
   874     s->nzero = 0;
       
   875     s->highspeed = 0;
       
   876     s->v2x6 = 0;
       
   877     s->cmd = -1;
       
   878 
       
   879     dsp_out_data(s, 0xaa);
       
   880     speaker (s, 0);
       
   881     control (s, 0);
       
   882     legacy_reset (s);
       
   883 }
       
   884 
       
   885 static IO_WRITE_PROTO (dsp_write)
       
   886 {
       
   887     SB16State *s = opaque;
       
   888     int iport;
       
   889 
       
   890     iport = nport - s->port;
       
   891 
       
   892     ldebug ("write %#x <- %#x\n", nport, val);
       
   893     switch (iport) {
       
   894     case 0x06:
       
   895         switch (val) {
       
   896         case 0x00:
       
   897             if (s->v2x6 == 1) {
       
   898                 if (0 && s->highspeed) {
       
   899                     s->highspeed = 0;
       
   900                     qemu_irq_lower (s->pic[s->irq]);
       
   901                     control (s, 0);
       
   902                 }
       
   903                 else {
       
   904                     reset (s);
       
   905                 }
       
   906             }
       
   907             s->v2x6 = 0;
       
   908             break;
       
   909 
       
   910         case 0x01:
       
   911         case 0x03:              /* FreeBSD kludge */
       
   912             s->v2x6 = 1;
       
   913             break;
       
   914 
       
   915         case 0xc6:
       
   916             s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
       
   917             break;
       
   918 
       
   919         case 0xb8:              /* Panic */
       
   920             reset (s);
       
   921             break;
       
   922 
       
   923         case 0x39:
       
   924             dsp_out_data (s, 0x38);
       
   925             reset (s);
       
   926             s->v2x6 = 0x39;
       
   927             break;
       
   928 
       
   929         default:
       
   930             s->v2x6 = val;
       
   931             break;
       
   932         }
       
   933         break;
       
   934 
       
   935     case 0x0c:                  /* write data or command | write status */
       
   936 /*         if (s->highspeed) */
       
   937 /*             break; */
       
   938 
       
   939         if (0 == s->needed_bytes) {
       
   940             command (s, val);
       
   941 #if 0
       
   942             if (0 == s->needed_bytes) {
       
   943                 log_dsp (s);
       
   944             }
       
   945 #endif
       
   946         }
       
   947         else {
       
   948             if (s->in_index == sizeof (s->in2_data)) {
       
   949                 dolog ("in data overrun\n");
       
   950             }
       
   951             else {
       
   952                 s->in2_data[s->in_index++] = val;
       
   953                 if (s->in_index == s->needed_bytes) {
       
   954                     s->needed_bytes = 0;
       
   955                     complete (s);
       
   956 #if 0
       
   957                     log_dsp (s);
       
   958 #endif
       
   959                 }
       
   960             }
       
   961         }
       
   962         break;
       
   963 
       
   964     default:
       
   965         ldebug ("(nport=%#x, val=%#x)\n", nport, val);
       
   966         break;
       
   967     }
       
   968 }
       
   969 
       
   970 static IO_READ_PROTO (dsp_read)
       
   971 {
       
   972     SB16State *s = opaque;
       
   973     int iport, retval, ack = 0;
       
   974 
       
   975     iport = nport - s->port;
       
   976 
       
   977     switch (iport) {
       
   978     case 0x06:                  /* reset */
       
   979         retval = 0xff;
       
   980         break;
       
   981 
       
   982     case 0x0a:                  /* read data */
       
   983         if (s->out_data_len) {
       
   984             retval = s->out_data[--s->out_data_len];
       
   985             s->last_read_byte = retval;
       
   986         }
       
   987         else {
       
   988             if (s->cmd != -1) {
       
   989                 dolog ("empty output buffer for command %#x\n",
       
   990                        s->cmd);
       
   991             }
       
   992             retval = s->last_read_byte;
       
   993             /* goto error; */
       
   994         }
       
   995         break;
       
   996 
       
   997     case 0x0c:                  /* 0 can write */
       
   998         retval = s->can_write ? 0 : 0x80;
       
   999         break;
       
  1000 
       
  1001     case 0x0d:                  /* timer interrupt clear */
       
  1002         /* dolog ("timer interrupt clear\n"); */
       
  1003         retval = 0;
       
  1004         break;
       
  1005 
       
  1006     case 0x0e:                  /* data available status | irq 8 ack */
       
  1007         retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
       
  1008         if (s->mixer_regs[0x82] & 1) {
       
  1009             ack = 1;
       
  1010             s->mixer_regs[0x82] &= 1;
       
  1011             qemu_irq_lower (s->pic[s->irq]);
       
  1012         }
       
  1013         break;
       
  1014 
       
  1015     case 0x0f:                  /* irq 16 ack */
       
  1016         retval = 0xff;
       
  1017         if (s->mixer_regs[0x82] & 2) {
       
  1018             ack = 1;
       
  1019             s->mixer_regs[0x82] &= 2;
       
  1020             qemu_irq_lower (s->pic[s->irq]);
       
  1021         }
       
  1022         break;
       
  1023 
       
  1024     default:
       
  1025         goto error;
       
  1026     }
       
  1027 
       
  1028     if (!ack) {
       
  1029         ldebug ("read %#x -> %#x\n", nport, retval);
       
  1030     }
       
  1031 
       
  1032     return retval;
       
  1033 
       
  1034  error:
       
  1035     dolog ("warning: dsp_read %#x error\n", nport);
       
  1036     return 0xff;
       
  1037 }
       
  1038 
       
  1039 static void reset_mixer (SB16State *s)
       
  1040 {
       
  1041     int i;
       
  1042 
       
  1043     memset (s->mixer_regs, 0xff, 0x7f);
       
  1044     memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
       
  1045 
       
  1046     s->mixer_regs[0x02] = 4;    /* master volume 3bits */
       
  1047     s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
       
  1048     s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
       
  1049     s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
       
  1050 
       
  1051     /* d5=input filt, d3=lowpass filt, d1,d2=input source */
       
  1052     s->mixer_regs[0x0c] = 0;
       
  1053 
       
  1054     /* d5=output filt, d1=stereo switch */
       
  1055     s->mixer_regs[0x0e] = 0;
       
  1056 
       
  1057     /* voice volume L d5,d7, R d1,d3 */
       
  1058     s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
       
  1059     /* master ... */
       
  1060     s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
       
  1061     /* MIDI ... */
       
  1062     s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
       
  1063 
       
  1064     for (i = 0x30; i < 0x48; i++) {
       
  1065         s->mixer_regs[i] = 0x20;
       
  1066     }
       
  1067 }
       
  1068 
       
  1069 static IO_WRITE_PROTO(mixer_write_indexb)
       
  1070 {
       
  1071     SB16State *s = opaque;
       
  1072     (void) nport;
       
  1073     s->mixer_nreg = val;
       
  1074 }
       
  1075 
       
  1076 static IO_WRITE_PROTO(mixer_write_datab)
       
  1077 {
       
  1078     SB16State *s = opaque;
       
  1079 
       
  1080     (void) nport;
       
  1081     ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
       
  1082 
       
  1083     switch (s->mixer_nreg) {
       
  1084     case 0x00:
       
  1085         reset_mixer (s);
       
  1086         break;
       
  1087 
       
  1088     case 0x80:
       
  1089         {
       
  1090             int irq = irq_of_magic (val);
       
  1091             ldebug ("setting irq to %d (val=%#x)\n", irq, val);
       
  1092             if (irq > 0) {
       
  1093                 s->irq = irq;
       
  1094             }
       
  1095         }
       
  1096         break;
       
  1097 
       
  1098     case 0x81:
       
  1099         {
       
  1100             int dma, hdma;
       
  1101 
       
  1102             dma = lsbindex (val & 0xf);
       
  1103             hdma = lsbindex (val & 0xf0);
       
  1104             if (dma != s->dma || hdma != s->hdma) {
       
  1105                 dolog (
       
  1106                     "attempt to change DMA "
       
  1107                     "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
       
  1108                     dma, s->dma, hdma, s->hdma, val);
       
  1109             }
       
  1110 #if 0
       
  1111             s->dma = dma;
       
  1112             s->hdma = hdma;
       
  1113 #endif
       
  1114         }
       
  1115         break;
       
  1116 
       
  1117     case 0x82:
       
  1118         dolog ("attempt to write into IRQ status register (val=%#x)\n",
       
  1119                val);
       
  1120         return;
       
  1121 
       
  1122     default:
       
  1123         if (s->mixer_nreg >= 0x80) {
       
  1124             ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
       
  1125         }
       
  1126         break;
       
  1127     }
       
  1128 
       
  1129     s->mixer_regs[s->mixer_nreg] = val;
       
  1130 }
       
  1131 
       
  1132 static IO_WRITE_PROTO(mixer_write_indexw)
       
  1133 {
       
  1134     mixer_write_indexb (opaque, nport, val & 0xff);
       
  1135     mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
       
  1136 }
       
  1137 
       
  1138 static IO_READ_PROTO(mixer_read)
       
  1139 {
       
  1140     SB16State *s = opaque;
       
  1141 
       
  1142     (void) nport;
       
  1143 #ifndef DEBUG_SB16_MOST
       
  1144     if (s->mixer_nreg != 0x82) {
       
  1145         ldebug ("mixer_read[%#x] -> %#x\n",
       
  1146                 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
       
  1147     }
       
  1148 #else
       
  1149     ldebug ("mixer_read[%#x] -> %#x\n",
       
  1150             s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
       
  1151 #endif
       
  1152     return s->mixer_regs[s->mixer_nreg];
       
  1153 }
       
  1154 
       
  1155 static int write_audio (SB16State *s, int nchan, int dma_pos,
       
  1156                         int dma_len, int len)
       
  1157 {
       
  1158     int temp, net;
       
  1159     uint8_t tmpbuf[4096];
       
  1160 
       
  1161     temp = len;
       
  1162     net = 0;
       
  1163 
       
  1164     while (temp) {
       
  1165         int left = dma_len - dma_pos;
       
  1166         int copied;
       
  1167         size_t to_copy;
       
  1168 
       
  1169         to_copy = audio_MIN (temp, left);
       
  1170         if (to_copy > sizeof (tmpbuf)) {
       
  1171             to_copy = sizeof (tmpbuf);
       
  1172         }
       
  1173 
       
  1174         copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
       
  1175         copied = AUD_write (s->voice, tmpbuf, copied);
       
  1176 
       
  1177         temp -= copied;
       
  1178         dma_pos = (dma_pos + copied) % dma_len;
       
  1179         net += copied;
       
  1180 
       
  1181         if (!copied) {
       
  1182             break;
       
  1183         }
       
  1184     }
       
  1185 
       
  1186     return net;
       
  1187 }
       
  1188 
       
  1189 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
       
  1190 {
       
  1191     SB16State *s = opaque;
       
  1192     int till, copy, written, free;
       
  1193 
       
  1194     if (s->block_size <= 0) {
       
  1195         dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
       
  1196                s->block_size, nchan, dma_pos, dma_len);
       
  1197         return dma_pos;
       
  1198     }
       
  1199 
       
  1200     if (s->left_till_irq < 0) {
       
  1201         s->left_till_irq = s->block_size;
       
  1202     }
       
  1203 
       
  1204     if (s->voice) {
       
  1205         free = s->audio_free & ~s->align;
       
  1206         if ((free <= 0) || !dma_len) {
       
  1207             return dma_pos;
       
  1208         }
       
  1209     }
       
  1210     else {
       
  1211         free = dma_len;
       
  1212     }
       
  1213 
       
  1214     copy = free;
       
  1215     till = s->left_till_irq;
       
  1216 
       
  1217 #ifdef DEBUG_SB16_MOST
       
  1218     dolog ("pos:%06d %d till:%d len:%d\n",
       
  1219            dma_pos, free, till, dma_len);
       
  1220 #endif
       
  1221 
       
  1222     if (till <= copy) {
       
  1223         if (0 == s->dma_auto) {
       
  1224             copy = till;
       
  1225         }
       
  1226     }
       
  1227 
       
  1228     written = write_audio (s, nchan, dma_pos, dma_len, copy);
       
  1229     dma_pos = (dma_pos + written) % dma_len;
       
  1230     s->left_till_irq -= written;
       
  1231 
       
  1232     if (s->left_till_irq <= 0) {
       
  1233         s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
       
  1234         qemu_irq_raise (s->pic[s->irq]);
       
  1235         if (0 == s->dma_auto) {
       
  1236             control (s, 0);
       
  1237             speaker (s, 0);
       
  1238         }
       
  1239     }
       
  1240 
       
  1241 #ifdef DEBUG_SB16_MOST
       
  1242     ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
       
  1243             dma_pos, free, dma_len, s->left_till_irq, copy, written,
       
  1244             s->block_size);
       
  1245 #endif
       
  1246 
       
  1247     while (s->left_till_irq <= 0) {
       
  1248         s->left_till_irq = s->block_size + s->left_till_irq;
       
  1249     }
       
  1250 
       
  1251     return dma_pos;
       
  1252 }
       
  1253 
       
  1254 static void SB_audio_callback (void *opaque, int free)
       
  1255 {
       
  1256     SB16State *s = opaque;
       
  1257     s->audio_free = free;
       
  1258 }
       
  1259 
       
  1260 static void SB_save (QEMUFile *f, void *opaque)
       
  1261 {
       
  1262     SB16State *s = opaque;
       
  1263 
       
  1264     qemu_put_be32 (f, s->irq);
       
  1265     qemu_put_be32 (f, s->dma);
       
  1266     qemu_put_be32 (f, s->hdma);
       
  1267     qemu_put_be32 (f, s->port);
       
  1268     qemu_put_be32 (f, s->ver);
       
  1269     qemu_put_be32 (f, s->in_index);
       
  1270     qemu_put_be32 (f, s->out_data_len);
       
  1271     qemu_put_be32 (f, s->fmt_stereo);
       
  1272     qemu_put_be32 (f, s->fmt_signed);
       
  1273     qemu_put_be32 (f, s->fmt_bits);
       
  1274     qemu_put_be32s (f, &s->fmt);
       
  1275     qemu_put_be32 (f, s->dma_auto);
       
  1276     qemu_put_be32 (f, s->block_size);
       
  1277     qemu_put_be32 (f, s->fifo);
       
  1278     qemu_put_be32 (f, s->freq);
       
  1279     qemu_put_be32 (f, s->time_const);
       
  1280     qemu_put_be32 (f, s->speaker);
       
  1281     qemu_put_be32 (f, s->needed_bytes);
       
  1282     qemu_put_be32 (f, s->cmd);
       
  1283     qemu_put_be32 (f, s->use_hdma);
       
  1284     qemu_put_be32 (f, s->highspeed);
       
  1285     qemu_put_be32 (f, s->can_write);
       
  1286     qemu_put_be32 (f, s->v2x6);
       
  1287 
       
  1288     qemu_put_8s (f, &s->csp_param);
       
  1289     qemu_put_8s (f, &s->csp_value);
       
  1290     qemu_put_8s (f, &s->csp_mode);
       
  1291     qemu_put_8s (f, &s->csp_param);
       
  1292     qemu_put_buffer (f, s->csp_regs, 256);
       
  1293     qemu_put_8s (f, &s->csp_index);
       
  1294     qemu_put_buffer (f, s->csp_reg83, 4);
       
  1295     qemu_put_be32 (f, s->csp_reg83r);
       
  1296     qemu_put_be32 (f, s->csp_reg83w);
       
  1297 
       
  1298     qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
       
  1299     qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
       
  1300     qemu_put_8s (f, &s->test_reg);
       
  1301     qemu_put_8s (f, &s->last_read_byte);
       
  1302 
       
  1303     qemu_put_be32 (f, s->nzero);
       
  1304     qemu_put_be32 (f, s->left_till_irq);
       
  1305     qemu_put_be32 (f, s->dma_running);
       
  1306     qemu_put_be32 (f, s->bytes_per_second);
       
  1307     qemu_put_be32 (f, s->align);
       
  1308 
       
  1309     qemu_put_be32 (f, s->mixer_nreg);
       
  1310     qemu_put_buffer (f, s->mixer_regs, 256);
       
  1311 }
       
  1312 
       
  1313 static int SB_load (QEMUFile *f, void *opaque, int version_id)
       
  1314 {
       
  1315     SB16State *s = opaque;
       
  1316 
       
  1317     if (version_id != 1) {
       
  1318         return -EINVAL;
       
  1319     }
       
  1320 
       
  1321     s->irq=qemu_get_be32 (f);
       
  1322     s->dma=qemu_get_be32 (f);
       
  1323     s->hdma=qemu_get_be32 (f);
       
  1324     s->port=qemu_get_be32 (f);
       
  1325     s->ver=qemu_get_be32 (f);
       
  1326     s->in_index=qemu_get_be32 (f);
       
  1327     s->out_data_len=qemu_get_be32 (f);
       
  1328     s->fmt_stereo=qemu_get_be32 (f);
       
  1329     s->fmt_signed=qemu_get_be32 (f);
       
  1330     s->fmt_bits=qemu_get_be32 (f);
       
  1331     qemu_get_be32s (f, &s->fmt);
       
  1332     s->dma_auto=qemu_get_be32 (f);
       
  1333     s->block_size=qemu_get_be32 (f);
       
  1334     s->fifo=qemu_get_be32 (f);
       
  1335     s->freq=qemu_get_be32 (f);
       
  1336     s->time_const=qemu_get_be32 (f);
       
  1337     s->speaker=qemu_get_be32 (f);
       
  1338     s->needed_bytes=qemu_get_be32 (f);
       
  1339     s->cmd=qemu_get_be32 (f);
       
  1340     s->use_hdma=qemu_get_be32 (f);
       
  1341     s->highspeed=qemu_get_be32 (f);
       
  1342     s->can_write=qemu_get_be32 (f);
       
  1343     s->v2x6=qemu_get_be32 (f);
       
  1344 
       
  1345     qemu_get_8s (f, &s->csp_param);
       
  1346     qemu_get_8s (f, &s->csp_value);
       
  1347     qemu_get_8s (f, &s->csp_mode);
       
  1348     qemu_get_8s (f, &s->csp_param);
       
  1349     qemu_get_buffer (f, s->csp_regs, 256);
       
  1350     qemu_get_8s (f, &s->csp_index);
       
  1351     qemu_get_buffer (f, s->csp_reg83, 4);
       
  1352     s->csp_reg83r=qemu_get_be32 (f);
       
  1353     s->csp_reg83w=qemu_get_be32 (f);
       
  1354 
       
  1355     qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
       
  1356     qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
       
  1357     qemu_get_8s (f, &s->test_reg);
       
  1358     qemu_get_8s (f, &s->last_read_byte);
       
  1359 
       
  1360     s->nzero=qemu_get_be32 (f);
       
  1361     s->left_till_irq=qemu_get_be32 (f);
       
  1362     s->dma_running=qemu_get_be32 (f);
       
  1363     s->bytes_per_second=qemu_get_be32 (f);
       
  1364     s->align=qemu_get_be32 (f);
       
  1365 
       
  1366     s->mixer_nreg=qemu_get_be32 (f);
       
  1367     qemu_get_buffer (f, s->mixer_regs, 256);
       
  1368 
       
  1369     if (s->voice) {
       
  1370         AUD_close_out (&s->card, s->voice);
       
  1371         s->voice = NULL;
       
  1372     }
       
  1373 
       
  1374     if (s->dma_running) {
       
  1375         if (s->freq) {
       
  1376             struct audsettings as;
       
  1377 
       
  1378             s->audio_free = 0;
       
  1379 
       
  1380             as.freq = s->freq;
       
  1381             as.nchannels = 1 << s->fmt_stereo;
       
  1382             as.fmt = s->fmt;
       
  1383             as.endianness = 0;
       
  1384 
       
  1385             s->voice = AUD_open_out (
       
  1386                 &s->card,
       
  1387                 s->voice,
       
  1388                 "sb16",
       
  1389                 s,
       
  1390                 SB_audio_callback,
       
  1391                 &as
       
  1392                 );
       
  1393         }
       
  1394 
       
  1395         control (s, 1);
       
  1396         speaker (s, s->speaker);
       
  1397     }
       
  1398     return 0;
       
  1399 }
       
  1400 
       
  1401 int SB16_init (AudioState *audio, qemu_irq *pic)
       
  1402 {
       
  1403     SB16State *s;
       
  1404     int i;
       
  1405     static const uint8_t dsp_write_ports[] = {0x6, 0xc};
       
  1406     static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
       
  1407 
       
  1408     if (!audio) {
       
  1409         dolog ("No audio state\n");
       
  1410         return -1;
       
  1411     }
       
  1412 
       
  1413     s = qemu_mallocz (sizeof (*s));
       
  1414     if (!s) {
       
  1415         dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
       
  1416                sizeof (*s));
       
  1417         return -1;
       
  1418     }
       
  1419 
       
  1420     s->cmd = -1;
       
  1421     s->pic = pic;
       
  1422     s->irq = conf.irq;
       
  1423     s->dma = conf.dma;
       
  1424     s->hdma = conf.hdma;
       
  1425     s->port = conf.port;
       
  1426     s->ver = conf.ver_lo | (conf.ver_hi << 8);
       
  1427 
       
  1428     s->mixer_regs[0x80] = magic_of_irq (s->irq);
       
  1429     s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
       
  1430     s->mixer_regs[0x82] = 2 << 5;
       
  1431 
       
  1432     s->csp_regs[5] = 1;
       
  1433     s->csp_regs[9] = 0xf8;
       
  1434 
       
  1435     reset_mixer (s);
       
  1436     s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
       
  1437     if (!s->aux_ts) {
       
  1438         dolog ("warning: Could not create auxiliary timer\n");
       
  1439     }
       
  1440 
       
  1441     for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) {
       
  1442         register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
       
  1443     }
       
  1444 
       
  1445     for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
       
  1446         register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
       
  1447     }
       
  1448 
       
  1449     register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
       
  1450     register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
       
  1451     register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
       
  1452     register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
       
  1453 
       
  1454     DMA_register_channel (s->hdma, SB_read_DMA, s);
       
  1455     DMA_register_channel (s->dma, SB_read_DMA, s);
       
  1456     s->can_write = 1;
       
  1457 
       
  1458     register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
       
  1459     AUD_register_card (audio, "sb16", &s->card);
       
  1460     return 0;
       
  1461 }