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