Statistics
| Branch: | Revision:

root / hw / sb16.c @ fb065187

History | View | Annotate | Download (30.9 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
#ifdef DEBUG
30
#define ldebug(...) dolog (__VA_ARGS__)
31
#else
32
#define ldebug(...)
33
#endif
34

    
35
/* #define DEBUG */
36
/* #define DEBUG_SB16_MOST */
37

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

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

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

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

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

    
79
    int v2x6;
80

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

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

    
96
    int left_till_irq;
97

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

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

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

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

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

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

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

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

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

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

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

    
191
#define DMA8_AUTO 1
192
#define DMA8_HIGH 2
193

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

    
209
    if (-1 != dma_len)
210
        s->block_size = dma_len + 1;
211

    
212
    s->freq >>= s->fmt_stereo;
213
    s->left_till_irq = s->block_size;
214
    s->bytes_per_second = (s->freq << s->fmt_stereo);
215
    /* s->highspeed = (mask & DMA8_HIGH) != 0; */
216
    s->dma_auto = (mask & DMA8_AUTO) != 0;
217
    s->align = (1 << s->fmt_stereo) - 1;
218

    
219
    ldebug ("freq %d, stereo %d, sign %d, bits %d, "
220
            "dma %d, auto %d, fifo %d, high %d\n",
221
            s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
222
            s->block_size, s->dma_auto, s->fifo, s->highspeed);
223

    
224
    if (s->freq)
225
        s->voice = AUD_open (s->voice, "sb16", s->freq,
226
                             1 << s->fmt_stereo, s->fmt);
227

    
228
    control (s, 1);
229
    speaker (s, 1);
230
}
231

    
232
static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
233
{
234
    s->use_hdma = cmd < 0xc0;
235
    s->fifo = (cmd >> 1) & 1;
236
    s->dma_auto = (cmd >> 2) & 1;
237
    s->fmt_signed = (d0 >> 4) & 1;
238
    s->fmt_stereo = (d0 >> 5) & 1;
239

    
240
    switch (cmd >> 4) {
241
    case 11:
242
        s->fmt_bits = 16;
243
        break;
244

    
245
    case 12:
246
        s->fmt_bits = 8;
247
        break;
248
    }
249

    
250
    if (-1 != s->time_const) {
251
#if 1
252
        int tmp = 256 - s->time_const;
253
        s->freq = (1000000 + (tmp / 2)) / tmp;
254
#else
255
        /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
256
        s->freq = 1000000 / ((255 - s->time_const));
257
#endif
258
        s->time_const = -1;
259
    }
260

    
261
    s->block_size = dma_len + 1;
262
    s->block_size <<= (s->fmt_bits == 16);
263
    if (!s->dma_auto)           /* Miles Sound System ? */
264
        s->block_size <<= s->fmt_stereo;
265

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

    
271
    if (16 == s->fmt_bits) {
272
        if (s->fmt_signed) {
273
            s->fmt = AUD_FMT_S16;
274
        }
275
        else {
276
            s->fmt = AUD_FMT_U16;
277
        }
278
    }
279
    else {
280
        if (s->fmt_signed) {
281
            s->fmt = AUD_FMT_S8;
282
        }
283
        else {
284
            s->fmt = AUD_FMT_U8;
285
        }
286
    }
287

    
288
    s->left_till_irq = s->block_size;
289

    
290
    s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
291
    s->highspeed = 0;
292
    s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
293

    
294
    if (s->freq)
295
        s->voice = AUD_open (s->voice, "sb16", s->freq,
296
                             1 << s->fmt_stereo, s->fmt);
297

    
298
    control (s, 1);
299
    speaker (s, 1);
300
}
301

    
302
static inline void dsp_out_data (SB16State *s, uint8_t val)
303
{
304
    ldebug ("outdata %#x\n", val);
305
    if (s->out_data_len < sizeof (s->out_data))
306
        s->out_data[s->out_data_len++] = val;
307
}
308

    
309
static inline uint8_t dsp_get_data (SB16State *s)
310
{
311
    if (s->in_index)
312
        return s->in2_data[--s->in_index];
313
    else {
314
        dolog ("buffer underflow\n");
315
        return 0;
316
    }
317
}
318

    
319
static void command (SB16State *s, uint8_t cmd)
320
{
321
    ldebug ("command %#x\n", cmd);
322

    
323
    if (cmd > 0xaf && cmd < 0xd0) {
324
        if (cmd & 8) {
325
            dolog ("ADC not yet supported (command %#x)\n", cmd);
326
        }
327

    
328
        switch (cmd >> 4) {
329
        case 11:
330
        case 12:
331
            break;
332
        default:
333
            dolog ("%#x wrong bits\n", cmd);
334
        }
335
        s->needed_bytes = 3;
336
    }
337
    else {
338
        switch (cmd) {
339
        case 0x03:
340
            dsp_out_data (s, 0x10); /* s->csp_param); */
341
            goto warn;
342

    
343
        case 0x04:
344
            s->needed_bytes = 1;
345
            goto warn;
346

    
347
        case 0x05:
348
            s->needed_bytes = 2;
349
            goto warn;
350

    
351
        case 0x08:
352
            /* __asm__ ("int3"); */
353
            goto warn;
354

    
355
        case 0x0e:
356
            s->needed_bytes = 2;
357
            goto warn;
358

    
359
        case 0x09:
360
            dsp_out_data (s, 0xf8);
361
            goto warn;
362

    
363
        case 0x0f:
364
            s->needed_bytes = 1;
365
            goto warn;
366

    
367
        case 0x10:
368
            s->needed_bytes = 1;
369
            goto warn;
370

    
371
        case 0x14:
372
            s->needed_bytes = 2;
373
            s->block_size = 0;
374
            break;
375

    
376
        case 0x20:              /* Direct ADC, Juice/PL */
377
            dsp_out_data (s, 0xff);
378
            goto warn;
379

    
380
        case 0x35:
381
            dolog ("MIDI command(0x35) not implemented\n");
382
            break;
383

    
384
        case 0x40:
385
            s->freq = -1;
386
            s->time_const = -1;
387
            s->needed_bytes = 1;
388
            break;
389

    
390
        case 0x41:
391
            s->freq = -1;
392
            s->time_const = -1;
393
            s->needed_bytes = 2;
394
            break;
395

    
396
        case 0x42:
397
            s->freq = -1;
398
            s->time_const = -1;
399
            s->needed_bytes = 2;
400
            goto warn;
401

    
402
        case 0x45:
403
            dsp_out_data (s, 0xaa);
404
            goto warn;
405

    
406
        case 0x47:                /* Continue Auto-Initialize DMA 16bit */
407
            break;
408

    
409
        case 0x48:
410
            s->needed_bytes = 2;
411
            break;
412

    
413
        case 0x80:
414
            s->needed_bytes = 2;
415
            break;
416

    
417
        case 0x90:
418
        case 0x91:
419
            dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
420
            break;
421

    
422
        case 0xd0:              /* halt DMA operation. 8bit */
423
            control (s, 0);
424
            break;
425

    
426
        case 0xd1:              /* speaker on */
427
            speaker (s, 1);
428
            break;
429

    
430
        case 0xd3:              /* speaker off */
431
            speaker (s, 0);
432
            break;
433

    
434
        case 0xd4:              /* continue DMA operation. 8bit */
435
            control (s, 1);
436
            break;
437

    
438
        case 0xd5:              /* halt DMA operation. 16bit */
439
            control (s, 0);
440
            break;
441

    
442
        case 0xd6:              /* continue DMA operation. 16bit */
443
            control (s, 1);
444
            break;
445

    
446
        case 0xd9:              /* exit auto-init DMA after this block. 16bit */
447
            s->dma_auto = 0;
448
            break;
449

    
450
        case 0xda:              /* exit auto-init DMA after this block. 8bit */
451
            s->dma_auto = 0;
452
            break;
453

    
454
        case 0xe0:
455
            s->needed_bytes = 1;
456
            goto warn;
457

    
458
        case 0xe1:
459
            dsp_out_data (s, s->ver & 0xff);
460
            dsp_out_data (s, s->ver >> 8);
461
            break;
462

    
463
        case 0xe2:
464
            s->needed_bytes = 1;
465
            goto warn;
466

    
467
        case 0xe3:
468
            {
469
                int i;
470
                for (i = sizeof (e3) - 1; i >= 0; --i)
471
                    dsp_out_data (s, e3[i]);
472
            }
473
            break;
474

    
475
        case 0xe4:              /* write test reg */
476
            s->needed_bytes = 1;
477
            break;
478

    
479
        case 0xe7:
480
            dolog ("Attempt to probe for ESS (0xe7)?\n");
481
            return;
482

    
483
        case 0xe8:              /* read test reg */
484
            dsp_out_data (s, s->test_reg);
485
            break;
486

    
487
        case 0xf2:
488
        case 0xf3:
489
            dsp_out_data (s, 0xaa);
490
            s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
491
            pic_set_irq (s->irq, 1);
492
            break;
493

    
494
        case 0xf9:
495
            s->needed_bytes = 1;
496
            goto warn;
497

    
498
        case 0xfa:
499
            dsp_out_data (s, 0);
500
            goto warn;
501

    
502
        case 0xfc:              /* FIXME */
503
            dsp_out_data (s, 0);
504
            goto warn;
505

    
506
        default:
507
            dolog ("unrecognized command %#x\n", cmd);
508
            return;
509
        }
510
    }
511

    
512
    s->cmd = cmd;
513
    if (!s->needed_bytes)
514
        ldebug ("\n");
515
    return;
516

    
517
 warn:
518
    dolog ("warning: command %#x,%d is not trully understood yet\n",
519
           cmd, s->needed_bytes);
520
    s->cmd = cmd;
521
    return;
522
}
523

    
524
static uint16_t dsp_get_lohi (SB16State *s)
525
{
526
    uint8_t hi = dsp_get_data (s);
527
    uint8_t lo = dsp_get_data (s);
528
    return (hi << 8) | lo;
529
}
530

    
531
static uint16_t dsp_get_hilo (SB16State *s)
532
{
533
    uint8_t lo = dsp_get_data (s);
534
    uint8_t hi = dsp_get_data (s);
535
    return (hi << 8) | lo;
536
}
537

    
538
static void complete (SB16State *s)
539
{
540
    int d0, d1, d2;
541
    ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
542
            s->cmd, s->in_index, s->needed_bytes);
543

    
544
    if (s->cmd > 0xaf && s->cmd < 0xd0) {
545
        d2 = dsp_get_data (s);
546
        d1 = dsp_get_data (s);
547
        d0 = dsp_get_data (s);
548

    
549
        if (s->cmd & 8) {
550
            dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
551
                   s->cmd, d0, d1, d2);
552
        }
553
        else {
554
            ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
555
                    s->cmd, d0, d1, d2);
556
            dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
557
        }
558
    }
559
    else {
560
        switch (s->cmd) {
561
        case 0x04:
562
            s->csp_mode = dsp_get_data (s);
563
            s->csp_reg83r = 0;
564
            s->csp_reg83w = 0;
565
            ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
566
            break;
567

    
568
        case 0x05:
569
            s->csp_param = dsp_get_data (s);
570
            s->csp_value = dsp_get_data (s);
571
            ldebug ("CSP command 0x05: param=%#x value=%#x\n",
572
                    s->csp_param,
573
                    s->csp_value);
574
            break;
575

    
576
        case 0x0e:
577
            d0 = dsp_get_data (s);
578
            d1 = dsp_get_data (s);
579
            ldebug ("write CSP register %d <- %#x\n", d1, d0);
580
            if (d1 == 0x83) {
581
                ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
582
                s->csp_reg83[s->csp_reg83r % 4] = d0;
583
                s->csp_reg83r += 1;
584
            }
585
            else
586
                s->csp_regs[d1] = d0;
587
            break;
588

    
589
        case 0x0f:
590
            d0 = dsp_get_data (s);
591
            ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
592
                    d0, s->csp_regs[d0], s->csp_mode);
593
            if (d0 == 0x83) {
594
                ldebug ("0x83[%d] -> %#x\n",
595
                        s->csp_reg83w,
596
                        s->csp_reg83[s->csp_reg83w % 4]);
597
                dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
598
                s->csp_reg83w += 1;
599
            }
600
            else
601
                dsp_out_data (s, s->csp_regs[d0]);
602
            break;
603

    
604
        case 0x10:
605
            d0 = dsp_get_data (s);
606
            dolog ("cmd 0x10 d0=%#x\n", d0);
607
            break;
608

    
609
        case 0x14:
610
            dma_cmd8 (s, 0, dsp_get_lohi (s));
611
            /* s->can_write = 0; */
612
            /* qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + (ticks_per_sec * 320) / 1000000); */
613
            break;
614

    
615
        case 0x40:
616
            s->time_const = dsp_get_data (s);
617
            ldebug ("set time const %d\n", s->time_const);
618
            break;
619

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

    
623
        case 0x41:
624
            s->freq = dsp_get_hilo (s);
625
            ldebug ("set freq %d\n", s->freq);
626
            break;
627

    
628
        case 0x48:
629
            s->block_size = dsp_get_lohi (s);
630
            /* s->highspeed = 1; */
631
            ldebug ("set dma block len %d\n", s->block_size);
632
            break;
633

    
634
        case 0x80:
635
            {
636
                int samples, bytes;
637
                int64_t ticks;
638

    
639
                if (-1 == s->freq)
640
                    s->freq = 11025;
641
                samples = dsp_get_lohi (s);
642
                bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
643
                ticks = ticks_per_sec / (s->freq / bytes);
644
                if (ticks < ticks_per_sec / 1024)
645
                    pic_set_irq (s->irq, 1);
646
                else
647
                    qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
648
                ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
649
            }
650
            break;
651

    
652
        case 0xe0:
653
            d0 = dsp_get_data (s);
654
            s->out_data_len = 0;
655
            ldebug ("E0 data = %#x\n", d0);
656
            dsp_out_data(s, ~d0);
657
            break;
658

    
659
        case 0xe2:
660
            d0 = dsp_get_data (s);
661
            dolog ("E2 = %#x\n", d0);
662
            break;
663

    
664
        case 0xe4:
665
            s->test_reg = dsp_get_data (s);
666
            break;
667

    
668
        case 0xf9:
669
            d0 = dsp_get_data (s);
670
            ldebug ("command 0xf9 with %#x\n", d0);
671
            switch (d0) {
672
            case 0x0e:
673
                dsp_out_data (s, 0xff);
674
                break;
675

    
676
            case 0x0f:
677
                dsp_out_data (s, 0x07);
678
                break;
679

    
680
            case 0x37:
681
                dsp_out_data (s, 0x38);
682
                break;
683

    
684
            default:
685
                dsp_out_data (s, 0x00);
686
                break;
687
            }
688
            break;
689

    
690
        default:
691
            dolog ("complete: unrecognized command %#x\n", s->cmd);
692
            return;
693
        }
694
    }
695

    
696
    ldebug ("\n");
697
    s->cmd = -1;
698
    return;
699
}
700

    
701
static void reset (SB16State *s)
702
{
703
    pic_set_irq (s->irq, 0);
704
    if (s->dma_auto) {
705
        pic_set_irq (s->irq, 1);
706
        pic_set_irq (s->irq, 0);
707
    }
708

    
709
    s->mixer_regs[0x82] = 0;
710
    s->dma_auto = 0;
711
    s->in_index = 0;
712
    s->out_data_len = 0;
713
    s->left_till_irq = 0;
714
    s->needed_bytes = 0;
715
    s->block_size = -1;
716
    s->nzero = 0;
717
    s->highspeed = 0;
718
    s->v2x6 = 0;
719

    
720
    dsp_out_data(s, 0xaa);
721
    speaker (s, 0);
722
    control (s, 0);
723
}
724

    
725
static IO_WRITE_PROTO (dsp_write)
726
{
727
    SB16State *s = opaque;
728
    int iport;
729

    
730
    iport = nport - s->port;
731

    
732
    ldebug ("write %#x <- %#x\n", nport, val);
733
    switch (iport) {
734
    case 0x06:
735
        switch (val) {
736
        case 0x00:
737
            if (s->v2x6 == 1) {
738
                if (0 && s->highspeed) {
739
                    s->highspeed = 0;
740
                    pic_set_irq (s->irq, 0);
741
                    control (s, 0);
742
                }
743
                else
744
                    reset (s);
745
            }
746
            s->v2x6 = 0;
747
            break;
748

    
749
        case 0x01:
750
        case 0x03:              /* FreeBSD kludge */
751
            s->v2x6 = 1;
752
            break;
753

    
754
        case 0xc6:
755
            s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
756
            break;
757

    
758
        case 0xb8:              /* Panic */
759
            reset (s);
760
            break;
761

    
762
        case 0x39:
763
            dsp_out_data (s, 0x38);
764
            reset (s);
765
            s->v2x6 = 0x39;
766
            break;
767

    
768
        default:
769
            s->v2x6 = val;
770
            break;
771
        }
772
        break;
773

    
774
    case 0x0c:                  /* write data or command | write status */
775
/*         if (s->highspeed) */
776
/*             break; */
777

    
778
        if (0 == s->needed_bytes) {
779
            command (s, val);
780
#if 0
781
            if (0 == s->needed_bytes) {
782
                log_dsp (s);
783
            }
784
#endif
785
        }
786
        else {
787
            if (s->in_index == sizeof (s->in2_data)) {
788
                dolog ("in data overrun\n");
789
            }
790
            else {
791
                s->in2_data[s->in_index++] = val;
792
                if (s->in_index == s->needed_bytes) {
793
                    s->needed_bytes = 0;
794
                    complete (s);
795
#if 0
796
                    log_dsp (s);
797
#endif
798
                }
799
            }
800
        }
801
        break;
802

    
803
    default:
804
        ldebug ("(nport=%#x, val=%#x)\n", nport, val);
805
        break;
806
    }
807
}
808

    
809
static IO_READ_PROTO (dsp_read)
810
{
811
    SB16State *s = opaque;
812
    int iport, retval, ack = 0;
813

    
814
    iport = nport - s->port;
815

    
816
    switch (iport) {
817
    case 0x06:                  /* reset */
818
        retval = 0xff;
819
        break;
820

    
821
    case 0x0a:                  /* read data */
822
        if (s->out_data_len) {
823
            retval = s->out_data[--s->out_data_len];
824
            s->last_read_byte = retval;
825
        }
826
        else {
827
            dolog ("empty output buffer\n");
828
            retval = s->last_read_byte;
829
            /* goto error; */
830
        }
831
        break;
832

    
833
    case 0x0c:                  /* 0 can write */
834
        retval = s->can_write ? 0 : 0x80;
835
        break;
836

    
837
    case 0x0d:                  /* timer interrupt clear */
838
        /* dolog ("timer interrupt clear\n"); */
839
        retval = 0;
840
        break;
841

    
842
    case 0x0e:                  /* data available status | irq 8 ack */
843
        retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
844
        if (s->mixer_regs[0x82] & 1) {
845
            ack = 1;
846
            s->mixer_regs[0x82] &= 1;
847
            pic_set_irq (s->irq, 0);
848
        }
849
        break;
850

    
851
    case 0x0f:                  /* irq 16 ack */
852
        retval = 0xff;
853
        if (s->mixer_regs[0x82] & 2) {
854
            ack = 1;
855
            s->mixer_regs[0x82] &= 2;
856
            pic_set_irq (s->irq, 0);
857
        }
858
        break;
859

    
860
    default:
861
        goto error;
862
    }
863

    
864
    if (!ack)
865
        ldebug ("read %#x -> %#x\n", nport, retval);
866

    
867
    return retval;
868

    
869
 error:
870
    dolog ("WARNING dsp_read %#x error\n", nport);
871
    return 0xff;
872
}
873

    
874
static void reset_mixer (SB16State *s)
875
{
876
    int i;
877

    
878
    memset (s->mixer_regs, 0xff, 0x7f);
879
    memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
880

    
881
    s->mixer_regs[0x02] = 4;    /* master volume 3bits */
882
    s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
883
    s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
884
    s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
885

    
886
    /* d5=input filt, d3=lowpass filt, d1,d2=input source */
887
    s->mixer_regs[0x0c] = 0;
888

    
889
    /* d5=output filt, d1=stereo switch */
890
    s->mixer_regs[0x0e] = 0;
891

    
892
    /* voice volume L d5,d7, R d1,d3 */
893
    s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
894
    /* master ... */
895
    s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
896
    /* MIDI ... */
897
    s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
898

    
899
    for (i = 0x30; i < 0x48; i++) {
900
        s->mixer_regs[i] = 0x20;
901
    }
902
}
903

    
904
static IO_WRITE_PROTO(mixer_write_indexb)
905
{
906
    SB16State *s = opaque;
907
    s->mixer_nreg = val;
908
}
909

    
910
static IO_WRITE_PROTO(mixer_write_datab)
911
{
912
    SB16State *s = opaque;
913

    
914
    ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
915
    if (s->mixer_nreg > sizeof (s->mixer_regs))
916
        return;
917

    
918
    switch (s->mixer_nreg) {
919
    case 0x00:
920
        reset_mixer (s);
921
        break;
922

    
923
    case 0x80:
924
        {
925
            int irq = irq_of_magic (val);
926
            ldebug ("setting irq to %d (val=%#x)\n", irq, val);
927
            if (irq > 0)
928
                s->irq = irq;
929
        }
930
        break;
931

    
932
    case 0x81:
933
        {
934
            int dma, hdma;
935

    
936
            dma = lsbindex (val & 0xf);
937
            hdma = lsbindex (val & 0xf0);
938
            dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
939
                   dma, hdma, val);
940
#if 0
941
            s->dma = dma;
942
            s->hdma = hdma;
943
#endif
944
        }
945
        break;
946

    
947
    case 0x82:
948
        dolog ("attempt to write into IRQ status register (val=%#x)\n",
949
               val);
950
        return;
951

    
952
    default:
953
        if (s->mixer_nreg >= 0x80)
954
            dolog ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
955
        break;
956
    }
957

    
958
    s->mixer_regs[s->mixer_nreg] = val;
959
}
960

    
961
static IO_WRITE_PROTO(mixer_write_indexw)
962
{
963
    mixer_write_indexb (opaque, nport, val & 0xff);
964
    mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
965
}
966

    
967
static IO_READ_PROTO(mixer_read)
968
{
969
    SB16State *s = opaque;
970
    ldebug ("mixer_read[%#x] -> %#x\n",
971
            s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
972
    return s->mixer_regs[s->mixer_nreg];
973
}
974

    
975
static int write_audio (SB16State *s, int nchan, int dma_pos,
976
                        int dma_len, int len)
977
{
978
    int temp, net;
979
    uint8_t tmpbuf[4096];
980

    
981
    temp = len;
982
    net = 0;
983

    
984
    while (temp) {
985
        int left = dma_len - dma_pos;
986
        int to_copy, copied;
987

    
988
        to_copy = audio_MIN (temp, left);
989
        if (to_copy > sizeof(tmpbuf))
990
            to_copy = sizeof(tmpbuf);
991

    
992
        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
993
        copied = AUD_write (s->voice, tmpbuf, copied);
994

    
995
        temp -= copied;
996
        dma_pos = (dma_pos + copied) % dma_len;
997
        net += copied;
998

    
999
        if (!copied)
1000
            break;
1001
    }
1002

    
1003
    return net;
1004
}
1005

    
1006
static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1007
{
1008
    SB16State *s = opaque;
1009
    int free, rfree, till, copy, written, elapsed;
1010

    
1011
    if (s->left_till_irq < 0) {
1012
        s->left_till_irq = s->block_size;
1013
    }
1014

    
1015
    elapsed = AUD_calc_elapsed (s->voice);
1016
    free = elapsed;/* AUD_get_free (s->voice); */
1017
    rfree = free;
1018
    free = audio_MIN (free, elapsed) & ~s->align;
1019

    
1020
    if ((free <= 0) || !dma_len) {
1021
        return dma_pos;
1022
    }
1023

    
1024
    copy = free;
1025
    till = s->left_till_irq;
1026

    
1027
#ifdef DEBUG_SB16_MOST
1028
    dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
1029
           dma_pos, free, AUD_get_free (s->voice), till, dma_len);
1030
#endif
1031

    
1032
    if (till <= copy) {
1033
        if (0 == s->dma_auto) {
1034
            copy = till;
1035
        }
1036
    }
1037

    
1038
    written = write_audio (s, nchan, dma_pos, dma_len, copy);
1039
    dma_pos = (dma_pos + written) % dma_len;
1040
    s->left_till_irq -= written;
1041

    
1042
    if (s->left_till_irq <= 0) {
1043
        s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1044
        pic_set_irq (s->irq, 1);
1045
        if (0 == s->dma_auto) {
1046
            control (s, 0);
1047
            speaker (s, 0);
1048
        }
1049
    }
1050

    
1051
#ifdef DEBUG_SB16_MOST
1052
    ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
1053
            dma_pos, free, dma_len, s->left_till_irq, copy, s->block_size);
1054
#endif
1055

    
1056
    while (s->left_till_irq <= 0) {
1057
        s->left_till_irq = s->block_size + s->left_till_irq;
1058
    }
1059

    
1060
    AUD_adjust (s->voice, written);
1061
    return dma_pos;
1062
}
1063

    
1064
void SB_timer (void *opaque)
1065
{
1066
    SB16State *s = opaque;
1067
    AUD_run ();
1068
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1069
}
1070

    
1071
static void SB_save (QEMUFile *f, void *opaque)
1072
{
1073
    SB16State *s = opaque;
1074

    
1075
    qemu_put_be32s (f, &s->irq);
1076
    qemu_put_be32s (f, &s->dma);
1077
    qemu_put_be32s (f, &s->hdma);
1078
    qemu_put_be32s (f, &s->port);
1079
    qemu_put_be32s (f, &s->ver);
1080
    qemu_put_be32s (f, &s->in_index);
1081
    qemu_put_be32s (f, &s->out_data_len);
1082
    qemu_put_be32s (f, &s->fmt_stereo);
1083
    qemu_put_be32s (f, &s->fmt_signed);
1084
    qemu_put_be32s (f, &s->fmt_bits);
1085
    qemu_put_be32s (f, &s->fmt);
1086
    qemu_put_be32s (f, &s->dma_auto);
1087
    qemu_put_be32s (f, &s->block_size);
1088
    qemu_put_be32s (f, &s->fifo);
1089
    qemu_put_be32s (f, &s->freq);
1090
    qemu_put_be32s (f, &s->time_const);
1091
    qemu_put_be32s (f, &s->speaker);
1092
    qemu_put_be32s (f, &s->needed_bytes);
1093
    qemu_put_be32s (f, &s->cmd);
1094
    qemu_put_be32s (f, &s->use_hdma);
1095
    qemu_put_be32s (f, &s->highspeed);
1096
    qemu_put_be32s (f, &s->can_write);
1097
    qemu_put_be32s (f, &s->v2x6);
1098

    
1099
    qemu_put_8s (f, &s->csp_param);
1100
    qemu_put_8s (f, &s->csp_value);
1101
    qemu_put_8s (f, &s->csp_mode);
1102
    qemu_put_8s (f, &s->csp_param);
1103
    qemu_put_buffer (f, s->csp_regs, 256);
1104
    qemu_put_8s (f, &s->csp_index);
1105
    qemu_put_buffer (f, s->csp_reg83, 4);
1106
    qemu_put_be32s (f, &s->csp_reg83r);
1107
    qemu_put_be32s (f, &s->csp_reg83w);
1108

    
1109
    qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1110
    qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1111
    qemu_put_8s (f, &s->test_reg);
1112
    qemu_put_8s (f, &s->last_read_byte);
1113

    
1114
    qemu_put_be32s (f, &s->nzero);
1115
    qemu_put_be32s (f, &s->left_till_irq);
1116
    qemu_put_be32s (f, &s->dma_running);
1117
    qemu_put_be32s (f, &s->bytes_per_second);
1118
    qemu_put_be32s (f, &s->align);
1119

    
1120
    qemu_put_be32s (f, &s->mixer_nreg);
1121
    qemu_put_buffer (f, s->mixer_regs, 256);
1122
}
1123

    
1124
static int SB_load (QEMUFile *f, void *opaque, int version_id)
1125
{
1126
    SB16State *s = opaque;
1127

    
1128
    if (version_id != 1)
1129
        return -EINVAL;
1130

    
1131
    qemu_get_be32s (f, &s->irq);
1132
    qemu_get_be32s (f, &s->dma);
1133
    qemu_get_be32s (f, &s->hdma);
1134
    qemu_get_be32s (f, &s->port);
1135
    qemu_get_be32s (f, &s->ver);
1136
    qemu_get_be32s (f, &s->in_index);
1137
    qemu_get_be32s (f, &s->out_data_len);
1138
    qemu_get_be32s (f, &s->fmt_stereo);
1139
    qemu_get_be32s (f, &s->fmt_signed);
1140
    qemu_get_be32s (f, &s->fmt_bits);
1141
    qemu_get_be32s (f, &s->fmt);
1142
    qemu_get_be32s (f, &s->dma_auto);
1143
    qemu_get_be32s (f, &s->block_size);
1144
    qemu_get_be32s (f, &s->fifo);
1145
    qemu_get_be32s (f, &s->freq);
1146
    qemu_get_be32s (f, &s->time_const);
1147
    qemu_get_be32s (f, &s->speaker);
1148
    qemu_get_be32s (f, &s->needed_bytes);
1149
    qemu_get_be32s (f, &s->cmd);
1150
    qemu_get_be32s (f, &s->use_hdma);
1151
    qemu_get_be32s (f, &s->highspeed);
1152
    qemu_get_be32s (f, &s->can_write);
1153
    qemu_get_be32s (f, &s->v2x6);
1154

    
1155
    qemu_get_8s (f, &s->csp_param);
1156
    qemu_get_8s (f, &s->csp_value);
1157
    qemu_get_8s (f, &s->csp_mode);
1158
    qemu_get_8s (f, &s->csp_param);
1159
    qemu_get_buffer (f, s->csp_regs, 256);
1160
    qemu_get_8s (f, &s->csp_index);
1161
    qemu_get_buffer (f, s->csp_reg83, 4);
1162
    qemu_get_be32s (f, &s->csp_reg83r);
1163
    qemu_get_be32s (f, &s->csp_reg83w);
1164

    
1165
    qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1166
    qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1167
    qemu_get_8s (f, &s->test_reg);
1168
    qemu_get_8s (f, &s->last_read_byte);
1169

    
1170
    qemu_get_be32s (f, &s->nzero);
1171
    qemu_get_be32s (f, &s->left_till_irq);
1172
    qemu_get_be32s (f, &s->dma_running);
1173
    qemu_get_be32s (f, &s->bytes_per_second);
1174
    qemu_get_be32s (f, &s->align);
1175

    
1176
    qemu_get_be32s (f, &s->mixer_nreg);
1177
    qemu_get_buffer (f, s->mixer_regs, 256);
1178

    
1179
    if (s->voice) {
1180
        AUD_close (s->voice);
1181
        s->voice = NULL;
1182
    }
1183

    
1184
    if (s->dma_running) {
1185
        if (s->freq)
1186
            s->voice = AUD_open (s->voice, "sb16", s->freq,
1187
                                 1 << s->fmt_stereo, s->fmt);
1188

    
1189
        control (s, 1);
1190
        speaker (s, s->speaker);
1191
    }
1192
    return 0;
1193
}
1194

    
1195
void SB16_init (void)
1196
{
1197
    SB16State *s = &dsp;
1198
    int i;
1199
    static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1200
    static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1201

    
1202
    s->ts = qemu_new_timer (vm_clock, SB_timer, s);
1203
    if (!s->ts)
1204
        return;
1205

    
1206
    s->irq = conf.irq;
1207
    s->dma = conf.dma;
1208
    s->hdma = conf.hdma;
1209
    s->port = conf.port;
1210
    s->ver = conf.ver_lo | (conf.ver_hi << 8);
1211

    
1212
    s->mixer_regs[0x80] = magic_of_irq (s->irq);
1213
    s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1214
    s->mixer_regs[0x82] = 2 << 5;
1215

    
1216
    s->csp_regs[5] = 1;
1217
    s->csp_regs[9] = 0xf8;
1218

    
1219
    reset_mixer (s);
1220
    s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1221
    if (!s->aux_ts)
1222
        return;
1223

    
1224
    for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1225
        register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1226
    }
1227

    
1228
    for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1229
        register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1230
    }
1231

    
1232
    register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1233
    register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1234
    register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1235
    register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1236

    
1237
    DMA_register_channel (s->hdma, SB_read_DMA, s);
1238
    DMA_register_channel (s->dma, SB_read_DMA, s);
1239
    s->can_write = 1;
1240

    
1241
    qemu_mod_timer (s->ts, qemu_get_clock (vm_clock) + 1);
1242
    register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1243
}