]> Git Repo - qemu.git/blob - hw/sb16.c
change all rt_clock references to use millisecond resolution accessors
[qemu.git] / hw / sb16.c
1 /*
2  * QEMU Soundblaster 16 emulation
3  *
4  * Copyright (c) 2003-2005 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 "hw.h"
25 #include "audiodev.h"
26 #include "audio/audio.h"
27 #include "isa.h"
28 #include "qdev.h"
29 #include "qemu-timer.h"
30 #include "host-utils.h"
31
32 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
33
34 /* #define DEBUG */
35 /* #define DEBUG_SB16_MOST */
36
37 #ifdef DEBUG
38 #define ldebug(...) dolog (__VA_ARGS__)
39 #else
40 #define ldebug(...)
41 #endif
42
43 #define IO_READ_PROTO(name)                             \
44     uint32_t name (void *opaque, uint32_t nport)
45 #define IO_WRITE_PROTO(name)                                    \
46     void name (void *opaque, uint32_t nport, uint32_t val)
47
48 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
49
50 typedef struct SB16State {
51     ISADevice dev;
52     QEMUSoundCard card;
53     qemu_irq pic;
54     uint32_t irq;
55     uint32_t dma;
56     uint32_t hdma;
57     uint32_t port;
58     uint32_t ver;
59
60     int in_index;
61     int out_data_len;
62     int fmt_stereo;
63     int fmt_signed;
64     int fmt_bits;
65     audfmt_e fmt;
66     int dma_auto;
67     int block_size;
68     int fifo;
69     int freq;
70     int time_const;
71     int speaker;
72     int needed_bytes;
73     int cmd;
74     int use_hdma;
75     int highspeed;
76     int can_write;
77
78     int v2x6;
79
80     uint8_t csp_param;
81     uint8_t csp_value;
82     uint8_t csp_mode;
83     uint8_t csp_regs[256];
84     uint8_t csp_index;
85     uint8_t csp_reg83[4];
86     int csp_reg83r;
87     int csp_reg83w;
88
89     uint8_t in2_data[10];
90     uint8_t out_data[50];
91     uint8_t test_reg;
92     uint8_t last_read_byte;
93     int nzero;
94
95     int left_till_irq;
96
97     int dma_running;
98     int bytes_per_second;
99     int align;
100     int audio_free;
101     SWVoiceOut *voice;
102
103     QEMUTimer *aux_ts;
104     /* mixer state */
105     int mixer_nreg;
106     uint8_t mixer_regs[256];
107 } SB16State;
108
109 static void SB_audio_callback (void *opaque, int free);
110
111 static int magic_of_irq (int irq)
112 {
113     switch (irq) {
114     case 5:
115         return 2;
116     case 7:
117         return 4;
118     case 9:
119         return 1;
120     case 10:
121         return 8;
122     default:
123         dolog ("bad irq %d\n", irq);
124         return 2;
125     }
126 }
127
128 static int irq_of_magic (int magic)
129 {
130     switch (magic) {
131     case 1:
132         return 9;
133     case 2:
134         return 5;
135     case 4:
136         return 7;
137     case 8:
138         return 10;
139     default:
140         dolog ("bad irq magic %d\n", magic);
141         return -1;
142     }
143 }
144
145 #if 0
146 static void log_dsp (SB16State *dsp)
147 {
148     ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
149             dsp->fmt_stereo ? "Stereo" : "Mono",
150             dsp->fmt_signed ? "Signed" : "Unsigned",
151             dsp->fmt_bits,
152             dsp->dma_auto ? "Auto" : "Single",
153             dsp->block_size,
154             dsp->freq,
155             dsp->time_const,
156             dsp->speaker);
157 }
158 #endif
159
160 static void speaker (SB16State *s, int on)
161 {
162     s->speaker = on;
163     /* AUD_enable (s->voice, on); */
164 }
165
166 static void control (SB16State *s, int hold)
167 {
168     int dma = s->use_hdma ? s->hdma : s->dma;
169     s->dma_running = hold;
170
171     ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
172
173     if (hold) {
174         DMA_hold_DREQ (dma);
175         AUD_set_active_out (s->voice, 1);
176     }
177     else {
178         DMA_release_DREQ (dma);
179         AUD_set_active_out (s->voice, 0);
180     }
181 }
182
183 static void aux_timer (void *opaque)
184 {
185     SB16State *s = opaque;
186     s->can_write = 1;
187     qemu_irq_raise (s->pic);
188 }
189
190 #define DMA8_AUTO 1
191 #define DMA8_HIGH 2
192
193 static void continue_dma8 (SB16State *s)
194 {
195     if (s->freq > 0) {
196         struct audsettings as;
197
198         s->audio_free = 0;
199
200         as.freq = s->freq;
201         as.nchannels = 1 << s->fmt_stereo;
202         as.fmt = s->fmt;
203         as.endianness = 0;
204
205         s->voice = AUD_open_out (
206             &s->card,
207             s->voice,
208             "sb16",
209             s,
210             SB_audio_callback,
211             &as
212             );
213     }
214
215     control (s, 1);
216 }
217
218 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
219 {
220     s->fmt = AUD_FMT_U8;
221     s->use_hdma = 0;
222     s->fmt_bits = 8;
223     s->fmt_signed = 0;
224     s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
225     if (-1 == s->time_const) {
226         if (s->freq <= 0)
227             s->freq = 11025;
228     }
229     else {
230         int tmp = (256 - s->time_const);
231         s->freq = (1000000 + (tmp / 2)) / tmp;
232     }
233
234     if (dma_len != -1) {
235         s->block_size = dma_len << s->fmt_stereo;
236     }
237     else {
238         /* This is apparently the only way to make both Act1/PL
239            and SecondReality/FC work
240
241            Act1 sets block size via command 0x48 and it's an odd number
242            SR does the same with even number
243            Both use stereo, and Creatives own documentation states that
244            0x48 sets block size in bytes less one.. go figure */
245         s->block_size &= ~s->fmt_stereo;
246     }
247
248     s->freq >>= s->fmt_stereo;
249     s->left_till_irq = s->block_size;
250     s->bytes_per_second = (s->freq << s->fmt_stereo);
251     /* s->highspeed = (mask & DMA8_HIGH) != 0; */
252     s->dma_auto = (mask & DMA8_AUTO) != 0;
253     s->align = (1 << s->fmt_stereo) - 1;
254
255     if (s->block_size & s->align) {
256         dolog ("warning: misaligned block size %d, alignment %d\n",
257                s->block_size, s->align + 1);
258     }
259
260     ldebug ("freq %d, stereo %d, sign %d, bits %d, "
261             "dma %d, auto %d, fifo %d, high %d\n",
262             s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
263             s->block_size, s->dma_auto, s->fifo, s->highspeed);
264
265     continue_dma8 (s);
266     speaker (s, 1);
267 }
268
269 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
270 {
271     s->use_hdma = cmd < 0xc0;
272     s->fifo = (cmd >> 1) & 1;
273     s->dma_auto = (cmd >> 2) & 1;
274     s->fmt_signed = (d0 >> 4) & 1;
275     s->fmt_stereo = (d0 >> 5) & 1;
276
277     switch (cmd >> 4) {
278     case 11:
279         s->fmt_bits = 16;
280         break;
281
282     case 12:
283         s->fmt_bits = 8;
284         break;
285     }
286
287     if (-1 != s->time_const) {
288 #if 1
289         int tmp = 256 - s->time_const;
290         s->freq = (1000000 + (tmp / 2)) / tmp;
291 #else
292         /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
293         s->freq = 1000000 / ((255 - s->time_const));
294 #endif
295         s->time_const = -1;
296     }
297
298     s->block_size = dma_len + 1;
299     s->block_size <<= (s->fmt_bits == 16);
300     if (!s->dma_auto) {
301         /* It is clear that for DOOM and auto-init this value
302            shouldn't take stereo into account, while Miles Sound Systems
303            setsound.exe with single transfer mode wouldn't work without it
304            wonders of SB16 yet again */
305         s->block_size <<= s->fmt_stereo;
306     }
307
308     ldebug ("freq %d, stereo %d, sign %d, bits %d, "
309             "dma %d, auto %d, fifo %d, high %d\n",
310             s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
311             s->block_size, s->dma_auto, s->fifo, s->highspeed);
312
313     if (16 == s->fmt_bits) {
314         if (s->fmt_signed) {
315             s->fmt = AUD_FMT_S16;
316         }
317         else {
318             s->fmt = AUD_FMT_U16;
319         }
320     }
321     else {
322         if (s->fmt_signed) {
323             s->fmt = AUD_FMT_S8;
324         }
325         else {
326             s->fmt = AUD_FMT_U8;
327         }
328     }
329
330     s->left_till_irq = s->block_size;
331
332     s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
333     s->highspeed = 0;
334     s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
335     if (s->block_size & s->align) {
336         dolog ("warning: misaligned block size %d, alignment %d\n",
337                s->block_size, s->align + 1);
338     }
339
340     if (s->freq) {
341         struct audsettings as;
342
343         s->audio_free = 0;
344
345         as.freq = s->freq;
346         as.nchannels = 1 << s->fmt_stereo;
347         as.fmt = s->fmt;
348         as.endianness = 0;
349
350         s->voice = AUD_open_out (
351             &s->card,
352             s->voice,
353             "sb16",
354             s,
355             SB_audio_callback,
356             &as
357             );
358     }
359
360     control (s, 1);
361     speaker (s, 1);
362 }
363
364 static inline void dsp_out_data (SB16State *s, uint8_t val)
365 {
366     ldebug ("outdata %#x\n", val);
367     if ((size_t) s->out_data_len < sizeof (s->out_data)) {
368         s->out_data[s->out_data_len++] = val;
369     }
370 }
371
372 static inline uint8_t dsp_get_data (SB16State *s)
373 {
374     if (s->in_index) {
375         return s->in2_data[--s->in_index];
376     }
377     else {
378         dolog ("buffer underflow\n");
379         return 0;
380     }
381 }
382
383 static void command (SB16State *s, uint8_t cmd)
384 {
385     ldebug ("command %#x\n", cmd);
386
387     if (cmd > 0xaf && cmd < 0xd0) {
388         if (cmd & 8) {
389             dolog ("ADC not yet supported (command %#x)\n", cmd);
390         }
391
392         switch (cmd >> 4) {
393         case 11:
394         case 12:
395             break;
396         default:
397             dolog ("%#x wrong bits\n", cmd);
398         }
399         s->needed_bytes = 3;
400     }
401     else {
402         s->needed_bytes = 0;
403
404         switch (cmd) {
405         case 0x03:
406             dsp_out_data (s, 0x10); /* s->csp_param); */
407             goto warn;
408
409         case 0x04:
410             s->needed_bytes = 1;
411             goto warn;
412
413         case 0x05:
414             s->needed_bytes = 2;
415             goto warn;
416
417         case 0x08:
418             /* __asm__ ("int3"); */
419             goto warn;
420
421         case 0x0e:
422             s->needed_bytes = 2;
423             goto warn;
424
425         case 0x09:
426             dsp_out_data (s, 0xf8);
427             goto warn;
428
429         case 0x0f:
430             s->needed_bytes = 1;
431             goto warn;
432
433         case 0x10:
434             s->needed_bytes = 1;
435             goto warn;
436
437         case 0x14:
438             s->needed_bytes = 2;
439             s->block_size = 0;
440             break;
441
442         case 0x1c:              /* Auto-Initialize DMA DAC, 8-bit */
443             dma_cmd8 (s, DMA8_AUTO, -1);
444             break;
445
446         case 0x20:              /* Direct ADC, Juice/PL */
447             dsp_out_data (s, 0xff);
448             goto warn;
449
450         case 0x35:
451             dolog ("0x35 - MIDI command not implemented\n");
452             break;
453
454         case 0x40:
455             s->freq = -1;
456             s->time_const = -1;
457             s->needed_bytes = 1;
458             break;
459
460         case 0x41:
461             s->freq = -1;
462             s->time_const = -1;
463             s->needed_bytes = 2;
464             break;
465
466         case 0x42:
467             s->freq = -1;
468             s->time_const = -1;
469             s->needed_bytes = 2;
470             goto warn;
471
472         case 0x45:
473             dsp_out_data (s, 0xaa);
474             goto warn;
475
476         case 0x47:                /* Continue Auto-Initialize DMA 16bit */
477             break;
478
479         case 0x48:
480             s->needed_bytes = 2;
481             break;
482
483         case 0x74:
484             s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
485             dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
486             break;
487
488         case 0x75:              /* DMA DAC, 4-bit ADPCM Reference */
489             s->needed_bytes = 2;
490             dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
491             break;
492
493         case 0x76:              /* DMA DAC, 2.6-bit ADPCM */
494             s->needed_bytes = 2;
495             dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
496             break;
497
498         case 0x77:              /* DMA DAC, 2.6-bit ADPCM Reference */
499             s->needed_bytes = 2;
500             dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
501             break;
502
503         case 0x7d:
504             dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
505             dolog ("not implemented\n");
506             break;
507
508         case 0x7f:
509             dolog (
510                 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
511                 );
512             dolog ("not implemented\n");
513             break;
514
515         case 0x80:
516             s->needed_bytes = 2;
517             break;
518
519         case 0x90:
520         case 0x91:
521             dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
522             break;
523
524         case 0xd0:              /* halt DMA operation. 8bit */
525             control (s, 0);
526             break;
527
528         case 0xd1:              /* speaker on */
529             speaker (s, 1);
530             break;
531
532         case 0xd3:              /* speaker off */
533             speaker (s, 0);
534             break;
535
536         case 0xd4:              /* continue DMA operation. 8bit */
537             /* KQ6 (or maybe Sierras audblst.drv in general) resets
538                the frequency between halt/continue */
539             continue_dma8 (s);
540             break;
541
542         case 0xd5:              /* halt DMA operation. 16bit */
543             control (s, 0);
544             break;
545
546         case 0xd6:              /* continue DMA operation. 16bit */
547             control (s, 1);
548             break;
549
550         case 0xd9:              /* exit auto-init DMA after this block. 16bit */
551             s->dma_auto = 0;
552             break;
553
554         case 0xda:              /* exit auto-init DMA after this block. 8bit */
555             s->dma_auto = 0;
556             break;
557
558         case 0xe0:              /* DSP identification */
559             s->needed_bytes = 1;
560             break;
561
562         case 0xe1:
563             dsp_out_data (s, s->ver & 0xff);
564             dsp_out_data (s, s->ver >> 8);
565             break;
566
567         case 0xe2:
568             s->needed_bytes = 1;
569             goto warn;
570
571         case 0xe3:
572             {
573                 int i;
574                 for (i = sizeof (e3) - 1; i >= 0; --i)
575                     dsp_out_data (s, e3[i]);
576             }
577             break;
578
579         case 0xe4:              /* write test reg */
580             s->needed_bytes = 1;
581             break;
582
583         case 0xe7:
584             dolog ("Attempt to probe for ESS (0xe7)?\n");
585             break;
586
587         case 0xe8:              /* read test reg */
588             dsp_out_data (s, s->test_reg);
589             break;
590
591         case 0xf2:
592         case 0xf3:
593             dsp_out_data (s, 0xaa);
594             s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
595             qemu_irq_raise (s->pic);
596             break;
597
598         case 0xf9:
599             s->needed_bytes = 1;
600             goto warn;
601
602         case 0xfa:
603             dsp_out_data (s, 0);
604             goto warn;
605
606         case 0xfc:              /* FIXME */
607             dsp_out_data (s, 0);
608             goto warn;
609
610         default:
611             dolog ("Unrecognized command %#x\n", cmd);
612             break;
613         }
614     }
615
616     if (!s->needed_bytes) {
617         ldebug ("\n");
618     }
619
620  exit:
621     if (!s->needed_bytes) {
622         s->cmd = -1;
623     }
624     else {
625         s->cmd = cmd;
626     }
627     return;
628
629  warn:
630     dolog ("warning: command %#x,%d is not truly understood yet\n",
631            cmd, s->needed_bytes);
632     goto exit;
633
634 }
635
636 static uint16_t dsp_get_lohi (SB16State *s)
637 {
638     uint8_t hi = dsp_get_data (s);
639     uint8_t lo = dsp_get_data (s);
640     return (hi << 8) | lo;
641 }
642
643 static uint16_t dsp_get_hilo (SB16State *s)
644 {
645     uint8_t lo = dsp_get_data (s);
646     uint8_t hi = dsp_get_data (s);
647     return (hi << 8) | lo;
648 }
649
650 static void complete (SB16State *s)
651 {
652     int d0, d1, d2;
653     ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
654             s->cmd, s->in_index, s->needed_bytes);
655
656     if (s->cmd > 0xaf && s->cmd < 0xd0) {
657         d2 = dsp_get_data (s);
658         d1 = dsp_get_data (s);
659         d0 = dsp_get_data (s);
660
661         if (s->cmd & 8) {
662             dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
663                    s->cmd, d0, d1, d2);
664         }
665         else {
666             ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
667                     s->cmd, d0, d1, d2);
668             dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
669         }
670     }
671     else {
672         switch (s->cmd) {
673         case 0x04:
674             s->csp_mode = dsp_get_data (s);
675             s->csp_reg83r = 0;
676             s->csp_reg83w = 0;
677             ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
678             break;
679
680         case 0x05:
681             s->csp_param = dsp_get_data (s);
682             s->csp_value = dsp_get_data (s);
683             ldebug ("CSP command 0x05: param=%#x value=%#x\n",
684                     s->csp_param,
685                     s->csp_value);
686             break;
687
688         case 0x0e:
689             d0 = dsp_get_data (s);
690             d1 = dsp_get_data (s);
691             ldebug ("write CSP register %d <- %#x\n", d1, d0);
692             if (d1 == 0x83) {
693                 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
694                 s->csp_reg83[s->csp_reg83r % 4] = d0;
695                 s->csp_reg83r += 1;
696             }
697             else {
698                 s->csp_regs[d1] = d0;
699             }
700             break;
701
702         case 0x0f:
703             d0 = dsp_get_data (s);
704             ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
705                     d0, s->csp_regs[d0], s->csp_mode);
706             if (d0 == 0x83) {
707                 ldebug ("0x83[%d] -> %#x\n",
708                         s->csp_reg83w,
709                         s->csp_reg83[s->csp_reg83w % 4]);
710                 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
711                 s->csp_reg83w += 1;
712             }
713             else {
714                 dsp_out_data (s, s->csp_regs[d0]);
715             }
716             break;
717
718         case 0x10:
719             d0 = dsp_get_data (s);
720             dolog ("cmd 0x10 d0=%#x\n", d0);
721             break;
722
723         case 0x14:
724             dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
725             break;
726
727         case 0x40:
728             s->time_const = dsp_get_data (s);
729             ldebug ("set time const %d\n", s->time_const);
730             break;
731
732         case 0x42:              /* FT2 sets output freq with this, go figure */
733 #if 0
734             dolog ("cmd 0x42 might not do what it think it should\n");
735 #endif
736         case 0x41:
737             s->freq = dsp_get_hilo (s);
738             ldebug ("set freq %d\n", s->freq);
739             break;
740
741         case 0x48:
742             s->block_size = dsp_get_lohi (s) + 1;
743             ldebug ("set dma block len %d\n", s->block_size);
744             break;
745
746         case 0x74:
747         case 0x75:
748         case 0x76:
749         case 0x77:
750             /* ADPCM stuff, ignore */
751             break;
752
753         case 0x80:
754             {
755                 int freq, samples, bytes;
756                 int64_t ticks;
757
758                 freq = s->freq > 0 ? s->freq : 11025;
759                 samples = dsp_get_lohi (s) + 1;
760                 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
761                 ticks = muldiv64 (bytes, get_ticks_per_sec (), freq);
762                 if (ticks < get_ticks_per_sec () / 1024) {
763                     qemu_irq_raise (s->pic);
764                 }
765                 else {
766                     if (s->aux_ts) {
767                         qemu_mod_timer (
768                             s->aux_ts,
769                             qemu_get_clock (vm_clock) + ticks
770                             );
771                     }
772                 }
773                 ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
774             }
775             break;
776
777         case 0xe0:
778             d0 = dsp_get_data (s);
779             s->out_data_len = 0;
780             ldebug ("E0 data = %#x\n", d0);
781             dsp_out_data (s, ~d0);
782             break;
783
784         case 0xe2:
785 #ifdef DEBUG
786             d0 = dsp_get_data (s);
787             dolog ("E2 = %#x\n", d0);
788 #endif
789             break;
790
791         case 0xe4:
792             s->test_reg = dsp_get_data (s);
793             break;
794
795         case 0xf9:
796             d0 = dsp_get_data (s);
797             ldebug ("command 0xf9 with %#x\n", d0);
798             switch (d0) {
799             case 0x0e:
800                 dsp_out_data (s, 0xff);
801                 break;
802
803             case 0x0f:
804                 dsp_out_data (s, 0x07);
805                 break;
806
807             case 0x37:
808                 dsp_out_data (s, 0x38);
809                 break;
810
811             default:
812                 dsp_out_data (s, 0x00);
813                 break;
814             }
815             break;
816
817         default:
818             dolog ("complete: unrecognized command %#x\n", s->cmd);
819             return;
820         }
821     }
822
823     ldebug ("\n");
824     s->cmd = -1;
825     return;
826 }
827
828 static void legacy_reset (SB16State *s)
829 {
830     struct audsettings as;
831
832     s->freq = 11025;
833     s->fmt_signed = 0;
834     s->fmt_bits = 8;
835     s->fmt_stereo = 0;
836
837     as.freq = s->freq;
838     as.nchannels = 1;
839     as.fmt = AUD_FMT_U8;
840     as.endianness = 0;
841
842     s->voice = AUD_open_out (
843         &s->card,
844         s->voice,
845         "sb16",
846         s,
847         SB_audio_callback,
848         &as
849         );
850
851     /* Not sure about that... */
852     /* AUD_set_active_out (s->voice, 1); */
853 }
854
855 static void reset (SB16State *s)
856 {
857     qemu_irq_lower (s->pic);
858     if (s->dma_auto) {
859         qemu_irq_raise (s->pic);
860         qemu_irq_lower (s->pic);
861     }
862
863     s->mixer_regs[0x82] = 0;
864     s->dma_auto = 0;
865     s->in_index = 0;
866     s->out_data_len = 0;
867     s->left_till_irq = 0;
868     s->needed_bytes = 0;
869     s->block_size = -1;
870     s->nzero = 0;
871     s->highspeed = 0;
872     s->v2x6 = 0;
873     s->cmd = -1;
874
875     dsp_out_data (s, 0xaa);
876     speaker (s, 0);
877     control (s, 0);
878     legacy_reset (s);
879 }
880
881 static IO_WRITE_PROTO (dsp_write)
882 {
883     SB16State *s = opaque;
884     int iport;
885
886     iport = nport - s->port;
887
888     ldebug ("write %#x <- %#x\n", nport, val);
889     switch (iport) {
890     case 0x06:
891         switch (val) {
892         case 0x00:
893             if (s->v2x6 == 1) {
894                 reset (s);
895             }
896             s->v2x6 = 0;
897             break;
898
899         case 0x01:
900         case 0x03:              /* FreeBSD kludge */
901             s->v2x6 = 1;
902             break;
903
904         case 0xc6:
905             s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
906             break;
907
908         case 0xb8:              /* Panic */
909             reset (s);
910             break;
911
912         case 0x39:
913             dsp_out_data (s, 0x38);
914             reset (s);
915             s->v2x6 = 0x39;
916             break;
917
918         default:
919             s->v2x6 = val;
920             break;
921         }
922         break;
923
924     case 0x0c:                  /* write data or command | write status */
925 /*         if (s->highspeed) */
926 /*             break; */
927
928         if (0 == s->needed_bytes) {
929             command (s, val);
930 #if 0
931             if (0 == s->needed_bytes) {
932                 log_dsp (s);
933             }
934 #endif
935         }
936         else {
937             if (s->in_index == sizeof (s->in2_data)) {
938                 dolog ("in data overrun\n");
939             }
940             else {
941                 s->in2_data[s->in_index++] = val;
942                 if (s->in_index == s->needed_bytes) {
943                     s->needed_bytes = 0;
944                     complete (s);
945 #if 0
946                     log_dsp (s);
947 #endif
948                 }
949             }
950         }
951         break;
952
953     default:
954         ldebug ("(nport=%#x, val=%#x)\n", nport, val);
955         break;
956     }
957 }
958
959 static IO_READ_PROTO (dsp_read)
960 {
961     SB16State *s = opaque;
962     int iport, retval, ack = 0;
963
964     iport = nport - s->port;
965
966     switch (iport) {
967     case 0x06:                  /* reset */
968         retval = 0xff;
969         break;
970
971     case 0x0a:                  /* read data */
972         if (s->out_data_len) {
973             retval = s->out_data[--s->out_data_len];
974             s->last_read_byte = retval;
975         }
976         else {
977             if (s->cmd != -1) {
978                 dolog ("empty output buffer for command %#x\n",
979                        s->cmd);
980             }
981             retval = s->last_read_byte;
982             /* goto error; */
983         }
984         break;
985
986     case 0x0c:                  /* 0 can write */
987         retval = s->can_write ? 0 : 0x80;
988         break;
989
990     case 0x0d:                  /* timer interrupt clear */
991         /* dolog ("timer interrupt clear\n"); */
992         retval = 0;
993         break;
994
995     case 0x0e:                  /* data available status | irq 8 ack */
996         retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
997         if (s->mixer_regs[0x82] & 1) {
998             ack = 1;
999             s->mixer_regs[0x82] &= 1;
1000             qemu_irq_lower (s->pic);
1001         }
1002         break;
1003
1004     case 0x0f:                  /* irq 16 ack */
1005         retval = 0xff;
1006         if (s->mixer_regs[0x82] & 2) {
1007             ack = 1;
1008             s->mixer_regs[0x82] &= 2;
1009             qemu_irq_lower (s->pic);
1010         }
1011         break;
1012
1013     default:
1014         goto error;
1015     }
1016
1017     if (!ack) {
1018         ldebug ("read %#x -> %#x\n", nport, retval);
1019     }
1020
1021     return retval;
1022
1023  error:
1024     dolog ("warning: dsp_read %#x error\n", nport);
1025     return 0xff;
1026 }
1027
1028 static void reset_mixer (SB16State *s)
1029 {
1030     int i;
1031
1032     memset (s->mixer_regs, 0xff, 0x7f);
1033     memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1034
1035     s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1036     s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1037     s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1038     s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1039
1040     /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1041     s->mixer_regs[0x0c] = 0;
1042
1043     /* d5=output filt, d1=stereo switch */
1044     s->mixer_regs[0x0e] = 0;
1045
1046     /* voice volume L d5,d7, R d1,d3 */
1047     s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1048     /* master ... */
1049     s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1050     /* MIDI ... */
1051     s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1052
1053     for (i = 0x30; i < 0x48; i++) {
1054         s->mixer_regs[i] = 0x20;
1055     }
1056 }
1057
1058 static IO_WRITE_PROTO (mixer_write_indexb)
1059 {
1060     SB16State *s = opaque;
1061     (void) nport;
1062     s->mixer_nreg = val;
1063 }
1064
1065 static IO_WRITE_PROTO (mixer_write_datab)
1066 {
1067     SB16State *s = opaque;
1068
1069     (void) nport;
1070     ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1071
1072     switch (s->mixer_nreg) {
1073     case 0x00:
1074         reset_mixer (s);
1075         break;
1076
1077     case 0x80:
1078         {
1079             int irq = irq_of_magic (val);
1080             ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1081             if (irq > 0) {
1082                 s->irq = irq;
1083             }
1084         }
1085         break;
1086
1087     case 0x81:
1088         {
1089             int dma, hdma;
1090
1091             dma = ctz32 (val & 0xf);
1092             hdma = ctz32 (val & 0xf0);
1093             if (dma != s->dma || hdma != s->hdma) {
1094                 dolog (
1095                     "attempt to change DMA "
1096                     "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1097                     dma, s->dma, hdma, s->hdma, val);
1098             }
1099 #if 0
1100             s->dma = dma;
1101             s->hdma = hdma;
1102 #endif
1103         }
1104         break;
1105
1106     case 0x82:
1107         dolog ("attempt to write into IRQ status register (val=%#x)\n",
1108                val);
1109         return;
1110
1111     default:
1112         if (s->mixer_nreg >= 0x80) {
1113             ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1114         }
1115         break;
1116     }
1117
1118     s->mixer_regs[s->mixer_nreg] = val;
1119 }
1120
1121 static IO_WRITE_PROTO (mixer_write_indexw)
1122 {
1123     mixer_write_indexb (opaque, nport, val & 0xff);
1124     mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1125 }
1126
1127 static IO_READ_PROTO (mixer_read)
1128 {
1129     SB16State *s = opaque;
1130
1131     (void) nport;
1132 #ifndef DEBUG_SB16_MOST
1133     if (s->mixer_nreg != 0x82) {
1134         ldebug ("mixer_read[%#x] -> %#x\n",
1135                 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1136     }
1137 #else
1138     ldebug ("mixer_read[%#x] -> %#x\n",
1139             s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1140 #endif
1141     return s->mixer_regs[s->mixer_nreg];
1142 }
1143
1144 static int write_audio (SB16State *s, int nchan, int dma_pos,
1145                         int dma_len, int len)
1146 {
1147     int temp, net;
1148     uint8_t tmpbuf[4096];
1149
1150     temp = len;
1151     net = 0;
1152
1153     while (temp) {
1154         int left = dma_len - dma_pos;
1155         int copied;
1156         size_t to_copy;
1157
1158         to_copy = audio_MIN (temp, left);
1159         if (to_copy > sizeof (tmpbuf)) {
1160             to_copy = sizeof (tmpbuf);
1161         }
1162
1163         copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1164         copied = AUD_write (s->voice, tmpbuf, copied);
1165
1166         temp -= copied;
1167         dma_pos = (dma_pos + copied) % dma_len;
1168         net += copied;
1169
1170         if (!copied) {
1171             break;
1172         }
1173     }
1174
1175     return net;
1176 }
1177
1178 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1179 {
1180     SB16State *s = opaque;
1181     int till, copy, written, free;
1182
1183     if (s->block_size <= 0) {
1184         dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1185                s->block_size, nchan, dma_pos, dma_len);
1186         return dma_pos;
1187     }
1188
1189     if (s->left_till_irq < 0) {
1190         s->left_till_irq = s->block_size;
1191     }
1192
1193     if (s->voice) {
1194         free = s->audio_free & ~s->align;
1195         if ((free <= 0) || !dma_len) {
1196             return dma_pos;
1197         }
1198     }
1199     else {
1200         free = dma_len;
1201     }
1202
1203     copy = free;
1204     till = s->left_till_irq;
1205
1206 #ifdef DEBUG_SB16_MOST
1207     dolog ("pos:%06d %d till:%d len:%d\n",
1208            dma_pos, free, till, dma_len);
1209 #endif
1210
1211     if (till <= copy) {
1212         if (0 == s->dma_auto) {
1213             copy = till;
1214         }
1215     }
1216
1217     written = write_audio (s, nchan, dma_pos, dma_len, copy);
1218     dma_pos = (dma_pos + written) % dma_len;
1219     s->left_till_irq -= written;
1220
1221     if (s->left_till_irq <= 0) {
1222         s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1223         qemu_irq_raise (s->pic);
1224         if (0 == s->dma_auto) {
1225             control (s, 0);
1226             speaker (s, 0);
1227         }
1228     }
1229
1230 #ifdef DEBUG_SB16_MOST
1231     ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1232             dma_pos, free, dma_len, s->left_till_irq, copy, written,
1233             s->block_size);
1234 #endif
1235
1236     while (s->left_till_irq <= 0) {
1237         s->left_till_irq = s->block_size + s->left_till_irq;
1238     }
1239
1240     return dma_pos;
1241 }
1242
1243 static void SB_audio_callback (void *opaque, int free)
1244 {
1245     SB16State *s = opaque;
1246     s->audio_free = free;
1247 }
1248
1249 static int sb16_post_load (void *opaque, int version_id)
1250 {
1251     SB16State *s = opaque;
1252
1253     if (s->voice) {
1254         AUD_close_out (&s->card, s->voice);
1255         s->voice = NULL;
1256     }
1257
1258     if (s->dma_running) {
1259         if (s->freq) {
1260             struct audsettings as;
1261
1262             s->audio_free = 0;
1263
1264             as.freq = s->freq;
1265             as.nchannels = 1 << s->fmt_stereo;
1266             as.fmt = s->fmt;
1267             as.endianness = 0;
1268
1269             s->voice = AUD_open_out (
1270                 &s->card,
1271                 s->voice,
1272                 "sb16",
1273                 s,
1274                 SB_audio_callback,
1275                 &as
1276                 );
1277         }
1278
1279         control (s, 1);
1280         speaker (s, s->speaker);
1281     }
1282     return 0;
1283 }
1284
1285 static const VMStateDescription vmstate_sb16 = {
1286     .name = "sb16",
1287     .version_id = 1,
1288     .minimum_version_id = 1,
1289     .minimum_version_id_old = 1,
1290     .post_load = sb16_post_load,
1291     .fields      = (VMStateField []) {
1292         VMSTATE_UINT32(irq, SB16State),
1293         VMSTATE_UINT32(dma, SB16State),
1294         VMSTATE_UINT32(hdma, SB16State),
1295         VMSTATE_UINT32(port, SB16State),
1296         VMSTATE_UINT32(ver, SB16State),
1297         VMSTATE_INT32(in_index, SB16State),
1298         VMSTATE_INT32(out_data_len, SB16State),
1299         VMSTATE_INT32(fmt_stereo, SB16State),
1300         VMSTATE_INT32(fmt_signed, SB16State),
1301         VMSTATE_INT32(fmt_bits, SB16State),
1302         VMSTATE_UINT32(fmt, SB16State),
1303         VMSTATE_INT32(dma_auto, SB16State),
1304         VMSTATE_INT32(block_size, SB16State),
1305         VMSTATE_INT32(fifo, SB16State),
1306         VMSTATE_INT32(freq, SB16State),
1307         VMSTATE_INT32(time_const, SB16State),
1308         VMSTATE_INT32(speaker, SB16State),
1309         VMSTATE_INT32(needed_bytes, SB16State),
1310         VMSTATE_INT32(cmd, SB16State),
1311         VMSTATE_INT32(use_hdma, SB16State),
1312         VMSTATE_INT32(highspeed, SB16State),
1313         VMSTATE_INT32(can_write, SB16State),
1314         VMSTATE_INT32(v2x6, SB16State),
1315
1316         VMSTATE_UINT8(csp_param, SB16State),
1317         VMSTATE_UINT8(csp_value, SB16State),
1318         VMSTATE_UINT8(csp_mode, SB16State),
1319         VMSTATE_UINT8(csp_param, SB16State),
1320         VMSTATE_BUFFER(csp_regs, SB16State),
1321         VMSTATE_UINT8(csp_index, SB16State),
1322         VMSTATE_BUFFER(csp_reg83, SB16State),
1323         VMSTATE_INT32(csp_reg83r, SB16State),
1324         VMSTATE_INT32(csp_reg83w, SB16State),
1325
1326         VMSTATE_BUFFER(in2_data, SB16State),
1327         VMSTATE_BUFFER(out_data, SB16State),
1328         VMSTATE_UINT8(test_reg, SB16State),
1329         VMSTATE_UINT8(last_read_byte, SB16State),
1330
1331         VMSTATE_INT32(nzero, SB16State),
1332         VMSTATE_INT32(left_till_irq, SB16State),
1333         VMSTATE_INT32(dma_running, SB16State),
1334         VMSTATE_INT32(bytes_per_second, SB16State),
1335         VMSTATE_INT32(align, SB16State),
1336
1337         VMSTATE_INT32(mixer_nreg, SB16State),
1338         VMSTATE_BUFFER(mixer_regs, SB16State),
1339
1340         VMSTATE_END_OF_LIST()
1341     }
1342 };
1343
1344 static int sb16_initfn (ISADevice *dev)
1345 {
1346     static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1347     static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1348     SB16State *s;
1349     int i;
1350
1351     s = DO_UPCAST (SB16State, dev, dev);
1352
1353     s->cmd = -1;
1354     isa_init_irq (dev, &s->pic, s->irq);
1355
1356     s->mixer_regs[0x80] = magic_of_irq (s->irq);
1357     s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1358     s->mixer_regs[0x82] = 2 << 5;
1359
1360     s->csp_regs[5] = 1;
1361     s->csp_regs[9] = 0xf8;
1362
1363     reset_mixer (s);
1364     s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1365     if (!s->aux_ts) {
1366         dolog ("warning: Could not create auxiliary timer\n");
1367     }
1368
1369     for (i = 0; i < ARRAY_SIZE (dsp_write_ports); i++) {
1370         register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1371         isa_init_ioport(dev, s->port + dsp_write_ports[i]);
1372     }
1373
1374     for (i = 0; i < ARRAY_SIZE (dsp_read_ports); i++) {
1375         register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1376         isa_init_ioport(dev, s->port + dsp_read_ports[i]);
1377     }
1378
1379     register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1380     register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1381     isa_init_ioport(dev, s->port + 0x4);
1382     register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1383     register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1384     isa_init_ioport(dev, s->port + 0x5);
1385
1386     DMA_register_channel (s->hdma, SB_read_DMA, s);
1387     DMA_register_channel (s->dma, SB_read_DMA, s);
1388     s->can_write = 1;
1389
1390     AUD_register_card ("sb16", &s->card);
1391     return 0;
1392 }
1393
1394 int SB16_init (qemu_irq *pic)
1395 {
1396     isa_create_simple ("sb16");
1397     return 0;
1398 }
1399
1400 static ISADeviceInfo sb16_info = {
1401     .qdev.name     = "sb16",
1402     .qdev.desc     = "Creative Sound Blaster 16",
1403     .qdev.size     = sizeof (SB16State),
1404     .qdev.vmsd     = &vmstate_sb16,
1405     .init          = sb16_initfn,
1406     .qdev.props    = (Property[]) {
1407         DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
1408         DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
1409         DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
1410         DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
1411         DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
1412         DEFINE_PROP_END_OF_LIST (),
1413     },
1414 };
1415
1416 static void sb16_register (void)
1417 {
1418     isa_qdev_register (&sb16_info);
1419 }
1420 device_init (sb16_register)
This page took 0.105786 seconds and 4 git commands to generate.