Statistics
| Branch: | Revision:

root / hw / sb16.c @ 22d83b14

History | View | Annotate | Download (35.6 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 "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

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

    
48
static 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

    
57
typedef 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

    
115
static void SB_audio_callback (void *opaque, int free);
116

    
117
static 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

    
134
static 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
152
static 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

    
166
static void speaker (SB16State *s, int on)
167
{
168
    s->speaker = on;
169
    /* AUD_enable (s->voice, on); */
170
}
171

    
172
static 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

    
189
static 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

    
199
static 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

    
224
static 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

    
275
static 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

    
370
static 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

    
378
static 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

    
389
static 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

    
642
static 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

    
649
static 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

    
656
static 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

    
832
static 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

    
859
static 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

    
885
static 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

    
970
static 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

    
1039
static 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

    
1069
static IO_WRITE_PROTO(mixer_write_indexb)
1070
{
1071
    SB16State *s = opaque;
1072
    (void) nport;
1073
    s->mixer_nreg = val;
1074
}
1075

    
1076
static 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

    
1132
static 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

    
1138
static 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

    
1155
static 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

    
1189
static 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

    
1254
static void SB_audio_callback (void *opaque, int free)
1255
{
1256
    SB16State *s = opaque;
1257
    s->audio_free = free;
1258
}
1259

    
1260
static 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

    
1313
static 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

    
1401
int SB16_init (qemu_irq *pic)
1402
{
1403
    AudioState *audio = AUD_init();
1404
    SB16State *s;
1405
    int i;
1406
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1407
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1408

    
1409
    s = qemu_mallocz (sizeof (*s));
1410

    
1411
    s->cmd = -1;
1412
    s->pic = pic;
1413
    s->irq = conf.irq;
1414
    s->dma = conf.dma;
1415
    s->hdma = conf.hdma;
1416
    s->port = conf.port;
1417
    s->ver = conf.ver_lo | (conf.ver_hi << 8);
1418

    
1419
    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1420
    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1421
    s->mixer_regs[0x82] = 2 << 5;
1422

    
1423
    s->csp_regs[5] = 1;
1424
    s->csp_regs[9] = 0xf8;
1425

    
1426
    reset_mixer (s);
1427
    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1428
    if (!s->aux_ts) {
1429
        dolog ("warning: Could not create auxiliary timer\n");
1430
    }
1431

    
1432
    for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) {
1433
        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1434
    }
1435

    
1436
    for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
1437
        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1438
    }
1439

    
1440
    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1441
    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1442
    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1443
    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1444

    
1445
    DMA_register_channel (s->hdma, SB_read_DMA, s);
1446
    DMA_register_channel (s->dma, SB_read_DMA, s);
1447
    s->can_write = 1;
1448

    
1449
    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1450
    AUD_register_card (audio, "sb16", &s->card);
1451
    return 0;
1452
}