Statistics
| Branch: | Revision:

root / hw / sb16.c @ 7f647cf6

History | View | Annotate | Download (17.3 kB)

1
/*
2
 * QEMU Soundblaster 16 emulation
3
 * 
4
 * Copyright (c) 2003 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 MIN(a, b) ((a)>(b)?(b):(a))
27
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
28

    
29
#define log(...) do {                           \
30
    fprintf (stderr, "sb16: " __VA_ARGS__);     \
31
    fputc ('\n', stderr);                       \
32
} while (0)
33

    
34
/* #define DEBUG_SB16 */
35
#ifdef DEBUG_SB16
36
#define lwarn(...) fprintf (stderr, "sb16: " __VA_ARGS__)
37
#define linfo(...) fprintf (stderr, "sb16: " __VA_ARGS__)
38
#define ldebug(...) fprintf (stderr, "sb16: " __VA_ARGS__)
39
#else
40
#define lwarn(...)
41
#define linfo(...)
42
#define ldebug(...)
43
#endif
44

    
45
#define IO_READ_PROTO(name) \
46
    uint32_t name (void *opaque, uint32_t nport)
47
#define IO_WRITE_PROTO(name) \
48
    void name (void *opaque, uint32_t nport, uint32_t val)
49

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

    
52
static struct {
53
    int ver_lo;
54
    int ver_hi;
55
    int irq;
56
    int dma;
57
    int hdma;
58
    int port;
59
    int mix_block;
60
} sb = {5, 4, 5, 1, 5, 0x220, -1};
61

    
62
static int mix_block, noirq;
63

    
64
typedef struct SB16State {
65
    int in_index;
66
    int out_data_len;
67
    int fmt_stereo;
68
    int fmt_signed;
69
    int fmt_bits;
70
    int dma_auto;
71
    int dma_buffer_size;
72
    int fifo;
73
    int freq;
74
    int time_const;
75
    int speaker;
76
    int needed_bytes;
77
    int cmd;
78
    int dma_pos;
79
    int use_hdma;
80

    
81
    int v2x6;
82

    
83
    uint8_t in_data[10];
84
    uint8_t out_data[50];
85

    
86
    int left_till_irq;
87

    
88
    /* mixer state */
89
    int mixer_nreg;
90
    uint8_t mixer_regs[256];
91
} SB16State;
92

    
93
/* XXX: suppress that and use a context */
94
static struct SB16State dsp;
95

    
96
static void log_dsp (SB16State *dsp)
97
{
98
    linfo ("%c:%c:%d:%c:dmabuf=%d:pos=%d:freq=%d:timeconst=%d:speaker=%d\n",
99
           dsp->fmt_stereo ? 'S' : 'M',
100
           dsp->fmt_signed ? 'S' : 'U',
101
           dsp->fmt_bits,
102
           dsp->dma_auto ? 'a' : 's',
103
           dsp->dma_buffer_size,
104
           dsp->dma_pos,
105
           dsp->freq,
106
           dsp->time_const,
107
           dsp->speaker);
108
}
109

    
110
static void control (int hold)
111
{
112
    linfo ("%d high %d\n", hold, dsp.use_hdma);
113
    if (hold) {
114
        if (dsp.use_hdma)
115
            DMA_hold_DREQ (sb.hdma);
116
        else
117
            DMA_hold_DREQ (sb.dma);
118
    }
119
    else {
120
        if (dsp.use_hdma)
121
            DMA_release_DREQ (sb.hdma);
122
        else
123
            DMA_release_DREQ (sb.dma);
124
    }
125
}
126

    
127
static void dma_cmd (uint8_t cmd, uint8_t d0, int dma_len)
128
{
129
    int bps;
130
    audfmt_e fmt;
131

    
132
    dsp.use_hdma = cmd < 0xc0;
133
    dsp.fifo = (cmd >> 1) & 1;
134
    dsp.dma_auto = (cmd >> 2) & 1;
135

    
136
    switch (cmd >> 4) {
137
    case 11:
138
        dsp.fmt_bits = 16;
139
        break;
140

    
141
    case 12:
142
        dsp.fmt_bits = 8;
143
        break;
144
    }
145

    
146
    dsp.fmt_signed = (d0 >> 4) & 1;
147
    dsp.fmt_stereo = (d0 >> 5) & 1;
148

    
149
    if (-1 != dsp.time_const) {
150
        int tmp;
151

    
152
        tmp = 256 - dsp.time_const;
153
        dsp.freq = (1000000 + (tmp / 2)) / tmp;
154
    }
155
    bps = 1 << (16 == dsp.fmt_bits);
156

    
157
    if (-1 != dma_len)
158
        dsp.dma_buffer_size = (dma_len + 1) * bps;
159

    
160
    linfo ("frequency %d, stereo %d, signed %d, bits %d, size %d, auto %d\n",
161
           dsp.freq, dsp.fmt_stereo, dsp.fmt_signed, dsp.fmt_bits,
162
           dsp.dma_buffer_size, dsp.dma_auto);
163

    
164
    if (16 == dsp.fmt_bits) {
165
        if (dsp.fmt_signed) {
166
            fmt = AUD_FMT_S16;
167
        }
168
        else {
169
            fmt = AUD_FMT_U16;
170
        }
171
    }
172
    else {
173
        if (dsp.fmt_signed) {
174
            fmt = AUD_FMT_S8;
175
        }
176
        else {
177
            fmt = AUD_FMT_U8;
178
        }
179
    }
180

    
181
    dsp.dma_pos = 0;
182
    dsp.left_till_irq = dsp.dma_buffer_size;
183

    
184
    if (sb.mix_block) {
185
        mix_block = sb.mix_block;
186
    }
187
    else {
188
        int align;
189

    
190
        align = bps << dsp.fmt_stereo;
191
        mix_block = ((dsp.freq * align) / 100) & ~(align - 1);
192
    }
193

    
194
    AUD_reset (dsp.freq, 1 << dsp.fmt_stereo, fmt);
195
    control (1);
196
    dsp.speaker = 1;
197
}
198

    
199
static inline void dsp_out_data(SB16State *dsp, int val)
200
{
201
    if (dsp->out_data_len < sizeof(dsp->out_data))
202
        dsp->out_data[dsp->out_data_len++] = val;
203
}
204

    
205
static void command (SB16State *dsp, uint8_t cmd)
206
{
207
    linfo ("%#x\n", cmd);
208

    
209
    if (cmd > 0xaf && cmd < 0xd0) {
210
        if (cmd & 8)
211
            goto error;
212

    
213
        switch (cmd >> 4) {
214
        case 11:
215
        case 12:
216
            break;
217
        default:
218
            log("%#x wrong bits", cmd);
219
            goto error;
220
        }
221
        dsp->needed_bytes = 3;
222
    }
223
    else {
224
        switch (cmd) {
225
        case 0x00:
226
        case 0x03:
227
        case 0xe7:
228
            /* IMS uses those when probing for sound devices */
229
            return;
230

    
231
        case 0x04:
232
            dsp->needed_bytes = 1;
233
            break;
234

    
235
        case 0x05:
236
        case 0x0e:
237
            dsp->needed_bytes = 2;
238
            break;
239

    
240
        case 0x0f:
241
            dsp->needed_bytes = 1;
242
            dsp_out_data (dsp, 0);
243
            break;
244

    
245
        case 0x10:
246
            dsp->needed_bytes = 1;
247
            break;
248

    
249
        case 0x14:
250
            dsp->needed_bytes = 2;
251
            dsp->dma_buffer_size = 0;
252
            break;
253

    
254
        case 0x20:
255
            dsp_out_data(dsp, 0xff);
256
            break;
257

    
258
        case 0x35:
259
            lwarn ("MIDI commands not implemented\n");
260
            break;
261

    
262
        case 0x40:
263
            dsp->freq = -1;
264
            dsp->time_const = -1;
265
            dsp->needed_bytes = 1;
266
            break;
267

    
268
        case 0x41:
269
        case 0x42:
270
            dsp->freq = -1;
271
            dsp->time_const = -1;
272
            dsp->needed_bytes = 2;
273
            break;
274

    
275
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
276
            break;
277

    
278
        case 0x48:
279
            dsp->needed_bytes = 2;
280
            break;
281

    
282
        case 0x27:                /* ????????? */
283
        case 0x4e:
284
            return;
285

    
286
        case 0x80:
287
            cmd = -1;
288
            break;
289

    
290
        case 0x90:
291
        case 0x91:
292
            {
293
                uint8_t d0;
294

    
295
                d0 = 4;
296
                /* if (dsp->fmt_signed) d0 |= 16; */
297
                /* if (dsp->fmt_stereo) d0 |= 32; */
298
                dma_cmd (cmd == 0x90 ? 0xc4 : 0xc0, d0, -1);
299
                cmd = -1;
300
                break;
301
            }
302

    
303
        case 0xd0:                /* XXX */
304
            control (0);
305
            return;
306

    
307
        case 0xd1:
308
            dsp->speaker = 1;
309
            break;
310

    
311
        case 0xd3:
312
            dsp->speaker = 0;
313
            return;
314

    
315
        case 0xd4:
316
            control (1);
317
            break;
318

    
319
        case 0xd5:
320
            control (0);
321
            break;
322

    
323
        case 0xd6:
324
            control (1);
325
            break;
326

    
327
        case 0xd9:
328
            control (0);
329
            dsp->dma_auto = 0;
330
            return;
331

    
332
        case 0xda:
333
            control (0);
334
            dsp->dma_auto = 0;
335
            break;
336

    
337
        case 0xe0:
338
            dsp->needed_bytes = 1;
339
            break;
340

    
341
        case 0xe1:
342
            dsp_out_data(dsp, sb.ver_lo);
343
            dsp_out_data(dsp, sb.ver_hi);
344
            return;
345

    
346
        case 0xe3:
347
            {
348
                int i;
349
                for (i = sizeof (e3) - 1; i >= 0; --i)
350
                    dsp_out_data (dsp, e3[i]);
351
                return;
352
            }
353

    
354
        case 0xf2:
355
            dsp_out_data(dsp, 0xaa);
356
            dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
357
            pic_set_irq (sb.irq, 1);
358
            return;
359

    
360
        default:
361
            log("%#x is unknown", cmd);
362
            goto error;
363
        }
364
    }
365
    dsp->cmd = cmd;
366
    return;
367

    
368
 error:
369
    return;
370
}
371

    
372
static void complete (SB16State *dsp)
373
{
374
    linfo ("complete command %#x, in_index %d, needed_bytes %d\n",
375
           dsp->cmd, dsp->in_index, dsp->needed_bytes);
376

    
377
    if (dsp->cmd > 0xaf && dsp->cmd < 0xd0) {
378
        int d0, d1, d2;
379

    
380
        d0 = dsp->in_data[0];
381
        d1 = dsp->in_data[1];
382
        d2 = dsp->in_data[2];
383

    
384
        ldebug ("d0 = %d, d1 = %d, d2 = %d\n",
385
                d0, d1, d2);
386
        dma_cmd (dsp->cmd, d0, d1 + (d2 << 8));
387
    }
388
    else {
389
        switch (dsp->cmd) {
390
        case 0x05:
391
        case 0x04:
392
        case 0x0e:
393
        case 0x0f:
394
            break;
395

    
396
        case 0x10:
397
            break;
398

    
399
        case 0x14:
400
            {
401
                int d0, d1;
402
                int save_left;
403
                int save_pos;
404

    
405
                d0 = dsp->in_data[0];
406
                d1 = dsp->in_data[1];
407

    
408
                save_left = dsp->left_till_irq;
409
                save_pos = dsp->dma_pos;
410
                dma_cmd (0xc0, 0, d0 + (d1 << 8));
411
                dsp->left_till_irq = save_left;
412
                dsp->dma_pos = save_pos;
413

    
414
                linfo ("set buffer size data[%d, %d] %d pos %d\n",
415
                       d0, d1, dsp->dma_buffer_size, dsp->dma_pos);
416
                break;
417
            }
418

    
419
        case 0x40:
420
            dsp->time_const = dsp->in_data[0];
421
            linfo ("set time const %d\n", dsp->time_const);
422
            break;
423

    
424
        case 0x41:
425
        case 0x42:
426
            dsp->freq = dsp->in_data[1] + (dsp->in_data[0] << 8);
427
            linfo ("set freq %#x, %#x = %d\n",
428
                   dsp->in_data[1], dsp->in_data[0], dsp->freq);
429
            break;
430

    
431
        case 0x48:
432
            dsp->dma_buffer_size = dsp->in_data[1] + (dsp->in_data[0] << 8);
433
            linfo ("set dma len %#x, %#x = %d\n",
434
                   dsp->in_data[1], dsp->in_data[0], dsp->dma_buffer_size);
435
            break;
436

    
437
        case 0xe0:
438
            dsp->out_data_len = 0;
439
            linfo ("data = %#x\n", dsp->in_data[0]);
440
            dsp_out_data(dsp, dsp->in_data[0] ^ 0xff);
441
            break;
442

    
443
        default:
444
            log ("unrecognized command %#x", dsp->cmd);
445
            return;
446
        }
447
    }
448

    
449
    dsp->cmd = -1;
450
    return;
451
}
452

    
453
static IO_WRITE_PROTO (dsp_write)
454
{
455
    SB16State *dsp = opaque;
456
    int iport;
457

    
458
    iport = nport - sb.port;
459

    
460
    ldebug ("write %#x %#x\n", nport, iport);
461
    switch (iport) {
462
    case 0x6:
463
        control (0);
464
        if (0 == val)
465
            dsp->v2x6 = 0;
466
        else if ((1 == val) && (0 == dsp->v2x6)) {
467
            dsp->v2x6 = 1;
468
            dsp_out_data(dsp, 0xaa);
469
        }
470
        else
471
            dsp->v2x6 = ~0;
472
        break;
473

    
474
    case 0xc:                   /* write data or command | write status */
475
        if (0 == dsp->needed_bytes) {
476
            command (dsp, val);
477
            if (0 == dsp->needed_bytes) {
478
                log_dsp (dsp);
479
            }
480
        }
481
        else {
482
            dsp->in_data[dsp->in_index++] = val;
483
            if (dsp->in_index == dsp->needed_bytes) {
484
                dsp->needed_bytes = 0;
485
                dsp->in_index = 0;
486
                complete (dsp);
487
                log_dsp (dsp);
488
            }
489
        }
490
        break;
491

    
492
    default:
493
        log ("(nport=%#x, val=%#x)", nport, val);
494
        break;
495
    }
496
}
497

    
498
static IO_READ_PROTO (dsp_read)
499
{
500
    SB16State *dsp = opaque;
501
    int iport, retval;
502

    
503
    iport = nport - sb.port;
504

    
505
    switch (iport) {
506

    
507
    case 0x6:                   /* reset */
508
        return 0;
509

    
510
    case 0xa:                   /* read data */
511
        if (dsp->out_data_len) {
512
            retval = dsp->out_data[--dsp->out_data_len];
513
        } else {
514
            log("empty output buffer");
515
            goto error;
516
        }
517
        break;
518

    
519
    case 0xc:                   /* 0 can write */
520
        retval = 0;
521
        break;
522

    
523
    case 0xd:                   /* timer interrupt clear */
524
        log("timer interrupt clear");
525
        goto error;
526

    
527
    case 0xe:                   /* data available status | irq 8 ack */
528
        /* XXX drop pic irq line here? */
529
        ldebug ("8 ack\n");
530
        retval = (0 == dsp->out_data_len) ? 0 : 0x80;
531
        dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
532
        pic_set_irq (sb.irq, 0);
533
        break;
534

    
535
    case 0xf:                   /* irq 16 ack */
536
        /* XXX drop pic irq line here? */
537
        ldebug ("16 ack\n");
538
        retval = 0xff;
539
        dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
540
        pic_set_irq (sb.irq, 0);
541
        break;
542

    
543
    default:
544
        goto error;
545
    }
546

    
547
    if ((0xc != iport) && (0xe != iport)) {
548
        ldebug ("nport=%#x iport %#x = %#x\n",
549
                nport, iport, retval);
550
    }
551

    
552
    return retval;
553

    
554
 error:
555
    return 0;
556
}
557

    
558
static IO_WRITE_PROTO(mixer_write_indexb)
559
{
560
    SB16State *dsp = opaque;
561
    dsp->mixer_nreg = val;
562
}
563

    
564
static IO_WRITE_PROTO(mixer_write_datab)
565
{
566
    SB16State *dsp = opaque;
567

    
568
    if (dsp->mixer_nreg > 0x83)
569
        return;
570
    dsp->mixer_regs[dsp->mixer_nreg] = val;
571
}
572

    
573
static IO_WRITE_PROTO(mixer_write_indexw)
574
{
575
    mixer_write_indexb (opaque, nport, val & 0xff);
576
    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
577
}
578

    
579
static IO_READ_PROTO(mixer_read)
580
{
581
    SB16State *dsp = opaque;
582
    return dsp->mixer_regs[dsp->mixer_nreg];
583
}
584

    
585
void SB16_run (void)
586
{
587
    if (0 == dsp.speaker)
588
        return;
589

    
590
    AUD_run ();
591
}
592

    
593
static int write_audio (uint32_t addr, int len, int size)
594
{
595
    int temp, net;
596
    uint8_t tmpbuf[4096];
597

    
598
    temp = size;
599

    
600
    net = 0;
601

    
602
    while (temp) {
603
        int left_till_end;
604
        int to_copy;
605
        int copied;
606

    
607
        left_till_end = len - dsp.dma_pos;
608

    
609
        to_copy = MIN (temp, left_till_end);
610
        if (to_copy > sizeof(tmpbuf))
611
            to_copy = sizeof(tmpbuf);
612
        cpu_physical_memory_read(addr + dsp.dma_pos, tmpbuf, to_copy);
613
        copied = AUD_write (tmpbuf, to_copy);
614

    
615
        temp -= copied;
616
        dsp.dma_pos += copied;
617

    
618
        if (dsp.dma_pos == len) {
619
            dsp.dma_pos = 0;
620
        }
621

    
622
        net += copied;
623

    
624
        if (copied != to_copy)
625
            return net;
626
    }
627

    
628
    return net;
629
}
630

    
631
static int SB_read_DMA (void *opaque, target_ulong addr, int size)
632
{
633
    SB16State *dsp = opaque;
634
    int free, till, copy, written;
635

    
636
    if (0 == dsp->speaker)
637
        return 0;
638

    
639
    if (dsp->left_till_irq < 0) {
640
        dsp->left_till_irq += dsp->dma_buffer_size;
641
        return dsp->dma_pos;
642
    }
643

    
644
    free = AUD_get_free ();
645

    
646
    if ((free <= 0) || (0 == size)) {
647
        return dsp->dma_pos;
648
    }
649

    
650
    if (mix_block > 0) {
651
        copy = MIN (free, mix_block);
652
    }
653
    else {
654
        copy = free;
655
    }
656

    
657
    till = dsp->left_till_irq;
658

    
659
    ldebug ("addr:%#010x free:%d till:%d size:%d\n",
660
            addr, free, till, size);
661
    if (till <= copy) {
662
        if (0 == dsp->dma_auto) {
663
            copy = till;
664
        }
665
    }
666

    
667
    written = write_audio (addr, size, copy);
668
    dsp->left_till_irq -= written;
669
    AUD_adjust_estimate (free - written);
670

    
671
    if (dsp->left_till_irq <= 0) {
672
        dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
673
        if (0 == noirq) {
674
            ldebug ("request irq\n");
675
            pic_set_irq(sb.irq, 1);
676
        }
677

    
678
        if (0 == dsp->dma_auto) {
679
            control (0);
680
        }
681
    }
682

    
683
    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
684
            dsp->dma_pos, free, size, dsp->left_till_irq, copy,
685
            dsp->dma_buffer_size);
686

    
687
    if (dsp->left_till_irq <= 0) {
688
        dsp->left_till_irq += dsp->dma_buffer_size;
689
    }
690

    
691
    return dsp->dma_pos;
692
}
693

    
694
static int magic_of_irq (int irq)
695
{
696
    switch (irq) {
697
    case 2:
698
        return 1;
699
    case 5:
700
        return 2;
701
    case 7:
702
        return 4;
703
    case 10:
704
        return 8;
705
    default:
706
        log ("bad irq %d", irq);
707
        return 2;
708
    }
709
}
710

    
711
#if 0
712
static int irq_of_magic (int magic)
713
{
714
    switch (magic) {
715
    case 1:
716
        return 2;
717
    case 2:
718
        return 5;
719
    case 4:
720
        return 7;
721
    case 8:
722
        return 10;
723
    default:
724
        log ("bad irq magic %d", magic);
725
        return 2;
726
    }
727
}
728
#endif
729

    
730
void SB16_init (void)
731
{
732
    SB16State *s = &dsp;
733
    int i;
734
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
735
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
736

    
737
    memset(s->mixer_regs, 0xff, sizeof(s->mixer_regs));
738

    
739
    s->mixer_regs[0x0e] = ~0;
740
    s->mixer_regs[0x80] = magic_of_irq (sb.irq);
741
    s->mixer_regs[0x81] = 0x20 | (sb.dma << 1);
742

    
743
    for (i = 0x30; i < 0x48; i++) {
744
        s->mixer_regs[i] = 0x20;
745
    }
746

    
747
    for (i = 0; i < LENOFA (dsp_write_ports); i++) {
748
        register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, s);
749
    }
750

    
751
    for (i = 0; i < LENOFA (dsp_read_ports); i++) {
752
        register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, s);
753
    }
754

    
755
    register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, s);
756
    register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, s);
757
    register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, s);
758
    register_ioport_write (sb.port + 0x5, 1, 1, mixer_write_datab, s);
759

    
760
    DMA_register_channel (sb.hdma, SB_read_DMA, s);
761
    DMA_register_channel (sb.dma, SB_read_DMA, s);
762
}