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 static void SB_audio_callback (void *opaque
, int free
);
120 static int magic_of_irq (int irq
)
132 qemu_log_mask(LOG_GUEST_ERROR
, "bad irq %d\n", irq
);
137 static int irq_of_magic (int magic
)
149 qemu_log_mask(LOG_GUEST_ERROR
, "bad irq magic %d\n", magic
);
155 static void log_dsp (SB16State
*dsp
)
157 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
158 dsp
->fmt_stereo
? "Stereo" : "Mono",
159 dsp
->fmt_signed
? "Signed" : "Unsigned",
161 dsp
->dma_auto
? "Auto" : "Single",
169 static void speaker (SB16State
*s
, int on
)
172 /* AUD_enable (s->voice, on); */
175 static void control (SB16State
*s
, int hold
)
177 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
178 IsaDma
*isa_dma
= s
->use_hdma
? s
->isa_hdma
: s
->isa_dma
;
179 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
180 s
->dma_running
= hold
;
182 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
185 k
->hold_DREQ(isa_dma
, dma
);
186 AUD_set_active_out (s
->voice
, 1);
189 k
->release_DREQ(isa_dma
, dma
);
190 AUD_set_active_out (s
->voice
, 0);
194 static void aux_timer (void *opaque
)
196 SB16State
*s
= opaque
;
198 qemu_irq_raise (s
->pic
);
204 static void continue_dma8 (SB16State
*s
)
207 struct audsettings as
;
212 as
.nchannels
= 1 << s
->fmt_stereo
;
216 s
->voice
= AUD_open_out (
229 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
231 s
->fmt
= AUDIO_FORMAT_U8
;
235 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
236 if (-1 == s
->time_const
) {
241 int tmp
= (256 - s
->time_const
);
242 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
246 s
->block_size
= dma_len
<< s
->fmt_stereo
;
249 /* This is apparently the only way to make both Act1/PL
250 and SecondReality/FC work
252 Act1 sets block size via command 0x48 and it's an odd number
253 SR does the same with even number
254 Both use stereo, and Creatives own documentation states that
255 0x48 sets block size in bytes less one.. go figure */
256 s
->block_size
&= ~s
->fmt_stereo
;
259 s
->freq
>>= s
->fmt_stereo
;
260 s
->left_till_irq
= s
->block_size
;
261 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
262 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
263 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
264 s
->align
= (1 << s
->fmt_stereo
) - 1;
266 if (s
->block_size
& s
->align
) {
267 qemu_log_mask(LOG_GUEST_ERROR
, "warning: misaligned block size %d,"
268 " alignment %d\n", s
->block_size
, s
->align
+ 1);
271 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
272 "dma %d, auto %d, fifo %d, high %d\n",
273 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
274 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
280 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
282 s
->use_hdma
= cmd
< 0xc0;
283 s
->fifo
= (cmd
>> 1) & 1;
284 s
->dma_auto
= (cmd
>> 2) & 1;
285 s
->fmt_signed
= (d0
>> 4) & 1;
286 s
->fmt_stereo
= (d0
>> 5) & 1;
298 if (-1 != s
->time_const
) {
300 int tmp
= 256 - s
->time_const
;
301 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
303 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
304 s
->freq
= 1000000 / ((255 - s
->time_const
));
309 s
->block_size
= dma_len
+ 1;
310 s
->block_size
<<= (s
->fmt_bits
== 16);
312 /* It is clear that for DOOM and auto-init this value
313 shouldn't take stereo into account, while Miles Sound Systems
314 setsound.exe with single transfer mode wouldn't work without it
315 wonders of SB16 yet again */
316 s
->block_size
<<= s
->fmt_stereo
;
319 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
320 "dma %d, auto %d, fifo %d, high %d\n",
321 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
322 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
324 if (16 == s
->fmt_bits
) {
326 s
->fmt
= AUDIO_FORMAT_S16
;
329 s
->fmt
= AUDIO_FORMAT_U16
;
334 s
->fmt
= AUDIO_FORMAT_S8
;
337 s
->fmt
= AUDIO_FORMAT_U8
;
341 s
->left_till_irq
= s
->block_size
;
343 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
345 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
346 if (s
->block_size
& s
->align
) {
347 qemu_log_mask(LOG_GUEST_ERROR
, "warning: misaligned block size %d,"
348 " alignment %d\n", s
->block_size
, s
->align
+ 1);
352 struct audsettings as
;
357 as
.nchannels
= 1 << s
->fmt_stereo
;
361 s
->voice
= AUD_open_out (
375 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
377 ldebug ("outdata %#x\n", val
);
378 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
379 s
->out_data
[s
->out_data_len
++] = val
;
383 static inline uint8_t dsp_get_data (SB16State
*s
)
386 return s
->in2_data
[--s
->in_index
];
389 dolog ("buffer underflow\n");
394 static void command (SB16State
*s
, uint8_t cmd
)
396 ldebug ("command %#x\n", cmd
);
398 if (cmd
> 0xaf && cmd
< 0xd0) {
400 qemu_log_mask(LOG_UNIMP
, "ADC not yet supported (command %#x)\n",
409 qemu_log_mask(LOG_GUEST_ERROR
, "%#x wrong bits\n", cmd
);
418 dsp_out_data (s
, 0x10); /* s->csp_param); */
430 /* __asm__ ("int3"); */
438 dsp_out_data (s
, 0xf8);
454 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
455 dma_cmd8 (s
, DMA8_AUTO
, -1);
458 case 0x20: /* Direct ADC, Juice/PL */
459 dsp_out_data (s
, 0xff);
463 qemu_log_mask(LOG_UNIMP
, "0x35 - MIDI command not implemented\n");
485 dsp_out_data (s
, 0xaa);
488 case 0x47: /* Continue Auto-Initialize DMA 16bit */
496 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
497 qemu_log_mask(LOG_UNIMP
, "0x75 - DMA DAC, 4-bit ADPCM not"
501 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
503 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 4-bit ADPCM Reference not"
507 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
509 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 2.6-bit ADPCM not"
513 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
515 qemu_log_mask(LOG_UNIMP
, "0x74 - DMA DAC, 2.6-bit ADPCM Reference"
516 " not implemented\n");
520 qemu_log_mask(LOG_UNIMP
, "0x7d - Autio-Initialize DMA DAC, 4-bit"
521 " ADPCM Reference\n");
522 qemu_log_mask(LOG_UNIMP
, "not implemented\n");
526 qemu_log_mask(LOG_UNIMP
, "0x7d - Autio-Initialize DMA DAC, 2.6-bit"
527 " ADPCM Reference\n");
528 qemu_log_mask(LOG_UNIMP
, "not implemented\n");
537 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
540 case 0xd0: /* halt DMA operation. 8bit */
544 case 0xd1: /* speaker on */
548 case 0xd3: /* speaker off */
552 case 0xd4: /* continue DMA operation. 8bit */
553 /* KQ6 (or maybe Sierras audblst.drv in general) resets
554 the frequency between halt/continue */
558 case 0xd5: /* halt DMA operation. 16bit */
562 case 0xd6: /* continue DMA operation. 16bit */
566 case 0xd9: /* exit auto-init DMA after this block. 16bit */
570 case 0xda: /* exit auto-init DMA after this block. 8bit */
574 case 0xe0: /* DSP identification */
579 dsp_out_data (s
, s
->ver
& 0xff);
580 dsp_out_data (s
, s
->ver
>> 8);
590 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
591 dsp_out_data (s
, e3
[i
]);
595 case 0xe4: /* write test reg */
600 qemu_log_mask(LOG_UNIMP
, "Attempt to probe for ESS (0xe7)?\n");
603 case 0xe8: /* read test reg */
604 dsp_out_data (s
, s
->test_reg
);
609 dsp_out_data (s
, 0xaa);
610 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
611 qemu_irq_raise (s
->pic
);
622 case 0xfc: /* FIXME */
627 qemu_log_mask(LOG_UNIMP
, "Unrecognized command %#x\n", cmd
);
632 if (!s
->needed_bytes
) {
637 if (!s
->needed_bytes
) {
646 qemu_log_mask(LOG_UNIMP
, "warning: command %#x,%d is not truly understood"
647 " yet\n", cmd
, s
->needed_bytes
);
652 static uint16_t dsp_get_lohi (SB16State
*s
)
654 uint8_t hi
= dsp_get_data (s
);
655 uint8_t lo
= dsp_get_data (s
);
656 return (hi
<< 8) | lo
;
659 static uint16_t dsp_get_hilo (SB16State
*s
)
661 uint8_t lo
= dsp_get_data (s
);
662 uint8_t hi
= dsp_get_data (s
);
663 return (hi
<< 8) | lo
;
666 static void complete (SB16State
*s
)
669 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
670 s
->cmd
, s
->in_index
, s
->needed_bytes
);
672 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
673 d2
= dsp_get_data (s
);
674 d1
= dsp_get_data (s
);
675 d0
= dsp_get_data (s
);
678 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
682 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
684 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
690 s
->csp_mode
= dsp_get_data (s
);
693 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
697 s
->csp_param
= dsp_get_data (s
);
698 s
->csp_value
= dsp_get_data (s
);
699 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
705 d0
= dsp_get_data (s
);
706 d1
= dsp_get_data (s
);
707 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
709 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
710 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
714 s
->csp_regs
[d1
] = d0
;
719 d0
= dsp_get_data (s
);
720 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
721 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
723 ldebug ("0x83[%d] -> %#x\n",
725 s
->csp_reg83
[s
->csp_reg83w
% 4]);
726 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
730 dsp_out_data (s
, s
->csp_regs
[d0
]);
735 d0
= dsp_get_data (s
);
736 dolog ("cmd 0x10 d0=%#x\n", d0
);
740 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
744 s
->time_const
= dsp_get_data (s
);
745 ldebug ("set time const %d\n", s
->time_const
);
751 * 0x41 is documented as setting the output sample rate,
752 * and 0x42 the input sample rate, but in fact SB16 hardware
753 * seems to have only a single sample rate under the hood,
754 * and FT2 sets output freq with this (go figure). Compare:
755 * http://homepages.cae.wisc.edu/~brodskye/sb16doc/sb16doc.html#SamplingRate
757 s
->freq
= dsp_get_hilo (s
);
758 ldebug ("set freq %d\n", s
->freq
);
762 s
->block_size
= dsp_get_lohi (s
) + 1;
763 ldebug ("set dma block len %d\n", s
->block_size
);
770 /* ADPCM stuff, ignore */
775 int freq
, samples
, bytes
;
778 freq
= s
->freq
> 0 ? s
->freq
: 11025;
779 samples
= dsp_get_lohi (s
) + 1;
780 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
781 ticks
= muldiv64(bytes
, NANOSECONDS_PER_SECOND
, freq
);
782 if (ticks
< NANOSECONDS_PER_SECOND
/ 1024) {
783 qemu_irq_raise (s
->pic
);
789 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) + ticks
793 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
798 d0
= dsp_get_data (s
);
800 ldebug ("E0 data = %#x\n", d0
);
801 dsp_out_data (s
, ~d0
);
806 d0
= dsp_get_data (s
);
807 dolog ("E2 = %#x\n", d0
);
812 s
->test_reg
= dsp_get_data (s
);
816 d0
= dsp_get_data (s
);
817 ldebug ("command 0xf9 with %#x\n", d0
);
820 dsp_out_data (s
, 0xff);
824 dsp_out_data (s
, 0x07);
828 dsp_out_data (s
, 0x38);
832 dsp_out_data (s
, 0x00);
838 qemu_log_mask(LOG_UNIMP
, "complete: unrecognized command %#x\n",
848 static void legacy_reset (SB16State
*s
)
850 struct audsettings as
;
859 as
.fmt
= AUDIO_FORMAT_U8
;
862 s
->voice
= AUD_open_out (
871 /* Not sure about that... */
872 /* AUD_set_active_out (s->voice, 1); */
875 static void reset (SB16State
*s
)
877 qemu_irq_lower (s
->pic
);
879 qemu_irq_raise (s
->pic
);
880 qemu_irq_lower (s
->pic
);
883 s
->mixer_regs
[0x82] = 0;
887 s
->left_till_irq
= 0;
895 dsp_out_data (s
, 0xaa);
901 static void dsp_write(void *opaque
, uint32_t nport
, uint32_t val
)
903 SB16State
*s
= opaque
;
906 iport
= nport
- s
->port
;
908 ldebug ("write %#x <- %#x\n", nport
, val
);
920 case 0x03: /* FreeBSD kludge */
925 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
928 case 0xb8: /* Panic */
933 dsp_out_data (s
, 0x38);
944 case 0x0c: /* write data or command | write status */
945 /* if (s->highspeed) */
948 if (s
->needed_bytes
== 0) {
951 if (0 == s
->needed_bytes
) {
957 if (s
->in_index
== sizeof (s
->in2_data
)) {
958 dolog ("in data overrun\n");
961 s
->in2_data
[s
->in_index
++] = val
;
962 if (s
->in_index
== s
->needed_bytes
) {
974 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
979 static uint32_t dsp_read(void *opaque
, uint32_t nport
)
981 SB16State
*s
= opaque
;
982 int iport
, retval
, ack
= 0;
984 iport
= nport
- s
->port
;
987 case 0x06: /* reset */
991 case 0x0a: /* read data */
992 if (s
->out_data_len
) {
993 retval
= s
->out_data
[--s
->out_data_len
];
994 s
->last_read_byte
= retval
;
998 dolog ("empty output buffer for command %#x\n",
1001 retval
= s
->last_read_byte
;
1006 case 0x0c: /* 0 can write */
1007 retval
= s
->can_write
? 0 : 0x80;
1010 case 0x0d: /* timer interrupt clear */
1011 /* dolog ("timer interrupt clear\n"); */
1015 case 0x0e: /* data available status | irq 8 ack */
1016 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1017 if (s
->mixer_regs
[0x82] & 1) {
1019 s
->mixer_regs
[0x82] &= ~1;
1020 qemu_irq_lower (s
->pic
);
1024 case 0x0f: /* irq 16 ack */
1026 if (s
->mixer_regs
[0x82] & 2) {
1028 s
->mixer_regs
[0x82] &= ~2;
1029 qemu_irq_lower (s
->pic
);
1038 ldebug ("read %#x -> %#x\n", nport
, retval
);
1044 dolog ("warning: dsp_read %#x error\n", nport
);
1048 static void reset_mixer (SB16State
*s
)
1052 memset (s
->mixer_regs
, 0xff, 0x7f);
1053 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1055 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1056 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1057 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1058 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1060 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1061 s
->mixer_regs
[0x0c] = 0;
1063 /* d5=output filt, d1=stereo switch */
1064 s
->mixer_regs
[0x0e] = 0;
1066 /* voice volume L d5,d7, R d1,d3 */
1067 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1069 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1071 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1073 for (i
= 0x30; i
< 0x48; i
++) {
1074 s
->mixer_regs
[i
] = 0x20;
1078 static void mixer_write_indexb(void *opaque
, uint32_t nport
, uint32_t val
)
1080 SB16State
*s
= opaque
;
1082 s
->mixer_nreg
= val
;
1085 static void mixer_write_datab(void *opaque
, uint32_t nport
, uint32_t val
)
1087 SB16State
*s
= opaque
;
1090 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1092 switch (s
->mixer_nreg
) {
1099 int irq
= irq_of_magic (val
);
1100 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1111 dma
= ctz32 (val
& 0xf);
1112 hdma
= ctz32 (val
& 0xf0);
1113 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1114 qemu_log_mask(LOG_GUEST_ERROR
, "attempt to change DMA 8bit"
1115 " %d(%d), 16bit %d(%d) (val=%#x)\n", dma
, s
->dma
,
1116 hdma
, s
->hdma
, val
);
1126 qemu_log_mask(LOG_GUEST_ERROR
, "attempt to write into IRQ status"
1127 " register (val=%#x)\n", val
);
1131 if (s
->mixer_nreg
>= 0x80) {
1132 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1137 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1140 static uint32_t mixer_read(void *opaque
, uint32_t nport
)
1142 SB16State
*s
= opaque
;
1145 #ifndef DEBUG_SB16_MOST
1146 if (s
->mixer_nreg
!= 0x82) {
1147 ldebug ("mixer_read[%#x] -> %#x\n",
1148 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1151 ldebug ("mixer_read[%#x] -> %#x\n",
1152 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1154 return s
->mixer_regs
[s
->mixer_nreg
];
1157 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1158 int dma_len
, int len
)
1160 IsaDma
*isa_dma
= nchan
== s
->dma
? s
->isa_dma
: s
->isa_hdma
;
1161 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
1163 uint8_t tmpbuf
[4096];
1169 int left
= dma_len
- dma_pos
;
1173 to_copy
= MIN (temp
, left
);
1174 if (to_copy
> sizeof (tmpbuf
)) {
1175 to_copy
= sizeof (tmpbuf
);
1178 copied
= k
->read_memory(isa_dma
, nchan
, tmpbuf
, dma_pos
, to_copy
);
1179 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1182 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1193 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1195 SB16State
*s
= opaque
;
1196 int till
, copy
, written
, free
;
1198 if (s
->block_size
<= 0) {
1199 qemu_log_mask(LOG_GUEST_ERROR
, "invalid block size=%d nchan=%d"
1200 " dma_pos=%d dma_len=%d\n", s
->block_size
, nchan
,
1205 if (s
->left_till_irq
< 0) {
1206 s
->left_till_irq
= s
->block_size
;
1210 free
= s
->audio_free
& ~s
->align
;
1211 if ((free
<= 0) || !dma_len
) {
1220 till
= s
->left_till_irq
;
1222 #ifdef DEBUG_SB16_MOST
1223 dolog ("pos:%06d %d till:%d len:%d\n",
1224 dma_pos
, free
, till
, dma_len
);
1228 if (s
->dma_auto
== 0) {
1233 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1234 dma_pos
= (dma_pos
+ written
) % dma_len
;
1235 s
->left_till_irq
-= written
;
1237 if (s
->left_till_irq
<= 0) {
1238 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1239 qemu_irq_raise (s
->pic
);
1240 if (s
->dma_auto
== 0) {
1246 #ifdef DEBUG_SB16_MOST
1247 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1248 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1252 while (s
->left_till_irq
<= 0) {
1253 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1259 static void SB_audio_callback (void *opaque
, int free
)
1261 SB16State
*s
= opaque
;
1262 s
->audio_free
= free
;
1265 static int sb16_post_load (void *opaque
, int version_id
)
1267 SB16State
*s
= opaque
;
1270 AUD_close_out (&s
->card
, s
->voice
);
1274 if (s
->dma_running
) {
1276 struct audsettings as
;
1281 as
.nchannels
= 1 << s
->fmt_stereo
;
1285 s
->voice
= AUD_open_out (
1296 speaker (s
, s
->speaker
);
1301 static const VMStateDescription vmstate_sb16
= {
1304 .minimum_version_id
= 1,
1305 .post_load
= sb16_post_load
,
1306 .fields
= (VMStateField
[]) {
1307 VMSTATE_UINT32 (irq
, SB16State
),
1308 VMSTATE_UINT32 (dma
, SB16State
),
1309 VMSTATE_UINT32 (hdma
, SB16State
),
1310 VMSTATE_UINT32 (port
, SB16State
),
1311 VMSTATE_UINT32 (ver
, SB16State
),
1312 VMSTATE_INT32 (in_index
, SB16State
),
1313 VMSTATE_INT32 (out_data_len
, SB16State
),
1314 VMSTATE_INT32 (fmt_stereo
, SB16State
),
1315 VMSTATE_INT32 (fmt_signed
, SB16State
),
1316 VMSTATE_INT32 (fmt_bits
, SB16State
),
1317 VMSTATE_UINT32 (fmt
, SB16State
),
1318 VMSTATE_INT32 (dma_auto
, SB16State
),
1319 VMSTATE_INT32 (block_size
, SB16State
),
1320 VMSTATE_INT32 (fifo
, SB16State
),
1321 VMSTATE_INT32 (freq
, SB16State
),
1322 VMSTATE_INT32 (time_const
, SB16State
),
1323 VMSTATE_INT32 (speaker
, SB16State
),
1324 VMSTATE_INT32 (needed_bytes
, SB16State
),
1325 VMSTATE_INT32 (cmd
, SB16State
),
1326 VMSTATE_INT32 (use_hdma
, SB16State
),
1327 VMSTATE_INT32 (highspeed
, SB16State
),
1328 VMSTATE_INT32 (can_write
, SB16State
),
1329 VMSTATE_INT32 (v2x6
, SB16State
),
1331 VMSTATE_UINT8 (csp_param
, SB16State
),
1332 VMSTATE_UINT8 (csp_value
, SB16State
),
1333 VMSTATE_UINT8 (csp_mode
, SB16State
),
1334 VMSTATE_UINT8 (csp_param
, SB16State
),
1335 VMSTATE_BUFFER (csp_regs
, SB16State
),
1336 VMSTATE_UINT8 (csp_index
, SB16State
),
1337 VMSTATE_BUFFER (csp_reg83
, SB16State
),
1338 VMSTATE_INT32 (csp_reg83r
, SB16State
),
1339 VMSTATE_INT32 (csp_reg83w
, SB16State
),
1341 VMSTATE_BUFFER (in2_data
, SB16State
),
1342 VMSTATE_BUFFER (out_data
, SB16State
),
1343 VMSTATE_UINT8 (test_reg
, SB16State
),
1344 VMSTATE_UINT8 (last_read_byte
, SB16State
),
1346 VMSTATE_INT32 (nzero
, SB16State
),
1347 VMSTATE_INT32 (left_till_irq
, SB16State
),
1348 VMSTATE_INT32 (dma_running
, SB16State
),
1349 VMSTATE_INT32 (bytes_per_second
, SB16State
),
1350 VMSTATE_INT32 (align
, SB16State
),
1352 VMSTATE_INT32 (mixer_nreg
, SB16State
),
1353 VMSTATE_BUFFER (mixer_regs
, SB16State
),
1355 VMSTATE_END_OF_LIST ()
1359 static const MemoryRegionPortio sb16_ioport_list
[] = {
1360 { 4, 1, 1, .write
= mixer_write_indexb
},
1361 { 5, 1, 1, .read
= mixer_read
, .write
= mixer_write_datab
},
1362 { 6, 1, 1, .read
= dsp_read
, .write
= dsp_write
},
1363 { 10, 1, 1, .read
= dsp_read
},
1364 { 12, 1, 1, .write
= dsp_write
},
1365 { 12, 4, 1, .read
= dsp_read
},
1366 PORTIO_END_OF_LIST (),
1370 static void sb16_initfn (Object
*obj
)
1372 SB16State
*s
= SB16 (obj
);
1377 static void sb16_realizefn (DeviceState
*dev
, Error
**errp
)
1379 ISADevice
*isadev
= ISA_DEVICE (dev
);
1380 SB16State
*s
= SB16 (dev
);
1383 s
->isa_hdma
= isa_get_dma(isa_bus_from_device(isadev
), s
->hdma
);
1384 s
->isa_dma
= isa_get_dma(isa_bus_from_device(isadev
), s
->dma
);
1385 if (!s
->isa_dma
|| !s
->isa_hdma
) {
1386 error_setg(errp
, "ISA controller does not support DMA");
1390 isa_init_irq (isadev
, &s
->pic
, s
->irq
);
1392 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1393 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1394 s
->mixer_regs
[0x82] = 2 << 5;
1397 s
->csp_regs
[9] = 0xf8;
1400 s
->aux_ts
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, aux_timer
, s
);
1402 error_setg(errp
, "warning: Could not create auxiliary timer");
1405 isa_register_portio_list(isadev
, &s
->portio_list
, s
->port
,
1406 sb16_ioport_list
, s
, "sb16");
1408 k
= ISADMA_GET_CLASS(s
->isa_hdma
);
1409 k
->register_channel(s
->isa_hdma
, s
->hdma
, SB_read_DMA
, s
);
1411 k
= ISADMA_GET_CLASS(s
->isa_dma
);
1412 k
->register_channel(s
->isa_dma
, s
->dma
, SB_read_DMA
, s
);
1416 AUD_register_card ("sb16", &s
->card
);
1419 static Property sb16_properties
[] = {
1420 DEFINE_AUDIO_PROPERTIES(SB16State
, card
),
1421 DEFINE_PROP_UINT32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1422 DEFINE_PROP_UINT32 ("iobase", SB16State
, port
, 0x220),
1423 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1424 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1425 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1426 DEFINE_PROP_END_OF_LIST (),
1429 static void sb16_class_initfn (ObjectClass
*klass
, void *data
)
1431 DeviceClass
*dc
= DEVICE_CLASS (klass
);
1433 dc
->realize
= sb16_realizefn
;
1434 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1435 dc
->desc
= "Creative Sound Blaster 16";
1436 dc
->vmsd
= &vmstate_sb16
;
1437 device_class_set_props(dc
, sb16_properties
);
1440 static const TypeInfo sb16_info
= {
1442 .parent
= TYPE_ISA_DEVICE
,
1443 .instance_size
= sizeof (SB16State
),
1444 .instance_init
= sb16_initfn
,
1445 .class_init
= sb16_class_initfn
,
1448 static void sb16_register_types (void)
1450 type_register_static (&sb16_info
);
1451 deprecated_register_soundhw("sb16", "Creative Sound Blaster 16",
1455 type_init (sb16_register_types
)