0.7.0-alt1
[qemu] / qemu / hw / sb16.c
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 }