Statistics
| Branch: | Revision:

root / hw / sb16.c @ 546fa6ab

History | View | Annotate | Download (31.7 kB)

1
/*
2
 * QEMU Soundblaster 16 emulation
3
 * 
4
 * Copyright (c) 2003-2004 Vassili Karpov (malc)
5
 * 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "vl.h"
25

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

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

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

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

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

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

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

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

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

    
80
    int v2x6;
81

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

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

    
97
    int left_till_irq;
98

    
99
    int dma_running;
100
    int bytes_per_second;
101
    int align;
102
    SWVoice *voice;
103

    
104
    QEMUTimer *ts, *aux_ts;
105
    /* mixer state */
106
    int mixer_nreg;
107
    uint8_t mixer_regs[256];
108
} SB16State;
109

    
110
/* XXX: suppress that and use a context */
111
static struct SB16State dsp;
112

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

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

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

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

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

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

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

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

    
192
#define DMA8_AUTO 1
193
#define DMA8_HIGH 2
194

    
195
static void dma_cmd8 (SB16State *s, int mask, int dma_len)
196
{
197
    s->fmt = AUD_FMT_U8;
198
    s->use_hdma = 0;
199
    s->fmt_bits = 8;
200
    s->fmt_signed = 0;
201
    s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
202
    if (-1 == s->time_const) {
203
        s->freq = 11025;
204
    }
205
    else {
206
        int tmp = (256 - s->time_const);
207
        s->freq = (1000000 + (tmp / 2)) / tmp;
208
    }
209

    
210
    if (dma_len != -1)
211
        s->block_size = dma_len << s->fmt_stereo;
212
    else {
213
        /* This is apparently the only way to make both Act1/PL
214
           and SecondReality/FC work
215

216
           Act1 sets block size via command 0x48 and it's an odd number
217
           SR does the same with even number
218
           Both use stereo, and Creatives own documentation states that
219
           0x48 sets block size in bytes less one.. go figure */
220
        s->block_size &= ~s->fmt_stereo;
221
    }
222

    
223
    s->freq >>= s->fmt_stereo;
224
    s->left_till_irq = s->block_size;
225
    s->bytes_per_second = (s->freq << s->fmt_stereo);
226
    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
227
    s->dma_auto = (mask & DMA8_AUTO) != 0;
228
    s->align = (1 << s->fmt_stereo) - 1;
229

    
230
    if (s->block_size & s->align)
231
        dolog ("warning: unaligned buffer\n");
232

    
233
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
234
            "dma %d, auto %d, fifo %d, high %d\n",
235
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
236
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
237

    
238
    if (s->freq)
239
        s->voice = AUD_open (s->voice, "sb16", s->freq,
240
                             1 << s->fmt_stereo, s->fmt);
241

    
242
    control (s, 1);
243
    speaker (s, 1);
244
}
245

    
246
static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
247
{
248
    s->use_hdma = cmd < 0xc0;
249
    s->fifo = (cmd >> 1) & 1;
250
    s->dma_auto = (cmd >> 2) & 1;
251
    s->fmt_signed = (d0 >> 4) & 1;
252
    s->fmt_stereo = (d0 >> 5) & 1;
253

    
254
    switch (cmd >> 4) {
255
    case 11:
256
        s->fmt_bits = 16;
257
        break;
258

    
259
    case 12:
260
        s->fmt_bits = 8;
261
        break;
262
    }
263

    
264
    if (-1 != s->time_const) {
265
#if 1
266
        int tmp = 256 - s->time_const;
267
        s->freq = (1000000 + (tmp / 2)) / tmp;
268
#else
269
        /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
270
        s->freq = 1000000 / ((255 - s->time_const));
271
#endif
272
        s->time_const = -1;
273
    }
274

    
275
    s->block_size = dma_len + 1;
276
    s->block_size <<= (s->fmt_bits == 16);
277
    if (!s->dma_auto) {
278
        /* It is clear that for DOOM and auto-init this value
279
           shouldn't take stereo into account, while Miles Sound Systems
280
           setsound.exe with single transfer mode wouldn't work without it
281
           wonders of SB16 yet again */
282
        s->block_size <<= s->fmt_stereo;
283
    }
284

    
285
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
286
            "dma %d, auto %d, fifo %d, high %d\n",
287
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
288
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
289

    
290
    if (16 == s->fmt_bits) {
291
        if (s->fmt_signed) {
292
            s->fmt = AUD_FMT_S16;
293
        }
294
        else {
295
            s->fmt = AUD_FMT_U16;
296
        }
297
    }
298
    else {
299
        if (s->fmt_signed) {
300
            s->fmt = AUD_FMT_S8;
301
        }
302
        else {
303
            s->fmt = AUD_FMT_U8;
304
        }
305
    }
306

    
307
    s->left_till_irq = s->block_size;
308

    
309
    s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
310
    s->highspeed = 0;
311
    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
312
    if (s->block_size & s->align)
313
        dolog ("warning: unaligned buffer\n");
314

    
315
    if (s->freq)
316
        s->voice = AUD_open (s->voice, "sb16", s->freq,
317
                             1 << s->fmt_stereo, s->fmt);
318

    
319
    control (s, 1);
320
    speaker (s, 1);
321
}
322

    
323
static inline void dsp_out_data (SB16State *s, uint8_t val)
324
{
325
    ldebug ("outdata %#x\n", val);
326
    if (s->out_data_len < sizeof (s->out_data))
327
        s->out_data[s->out_data_len++] = val;
328
}
329

    
330
static inline uint8_t dsp_get_data (SB16State *s)
331
{
332
    if (s->in_index)
333
        return s->in2_data[--s->in_index];
334
    else {
335
        dolog ("buffer underflow\n");
336
        return 0;
337
    }
338
}
339

    
340
static void command (SB16State *s, uint8_t cmd)
341
{
342
    ldebug ("command %#x\n", cmd);
343

    
344
    if (cmd > 0xaf && cmd < 0xd0) {
345
        if (cmd & 8) {
346
            dolog ("ADC not yet supported (command %#x)\n", cmd);
347
        }
348

    
349
        switch (cmd >> 4) {
350
        case 11:
351
        case 12:
352
            break;
353
        default:
354
            dolog ("%#x wrong bits\n", cmd);
355
        }
356
        s->needed_bytes = 3;
357
    }
358
    else {
359
        switch (cmd) {
360
        case 0x03:
361
            dsp_out_data (s, 0x10); /* s->csp_param); */
362
            goto warn;
363

    
364
        case 0x04:
365
            s->needed_bytes = 1;
366
            goto warn;
367

    
368
        case 0x05:
369
            s->needed_bytes = 2;
370
            goto warn;
371

    
372
        case 0x08:
373
            /* __asm__ ("int3"); */
374
            goto warn;
375

    
376
        case 0x0e:
377
            s->needed_bytes = 2;
378
            goto warn;
379

    
380
        case 0x09:
381
            dsp_out_data (s, 0xf8);
382
            goto warn;
383

    
384
        case 0x0f:
385
            s->needed_bytes = 1;
386
            goto warn;
387

    
388
        case 0x10:
389
            s->needed_bytes = 1;
390
            goto warn;
391

    
392
        case 0x14:
393
            s->needed_bytes = 2;
394
            s->block_size = 0;
395
            break;
396

    
397
        case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
398
            control (s, 1);
399
            break;
400

    
401
        case 0x20:              /* Direct ADC, Juice/PL */
402
            dsp_out_data (s, 0xff);
403
            goto warn;
404

    
405
        case 0x35:
406
            dolog ("MIDI command(0x35) not implemented\n");
407
            break;
408

    
409
        case 0x40:
410
            s->freq = -1;
411
            s->time_const = -1;
412
            s->needed_bytes = 1;
413
            break;
414

    
415
        case 0x41:
416
            s->freq = -1;
417
            s->time_const = -1;
418
            s->needed_bytes = 2;
419
            break;
420

    
421
        case 0x42:
422
            s->freq = -1;
423
            s->time_const = -1;
424
            s->needed_bytes = 2;
425
            goto warn;
426

    
427
        case 0x45:
428
            dsp_out_data (s, 0xaa);
429
            goto warn;
430

    
431
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
432
            break;
433

    
434
        case 0x48:
435
            s->needed_bytes = 2;
436
            break;
437

    
438
        case 0x80:
439
            s->needed_bytes = 2;
440
            break;
441

    
442
        case 0x90:
443
        case 0x91:
444
            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
445
            break;
446

    
447
        case 0xd0:              /* halt DMA operation. 8bit */
448
            control (s, 0);
449
            break;
450

    
451
        case 0xd1:              /* speaker on */
452
            speaker (s, 1);
453
            break;
454

    
455
        case 0xd3:              /* speaker off */
456
            speaker (s, 0);
457
            break;
458

    
459
        case 0xd4:              /* continue DMA operation. 8bit */
460
            control (s, 1);
461
            break;
462

    
463
        case 0xd5:              /* halt DMA operation. 16bit */
464
            control (s, 0);
465
            break;
466

    
467
        case 0xd6:              /* continue DMA operation. 16bit */
468
            control (s, 1);
469
            break;
470

    
471
        case 0xd9:              /* exit auto-init DMA after this block. 16bit */
472
            s->dma_auto = 0;
473
            break;
474

    
475
        case 0xda:              /* exit auto-init DMA after this block. 8bit */
476
            s->dma_auto = 0;
477
            break;
478

    
479
        case 0xe0:
480
            s->needed_bytes = 1;
481
            goto warn;
482

    
483
        case 0xe1:
484
            dsp_out_data (s, s->ver & 0xff);
485
            dsp_out_data (s, s->ver >> 8);
486
            break;
487

    
488
        case 0xe2:
489
            s->needed_bytes = 1;
490
            goto warn;
491

    
492
        case 0xe3:
493
            {
494
                int i;
495
                for (i = sizeof (e3) - 1; i >= 0; --i)
496
                    dsp_out_data (s, e3[i]);
497
            }
498
            break;
499

    
500
        case 0xe4:              /* write test reg */
501
            s->needed_bytes = 1;
502
            break;
503

    
504
        case 0xe7:
505
            dolog ("Attempt to probe for ESS (0xe7)?\n");
506
            return;
507

    
508
        case 0xe8:              /* read test reg */
509
            dsp_out_data (s, s->test_reg);
510
            break;
511

    
512
        case 0xf2:
513
        case 0xf3:
514
            dsp_out_data (s, 0xaa);
515
            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
516
            pic_set_irq (s->irq, 1);
517
            break;
518

    
519
        case 0xf9:
520
            s->needed_bytes = 1;
521
            goto warn;
522

    
523
        case 0xfa:
524
            dsp_out_data (s, 0);
525
            goto warn;
526

    
527
        case 0xfc:              /* FIXME */
528
            dsp_out_data (s, 0);
529
            goto warn;
530

    
531
        default:
532
            dolog ("unrecognized command %#x\n", cmd);
533
            return;
534
        }
535
    }
536

    
537
    s->cmd = cmd;
538
    if (!s->needed_bytes)
539
        ldebug ("\n");
540
    return;
541

    
542
 warn:
543
    dolog ("warning: command %#x,%d is not trully understood yet\n",
544
           cmd, s->needed_bytes);
545
    s->cmd = cmd;
546
    return;
547
}
548

    
549
static uint16_t dsp_get_lohi (SB16State *s)
550
{
551
    uint8_t hi = dsp_get_data (s);
552
    uint8_t lo = dsp_get_data (s);
553
    return (hi << 8) | lo;
554
}
555

    
556
static uint16_t dsp_get_hilo (SB16State *s)
557
{
558
    uint8_t lo = dsp_get_data (s);
559
    uint8_t hi = dsp_get_data (s);
560
    return (hi << 8) | lo;
561
}
562

    
563
static void complete (SB16State *s)
564
{
565
    int d0, d1, d2;
566
    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
567
            s->cmd, s->in_index, s->needed_bytes);
568

    
569
    if (s->cmd > 0xaf && s->cmd < 0xd0) {
570
        d2 = dsp_get_data (s);
571
        d1 = dsp_get_data (s);
572
        d0 = dsp_get_data (s);
573

    
574
        if (s->cmd & 8) {
575
            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
576
                   s->cmd, d0, d1, d2);
577
        }
578
        else {
579
            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
580
                    s->cmd, d0, d1, d2);
581
            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
582
        }
583
    }
584
    else {
585
        switch (s->cmd) {
586
        case 0x04:
587
            s->csp_mode = dsp_get_data (s);
588
            s->csp_reg83r = 0;
589
            s->csp_reg83w = 0;
590
            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
591
            break;
592

    
593
        case 0x05:
594
            s->csp_param = dsp_get_data (s);
595
            s->csp_value = dsp_get_data (s);
596
            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
597
                    s->csp_param,
598
                    s->csp_value);
599
            break;
600

    
601
        case 0x0e:
602
            d0 = dsp_get_data (s);
603
            d1 = dsp_get_data (s);
604
            ldebug ("write CSP register %d <- %#x\n", d1, d0);
605
            if (d1 == 0x83) {
606
                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
607
                s->csp_reg83[s->csp_reg83r % 4] = d0;
608
                s->csp_reg83r += 1;
609
            }
610
            else
611
                s->csp_regs[d1] = d0;
612
            break;
613

    
614
        case 0x0f:
615
            d0 = dsp_get_data (s);
616
            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
617
                    d0, s->csp_regs[d0], s->csp_mode);
618
            if (d0 == 0x83) {
619
                ldebug ("0x83[%d] -> %#x\n",
620
                        s->csp_reg83w,
621
                        s->csp_reg83[s->csp_reg83w % 4]);
622
                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
623
                s->csp_reg83w += 1;
624
            }
625
            else
626
                dsp_out_data (s, s->csp_regs[d0]);
627
            break;
628

    
629
        case 0x10:
630
            d0 = dsp_get_data (s);
631
            dolog ("cmd 0x10 d0=%#x\n", d0);
632
            break;
633

    
634
        case 0x14:
635
            dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
636
            break;
637

    
638
        case 0x40:
639
            s->time_const = dsp_get_data (s);
640
            ldebug ("set time const %d\n", s->time_const);
641
            break;
642

    
643
        case 0x42:              /* FT2 sets output freq with this, go figure */
644
            dolog ("cmd 0x42 might not do what it think it should\n");
645

    
646
        case 0x41:
647
            s->freq = dsp_get_hilo (s);
648
            ldebug ("set freq %d\n", s->freq);
649
            break;
650

    
651
        case 0x48:
652
            s->block_size = dsp_get_lohi (s) + 1;
653
            ldebug ("set dma block len %d\n", s->block_size);
654
            break;
655

    
656
        case 0x80:
657
            {
658
                int freq, samples, bytes;
659
                int64_t ticks;
660

    
661
                freq = s->freq > 0 ? s->freq : 11025;
662
                samples = dsp_get_lohi (s) + 1;
663
                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
664
                ticks = (bytes * ticks_per_sec) / freq;
665
                if (ticks < ticks_per_sec / 1024)
666
                    pic_set_irq (s->irq, 1);
667
                else
668
                    qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
669
                ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
670
            }
671
            break;
672

    
673
        case 0xe0:
674
            d0 = dsp_get_data (s);
675
            s->out_data_len = 0;
676
            ldebug ("E0 data = %#x\n", d0);
677
            dsp_out_data(s, ~d0);
678
            break;
679

    
680
        case 0xe2:
681
            d0 = dsp_get_data (s);
682
            ldebug ("E2 = %#x\n", d0);
683
            break;
684

    
685
        case 0xe4:
686
            s->test_reg = dsp_get_data (s);
687
            break;
688

    
689
        case 0xf9:
690
            d0 = dsp_get_data (s);
691
            ldebug ("command 0xf9 with %#x\n", d0);
692
            switch (d0) {
693
            case 0x0e:
694
                dsp_out_data (s, 0xff);
695
                break;
696

    
697
            case 0x0f:
698
                dsp_out_data (s, 0x07);
699
                break;
700

    
701
            case 0x37:
702
                dsp_out_data (s, 0x38);
703
                break;
704

    
705
            default:
706
                dsp_out_data (s, 0x00);
707
                break;
708
            }
709
            break;
710

    
711
        default:
712
            dolog ("complete: unrecognized command %#x\n", s->cmd);
713
            return;
714
        }
715
    }
716

    
717
    ldebug ("\n");
718
    s->cmd = -1;
719
    return;
720
}
721

    
722
static void reset (SB16State *s)
723
{
724
    pic_set_irq (s->irq, 0);
725
    if (s->dma_auto) {
726
        pic_set_irq (s->irq, 1);
727
        pic_set_irq (s->irq, 0);
728
    }
729

    
730
    s->mixer_regs[0x82] = 0;
731
    s->dma_auto = 0;
732
    s->in_index = 0;
733
    s->out_data_len = 0;
734
    s->left_till_irq = 0;
735
    s->needed_bytes = 0;
736
    s->block_size = -1;
737
    s->nzero = 0;
738
    s->highspeed = 0;
739
    s->v2x6 = 0;
740

    
741
    dsp_out_data(s, 0xaa);
742
    speaker (s, 0);
743
    control (s, 0);
744
}
745

    
746
static IO_WRITE_PROTO (dsp_write)
747
{
748
    SB16State *s = opaque;
749
    int iport;
750

    
751
    iport = nport - s->port;
752

    
753
    ldebug ("write %#x <- %#x\n", nport, val);
754
    switch (iport) {
755
    case 0x06:
756
        switch (val) {
757
        case 0x00:
758
            if (s->v2x6 == 1) {
759
                if (0 && s->highspeed) {
760
                    s->highspeed = 0;
761
                    pic_set_irq (s->irq, 0);
762
                    control (s, 0);
763
                }
764
                else
765
                    reset (s);
766
            }
767
            s->v2x6 = 0;
768
            break;
769

    
770
        case 0x01:
771
        case 0x03:              /* FreeBSD kludge */
772
            s->v2x6 = 1;
773
            break;
774

    
775
        case 0xc6:
776
            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
777
            break;
778

    
779
        case 0xb8:              /* Panic */
780
            reset (s);
781
            break;
782

    
783
        case 0x39:
784
            dsp_out_data (s, 0x38);
785
            reset (s);
786
            s->v2x6 = 0x39;
787
            break;
788

    
789
        default:
790
            s->v2x6 = val;
791
            break;
792
        }
793
        break;
794

    
795
    case 0x0c:                  /* write data or command | write status */
796
/*         if (s->highspeed) */
797
/*             break; */
798

    
799
        if (0 == s->needed_bytes) {
800
            command (s, val);
801
#if 0
802
            if (0 == s->needed_bytes) {
803
                log_dsp (s);
804
            }
805
#endif
806
        }
807
        else {
808
            if (s->in_index == sizeof (s->in2_data)) {
809
                dolog ("in data overrun\n");
810
            }
811
            else {
812
                s->in2_data[s->in_index++] = val;
813
                if (s->in_index == s->needed_bytes) {
814
                    s->needed_bytes = 0;
815
                    complete (s);
816
#if 0
817
                    log_dsp (s);
818
#endif
819
                }
820
            }
821
        }
822
        break;
823

    
824
    default:
825
        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
826
        break;
827
    }
828
}
829

    
830
static IO_READ_PROTO (dsp_read)
831
{
832
    SB16State *s = opaque;
833
    int iport, retval, ack = 0;
834

    
835
    iport = nport - s->port;
836

    
837
    switch (iport) {
838
    case 0x06:                  /* reset */
839
        retval = 0xff;
840
        break;
841

    
842
    case 0x0a:                  /* read data */
843
        if (s->out_data_len) {
844
            retval = s->out_data[--s->out_data_len];
845
            s->last_read_byte = retval;
846
        }
847
        else {
848
            dolog ("empty output buffer\n");
849
            retval = s->last_read_byte;
850
            /* goto error; */
851
        }
852
        break;
853

    
854
    case 0x0c:                  /* 0 can write */
855
        retval = s->can_write ? 0 : 0x80;
856
        break;
857

    
858
    case 0x0d:                  /* timer interrupt clear */
859
        /* dolog ("timer interrupt clear\n"); */
860
        retval = 0;
861
        break;
862

    
863
    case 0x0e:                  /* data available status | irq 8 ack */
864
        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
865
        if (s->mixer_regs[0x82] & 1) {
866
            ack = 1;
867
            s->mixer_regs[0x82] &= 1;
868
            pic_set_irq (s->irq, 0);
869
        }
870
        break;
871

    
872
    case 0x0f:                  /* irq 16 ack */
873
        retval = 0xff;
874
        if (s->mixer_regs[0x82] & 2) {
875
            ack = 1;
876
            s->mixer_regs[0x82] &= 2;
877
            pic_set_irq (s->irq, 0);
878
        }
879
        break;
880

    
881
    default:
882
        goto error;
883
    }
884

    
885
    if (!ack)
886
        ldebug ("read %#x -> %#x\n", nport, retval);
887

    
888
    return retval;
889

    
890
 error:
891
    dolog ("WARNING dsp_read %#x error\n", nport);
892
    return 0xff;
893
}
894

    
895
static void reset_mixer (SB16State *s)
896
{
897
    int i;
898

    
899
    memset (s->mixer_regs, 0xff, 0x7f);
900
    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
901

    
902
    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
903
    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
904
    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
905
    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
906

    
907
    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
908
    s->mixer_regs[0x0c] = 0;
909

    
910
    /* d5=output filt, d1=stereo switch */
911
    s->mixer_regs[0x0e] = 0;
912

    
913
    /* voice volume L d5,d7, R d1,d3 */
914
    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
915
    /* master ... */
916
    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
917
    /* MIDI ... */
918
    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
919

    
920
    for (i = 0x30; i < 0x48; i++) {
921
        s->mixer_regs[i] = 0x20;
922
    }
923
}
924

    
925
static IO_WRITE_PROTO(mixer_write_indexb)
926
{
927
    SB16State *s = opaque;
928
    s->mixer_nreg = val;
929
}
930

    
931
static IO_WRITE_PROTO(mixer_write_datab)
932
{
933
    SB16State *s = opaque;
934

    
935
    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
936
    if (s->mixer_nreg > sizeof (s->mixer_regs))
937
        return;
938

    
939
    switch (s->mixer_nreg) {
940
    case 0x00:
941
        reset_mixer (s);
942
        break;
943

    
944
    case 0x80:
945
        {
946
            int irq = irq_of_magic (val);
947
            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
948
            if (irq > 0)
949
                s->irq = irq;
950
        }
951
        break;
952

    
953
    case 0x81:
954
        {
955
            int dma, hdma;
956

    
957
            dma = lsbindex (val & 0xf);
958
            hdma = lsbindex (val & 0xf0);
959
            dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
960
                   dma, hdma, val);
961
#if 0
962
            s->dma = dma;
963
            s->hdma = hdma;
964
#endif
965
        }
966
        break;
967

    
968
    case 0x82:
969
        dolog ("attempt to write into IRQ status register (val=%#x)\n",
970
               val);
971
        return;
972

    
973
    default:
974
        if (s->mixer_nreg >= 0x80)
975
            dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
976
        break;
977
    }
978

    
979
    s->mixer_regs[s->mixer_nreg] = val;
980
}
981

    
982
static IO_WRITE_PROTO(mixer_write_indexw)
983
{
984
    mixer_write_indexb (opaque, nport, val & 0xff);
985
    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
986
}
987

    
988
static IO_READ_PROTO(mixer_read)
989
{
990
    SB16State *s = opaque;
991
#ifndef DEBUG_SB16_MOST
992
    if (s->mixer_nreg != 0x82)
993
#endif
994
    ldebug ("mixer_read[%#x] -> %#x\n",
995
            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
996
    return s->mixer_regs[s->mixer_nreg];
997
}
998

    
999
static int write_audio (SB16State *s, int nchan, int dma_pos,
1000
                        int dma_len, int len)
1001
{
1002
    int temp, net;
1003
    uint8_t tmpbuf[4096];
1004

    
1005
    temp = len;
1006
    net = 0;
1007

    
1008
    while (temp) {
1009
        int left = dma_len - dma_pos;
1010
        int to_copy, copied;
1011

    
1012
        to_copy = audio_MIN (temp, left);
1013
        if (to_copy > sizeof(tmpbuf))
1014
            to_copy = sizeof(tmpbuf);
1015

    
1016
        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1017
        copied = AUD_write (s->voice, tmpbuf, copied);
1018

    
1019
        temp -= copied;
1020
        dma_pos = (dma_pos + copied) % dma_len;
1021
        net += copied;
1022

    
1023
        if (!copied)
1024
            break;
1025
    }
1026

    
1027
    return net;
1028
}
1029

    
1030
static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1031
{
1032
    SB16State *s = opaque;
1033
    int free, rfree, till, copy, written, elapsed;
1034

    
1035
    if (s->left_till_irq < 0) {
1036
        s->left_till_irq = s->block_size;
1037
    }
1038

    
1039
    elapsed = AUD_calc_elapsed (s->voice);
1040
    free = elapsed;/* AUD_get_free (s->voice); */
1041
    rfree = free;
1042
    free = audio_MIN (free, elapsed) & ~s->align;
1043

    
1044
    if ((free <= 0) || !dma_len) {
1045
        return dma_pos;
1046
    }
1047

    
1048
    copy = free;
1049
    till = s->left_till_irq;
1050

    
1051
#ifdef DEBUG_SB16_MOST
1052
    dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
1053
           dma_pos, free, AUD_get_free (s->voice), till, dma_len);
1054
#endif
1055

    
1056
    if (till <= copy) {
1057
        if (0 == s->dma_auto) {
1058
            copy = till;
1059
        }
1060
    }
1061

    
1062
    written = write_audio (s, nchan, dma_pos, dma_len, copy);
1063
    dma_pos = (dma_pos + written) % dma_len;
1064
    s->left_till_irq -= written;
1065

    
1066
    if (s->left_till_irq <= 0) {
1067
        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1068
        pic_set_irq (s->irq, 1);
1069
        if (0 == s->dma_auto) {
1070
            control (s, 0);
1071
            speaker (s, 0);
1072
        }
1073
    }
1074

    
1075
#ifdef DEBUG_SB16_MOST
1076
    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1077
            dma_pos, free, dma_len, s->left_till_irq, copy, written,
1078
            s->block_size);
1079
#endif
1080

    
1081
    while (s->left_till_irq <= 0) {
1082
        s->left_till_irq = s->block_size + s->left_till_irq;
1083
    }
1084

    
1085
    AUD_adjust (s->voice, written);
1086
    return dma_pos;
1087
}
1088

    
1089
void SB_timer (void *opaque)
1090
{
1091
    SB16State *s = opaque;
1092
    AUD_run ();
1093
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1094
}
1095

    
1096
static void SB_save (QEMUFile *f, void *opaque)
1097
{
1098
    SB16State *s = opaque;
1099

    
1100
    qemu_put_be32s (f, &s->irq);
1101
    qemu_put_be32s (f, &s->dma);
1102
    qemu_put_be32s (f, &s->hdma);
1103
    qemu_put_be32s (f, &s->port);
1104
    qemu_put_be32s (f, &s->ver);
1105
    qemu_put_be32s (f, &s->in_index);
1106
    qemu_put_be32s (f, &s->out_data_len);
1107
    qemu_put_be32s (f, &s->fmt_stereo);
1108
    qemu_put_be32s (f, &s->fmt_signed);
1109
    qemu_put_be32s (f, &s->fmt_bits);
1110
    qemu_put_be32s (f, &s->fmt);
1111
    qemu_put_be32s (f, &s->dma_auto);
1112
    qemu_put_be32s (f, &s->block_size);
1113
    qemu_put_be32s (f, &s->fifo);
1114
    qemu_put_be32s (f, &s->freq);
1115
    qemu_put_be32s (f, &s->time_const);
1116
    qemu_put_be32s (f, &s->speaker);
1117
    qemu_put_be32s (f, &s->needed_bytes);
1118
    qemu_put_be32s (f, &s->cmd);
1119
    qemu_put_be32s (f, &s->use_hdma);
1120
    qemu_put_be32s (f, &s->highspeed);
1121
    qemu_put_be32s (f, &s->can_write);
1122
    qemu_put_be32s (f, &s->v2x6);
1123

    
1124
    qemu_put_8s (f, &s->csp_param);
1125
    qemu_put_8s (f, &s->csp_value);
1126
    qemu_put_8s (f, &s->csp_mode);
1127
    qemu_put_8s (f, &s->csp_param);
1128
    qemu_put_buffer (f, s->csp_regs, 256);
1129
    qemu_put_8s (f, &s->csp_index);
1130
    qemu_put_buffer (f, s->csp_reg83, 4);
1131
    qemu_put_be32s (f, &s->csp_reg83r);
1132
    qemu_put_be32s (f, &s->csp_reg83w);
1133

    
1134
    qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1135
    qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1136
    qemu_put_8s (f, &s->test_reg);
1137
    qemu_put_8s (f, &s->last_read_byte);
1138

    
1139
    qemu_put_be32s (f, &s->nzero);
1140
    qemu_put_be32s (f, &s->left_till_irq);
1141
    qemu_put_be32s (f, &s->dma_running);
1142
    qemu_put_be32s (f, &s->bytes_per_second);
1143
    qemu_put_be32s (f, &s->align);
1144

    
1145
    qemu_put_be32s (f, &s->mixer_nreg);
1146
    qemu_put_buffer (f, s->mixer_regs, 256);
1147
}
1148

    
1149
static int SB_load (QEMUFile *f, void *opaque, int version_id)
1150
{
1151
    SB16State *s = opaque;
1152

    
1153
    if (version_id != 1)
1154
        return -EINVAL;
1155

    
1156
    qemu_get_be32s (f, &s->irq);
1157
    qemu_get_be32s (f, &s->dma);
1158
    qemu_get_be32s (f, &s->hdma);
1159
    qemu_get_be32s (f, &s->port);
1160
    qemu_get_be32s (f, &s->ver);
1161
    qemu_get_be32s (f, &s->in_index);
1162
    qemu_get_be32s (f, &s->out_data_len);
1163
    qemu_get_be32s (f, &s->fmt_stereo);
1164
    qemu_get_be32s (f, &s->fmt_signed);
1165
    qemu_get_be32s (f, &s->fmt_bits);
1166
    qemu_get_be32s (f, &s->fmt);
1167
    qemu_get_be32s (f, &s->dma_auto);
1168
    qemu_get_be32s (f, &s->block_size);
1169
    qemu_get_be32s (f, &s->fifo);
1170
    qemu_get_be32s (f, &s->freq);
1171
    qemu_get_be32s (f, &s->time_const);
1172
    qemu_get_be32s (f, &s->speaker);
1173
    qemu_get_be32s (f, &s->needed_bytes);
1174
    qemu_get_be32s (f, &s->cmd);
1175
    qemu_get_be32s (f, &s->use_hdma);
1176
    qemu_get_be32s (f, &s->highspeed);
1177
    qemu_get_be32s (f, &s->can_write);
1178
    qemu_get_be32s (f, &s->v2x6);
1179

    
1180
    qemu_get_8s (f, &s->csp_param);
1181
    qemu_get_8s (f, &s->csp_value);
1182
    qemu_get_8s (f, &s->csp_mode);
1183
    qemu_get_8s (f, &s->csp_param);
1184
    qemu_get_buffer (f, s->csp_regs, 256);
1185
    qemu_get_8s (f, &s->csp_index);
1186
    qemu_get_buffer (f, s->csp_reg83, 4);
1187
    qemu_get_be32s (f, &s->csp_reg83r);
1188
    qemu_get_be32s (f, &s->csp_reg83w);
1189

    
1190
    qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1191
    qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1192
    qemu_get_8s (f, &s->test_reg);
1193
    qemu_get_8s (f, &s->last_read_byte);
1194

    
1195
    qemu_get_be32s (f, &s->nzero);
1196
    qemu_get_be32s (f, &s->left_till_irq);
1197
    qemu_get_be32s (f, &s->dma_running);
1198
    qemu_get_be32s (f, &s->bytes_per_second);
1199
    qemu_get_be32s (f, &s->align);
1200

    
1201
    qemu_get_be32s (f, &s->mixer_nreg);
1202
    qemu_get_buffer (f, s->mixer_regs, 256);
1203

    
1204
    if (s->voice) {
1205
        AUD_close (s->voice);
1206
        s->voice = NULL;
1207
    }
1208

    
1209
    if (s->dma_running) {
1210
        if (s->freq)
1211
            s->voice = AUD_open (s->voice, "sb16", s->freq,
1212
                                 1 << s->fmt_stereo, s->fmt);
1213

    
1214
        control (s, 1);
1215
        speaker (s, s->speaker);
1216
    }
1217
    return 0;
1218
}
1219

    
1220
void SB16_init (void)
1221
{
1222
    SB16State *s = &dsp;
1223
    int i;
1224
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1225
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1226

    
1227
    s->ts = qemu_new_timer (vm_clock, SB_timer, s);
1228
    if (!s->ts)
1229
        return;
1230

    
1231
    s->irq = conf.irq;
1232
    s->dma = conf.dma;
1233
    s->hdma = conf.hdma;
1234
    s->port = conf.port;
1235
    s->ver = conf.ver_lo | (conf.ver_hi << 8);
1236

    
1237
    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1238
    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1239
    s->mixer_regs[0x82] = 2 << 5;
1240

    
1241
    s->csp_regs[5] = 1;
1242
    s->csp_regs[9] = 0xf8;
1243

    
1244
    reset_mixer (s);
1245
    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1246
    if (!s->aux_ts)
1247
        return;
1248

    
1249
    for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1250
        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1251
    }
1252

    
1253
    for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1254
        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1255
    }
1256

    
1257
    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1258
    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1259
    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1260
    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1261

    
1262
    DMA_register_channel (s->hdma, SB_read_DMA, s);
1263
    DMA_register_channel (s->dma, SB_read_DMA, s);
1264
    s->can_write = 1;
1265

    
1266
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1267
    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1268
}