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