sb16 patch (malc)
[qemu] / hw / sb16.c
1 /*
2  * QEMU Soundblaster 16 emulation
3  * 
4  * Copyright (c) 2003 Vassili Karpov (malc)
5  * 
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <inttypes.h>
27
28 #include "vl.h"
29
30 #define MIN(a, b) ((a)>(b)?(b):(a))
31 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
32
33 #define DEREF(x) (void)x
34 #define log(...) fprintf (stderr, "sb16: " __VA_ARGS__)
35 #define Fail(...) do {                          \
36     fprintf (stderr, "sb16: " __VA_ARGS__);     \
37     abort ();                                   \
38 } while (0)
39
40 /* #define DEBUG_SB16 */
41 #ifdef DEBUG_SB16
42 #define lwarn(...) fprintf (stderr, "sb16: " __VA_ARGS__)
43 #define linfo(...) fprintf (stderr, "sb16: " __VA_ARGS__)
44 #define ldebug(...) fprintf (stderr, "sb16: " __VA_ARGS__)
45 #else
46 #define lwarn(...)
47 #define linfo(...)
48 #define ldebug(...)
49 #endif
50
51 #define IO_READ_PROTO(name) \
52     uint32_t name (struct CPUState *env, uint32_t nport)
53 #define IO_WRITE_PROTO(name) \
54     void name (struct CPUState *env, uint32_t nport, uint32_t val)
55
56 static struct {
57     int ver_lo;
58     int ver_hi;
59     int irq;
60     int dma;
61     int hdma;
62     int port;
63     int mix_block;
64 } sb = {5, 4, 5, 1, 5, 0x220, -1};
65
66 static int mix_block, noirq;
67
68 static struct mixer {
69     int nreg;
70     uint8_t regs[0x83];
71 } mixer;
72
73 static struct dsp {
74     int in_index;
75     int out_data_len;
76     int fmt_stereo;
77     int fmt_signed;
78     int fmt_bits;
79     int dma_auto;
80     int dma_buffer_size;
81     int fifo;
82     int freq;
83     int time_const;
84     int speaker;
85     int needed_bytes;
86     int cmd;
87     int dma_pos;
88     int use_hdma;
89
90     int v2x6;
91
92     uint8_t in_data[10];
93     uint8_t out_data[10];
94
95     int left_till_irq;
96 } dsp;
97
98 #define nocmd ~0
99
100 static void log_dsp (const char *cap)
101 {
102     DEREF (cap);
103
104     linfo ("%c:%c:%d:%c:dmabuf=%d:pos=%d:freq=%d:timeconst=%d:speaker=%d\n",
105            dsp.fmt_stereo ? 'S' : 'M',
106            dsp.fmt_signed ? 'S' : 'U',
107            dsp.fmt_bits,
108            dsp.dma_auto ? 'a' : 's',
109            dsp.dma_buffer_size,
110            dsp.dma_pos,
111            dsp.freq,
112            dsp.time_const,
113            dsp.speaker);
114 }
115
116 static void control (int hold)
117 {
118     linfo ("%d high %d\n", hold, dsp.use_hdma);
119     if (hold) {
120         if (dsp.use_hdma)
121             DMA_hold_DREQ (sb.hdma);
122         else
123             DMA_hold_DREQ (sb.dma);
124     }
125     else {
126         if (dsp.use_hdma)
127             DMA_release_DREQ (sb.hdma);
128         else
129             DMA_release_DREQ (sb.dma);
130     }
131 }
132
133 static void dma_cmd (uint8_t cmd, uint8_t d0, int dma_len)
134 {
135     int bps;
136     audfmt_e fmt;
137
138     dsp.use_hdma = cmd < 0xc0;
139     dsp.fifo = (cmd >> 1) & 1;
140     dsp.dma_auto = (cmd >> 2) & 1;
141
142     switch (cmd >> 4) {
143     case 11:
144         dsp.fmt_bits = 16;
145         break;
146
147     case 12:
148         dsp.fmt_bits = 8;
149         break;
150     }
151
152     dsp.fmt_signed = (d0 >> 4) & 1;
153     dsp.fmt_stereo = (d0 >> 5) & 1;
154
155     if (-1 != dsp.time_const) {
156         int tmp;
157
158         tmp = 256 - dsp.time_const;
159         dsp.freq = (1000000 + (tmp / 2)) / tmp;
160     }
161     bps = 1 << (16 == dsp.fmt_bits);
162
163     if (-1 != dma_len)
164         dsp.dma_buffer_size = (dma_len + 1) * bps;
165
166     linfo ("frequency %d, stereo %d, signed %d, bits %d, size %d, auto %d\n",
167            dsp.freq, dsp.fmt_stereo, dsp.fmt_signed, dsp.fmt_bits,
168            dsp.dma_buffer_size, dsp.dma_auto);
169
170     if (16 == dsp.fmt_bits) {
171         if (dsp.fmt_signed) {
172             fmt = AUD_FMT_S16;
173         }
174         else {
175             fmt = AUD_FMT_U16;
176         }
177     }
178     else {
179         if (dsp.fmt_signed) {
180             fmt = AUD_FMT_S8;
181         }
182         else {
183             fmt = AUD_FMT_U8;
184         }
185     }
186
187     dsp.dma_pos = 0;
188     dsp.left_till_irq = dsp.dma_buffer_size;
189
190     if (sb.mix_block) {
191         mix_block = sb.mix_block;
192     }
193     else {
194         int align;
195
196         align = bps << dsp.fmt_stereo;
197         mix_block = ((dsp.freq * align) / 100) & ~(align - 1);
198     }
199
200     AUD_reset (dsp.freq, 1 << dsp.fmt_stereo, fmt);
201     control (1);
202     dsp.speaker = 1;
203 }
204
205 static void command (uint8_t cmd)
206 {
207     char *msg;
208
209     msg = (char *) -1;
210
211     linfo ("%#x\n", cmd);
212
213     if (cmd > 0xaf && cmd < 0xd0) {
214         if (cmd & 8)
215             goto error;
216
217         switch (cmd >> 4) {
218         case 11:
219         case 12:
220             break;
221         default:
222             msg = "wrong bits";
223             goto error;
224         }
225         dsp.needed_bytes = 3;
226     }
227     else {
228         switch (cmd) {
229         case 0x00:
230         case 0x03:
231         case 0xe7:
232             /* IMS uses those when probing for sound devices */
233             return;
234
235         case 0x10:
236             dsp.needed_bytes = 1;
237             break;
238
239         case 0x14:
240             dsp.needed_bytes = 2;
241             dsp.dma_buffer_size = 0;
242             break;
243
244         case 0x20:
245             dsp.out_data[dsp.out_data_len++] = 0xff;
246             break;
247
248         case 0x35:
249             lwarn ("MIDI commands not implemented\n");
250             break;
251
252         case 0x40:
253             dsp.freq = -1;
254             dsp.time_const = -1;
255             dsp.needed_bytes = 1;
256             break;
257
258         case 0x41:
259         case 0x42:
260             dsp.freq = -1;
261             dsp.time_const = -1;
262             dsp.needed_bytes = 2;
263             break;
264
265         case 0x47:                /* Continue Auto-Initialize DMA 16bit */
266             break;
267
268         case 0x48:
269             dsp.needed_bytes = 2;
270             break;
271
272         case 0x27:                /* ????????? */
273         case 0x4e:
274             return;
275
276         case 0x80:
277             cmd = nocmd;
278             break;
279
280         case 0x90:
281         case 0x91:
282             {
283                 uint8_t d0;
284
285                 d0 = 4;
286                 if (dsp.fmt_signed) d0 |= 16;
287                 if (dsp.fmt_stereo) d0 |= 32;
288                 dma_cmd (cmd == 0x90 ? 0xc4 : 0xc0, d0, -1);
289                 cmd = nocmd;
290                 break;
291             }
292
293         case 0xd0:                /* XXX */
294             control (0);
295             return;
296
297         case 0xd1:
298             dsp.speaker = 1;
299             break;
300
301         case 0xd3:
302             dsp.speaker = 0;
303             return;
304
305         case 0xd4:
306             control (1);
307             break;
308
309         case 0xd5:
310             control (0);
311             break;
312
313         case 0xd6:
314             control (1);
315             break;
316
317         case 0xd9:
318             control (0);
319             dsp.dma_auto = 0;
320             return;
321
322         case 0xda:
323             control (0);
324             dsp.dma_auto = 0;
325             break;
326
327         case 0xe0:
328             dsp.needed_bytes = 1;
329             break;
330
331         case 0xe1:
332             dsp.out_data[dsp.out_data_len++] = sb.ver_lo;
333             dsp.out_data[dsp.out_data_len++] = sb.ver_hi;
334             return;
335
336         case 0xf2:
337             dsp.out_data[dsp.out_data_len++] = 0xaa;
338             mixer.regs[0x82] |= mixer.regs[0x80];
339             pic_set_irq (sb.irq, 1);
340             return;
341
342         default:
343             msg = "is unknown";
344             goto error;
345         }
346     }
347     dsp.cmd = cmd;
348     return;
349
350  error:
351     Fail ("%#x %s", cmd, msg);
352     return;
353 }
354
355 static void complete (void)
356 {
357     linfo ("complete command %#x, in_index %d, needed_bytes %d\n",
358            dsp.cmd, dsp.in_index, dsp.needed_bytes);
359
360     if (dsp.cmd > 0xaf && dsp.cmd < 0xd0) {
361         int d0, d1, d2;
362
363         d0 = dsp.in_data[0];
364         d1 = dsp.in_data[1];
365         d2 = dsp.in_data[2];
366
367         ldebug ("d0 = %d, d1 = %d, d2 = %d\n",
368                 d0, d1, d2);
369         dma_cmd (dsp.cmd, d0, d1 + (d2 << 8));
370     }
371     else {
372         switch (dsp.cmd) {
373
374         case 0x10:
375             break;
376
377         case 0x14:
378             {
379                 int d0, d1;
380                 int save_left;
381                 int save_pos;
382
383                 d0 = dsp.in_data[0];
384                 d1 = dsp.in_data[1];
385
386                 save_left = dsp.left_till_irq;
387                 save_pos = dsp.dma_pos;
388                 dma_cmd (0xc0, 0, d0 + (d1 << 8));
389                 dsp.left_till_irq = save_left;
390                 dsp.dma_pos = save_pos;
391
392                 linfo ("set buffer size data[%d, %d] %d pos %d\n",
393                        d0, d1, dsp.dma_buffer_size, dsp.dma_pos);
394                 break;
395             }
396
397         case 0x40:
398             dsp.time_const = dsp.in_data[0];
399             linfo ("set time const %d\n", dsp.time_const);
400             break;
401
402         case 0x41:
403         case 0x42:
404             dsp.freq = dsp.in_data[1] + (dsp.in_data[0] << 8);
405             linfo ("set freq %#x, %#x = %d\n",
406                    dsp.in_data[1], dsp.in_data[0], dsp.freq);
407             break;
408
409         case 0x48:
410             dsp.dma_buffer_size = dsp.in_data[1] + (dsp.in_data[0] << 8);
411             linfo ("set dma len %#x, %#x = %d\n",
412                    dsp.in_data[1], dsp.in_data[0], dsp.dma_buffer_size);
413             break;
414
415         case 0xe0:
416             dsp.out_data_len = 1;
417             linfo ("data = %#x\n", dsp.in_data[0]);
418             dsp.out_data[0] = dsp.in_data[0] ^ 0xff;
419             break;
420
421         default:
422             goto error;
423         }
424     }
425
426     dsp.cmd = -1;
427     return;
428
429  error:
430     Fail ("unrecognized command %#x", dsp.cmd);
431 }
432
433 static IO_WRITE_PROTO (dsp_write)
434 {
435     int iport;
436
437     iport = nport - sb.port;
438
439     switch (iport) {
440     case 0x6:
441         if (0 == val)
442             dsp.v2x6 = 0;
443         else if ((1 == val) && (0 == dsp.v2x6)) {
444             dsp.v2x6 = 1;
445             dsp.out_data[dsp.out_data_len++] = 0xaa;
446         }
447         else
448             dsp.v2x6 = ~0;
449         break;
450
451     case 0xc:                   /* write data or command | write status */
452         if (0 == dsp.needed_bytes) {
453             command (val);
454             if (0 == dsp.needed_bytes) {
455                 log_dsp (__func__);
456             }
457         }
458         else {
459             dsp.in_data[dsp.in_index++] = val;
460             if (dsp.in_index == dsp.needed_bytes) {
461                 dsp.needed_bytes = 0;
462                 dsp.in_index = 0;
463                 complete ();
464                 log_dsp (__func__);
465             }
466         }
467         break;
468
469     default:
470         Fail ("(nport=%#x, val=%#x)", nport, val);
471     }
472 }
473
474 static IO_READ_PROTO (dsp_read)
475 {
476     char *msg;
477     int iport, retval;
478
479     msg = (char *) -1;
480     iport = nport - sb.port;
481
482     switch (iport) {
483
484     case 0x6:                   /* reset */
485         return 0;
486
487     case 0xa:                   /* read data */
488         if (dsp.out_data_len) {
489             retval = dsp.out_data[--dsp.out_data_len];
490         }
491         else {
492 #if 1
493             lwarn ("empty output buffer\n");
494             retval = 0;
495 #else
496             msg = "empty output buffer";
497             goto error;
498 #endif
499         }
500         break;
501
502     case 0xc:                   /* 0 can write */
503         retval = 0;
504         break;
505
506     case 0xd:                   /* timer interrupt clear */
507         goto error;
508
509     case 0xe:                   /* data available status | irq 8 ack */
510         /* XXX drop pic irq line here? */
511         ldebug ("8 ack\n");
512         retval = (0 == dsp.out_data_len) ? 0 : 0x80;
513         mixer.regs[0x82] &= ~mixer.regs[0x80];
514         pic_set_irq (sb.irq, 0);
515         break;
516
517     case 0xf:                   /* irq 16 ack */
518         /* XXX drop pic irq line here? */
519         ldebug ("16 ack\n");
520         retval = 0xff;
521         mixer.regs[0x82] &= ~mixer.regs[0x80];
522         pic_set_irq (sb.irq, 0);
523         break;
524
525     default:
526         goto error;
527     }
528
529     if ((0xc != iport) && (0xe != iport)) {
530         ldebug ("nport=%#x iport %#x = %#x\n",
531                 nport, iport, retval);
532     }
533
534     return retval;
535
536  error:
537     Fail ("(nport=%#x) %s",  nport, msg);
538 }
539
540 static IO_WRITE_PROTO(mixer_write_indexb)
541 {
542     mixer.nreg = val & 0xff;
543 }
544
545 static IO_WRITE_PROTO(mixer_write_datab)
546 {
547     mixer.regs[mixer.nreg] = val;
548 }
549
550 static IO_WRITE_PROTO(mixer_write_indexw)
551 {
552     mixer_write_indexb (env, nport, val & 0xff);
553     mixer_write_datab (env, nport, (val >> 8) & 0xff);
554 }
555
556 static IO_READ_PROTO(mixer_read)
557 {
558     return mixer.regs[mixer.nreg];
559 }
560
561 void SB16_run (void)
562 {
563     if (0 == dsp.speaker)
564         return;
565
566     AUD_run ();
567 }
568
569 static int write_audio (uint32_t addr, int len, int size)
570 {
571     int temp, net;
572
573     temp = size;
574
575     net = 0;
576
577     while (temp) {
578         int left_till_end;
579         int to_copy;
580         int copied;
581
582         left_till_end = len - dsp.dma_pos;
583
584         to_copy = MIN (temp, left_till_end);
585
586         copied = AUD_write ((void *) (addr + dsp.dma_pos), to_copy);
587
588         temp -= copied;
589         dsp.dma_pos += copied;
590
591         if (dsp.dma_pos == len) {
592             dsp.dma_pos = 0;
593         }
594
595         net += copied;
596
597         if (copied != to_copy)
598             return net;
599     }
600
601     return net;
602 }
603
604 static int SB_read_DMA (uint32_t addr, int size, int *_irq)
605 {
606     int free, till, copy, written;
607
608     if (0 == dsp.speaker)
609         return 0;
610
611     if (dsp.left_till_irq < 0) {
612         dsp.left_till_irq += dsp.dma_buffer_size;
613         return dsp.dma_pos;
614     }
615
616     free = AUD_get_free ();
617
618     if ((free <= 0) || (0 == size)) {
619         return dsp.dma_pos;
620     }
621
622     if (mix_block > 0) {
623         copy = MIN (free, mix_block);
624     }
625     else {
626         copy = free;
627     }
628
629     till = dsp.left_till_irq;
630
631     ldebug ("addr:%#010x free:%d till:%d size:%d\n",
632             addr, free, till, size);
633     if (till <= copy) {
634         if (0 == dsp.dma_auto) {
635             copy = till;
636         }
637     }
638
639     written = write_audio (addr, size, copy);
640     dsp.left_till_irq -= written;
641     AUD_adjust_estimate (free - written);
642
643     if (dsp.left_till_irq <= 0) {
644         mixer.regs[0x82] |= mixer.regs[0x80];
645         if (0 == noirq) {
646             ldebug ("request irq\n");
647             *_irq = sb.irq;
648         }
649
650         if (0 == dsp.dma_auto) {
651             control (0);
652         }
653     }
654
655     ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
656             dsp.dma_pos, free, size, dsp.left_till_irq, copy,
657             dsp.dma_buffer_size);
658
659     if (dsp.left_till_irq <= 0) {
660         dsp.left_till_irq += dsp.dma_buffer_size;
661     }
662
663     return dsp.dma_pos;
664 }
665
666 static int dma_misc_handler (int moo)
667 {
668     return -1;
669 }
670
671 static int magic_of_irq (int irq)
672 {
673     switch (irq) {
674     case 2:
675         return 1;
676     case 5:
677         return 2;
678     case 7:
679         return 4;
680     case 10:
681         return 8;
682     default:
683         log ("bad irq %d\n", irq);
684         return 2;
685     }
686 }
687
688 static int irq_of_magic (int magic)
689 {
690     switch (magic) {
691     case 1:
692         return 2;
693     case 2:
694         return 5;
695     case 4:
696         return 7;
697     case 8:
698         return 10;
699     default:
700         log ("bad irq magic %d\n", magic);
701         return 2;
702     }
703 }
704
705 void SB16_init (void)
706 {
707     int i;
708     static const uint8_t dsp_write_ports[] = {0x6, 0xc};
709     static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
710
711     mixer.regs[0x0e] = ~0;
712     mixer.regs[0x80] = magic_of_irq (sb.irq);
713     mixer.regs[0x81] = 0x20 | (sb.dma << 1);
714
715     DEREF (irq_of_magic);
716
717     for (i = 0x30; i < 0x48; i++) {
718         mixer.regs[i] = 0x20;
719     }
720
721     for (i = 0; i < LENOFA (dsp_write_ports); i++) {
722         register_ioport_write (sb.port + dsp_write_ports[i], 1, dsp_write, 1);
723     }
724
725     for (i = 0; i < LENOFA (dsp_read_ports); i++) {
726         register_ioport_read (sb.port + dsp_read_ports[i], 1, dsp_read, 1);
727     }
728
729     register_ioport_write (sb.port + 0x4, 1, mixer_write_indexb, 1);
730     register_ioport_write (sb.port + 0x4, 1, mixer_write_indexw, 2);
731     register_ioport_read (sb.port + 0x5, 1, mixer_read, 1);
732     register_ioport_write (sb.port + 0x5, 1, mixer_write_datab, 1);
733
734     DMA_register_channel (sb.hdma, SB_read_DMA, dma_misc_handler);
735     DMA_register_channel (sb.dma, SB_read_DMA, dma_misc_handler);
736 }