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    AudioFormat 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 = AUDIO_FORMAT_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 = AUDIO_FORMAT_S16;
 323        }
 324        else {
 325            s->fmt = AUDIO_FORMAT_U16;
 326        }
 327    }
 328    else {
 329        if (s->fmt_signed) {
 330            s->fmt = AUDIO_FORMAT_S8;
 331        }
 332        else {
 333            s->fmt = AUDIO_FORMAT_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 0x41:
 745        case 0x42:
 746            /*
 747             * 0x41 is documented as setting the output sample rate,
 748             * and 0x42 the input sample rate, but in fact SB16 hardware
 749             * seems to have only a single sample rate under the hood,
 750             * and FT2 sets output freq with this (go figure).  Compare:
 751             * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
 752             */
 753            s->freq = dsp_get_hilo (s);
 754            ldebug ("set freq %d\n", s->freq);
 755            break;
 756
 757        case 0x48:
 758            s->block_size = dsp_get_lohi (s) + 1;
 759            ldebug ("set dma block len %d\n", s->block_size);
 760            break;
 761
 762        case 0x74:
 763        case 0x75:
 764        case 0x76:
 765        case 0x77:
 766            /* ADPCM stuff, ignore */
 767            break;
 768
 769        case 0x80:
 770            {
 771                int freq, samples, bytes;
 772                int64_t ticks;
 773
 774                freq = s->freq > 0 ? s->freq : 11025;
 775                samples = dsp_get_lohi (s) + 1;
 776                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
 777                ticks = muldiv64(bytes, NANOSECONDS_PER_SECOND, freq);
 778                if (ticks < NANOSECONDS_PER_SECOND / 1024) {
 779                    qemu_irq_raise (s->pic);
 780                }
 781                else {
 782                    if (s->aux_ts) {
 783                        timer_mod (
 784                            s->aux_ts,
 785                            qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ticks
 786                            );
 787                    }
 788                }
 789                ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
 790            }
 791            break;
 792
 793        case 0xe0:
 794            d0 = dsp_get_data (s);
 795            s->out_data_len = 0;
 796            ldebug ("E0 data = %#x\n", d0);
 797            dsp_out_data (s, ~d0);
 798            break;
 799
 800        case 0xe2:
 801#ifdef DEBUG
 802            d0 = dsp_get_data (s);
 803            dolog ("E2 = %#x\n", d0);
 804#endif
 805            break;
 806
 807        case 0xe4:
 808            s->test_reg = dsp_get_data (s);
 809            break;
 810
 811        case 0xf9:
 812            d0 = dsp_get_data (s);
 813            ldebug ("command 0xf9 with %#x\n", d0);
 814            switch (d0) {
 815            case 0x0e:
 816                dsp_out_data (s, 0xff);
 817                break;
 818
 819            case 0x0f:
 820                dsp_out_data (s, 0x07);
 821                break;
 822
 823            case 0x37:
 824                dsp_out_data (s, 0x38);
 825                break;
 826
 827            default:
 828                dsp_out_data (s, 0x00);
 829                break;
 830            }
 831            break;
 832
 833        default:
 834            qemu_log_mask(LOG_UNIMP, "complete: unrecognized command %#x\n",
 835                          s->cmd);
 836            return;
 837        }
 838    }
 839
 840    ldebug ("\n");
 841    s->cmd = -1;
 842}
 843
 844static void legacy_reset (SB16State *s)
 845{
 846    struct audsettings as;
 847
 848    s->freq = 11025;
 849    s->fmt_signed = 0;
 850    s->fmt_bits = 8;
 851    s->fmt_stereo = 0;
 852
 853    as.freq = s->freq;
 854    as.nchannels = 1;
 855    as.fmt = AUDIO_FORMAT_U8;
 856    as.endianness = 0;
 857
 858    s->voice = AUD_open_out (
 859        &s->card,
 860        s->voice,
 861        "sb16",
 862        s,
 863        SB_audio_callback,
 864        &as
 865        );
 866
 867    /* Not sure about that... */
 868    /* AUD_set_active_out (s->voice, 1); */
 869}
 870
 871static void reset (SB16State *s)
 872{
 873    qemu_irq_lower (s->pic);
 874    if (s->dma_auto) {
 875        qemu_irq_raise (s->pic);
 876        qemu_irq_lower (s->pic);
 877    }
 878
 879    s->mixer_regs[0x82] = 0;
 880    s->dma_auto = 0;
 881    s->in_index = 0;
 882    s->out_data_len = 0;
 883    s->left_till_irq = 0;
 884    s->needed_bytes = 0;
 885    s->block_size = -1;
 886    s->nzero = 0;
 887    s->highspeed = 0;
 888    s->v2x6 = 0;
 889    s->cmd = -1;
 890
 891    dsp_out_data (s, 0xaa);
 892    speaker (s, 0);
 893    control (s, 0);
 894    legacy_reset (s);
 895}
 896
 897static void dsp_write(void *opaque, uint32_t nport, uint32_t val)
 898{
 899    SB16State *s = opaque;
 900    int iport;
 901
 902    iport = nport - s->port;
 903
 904    ldebug ("write %#x <- %#x\n", nport, val);
 905    switch (iport) {
 906    case 0x06:
 907        switch (val) {
 908        case 0x00:
 909            if (s->v2x6 == 1) {
 910                reset (s);
 911            }
 912            s->v2x6 = 0;
 913            break;
 914
 915        case 0x01:
 916        case 0x03:              /* FreeBSD kludge */
 917            s->v2x6 = 1;
 918            break;
 919
 920        case 0xc6:
 921            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
 922            break;
 923
 924        case 0xb8:              /* Panic */
 925            reset (s);
 926            break;
 927
 928        case 0x39:
 929            dsp_out_data (s, 0x38);
 930            reset (s);
 931            s->v2x6 = 0x39;
 932            break;
 933
 934        default:
 935            s->v2x6 = val;
 936            break;
 937        }
 938        break;
 939
 940    case 0x0c:                  /* write data or command | write status */
 941/*         if (s->highspeed) */
 942/*             break; */
 943
 944        if (s->needed_bytes == 0) {
 945            command (s, val);
 946#if 0
 947            if (0 == s->needed_bytes) {
 948                log_dsp (s);
 949            }
 950#endif
 951        }
 952        else {
 953            if (s->in_index == sizeof (s->in2_data)) {
 954                dolog ("in data overrun\n");
 955            }
 956            else {
 957                s->in2_data[s->in_index++] = val;
 958                if (s->in_index == s->needed_bytes) {
 959                    s->needed_bytes = 0;
 960                    complete (s);
 961#if 0
 962                    log_dsp (s);
 963#endif
 964                }
 965            }
 966        }
 967        break;
 968
 969    default:
 970        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
 971        break;
 972    }
 973}
 974
 975static uint32_t dsp_read(void *opaque, uint32_t nport)
 976{
 977    SB16State *s = opaque;
 978    int iport, retval, ack = 0;
 979
 980    iport = nport - s->port;
 981
 982    switch (iport) {
 983    case 0x06:                  /* reset */
 984        retval = 0xff;
 985        break;
 986
 987    case 0x0a:                  /* read data */
 988        if (s->out_data_len) {
 989            retval = s->out_data[--s->out_data_len];
 990            s->last_read_byte = retval;
 991        }
 992        else {
 993            if (s->cmd != -1) {
 994                dolog ("empty output buffer for command %#x\n",
 995                       s->cmd);
 996            }
 997            retval = s->last_read_byte;
 998            /* goto error; */
 999        }
1000        break;
1001
1002    case 0x0c:                  /* 0 can write */
1003        retval = s->can_write ? 0 : 0x80;
1004        break;
1005
1006    case 0x0d:                  /* timer interrupt clear */
1007        /* dolog ("timer interrupt clear\n"); */
1008        retval = 0;
1009        break;
1010
1011    case 0x0e:                  /* data available status | irq 8 ack */
1012        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1013        if (s->mixer_regs[0x82] & 1) {
1014            ack = 1;
1015            s->mixer_regs[0x82] &= ~1;
1016            qemu_irq_lower (s->pic);
1017        }
1018        break;
1019
1020    case 0x0f:                  /* irq 16 ack */
1021        retval = 0xff;
1022        if (s->mixer_regs[0x82] & 2) {
1023            ack = 1;
1024            s->mixer_regs[0x82] &= ~2;
1025            qemu_irq_lower (s->pic);
1026        }
1027        break;
1028
1029    default:
1030        goto error;
1031    }
1032
1033    if (!ack) {
1034        ldebug ("read %#x -> %#x\n", nport, retval);
1035    }
1036
1037    return retval;
1038
1039 error:
1040    dolog ("warning: dsp_read %#x error\n", nport);
1041    return 0xff;
1042}
1043
1044static void reset_mixer (SB16State *s)
1045{
1046    int i;
1047
1048    memset (s->mixer_regs, 0xff, 0x7f);
1049    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1050
1051    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1052    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1053    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1054    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1055
1056    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1057    s->mixer_regs[0x0c] = 0;
1058
1059    /* d5=output filt, d1=stereo switch */
1060    s->mixer_regs[0x0e] = 0;
1061
1062    /* voice volume L d5,d7, R d1,d3 */
1063    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1064    /* master ... */
1065    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1066    /* MIDI ... */
1067    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1068
1069    for (i = 0x30; i < 0x48; i++) {
1070        s->mixer_regs[i] = 0x20;
1071    }
1072}
1073
1074static void mixer_write_indexb(void *opaque, uint32_t nport, uint32_t val)
1075{
1076    SB16State *s = opaque;
1077    (void) nport;
1078    s->mixer_nreg = val;
1079}
1080
1081static void mixer_write_datab(void *opaque, uint32_t nport, uint32_t val)
1082{
1083    SB16State *s = opaque;
1084
1085    (void) nport;
1086    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1087
1088    switch (s->mixer_nreg) {
1089    case 0x00:
1090        reset_mixer (s);
1091        break;
1092
1093    case 0x80:
1094        {
1095            int irq = irq_of_magic (val);
1096            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1097            if (irq > 0) {
1098                s->irq = irq;
1099            }
1100        }
1101        break;
1102
1103    case 0x81:
1104        {
1105            int dma, hdma;
1106
1107            dma = ctz32 (val & 0xf);
1108            hdma = ctz32 (val & 0xf0);
1109            if (dma != s->dma || hdma != s->hdma) {
1110                qemu_log_mask(LOG_GUEST_ERROR, "attempt to change DMA 8bit"
1111                              " %d(%d), 16bit %d(%d) (val=%#x)\n", dma, s->dma,
1112                              hdma, s->hdma, val);
1113            }
1114#if 0
1115            s->dma = dma;
1116            s->hdma = hdma;
1117#endif
1118        }
1119        break;
1120
1121    case 0x82:
1122        qemu_log_mask(LOG_GUEST_ERROR, "attempt to write into IRQ status"
1123                      " register (val=%#x)\n", val);
1124        return;
1125
1126    default:
1127        if (s->mixer_nreg >= 0x80) {
1128            ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1129        }
1130        break;
1131    }
1132
1133    s->mixer_regs[s->mixer_nreg] = val;
1134}
1135
1136static uint32_t mixer_read(void *opaque, uint32_t nport)
1137{
1138    SB16State *s = opaque;
1139
1140    (void) nport;
1141#ifndef DEBUG_SB16_MOST
1142    if (s->mixer_nreg != 0x82) {
1143        ldebug ("mixer_read[%#x] -> %#x\n",
1144                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1145    }
1146#else
1147    ldebug ("mixer_read[%#x] -> %#x\n",
1148            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1149#endif
1150    return s->mixer_regs[s->mixer_nreg];
1151}
1152
1153static int write_audio (SB16State *s, int nchan, int dma_pos,
1154                        int dma_len, int len)
1155{
1156    IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma;
1157    IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma);
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 = k->read_memory(isa_dma, 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
1189static 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        qemu_log_mask(LOG_GUEST_ERROR, "invalid block size=%d nchan=%d"
1196                      " dma_pos=%d dma_len=%d\n", s->block_size, nchan,
1197                      dma_pos, dma_len);
1198        return dma_pos;
1199    }
1200
1201    if (s->left_till_irq < 0) {
1202        s->left_till_irq = s->block_size;
1203    }
1204
1205    if (s->voice) {
1206        free = s->audio_free & ~s->align;
1207        if ((free <= 0) || !dma_len) {
1208            return dma_pos;
1209        }
1210    }
1211    else {
1212        free = dma_len;
1213    }
1214
1215    copy = free;
1216    till = s->left_till_irq;
1217
1218#ifdef DEBUG_SB16_MOST
1219    dolog ("pos:%06d %d till:%d len:%d\n",
1220           dma_pos, free, till, dma_len);
1221#endif
1222
1223    if (till <= copy) {
1224        if (s->dma_auto == 0) {
1225            copy = till;
1226        }
1227    }
1228
1229    written = write_audio (s, nchan, dma_pos, dma_len, copy);
1230    dma_pos = (dma_pos + written) % dma_len;
1231    s->left_till_irq -= written;
1232
1233    if (s->left_till_irq <= 0) {
1234        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1235        qemu_irq_raise (s->pic);
1236        if (s->dma_auto == 0) {
1237            control (s, 0);
1238            speaker (s, 0);
1239        }
1240    }
1241
1242#ifdef DEBUG_SB16_MOST
1243    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1244            dma_pos, free, dma_len, s->left_till_irq, copy, written,
1245            s->block_size);
1246#endif
1247
1248    while (s->left_till_irq <= 0) {
1249        s->left_till_irq = s->block_size + s->left_till_irq;
1250    }
1251
1252    return dma_pos;
1253}
1254
1255static void SB_audio_callback (void *opaque, int free)
1256{
1257    SB16State *s = opaque;
1258    s->audio_free = free;
1259}
1260
1261static int sb16_post_load (void *opaque, int version_id)
1262{
1263    SB16State *s = opaque;
1264
1265    if (s->voice) {
1266        AUD_close_out (&s->card, s->voice);
1267        s->voice = NULL;
1268    }
1269
1270    if (s->dma_running) {
1271        if (s->freq) {
1272            struct audsettings as;
1273
1274            s->audio_free = 0;
1275
1276            as.freq = s->freq;
1277            as.nchannels = 1 << s->fmt_stereo;
1278            as.fmt = s->fmt;
1279            as.endianness = 0;
1280
1281            s->voice = AUD_open_out (
1282                &s->card,
1283                s->voice,
1284                "sb16",
1285                s,
1286                SB_audio_callback,
1287                &as
1288                );
1289        }
1290
1291        control (s, 1);
1292        speaker (s, s->speaker);
1293    }
1294    return 0;
1295}
1296
1297static const VMStateDescription vmstate_sb16 = {
1298    .name = "sb16",
1299    .version_id = 1,
1300    .minimum_version_id = 1,
1301    .post_load = sb16_post_load,
1302    .fields = (VMStateField[]) {
1303        VMSTATE_UINT32 (irq, SB16State),
1304        VMSTATE_UINT32 (dma, SB16State),
1305        VMSTATE_UINT32 (hdma, SB16State),
1306        VMSTATE_UINT32 (port, SB16State),
1307        VMSTATE_UINT32 (ver, SB16State),
1308        VMSTATE_INT32 (in_index, SB16State),
1309        VMSTATE_INT32 (out_data_len, SB16State),
1310        VMSTATE_INT32 (fmt_stereo, SB16State),
1311        VMSTATE_INT32 (fmt_signed, SB16State),
1312        VMSTATE_INT32 (fmt_bits, SB16State),
1313        VMSTATE_UINT32 (fmt, SB16State),
1314        VMSTATE_INT32 (dma_auto, SB16State),
1315        VMSTATE_INT32 (block_size, SB16State),
1316        VMSTATE_INT32 (fifo, SB16State),
1317        VMSTATE_INT32 (freq, SB16State),
1318        VMSTATE_INT32 (time_const, SB16State),
1319        VMSTATE_INT32 (speaker, SB16State),
1320        VMSTATE_INT32 (needed_bytes, SB16State),
1321        VMSTATE_INT32 (cmd, SB16State),
1322        VMSTATE_INT32 (use_hdma, SB16State),
1323        VMSTATE_INT32 (highspeed, SB16State),
1324        VMSTATE_INT32 (can_write, SB16State),
1325        VMSTATE_INT32 (v2x6, SB16State),
1326
1327        VMSTATE_UINT8 (csp_param, SB16State),
1328        VMSTATE_UINT8 (csp_value, SB16State),
1329        VMSTATE_UINT8 (csp_mode, SB16State),
1330        VMSTATE_UINT8 (csp_param, SB16State),
1331        VMSTATE_BUFFER (csp_regs, SB16State),
1332        VMSTATE_UINT8 (csp_index, SB16State),
1333        VMSTATE_BUFFER (csp_reg83, SB16State),
1334        VMSTATE_INT32 (csp_reg83r, SB16State),
1335        VMSTATE_INT32 (csp_reg83w, SB16State),
1336
1337        VMSTATE_BUFFER (in2_data, SB16State),
1338        VMSTATE_BUFFER (out_data, SB16State),
1339        VMSTATE_UINT8 (test_reg, SB16State),
1340        VMSTATE_UINT8 (last_read_byte, SB16State),
1341
1342        VMSTATE_INT32 (nzero, SB16State),
1343        VMSTATE_INT32 (left_till_irq, SB16State),
1344        VMSTATE_INT32 (dma_running, SB16State),
1345        VMSTATE_INT32 (bytes_per_second, SB16State),
1346        VMSTATE_INT32 (align, SB16State),
1347
1348        VMSTATE_INT32 (mixer_nreg, SB16State),
1349        VMSTATE_BUFFER (mixer_regs, SB16State),
1350
1351        VMSTATE_END_OF_LIST ()
1352    }
1353};
1354
1355static const MemoryRegionPortio sb16_ioport_list[] = {
1356    {  4, 1, 1, .write = mixer_write_indexb },
1357    {  5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
1358    {  6, 1, 1, .read = dsp_read, .write = dsp_write },
1359    { 10, 1, 1, .read = dsp_read },
1360    { 12, 1, 1, .write = dsp_write },
1361    { 12, 4, 1, .read = dsp_read },
1362    PORTIO_END_OF_LIST (),
1363};
1364
1365
1366static void sb16_initfn (Object *obj)
1367{
1368    SB16State *s = SB16 (obj);
1369
1370    s->cmd = -1;
1371}
1372
1373static void sb16_realizefn (DeviceState *dev, Error **errp)
1374{
1375    ISADevice *isadev = ISA_DEVICE (dev);
1376    SB16State *s = SB16 (dev);
1377    IsaDmaClass *k;
1378
1379    s->isa_hdma = isa_get_dma(isa_bus_from_device(isadev), s->hdma);
1380    s->isa_dma = isa_get_dma(isa_bus_from_device(isadev), s->dma);
1381    if (!s->isa_dma || !s->isa_hdma) {
1382        error_setg(errp, "ISA controller does not support DMA");
1383        return;
1384    }
1385
1386    isa_init_irq (isadev, &s->pic, s->irq);
1387
1388    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1389    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1390    s->mixer_regs[0x82] = 2 << 5;
1391
1392    s->csp_regs[5] = 1;
1393    s->csp_regs[9] = 0xf8;
1394
1395    reset_mixer (s);
1396    s->aux_ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, aux_timer, s);
1397    if (!s->aux_ts) {
1398        error_setg(errp, "warning: Could not create auxiliary timer");
1399    }
1400
1401    isa_register_portio_list(isadev, &s->portio_list, s->port,
1402                             sb16_ioport_list, s, "sb16");
1403
1404    k = ISADMA_GET_CLASS(s->isa_hdma);
1405    k->register_channel(s->isa_hdma, s->hdma, SB_read_DMA, s);
1406
1407    k = ISADMA_GET_CLASS(s->isa_dma);
1408    k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);
1409
1410    s->can_write = 1;
1411
1412    AUD_register_card ("sb16", &s->card);
1413}
1414
1415static int SB16_init (ISABus *bus)
1416{
1417    isa_create_simple (bus, TYPE_SB16);
1418    return 0;
1419}
1420
1421static Property sb16_properties[] = {
1422    DEFINE_PROP_UINT32 ("version", SB16State, ver,  0x0405), /* 4.5 */
1423    DEFINE_PROP_UINT32 ("iobase",  SB16State, port, 0x220),
1424    DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
1425    DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
1426    DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
1427    DEFINE_PROP_END_OF_LIST (),
1428};
1429
1430static void sb16_class_initfn (ObjectClass *klass, void *data)
1431{
1432    DeviceClass *dc = DEVICE_CLASS (klass);
1433
1434    dc->realize = sb16_realizefn;
1435    set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
1436    dc->desc = "Creative Sound Blaster 16";
1437    dc->vmsd = &vmstate_sb16;
1438    dc->props = sb16_properties;
1439}
1440
1441static const TypeInfo sb16_info = {
1442    .name          = TYPE_SB16,
1443    .parent        = TYPE_ISA_DEVICE,
1444    .instance_size = sizeof (SB16State),
1445    .instance_init = sb16_initfn,
1446    .class_init    = sb16_class_initfn,
1447};
1448
1449static void sb16_register_types (void)
1450{
1451    type_register_static (&sb16_info);
1452    isa_register_soundhw("sb16", "Creative Sound Blaster 16", SB16_init);
1453}
1454
1455type_init (sb16_register_types)
1456