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 (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            d0 = dsp_get_data (s);
 786            ldebug ("E2 = %#x\n", d0);
 787            break;
 788
 789        case 0xe4:
 790            s->test_reg = dsp_get_data (s);
 791            break;
 792
 793        case 0xf9:
 794            d0 = dsp_get_data (s);
 795            ldebug ("command 0xf9 with %#x\n", d0);
 796            switch (d0) {
 797            case 0x0e:
 798                dsp_out_data (s, 0xff);
 799                break;
 800
 801            case 0x0f:
 802                dsp_out_data (s, 0x07);
 803                break;
 804
 805            case 0x37:
 806                dsp_out_data (s, 0x38);
 807                break;
 808
 809            default:
 810                dsp_out_data (s, 0x00);
 811                break;
 812            }
 813            break;
 814
 815        default:
 816            dolog ("complete: unrecognized command %#x\n", s->cmd);
 817            return;
 818        }
 819    }
 820
 821    ldebug ("\n");
 822    s->cmd = -1;
 823    return;
 824}
 825
 826static void legacy_reset (SB16State *s)
 827{
 828    struct audsettings as;
 829
 830    s->freq = 11025;
 831    s->fmt_signed = 0;
 832    s->fmt_bits = 8;
 833    s->fmt_stereo = 0;
 834
 835    as.freq = s->freq;
 836    as.nchannels = 1;
 837    as.fmt = AUD_FMT_U8;
 838    as.endianness = 0;
 839
 840    s->voice = AUD_open_out (
 841        &s->card,
 842        s->voice,
 843        "sb16",
 844        s,
 845        SB_audio_callback,
 846        &as
 847        );
 848
 849    /* Not sure about that... */
 850    /* AUD_set_active_out (s->voice, 1); */
 851}
 852
 853static void reset (SB16State *s)
 854{
 855    qemu_irq_lower (s->pic);
 856    if (s->dma_auto) {
 857        qemu_irq_raise (s->pic);
 858        qemu_irq_lower (s->pic);
 859    }
 860
 861    s->mixer_regs[0x82] = 0;
 862    s->dma_auto = 0;
 863    s->in_index = 0;
 864    s->out_data_len = 0;
 865    s->left_till_irq = 0;
 866    s->needed_bytes = 0;
 867    s->block_size = -1;
 868    s->nzero = 0;
 869    s->highspeed = 0;
 870    s->v2x6 = 0;
 871    s->cmd = -1;
 872
 873    dsp_out_data (s, 0xaa);
 874    speaker (s, 0);
 875    control (s, 0);
 876    legacy_reset (s);
 877}
 878
 879static IO_WRITE_PROTO (dsp_write)
 880{
 881    SB16State *s = opaque;
 882    int iport;
 883
 884    iport = nport - s->port;
 885
 886    ldebug ("write %#x <- %#x\n", nport, val);
 887    switch (iport) {
 888    case 0x06:
 889        switch (val) {
 890        case 0x00:
 891            if (s->v2x6 == 1) {
 892                reset (s);
 893            }
 894            s->v2x6 = 0;
 895            break;
 896
 897        case 0x01:
 898        case 0x03:              /* FreeBSD kludge */
 899            s->v2x6 = 1;
 900            break;
 901
 902        case 0xc6:
 903            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
 904            break;
 905
 906        case 0xb8:              /* Panic */
 907            reset (s);
 908            break;
 909
 910        case 0x39:
 911            dsp_out_data (s, 0x38);
 912            reset (s);
 913            s->v2x6 = 0x39;
 914            break;
 915
 916        default:
 917            s->v2x6 = val;
 918            break;
 919        }
 920        break;
 921
 922    case 0x0c:                  /* write data or command | write status */
 923/*         if (s->highspeed) */
 924/*             break; */
 925
 926        if (0 == s->needed_bytes) {
 927            command (s, val);
 928#if 0
 929            if (0 == s->needed_bytes) {
 930                log_dsp (s);
 931            }
 932#endif
 933        }
 934        else {
 935            if (s->in_index == sizeof (s->in2_data)) {
 936                dolog ("in data overrun\n");
 937            }
 938            else {
 939                s->in2_data[s->in_index++] = val;
 940                if (s->in_index == s->needed_bytes) {
 941                    s->needed_bytes = 0;
 942                    complete (s);
 943#if 0
 944                    log_dsp (s);
 945#endif
 946                }
 947            }
 948        }
 949        break;
 950
 951    default:
 952        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
 953        break;
 954    }
 955}
 956
 957static IO_READ_PROTO (dsp_read)
 958{
 959    SB16State *s = opaque;
 960    int iport, retval, ack = 0;
 961
 962    iport = nport - s->port;
 963
 964    switch (iport) {
 965    case 0x06:                  /* reset */
 966        retval = 0xff;
 967        break;
 968
 969    case 0x0a:                  /* read data */
 970        if (s->out_data_len) {
 971            retval = s->out_data[--s->out_data_len];
 972            s->last_read_byte = retval;
 973        }
 974        else {
 975            if (s->cmd != -1) {
 976                dolog ("empty output buffer for command %#x\n",
 977                       s->cmd);
 978            }
 979            retval = s->last_read_byte;
 980            /* goto error; */
 981        }
 982        break;
 983
 984    case 0x0c:                  /* 0 can write */
 985        retval = s->can_write ? 0 : 0x80;
 986        break;
 987
 988    case 0x0d:                  /* timer interrupt clear */
 989        /* dolog ("timer interrupt clear\n"); */
 990        retval = 0;
 991        break;
 992
 993    case 0x0e:                  /* data available status | irq 8 ack */
 994        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
 995        if (s->mixer_regs[0x82] & 1) {
 996            ack = 1;
 997            s->mixer_regs[0x82] &= 1;
 998            qemu_irq_lower (s->pic);
 999        }
1000        break;
1001
1002    case 0x0f:                  /* irq 16 ack */
1003        retval = 0xff;
1004        if (s->mixer_regs[0x82] & 2) {
1005            ack = 1;
1006            s->mixer_regs[0x82] &= 2;
1007            qemu_irq_lower (s->pic);
1008        }
1009        break;
1010
1011    default:
1012        goto error;
1013    }
1014
1015    if (!ack) {
1016        ldebug ("read %#x -> %#x\n", nport, retval);
1017    }
1018
1019    return retval;
1020
1021 error:
1022    dolog ("warning: dsp_read %#x error\n", nport);
1023    return 0xff;
1024}
1025
1026static void reset_mixer (SB16State *s)
1027{
1028    int i;
1029
1030    memset (s->mixer_regs, 0xff, 0x7f);
1031    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1032
1033    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1034    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1035    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1036    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1037
1038    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1039    s->mixer_regs[0x0c] = 0;
1040
1041    /* d5=output filt, d1=stereo switch */
1042    s->mixer_regs[0x0e] = 0;
1043
1044    /* voice volume L d5,d7, R d1,d3 */
1045    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1046    /* master ... */
1047    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1048    /* MIDI ... */
1049    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1050
1051    for (i = 0x30; i < 0x48; i++) {
1052        s->mixer_regs[i] = 0x20;
1053    }
1054}
1055
1056static IO_WRITE_PROTO (mixer_write_indexb)
1057{
1058    SB16State *s = opaque;
1059    (void) nport;
1060    s->mixer_nreg = val;
1061}
1062
1063static IO_WRITE_PROTO (mixer_write_datab)
1064{
1065    SB16State *s = opaque;
1066
1067    (void) nport;
1068    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1069
1070    switch (s->mixer_nreg) {
1071    case 0x00:
1072        reset_mixer (s);
1073        break;
1074
1075    case 0x80:
1076        {
1077            int irq = irq_of_magic (val);
1078            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1079            if (irq > 0) {
1080                s->irq = irq;
1081            }
1082        }
1083        break;
1084
1085    case 0x81:
1086        {
1087            int dma, hdma;
1088
1089            dma = ctz32 (val & 0xf);
1090            hdma = ctz32 (val & 0xf0);
1091            if (dma != s->dma || hdma != s->hdma) {
1092                dolog (
1093                    "attempt to change DMA "
1094                    "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1095                    dma, s->dma, hdma, s->hdma, val);
1096            }
1097#if 0
1098            s->dma = dma;
1099            s->hdma = hdma;
1100#endif
1101        }
1102        break;
1103
1104    case 0x82:
1105        dolog ("attempt to write into IRQ status register (val=%#x)\n",
1106               val);
1107        return;
1108
1109    default:
1110        if (s->mixer_nreg >= 0x80) {
1111            ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1112        }
1113        break;
1114    }
1115
1116    s->mixer_regs[s->mixer_nreg] = val;
1117}
1118
1119static IO_WRITE_PROTO (mixer_write_indexw)
1120{
1121    mixer_write_indexb (opaque, nport, val & 0xff);
1122    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1123}
1124
1125static IO_READ_PROTO (mixer_read)
1126{
1127    SB16State *s = opaque;
1128
1129    (void) nport;
1130#ifndef DEBUG_SB16_MOST
1131    if (s->mixer_nreg != 0x82) {
1132        ldebug ("mixer_read[%#x] -> %#x\n",
1133                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1134    }
1135#else
1136    ldebug ("mixer_read[%#x] -> %#x\n",
1137            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1138#endif
1139    return s->mixer_regs[s->mixer_nreg];
1140}
1141
1142static int write_audio (SB16State *s, int nchan, int dma_pos,
1143                        int dma_len, int len)
1144{
1145    int temp, net;
1146    uint8_t tmpbuf[4096];
1147
1148    temp = len;
1149    net = 0;
1150
1151    while (temp) {
1152        int left = dma_len - dma_pos;
1153        int copied;
1154        size_t to_copy;
1155
1156        to_copy = audio_MIN (temp, left);
1157        if (to_copy > sizeof (tmpbuf)) {
1158            to_copy = sizeof (tmpbuf);
1159        }
1160
1161        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1162        copied = AUD_write (s->voice, tmpbuf, copied);
1163
1164        temp -= copied;
1165        dma_pos = (dma_pos + copied) % dma_len;
1166        net += copied;
1167
1168        if (!copied) {
1169            break;
1170        }
1171    }
1172
1173    return net;
1174}
1175
1176static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1177{
1178    SB16State *s = opaque;
1179    int till, copy, written, free;
1180
1181    if (s->block_size <= 0) {
1182        dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1183               s->block_size, nchan, dma_pos, dma_len);
1184        return dma_pos;
1185    }
1186
1187    if (s->left_till_irq < 0) {
1188        s->left_till_irq = s->block_size;
1189    }
1190
1191    if (s->voice) {
1192        free = s->audio_free & ~s->align;
1193        if ((free <= 0) || !dma_len) {
1194            return dma_pos;
1195        }
1196    }
1197    else {
1198        free = dma_len;
1199    }
1200
1201    copy = free;
1202    till = s->left_till_irq;
1203
1204#ifdef DEBUG_SB16_MOST
1205    dolog ("pos:%06d %d till:%d len:%d\n",
1206           dma_pos, free, till, dma_len);
1207#endif
1208
1209    if (till <= copy) {
1210        if (0 == s->dma_auto) {
1211            copy = till;
1212        }
1213    }
1214
1215    written = write_audio (s, nchan, dma_pos, dma_len, copy);
1216    dma_pos = (dma_pos + written) % dma_len;
1217    s->left_till_irq -= written;
1218
1219    if (s->left_till_irq <= 0) {
1220        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1221        qemu_irq_raise (s->pic);
1222        if (0 == s->dma_auto) {
1223            control (s, 0);
1224            speaker (s, 0);
1225        }
1226    }
1227
1228#ifdef DEBUG_SB16_MOST
1229    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1230            dma_pos, free, dma_len, s->left_till_irq, copy, written,
1231            s->block_size);
1232#endif
1233
1234    while (s->left_till_irq <= 0) {
1235        s->left_till_irq = s->block_size + s->left_till_irq;
1236    }
1237
1238    return dma_pos;
1239}
1240
1241static void SB_audio_callback (void *opaque, int free)
1242{
1243    SB16State *s = opaque;
1244    s->audio_free = free;
1245}
1246
1247static int sb16_post_load (void *opaque, int version_id)
1248{
1249    SB16State *s = opaque;
1250
1251    if (s->voice) {
1252        AUD_close_out (&s->card, s->voice);
1253        s->voice = NULL;
1254    }
1255
1256    if (s->dma_running) {
1257        if (s->freq) {
1258            struct audsettings as;
1259
1260            s->audio_free = 0;
1261
1262            as.freq = s->freq;
1263            as.nchannels = 1 << s->fmt_stereo;
1264            as.fmt = s->fmt;
1265            as.endianness = 0;
1266
1267            s->voice = AUD_open_out (
1268                &s->card,
1269                s->voice,
1270                "sb16",
1271                s,
1272                SB_audio_callback,
1273                &as
1274                );
1275        }
1276
1277        control (s, 1);
1278        speaker (s, s->speaker);
1279    }
1280    return 0;
1281}
1282
1283static const VMStateDescription vmstate_sb16 = {
1284    .name = "sb16",
1285    .version_id = 1,
1286    .minimum_version_id = 1,
1287    .minimum_version_id_old = 1,
1288    .post_load = sb16_post_load,
1289    .fields      = (VMStateField []) {
1290        VMSTATE_UINT32(irq, SB16State),
1291        VMSTATE_UINT32(dma, SB16State),
1292        VMSTATE_UINT32(hdma, SB16State),
1293        VMSTATE_UINT32(port, SB16State),
1294        VMSTATE_UINT32(ver, SB16State),
1295        VMSTATE_INT32(in_index, SB16State),
1296        VMSTATE_INT32(out_data_len, SB16State),
1297        VMSTATE_INT32(fmt_stereo, SB16State),
1298        VMSTATE_INT32(fmt_signed, SB16State),
1299        VMSTATE_INT32(fmt_bits, SB16State),
1300        VMSTATE_UINT32(fmt, SB16State),
1301        VMSTATE_INT32(dma_auto, SB16State),
1302        VMSTATE_INT32(block_size, SB16State),
1303        VMSTATE_INT32(fifo, SB16State),
1304        VMSTATE_INT32(freq, SB16State),
1305        VMSTATE_INT32(time_const, SB16State),
1306        VMSTATE_INT32(speaker, SB16State),
1307        VMSTATE_INT32(needed_bytes, SB16State),
1308        VMSTATE_INT32(cmd, SB16State),
1309        VMSTATE_INT32(use_hdma, SB16State),
1310        VMSTATE_INT32(highspeed, SB16State),
1311        VMSTATE_INT32(can_write, SB16State),
1312        VMSTATE_INT32(v2x6, SB16State),
1313
1314        VMSTATE_UINT8(csp_param, SB16State),
1315        VMSTATE_UINT8(csp_value, SB16State),
1316        VMSTATE_UINT8(csp_mode, SB16State),
1317        VMSTATE_UINT8(csp_param, SB16State),
1318        VMSTATE_BUFFER(csp_regs, SB16State),
1319        VMSTATE_UINT8(csp_index, SB16State),
1320        VMSTATE_BUFFER(csp_reg83, SB16State),
1321        VMSTATE_INT32(csp_reg83r, SB16State),
1322        VMSTATE_INT32(csp_reg83w, SB16State),
1323
1324        VMSTATE_BUFFER(in2_data, SB16State),
1325        VMSTATE_BUFFER(out_data, SB16State),
1326        VMSTATE_UINT8(test_reg, SB16State),
1327        VMSTATE_UINT8(last_read_byte, SB16State),
1328
1329        VMSTATE_INT32(nzero, SB16State),
1330        VMSTATE_INT32(left_till_irq, SB16State),
1331        VMSTATE_INT32(dma_running, SB16State),
1332        VMSTATE_INT32(bytes_per_second, SB16State),
1333        VMSTATE_INT32(align, SB16State),
1334
1335        VMSTATE_INT32(mixer_nreg, SB16State),
1336        VMSTATE_BUFFER(mixer_regs, SB16State),
1337
1338        VMSTATE_END_OF_LIST()
1339    }
1340};
1341
1342static int sb16_initfn (ISADevice *dev)
1343{
1344    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1345    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1346    SB16State *s;
1347    int i;
1348
1349    s = DO_UPCAST (SB16State, dev, dev);
1350
1351    s->cmd = -1;
1352    isa_init_irq (dev, &s->pic, s->irq);
1353
1354    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1355    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1356    s->mixer_regs[0x82] = 2 << 5;
1357
1358    s->csp_regs[5] = 1;
1359    s->csp_regs[9] = 0xf8;
1360
1361    reset_mixer (s);
1362    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1363    if (!s->aux_ts) {
1364        dolog ("warning: Could not create auxiliary timer\n");
1365    }
1366
1367    for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) {
1368        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1369    }
1370
1371    for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
1372        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1373    }
1374
1375    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1376    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1377    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1378    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
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 (qemu_irq *pic)
1389{
1390    isa_create_simple ("sb16");
1391    return 0;
1392}
1393
1394static ISADeviceInfo sb16_info = {
1395    .qdev.name     = "sb16",
1396    .qdev.desc     = "Creative Sound Blaster 16",
1397    .qdev.size     = sizeof (SB16State),
1398    .qdev.vmsd     = &vmstate_sb16,
1399    .init          = sb16_initfn,
1400    .qdev.props    = (Property[]) {
1401        DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
1402        DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
1403        DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
1404        DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
1405        DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
1406        DEFINE_PROP_END_OF_LIST (),
1407    },
1408};
1409
1410static void sb16_register (void)
1411{
1412    isa_qdev_register (&sb16_info);
1413}
1414device_init (sb16_register)
1415