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 "qemu/osdep.h"
26 #include "hw/audio/soundhw.h"
27 #include "audio/audio.h"
29 #include "hw/isa/isa.h"
30 #include "hw/qdev-properties.h"
31 #include "migration/vmstate.h"
32 #include "qemu/timer.h"
33 #include "qemu/host-utils.h"
35 #include "qemu/module.h"
36 #include "qapi/error.h"
37 #include "qom/object.h"
39 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
42 /* #define DEBUG_SB16_MOST */
45 #define ldebug(...) dolog (__VA_ARGS__)
50 static const char e3
[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
52 #define TYPE_SB16 "sb16"
53 OBJECT_DECLARE_SIMPLE_TYPE(SB16State
, SB16
)
91 uint8_t csp_regs
[256];
100 uint8_t last_read_byte
;
106 int bytes_per_second
;
114 uint8_t mixer_regs
[256];
115 PortioList portio_list
;
118 #define SAMPLE_RATE_MIN 5000
119 #define SAMPLE_RATE_MAX 45000
121 static void SB_audio_callback (void *opaque
, int free
);
123 static int magic_of_irq (int irq
)
135 qemu_log_mask(LOG_GUEST_ERROR
, "bad irq %d\n", irq
);
140 static int irq_of_magic (int magic
)
152 qemu_log_mask(LOG_GUEST_ERROR
, "bad irq magic %d\n", magic
);
158 static void log_dsp (SB16State
*dsp
)
160 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
161 dsp
->fmt_stereo
? "Stereo" : "Mono",
162 dsp
->fmt_signed
? "Signed" : "Unsigned",
164 dsp
->dma_auto
? "Auto" : "Single",
172 static void speaker (SB16State
*s
, int on
)
175 /* AUD_enable (s->voice, on); */
178 static void control (SB16State
*s
, int hold
)
180 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
181 IsaDma
*isa_dma
= s
->use_hdma
? s
->isa_hdma
: s
->isa_dma
;
182 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
183 s
->dma_running
= hold
;
185 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
188 k
->hold_DREQ(isa_dma
, dma
);
189 AUD_set_active_out (s
->voice
, 1);
192 k
->release_DREQ(isa_dma
, dma
);
193 AUD_set_active_out (s
->voice
, 0);
197 static void aux_timer (void *opaque
)
199 SB16State
*s
= opaque
;
201 qemu_irq_raise (s
->pic
);
207 static void continue_dma8 (SB16State
*s
)
210 struct audsettings as
;
215 as
.nchannels
= 1 << s
->fmt_stereo
;
219 s
->voice
= AUD_open_out (
232 static inline int restrict_sampling_rate(int freq
)
234 if (freq
< SAMPLE_RATE_MIN
) {
235 qemu_log_mask(LOG_GUEST_ERROR
,
236 "sampling range too low: %d, increasing to %u\n",
237 freq
, SAMPLE_RATE_MIN
);
238 return SAMPLE_RATE_MIN
;
239 } else if (freq
> SAMPLE_RATE_MAX
) {
240 qemu_log_mask(LOG_GUEST_ERROR
,
241 "sampling range too high: %d, decreasing to %u\n",
242 freq
, SAMPLE_RATE_MAX
);
243 return SAMPLE_RATE_MAX
;
249 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
251 s
->fmt
= AUDIO_FORMAT_U8
;
255 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
256 if (-1 == s
->time_const
) {
261 int tmp
= (256 - s
->time_const
);
262 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
264 s
->freq
= restrict_sampling_rate(s
->freq
);
267 s
->block_size
= dma_len
<< s
->fmt_stereo
;
270 /* This is apparently the only way to make both Act1/PL
271 and SecondReality/FC work
273 Act1 sets block size via command 0x48 and it's an odd number
274 SR does the same with even number
275 Both use stereo, and Creatives own documentation states that
276 0x48 sets block size in bytes less one.. go figure */
277 s
->block_size
&= ~s
->fmt_stereo
;
280 s
->freq
>>= s
->fmt_stereo
;
281 s
->left_till_irq
= s
->block_size
;
282 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
283 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
284 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
285 s
->align
= (1 << s
->fmt_stereo
) - 1;
287 if (s
->block_size
& s
->align
) {
288 qemu_log_mask(LOG_GUEST_ERROR
, "warning: misaligned block size %d,"
289 " alignment %d\n", s
->block_size
, s
->align
+ 1);
292 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
293 "dma %d, auto %d, fifo %d, high %d\n",
294 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
295 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
301 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
303 s
->use_hdma
= cmd
< 0xc0;
304 s
->fifo
= (cmd
>> 1) & 1;
305 s
->dma_auto
= (cmd
>> 2) & 1;
306 s
->fmt_signed
= (d0
>> 4) & 1;
307 s
->fmt_stereo
= (d0
>> 5) & 1;
319 if (-1 != s
->time_const
) {
321 int tmp
= 256 - s
->time_const
;
322 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
324 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
325 s
->freq
= 1000000 / ((255 - s
->time_const
));
330 s
->block_size
= dma_len
+ 1;
331 s
->block_size
<<= (s
->fmt_bits
== 16);
333 /* It is clear that for DOOM and auto-init this value
334 shouldn't take stereo into account, while Miles Sound Systems
335 setsound.exe with single transfer mode wouldn't work without it
336 wonders of SB16 yet again */
337 s
->block_size
<<= s
->fmt_stereo
;
340 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
341 "dma %d, auto %d, fifo %d, high %d\n",
342 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
343 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
345 if (16 == s
->fmt_bits
) {
347 s
->fmt
= AUDIO_FORMAT_S16
;
350 s
->fmt
= AUDIO_FORMAT_U16
;
355 s
->fmt
= AUDIO_FORMAT_S8
;
358 s
->fmt
= AUDIO_FORMAT_U8
;
362 s
->left_till_irq
= s
->block_size
;
364 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
366 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
367 if (s
->block_size
& s
->align
) {
368 qemu_log_mask(LOG_GUEST_ERROR
, "warning: misaligned block size %d,"
369 " alignment %d\n", s
->block_size
, s
->align
+ 1);
373 struct audsettings as
;
378 as
.nchannels
= 1 << s
->fmt_stereo
;
382 s
->voice
= AUD_open_out (
396 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
398 ldebug ("outdata %#x\n", val
);
399 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
400 s
->out_data
[s
->out_data_len
++] = val
;
404 static inline uint8_t dsp_get_data (SB16State
*s
)
407 return s
->in2_data
[--s
->in_index
];
410 dolog ("buffer underflow\n");
415 static void command (SB16State
*s
, uint8_t cmd
)
417 ldebug ("command %#x\n", cmd
);
419 if (cmd
> 0xaf && cmd
< 0xd0) {
421 qemu_log_mask(LOG_UNIMP
, "ADC not yet supported (command %#x)\n",
430 qemu_log_mask(LOG_GUEST_ERROR
, "%#x wrong bits\n", cmd
);
439 dsp_out_data (s
, 0x10); /* s->csp_param); */
451 /* __asm__ ("int3"); */
459 dsp_out_data (s
, 0xf8);
475 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
476 dma_cmd8 (s
, DMA8_AUTO
, -1);
479 case 0x20: /* Direct ADC, Juice/PL */
480 dsp_out_data (s
, 0xff);
484 qemu_log_mask(LOG_UNIMP
, "0x35 - MIDI command not implemented\n");
506 dsp_out_data (s
, 0xaa);
509 case 0x47: /* Continue Auto-Initialize DMA 16bit */
517 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
518 qemu_log_mask(LOG_UNIMP
, "0x75 - DMA DAC, 4-bit ADPCM not"
522 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
524 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 4-bit ADPCM Reference not"
528 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
530 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 2.6-bit ADPCM not"
534 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
536 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 2.6-bit ADPCM Reference"
537 " not implemented\n");
541 qemu_log_mask(LOG_UNIMP
, "0x7d - Autio-Initialize DMA DAC, 4-bit"
542 " ADPCM Reference\n");
543 qemu_log_mask(LOG_UNIMP
, "not implemented\n");
547 qemu_log_mask(LOG_UNIMP
, "0x7d - Autio-Initialize DMA DAC, 2.6-bit"
548 " ADPCM Reference\n");
549 qemu_log_mask(LOG_UNIMP
, "not implemented\n");
558 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
561 case 0xd0: /* halt DMA operation. 8bit */
565 case 0xd1: /* speaker on */
569 case 0xd3: /* speaker off */
573 case 0xd4: /* continue DMA operation. 8bit */
574 /* KQ6 (or maybe Sierras audblst.drv in general) resets
575 the frequency between halt/continue */
579 case 0xd5: /* halt DMA operation. 16bit */
583 case 0xd6: /* continue DMA operation. 16bit */
587 case 0xd9: /* exit auto-init DMA after this block. 16bit */
591 case 0xda: /* exit auto-init DMA after this block. 8bit */
595 case 0xe0: /* DSP identification */
600 dsp_out_data (s
, s
->ver
& 0xff);
601 dsp_out_data (s
, s
->ver
>> 8);
611 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
612 dsp_out_data (s
, e3
[i
]);
616 case 0xe4: /* write test reg */
621 qemu_log_mask(LOG_UNIMP
, "Attempt to probe for ESS (0xe7)?\n");
624 case 0xe8: /* read test reg */
625 dsp_out_data (s
, s
->test_reg
);
630 dsp_out_data (s
, 0xaa);
631 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
632 qemu_irq_raise (s
->pic
);
643 case 0xfc: /* FIXME */
648 qemu_log_mask(LOG_UNIMP
, "Unrecognized command %#x\n", cmd
);
653 if (!s
->needed_bytes
) {
658 if (!s
->needed_bytes
) {
667 qemu_log_mask(LOG_UNIMP
, "warning: command %#x,%d is not truly understood"
668 " yet\n", cmd
, s
->needed_bytes
);
673 static uint16_t dsp_get_lohi (SB16State
*s
)
675 uint8_t hi
= dsp_get_data (s
);
676 uint8_t lo
= dsp_get_data (s
);
677 return (hi
<< 8) | lo
;
680 static uint16_t dsp_get_hilo (SB16State
*s
)
682 uint8_t lo
= dsp_get_data (s
);
683 uint8_t hi
= dsp_get_data (s
);
684 return (hi
<< 8) | lo
;
687 static void complete (SB16State
*s
)
690 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
691 s
->cmd
, s
->in_index
, s
->needed_bytes
);
693 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
694 d2
= dsp_get_data (s
);
695 d1
= dsp_get_data (s
);
696 d0
= dsp_get_data (s
);
699 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
703 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
705 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
711 s
->csp_mode
= dsp_get_data (s
);
714 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
718 s
->csp_param
= dsp_get_data (s
);
719 s
->csp_value
= dsp_get_data (s
);
720 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
726 d0
= dsp_get_data (s
);
727 d1
= dsp_get_data (s
);
728 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
730 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
731 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
735 s
->csp_regs
[d1
] = d0
;
740 d0
= dsp_get_data (s
);
741 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
742 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
744 ldebug ("0x83[%d] -> %#x\n",
746 s
->csp_reg83
[s
->csp_reg83w
% 4]);
747 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
751 dsp_out_data (s
, s
->csp_regs
[d0
]);
756 d0
= dsp_get_data (s
);
757 dolog ("cmd 0x10 d0=%#x\n", d0
);
761 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
765 s
->time_const
= dsp_get_data (s
);
766 ldebug ("set time const %d\n", s
->time_const
);
772 * 0x41 is documented as setting the output sample rate,
773 * and 0x42 the input sample rate, but in fact SB16 hardware
774 * seems to have only a single sample rate under the hood,
775 * and FT2 sets output freq with this (go figure). Compare:
776 * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
778 s
->freq
= restrict_sampling_rate(dsp_get_hilo(s
));
779 ldebug ("set freq %d\n", s
->freq
);
783 s
->block_size
= dsp_get_lohi (s
) + 1;
784 ldebug ("set dma block len %d\n", s
->block_size
);
791 /* ADPCM stuff, ignore */
796 int freq
, samples
, bytes
;
799 freq
= s
->freq
> 0 ? s
->freq
: 11025;
800 samples
= dsp_get_lohi (s
) + 1;
801 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
802 ticks
= muldiv64(bytes
, NANOSECONDS_PER_SECOND
, freq
);
803 if (ticks
< NANOSECONDS_PER_SECOND
/ 1024) {
804 qemu_irq_raise (s
->pic
);
810 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) + ticks
814 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
819 d0
= dsp_get_data (s
);
821 ldebug ("E0 data = %#x\n", d0
);
822 dsp_out_data (s
, ~d0
);
827 d0
= dsp_get_data (s
);
828 dolog ("E2 = %#x\n", d0
);
833 s
->test_reg
= dsp_get_data (s
);
837 d0
= dsp_get_data (s
);
838 ldebug ("command 0xf9 with %#x\n", d0
);
841 dsp_out_data (s
, 0xff);
845 dsp_out_data (s
, 0x07);
849 dsp_out_data (s
, 0x38);
853 dsp_out_data (s
, 0x00);
859 qemu_log_mask(LOG_UNIMP
, "complete: unrecognized command %#x\n",
869 static void legacy_reset (SB16State
*s
)
871 struct audsettings as
;
880 as
.fmt
= AUDIO_FORMAT_U8
;
883 s
->voice
= AUD_open_out (
892 /* Not sure about that... */
893 /* AUD_set_active_out (s->voice, 1); */
896 static void reset (SB16State
*s
)
898 qemu_irq_lower (s
->pic
);
900 qemu_irq_raise (s
->pic
);
901 qemu_irq_lower (s
->pic
);
904 s
->mixer_regs
[0x82] = 0;
908 s
->left_till_irq
= 0;
916 dsp_out_data (s
, 0xaa);
922 static void dsp_write(void *opaque
, uint32_t nport
, uint32_t val
)
924 SB16State
*s
= opaque
;
927 iport
= nport
- s
->port
;
929 ldebug ("write %#x <- %#x\n", nport
, val
);
941 case 0x03: /* FreeBSD kludge */
946 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
949 case 0xb8: /* Panic */
954 dsp_out_data (s
, 0x38);
965 case 0x0c: /* write data or command | write status */
966 /* if (s->highspeed) */
969 if (s
->needed_bytes
== 0) {
972 if (0 == s
->needed_bytes
) {
978 if (s
->in_index
== sizeof (s
->in2_data
)) {
979 dolog ("in data overrun\n");
982 s
->in2_data
[s
->in_index
++] = val
;
983 if (s
->in_index
== s
->needed_bytes
) {
995 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
1000 static uint32_t dsp_read(void *opaque
, uint32_t nport
)
1002 SB16State
*s
= opaque
;
1003 int iport
, retval
, ack
= 0;
1005 iport
= nport
- s
->port
;
1008 case 0x06: /* reset */
1012 case 0x0a: /* read data */
1013 if (s
->out_data_len
) {
1014 retval
= s
->out_data
[--s
->out_data_len
];
1015 s
->last_read_byte
= retval
;
1019 dolog ("empty output buffer for command %#x\n",
1022 retval
= s
->last_read_byte
;
1027 case 0x0c: /* 0 can write */
1028 retval
= s
->can_write
? 0 : 0x80;
1031 case 0x0d: /* timer interrupt clear */
1032 /* dolog ("timer interrupt clear\n"); */
1036 case 0x0e: /* data available status | irq 8 ack */
1037 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1038 if (s
->mixer_regs
[0x82] & 1) {
1040 s
->mixer_regs
[0x82] &= ~1;
1041 qemu_irq_lower (s
->pic
);
1045 case 0x0f: /* irq 16 ack */
1047 if (s
->mixer_regs
[0x82] & 2) {
1049 s
->mixer_regs
[0x82] &= ~2;
1050 qemu_irq_lower (s
->pic
);
1059 ldebug ("read %#x -> %#x\n", nport
, retval
);
1065 dolog ("warning: dsp_read %#x error\n", nport
);
1069 static void reset_mixer (SB16State
*s
)
1073 memset (s
->mixer_regs
, 0xff, 0x7f);
1074 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1076 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1077 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1078 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1079 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1081 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1082 s
->mixer_regs
[0x0c] = 0;
1084 /* d5=output filt, d1=stereo switch */
1085 s
->mixer_regs
[0x0e] = 0;
1087 /* voice volume L d5,d7, R d1,d3 */
1088 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1090 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1092 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1094 for (i
= 0x30; i
< 0x48; i
++) {
1095 s
->mixer_regs
[i
] = 0x20;
1099 static void mixer_write_indexb(void *opaque
, uint32_t nport
, uint32_t val
)
1101 SB16State
*s
= opaque
;
1103 s
->mixer_nreg
= val
;
1106 static void mixer_write_datab(void *opaque
, uint32_t nport
, uint32_t val
)
1108 SB16State
*s
= opaque
;
1111 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1113 switch (s
->mixer_nreg
) {
1120 int irq
= irq_of_magic (val
);
1121 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1132 dma
= ctz32 (val
& 0xf);
1133 hdma
= ctz32 (val
& 0xf0);
1134 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1135 qemu_log_mask(LOG_GUEST_ERROR
, "attempt to change DMA 8bit"
1136 " %d(%d), 16bit %d(%d) (val=%#x)\n", dma
, s
->dma
,
1137 hdma
, s
->hdma
, val
);
1147 qemu_log_mask(LOG_GUEST_ERROR
, "attempt to write into IRQ status"
1148 " register (val=%#x)\n", val
);
1152 if (s
->mixer_nreg
>= 0x80) {
1153 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1158 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1161 static uint32_t mixer_read(void *opaque
, uint32_t nport
)
1163 SB16State
*s
= opaque
;
1166 #ifndef DEBUG_SB16_MOST
1167 if (s
->mixer_nreg
!= 0x82) {
1168 ldebug ("mixer_read[%#x] -> %#x\n",
1169 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1172 ldebug ("mixer_read[%#x] -> %#x\n",
1173 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1175 return s
->mixer_regs
[s
->mixer_nreg
];
1178 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1179 int dma_len
, int len
)
1181 IsaDma
*isa_dma
= nchan
== s
->dma
? s
->isa_dma
: s
->isa_hdma
;
1182 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
1184 uint8_t tmpbuf
[4096];
1190 int left
= dma_len
- dma_pos
;
1194 to_copy
= MIN (temp
, left
);
1195 if (to_copy
> sizeof (tmpbuf
)) {
1196 to_copy
= sizeof (tmpbuf
);
1199 copied
= k
->read_memory(isa_dma
, nchan
, tmpbuf
, dma_pos
, to_copy
);
1200 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1203 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1214 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1216 SB16State
*s
= opaque
;
1217 int till
, copy
, written
, free
;
1219 if (s
->block_size
<= 0) {
1220 qemu_log_mask(LOG_GUEST_ERROR
, "invalid block size=%d nchan=%d"
1221 " dma_pos=%d dma_len=%d\n", s
->block_size
, nchan
,
1226 if (s
->left_till_irq
< 0) {
1227 s
->left_till_irq
= s
->block_size
;
1231 free
= s
->audio_free
& ~s
->align
;
1232 if ((free
<= 0) || !dma_len
) {
1241 till
= s
->left_till_irq
;
1243 #ifdef DEBUG_SB16_MOST
1244 dolog ("pos:%06d %d till:%d len:%d\n",
1245 dma_pos
, free
, till
, dma_len
);
1249 if (s
->dma_auto
== 0) {
1254 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1255 dma_pos
= (dma_pos
+ written
) % dma_len
;
1256 s
->left_till_irq
-= written
;
1258 if (s
->left_till_irq
<= 0) {
1259 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1260 qemu_irq_raise (s
->pic
);
1261 if (s
->dma_auto
== 0) {
1267 #ifdef DEBUG_SB16_MOST
1268 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1269 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1273 while (s
->left_till_irq
<= 0) {
1274 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1280 static void SB_audio_callback (void *opaque
, int free
)
1282 SB16State
*s
= opaque
;
1283 s
->audio_free
= free
;
1286 static int sb16_post_load (void *opaque
, int version_id
)
1288 SB16State
*s
= opaque
;
1291 AUD_close_out (&s
->card
, s
->voice
);
1295 if (s
->dma_running
) {
1297 struct audsettings as
;
1302 as
.nchannels
= 1 << s
->fmt_stereo
;
1306 s
->voice
= AUD_open_out (
1317 speaker (s
, s
->speaker
);
1322 static const VMStateDescription vmstate_sb16
= {
1325 .minimum_version_id
= 1,
1326 .post_load
= sb16_post_load
,
1327 .fields
= (VMStateField
[]) {
1328 VMSTATE_UINT32 (irq
, SB16State
),
1329 VMSTATE_UINT32 (dma
, SB16State
),
1330 VMSTATE_UINT32 (hdma
, SB16State
),
1331 VMSTATE_UINT32 (port
, SB16State
),
1332 VMSTATE_UINT32 (ver
, SB16State
),
1333 VMSTATE_INT32 (in_index
, SB16State
),
1334 VMSTATE_INT32 (out_data_len
, SB16State
),
1335 VMSTATE_INT32 (fmt_stereo
, SB16State
),
1336 VMSTATE_INT32 (fmt_signed
, SB16State
),
1337 VMSTATE_INT32 (fmt_bits
, SB16State
),
1338 VMSTATE_UINT32 (fmt
, SB16State
),
1339 VMSTATE_INT32 (dma_auto
, SB16State
),
1340 VMSTATE_INT32 (block_size
, SB16State
),
1341 VMSTATE_INT32 (fifo
, SB16State
),
1342 VMSTATE_INT32 (freq
, SB16State
),
1343 VMSTATE_INT32 (time_const
, SB16State
),
1344 VMSTATE_INT32 (speaker
, SB16State
),
1345 VMSTATE_INT32 (needed_bytes
, SB16State
),
1346 VMSTATE_INT32 (cmd
, SB16State
),
1347 VMSTATE_INT32 (use_hdma
, SB16State
),
1348 VMSTATE_INT32 (highspeed
, SB16State
),
1349 VMSTATE_INT32 (can_write
, SB16State
),
1350 VMSTATE_INT32 (v2x6
, SB16State
),
1352 VMSTATE_UINT8 (csp_param
, SB16State
),
1353 VMSTATE_UINT8 (csp_value
, SB16State
),
1354 VMSTATE_UINT8 (csp_mode
, SB16State
),
1355 VMSTATE_UINT8 (csp_param
, SB16State
),
1356 VMSTATE_BUFFER (csp_regs
, SB16State
),
1357 VMSTATE_UINT8 (csp_index
, SB16State
),
1358 VMSTATE_BUFFER (csp_reg83
, SB16State
),
1359 VMSTATE_INT32 (csp_reg83r
, SB16State
),
1360 VMSTATE_INT32 (csp_reg83w
, SB16State
),
1362 VMSTATE_BUFFER (in2_data
, SB16State
),
1363 VMSTATE_BUFFER (out_data
, SB16State
),
1364 VMSTATE_UINT8 (test_reg
, SB16State
),
1365 VMSTATE_UINT8 (last_read_byte
, SB16State
),
1367 VMSTATE_INT32 (nzero
, SB16State
),
1368 VMSTATE_INT32 (left_till_irq
, SB16State
),
1369 VMSTATE_INT32 (dma_running
, SB16State
),
1370 VMSTATE_INT32 (bytes_per_second
, SB16State
),
1371 VMSTATE_INT32 (align
, SB16State
),
1373 VMSTATE_INT32 (mixer_nreg
, SB16State
),
1374 VMSTATE_BUFFER (mixer_regs
, SB16State
),
1376 VMSTATE_END_OF_LIST ()
1380 static const MemoryRegionPortio sb16_ioport_list
[] = {
1381 { 4, 1, 1, .write
= mixer_write_indexb
},
1382 { 5, 1, 1, .read
= mixer_read
, .write
= mixer_write_datab
},
1383 { 6, 1, 1, .read
= dsp_read
, .write
= dsp_write
},
1384 { 10, 1, 1, .read
= dsp_read
},
1385 { 12, 1, 1, .write
= dsp_write
},
1386 { 12, 4, 1, .read
= dsp_read
},
1387 PORTIO_END_OF_LIST (),
1391 static void sb16_initfn (Object
*obj
)
1393 SB16State
*s
= SB16 (obj
);
1398 static void sb16_realizefn (DeviceState
*dev
, Error
**errp
)
1400 ISADevice
*isadev
= ISA_DEVICE (dev
);
1401 SB16State
*s
= SB16 (dev
);
1404 s
->isa_hdma
= isa_get_dma(isa_bus_from_device(isadev
), s
->hdma
);
1405 s
->isa_dma
= isa_get_dma(isa_bus_from_device(isadev
), s
->dma
);
1406 if (!s
->isa_dma
|| !s
->isa_hdma
) {
1407 error_setg(errp
, "ISA controller does not support DMA");
1411 isa_init_irq (isadev
, &s
->pic
, s
->irq
);
1413 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1414 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1415 s
->mixer_regs
[0x82] = 2 << 5;
1418 s
->csp_regs
[9] = 0xf8;
1421 s
->aux_ts
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, aux_timer
, s
);
1423 error_setg(errp
, "warning: Could not create auxiliary timer");
1426 isa_register_portio_list(isadev
, &s
->portio_list
, s
->port
,
1427 sb16_ioport_list
, s
, "sb16");
1429 k
= ISADMA_GET_CLASS(s
->isa_hdma
);
1430 k
->register_channel(s
->isa_hdma
, s
->hdma
, SB_read_DMA
, s
);
1432 k
= ISADMA_GET_CLASS(s
->isa_dma
);
1433 k
->register_channel(s
->isa_dma
, s
->dma
, SB_read_DMA
, s
);
1437 AUD_register_card ("sb16", &s
->card
);
1440 static Property sb16_properties
[] = {
1441 DEFINE_AUDIO_PROPERTIES(SB16State
, card
),
1442 DEFINE_PROP_UINT32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1443 DEFINE_PROP_UINT32 ("iobase", SB16State
, port
, 0x220),
1444 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1445 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1446 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1447 DEFINE_PROP_END_OF_LIST (),
1450 static void sb16_class_initfn (ObjectClass
*klass
, void *data
)
1452 DeviceClass
*dc
= DEVICE_CLASS (klass
);
1454 dc
->realize
= sb16_realizefn
;
1455 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1456 dc
->desc
= "Creative Sound Blaster 16";
1457 dc
->vmsd
= &vmstate_sb16
;
1458 device_class_set_props(dc
, sb16_properties
);
1461 static const TypeInfo sb16_info
= {
1463 .parent
= TYPE_ISA_DEVICE
,
1464 .instance_size
= sizeof (SB16State
),
1465 .instance_init
= sb16_initfn
,
1466 .class_init
= sb16_class_initfn
,
1469 static void sb16_register_types (void)
1471 type_register_static (&sb16_info
);
1472 deprecated_register_soundhw("sb16", "Creative Sound Blaster 16",
1476 type_init (sb16_register_types
)