Statistics
| Branch: | Revision:

root / hw / sb16.c @ 6ee093c9

History | View | Annotate | Download (36.1 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 "qdev.h"
29
#include "qemu-timer.h"
30

    
31
#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
32

    
33
/* #define DEBUG */
34
/* #define DEBUG_SB16_MOST */
35

    
36
#ifdef DEBUG
37
#define ldebug(...) dolog (__VA_ARGS__)
38
#else
39
#define ldebug(...)
40
#endif
41

    
42
#define IO_READ_PROTO(name)                             \
43
    uint32_t name (void *opaque, uint32_t nport)
44
#define IO_WRITE_PROTO(name)                                    \
45
    void name (void *opaque, uint32_t nport, uint32_t val)
46

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

    
49
typedef struct SB16State {
50
    ISADevice dev;
51
    QEMUSoundCard card;
52
    qemu_irq pic;
53
    uint32_t irq;
54
    uint32_t dma;
55
    uint32_t hdma;
56
    uint32_t port;
57
    uint32_t ver;
58

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

    
77
    int v2x6;
78

    
79
    uint8_t csp_param;
80
    uint8_t csp_value;
81
    uint8_t csp_mode;
82
    uint8_t csp_regs[256];
83
    uint8_t csp_index;
84
    uint8_t csp_reg83[4];
85
    int csp_reg83r;
86
    int csp_reg83w;
87

    
88
    uint8_t in2_data[10];
89
    uint8_t out_data[50];
90
    uint8_t test_reg;
91
    uint8_t last_read_byte;
92
    int nzero;
93

    
94
    int left_till_irq;
95

    
96
    int dma_running;
97
    int bytes_per_second;
98
    int align;
99
    int audio_free;
100
    SWVoiceOut *voice;
101

    
102
    QEMUTimer *aux_ts;
103
    /* mixer state */
104
    int mixer_nreg;
105
    uint8_t mixer_regs[256];
106
} SB16State;
107

    
108
static void SB_audio_callback (void *opaque, int free);
109

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

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

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

    
159
static void speaker (SB16State *s, int on)
160
{
161
    s->speaker = on;
162
    /* AUD_enable (s->voice, on); */
163
}
164

    
165
static void control (SB16State *s, int hold)
166
{
167
    int dma = s->use_hdma ? s->hdma : s->dma;
168
    s->dma_running = hold;
169

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

    
172
    if (hold) {
173
        DMA_hold_DREQ (dma);
174
        AUD_set_active_out (s->voice, 1);
175
    }
176
    else {
177
        DMA_release_DREQ (dma);
178
        AUD_set_active_out (s->voice, 0);
179
    }
180
}
181

    
182
static void aux_timer (void *opaque)
183
{
184
    SB16State *s = opaque;
185
    s->can_write = 1;
186
    qemu_irq_raise (s->pic);
187
}
188

    
189
#define DMA8_AUTO 1
190
#define DMA8_HIGH 2
191

    
192
static void continue_dma8 (SB16State *s)
193
{
194
    if (s->freq > 0) {
195
        struct audsettings as;
196

    
197
        s->audio_free = 0;
198

    
199
        as.freq = s->freq;
200
        as.nchannels = 1 << s->fmt_stereo;
201
        as.fmt = s->fmt;
202
        as.endianness = 0;
203

    
204
        s->voice = AUD_open_out (
205
            &s->card,
206
            s->voice,
207
            "sb16",
208
            s,
209
            SB_audio_callback,
210
            &as
211
            );
212
    }
213

    
214
    control (s, 1);
215
}
216

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

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

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

    
247
    s->freq >>= s->fmt_stereo;
248
    s->left_till_irq = s->block_size;
249
    s->bytes_per_second = (s->freq << s->fmt_stereo);
250
    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
251
    s->dma_auto = (mask & DMA8_AUTO) != 0;
252
    s->align = (1 << s->fmt_stereo) - 1;
253

    
254
    if (s->block_size & s->align) {
255
        dolog ("warning: misaligned block size %d, alignment %d\n",
256
               s->block_size, s->align + 1);
257
    }
258

    
259
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
260
            "dma %d, auto %d, fifo %d, high %d\n",
261
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
262
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
263

    
264
    continue_dma8 (s);
265
    speaker (s, 1);
266
}
267

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

    
276
    switch (cmd >> 4) {
277
    case 11:
278
        s->fmt_bits = 16;
279
        break;
280

    
281
    case 12:
282
        s->fmt_bits = 8;
283
        break;
284
    }
285

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

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

    
307
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
308
            "dma %d, auto %d, fifo %d, high %d\n",
309
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
310
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
311

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

    
329
    s->left_till_irq = s->block_size;
330

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

    
339
    if (s->freq) {
340
        struct audsettings as;
341

    
342
        s->audio_free = 0;
343

    
344
        as.freq = s->freq;
345
        as.nchannels = 1 << s->fmt_stereo;
346
        as.fmt = s->fmt;
347
        as.endianness = 0;
348

    
349
        s->voice = AUD_open_out (
350
            &s->card,
351
            s->voice,
352
            "sb16",
353
            s,
354
            SB_audio_callback,
355
            &as
356
            );
357
    }
358

    
359
    control (s, 1);
360
    speaker (s, 1);
361
}
362

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

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

    
382
static void command (SB16State *s, uint8_t cmd)
383
{
384
    ldebug ("command %#x\n", cmd);
385

    
386
    if (cmd > 0xaf && cmd < 0xd0) {
387
        if (cmd & 8) {
388
            dolog ("ADC not yet supported (command %#x)\n", cmd);
389
        }
390

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

    
403
        switch (cmd) {
404
        case 0x03:
405
            dsp_out_data (s, 0x10); /* s->csp_param); */
406
            goto warn;
407

    
408
        case 0x04:
409
            s->needed_bytes = 1;
410
            goto warn;
411

    
412
        case 0x05:
413
            s->needed_bytes = 2;
414
            goto warn;
415

    
416
        case 0x08:
417
            /* __asm__ ("int3"); */
418
            goto warn;
419

    
420
        case 0x0e:
421
            s->needed_bytes = 2;
422
            goto warn;
423

    
424
        case 0x09:
425
            dsp_out_data (s, 0xf8);
426
            goto warn;
427

    
428
        case 0x0f:
429
            s->needed_bytes = 1;
430
            goto warn;
431

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

    
436
        case 0x14:
437
            s->needed_bytes = 2;
438
            s->block_size = 0;
439
            break;
440

    
441
        case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
442
            dma_cmd8 (s, DMA8_AUTO, -1);
443
            break;
444

    
445
        case 0x20:              /* Direct ADC, Juice/PL */
446
            dsp_out_data (s, 0xff);
447
            goto warn;
448

    
449
        case 0x35:
450
            dolog ("0x35 - MIDI command not implemented\n");
451
            break;
452

    
453
        case 0x40:
454
            s->freq = -1;
455
            s->time_const = -1;
456
            s->needed_bytes = 1;
457
            break;
458

    
459
        case 0x41:
460
            s->freq = -1;
461
            s->time_const = -1;
462
            s->needed_bytes = 2;
463
            break;
464

    
465
        case 0x42:
466
            s->freq = -1;
467
            s->time_const = -1;
468
            s->needed_bytes = 2;
469
            goto warn;
470

    
471
        case 0x45:
472
            dsp_out_data (s, 0xaa);
473
            goto warn;
474

    
475
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
476
            break;
477

    
478
        case 0x48:
479
            s->needed_bytes = 2;
480
            break;
481

    
482
        case 0x74:
483
            s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
484
            dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
485
            break;
486

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

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

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

    
502
        case 0x7d:
503
            dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
504
            dolog ("not implemented\n");
505
            break;
506

    
507
        case 0x7f:
508
            dolog (
509
                "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
510
                );
511
            dolog ("not implemented\n");
512
            break;
513

    
514
        case 0x80:
515
            s->needed_bytes = 2;
516
            break;
517

    
518
        case 0x90:
519
        case 0x91:
520
            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
521
            break;
522

    
523
        case 0xd0:              /* halt DMA operation. 8bit */
524
            control (s, 0);
525
            break;
526

    
527
        case 0xd1:              /* speaker on */
528
            speaker (s, 1);
529
            break;
530

    
531
        case 0xd3:              /* speaker off */
532
            speaker (s, 0);
533
            break;
534

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

    
541
        case 0xd5:              /* halt DMA operation. 16bit */
542
            control (s, 0);
543
            break;
544

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

    
549
        case 0xd9:              /* exit auto-init DMA after this block. 16bit */
550
            s->dma_auto = 0;
551
            break;
552

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

    
557
        case 0xe0:              /* DSP identification */
558
            s->needed_bytes = 1;
559
            break;
560

    
561
        case 0xe1:
562
            dsp_out_data (s, s->ver & 0xff);
563
            dsp_out_data (s, s->ver >> 8);
564
            break;
565

    
566
        case 0xe2:
567
            s->needed_bytes = 1;
568
            goto warn;
569

    
570
        case 0xe3:
571
            {
572
                int i;
573
                for (i = sizeof (e3) - 1; i >= 0; --i)
574
                    dsp_out_data (s, e3[i]);
575
            }
576
            break;
577

    
578
        case 0xe4:              /* write test reg */
579
            s->needed_bytes = 1;
580
            break;
581

    
582
        case 0xe7:
583
            dolog ("Attempt to probe for ESS (0xe7)?\n");
584
            break;
585

    
586
        case 0xe8:              /* read test reg */
587
            dsp_out_data (s, s->test_reg);
588
            break;
589

    
590
        case 0xf2:
591
        case 0xf3:
592
            dsp_out_data (s, 0xaa);
593
            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
594
            qemu_irq_raise (s->pic);
595
            break;
596

    
597
        case 0xf9:
598
            s->needed_bytes = 1;
599
            goto warn;
600

    
601
        case 0xfa:
602
            dsp_out_data (s, 0);
603
            goto warn;
604

    
605
        case 0xfc:              /* FIXME */
606
            dsp_out_data (s, 0);
607
            goto warn;
608

    
609
        default:
610
            dolog ("Unrecognized command %#x\n", cmd);
611
            break;
612
        }
613
    }
614

    
615
    if (!s->needed_bytes) {
616
        ldebug ("\n");
617
    }
618

    
619
 exit:
620
    if (!s->needed_bytes) {
621
        s->cmd = -1;
622
    }
623
    else {
624
        s->cmd = cmd;
625
    }
626
    return;
627

    
628
 warn:
629
    dolog ("warning: command %#x,%d is not truly understood yet\n",
630
           cmd, s->needed_bytes);
631
    goto exit;
632

    
633
}
634

    
635
static uint16_t dsp_get_lohi (SB16State *s)
636
{
637
    uint8_t hi = dsp_get_data (s);
638
    uint8_t lo = dsp_get_data (s);
639
    return (hi << 8) | lo;
640
}
641

    
642
static uint16_t dsp_get_hilo (SB16State *s)
643
{
644
    uint8_t lo = dsp_get_data (s);
645
    uint8_t hi = dsp_get_data (s);
646
    return (hi << 8) | lo;
647
}
648

    
649
static void complete (SB16State *s)
650
{
651
    int d0, d1, d2;
652
    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
653
            s->cmd, s->in_index, s->needed_bytes);
654

    
655
    if (s->cmd > 0xaf && s->cmd < 0xd0) {
656
        d2 = dsp_get_data (s);
657
        d1 = dsp_get_data (s);
658
        d0 = dsp_get_data (s);
659

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

    
679
        case 0x05:
680
            s->csp_param = dsp_get_data (s);
681
            s->csp_value = dsp_get_data (s);
682
            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
683
                    s->csp_param,
684
                    s->csp_value);
685
            break;
686

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

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

    
717
        case 0x10:
718
            d0 = dsp_get_data (s);
719
            dolog ("cmd 0x10 d0=%#x\n", d0);
720
            break;
721

    
722
        case 0x14:
723
            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
724
            break;
725

    
726
        case 0x40:
727
            s->time_const = dsp_get_data (s);
728
            ldebug ("set time const %d\n", s->time_const);
729
            break;
730

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

    
740
        case 0x48:
741
            s->block_size = dsp_get_lohi (s) + 1;
742
            ldebug ("set dma block len %d\n", s->block_size);
743
            break;
744

    
745
        case 0x74:
746
        case 0x75:
747
        case 0x76:
748
        case 0x77:
749
            /* ADPCM stuff, ignore */
750
            break;
751

    
752
        case 0x80:
753
            {
754
                int freq, samples, bytes;
755
                int64_t ticks;
756

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

    
776
        case 0xe0:
777
            d0 = dsp_get_data (s);
778
            s->out_data_len = 0;
779
            ldebug ("E0 data = %#x\n", d0);
780
            dsp_out_data (s, ~d0);
781
            break;
782

    
783
        case 0xe2:
784
            d0 = dsp_get_data (s);
785
            ldebug ("E2 = %#x\n", d0);
786
            break;
787

    
788
        case 0xe4:
789
            s->test_reg = dsp_get_data (s);
790
            break;
791

    
792
        case 0xf9:
793
            d0 = dsp_get_data (s);
794
            ldebug ("command 0xf9 with %#x\n", d0);
795
            switch (d0) {
796
            case 0x0e:
797
                dsp_out_data (s, 0xff);
798
                break;
799

    
800
            case 0x0f:
801
                dsp_out_data (s, 0x07);
802
                break;
803

    
804
            case 0x37:
805
                dsp_out_data (s, 0x38);
806
                break;
807

    
808
            default:
809
                dsp_out_data (s, 0x00);
810
                break;
811
            }
812
            break;
813

    
814
        default:
815
            dolog ("complete: unrecognized command %#x\n", s->cmd);
816
            return;
817
        }
818
    }
819

    
820
    ldebug ("\n");
821
    s->cmd = -1;
822
    return;
823
}
824

    
825
static void legacy_reset (SB16State *s)
826
{
827
    struct audsettings as;
828

    
829
    s->freq = 11025;
830
    s->fmt_signed = 0;
831
    s->fmt_bits = 8;
832
    s->fmt_stereo = 0;
833

    
834
    as.freq = s->freq;
835
    as.nchannels = 1;
836
    as.fmt = AUD_FMT_U8;
837
    as.endianness = 0;
838

    
839
    s->voice = AUD_open_out (
840
        &s->card,
841
        s->voice,
842
        "sb16",
843
        s,
844
        SB_audio_callback,
845
        &as
846
        );
847

    
848
    /* Not sure about that... */
849
    /* AUD_set_active_out (s->voice, 1); */
850
}
851

    
852
static void reset (SB16State *s)
853
{
854
    qemu_irq_lower (s->pic);
855
    if (s->dma_auto) {
856
        qemu_irq_raise (s->pic);
857
        qemu_irq_lower (s->pic);
858
    }
859

    
860
    s->mixer_regs[0x82] = 0;
861
    s->dma_auto = 0;
862
    s->in_index = 0;
863
    s->out_data_len = 0;
864
    s->left_till_irq = 0;
865
    s->needed_bytes = 0;
866
    s->block_size = -1;
867
    s->nzero = 0;
868
    s->highspeed = 0;
869
    s->v2x6 = 0;
870
    s->cmd = -1;
871

    
872
    dsp_out_data (s, 0xaa);
873
    speaker (s, 0);
874
    control (s, 0);
875
    legacy_reset (s);
876
}
877

    
878
static IO_WRITE_PROTO (dsp_write)
879
{
880
    SB16State *s = opaque;
881
    int iport;
882

    
883
    iport = nport - s->port;
884

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

    
903
        case 0x01:
904
        case 0x03:              /* FreeBSD kludge */
905
            s->v2x6 = 1;
906
            break;
907

    
908
        case 0xc6:
909
            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
910
            break;
911

    
912
        case 0xb8:              /* Panic */
913
            reset (s);
914
            break;
915

    
916
        case 0x39:
917
            dsp_out_data (s, 0x38);
918
            reset (s);
919
            s->v2x6 = 0x39;
920
            break;
921

    
922
        default:
923
            s->v2x6 = val;
924
            break;
925
        }
926
        break;
927

    
928
    case 0x0c:                  /* write data or command | write status */
929
/*         if (s->highspeed) */
930
/*             break; */
931

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

    
957
    default:
958
        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
959
        break;
960
    }
961
}
962

    
963
static IO_READ_PROTO (dsp_read)
964
{
965
    SB16State *s = opaque;
966
    int iport, retval, ack = 0;
967

    
968
    iport = nport - s->port;
969

    
970
    switch (iport) {
971
    case 0x06:                  /* reset */
972
        retval = 0xff;
973
        break;
974

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

    
990
    case 0x0c:                  /* 0 can write */
991
        retval = s->can_write ? 0 : 0x80;
992
        break;
993

    
994
    case 0x0d:                  /* timer interrupt clear */
995
        /* dolog ("timer interrupt clear\n"); */
996
        retval = 0;
997
        break;
998

    
999
    case 0x0e:                  /* data available status | irq 8 ack */
1000
        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1001
        if (s->mixer_regs[0x82] & 1) {
1002
            ack = 1;
1003
            s->mixer_regs[0x82] &= 1;
1004
            qemu_irq_lower (s->pic);
1005
        }
1006
        break;
1007

    
1008
    case 0x0f:                  /* irq 16 ack */
1009
        retval = 0xff;
1010
        if (s->mixer_regs[0x82] & 2) {
1011
            ack = 1;
1012
            s->mixer_regs[0x82] &= 2;
1013
            qemu_irq_lower (s->pic);
1014
        }
1015
        break;
1016

    
1017
    default:
1018
        goto error;
1019
    }
1020

    
1021
    if (!ack) {
1022
        ldebug ("read %#x -> %#x\n", nport, retval);
1023
    }
1024

    
1025
    return retval;
1026

    
1027
 error:
1028
    dolog ("warning: dsp_read %#x error\n", nport);
1029
    return 0xff;
1030
}
1031

    
1032
static void reset_mixer (SB16State *s)
1033
{
1034
    int i;
1035

    
1036
    memset (s->mixer_regs, 0xff, 0x7f);
1037
    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1038

    
1039
    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1040
    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1041
    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1042
    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1043

    
1044
    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1045
    s->mixer_regs[0x0c] = 0;
1046

    
1047
    /* d5=output filt, d1=stereo switch */
1048
    s->mixer_regs[0x0e] = 0;
1049

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

    
1057
    for (i = 0x30; i < 0x48; i++) {
1058
        s->mixer_regs[i] = 0x20;
1059
    }
1060
}
1061

    
1062
static IO_WRITE_PROTO (mixer_write_indexb)
1063
{
1064
    SB16State *s = opaque;
1065
    (void) nport;
1066
    s->mixer_nreg = val;
1067
}
1068

    
1069
static IO_WRITE_PROTO (mixer_write_datab)
1070
{
1071
    SB16State *s = opaque;
1072

    
1073
    (void) nport;
1074
    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1075

    
1076
    switch (s->mixer_nreg) {
1077
    case 0x00:
1078
        reset_mixer (s);
1079
        break;
1080

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

    
1091
    case 0x81:
1092
        {
1093
            int dma, hdma;
1094

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

    
1110
    case 0x82:
1111
        dolog ("attempt to write into IRQ status register (val=%#x)\n",
1112
               val);
1113
        return;
1114

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

    
1122
    s->mixer_regs[s->mixer_nreg] = val;
1123
}
1124

    
1125
static IO_WRITE_PROTO (mixer_write_indexw)
1126
{
1127
    mixer_write_indexb (opaque, nport, val & 0xff);
1128
    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1129
}
1130

    
1131
static IO_READ_PROTO (mixer_read)
1132
{
1133
    SB16State *s = opaque;
1134

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

    
1148
static int write_audio (SB16State *s, int nchan, int dma_pos,
1149
                        int dma_len, int len)
1150
{
1151
    int temp, net;
1152
    uint8_t tmpbuf[4096];
1153

    
1154
    temp = len;
1155
    net = 0;
1156

    
1157
    while (temp) {
1158
        int left = dma_len - dma_pos;
1159
        int copied;
1160
        size_t to_copy;
1161

    
1162
        to_copy = audio_MIN (temp, left);
1163
        if (to_copy > sizeof (tmpbuf)) {
1164
            to_copy = sizeof (tmpbuf);
1165
        }
1166

    
1167
        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1168
        copied = AUD_write (s->voice, tmpbuf, copied);
1169

    
1170
        temp -= copied;
1171
        dma_pos = (dma_pos + copied) % dma_len;
1172
        net += copied;
1173

    
1174
        if (!copied) {
1175
            break;
1176
        }
1177
    }
1178

    
1179
    return net;
1180
}
1181

    
1182
static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1183
{
1184
    SB16State *s = opaque;
1185
    int till, copy, written, free;
1186

    
1187
    if (s->block_size <= 0) {
1188
        dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1189
               s->block_size, nchan, dma_pos, dma_len);
1190
        return dma_pos;
1191
    }
1192

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

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

    
1207
    copy = free;
1208
    till = s->left_till_irq;
1209

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

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

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

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

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

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

    
1244
    return dma_pos;
1245
}
1246

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

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

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

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

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

    
1296
    qemu_put_be32 (f, s->nzero);
1297
    qemu_put_be32 (f, s->left_till_irq);
1298
    qemu_put_be32 (f, s->dma_running);
1299
    qemu_put_be32 (f, s->bytes_per_second);
1300
    qemu_put_be32 (f, s->align);
1301

    
1302
    qemu_put_be32 (f, s->mixer_nreg);
1303
    qemu_put_buffer (f, s->mixer_regs, 256);
1304
}
1305

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

    
1310
    if (version_id != 1) {
1311
        return -EINVAL;
1312
    }
1313

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

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

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

    
1353
    s->nzero=qemu_get_be32 (f);
1354
    s->left_till_irq=qemu_get_be32 (f);
1355
    s->dma_running=qemu_get_be32 (f);
1356
    s->bytes_per_second=qemu_get_be32 (f);
1357
    s->align=qemu_get_be32 (f);
1358

    
1359
    s->mixer_nreg=qemu_get_be32 (f);
1360
    qemu_get_buffer (f, s->mixer_regs, 256);
1361

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

    
1367
    if (s->dma_running) {
1368
        if (s->freq) {
1369
            struct audsettings as;
1370

    
1371
            s->audio_free = 0;
1372

    
1373
            as.freq = s->freq;
1374
            as.nchannels = 1 << s->fmt_stereo;
1375
            as.fmt = s->fmt;
1376
            as.endianness = 0;
1377

    
1378
            s->voice = AUD_open_out (
1379
                &s->card,
1380
                s->voice,
1381
                "sb16",
1382
                s,
1383
                SB_audio_callback,
1384
                &as
1385
                );
1386
        }
1387

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

    
1394
static int sb16_initfn (ISADevice *dev)
1395
{
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
    SB16State *s;
1399
    int i;
1400

    
1401
    s = DO_UPCAST (SB16State, dev, dev);
1402

    
1403
    s->cmd = -1;
1404
    isa_init_irq (dev, &s->pic, s->irq);
1405

    
1406
    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1407
    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1408
    s->mixer_regs[0x82] = 2 << 5;
1409

    
1410
    s->csp_regs[5] = 1;
1411
    s->csp_regs[9] = 0xf8;
1412

    
1413
    reset_mixer (s);
1414
    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1415
    if (!s->aux_ts) {
1416
        dolog ("warning: Could not create auxiliary timer\n");
1417
    }
1418

    
1419
    for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) {
1420
        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1421
    }
1422

    
1423
    for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
1424
        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1425
    }
1426

    
1427
    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1428
    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1429
    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1430
    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1431

    
1432
    DMA_register_channel (s->hdma, SB_read_DMA, s);
1433
    DMA_register_channel (s->dma, SB_read_DMA, s);
1434
    s->can_write = 1;
1435

    
1436
    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1437
    AUD_register_card ("sb16", &s->card);
1438
    return 0;
1439
}
1440

    
1441
int SB16_init (qemu_irq *pic)
1442
{
1443
    isa_create_simple ("sb16");
1444
    return 0;
1445
}
1446

    
1447
static ISADeviceInfo sb16_info = {
1448
    .qdev.name     = "sb16",
1449
    .qdev.desc     = "Creative Sound Blaster 16",
1450
    .qdev.size     = sizeof (SB16State),
1451
    .init          = sb16_initfn,
1452
    .qdev.props    = (Property[]) {
1453
        DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
1454
        DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
1455
        DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
1456
        DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
1457
        DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
1458
        DEFINE_PROP_END_OF_LIST (),
1459
    },
1460
};
1461

    
1462
static void sb16_register (void)
1463
{
1464
    isa_qdev_register (&sb16_info);
1465
}
1466
device_init (sb16_register)