Statistics
| Branch: | Revision:

root / hw / sb16.c @ feea13e1

History | View | Annotate | Download (35.7 kB)

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 "vl.h"
25

    
26
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
27

    
28
#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
29

    
30
/* #define DEBUG */
31
/* #define DEBUG_SB16_MOST */
32

    
33
#ifdef DEBUG
34
#define ldebug(...) dolog (__VA_ARGS__)
35
#else
36
#define ldebug(...)
37
#endif
38

    
39
#define IO_READ_PROTO(name)                             \
40
    uint32_t name (void *opaque, uint32_t nport)
41
#define IO_WRITE_PROTO(name)                                    \
42
    void name (void *opaque, uint32_t nport, uint32_t val)
43

    
44
static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
45

    
46
static struct {
47
    int ver_lo;
48
    int ver_hi;
49
    int irq;
50
    int dma;
51
    int hdma;
52
    int port;
53
} conf = {5, 4, 5, 1, 5, 0x220};
54

    
55
typedef struct SB16State {
56
    QEMUSoundCard card;
57
    int irq;
58
    int dma;
59
    int hdma;
60
    int port;
61
    int ver;
62

    
63
    int in_index;
64
    int out_data_len;
65
    int fmt_stereo;
66
    int fmt_signed;
67
    int fmt_bits;
68
    audfmt_e fmt;
69
    int dma_auto;
70
    int block_size;
71
    int fifo;
72
    int freq;
73
    int time_const;
74
    int speaker;
75
    int needed_bytes;
76
    int cmd;
77
    int use_hdma;
78
    int highspeed;
79
    int can_write;
80

    
81
    int v2x6;
82

    
83
    uint8_t csp_param;
84
    uint8_t csp_value;
85
    uint8_t csp_mode;
86
    uint8_t csp_regs[256];
87
    uint8_t csp_index;
88
    uint8_t csp_reg83[4];
89
    int csp_reg83r;
90
    int csp_reg83w;
91

    
92
    uint8_t in2_data[10];
93
    uint8_t out_data[50];
94
    uint8_t test_reg;
95
    uint8_t last_read_byte;
96
    int nzero;
97

    
98
    int left_till_irq;
99

    
100
    int dma_running;
101
    int bytes_per_second;
102
    int align;
103
    int audio_free;
104
    SWVoiceOut *voice;
105

    
106
    QEMUTimer *aux_ts;
107
    /* mixer state */
108
    int mixer_nreg;
109
    uint8_t mixer_regs[256];
110
} SB16State;
111

    
112
static void SB_audio_callback (void *opaque, int free);
113

    
114
static int magic_of_irq (int irq)
115
{
116
    switch (irq) {
117
    case 5:
118
        return 2;
119
    case 7:
120
        return 4;
121
    case 9:
122
        return 1;
123
    case 10:
124
        return 8;
125
    default:
126
        dolog ("bad irq %d\n", irq);
127
        return 2;
128
    }
129
}
130

    
131
static int irq_of_magic (int magic)
132
{
133
    switch (magic) {
134
    case 1:
135
        return 9;
136
    case 2:
137
        return 5;
138
    case 4:
139
        return 7;
140
    case 8:
141
        return 10;
142
    default:
143
        dolog ("bad irq magic %d\n", magic);
144
        return -1;
145
    }
146
}
147

    
148
#if 0
149
static void log_dsp (SB16State *dsp)
150
{
151
    ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
152
            dsp->fmt_stereo ? "Stereo" : "Mono",
153
            dsp->fmt_signed ? "Signed" : "Unsigned",
154
            dsp->fmt_bits,
155
            dsp->dma_auto ? "Auto" : "Single",
156
            dsp->block_size,
157
            dsp->freq,
158
            dsp->time_const,
159
            dsp->speaker);
160
}
161
#endif
162

    
163
static void speaker (SB16State *s, int on)
164
{
165
    s->speaker = on;
166
    /* AUD_enable (s->voice, on); */
167
}
168

    
169
static void control (SB16State *s, int hold)
170
{
171
    int dma = s->use_hdma ? s->hdma : s->dma;
172
    s->dma_running = hold;
173

    
174
    ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
175

    
176
    if (hold) {
177
        DMA_hold_DREQ (dma);
178
        AUD_set_active_out (s->voice, 1);
179
    }
180
    else {
181
        DMA_release_DREQ (dma);
182
        AUD_set_active_out (s->voice, 0);
183
    }
184
}
185

    
186
static void aux_timer (void *opaque)
187
{
188
    SB16State *s = opaque;
189
    s->can_write = 1;
190
    pic_set_irq (s->irq, 1);
191
}
192

    
193
#define DMA8_AUTO 1
194
#define DMA8_HIGH 2
195

    
196
static void continue_dma8 (SB16State *s)
197
{
198
    if (s->freq > 0) {
199
        audsettings_t as;
200

    
201
        s->audio_free = 0;
202

    
203
        as.freq = s->freq;
204
        as.nchannels = 1 << s->fmt_stereo;
205
        as.fmt = s->fmt;
206

    
207
        s->voice = AUD_open_out (
208
            &s->card,
209
            s->voice,
210
            "sb16",
211
            s,
212
            SB_audio_callback,
213
            &as,
214
            0                   /* little endian */
215
            );
216
    }
217

    
218
    control (s, 1);
219
}
220

    
221
static void dma_cmd8 (SB16State *s, int mask, int dma_len)
222
{
223
    s->fmt = AUD_FMT_U8;
224
    s->use_hdma = 0;
225
    s->fmt_bits = 8;
226
    s->fmt_signed = 0;
227
    s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
228
    if (-1 == s->time_const) {
229
        if (s->freq <= 0)
230
            s->freq = 11025;
231
    }
232
    else {
233
        int tmp = (256 - s->time_const);
234
        s->freq = (1000000 + (tmp / 2)) / tmp;
235
    }
236

    
237
    if (dma_len != -1) {
238
        s->block_size = dma_len << s->fmt_stereo;
239
    }
240
    else {
241
        /* This is apparently the only way to make both Act1/PL
242
           and SecondReality/FC work
243

244
           Act1 sets block size via command 0x48 and it's an odd number
245
           SR does the same with even number
246
           Both use stereo, and Creatives own documentation states that
247
           0x48 sets block size in bytes less one.. go figure */
248
        s->block_size &= ~s->fmt_stereo;
249
    }
250

    
251
    s->freq >>= s->fmt_stereo;
252
    s->left_till_irq = s->block_size;
253
    s->bytes_per_second = (s->freq << s->fmt_stereo);
254
    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
255
    s->dma_auto = (mask & DMA8_AUTO) != 0;
256
    s->align = (1 << s->fmt_stereo) - 1;
257

    
258
    if (s->block_size & s->align) {
259
        dolog ("warning: misaligned block size %d, alignment %d\n",
260
               s->block_size, s->align + 1);
261
    }
262

    
263
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
264
            "dma %d, auto %d, fifo %d, high %d\n",
265
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
266
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
267

    
268
    continue_dma8 (s);
269
    speaker (s, 1);
270
}
271

    
272
static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
273
{
274
    s->use_hdma = cmd < 0xc0;
275
    s->fifo = (cmd >> 1) & 1;
276
    s->dma_auto = (cmd >> 2) & 1;
277
    s->fmt_signed = (d0 >> 4) & 1;
278
    s->fmt_stereo = (d0 >> 5) & 1;
279

    
280
    switch (cmd >> 4) {
281
    case 11:
282
        s->fmt_bits = 16;
283
        break;
284

    
285
    case 12:
286
        s->fmt_bits = 8;
287
        break;
288
    }
289

    
290
    if (-1 != s->time_const) {
291
#if 1
292
        int tmp = 256 - s->time_const;
293
        s->freq = (1000000 + (tmp / 2)) / tmp;
294
#else
295
        /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
296
        s->freq = 1000000 / ((255 - s->time_const));
297
#endif
298
        s->time_const = -1;
299
    }
300

    
301
    s->block_size = dma_len + 1;
302
    s->block_size <<= (s->fmt_bits == 16);
303
    if (!s->dma_auto) {
304
        /* It is clear that for DOOM and auto-init this value
305
           shouldn't take stereo into account, while Miles Sound Systems
306
           setsound.exe with single transfer mode wouldn't work without it
307
           wonders of SB16 yet again */
308
        s->block_size <<= s->fmt_stereo;
309
    }
310

    
311
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
312
            "dma %d, auto %d, fifo %d, high %d\n",
313
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
314
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
315

    
316
    if (16 == s->fmt_bits) {
317
        if (s->fmt_signed) {
318
            s->fmt = AUD_FMT_S16;
319
        }
320
        else {
321
            s->fmt = AUD_FMT_U16;
322
        }
323
    }
324
    else {
325
        if (s->fmt_signed) {
326
            s->fmt = AUD_FMT_S8;
327
        }
328
        else {
329
            s->fmt = AUD_FMT_U8;
330
        }
331
    }
332

    
333
    s->left_till_irq = s->block_size;
334

    
335
    s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
336
    s->highspeed = 0;
337
    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
338
    if (s->block_size & s->align) {
339
        dolog ("warning: misaligned block size %d, alignment %d\n",
340
               s->block_size, s->align + 1);
341
    }
342

    
343
    if (s->freq) {
344
        audsettings_t as;
345

    
346
        s->audio_free = 0;
347

    
348
        as.freq = s->freq;
349
        as.nchannels = 1 << s->fmt_stereo;
350
        as.fmt = s->fmt;
351

    
352
        s->voice = AUD_open_out (
353
            &s->card,
354
            s->voice,
355
            "sb16",
356
            s,
357
            SB_audio_callback,
358
            &as,
359
            0                   /* little endian */
360
            );
361
    }
362

    
363
    control (s, 1);
364
    speaker (s, 1);
365
}
366

    
367
static inline void dsp_out_data (SB16State *s, uint8_t val)
368
{
369
    ldebug ("outdata %#x\n", val);
370
    if ((size_t) s->out_data_len < sizeof (s->out_data)) {
371
        s->out_data[s->out_data_len++] = val;
372
    }
373
}
374

    
375
static inline uint8_t dsp_get_data (SB16State *s)
376
{
377
    if (s->in_index) {
378
        return s->in2_data[--s->in_index];
379
    }
380
    else {
381
        dolog ("buffer underflow\n");
382
        return 0;
383
    }
384
}
385

    
386
static void command (SB16State *s, uint8_t cmd)
387
{
388
    ldebug ("command %#x\n", cmd);
389

    
390
    if (cmd > 0xaf && cmd < 0xd0) {
391
        if (cmd & 8) {
392
            dolog ("ADC not yet supported (command %#x)\n", cmd);
393
        }
394

    
395
        switch (cmd >> 4) {
396
        case 11:
397
        case 12:
398
            break;
399
        default:
400
            dolog ("%#x wrong bits\n", cmd);
401
        }
402
        s->needed_bytes = 3;
403
    }
404
    else {
405
        s->needed_bytes = 0;
406

    
407
        switch (cmd) {
408
        case 0x03:
409
            dsp_out_data (s, 0x10); /* s->csp_param); */
410
            goto warn;
411

    
412
        case 0x04:
413
            s->needed_bytes = 1;
414
            goto warn;
415

    
416
        case 0x05:
417
            s->needed_bytes = 2;
418
            goto warn;
419

    
420
        case 0x08:
421
            /* __asm__ ("int3"); */
422
            goto warn;
423

    
424
        case 0x0e:
425
            s->needed_bytes = 2;
426
            goto warn;
427

    
428
        case 0x09:
429
            dsp_out_data (s, 0xf8);
430
            goto warn;
431

    
432
        case 0x0f:
433
            s->needed_bytes = 1;
434
            goto warn;
435

    
436
        case 0x10:
437
            s->needed_bytes = 1;
438
            goto warn;
439

    
440
        case 0x14:
441
            s->needed_bytes = 2;
442
            s->block_size = 0;
443
            break;
444

    
445
        case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
446
            dma_cmd8 (s, DMA8_AUTO, -1);
447
            break;
448

    
449
        case 0x20:              /* Direct ADC, Juice/PL */
450
            dsp_out_data (s, 0xff);
451
            goto warn;
452

    
453
        case 0x35:
454
            dolog ("0x35 - MIDI command not implemented\n");
455
            break;
456

    
457
        case 0x40:
458
            s->freq = -1;
459
            s->time_const = -1;
460
            s->needed_bytes = 1;
461
            break;
462

    
463
        case 0x41:
464
            s->freq = -1;
465
            s->time_const = -1;
466
            s->needed_bytes = 2;
467
            break;
468

    
469
        case 0x42:
470
            s->freq = -1;
471
            s->time_const = -1;
472
            s->needed_bytes = 2;
473
            goto warn;
474

    
475
        case 0x45:
476
            dsp_out_data (s, 0xaa);
477
            goto warn;
478

    
479
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
480
            break;
481

    
482
        case 0x48:
483
            s->needed_bytes = 2;
484
            break;
485

    
486
        case 0x74:
487
            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
488
            dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
489
            break;
490

    
491
        case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
492
            s->needed_bytes = 2;
493
            dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
494
            break;
495

    
496
        case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
497
            s->needed_bytes = 2;
498
            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
499
            break;
500

    
501
        case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
502
            s->needed_bytes = 2;
503
            dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
504
            break;
505

    
506
        case 0x7d:
507
            dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
508
            dolog ("not implemented\n");
509
            break;
510

    
511
        case 0x7f:
512
            dolog (
513
                "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
514
                );
515
            dolog ("not implemented\n");
516
            break;
517

    
518
        case 0x80:
519
            s->needed_bytes = 2;
520
            break;
521

    
522
        case 0x90:
523
        case 0x91:
524
            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
525
            break;
526

    
527
        case 0xd0:              /* halt DMA operation. 8bit */
528
            control (s, 0);
529
            break;
530

    
531
        case 0xd1:              /* speaker on */
532
            speaker (s, 1);
533
            break;
534

    
535
        case 0xd3:              /* speaker off */
536
            speaker (s, 0);
537
            break;
538

    
539
        case 0xd4:              /* continue DMA operation. 8bit */
540
            /* KQ6 (or maybe Sierras audblst.drv in general) resets
541
               the frequency between halt/continue */
542
            continue_dma8 (s);
543
            break;
544

    
545
        case 0xd5:              /* halt DMA operation. 16bit */
546
            control (s, 0);
547
            break;
548

    
549
        case 0xd6:              /* continue DMA operation. 16bit */
550
            control (s, 1);
551
            break;
552

    
553
        case 0xd9:              /* exit auto-init DMA after this block. 16bit */
554
            s->dma_auto = 0;
555
            break;
556

    
557
        case 0xda:              /* exit auto-init DMA after this block. 8bit */
558
            s->dma_auto = 0;
559
            break;
560

    
561
        case 0xe0:              /* DSP identification */
562
            s->needed_bytes = 1;
563
            break;
564

    
565
        case 0xe1:
566
            dsp_out_data (s, s->ver & 0xff);
567
            dsp_out_data (s, s->ver >> 8);
568
            break;
569

    
570
        case 0xe2:
571
            s->needed_bytes = 1;
572
            goto warn;
573

    
574
        case 0xe3:
575
            {
576
                int i;
577
                for (i = sizeof (e3) - 1; i >= 0; --i)
578
                    dsp_out_data (s, e3[i]);
579
            }
580
            break;
581

    
582
        case 0xe4:              /* write test reg */
583
            s->needed_bytes = 1;
584
            break;
585

    
586
        case 0xe7:
587
            dolog ("Attempt to probe for ESS (0xe7)?\n");
588
            break;
589

    
590
        case 0xe8:              /* read test reg */
591
            dsp_out_data (s, s->test_reg);
592
            break;
593

    
594
        case 0xf2:
595
        case 0xf3:
596
            dsp_out_data (s, 0xaa);
597
            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
598
            pic_set_irq (s->irq, 1);
599
            break;
600

    
601
        case 0xf9:
602
            s->needed_bytes = 1;
603
            goto warn;
604

    
605
        case 0xfa:
606
            dsp_out_data (s, 0);
607
            goto warn;
608

    
609
        case 0xfc:              /* FIXME */
610
            dsp_out_data (s, 0);
611
            goto warn;
612

    
613
        default:
614
            dolog ("Unrecognized command %#x\n", cmd);
615
            break;
616
        }
617
    }
618

    
619
    if (!s->needed_bytes) {
620
        ldebug ("\n");
621
    }
622

    
623
 exit:
624
    if (!s->needed_bytes) {
625
        s->cmd = -1;
626
    }
627
    else {
628
        s->cmd = cmd;
629
    }
630
    return;
631

    
632
 warn:
633
    dolog ("warning: command %#x,%d is not truly understood yet\n",
634
           cmd, s->needed_bytes);
635
    goto exit;
636

    
637
}
638

    
639
static uint16_t dsp_get_lohi (SB16State *s)
640
{
641
    uint8_t hi = dsp_get_data (s);
642
    uint8_t lo = dsp_get_data (s);
643
    return (hi << 8) | lo;
644
}
645

    
646
static uint16_t dsp_get_hilo (SB16State *s)
647
{
648
    uint8_t lo = dsp_get_data (s);
649
    uint8_t hi = dsp_get_data (s);
650
    return (hi << 8) | lo;
651
}
652

    
653
static void complete (SB16State *s)
654
{
655
    int d0, d1, d2;
656
    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
657
            s->cmd, s->in_index, s->needed_bytes);
658

    
659
    if (s->cmd > 0xaf && s->cmd < 0xd0) {
660
        d2 = dsp_get_data (s);
661
        d1 = dsp_get_data (s);
662
        d0 = dsp_get_data (s);
663

    
664
        if (s->cmd & 8) {
665
            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
666
                   s->cmd, d0, d1, d2);
667
        }
668
        else {
669
            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
670
                    s->cmd, d0, d1, d2);
671
            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
672
        }
673
    }
674
    else {
675
        switch (s->cmd) {
676
        case 0x04:
677
            s->csp_mode = dsp_get_data (s);
678
            s->csp_reg83r = 0;
679
            s->csp_reg83w = 0;
680
            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
681
            break;
682

    
683
        case 0x05:
684
            s->csp_param = dsp_get_data (s);
685
            s->csp_value = dsp_get_data (s);
686
            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
687
                    s->csp_param,
688
                    s->csp_value);
689
            break;
690

    
691
        case 0x0e:
692
            d0 = dsp_get_data (s);
693
            d1 = dsp_get_data (s);
694
            ldebug ("write CSP register %d <- %#x\n", d1, d0);
695
            if (d1 == 0x83) {
696
                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
697
                s->csp_reg83[s->csp_reg83r % 4] = d0;
698
                s->csp_reg83r += 1;
699
            }
700
            else {
701
                s->csp_regs[d1] = d0;
702
            }
703
            break;
704

    
705
        case 0x0f:
706
            d0 = dsp_get_data (s);
707
            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
708
                    d0, s->csp_regs[d0], s->csp_mode);
709
            if (d0 == 0x83) {
710
                ldebug ("0x83[%d] -> %#x\n",
711
                        s->csp_reg83w,
712
                        s->csp_reg83[s->csp_reg83w % 4]);
713
                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
714
                s->csp_reg83w += 1;
715
            }
716
            else {
717
                dsp_out_data (s, s->csp_regs[d0]);
718
            }
719
            break;
720

    
721
        case 0x10:
722
            d0 = dsp_get_data (s);
723
            dolog ("cmd 0x10 d0=%#x\n", d0);
724
            break;
725

    
726
        case 0x14:
727
            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
728
            break;
729

    
730
        case 0x40:
731
            s->time_const = dsp_get_data (s);
732
            ldebug ("set time const %d\n", s->time_const);
733
            break;
734

    
735
        case 0x42:              /* FT2 sets output freq with this, go figure */
736
#if 0
737
            dolog ("cmd 0x42 might not do what it think it should\n");
738
#endif
739
        case 0x41:
740
            s->freq = dsp_get_hilo (s);
741
            ldebug ("set freq %d\n", s->freq);
742
            break;
743

    
744
        case 0x48:
745
            s->block_size = dsp_get_lohi (s) + 1;
746
            ldebug ("set dma block len %d\n", s->block_size);
747
            break;
748

    
749
        case 0x74:
750
        case 0x75:
751
        case 0x76:
752
        case 0x77:
753
            /* ADPCM stuff, ignore */
754
            break;
755

    
756
        case 0x80:
757
            {
758
                int freq, samples, bytes;
759
                int64_t ticks;
760

    
761
                freq = s->freq > 0 ? s->freq : 11025;
762
                samples = dsp_get_lohi (s) + 1;
763
                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
764
                ticks = (bytes * ticks_per_sec) / freq;
765
                if (ticks < ticks_per_sec / 1024) {
766
                    pic_set_irq (s->irq, 1);
767
                }
768
                else {
769
                    if (s->aux_ts) {
770
                        qemu_mod_timer (
771
                            s->aux_ts,
772
                            qemu_get_clock (vm_clock) + ticks
773
                            );
774
                    }
775
                }
776
                ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
777
            }
778
            break;
779

    
780
        case 0xe0:
781
            d0 = dsp_get_data (s);
782
            s->out_data_len = 0;
783
            ldebug ("E0 data = %#x\n", d0);
784
            dsp_out_data (s, ~d0);
785
            break;
786

    
787
        case 0xe2:
788
            d0 = dsp_get_data (s);
789
            ldebug ("E2 = %#x\n", d0);
790
            break;
791

    
792
        case 0xe4:
793
            s->test_reg = dsp_get_data (s);
794
            break;
795

    
796
        case 0xf9:
797
            d0 = dsp_get_data (s);
798
            ldebug ("command 0xf9 with %#x\n", d0);
799
            switch (d0) {
800
            case 0x0e:
801
                dsp_out_data (s, 0xff);
802
                break;
803

    
804
            case 0x0f:
805
                dsp_out_data (s, 0x07);
806
                break;
807

    
808
            case 0x37:
809
                dsp_out_data (s, 0x38);
810
                break;
811

    
812
            default:
813
                dsp_out_data (s, 0x00);
814
                break;
815
            }
816
            break;
817

    
818
        default:
819
            dolog ("complete: unrecognized command %#x\n", s->cmd);
820
            return;
821
        }
822
    }
823

    
824
    ldebug ("\n");
825
    s->cmd = -1;
826
    return;
827
}
828

    
829
static void legacy_reset (SB16State *s)
830
{
831
    audsettings_t as;
832

    
833
    s->freq = 11025;
834
    s->fmt_signed = 0;
835
    s->fmt_bits = 8;
836
    s->fmt_stereo = 0;
837

    
838
    as.freq = s->freq;
839
    as.nchannels = 1;
840
    as.fmt = AUD_FMT_U8;
841

    
842
    s->voice = AUD_open_out (
843
        &s->card,
844
        s->voice,
845
        "sb16",
846
        s,
847
        SB_audio_callback,
848
        &as,
849
        0                   /* little endian */
850
        );
851

    
852
    /* Not sure about that... */
853
    /* AUD_set_active_out (s->voice, 1); */
854
}
855

    
856
static void reset (SB16State *s)
857
{
858
    pic_set_irq (s->irq, 0);
859
    if (s->dma_auto) {
860
        pic_set_irq (s->irq, 1);
861
        pic_set_irq (s->irq, 0);
862
    }
863

    
864
    s->mixer_regs[0x82] = 0;
865
    s->dma_auto = 0;
866
    s->in_index = 0;
867
    s->out_data_len = 0;
868
    s->left_till_irq = 0;
869
    s->needed_bytes = 0;
870
    s->block_size = -1;
871
    s->nzero = 0;
872
    s->highspeed = 0;
873
    s->v2x6 = 0;
874
    s->cmd = -1;
875

    
876
    dsp_out_data(s, 0xaa);
877
    speaker (s, 0);
878
    control (s, 0);
879
    legacy_reset (s);
880
}
881

    
882
static IO_WRITE_PROTO (dsp_write)
883
{
884
    SB16State *s = opaque;
885
    int iport;
886

    
887
    iport = nport - s->port;
888

    
889
    ldebug ("write %#x <- %#x\n", nport, val);
890
    switch (iport) {
891
    case 0x06:
892
        switch (val) {
893
        case 0x00:
894
            if (s->v2x6 == 1) {
895
                if (0 && s->highspeed) {
896
                    s->highspeed = 0;
897
                    pic_set_irq (s->irq, 0);
898
                    control (s, 0);
899
                }
900
                else {
901
                    reset (s);
902
                }
903
            }
904
            s->v2x6 = 0;
905
            break;
906

    
907
        case 0x01:
908
        case 0x03:              /* FreeBSD kludge */
909
            s->v2x6 = 1;
910
            break;
911

    
912
        case 0xc6:
913
            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
914
            break;
915

    
916
        case 0xb8:              /* Panic */
917
            reset (s);
918
            break;
919

    
920
        case 0x39:
921
            dsp_out_data (s, 0x38);
922
            reset (s);
923
            s->v2x6 = 0x39;
924
            break;
925

    
926
        default:
927
            s->v2x6 = val;
928
            break;
929
        }
930
        break;
931

    
932
    case 0x0c:                  /* write data or command | write status */
933
/*         if (s->highspeed) */
934
/*             break; */
935

    
936
        if (0 == s->needed_bytes) {
937
            command (s, val);
938
#if 0
939
            if (0 == s->needed_bytes) {
940
                log_dsp (s);
941
            }
942
#endif
943
        }
944
        else {
945
            if (s->in_index == sizeof (s->in2_data)) {
946
                dolog ("in data overrun\n");
947
            }
948
            else {
949
                s->in2_data[s->in_index++] = val;
950
                if (s->in_index == s->needed_bytes) {
951
                    s->needed_bytes = 0;
952
                    complete (s);
953
#if 0
954
                    log_dsp (s);
955
#endif
956
                }
957
            }
958
        }
959
        break;
960

    
961
    default:
962
        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
963
        break;
964
    }
965
}
966

    
967
static IO_READ_PROTO (dsp_read)
968
{
969
    SB16State *s = opaque;
970
    int iport, retval, ack = 0;
971

    
972
    iport = nport - s->port;
973

    
974
    switch (iport) {
975
    case 0x06:                  /* reset */
976
        retval = 0xff;
977
        break;
978

    
979
    case 0x0a:                  /* read data */
980
        if (s->out_data_len) {
981
            retval = s->out_data[--s->out_data_len];
982
            s->last_read_byte = retval;
983
        }
984
        else {
985
            if (s->cmd != -1) {
986
                dolog ("empty output buffer for command %#x\n",
987
                       s->cmd);
988
            }
989
            retval = s->last_read_byte;
990
            /* goto error; */
991
        }
992
        break;
993

    
994
    case 0x0c:                  /* 0 can write */
995
        retval = s->can_write ? 0 : 0x80;
996
        break;
997

    
998
    case 0x0d:                  /* timer interrupt clear */
999
        /* dolog ("timer interrupt clear\n"); */
1000
        retval = 0;
1001
        break;
1002

    
1003
    case 0x0e:                  /* data available status | irq 8 ack */
1004
        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1005
        if (s->mixer_regs[0x82] & 1) {
1006
            ack = 1;
1007
            s->mixer_regs[0x82] &= 1;
1008
            pic_set_irq (s->irq, 0);
1009
        }
1010
        break;
1011

    
1012
    case 0x0f:                  /* irq 16 ack */
1013
        retval = 0xff;
1014
        if (s->mixer_regs[0x82] & 2) {
1015
            ack = 1;
1016
            s->mixer_regs[0x82] &= 2;
1017
            pic_set_irq (s->irq, 0);
1018
        }
1019
        break;
1020

    
1021
    default:
1022
        goto error;
1023
    }
1024

    
1025
    if (!ack) {
1026
        ldebug ("read %#x -> %#x\n", nport, retval);
1027
    }
1028

    
1029
    return retval;
1030

    
1031
 error:
1032
    dolog ("warning: dsp_read %#x error\n", nport);
1033
    return 0xff;
1034
}
1035

    
1036
static void reset_mixer (SB16State *s)
1037
{
1038
    int i;
1039

    
1040
    memset (s->mixer_regs, 0xff, 0x7f);
1041
    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1042

    
1043
    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1044
    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1045
    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1046
    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1047

    
1048
    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1049
    s->mixer_regs[0x0c] = 0;
1050

    
1051
    /* d5=output filt, d1=stereo switch */
1052
    s->mixer_regs[0x0e] = 0;
1053

    
1054
    /* voice volume L d5,d7, R d1,d3 */
1055
    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1056
    /* master ... */
1057
    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1058
    /* MIDI ... */
1059
    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1060

    
1061
    for (i = 0x30; i < 0x48; i++) {
1062
        s->mixer_regs[i] = 0x20;
1063
    }
1064
}
1065

    
1066
static IO_WRITE_PROTO(mixer_write_indexb)
1067
{
1068
    SB16State *s = opaque;
1069
    (void) nport;
1070
    s->mixer_nreg = val;
1071
}
1072

    
1073
static IO_WRITE_PROTO(mixer_write_datab)
1074
{
1075
    SB16State *s = opaque;
1076

    
1077
    (void) nport;
1078
    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1079

    
1080
    switch (s->mixer_nreg) {
1081
    case 0x00:
1082
        reset_mixer (s);
1083
        break;
1084

    
1085
    case 0x80:
1086
        {
1087
            int irq = irq_of_magic (val);
1088
            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1089
            if (irq > 0) {
1090
                s->irq = irq;
1091
            }
1092
        }
1093
        break;
1094

    
1095
    case 0x81:
1096
        {
1097
            int dma, hdma;
1098

    
1099
            dma = lsbindex (val & 0xf);
1100
            hdma = lsbindex (val & 0xf0);
1101
            if (dma != s->dma || hdma != s->hdma) {
1102
                dolog (
1103
                    "attempt to change DMA "
1104
                    "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1105
                    dma, s->dma, hdma, s->hdma, val);
1106
            }
1107
#if 0
1108
            s->dma = dma;
1109
            s->hdma = hdma;
1110
#endif
1111
        }
1112
        break;
1113

    
1114
    case 0x82:
1115
        dolog ("attempt to write into IRQ status register (val=%#x)\n",
1116
               val);
1117
        return;
1118

    
1119
    default:
1120
        if (s->mixer_nreg >= 0x80) {
1121
            ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1122
        }
1123
        break;
1124
    }
1125

    
1126
    s->mixer_regs[s->mixer_nreg] = val;
1127
}
1128

    
1129
static IO_WRITE_PROTO(mixer_write_indexw)
1130
{
1131
    mixer_write_indexb (opaque, nport, val & 0xff);
1132
    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1133
}
1134

    
1135
static IO_READ_PROTO(mixer_read)
1136
{
1137
    SB16State *s = opaque;
1138

    
1139
    (void) nport;
1140
#ifndef DEBUG_SB16_MOST
1141
    if (s->mixer_nreg != 0x82) {
1142
        ldebug ("mixer_read[%#x] -> %#x\n",
1143
                s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1144
    }
1145
#else
1146
    ldebug ("mixer_read[%#x] -> %#x\n",
1147
            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1148
#endif
1149
    return s->mixer_regs[s->mixer_nreg];
1150
}
1151

    
1152
static int write_audio (SB16State *s, int nchan, int dma_pos,
1153
                        int dma_len, int len)
1154
{
1155
    int temp, net;
1156
    uint8_t tmpbuf[4096];
1157

    
1158
    temp = len;
1159
    net = 0;
1160

    
1161
    while (temp) {
1162
        int left = dma_len - dma_pos;
1163
        int copied;
1164
        size_t to_copy;
1165

    
1166
        to_copy = audio_MIN (temp, left);
1167
        if (to_copy > sizeof (tmpbuf)) {
1168
            to_copy = sizeof (tmpbuf);
1169
        }
1170

    
1171
        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1172
        copied = AUD_write (s->voice, tmpbuf, copied);
1173

    
1174
        temp -= copied;
1175
        dma_pos = (dma_pos + copied) % dma_len;
1176
        net += copied;
1177

    
1178
        if (!copied) {
1179
            break;
1180
        }
1181
    }
1182

    
1183
    return net;
1184
}
1185

    
1186
static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1187
{
1188
    SB16State *s = opaque;
1189
    int till, copy, written, free;
1190

    
1191
    if (s->left_till_irq < 0) {
1192
        s->left_till_irq = s->block_size;
1193
    }
1194

    
1195
    if (s->voice) {
1196
        free = s->audio_free & ~s->align;
1197
        if ((free <= 0) || !dma_len) {
1198
            return dma_pos;
1199
        }
1200
    }
1201
    else {
1202
        free = dma_len;
1203
    }
1204

    
1205
    copy = free;
1206
    till = s->left_till_irq;
1207

    
1208
#ifdef DEBUG_SB16_MOST
1209
    dolog ("pos:%06d %d till:%d len:%d\n",
1210
           dma_pos, free, till, dma_len);
1211
#endif
1212

    
1213
    if (till <= copy) {
1214
        if (0 == s->dma_auto) {
1215
            copy = till;
1216
        }
1217
    }
1218

    
1219
    written = write_audio (s, nchan, dma_pos, dma_len, copy);
1220
    dma_pos = (dma_pos + written) % dma_len;
1221
    s->left_till_irq -= written;
1222

    
1223
    if (s->left_till_irq <= 0) {
1224
        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1225
        pic_set_irq (s->irq, 1);
1226
        if (0 == s->dma_auto) {
1227
            control (s, 0);
1228
            speaker (s, 0);
1229
        }
1230
    }
1231

    
1232
#ifdef DEBUG_SB16_MOST
1233
    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1234
            dma_pos, free, dma_len, s->left_till_irq, copy, written,
1235
            s->block_size);
1236
#endif
1237

    
1238
    while (s->left_till_irq <= 0) {
1239
        s->left_till_irq = s->block_size + s->left_till_irq;
1240
    }
1241

    
1242
    return dma_pos;
1243
}
1244

    
1245
static void SB_audio_callback (void *opaque, int free)
1246
{
1247
    SB16State *s = opaque;
1248
    s->audio_free = free;
1249
}
1250

    
1251
static void SB_save (QEMUFile *f, void *opaque)
1252
{
1253
    SB16State *s = opaque;
1254

    
1255
    qemu_put_be32s (f, &s->irq);
1256
    qemu_put_be32s (f, &s->dma);
1257
    qemu_put_be32s (f, &s->hdma);
1258
    qemu_put_be32s (f, &s->port);
1259
    qemu_put_be32s (f, &s->ver);
1260
    qemu_put_be32s (f, &s->in_index);
1261
    qemu_put_be32s (f, &s->out_data_len);
1262
    qemu_put_be32s (f, &s->fmt_stereo);
1263
    qemu_put_be32s (f, &s->fmt_signed);
1264
    qemu_put_be32s (f, &s->fmt_bits);
1265
    qemu_put_be32s (f, &s->fmt);
1266
    qemu_put_be32s (f, &s->dma_auto);
1267
    qemu_put_be32s (f, &s->block_size);
1268
    qemu_put_be32s (f, &s->fifo);
1269
    qemu_put_be32s (f, &s->freq);
1270
    qemu_put_be32s (f, &s->time_const);
1271
    qemu_put_be32s (f, &s->speaker);
1272
    qemu_put_be32s (f, &s->needed_bytes);
1273
    qemu_put_be32s (f, &s->cmd);
1274
    qemu_put_be32s (f, &s->use_hdma);
1275
    qemu_put_be32s (f, &s->highspeed);
1276
    qemu_put_be32s (f, &s->can_write);
1277
    qemu_put_be32s (f, &s->v2x6);
1278

    
1279
    qemu_put_8s (f, &s->csp_param);
1280
    qemu_put_8s (f, &s->csp_value);
1281
    qemu_put_8s (f, &s->csp_mode);
1282
    qemu_put_8s (f, &s->csp_param);
1283
    qemu_put_buffer (f, s->csp_regs, 256);
1284
    qemu_put_8s (f, &s->csp_index);
1285
    qemu_put_buffer (f, s->csp_reg83, 4);
1286
    qemu_put_be32s (f, &s->csp_reg83r);
1287
    qemu_put_be32s (f, &s->csp_reg83w);
1288

    
1289
    qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1290
    qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1291
    qemu_put_8s (f, &s->test_reg);
1292
    qemu_put_8s (f, &s->last_read_byte);
1293

    
1294
    qemu_put_be32s (f, &s->nzero);
1295
    qemu_put_be32s (f, &s->left_till_irq);
1296
    qemu_put_be32s (f, &s->dma_running);
1297
    qemu_put_be32s (f, &s->bytes_per_second);
1298
    qemu_put_be32s (f, &s->align);
1299

    
1300
    qemu_put_be32s (f, &s->mixer_nreg);
1301
    qemu_put_buffer (f, s->mixer_regs, 256);
1302
}
1303

    
1304
static int SB_load (QEMUFile *f, void *opaque, int version_id)
1305
{
1306
    SB16State *s = opaque;
1307

    
1308
    if (version_id != 1) {
1309
        return -EINVAL;
1310
    }
1311

    
1312
    qemu_get_be32s (f, &s->irq);
1313
    qemu_get_be32s (f, &s->dma);
1314
    qemu_get_be32s (f, &s->hdma);
1315
    qemu_get_be32s (f, &s->port);
1316
    qemu_get_be32s (f, &s->ver);
1317
    qemu_get_be32s (f, &s->in_index);
1318
    qemu_get_be32s (f, &s->out_data_len);
1319
    qemu_get_be32s (f, &s->fmt_stereo);
1320
    qemu_get_be32s (f, &s->fmt_signed);
1321
    qemu_get_be32s (f, &s->fmt_bits);
1322
    qemu_get_be32s (f, &s->fmt);
1323
    qemu_get_be32s (f, &s->dma_auto);
1324
    qemu_get_be32s (f, &s->block_size);
1325
    qemu_get_be32s (f, &s->fifo);
1326
    qemu_get_be32s (f, &s->freq);
1327
    qemu_get_be32s (f, &s->time_const);
1328
    qemu_get_be32s (f, &s->speaker);
1329
    qemu_get_be32s (f, &s->needed_bytes);
1330
    qemu_get_be32s (f, &s->cmd);
1331
    qemu_get_be32s (f, &s->use_hdma);
1332
    qemu_get_be32s (f, &s->highspeed);
1333
    qemu_get_be32s (f, &s->can_write);
1334
    qemu_get_be32s (f, &s->v2x6);
1335

    
1336
    qemu_get_8s (f, &s->csp_param);
1337
    qemu_get_8s (f, &s->csp_value);
1338
    qemu_get_8s (f, &s->csp_mode);
1339
    qemu_get_8s (f, &s->csp_param);
1340
    qemu_get_buffer (f, s->csp_regs, 256);
1341
    qemu_get_8s (f, &s->csp_index);
1342
    qemu_get_buffer (f, s->csp_reg83, 4);
1343
    qemu_get_be32s (f, &s->csp_reg83r);
1344
    qemu_get_be32s (f, &s->csp_reg83w);
1345

    
1346
    qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1347
    qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1348
    qemu_get_8s (f, &s->test_reg);
1349
    qemu_get_8s (f, &s->last_read_byte);
1350

    
1351
    qemu_get_be32s (f, &s->nzero);
1352
    qemu_get_be32s (f, &s->left_till_irq);
1353
    qemu_get_be32s (f, &s->dma_running);
1354
    qemu_get_be32s (f, &s->bytes_per_second);
1355
    qemu_get_be32s (f, &s->align);
1356

    
1357
    qemu_get_be32s (f, &s->mixer_nreg);
1358
    qemu_get_buffer (f, s->mixer_regs, 256);
1359

    
1360
    if (s->voice) {
1361
        AUD_close_out (&s->card, s->voice);
1362
        s->voice = NULL;
1363
    }
1364

    
1365
    if (s->dma_running) {
1366
        if (s->freq) {
1367
            audsettings_t as;
1368

    
1369
            s->audio_free = 0;
1370

    
1371
            as.freq = s->freq;
1372
            as.nchannels = 1 << s->fmt_stereo;
1373
            as.fmt = s->fmt;
1374

    
1375
            s->voice = AUD_open_out (
1376
                &s->card,
1377
                s->voice,
1378
                "sb16",
1379
                s,
1380
                SB_audio_callback,
1381
                &as,
1382
                0               /* little endian */
1383
                );
1384
        }
1385

    
1386
        control (s, 1);
1387
        speaker (s, s->speaker);
1388
    }
1389
    return 0;
1390
}
1391

    
1392
int SB16_init (AudioState *audio)
1393
{
1394
    SB16State *s;
1395
    int i;
1396
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1397
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1398

    
1399
    if (!audio) {
1400
        dolog ("No audio state\n");
1401
        return -1;
1402
    }
1403

    
1404
    s = qemu_mallocz (sizeof (*s));
1405
    if (!s) {
1406
        dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
1407
               sizeof (*s));
1408
        return -1;
1409
    }
1410

    
1411
    s->cmd = -1;
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 < LENOFA (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 < LENOFA (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 (audio, "sb16", &s->card);
1450
    return 0;
1451
}