]> Git Repo - qemu.git/blob - hw/sb16.c
net: reorganize headers
[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_ns (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 }
826
827 static void legacy_reset (SB16State *s)
828 {
829     struct audsettings as;
830
831     s->freq = 11025;
832     s->fmt_signed = 0;
833     s->fmt_bits = 8;
834     s->fmt_stereo = 0;
835
836     as.freq = s->freq;
837     as.nchannels = 1;
838     as.fmt = AUD_FMT_U8;
839     as.endianness = 0;
840
841     s->voice = AUD_open_out (
842         &s->card,
843         s->voice,
844         "sb16",
845         s,
846         SB_audio_callback,
847         &as
848         );
849
850     /* Not sure about that... */
851     /* AUD_set_active_out (s->voice, 1); */
852 }
853
854 static void reset (SB16State *s)
855 {
856     qemu_irq_lower (s->pic);
857     if (s->dma_auto) {
858         qemu_irq_raise (s->pic);
859         qemu_irq_lower (s->pic);
860     }
861
862     s->mixer_regs[0x82] = 0;
863     s->dma_auto = 0;
864     s->in_index = 0;
865     s->out_data_len = 0;
866     s->left_till_irq = 0;
867     s->needed_bytes = 0;
868     s->block_size = -1;
869     s->nzero = 0;
870     s->highspeed = 0;
871     s->v2x6 = 0;
872     s->cmd = -1;
873
874     dsp_out_data (s, 0xaa);
875     speaker (s, 0);
876     control (s, 0);
877     legacy_reset (s);
878 }
879
880 static IO_WRITE_PROTO (dsp_write)
881 {
882     SB16State *s = opaque;
883     int iport;
884
885     iport = nport - s->port;
886
887     ldebug ("write %#x <- %#x\n", nport, val);
888     switch (iport) {
889     case 0x06:
890         switch (val) {
891         case 0x00:
892             if (s->v2x6 == 1) {
893                 reset (s);
894             }
895             s->v2x6 = 0;
896             break;
897
898         case 0x01:
899         case 0x03:              /* FreeBSD kludge */
900             s->v2x6 = 1;
901             break;
902
903         case 0xc6:
904             s->v2x6 = 0;        /* Prince of Persia, csp.sys, diagnose.exe */
905             break;
906
907         case 0xb8:              /* Panic */
908             reset (s);
909             break;
910
911         case 0x39:
912             dsp_out_data (s, 0x38);
913             reset (s);
914             s->v2x6 = 0x39;
915             break;
916
917         default:
918             s->v2x6 = val;
919             break;
920         }
921         break;
922
923     case 0x0c:                  /* write data or command | write status */
924 /*         if (s->highspeed) */
925 /*             break; */
926
927         if (0 == s->needed_bytes) {
928             command (s, val);
929 #if 0
930             if (0 == s->needed_bytes) {
931                 log_dsp (s);
932             }
933 #endif
934         }
935         else {
936             if (s->in_index == sizeof (s->in2_data)) {
937                 dolog ("in data overrun\n");
938             }
939             else {
940                 s->in2_data[s->in_index++] = val;
941                 if (s->in_index == s->needed_bytes) {
942                     s->needed_bytes = 0;
943                     complete (s);
944 #if 0
945                     log_dsp (s);
946 #endif
947                 }
948             }
949         }
950         break;
951
952     default:
953         ldebug ("(nport=%#x, val=%#x)\n", nport, val);
954         break;
955     }
956 }
957
958 static IO_READ_PROTO (dsp_read)
959 {
960     SB16State *s = opaque;
961     int iport, retval, ack = 0;
962
963     iport = nport - s->port;
964
965     switch (iport) {
966     case 0x06:                  /* reset */
967         retval = 0xff;
968         break;
969
970     case 0x0a:                  /* read data */
971         if (s->out_data_len) {
972             retval = s->out_data[--s->out_data_len];
973             s->last_read_byte = retval;
974         }
975         else {
976             if (s->cmd != -1) {
977                 dolog ("empty output buffer for command %#x\n",
978                        s->cmd);
979             }
980             retval = s->last_read_byte;
981             /* goto error; */
982         }
983         break;
984
985     case 0x0c:                  /* 0 can write */
986         retval = s->can_write ? 0 : 0x80;
987         break;
988
989     case 0x0d:                  /* timer interrupt clear */
990         /* dolog ("timer interrupt clear\n"); */
991         retval = 0;
992         break;
993
994     case 0x0e:                  /* data available status | irq 8 ack */
995         retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
996         if (s->mixer_regs[0x82] & 1) {
997             ack = 1;
998             s->mixer_regs[0x82] &= 1;
999             qemu_irq_lower (s->pic);
1000         }
1001         break;
1002
1003     case 0x0f:                  /* irq 16 ack */
1004         retval = 0xff;
1005         if (s->mixer_regs[0x82] & 2) {
1006             ack = 1;
1007             s->mixer_regs[0x82] &= 2;
1008             qemu_irq_lower (s->pic);
1009         }
1010         break;
1011
1012     default:
1013         goto error;
1014     }
1015
1016     if (!ack) {
1017         ldebug ("read %#x -> %#x\n", nport, retval);
1018     }
1019
1020     return retval;
1021
1022  error:
1023     dolog ("warning: dsp_read %#x error\n", nport);
1024     return 0xff;
1025 }
1026
1027 static void reset_mixer (SB16State *s)
1028 {
1029     int i;
1030
1031     memset (s->mixer_regs, 0xff, 0x7f);
1032     memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1033
1034     s->mixer_regs[0x02] = 4;    /* master volume 3bits */
1035     s->mixer_regs[0x06] = 4;    /* MIDI volume 3bits */
1036     s->mixer_regs[0x08] = 0;    /* CD volume 3bits */
1037     s->mixer_regs[0x0a] = 0;    /* voice volume 2bits */
1038
1039     /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1040     s->mixer_regs[0x0c] = 0;
1041
1042     /* d5=output filt, d1=stereo switch */
1043     s->mixer_regs[0x0e] = 0;
1044
1045     /* voice volume L d5,d7, R d1,d3 */
1046     s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1047     /* master ... */
1048     s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1049     /* MIDI ... */
1050     s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1051
1052     for (i = 0x30; i < 0x48; i++) {
1053         s->mixer_regs[i] = 0x20;
1054     }
1055 }
1056
1057 static IO_WRITE_PROTO (mixer_write_indexb)
1058 {
1059     SB16State *s = opaque;
1060     (void) nport;
1061     s->mixer_nreg = val;
1062 }
1063
1064 static IO_WRITE_PROTO (mixer_write_datab)
1065 {
1066     SB16State *s = opaque;
1067
1068     (void) nport;
1069     ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1070
1071     switch (s->mixer_nreg) {
1072     case 0x00:
1073         reset_mixer (s);
1074         break;
1075
1076     case 0x80:
1077         {
1078             int irq = irq_of_magic (val);
1079             ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1080             if (irq > 0) {
1081                 s->irq = irq;
1082             }
1083         }
1084         break;
1085
1086     case 0x81:
1087         {
1088             int dma, hdma;
1089
1090             dma = ctz32 (val & 0xf);
1091             hdma = ctz32 (val & 0xf0);
1092             if (dma != s->dma || hdma != s->hdma) {
1093                 dolog (
1094                     "attempt to change DMA "
1095                     "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1096                     dma, s->dma, hdma, s->hdma, val);
1097             }
1098 #if 0
1099             s->dma = dma;
1100             s->hdma = hdma;
1101 #endif
1102         }
1103         break;
1104
1105     case 0x82:
1106         dolog ("attempt to write into IRQ status register (val=%#x)\n",
1107                val);
1108         return;
1109
1110     default:
1111         if (s->mixer_nreg >= 0x80) {
1112             ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1113         }
1114         break;
1115     }
1116
1117     s->mixer_regs[s->mixer_nreg] = val;
1118 }
1119
1120 static IO_WRITE_PROTO (mixer_write_indexw)
1121 {
1122     mixer_write_indexb (opaque, nport, val & 0xff);
1123     mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1124 }
1125
1126 static IO_READ_PROTO (mixer_read)
1127 {
1128     SB16State *s = opaque;
1129
1130     (void) nport;
1131 #ifndef DEBUG_SB16_MOST
1132     if (s->mixer_nreg != 0x82) {
1133         ldebug ("mixer_read[%#x] -> %#x\n",
1134                 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1135     }
1136 #else
1137     ldebug ("mixer_read[%#x] -> %#x\n",
1138             s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1139 #endif
1140     return s->mixer_regs[s->mixer_nreg];
1141 }
1142
1143 static int write_audio (SB16State *s, int nchan, int dma_pos,
1144                         int dma_len, int len)
1145 {
1146     int temp, net;
1147     uint8_t tmpbuf[4096];
1148
1149     temp = len;
1150     net = 0;
1151
1152     while (temp) {
1153         int left = dma_len - dma_pos;
1154         int copied;
1155         size_t to_copy;
1156
1157         to_copy = audio_MIN (temp, left);
1158         if (to_copy > sizeof (tmpbuf)) {
1159             to_copy = sizeof (tmpbuf);
1160         }
1161
1162         copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1163         copied = AUD_write (s->voice, tmpbuf, copied);
1164
1165         temp -= copied;
1166         dma_pos = (dma_pos + copied) % dma_len;
1167         net += copied;
1168
1169         if (!copied) {
1170             break;
1171         }
1172     }
1173
1174     return net;
1175 }
1176
1177 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1178 {
1179     SB16State *s = opaque;
1180     int till, copy, written, free;
1181
1182     if (s->block_size <= 0) {
1183         dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1184                s->block_size, nchan, dma_pos, dma_len);
1185         return dma_pos;
1186     }
1187
1188     if (s->left_till_irq < 0) {
1189         s->left_till_irq = s->block_size;
1190     }
1191
1192     if (s->voice) {
1193         free = s->audio_free & ~s->align;
1194         if ((free <= 0) || !dma_len) {
1195             return dma_pos;
1196         }
1197     }
1198     else {
1199         free = dma_len;
1200     }
1201
1202     copy = free;
1203     till = s->left_till_irq;
1204
1205 #ifdef DEBUG_SB16_MOST
1206     dolog ("pos:%06d %d till:%d len:%d\n",
1207            dma_pos, free, till, dma_len);
1208 #endif
1209
1210     if (till <= copy) {
1211         if (0 == s->dma_auto) {
1212             copy = till;
1213         }
1214     }
1215
1216     written = write_audio (s, nchan, dma_pos, dma_len, copy);
1217     dma_pos = (dma_pos + written) % dma_len;
1218     s->left_till_irq -= written;
1219
1220     if (s->left_till_irq <= 0) {
1221         s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1222         qemu_irq_raise (s->pic);
1223         if (0 == s->dma_auto) {
1224             control (s, 0);
1225             speaker (s, 0);
1226         }
1227     }
1228
1229 #ifdef DEBUG_SB16_MOST
1230     ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1231             dma_pos, free, dma_len, s->left_till_irq, copy, written,
1232             s->block_size);
1233 #endif
1234
1235     while (s->left_till_irq <= 0) {
1236         s->left_till_irq = s->block_size + s->left_till_irq;
1237     }
1238
1239     return dma_pos;
1240 }
1241
1242 static void SB_audio_callback (void *opaque, int free)
1243 {
1244     SB16State *s = opaque;
1245     s->audio_free = free;
1246 }
1247
1248 static int sb16_post_load (void *opaque, int version_id)
1249 {
1250     SB16State *s = opaque;
1251
1252     if (s->voice) {
1253         AUD_close_out (&s->card, s->voice);
1254         s->voice = NULL;
1255     }
1256
1257     if (s->dma_running) {
1258         if (s->freq) {
1259             struct audsettings as;
1260
1261             s->audio_free = 0;
1262
1263             as.freq = s->freq;
1264             as.nchannels = 1 << s->fmt_stereo;
1265             as.fmt = s->fmt;
1266             as.endianness = 0;
1267
1268             s->voice = AUD_open_out (
1269                 &s->card,
1270                 s->voice,
1271                 "sb16",
1272                 s,
1273                 SB_audio_callback,
1274                 &as
1275                 );
1276         }
1277
1278         control (s, 1);
1279         speaker (s, s->speaker);
1280     }
1281     return 0;
1282 }
1283
1284 static const VMStateDescription vmstate_sb16 = {
1285     .name = "sb16",
1286     .version_id = 1,
1287     .minimum_version_id = 1,
1288     .minimum_version_id_old = 1,
1289     .post_load = sb16_post_load,
1290     .fields      = (VMStateField []) {
1291         VMSTATE_UINT32 (irq, SB16State),
1292         VMSTATE_UINT32 (dma, SB16State),
1293         VMSTATE_UINT32 (hdma, SB16State),
1294         VMSTATE_UINT32 (port, SB16State),
1295         VMSTATE_UINT32 (ver, SB16State),
1296         VMSTATE_INT32 (in_index, SB16State),
1297         VMSTATE_INT32 (out_data_len, SB16State),
1298         VMSTATE_INT32 (fmt_stereo, SB16State),
1299         VMSTATE_INT32 (fmt_signed, SB16State),
1300         VMSTATE_INT32 (fmt_bits, SB16State),
1301         VMSTATE_UINT32 (fmt, SB16State),
1302         VMSTATE_INT32 (dma_auto, SB16State),
1303         VMSTATE_INT32 (block_size, SB16State),
1304         VMSTATE_INT32 (fifo, SB16State),
1305         VMSTATE_INT32 (freq, SB16State),
1306         VMSTATE_INT32 (time_const, SB16State),
1307         VMSTATE_INT32 (speaker, SB16State),
1308         VMSTATE_INT32 (needed_bytes, SB16State),
1309         VMSTATE_INT32 (cmd, SB16State),
1310         VMSTATE_INT32 (use_hdma, SB16State),
1311         VMSTATE_INT32 (highspeed, SB16State),
1312         VMSTATE_INT32 (can_write, SB16State),
1313         VMSTATE_INT32 (v2x6, SB16State),
1314
1315         VMSTATE_UINT8 (csp_param, SB16State),
1316         VMSTATE_UINT8 (csp_value, SB16State),
1317         VMSTATE_UINT8 (csp_mode, SB16State),
1318         VMSTATE_UINT8 (csp_param, SB16State),
1319         VMSTATE_BUFFER (csp_regs, SB16State),
1320         VMSTATE_UINT8 (csp_index, SB16State),
1321         VMSTATE_BUFFER (csp_reg83, SB16State),
1322         VMSTATE_INT32 (csp_reg83r, SB16State),
1323         VMSTATE_INT32 (csp_reg83w, SB16State),
1324
1325         VMSTATE_BUFFER (in2_data, SB16State),
1326         VMSTATE_BUFFER (out_data, SB16State),
1327         VMSTATE_UINT8 (test_reg, SB16State),
1328         VMSTATE_UINT8 (last_read_byte, SB16State),
1329
1330         VMSTATE_INT32 (nzero, SB16State),
1331         VMSTATE_INT32 (left_till_irq, SB16State),
1332         VMSTATE_INT32 (dma_running, SB16State),
1333         VMSTATE_INT32 (bytes_per_second, SB16State),
1334         VMSTATE_INT32 (align, SB16State),
1335
1336         VMSTATE_INT32 (mixer_nreg, SB16State),
1337         VMSTATE_BUFFER (mixer_regs, SB16State),
1338
1339         VMSTATE_END_OF_LIST ()
1340     }
1341 };
1342
1343 static const MemoryRegionPortio sb16_ioport_list[] = {
1344     {  4, 1, 1, .write = mixer_write_indexb },
1345     {  4, 1, 2, .write = mixer_write_indexw },
1346     {  5, 1, 1, .read = mixer_read, .write = mixer_write_datab },
1347     {  6, 1, 1, .read = dsp_read, .write = dsp_write },
1348     { 10, 1, 1, .read = dsp_read },
1349     { 12, 1, 1, .write = dsp_write },
1350     { 12, 4, 1, .read = dsp_read },
1351     PORTIO_END_OF_LIST (),
1352 };
1353
1354
1355 static int sb16_initfn (ISADevice *dev)
1356 {
1357     SB16State *s;
1358
1359     s = DO_UPCAST (SB16State, dev, dev);
1360
1361     s->cmd = -1;
1362     isa_init_irq (dev, &s->pic, s->irq);
1363
1364     s->mixer_regs[0x80] = magic_of_irq (s->irq);
1365     s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1366     s->mixer_regs[0x82] = 2 << 5;
1367
1368     s->csp_regs[5] = 1;
1369     s->csp_regs[9] = 0xf8;
1370
1371     reset_mixer (s);
1372     s->aux_ts = qemu_new_timer_ns (vm_clock, aux_timer, s);
1373     if (!s->aux_ts) {
1374         dolog ("warning: Could not create auxiliary timer\n");
1375     }
1376
1377     isa_register_portio_list (dev, s->port, sb16_ioport_list, s, "sb16");
1378
1379     DMA_register_channel (s->hdma, SB_read_DMA, s);
1380     DMA_register_channel (s->dma, SB_read_DMA, s);
1381     s->can_write = 1;
1382
1383     AUD_register_card ("sb16", &s->card);
1384     return 0;
1385 }
1386
1387 int SB16_init (ISABus *bus)
1388 {
1389     isa_create_simple (bus, "sb16");
1390     return 0;
1391 }
1392
1393 static Property sb16_properties[] = {
1394     DEFINE_PROP_HEX32  ("version", SB16State, ver,  0x0405), /* 4.5 */
1395     DEFINE_PROP_HEX32  ("iobase",  SB16State, port, 0x220),
1396     DEFINE_PROP_UINT32 ("irq",     SB16State, irq,  5),
1397     DEFINE_PROP_UINT32 ("dma",     SB16State, dma,  1),
1398     DEFINE_PROP_UINT32 ("dma16",   SB16State, hdma, 5),
1399     DEFINE_PROP_END_OF_LIST (),
1400 };
1401
1402 static void sb16_class_initfn (ObjectClass *klass, void *data)
1403 {
1404     DeviceClass *dc = DEVICE_CLASS (klass);
1405     ISADeviceClass *ic = ISA_DEVICE_CLASS (klass);
1406     ic->init = sb16_initfn;
1407     dc->desc = "Creative Sound Blaster 16";
1408     dc->vmsd = &vmstate_sb16;
1409     dc->props = sb16_properties;
1410 }
1411
1412 static TypeInfo sb16_info = {
1413     .name          = "sb16",
1414     .parent        = TYPE_ISA_DEVICE,
1415     .instance_size = sizeof (SB16State),
1416     .class_init    = sb16_class_initfn,
1417 };
1418
1419 static void sb16_register_types (void)
1420 {
1421     type_register_static (&sb16_info);
1422 }
1423
1424 type_init (sb16_register_types)
This page took 0.101829 seconds and 4 git commands to generate.