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