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
24 #include "qemu/osdep.h"
26 #include "hw/audio/audio.h"
27 #include "audio/audio.h"
28 #include "hw/isa/isa.h"
30 #include "qemu/timer.h"
31 #include "qemu/host-utils.h"
33 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
36 /* #define DEBUG_SB16_MOST */
39 #define ldebug(...) dolog (__VA_ARGS__)
44 static const char e3
[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
46 #define TYPE_SB16 "sb16"
47 #define SB16(obj) OBJECT_CHECK (SB16State, (obj), TYPE_SB16)
49 typedef struct SB16State
{
85 uint8_t csp_regs
[256];
94 uint8_t last_read_byte
;
100 int bytes_per_second
;
108 uint8_t mixer_regs
[256];
111 static void SB_audio_callback (void *opaque
, int free
);
113 static int magic_of_irq (int irq
)
125 dolog ("bad irq %d\n", irq
);
130 static int irq_of_magic (int magic
)
142 dolog ("bad irq magic %d\n", magic
);
148 static void log_dsp (SB16State
*dsp
)
150 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
151 dsp
->fmt_stereo
? "Stereo" : "Mono",
152 dsp
->fmt_signed
? "Signed" : "Unsigned",
154 dsp
->dma_auto
? "Auto" : "Single",
162 static void speaker (SB16State
*s
, int on
)
165 /* AUD_enable (s->voice, on); */
168 static void control (SB16State
*s
, int hold
)
170 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
171 IsaDma
*isa_dma
= s
->use_hdma
? s
->isa_hdma
: s
->isa_dma
;
172 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
173 s
->dma_running
= hold
;
175 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
178 k
->hold_DREQ(isa_dma
, dma
);
179 AUD_set_active_out (s
->voice
, 1);
182 k
->release_DREQ(isa_dma
, dma
);
183 AUD_set_active_out (s
->voice
, 0);
187 static void aux_timer (void *opaque
)
189 SB16State
*s
= opaque
;
191 qemu_irq_raise (s
->pic
);
197 static void continue_dma8 (SB16State
*s
)
200 struct audsettings as
;
205 as
.nchannels
= 1 << s
->fmt_stereo
;
209 s
->voice
= AUD_open_out (
222 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
228 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
229 if (-1 == s
->time_const
) {
234 int tmp
= (256 - s
->time_const
);
235 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
239 s
->block_size
= dma_len
<< s
->fmt_stereo
;
242 /* This is apparently the only way to make both Act1/PL
243 and SecondReality/FC work
245 Act1 sets block size via command 0x48 and it's an odd number
246 SR does the same with even number
247 Both use stereo, and Creatives own documentation states that
248 0x48 sets block size in bytes less one.. go figure */
249 s
->block_size
&= ~s
->fmt_stereo
;
252 s
->freq
>>= s
->fmt_stereo
;
253 s
->left_till_irq
= s
->block_size
;
254 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
255 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
256 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
257 s
->align
= (1 << s
->fmt_stereo
) - 1;
259 if (s
->block_size
& s
->align
) {
260 dolog ("warning: misaligned block size %d, alignment %d\n",
261 s
->block_size
, s
->align
+ 1);
264 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
265 "dma %d, auto %d, fifo %d, high %d\n",
266 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
267 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
273 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
275 s
->use_hdma
= cmd
< 0xc0;
276 s
->fifo
= (cmd
>> 1) & 1;
277 s
->dma_auto
= (cmd
>> 2) & 1;
278 s
->fmt_signed
= (d0
>> 4) & 1;
279 s
->fmt_stereo
= (d0
>> 5) & 1;
291 if (-1 != s
->time_const
) {
293 int tmp
= 256 - s
->time_const
;
294 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
296 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
297 s
->freq
= 1000000 / ((255 - s
->time_const
));
302 s
->block_size
= dma_len
+ 1;
303 s
->block_size
<<= (s
->fmt_bits
== 16);
305 /* It is clear that for DOOM and auto-init this value
306 shouldn't take stereo into account, while Miles Sound Systems
307 setsound.exe with single transfer mode wouldn't work without it
308 wonders of SB16 yet again */
309 s
->block_size
<<= s
->fmt_stereo
;
312 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
313 "dma %d, auto %d, fifo %d, high %d\n",
314 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
315 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
317 if (16 == s
->fmt_bits
) {
319 s
->fmt
= AUD_FMT_S16
;
322 s
->fmt
= AUD_FMT_U16
;
334 s
->left_till_irq
= s
->block_size
;
336 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
338 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
339 if (s
->block_size
& s
->align
) {
340 dolog ("warning: misaligned block size %d, alignment %d\n",
341 s
->block_size
, s
->align
+ 1);
345 struct audsettings as
;
350 as
.nchannels
= 1 << s
->fmt_stereo
;
354 s
->voice
= AUD_open_out (
368 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
370 ldebug ("outdata %#x\n", val
);
371 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
372 s
->out_data
[s
->out_data_len
++] = val
;
376 static inline uint8_t dsp_get_data (SB16State
*s
)
379 return s
->in2_data
[--s
->in_index
];
382 dolog ("buffer underflow\n");
387 static void command (SB16State
*s
, uint8_t cmd
)
389 ldebug ("command %#x\n", cmd
);
391 if (cmd
> 0xaf && cmd
< 0xd0) {
393 dolog ("ADC not yet supported (command %#x)\n", cmd
);
401 dolog ("%#x wrong bits\n", cmd
);
410 dsp_out_data (s
, 0x10); /* s->csp_param); */
422 /* __asm__ ("int3"); */
430 dsp_out_data (s
, 0xf8);
446 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
447 dma_cmd8 (s
, DMA8_AUTO
, -1);
450 case 0x20: /* Direct ADC, Juice/PL */
451 dsp_out_data (s
, 0xff);
455 dolog ("0x35 - MIDI command not implemented\n");
477 dsp_out_data (s
, 0xaa);
480 case 0x47: /* Continue Auto-Initialize DMA 16bit */
488 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
489 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
492 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
494 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
497 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
499 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
502 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
504 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
508 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
509 dolog ("not implemented\n");
514 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
516 dolog ("not implemented\n");
525 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
528 case 0xd0: /* halt DMA operation. 8bit */
532 case 0xd1: /* speaker on */
536 case 0xd3: /* speaker off */
540 case 0xd4: /* continue DMA operation. 8bit */
541 /* KQ6 (or maybe Sierras audblst.drv in general) resets
542 the frequency between halt/continue */
546 case 0xd5: /* halt DMA operation. 16bit */
550 case 0xd6: /* continue DMA operation. 16bit */
554 case 0xd9: /* exit auto-init DMA after this block. 16bit */
558 case 0xda: /* exit auto-init DMA after this block. 8bit */
562 case 0xe0: /* DSP identification */
567 dsp_out_data (s
, s
->ver
& 0xff);
568 dsp_out_data (s
, s
->ver
>> 8);
578 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
579 dsp_out_data (s
, e3
[i
]);
583 case 0xe4: /* write test reg */
588 dolog ("Attempt to probe for ESS (0xe7)?\n");
591 case 0xe8: /* read test reg */
592 dsp_out_data (s
, s
->test_reg
);
597 dsp_out_data (s
, 0xaa);
598 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
599 qemu_irq_raise (s
->pic
);
610 case 0xfc: /* FIXME */
615 dolog ("Unrecognized command %#x\n", cmd
);
620 if (!s
->needed_bytes
) {
625 if (!s
->needed_bytes
) {
634 dolog ("warning: command %#x,%d is not truly understood yet\n",
635 cmd
, s
->needed_bytes
);
640 static uint16_t dsp_get_lohi (SB16State
*s
)
642 uint8_t hi
= dsp_get_data (s
);
643 uint8_t lo
= dsp_get_data (s
);
644 return (hi
<< 8) | lo
;
647 static uint16_t dsp_get_hilo (SB16State
*s
)
649 uint8_t lo
= dsp_get_data (s
);
650 uint8_t hi
= dsp_get_data (s
);
651 return (hi
<< 8) | lo
;
654 static void complete (SB16State
*s
)
657 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
658 s
->cmd
, s
->in_index
, s
->needed_bytes
);
660 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
661 d2
= dsp_get_data (s
);
662 d1
= dsp_get_data (s
);
663 d0
= dsp_get_data (s
);
666 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
670 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
672 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
678 s
->csp_mode
= dsp_get_data (s
);
681 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
685 s
->csp_param
= dsp_get_data (s
);
686 s
->csp_value
= dsp_get_data (s
);
687 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
693 d0
= dsp_get_data (s
);
694 d1
= dsp_get_data (s
);
695 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
697 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
698 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
702 s
->csp_regs
[d1
] = d0
;
707 d0
= dsp_get_data (s
);
708 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
709 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
711 ldebug ("0x83[%d] -> %#x\n",
713 s
->csp_reg83
[s
->csp_reg83w
% 4]);
714 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
718 dsp_out_data (s
, s
->csp_regs
[d0
]);
723 d0
= dsp_get_data (s
);
724 dolog ("cmd 0x10 d0=%#x\n", d0
);
728 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
732 s
->time_const
= dsp_get_data (s
);
733 ldebug ("set time const %d\n", s
->time_const
);
736 case 0x42: /* FT2 sets output freq with this, go figure */
738 dolog ("cmd 0x42 might not do what it think it should\n");
741 s
->freq
= dsp_get_hilo (s
);
742 ldebug ("set freq %d\n", s
->freq
);
746 s
->block_size
= dsp_get_lohi (s
) + 1;
747 ldebug ("set dma block len %d\n", s
->block_size
);
754 /* ADPCM stuff, ignore */
759 int freq
, samples
, bytes
;
762 freq
= s
->freq
> 0 ? s
->freq
: 11025;
763 samples
= dsp_get_lohi (s
) + 1;
764 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
765 ticks
= muldiv64 (bytes
, get_ticks_per_sec (), freq
);
766 if (ticks
< get_ticks_per_sec () / 1024) {
767 qemu_irq_raise (s
->pic
);
773 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) + ticks
777 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
782 d0
= dsp_get_data (s
);
784 ldebug ("E0 data = %#x\n", d0
);
785 dsp_out_data (s
, ~d0
);
790 d0
= dsp_get_data (s
);
791 dolog ("E2 = %#x\n", d0
);
796 s
->test_reg
= dsp_get_data (s
);
800 d0
= dsp_get_data (s
);
801 ldebug ("command 0xf9 with %#x\n", d0
);
804 dsp_out_data (s
, 0xff);
808 dsp_out_data (s
, 0x07);
812 dsp_out_data (s
, 0x38);
816 dsp_out_data (s
, 0x00);
822 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
831 static void legacy_reset (SB16State
*s
)
833 struct audsettings as
;
845 s
->voice
= AUD_open_out (
854 /* Not sure about that... */
855 /* AUD_set_active_out (s->voice, 1); */
858 static void reset (SB16State
*s
)
860 qemu_irq_lower (s
->pic
);
862 qemu_irq_raise (s
->pic
);
863 qemu_irq_lower (s
->pic
);
866 s
->mixer_regs
[0x82] = 0;
870 s
->left_till_irq
= 0;
878 dsp_out_data (s
, 0xaa);
884 static void dsp_write(void *opaque
, uint32_t nport
, uint32_t val
)
886 SB16State
*s
= opaque
;
889 iport
= nport
- s
->port
;
891 ldebug ("write %#x <- %#x\n", nport
, val
);
903 case 0x03: /* FreeBSD kludge */
908 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
911 case 0xb8: /* Panic */
916 dsp_out_data (s
, 0x38);
927 case 0x0c: /* write data or command | write status */
928 /* if (s->highspeed) */
931 if (s
->needed_bytes
== 0) {
934 if (0 == s
->needed_bytes
) {
940 if (s
->in_index
== sizeof (s
->in2_data
)) {
941 dolog ("in data overrun\n");
944 s
->in2_data
[s
->in_index
++] = val
;
945 if (s
->in_index
== s
->needed_bytes
) {
957 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
962 static uint32_t dsp_read(void *opaque
, uint32_t nport
)
964 SB16State
*s
= opaque
;
965 int iport
, retval
, ack
= 0;
967 iport
= nport
- s
->port
;
970 case 0x06: /* reset */
974 case 0x0a: /* read data */
975 if (s
->out_data_len
) {
976 retval
= s
->out_data
[--s
->out_data_len
];
977 s
->last_read_byte
= retval
;
981 dolog ("empty output buffer for command %#x\n",
984 retval
= s
->last_read_byte
;
989 case 0x0c: /* 0 can write */
990 retval
= s
->can_write
? 0 : 0x80;
993 case 0x0d: /* timer interrupt clear */
994 /* dolog ("timer interrupt clear\n"); */
998 case 0x0e: /* data available status | irq 8 ack */
999 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1000 if (s
->mixer_regs
[0x82] & 1) {
1002 s
->mixer_regs
[0x82] &= ~1;
1003 qemu_irq_lower (s
->pic
);
1007 case 0x0f: /* irq 16 ack */
1009 if (s
->mixer_regs
[0x82] & 2) {
1011 s
->mixer_regs
[0x82] &= ~2;
1012 qemu_irq_lower (s
->pic
);
1021 ldebug ("read %#x -> %#x\n", nport
, retval
);
1027 dolog ("warning: dsp_read %#x error\n", nport
);
1031 static void reset_mixer (SB16State
*s
)
1035 memset (s
->mixer_regs
, 0xff, 0x7f);
1036 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1038 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1039 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1040 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1041 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1043 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1044 s
->mixer_regs
[0x0c] = 0;
1046 /* d5=output filt, d1=stereo switch */
1047 s
->mixer_regs
[0x0e] = 0;
1049 /* voice volume L d5,d7, R d1,d3 */
1050 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1052 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1054 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1056 for (i
= 0x30; i
< 0x48; i
++) {
1057 s
->mixer_regs
[i
] = 0x20;
1061 static void mixer_write_indexb(void *opaque
, uint32_t nport
, uint32_t val
)
1063 SB16State
*s
= opaque
;
1065 s
->mixer_nreg
= val
;
1068 static void mixer_write_datab(void *opaque
, uint32_t nport
, uint32_t val
)
1070 SB16State
*s
= opaque
;
1073 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1075 switch (s
->mixer_nreg
) {
1082 int irq
= irq_of_magic (val
);
1083 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1094 dma
= ctz32 (val
& 0xf);
1095 hdma
= ctz32 (val
& 0xf0);
1096 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1098 "attempt to change DMA "
1099 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1100 dma
, s
->dma
, hdma
, s
->hdma
, val
);
1110 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1115 if (s
->mixer_nreg
>= 0x80) {
1116 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1121 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1124 static uint32_t mixer_read(void *opaque
, uint32_t nport
)
1126 SB16State
*s
= opaque
;
1129 #ifndef DEBUG_SB16_MOST
1130 if (s
->mixer_nreg
!= 0x82) {
1131 ldebug ("mixer_read[%#x] -> %#x\n",
1132 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1135 ldebug ("mixer_read[%#x] -> %#x\n",
1136 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1138 return s
->mixer_regs
[s
->mixer_nreg
];
1141 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1142 int dma_len
, int len
)
1144 IsaDma
*isa_dma
= nchan
== s
->dma
? s
->isa_dma
: s
->isa_hdma
;
1145 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
1147 uint8_t tmpbuf
[4096];
1153 int left
= dma_len
- dma_pos
;
1157 to_copy
= audio_MIN (temp
, left
);
1158 if (to_copy
> sizeof (tmpbuf
)) {
1159 to_copy
= sizeof (tmpbuf
);
1162 copied
= k
->read_memory(isa_dma
, nchan
, tmpbuf
, dma_pos
, to_copy
);
1163 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1166 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1177 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1179 SB16State
*s
= opaque
;
1180 int till
, copy
, written
, free
;
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
);
1188 if (s
->left_till_irq
< 0) {
1189 s
->left_till_irq
= s
->block_size
;
1193 free
= s
->audio_free
& ~s
->align
;
1194 if ((free
<= 0) || !dma_len
) {
1203 till
= s
->left_till_irq
;
1205 #ifdef DEBUG_SB16_MOST
1206 dolog ("pos:%06d %d till:%d len:%d\n",
1207 dma_pos
, free
, till
, dma_len
);
1211 if (s
->dma_auto
== 0) {
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
;
1220 if (s
->left_till_irq
<= 0) {
1221 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1222 qemu_irq_raise (s
->pic
);
1223 if (s
->dma_auto
== 0) {
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
,
1235 while (s
->left_till_irq
<= 0) {
1236 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1242 static void SB_audio_callback (void *opaque
, int free
)
1244 SB16State
*s
= opaque
;
1245 s
->audio_free
= free
;
1248 static int sb16_post_load (void *opaque
, int version_id
)
1250 SB16State
*s
= opaque
;
1253 AUD_close_out (&s
->card
, s
->voice
);
1257 if (s
->dma_running
) {
1259 struct audsettings as
;
1264 as
.nchannels
= 1 << s
->fmt_stereo
;
1268 s
->voice
= AUD_open_out (
1279 speaker (s
, s
->speaker
);
1284 static const VMStateDescription vmstate_sb16
= {
1287 .minimum_version_id
= 1,
1288 .post_load
= sb16_post_load
,
1289 .fields
= (VMStateField
[]) {
1290 VMSTATE_UINT32 (irq
, SB16State
),
1291 VMSTATE_UINT32 (dma
, SB16State
),
1292 VMSTATE_UINT32 (hdma
, SB16State
),
1293 VMSTATE_UINT32 (port
, SB16State
),
1294 VMSTATE_UINT32 (ver
, SB16State
),
1295 VMSTATE_INT32 (in_index
, SB16State
),
1296 VMSTATE_INT32 (out_data_len
, SB16State
),
1297 VMSTATE_INT32 (fmt_stereo
, SB16State
),
1298 VMSTATE_INT32 (fmt_signed
, SB16State
),
1299 VMSTATE_INT32 (fmt_bits
, SB16State
),
1300 VMSTATE_UINT32 (fmt
, SB16State
),
1301 VMSTATE_INT32 (dma_auto
, SB16State
),
1302 VMSTATE_INT32 (block_size
, SB16State
),
1303 VMSTATE_INT32 (fifo
, SB16State
),
1304 VMSTATE_INT32 (freq
, SB16State
),
1305 VMSTATE_INT32 (time_const
, SB16State
),
1306 VMSTATE_INT32 (speaker
, SB16State
),
1307 VMSTATE_INT32 (needed_bytes
, SB16State
),
1308 VMSTATE_INT32 (cmd
, SB16State
),
1309 VMSTATE_INT32 (use_hdma
, SB16State
),
1310 VMSTATE_INT32 (highspeed
, SB16State
),
1311 VMSTATE_INT32 (can_write
, SB16State
),
1312 VMSTATE_INT32 (v2x6
, SB16State
),
1314 VMSTATE_UINT8 (csp_param
, SB16State
),
1315 VMSTATE_UINT8 (csp_value
, SB16State
),
1316 VMSTATE_UINT8 (csp_mode
, SB16State
),
1317 VMSTATE_UINT8 (csp_param
, SB16State
),
1318 VMSTATE_BUFFER (csp_regs
, SB16State
),
1319 VMSTATE_UINT8 (csp_index
, SB16State
),
1320 VMSTATE_BUFFER (csp_reg83
, SB16State
),
1321 VMSTATE_INT32 (csp_reg83r
, SB16State
),
1322 VMSTATE_INT32 (csp_reg83w
, SB16State
),
1324 VMSTATE_BUFFER (in2_data
, SB16State
),
1325 VMSTATE_BUFFER (out_data
, SB16State
),
1326 VMSTATE_UINT8 (test_reg
, SB16State
),
1327 VMSTATE_UINT8 (last_read_byte
, SB16State
),
1329 VMSTATE_INT32 (nzero
, SB16State
),
1330 VMSTATE_INT32 (left_till_irq
, SB16State
),
1331 VMSTATE_INT32 (dma_running
, SB16State
),
1332 VMSTATE_INT32 (bytes_per_second
, SB16State
),
1333 VMSTATE_INT32 (align
, SB16State
),
1335 VMSTATE_INT32 (mixer_nreg
, SB16State
),
1336 VMSTATE_BUFFER (mixer_regs
, SB16State
),
1338 VMSTATE_END_OF_LIST ()
1342 static const MemoryRegionPortio sb16_ioport_list
[] = {
1343 { 4, 1, 1, .write
= mixer_write_indexb
},
1344 { 5, 1, 1, .read
= mixer_read
, .write
= mixer_write_datab
},
1345 { 6, 1, 1, .read
= dsp_read
, .write
= dsp_write
},
1346 { 10, 1, 1, .read
= dsp_read
},
1347 { 12, 1, 1, .write
= dsp_write
},
1348 { 12, 4, 1, .read
= dsp_read
},
1349 PORTIO_END_OF_LIST (),
1353 static void sb16_initfn (Object
*obj
)
1355 SB16State
*s
= SB16 (obj
);
1360 static void sb16_realizefn (DeviceState
*dev
, Error
**errp
)
1362 ISADevice
*isadev
= ISA_DEVICE (dev
);
1363 SB16State
*s
= SB16 (dev
);
1366 isa_init_irq (isadev
, &s
->pic
, s
->irq
);
1368 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1369 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1370 s
->mixer_regs
[0x82] = 2 << 5;
1373 s
->csp_regs
[9] = 0xf8;
1376 s
->aux_ts
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, aux_timer
, s
);
1378 dolog ("warning: Could not create auxiliary timer\n");
1381 isa_register_portio_list (isadev
, s
->port
, sb16_ioport_list
, s
, "sb16");
1383 s
->isa_hdma
= isa_get_dma(isa_bus_from_device(isadev
), s
->hdma
);
1384 k
= ISADMA_GET_CLASS(s
->isa_hdma
);
1385 k
->register_channel(s
->isa_hdma
, s
->hdma
, SB_read_DMA
, s
);
1387 s
->isa_dma
= isa_get_dma(isa_bus_from_device(isadev
), s
->dma
);
1388 k
= ISADMA_GET_CLASS(s
->isa_dma
);
1389 k
->register_channel(s
->isa_dma
, s
->dma
, SB_read_DMA
, s
);
1393 AUD_register_card ("sb16", &s
->card
);
1396 static int SB16_init (ISABus
*bus
)
1398 isa_create_simple (bus
, TYPE_SB16
);
1402 static Property sb16_properties
[] = {
1403 DEFINE_PROP_UINT32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1404 DEFINE_PROP_UINT32 ("iobase", SB16State
, port
, 0x220),
1405 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1406 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1407 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1408 DEFINE_PROP_END_OF_LIST (),
1411 static void sb16_class_initfn (ObjectClass
*klass
, void *data
)
1413 DeviceClass
*dc
= DEVICE_CLASS (klass
);
1415 dc
->realize
= sb16_realizefn
;
1416 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1417 dc
->desc
= "Creative Sound Blaster 16";
1418 dc
->vmsd
= &vmstate_sb16
;
1419 dc
->props
= sb16_properties
;
1422 static const TypeInfo sb16_info
= {
1424 .parent
= TYPE_ISA_DEVICE
,
1425 .instance_size
= sizeof (SB16State
),
1426 .instance_init
= sb16_initfn
,
1427 .class_init
= sb16_class_initfn
,
1430 static void sb16_register_types (void)
1432 type_register_static (&sb16_info
);
1433 isa_register_soundhw("sb16", "Creative Sound Blaster 16", SB16_init
);
1436 type_init (sb16_register_types
)