cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

sb16.c (38247B)


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