2 * QEMU Soundblaster 16 emulation
4 * Copyright (c) 2003-2005 Vassili Karpov (malc)
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
25 #include "hw/audio/audio.h"
26 #include "audio/audio.h"
27 #include "hw/isa/isa.h"
29 #include "qemu/timer.h"
30 #include "qemu/host-utils.h"
32 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
35 /* #define DEBUG_SB16_MOST */
38 #define ldebug(...) dolog (__VA_ARGS__)
43 static const char e3
[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
45 #define TYPE_SB16 "sb16"
46 #define SB16(obj) OBJECT_CHECK (SB16State, (obj), TYPE_SB16)
48 typedef struct SB16State
{
82 uint8_t csp_regs
[256];
91 uint8_t last_read_byte
;
105 uint8_t mixer_regs
[256];
108 static void SB_audio_callback (void *opaque
, int free
);
110 static int magic_of_irq (int irq
)
122 dolog ("bad irq %d\n", irq
);
127 static int irq_of_magic (int magic
)
139 dolog ("bad irq magic %d\n", magic
);
145 static void log_dsp (SB16State
*dsp
)
147 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
148 dsp
->fmt_stereo
? "Stereo" : "Mono",
149 dsp
->fmt_signed
? "Signed" : "Unsigned",
151 dsp
->dma_auto
? "Auto" : "Single",
159 static void speaker (SB16State
*s
, int on
)
162 /* AUD_enable (s->voice, on); */
165 static void control (SB16State
*s
, int hold
)
167 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
168 s
->dma_running
= hold
;
170 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
174 AUD_set_active_out (s
->voice
, 1);
177 DMA_release_DREQ (dma
);
178 AUD_set_active_out (s
->voice
, 0);
182 static void aux_timer (void *opaque
)
184 SB16State
*s
= opaque
;
186 qemu_irq_raise (s
->pic
);
192 static void continue_dma8 (SB16State
*s
)
195 struct audsettings as
;
200 as
.nchannels
= 1 << s
->fmt_stereo
;
204 s
->voice
= AUD_open_out (
217 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
223 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
224 if (-1 == s
->time_const
) {
229 int tmp
= (256 - s
->time_const
);
230 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
234 s
->block_size
= dma_len
<< s
->fmt_stereo
;
237 /* This is apparently the only way to make both Act1/PL
238 and SecondReality/FC work
240 Act1 sets block size via command 0x48 and it's an odd number
241 SR does the same with even number
242 Both use stereo, and Creatives own documentation states that
243 0x48 sets block size in bytes less one.. go figure */
244 s
->block_size
&= ~s
->fmt_stereo
;
247 s
->freq
>>= s
->fmt_stereo
;
248 s
->left_till_irq
= s
->block_size
;
249 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
250 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
251 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
252 s
->align
= (1 << s
->fmt_stereo
) - 1;
254 if (s
->block_size
& s
->align
) {
255 dolog ("warning: misaligned block size %d, alignment %d\n",
256 s
->block_size
, s
->align
+ 1);
259 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
260 "dma %d, auto %d, fifo %d, high %d\n",
261 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
262 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
268 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
270 s
->use_hdma
= cmd
< 0xc0;
271 s
->fifo
= (cmd
>> 1) & 1;
272 s
->dma_auto
= (cmd
>> 2) & 1;
273 s
->fmt_signed
= (d0
>> 4) & 1;
274 s
->fmt_stereo
= (d0
>> 5) & 1;
286 if (-1 != s
->time_const
) {
288 int tmp
= 256 - s
->time_const
;
289 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
291 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
292 s
->freq
= 1000000 / ((255 - s
->time_const
));
297 s
->block_size
= dma_len
+ 1;
298 s
->block_size
<<= (s
->fmt_bits
== 16);
300 /* It is clear that for DOOM and auto-init this value
301 shouldn't take stereo into account, while Miles Sound Systems
302 setsound.exe with single transfer mode wouldn't work without it
303 wonders of SB16 yet again */
304 s
->block_size
<<= s
->fmt_stereo
;
307 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
308 "dma %d, auto %d, fifo %d, high %d\n",
309 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
310 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
312 if (16 == s
->fmt_bits
) {
314 s
->fmt
= AUD_FMT_S16
;
317 s
->fmt
= AUD_FMT_U16
;
329 s
->left_till_irq
= s
->block_size
;
331 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
333 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
334 if (s
->block_size
& s
->align
) {
335 dolog ("warning: misaligned block size %d, alignment %d\n",
336 s
->block_size
, s
->align
+ 1);
340 struct audsettings as
;
345 as
.nchannels
= 1 << s
->fmt_stereo
;
349 s
->voice
= AUD_open_out (
363 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
365 ldebug ("outdata %#x\n", val
);
366 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
367 s
->out_data
[s
->out_data_len
++] = val
;
371 static inline uint8_t dsp_get_data (SB16State
*s
)
374 return s
->in2_data
[--s
->in_index
];
377 dolog ("buffer underflow\n");
382 static void command (SB16State
*s
, uint8_t cmd
)
384 ldebug ("command %#x\n", cmd
);
386 if (cmd
> 0xaf && cmd
< 0xd0) {
388 dolog ("ADC not yet supported (command %#x)\n", cmd
);
396 dolog ("%#x wrong bits\n", cmd
);
405 dsp_out_data (s
, 0x10); /* s->csp_param); */
417 /* __asm__ ("int3"); */
425 dsp_out_data (s
, 0xf8);
441 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
442 dma_cmd8 (s
, DMA8_AUTO
, -1);
445 case 0x20: /* Direct ADC, Juice/PL */
446 dsp_out_data (s
, 0xff);
450 dolog ("0x35 - MIDI command not implemented\n");
472 dsp_out_data (s
, 0xaa);
475 case 0x47: /* Continue Auto-Initialize DMA 16bit */
483 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
484 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
487 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
489 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
492 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
494 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
497 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
499 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
503 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
504 dolog ("not implemented\n");
509 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
511 dolog ("not implemented\n");
520 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
523 case 0xd0: /* halt DMA operation. 8bit */
527 case 0xd1: /* speaker on */
531 case 0xd3: /* speaker off */
535 case 0xd4: /* continue DMA operation. 8bit */
536 /* KQ6 (or maybe Sierras audblst.drv in general) resets
537 the frequency between halt/continue */
541 case 0xd5: /* halt DMA operation. 16bit */
545 case 0xd6: /* continue DMA operation. 16bit */
549 case 0xd9: /* exit auto-init DMA after this block. 16bit */
553 case 0xda: /* exit auto-init DMA after this block. 8bit */
557 case 0xe0: /* DSP identification */
562 dsp_out_data (s
, s
->ver
& 0xff);
563 dsp_out_data (s
, s
->ver
>> 8);
573 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
574 dsp_out_data (s
, e3
[i
]);
578 case 0xe4: /* write test reg */
583 dolog ("Attempt to probe for ESS (0xe7)?\n");
586 case 0xe8: /* read test reg */
587 dsp_out_data (s
, s
->test_reg
);
592 dsp_out_data (s
, 0xaa);
593 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
594 qemu_irq_raise (s
->pic
);
605 case 0xfc: /* FIXME */
610 dolog ("Unrecognized command %#x\n", cmd
);
615 if (!s
->needed_bytes
) {
620 if (!s
->needed_bytes
) {
629 dolog ("warning: command %#x,%d is not truly understood yet\n",
630 cmd
, s
->needed_bytes
);
635 static uint16_t dsp_get_lohi (SB16State
*s
)
637 uint8_t hi
= dsp_get_data (s
);
638 uint8_t lo
= dsp_get_data (s
);
639 return (hi
<< 8) | lo
;
642 static uint16_t dsp_get_hilo (SB16State
*s
)
644 uint8_t lo
= dsp_get_data (s
);
645 uint8_t hi
= dsp_get_data (s
);
646 return (hi
<< 8) | lo
;
649 static void complete (SB16State
*s
)
652 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
653 s
->cmd
, s
->in_index
, s
->needed_bytes
);
655 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
656 d2
= dsp_get_data (s
);
657 d1
= dsp_get_data (s
);
658 d0
= dsp_get_data (s
);
661 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
665 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
667 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
673 s
->csp_mode
= dsp_get_data (s
);
676 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
680 s
->csp_param
= dsp_get_data (s
);
681 s
->csp_value
= dsp_get_data (s
);
682 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
688 d0
= dsp_get_data (s
);
689 d1
= dsp_get_data (s
);
690 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
692 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
693 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
697 s
->csp_regs
[d1
] = d0
;
702 d0
= dsp_get_data (s
);
703 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
704 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
706 ldebug ("0x83[%d] -> %#x\n",
708 s
->csp_reg83
[s
->csp_reg83w
% 4]);
709 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
713 dsp_out_data (s
, s
->csp_regs
[d0
]);
718 d0
= dsp_get_data (s
);
719 dolog ("cmd 0x10 d0=%#x\n", d0
);
723 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
727 s
->time_const
= dsp_get_data (s
);
728 ldebug ("set time const %d\n", s
->time_const
);
731 case 0x42: /* FT2 sets output freq with this, go figure */
733 dolog ("cmd 0x42 might not do what it think it should\n");
736 s
->freq
= dsp_get_hilo (s
);
737 ldebug ("set freq %d\n", s
->freq
);
741 s
->block_size
= dsp_get_lohi (s
) + 1;
742 ldebug ("set dma block len %d\n", s
->block_size
);
749 /* ADPCM stuff, ignore */
754 int freq
, samples
, bytes
;
757 freq
= s
->freq
> 0 ? s
->freq
: 11025;
758 samples
= dsp_get_lohi (s
) + 1;
759 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
760 ticks
= muldiv64 (bytes
, get_ticks_per_sec (), freq
);
761 if (ticks
< get_ticks_per_sec () / 1024) {
762 qemu_irq_raise (s
->pic
);
768 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) + ticks
772 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
777 d0
= dsp_get_data (s
);
779 ldebug ("E0 data = %#x\n", d0
);
780 dsp_out_data (s
, ~d0
);
785 d0
= dsp_get_data (s
);
786 dolog ("E2 = %#x\n", d0
);
791 s
->test_reg
= dsp_get_data (s
);
795 d0
= dsp_get_data (s
);
796 ldebug ("command 0xf9 with %#x\n", d0
);
799 dsp_out_data (s
, 0xff);
803 dsp_out_data (s
, 0x07);
807 dsp_out_data (s
, 0x38);
811 dsp_out_data (s
, 0x00);
817 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
826 static void legacy_reset (SB16State
*s
)
828 struct audsettings as
;
840 s
->voice
= AUD_open_out (
849 /* Not sure about that... */
850 /* AUD_set_active_out (s->voice, 1); */
853 static void reset (SB16State
*s
)
855 qemu_irq_lower (s
->pic
);
857 qemu_irq_raise (s
->pic
);
858 qemu_irq_lower (s
->pic
);
861 s
->mixer_regs
[0x82] = 0;
865 s
->left_till_irq
= 0;
873 dsp_out_data (s
, 0xaa);
879 static void dsp_write(void *opaque
, uint32_t nport
, uint32_t val
)
881 SB16State
*s
= opaque
;
884 iport
= nport
- s
->port
;
886 ldebug ("write %#x <- %#x\n", nport
, val
);
898 case 0x03: /* FreeBSD kludge */
903 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
906 case 0xb8: /* Panic */
911 dsp_out_data (s
, 0x38);
922 case 0x0c: /* write data or command | write status */
923 /* if (s->highspeed) */
926 if (s
->needed_bytes
== 0) {
929 if (0 == s
->needed_bytes
) {
935 if (s
->in_index
== sizeof (s
->in2_data
)) {
936 dolog ("in data overrun\n");
939 s
->in2_data
[s
->in_index
++] = val
;
940 if (s
->in_index
== s
->needed_bytes
) {
952 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
957 static uint32_t dsp_read(void *opaque
, uint32_t nport
)
959 SB16State
*s
= opaque
;
960 int iport
, retval
, ack
= 0;
962 iport
= nport
- s
->port
;
965 case 0x06: /* reset */
969 case 0x0a: /* read data */
970 if (s
->out_data_len
) {
971 retval
= s
->out_data
[--s
->out_data_len
];
972 s
->last_read_byte
= retval
;
976 dolog ("empty output buffer for command %#x\n",
979 retval
= s
->last_read_byte
;
984 case 0x0c: /* 0 can write */
985 retval
= s
->can_write
? 0 : 0x80;
988 case 0x0d: /* timer interrupt clear */
989 /* dolog ("timer interrupt clear\n"); */
993 case 0x0e: /* data available status | irq 8 ack */
994 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
995 if (s
->mixer_regs
[0x82] & 1) {
997 s
->mixer_regs
[0x82] &= ~1;
998 qemu_irq_lower (s
->pic
);
1002 case 0x0f: /* irq 16 ack */
1004 if (s
->mixer_regs
[0x82] & 2) {
1006 s
->mixer_regs
[0x82] &= ~2;
1007 qemu_irq_lower (s
->pic
);
1016 ldebug ("read %#x -> %#x\n", nport
, retval
);
1022 dolog ("warning: dsp_read %#x error\n", nport
);
1026 static void reset_mixer (SB16State
*s
)
1030 memset (s
->mixer_regs
, 0xff, 0x7f);
1031 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1033 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1034 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1035 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1036 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1038 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1039 s
->mixer_regs
[0x0c] = 0;
1041 /* d5=output filt, d1=stereo switch */
1042 s
->mixer_regs
[0x0e] = 0;
1044 /* voice volume L d5,d7, R d1,d3 */
1045 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1047 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1049 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1051 for (i
= 0x30; i
< 0x48; i
++) {
1052 s
->mixer_regs
[i
] = 0x20;
1056 static void mixer_write_indexb(void *opaque
, uint32_t nport
, uint32_t val
)
1058 SB16State
*s
= opaque
;
1060 s
->mixer_nreg
= val
;
1063 static void mixer_write_datab(void *opaque
, uint32_t nport
, uint32_t val
)
1065 SB16State
*s
= opaque
;
1068 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1070 switch (s
->mixer_nreg
) {
1077 int irq
= irq_of_magic (val
);
1078 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1089 dma
= ctz32 (val
& 0xf);
1090 hdma
= ctz32 (val
& 0xf0);
1091 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1093 "attempt to change DMA "
1094 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1095 dma
, s
->dma
, hdma
, s
->hdma
, val
);
1105 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1110 if (s
->mixer_nreg
>= 0x80) {
1111 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1116 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1119 static uint32_t mixer_read(void *opaque
, uint32_t nport
)
1121 SB16State
*s
= opaque
;
1124 #ifndef DEBUG_SB16_MOST
1125 if (s
->mixer_nreg
!= 0x82) {
1126 ldebug ("mixer_read[%#x] -> %#x\n",
1127 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1130 ldebug ("mixer_read[%#x] -> %#x\n",
1131 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1133 return s
->mixer_regs
[s
->mixer_nreg
];
1136 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1137 int dma_len
, int len
)
1140 uint8_t tmpbuf
[4096];
1146 int left
= dma_len
- dma_pos
;
1150 to_copy
= audio_MIN (temp
, left
);
1151 if (to_copy
> sizeof (tmpbuf
)) {
1152 to_copy
= sizeof (tmpbuf
);
1155 copied
= DMA_read_memory (nchan
, tmpbuf
, dma_pos
, to_copy
);
1156 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1159 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1170 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1172 SB16State
*s
= opaque
;
1173 int till
, copy
, written
, free
;
1175 if (s
->block_size
<= 0) {
1176 dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1177 s
->block_size
, nchan
, dma_pos
, dma_len
);
1181 if (s
->left_till_irq
< 0) {
1182 s
->left_till_irq
= s
->block_size
;
1186 free
= s
->audio_free
& ~s
->align
;
1187 if ((free
<= 0) || !dma_len
) {
1196 till
= s
->left_till_irq
;
1198 #ifdef DEBUG_SB16_MOST
1199 dolog ("pos:%06d %d till:%d len:%d\n",
1200 dma_pos
, free
, till
, dma_len
);
1204 if (s
->dma_auto
== 0) {
1209 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1210 dma_pos
= (dma_pos
+ written
) % dma_len
;
1211 s
->left_till_irq
-= written
;
1213 if (s
->left_till_irq
<= 0) {
1214 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1215 qemu_irq_raise (s
->pic
);
1216 if (s
->dma_auto
== 0) {
1222 #ifdef DEBUG_SB16_MOST
1223 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1224 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1228 while (s
->left_till_irq
<= 0) {
1229 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1235 static void SB_audio_callback (void *opaque
, int free
)
1237 SB16State
*s
= opaque
;
1238 s
->audio_free
= free
;
1241 static int sb16_post_load (void *opaque
, int version_id
)
1243 SB16State
*s
= opaque
;
1246 AUD_close_out (&s
->card
, s
->voice
);
1250 if (s
->dma_running
) {
1252 struct audsettings as
;
1257 as
.nchannels
= 1 << s
->fmt_stereo
;
1261 s
->voice
= AUD_open_out (
1272 speaker (s
, s
->speaker
);
1277 static const VMStateDescription vmstate_sb16
= {
1280 .minimum_version_id
= 1,
1281 .post_load
= sb16_post_load
,
1282 .fields
= (VMStateField
[]) {
1283 VMSTATE_UINT32 (irq
, SB16State
),
1284 VMSTATE_UINT32 (dma
, SB16State
),
1285 VMSTATE_UINT32 (hdma
, SB16State
),
1286 VMSTATE_UINT32 (port
, SB16State
),
1287 VMSTATE_UINT32 (ver
, SB16State
),
1288 VMSTATE_INT32 (in_index
, SB16State
),
1289 VMSTATE_INT32 (out_data_len
, SB16State
),
1290 VMSTATE_INT32 (fmt_stereo
, SB16State
),
1291 VMSTATE_INT32 (fmt_signed
, SB16State
),
1292 VMSTATE_INT32 (fmt_bits
, SB16State
),
1293 VMSTATE_UINT32 (fmt
, SB16State
),
1294 VMSTATE_INT32 (dma_auto
, SB16State
),
1295 VMSTATE_INT32 (block_size
, SB16State
),
1296 VMSTATE_INT32 (fifo
, SB16State
),
1297 VMSTATE_INT32 (freq
, SB16State
),
1298 VMSTATE_INT32 (time_const
, SB16State
),
1299 VMSTATE_INT32 (speaker
, SB16State
),
1300 VMSTATE_INT32 (needed_bytes
, SB16State
),
1301 VMSTATE_INT32 (cmd
, SB16State
),
1302 VMSTATE_INT32 (use_hdma
, SB16State
),
1303 VMSTATE_INT32 (highspeed
, SB16State
),
1304 VMSTATE_INT32 (can_write
, SB16State
),
1305 VMSTATE_INT32 (v2x6
, SB16State
),
1307 VMSTATE_UINT8 (csp_param
, SB16State
),
1308 VMSTATE_UINT8 (csp_value
, SB16State
),
1309 VMSTATE_UINT8 (csp_mode
, SB16State
),
1310 VMSTATE_UINT8 (csp_param
, SB16State
),
1311 VMSTATE_BUFFER (csp_regs
, SB16State
),
1312 VMSTATE_UINT8 (csp_index
, SB16State
),
1313 VMSTATE_BUFFER (csp_reg83
, SB16State
),
1314 VMSTATE_INT32 (csp_reg83r
, SB16State
),
1315 VMSTATE_INT32 (csp_reg83w
, SB16State
),
1317 VMSTATE_BUFFER (in2_data
, SB16State
),
1318 VMSTATE_BUFFER (out_data
, SB16State
),
1319 VMSTATE_UINT8 (test_reg
, SB16State
),
1320 VMSTATE_UINT8 (last_read_byte
, SB16State
),
1322 VMSTATE_INT32 (nzero
, SB16State
),
1323 VMSTATE_INT32 (left_till_irq
, SB16State
),
1324 VMSTATE_INT32 (dma_running
, SB16State
),
1325 VMSTATE_INT32 (bytes_per_second
, SB16State
),
1326 VMSTATE_INT32 (align
, SB16State
),
1328 VMSTATE_INT32 (mixer_nreg
, SB16State
),
1329 VMSTATE_BUFFER (mixer_regs
, SB16State
),
1331 VMSTATE_END_OF_LIST ()
1335 static const MemoryRegionPortio sb16_ioport_list
[] = {
1336 { 4, 1, 1, .write
= mixer_write_indexb
},
1337 { 5, 1, 1, .read
= mixer_read
, .write
= mixer_write_datab
},
1338 { 6, 1, 1, .read
= dsp_read
, .write
= dsp_write
},
1339 { 10, 1, 1, .read
= dsp_read
},
1340 { 12, 1, 1, .write
= dsp_write
},
1341 { 12, 4, 1, .read
= dsp_read
},
1342 PORTIO_END_OF_LIST (),
1346 static void sb16_initfn (Object
*obj
)
1348 SB16State
*s
= SB16 (obj
);
1353 static void sb16_realizefn (DeviceState
*dev
, Error
**errp
)
1355 ISADevice
*isadev
= ISA_DEVICE (dev
);
1356 SB16State
*s
= SB16 (dev
);
1358 isa_init_irq (isadev
, &s
->pic
, s
->irq
);
1360 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1361 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1362 s
->mixer_regs
[0x82] = 2 << 5;
1365 s
->csp_regs
[9] = 0xf8;
1368 s
->aux_ts
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, aux_timer
, s
);
1370 dolog ("warning: Could not create auxiliary timer\n");
1373 isa_register_portio_list (isadev
, s
->port
, sb16_ioport_list
, s
, "sb16");
1375 DMA_register_channel (s
->hdma
, SB_read_DMA
, s
);
1376 DMA_register_channel (s
->dma
, SB_read_DMA
, s
);
1379 AUD_register_card ("sb16", &s
->card
);
1382 static int SB16_init (ISABus
*bus
)
1384 isa_create_simple (bus
, TYPE_SB16
);
1388 static Property sb16_properties
[] = {
1389 DEFINE_PROP_UINT32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1390 DEFINE_PROP_UINT32 ("iobase", SB16State
, port
, 0x220),
1391 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1392 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1393 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1394 DEFINE_PROP_END_OF_LIST (),
1397 static void sb16_class_initfn (ObjectClass
*klass
, void *data
)
1399 DeviceClass
*dc
= DEVICE_CLASS (klass
);
1401 dc
->realize
= sb16_realizefn
;
1402 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1403 dc
->desc
= "Creative Sound Blaster 16";
1404 dc
->vmsd
= &vmstate_sb16
;
1405 dc
->props
= sb16_properties
;
1408 static const TypeInfo sb16_info
= {
1410 .parent
= TYPE_ISA_DEVICE
,
1411 .instance_size
= sizeof (SB16State
),
1412 .instance_init
= sb16_initfn
,
1413 .class_init
= sb16_class_initfn
,
1416 static void sb16_register_types (void)
1418 type_register_static (&sb16_info
);
1419 isa_register_soundhw("sb16", "Creative Sound Blaster 16", SB16_init
);
1422 type_init (sb16_register_types
)