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