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 typedef struct SB16State SB16State
;
54 DECLARE_INSTANCE_CHECKER(SB16State
, SB16
,
93 uint8_t csp_regs
[256];
100 uint8_t out_data
[50];
102 uint8_t last_read_byte
;
108 int bytes_per_second
;
116 uint8_t mixer_regs
[256];
117 PortioList portio_list
;
120 static void SB_audio_callback (void *opaque
, int free
);
122 static int magic_of_irq (int irq
)
134 qemu_log_mask(LOG_GUEST_ERROR
, "bad irq %d\n", irq
);
139 static int irq_of_magic (int magic
)
151 qemu_log_mask(LOG_GUEST_ERROR
, "bad irq magic %d\n", magic
);
157 static void log_dsp (SB16State
*dsp
)
159 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
160 dsp
->fmt_stereo
? "Stereo" : "Mono",
161 dsp
->fmt_signed
? "Signed" : "Unsigned",
163 dsp
->dma_auto
? "Auto" : "Single",
171 static void speaker (SB16State
*s
, int on
)
174 /* AUD_enable (s->voice, on); */
177 static void control (SB16State
*s
, int hold
)
179 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
180 IsaDma
*isa_dma
= s
->use_hdma
? s
->isa_hdma
: s
->isa_dma
;
181 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
182 s
->dma_running
= hold
;
184 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
187 k
->hold_DREQ(isa_dma
, dma
);
188 AUD_set_active_out (s
->voice
, 1);
191 k
->release_DREQ(isa_dma
, dma
);
192 AUD_set_active_out (s
->voice
, 0);
196 static void aux_timer (void *opaque
)
198 SB16State
*s
= opaque
;
200 qemu_irq_raise (s
->pic
);
206 static void continue_dma8 (SB16State
*s
)
209 struct audsettings as
;
214 as
.nchannels
= 1 << s
->fmt_stereo
;
218 s
->voice
= AUD_open_out (
231 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
233 s
->fmt
= AUDIO_FORMAT_U8
;
237 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
238 if (-1 == s
->time_const
) {
243 int tmp
= (256 - s
->time_const
);
244 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
248 s
->block_size
= dma_len
<< s
->fmt_stereo
;
251 /* This is apparently the only way to make both Act1/PL
252 and SecondReality/FC work
254 Act1 sets block size via command 0x48 and it's an odd number
255 SR does the same with even number
256 Both use stereo, and Creatives own documentation states that
257 0x48 sets block size in bytes less one.. go figure */
258 s
->block_size
&= ~s
->fmt_stereo
;
261 s
->freq
>>= s
->fmt_stereo
;
262 s
->left_till_irq
= s
->block_size
;
263 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
264 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
265 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
266 s
->align
= (1 << s
->fmt_stereo
) - 1;
268 if (s
->block_size
& s
->align
) {
269 qemu_log_mask(LOG_GUEST_ERROR
, "warning: misaligned block size %d,"
270 " alignment %d\n", s
->block_size
, s
->align
+ 1);
273 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
274 "dma %d, auto %d, fifo %d, high %d\n",
275 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
276 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
282 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
284 s
->use_hdma
= cmd
< 0xc0;
285 s
->fifo
= (cmd
>> 1) & 1;
286 s
->dma_auto
= (cmd
>> 2) & 1;
287 s
->fmt_signed
= (d0
>> 4) & 1;
288 s
->fmt_stereo
= (d0
>> 5) & 1;
300 if (-1 != s
->time_const
) {
302 int tmp
= 256 - s
->time_const
;
303 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
305 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
306 s
->freq
= 1000000 / ((255 - s
->time_const
));
311 s
->block_size
= dma_len
+ 1;
312 s
->block_size
<<= (s
->fmt_bits
== 16);
314 /* It is clear that for DOOM and auto-init this value
315 shouldn't take stereo into account, while Miles Sound Systems
316 setsound.exe with single transfer mode wouldn't work without it
317 wonders of SB16 yet again */
318 s
->block_size
<<= s
->fmt_stereo
;
321 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
322 "dma %d, auto %d, fifo %d, high %d\n",
323 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
324 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
326 if (16 == s
->fmt_bits
) {
328 s
->fmt
= AUDIO_FORMAT_S16
;
331 s
->fmt
= AUDIO_FORMAT_U16
;
336 s
->fmt
= AUDIO_FORMAT_S8
;
339 s
->fmt
= AUDIO_FORMAT_U8
;
343 s
->left_till_irq
= s
->block_size
;
345 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
347 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
348 if (s
->block_size
& s
->align
) {
349 qemu_log_mask(LOG_GUEST_ERROR
, "warning: misaligned block size %d,"
350 " alignment %d\n", s
->block_size
, s
->align
+ 1);
354 struct audsettings as
;
359 as
.nchannels
= 1 << s
->fmt_stereo
;
363 s
->voice
= AUD_open_out (
377 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
379 ldebug ("outdata %#x\n", val
);
380 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
381 s
->out_data
[s
->out_data_len
++] = val
;
385 static inline uint8_t dsp_get_data (SB16State
*s
)
388 return s
->in2_data
[--s
->in_index
];
391 dolog ("buffer underflow\n");
396 static void command (SB16State
*s
, uint8_t cmd
)
398 ldebug ("command %#x\n", cmd
);
400 if (cmd
> 0xaf && cmd
< 0xd0) {
402 qemu_log_mask(LOG_UNIMP
, "ADC not yet supported (command %#x)\n",
411 qemu_log_mask(LOG_GUEST_ERROR
, "%#x wrong bits\n", cmd
);
420 dsp_out_data (s
, 0x10); /* s->csp_param); */
432 /* __asm__ ("int3"); */
440 dsp_out_data (s
, 0xf8);
456 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
457 dma_cmd8 (s
, DMA8_AUTO
, -1);
460 case 0x20: /* Direct ADC, Juice/PL */
461 dsp_out_data (s
, 0xff);
465 qemu_log_mask(LOG_UNIMP
, "0x35 - MIDI command not implemented\n");
487 dsp_out_data (s
, 0xaa);
490 case 0x47: /* Continue Auto-Initialize DMA 16bit */
498 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
499 qemu_log_mask(LOG_UNIMP
, "0x75 - DMA DAC, 4-bit ADPCM not"
503 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
505 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 4-bit ADPCM Reference not"
509 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
511 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 2.6-bit ADPCM not"
515 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
517 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 2.6-bit ADPCM Reference"
518 " not implemented\n");
522 qemu_log_mask(LOG_UNIMP
, "0x7d - Autio-Initialize DMA DAC, 4-bit"
523 " ADPCM Reference\n");
524 qemu_log_mask(LOG_UNIMP
, "not implemented\n");
528 qemu_log_mask(LOG_UNIMP
, "0x7d - Autio-Initialize DMA DAC, 2.6-bit"
529 " ADPCM Reference\n");
530 qemu_log_mask(LOG_UNIMP
, "not implemented\n");
539 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
542 case 0xd0: /* halt DMA operation. 8bit */
546 case 0xd1: /* speaker on */
550 case 0xd3: /* speaker off */
554 case 0xd4: /* continue DMA operation. 8bit */
555 /* KQ6 (or maybe Sierras audblst.drv in general) resets
556 the frequency between halt/continue */
560 case 0xd5: /* halt DMA operation. 16bit */
564 case 0xd6: /* continue DMA operation. 16bit */
568 case 0xd9: /* exit auto-init DMA after this block. 16bit */
572 case 0xda: /* exit auto-init DMA after this block. 8bit */
576 case 0xe0: /* DSP identification */
581 dsp_out_data (s
, s
->ver
& 0xff);
582 dsp_out_data (s
, s
->ver
>> 8);
592 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
593 dsp_out_data (s
, e3
[i
]);
597 case 0xe4: /* write test reg */
602 qemu_log_mask(LOG_UNIMP
, "Attempt to probe for ESS (0xe7)?\n");
605 case 0xe8: /* read test reg */
606 dsp_out_data (s
, s
->test_reg
);
611 dsp_out_data (s
, 0xaa);
612 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
613 qemu_irq_raise (s
->pic
);
624 case 0xfc: /* FIXME */
629 qemu_log_mask(LOG_UNIMP
, "Unrecognized command %#x\n", cmd
);
634 if (!s
->needed_bytes
) {
639 if (!s
->needed_bytes
) {
648 qemu_log_mask(LOG_UNIMP
, "warning: command %#x,%d is not truly understood"
649 " yet\n", cmd
, s
->needed_bytes
);
654 static uint16_t dsp_get_lohi (SB16State
*s
)
656 uint8_t hi
= dsp_get_data (s
);
657 uint8_t lo
= dsp_get_data (s
);
658 return (hi
<< 8) | lo
;
661 static uint16_t dsp_get_hilo (SB16State
*s
)
663 uint8_t lo
= dsp_get_data (s
);
664 uint8_t hi
= dsp_get_data (s
);
665 return (hi
<< 8) | lo
;
668 static void complete (SB16State
*s
)
671 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
672 s
->cmd
, s
->in_index
, s
->needed_bytes
);
674 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
675 d2
= dsp_get_data (s
);
676 d1
= dsp_get_data (s
);
677 d0
= dsp_get_data (s
);
680 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
684 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
686 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
692 s
->csp_mode
= dsp_get_data (s
);
695 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
699 s
->csp_param
= dsp_get_data (s
);
700 s
->csp_value
= dsp_get_data (s
);
701 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
707 d0
= dsp_get_data (s
);
708 d1
= dsp_get_data (s
);
709 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
711 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
712 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
716 s
->csp_regs
[d1
] = d0
;
721 d0
= dsp_get_data (s
);
722 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
723 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
725 ldebug ("0x83[%d] -> %#x\n",
727 s
->csp_reg83
[s
->csp_reg83w
% 4]);
728 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
732 dsp_out_data (s
, s
->csp_regs
[d0
]);
737 d0
= dsp_get_data (s
);
738 dolog ("cmd 0x10 d0=%#x\n", d0
);
742 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
746 s
->time_const
= dsp_get_data (s
);
747 ldebug ("set time const %d\n", s
->time_const
);
753 * 0x41 is documented as setting the output sample rate,
754 * and 0x42 the input sample rate, but in fact SB16 hardware
755 * seems to have only a single sample rate under the hood,
756 * and FT2 sets output freq with this (go figure). Compare:
757 * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
759 s
->freq
= dsp_get_hilo (s
);
760 ldebug ("set freq %d\n", s
->freq
);
764 s
->block_size
= dsp_get_lohi (s
) + 1;
765 ldebug ("set dma block len %d\n", s
->block_size
);
772 /* ADPCM stuff, ignore */
777 int freq
, samples
, bytes
;
780 freq
= s
->freq
> 0 ? s
->freq
: 11025;
781 samples
= dsp_get_lohi (s
) + 1;
782 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
783 ticks
= muldiv64(bytes
, NANOSECONDS_PER_SECOND
, freq
);
784 if (ticks
< NANOSECONDS_PER_SECOND
/ 1024) {
785 qemu_irq_raise (s
->pic
);
791 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) + ticks
795 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
800 d0
= dsp_get_data (s
);
802 ldebug ("E0 data = %#x\n", d0
);
803 dsp_out_data (s
, ~d0
);
808 d0
= dsp_get_data (s
);
809 dolog ("E2 = %#x\n", d0
);
814 s
->test_reg
= dsp_get_data (s
);
818 d0
= dsp_get_data (s
);
819 ldebug ("command 0xf9 with %#x\n", d0
);
822 dsp_out_data (s
, 0xff);
826 dsp_out_data (s
, 0x07);
830 dsp_out_data (s
, 0x38);
834 dsp_out_data (s
, 0x00);
840 qemu_log_mask(LOG_UNIMP
, "complete: unrecognized command %#x\n",
850 static void legacy_reset (SB16State
*s
)
852 struct audsettings as
;
861 as
.fmt
= AUDIO_FORMAT_U8
;
864 s
->voice
= AUD_open_out (
873 /* Not sure about that... */
874 /* AUD_set_active_out (s->voice, 1); */
877 static void reset (SB16State
*s
)
879 qemu_irq_lower (s
->pic
);
881 qemu_irq_raise (s
->pic
);
882 qemu_irq_lower (s
->pic
);
885 s
->mixer_regs
[0x82] = 0;
889 s
->left_till_irq
= 0;
897 dsp_out_data (s
, 0xaa);
903 static void dsp_write(void *opaque
, uint32_t nport
, uint32_t val
)
905 SB16State
*s
= opaque
;
908 iport
= nport
- s
->port
;
910 ldebug ("write %#x <- %#x\n", nport
, val
);
922 case 0x03: /* FreeBSD kludge */
927 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
930 case 0xb8: /* Panic */
935 dsp_out_data (s
, 0x38);
946 case 0x0c: /* write data or command | write status */
947 /* if (s->highspeed) */
950 if (s
->needed_bytes
== 0) {
953 if (0 == s
->needed_bytes
) {
959 if (s
->in_index
== sizeof (s
->in2_data
)) {
960 dolog ("in data overrun\n");
963 s
->in2_data
[s
->in_index
++] = val
;
964 if (s
->in_index
== s
->needed_bytes
) {
976 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
981 static uint32_t dsp_read(void *opaque
, uint32_t nport
)
983 SB16State
*s
= opaque
;
984 int iport
, retval
, ack
= 0;
986 iport
= nport
- s
->port
;
989 case 0x06: /* reset */
993 case 0x0a: /* read data */
994 if (s
->out_data_len
) {
995 retval
= s
->out_data
[--s
->out_data_len
];
996 s
->last_read_byte
= retval
;
1000 dolog ("empty output buffer for command %#x\n",
1003 retval
= s
->last_read_byte
;
1008 case 0x0c: /* 0 can write */
1009 retval
= s
->can_write
? 0 : 0x80;
1012 case 0x0d: /* timer interrupt clear */
1013 /* dolog ("timer interrupt clear\n"); */
1017 case 0x0e: /* data available status | irq 8 ack */
1018 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1019 if (s
->mixer_regs
[0x82] & 1) {
1021 s
->mixer_regs
[0x82] &= ~1;
1022 qemu_irq_lower (s
->pic
);
1026 case 0x0f: /* irq 16 ack */
1028 if (s
->mixer_regs
[0x82] & 2) {
1030 s
->mixer_regs
[0x82] &= ~2;
1031 qemu_irq_lower (s
->pic
);
1040 ldebug ("read %#x -> %#x\n", nport
, retval
);
1046 dolog ("warning: dsp_read %#x error\n", nport
);
1050 static void reset_mixer (SB16State
*s
)
1054 memset (s
->mixer_regs
, 0xff, 0x7f);
1055 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1057 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1058 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1059 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1060 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1062 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1063 s
->mixer_regs
[0x0c] = 0;
1065 /* d5=output filt, d1=stereo switch */
1066 s
->mixer_regs
[0x0e] = 0;
1068 /* voice volume L d5,d7, R d1,d3 */
1069 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1071 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1073 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1075 for (i
= 0x30; i
< 0x48; i
++) {
1076 s
->mixer_regs
[i
] = 0x20;
1080 static void mixer_write_indexb(void *opaque
, uint32_t nport
, uint32_t val
)
1082 SB16State
*s
= opaque
;
1084 s
->mixer_nreg
= val
;
1087 static void mixer_write_datab(void *opaque
, uint32_t nport
, uint32_t val
)
1089 SB16State
*s
= opaque
;
1092 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1094 switch (s
->mixer_nreg
) {
1101 int irq
= irq_of_magic (val
);
1102 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1113 dma
= ctz32 (val
& 0xf);
1114 hdma
= ctz32 (val
& 0xf0);
1115 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1116 qemu_log_mask(LOG_GUEST_ERROR
, "attempt to change DMA 8bit"
1117 " %d(%d), 16bit %d(%d) (val=%#x)\n", dma
, s
->dma
,
1118 hdma
, s
->hdma
, val
);
1128 qemu_log_mask(LOG_GUEST_ERROR
, "attempt to write into IRQ status"
1129 " register (val=%#x)\n", val
);
1133 if (s
->mixer_nreg
>= 0x80) {
1134 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1139 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1142 static uint32_t mixer_read(void *opaque
, uint32_t nport
)
1144 SB16State
*s
= opaque
;
1147 #ifndef DEBUG_SB16_MOST
1148 if (s
->mixer_nreg
!= 0x82) {
1149 ldebug ("mixer_read[%#x] -> %#x\n",
1150 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1153 ldebug ("mixer_read[%#x] -> %#x\n",
1154 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1156 return s
->mixer_regs
[s
->mixer_nreg
];
1159 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1160 int dma_len
, int len
)
1162 IsaDma
*isa_dma
= nchan
== s
->dma
? s
->isa_dma
: s
->isa_hdma
;
1163 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
1165 uint8_t tmpbuf
[4096];
1171 int left
= dma_len
- dma_pos
;
1175 to_copy
= MIN (temp
, left
);
1176 if (to_copy
> sizeof (tmpbuf
)) {
1177 to_copy
= sizeof (tmpbuf
);
1180 copied
= k
->read_memory(isa_dma
, nchan
, tmpbuf
, dma_pos
, to_copy
);
1181 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1184 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1195 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1197 SB16State
*s
= opaque
;
1198 int till
, copy
, written
, free
;
1200 if (s
->block_size
<= 0) {
1201 qemu_log_mask(LOG_GUEST_ERROR
, "invalid block size=%d nchan=%d"
1202 " dma_pos=%d dma_len=%d\n", s
->block_size
, nchan
,
1207 if (s
->left_till_irq
< 0) {
1208 s
->left_till_irq
= s
->block_size
;
1212 free
= s
->audio_free
& ~s
->align
;
1213 if ((free
<= 0) || !dma_len
) {
1222 till
= s
->left_till_irq
;
1224 #ifdef DEBUG_SB16_MOST
1225 dolog ("pos:%06d %d till:%d len:%d\n",
1226 dma_pos
, free
, till
, dma_len
);
1230 if (s
->dma_auto
== 0) {
1235 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1236 dma_pos
= (dma_pos
+ written
) % dma_len
;
1237 s
->left_till_irq
-= written
;
1239 if (s
->left_till_irq
<= 0) {
1240 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1241 qemu_irq_raise (s
->pic
);
1242 if (s
->dma_auto
== 0) {
1248 #ifdef DEBUG_SB16_MOST
1249 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1250 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1254 while (s
->left_till_irq
<= 0) {
1255 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1261 static void SB_audio_callback (void *opaque
, int free
)
1263 SB16State
*s
= opaque
;
1264 s
->audio_free
= free
;
1267 static int sb16_post_load (void *opaque
, int version_id
)
1269 SB16State
*s
= opaque
;
1272 AUD_close_out (&s
->card
, s
->voice
);
1276 if (s
->dma_running
) {
1278 struct audsettings as
;
1283 as
.nchannels
= 1 << s
->fmt_stereo
;
1287 s
->voice
= AUD_open_out (
1298 speaker (s
, s
->speaker
);
1303 static const VMStateDescription vmstate_sb16
= {
1306 .minimum_version_id
= 1,
1307 .post_load
= sb16_post_load
,
1308 .fields
= (VMStateField
[]) {
1309 VMSTATE_UINT32 (irq
, SB16State
),
1310 VMSTATE_UINT32 (dma
, SB16State
),
1311 VMSTATE_UINT32 (hdma
, SB16State
),
1312 VMSTATE_UINT32 (port
, SB16State
),
1313 VMSTATE_UINT32 (ver
, SB16State
),
1314 VMSTATE_INT32 (in_index
, SB16State
),
1315 VMSTATE_INT32 (out_data_len
, SB16State
),
1316 VMSTATE_INT32 (fmt_stereo
, SB16State
),
1317 VMSTATE_INT32 (fmt_signed
, SB16State
),
1318 VMSTATE_INT32 (fmt_bits
, SB16State
),
1319 VMSTATE_UINT32 (fmt
, SB16State
),
1320 VMSTATE_INT32 (dma_auto
, SB16State
),
1321 VMSTATE_INT32 (block_size
, SB16State
),
1322 VMSTATE_INT32 (fifo
, SB16State
),
1323 VMSTATE_INT32 (freq
, SB16State
),
1324 VMSTATE_INT32 (time_const
, SB16State
),
1325 VMSTATE_INT32 (speaker
, SB16State
),
1326 VMSTATE_INT32 (needed_bytes
, SB16State
),
1327 VMSTATE_INT32 (cmd
, SB16State
),
1328 VMSTATE_INT32 (use_hdma
, SB16State
),
1329 VMSTATE_INT32 (highspeed
, SB16State
),
1330 VMSTATE_INT32 (can_write
, SB16State
),
1331 VMSTATE_INT32 (v2x6
, SB16State
),
1333 VMSTATE_UINT8 (csp_param
, SB16State
),
1334 VMSTATE_UINT8 (csp_value
, SB16State
),
1335 VMSTATE_UINT8 (csp_mode
, SB16State
),
1336 VMSTATE_UINT8 (csp_param
, SB16State
),
1337 VMSTATE_BUFFER (csp_regs
, SB16State
),
1338 VMSTATE_UINT8 (csp_index
, SB16State
),
1339 VMSTATE_BUFFER (csp_reg83
, SB16State
),
1340 VMSTATE_INT32 (csp_reg83r
, SB16State
),
1341 VMSTATE_INT32 (csp_reg83w
, SB16State
),
1343 VMSTATE_BUFFER (in2_data
, SB16State
),
1344 VMSTATE_BUFFER (out_data
, SB16State
),
1345 VMSTATE_UINT8 (test_reg
, SB16State
),
1346 VMSTATE_UINT8 (last_read_byte
, SB16State
),
1348 VMSTATE_INT32 (nzero
, SB16State
),
1349 VMSTATE_INT32 (left_till_irq
, SB16State
),
1350 VMSTATE_INT32 (dma_running
, SB16State
),
1351 VMSTATE_INT32 (bytes_per_second
, SB16State
),
1352 VMSTATE_INT32 (align
, SB16State
),
1354 VMSTATE_INT32 (mixer_nreg
, SB16State
),
1355 VMSTATE_BUFFER (mixer_regs
, SB16State
),
1357 VMSTATE_END_OF_LIST ()
1361 static const MemoryRegionPortio sb16_ioport_list
[] = {
1362 { 4, 1, 1, .write
= mixer_write_indexb
},
1363 { 5, 1, 1, .read
= mixer_read
, .write
= mixer_write_datab
},
1364 { 6, 1, 1, .read
= dsp_read
, .write
= dsp_write
},
1365 { 10, 1, 1, .read
= dsp_read
},
1366 { 12, 1, 1, .write
= dsp_write
},
1367 { 12, 4, 1, .read
= dsp_read
},
1368 PORTIO_END_OF_LIST (),
1372 static void sb16_initfn (Object
*obj
)
1374 SB16State
*s
= SB16 (obj
);
1379 static void sb16_realizefn (DeviceState
*dev
, Error
**errp
)
1381 ISADevice
*isadev
= ISA_DEVICE (dev
);
1382 SB16State
*s
= SB16 (dev
);
1385 s
->isa_hdma
= isa_get_dma(isa_bus_from_device(isadev
), s
->hdma
);
1386 s
->isa_dma
= isa_get_dma(isa_bus_from_device(isadev
), s
->dma
);
1387 if (!s
->isa_dma
|| !s
->isa_hdma
) {
1388 error_setg(errp
, "ISA controller does not support DMA");
1392 isa_init_irq (isadev
, &s
->pic
, s
->irq
);
1394 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1395 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1396 s
->mixer_regs
[0x82] = 2 << 5;
1399 s
->csp_regs
[9] = 0xf8;
1402 s
->aux_ts
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, aux_timer
, s
);
1404 error_setg(errp
, "warning: Could not create auxiliary timer");
1407 isa_register_portio_list(isadev
, &s
->portio_list
, s
->port
,
1408 sb16_ioport_list
, s
, "sb16");
1410 k
= ISADMA_GET_CLASS(s
->isa_hdma
);
1411 k
->register_channel(s
->isa_hdma
, s
->hdma
, SB_read_DMA
, s
);
1413 k
= ISADMA_GET_CLASS(s
->isa_dma
);
1414 k
->register_channel(s
->isa_dma
, s
->dma
, SB_read_DMA
, s
);
1418 AUD_register_card ("sb16", &s
->card
);
1421 static Property sb16_properties
[] = {
1422 DEFINE_AUDIO_PROPERTIES(SB16State
, card
),
1423 DEFINE_PROP_UINT32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1424 DEFINE_PROP_UINT32 ("iobase", SB16State
, port
, 0x220),
1425 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1426 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1427 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1428 DEFINE_PROP_END_OF_LIST (),
1431 static void sb16_class_initfn (ObjectClass
*klass
, void *data
)
1433 DeviceClass
*dc
= DEVICE_CLASS (klass
);
1435 dc
->realize
= sb16_realizefn
;
1436 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1437 dc
->desc
= "Creative Sound Blaster 16";
1438 dc
->vmsd
= &vmstate_sb16
;
1439 device_class_set_props(dc
, sb16_properties
);
1442 static const TypeInfo sb16_info
= {
1444 .parent
= TYPE_ISA_DEVICE
,
1445 .instance_size
= sizeof (SB16State
),
1446 .instance_init
= sb16_initfn
,
1447 .class_init
= sb16_class_initfn
,
1450 static void sb16_register_types (void)
1452 type_register_static (&sb16_info
);
1453 deprecated_register_soundhw("sb16", "Creative Sound Blaster 16",
1457 type_init (sb16_register_types
)