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];
109 PortioList portio_list
;
112 static void SB_audio_callback (void *opaque
, int free
);
114 static int magic_of_irq (int irq
)
126 dolog ("bad irq %d\n", irq
);
131 static int irq_of_magic (int magic
)
143 dolog ("bad irq magic %d\n", magic
);
149 static void log_dsp (SB16State
*dsp
)
151 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
152 dsp
->fmt_stereo
? "Stereo" : "Mono",
153 dsp
->fmt_signed
? "Signed" : "Unsigned",
155 dsp
->dma_auto
? "Auto" : "Single",
163 static void speaker (SB16State
*s
, int on
)
166 /* AUD_enable (s->voice, on); */
169 static void control (SB16State
*s
, int hold
)
171 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
172 IsaDma
*isa_dma
= s
->use_hdma
? s
->isa_hdma
: s
->isa_dma
;
173 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
174 s
->dma_running
= hold
;
176 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
179 k
->hold_DREQ(isa_dma
, dma
);
180 AUD_set_active_out (s
->voice
, 1);
183 k
->release_DREQ(isa_dma
, dma
);
184 AUD_set_active_out (s
->voice
, 0);
188 static void aux_timer (void *opaque
)
190 SB16State
*s
= opaque
;
192 qemu_irq_raise (s
->pic
);
198 static void continue_dma8 (SB16State
*s
)
201 struct audsettings as
;
206 as
.nchannels
= 1 << s
->fmt_stereo
;
210 s
->voice
= AUD_open_out (
223 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
229 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
230 if (-1 == s
->time_const
) {
235 int tmp
= (256 - s
->time_const
);
236 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
240 s
->block_size
= dma_len
<< s
->fmt_stereo
;
243 /* This is apparently the only way to make both Act1/PL
244 and SecondReality/FC work
246 Act1 sets block size via command 0x48 and it's an odd number
247 SR does the same with even number
248 Both use stereo, and Creatives own documentation states that
249 0x48 sets block size in bytes less one.. go figure */
250 s
->block_size
&= ~s
->fmt_stereo
;
253 s
->freq
>>= s
->fmt_stereo
;
254 s
->left_till_irq
= s
->block_size
;
255 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
256 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
257 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
258 s
->align
= (1 << s
->fmt_stereo
) - 1;
260 if (s
->block_size
& s
->align
) {
261 dolog ("warning: misaligned block size %d, alignment %d\n",
262 s
->block_size
, s
->align
+ 1);
265 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
266 "dma %d, auto %d, fifo %d, high %d\n",
267 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
268 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
274 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
276 s
->use_hdma
= cmd
< 0xc0;
277 s
->fifo
= (cmd
>> 1) & 1;
278 s
->dma_auto
= (cmd
>> 2) & 1;
279 s
->fmt_signed
= (d0
>> 4) & 1;
280 s
->fmt_stereo
= (d0
>> 5) & 1;
292 if (-1 != s
->time_const
) {
294 int tmp
= 256 - s
->time_const
;
295 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
297 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
298 s
->freq
= 1000000 / ((255 - s
->time_const
));
303 s
->block_size
= dma_len
+ 1;
304 s
->block_size
<<= (s
->fmt_bits
== 16);
306 /* It is clear that for DOOM and auto-init this value
307 shouldn't take stereo into account, while Miles Sound Systems
308 setsound.exe with single transfer mode wouldn't work without it
309 wonders of SB16 yet again */
310 s
->block_size
<<= s
->fmt_stereo
;
313 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
314 "dma %d, auto %d, fifo %d, high %d\n",
315 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
316 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
318 if (16 == s
->fmt_bits
) {
320 s
->fmt
= AUD_FMT_S16
;
323 s
->fmt
= AUD_FMT_U16
;
335 s
->left_till_irq
= s
->block_size
;
337 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
339 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
340 if (s
->block_size
& s
->align
) {
341 dolog ("warning: misaligned block size %d, alignment %d\n",
342 s
->block_size
, s
->align
+ 1);
346 struct audsettings as
;
351 as
.nchannels
= 1 << s
->fmt_stereo
;
355 s
->voice
= AUD_open_out (
369 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
371 ldebug ("outdata %#x\n", val
);
372 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
373 s
->out_data
[s
->out_data_len
++] = val
;
377 static inline uint8_t dsp_get_data (SB16State
*s
)
380 return s
->in2_data
[--s
->in_index
];
383 dolog ("buffer underflow\n");
388 static void command (SB16State
*s
, uint8_t cmd
)
390 ldebug ("command %#x\n", cmd
);
392 if (cmd
> 0xaf && cmd
< 0xd0) {
394 dolog ("ADC not yet supported (command %#x)\n", cmd
);
402 dolog ("%#x wrong bits\n", cmd
);
411 dsp_out_data (s
, 0x10); /* s->csp_param); */
423 /* __asm__ ("int3"); */
431 dsp_out_data (s
, 0xf8);
447 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
448 dma_cmd8 (s
, DMA8_AUTO
, -1);
451 case 0x20: /* Direct ADC, Juice/PL */
452 dsp_out_data (s
, 0xff);
456 dolog ("0x35 - MIDI command not implemented\n");
478 dsp_out_data (s
, 0xaa);
481 case 0x47: /* Continue Auto-Initialize DMA 16bit */
489 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
490 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
493 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
495 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
498 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
500 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
503 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
505 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
509 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
510 dolog ("not implemented\n");
515 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
517 dolog ("not implemented\n");
526 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
529 case 0xd0: /* halt DMA operation. 8bit */
533 case 0xd1: /* speaker on */
537 case 0xd3: /* speaker off */
541 case 0xd4: /* continue DMA operation. 8bit */
542 /* KQ6 (or maybe Sierras audblst.drv in general) resets
543 the frequency between halt/continue */
547 case 0xd5: /* halt DMA operation. 16bit */
551 case 0xd6: /* continue DMA operation. 16bit */
555 case 0xd9: /* exit auto-init DMA after this block. 16bit */
559 case 0xda: /* exit auto-init DMA after this block. 8bit */
563 case 0xe0: /* DSP identification */
568 dsp_out_data (s
, s
->ver
& 0xff);
569 dsp_out_data (s
, s
->ver
>> 8);
579 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
580 dsp_out_data (s
, e3
[i
]);
584 case 0xe4: /* write test reg */
589 dolog ("Attempt to probe for ESS (0xe7)?\n");
592 case 0xe8: /* read test reg */
593 dsp_out_data (s
, s
->test_reg
);
598 dsp_out_data (s
, 0xaa);
599 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
600 qemu_irq_raise (s
->pic
);
611 case 0xfc: /* FIXME */
616 dolog ("Unrecognized command %#x\n", cmd
);
621 if (!s
->needed_bytes
) {
626 if (!s
->needed_bytes
) {
635 dolog ("warning: command %#x,%d is not truly understood yet\n",
636 cmd
, s
->needed_bytes
);
641 static uint16_t dsp_get_lohi (SB16State
*s
)
643 uint8_t hi
= dsp_get_data (s
);
644 uint8_t lo
= dsp_get_data (s
);
645 return (hi
<< 8) | lo
;
648 static uint16_t dsp_get_hilo (SB16State
*s
)
650 uint8_t lo
= dsp_get_data (s
);
651 uint8_t hi
= dsp_get_data (s
);
652 return (hi
<< 8) | lo
;
655 static void complete (SB16State
*s
)
658 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
659 s
->cmd
, s
->in_index
, s
->needed_bytes
);
661 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
662 d2
= dsp_get_data (s
);
663 d1
= dsp_get_data (s
);
664 d0
= dsp_get_data (s
);
667 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
671 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
673 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
679 s
->csp_mode
= dsp_get_data (s
);
682 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
686 s
->csp_param
= dsp_get_data (s
);
687 s
->csp_value
= dsp_get_data (s
);
688 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
694 d0
= dsp_get_data (s
);
695 d1
= dsp_get_data (s
);
696 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
698 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
699 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
703 s
->csp_regs
[d1
] = d0
;
708 d0
= dsp_get_data (s
);
709 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
710 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
712 ldebug ("0x83[%d] -> %#x\n",
714 s
->csp_reg83
[s
->csp_reg83w
% 4]);
715 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
719 dsp_out_data (s
, s
->csp_regs
[d0
]);
724 d0
= dsp_get_data (s
);
725 dolog ("cmd 0x10 d0=%#x\n", d0
);
729 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
733 s
->time_const
= dsp_get_data (s
);
734 ldebug ("set time const %d\n", s
->time_const
);
737 case 0x42: /* FT2 sets output freq with this, go figure */
739 dolog ("cmd 0x42 might not do what it think it should\n");
742 s
->freq
= dsp_get_hilo (s
);
743 ldebug ("set freq %d\n", s
->freq
);
747 s
->block_size
= dsp_get_lohi (s
) + 1;
748 ldebug ("set dma block len %d\n", s
->block_size
);
755 /* ADPCM stuff, ignore */
760 int freq
, samples
, bytes
;
763 freq
= s
->freq
> 0 ? s
->freq
: 11025;
764 samples
= dsp_get_lohi (s
) + 1;
765 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
766 ticks
= muldiv64(bytes
, NANOSECONDS_PER_SECOND
, freq
);
767 if (ticks
< NANOSECONDS_PER_SECOND
/ 1024) {
768 qemu_irq_raise (s
->pic
);
774 qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) + ticks
778 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
783 d0
= dsp_get_data (s
);
785 ldebug ("E0 data = %#x\n", d0
);
786 dsp_out_data (s
, ~d0
);
791 d0
= dsp_get_data (s
);
792 dolog ("E2 = %#x\n", d0
);
797 s
->test_reg
= dsp_get_data (s
);
801 d0
= dsp_get_data (s
);
802 ldebug ("command 0xf9 with %#x\n", d0
);
805 dsp_out_data (s
, 0xff);
809 dsp_out_data (s
, 0x07);
813 dsp_out_data (s
, 0x38);
817 dsp_out_data (s
, 0x00);
823 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
832 static void legacy_reset (SB16State
*s
)
834 struct audsettings as
;
846 s
->voice
= AUD_open_out (
855 /* Not sure about that... */
856 /* AUD_set_active_out (s->voice, 1); */
859 static void reset (SB16State
*s
)
861 qemu_irq_lower (s
->pic
);
863 qemu_irq_raise (s
->pic
);
864 qemu_irq_lower (s
->pic
);
867 s
->mixer_regs
[0x82] = 0;
871 s
->left_till_irq
= 0;
879 dsp_out_data (s
, 0xaa);
885 static void dsp_write(void *opaque
, uint32_t nport
, uint32_t val
)
887 SB16State
*s
= opaque
;
890 iport
= nport
- s
->port
;
892 ldebug ("write %#x <- %#x\n", nport
, val
);
904 case 0x03: /* FreeBSD kludge */
909 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
912 case 0xb8: /* Panic */
917 dsp_out_data (s
, 0x38);
928 case 0x0c: /* write data or command | write status */
929 /* if (s->highspeed) */
932 if (s
->needed_bytes
== 0) {
935 if (0 == s
->needed_bytes
) {
941 if (s
->in_index
== sizeof (s
->in2_data
)) {
942 dolog ("in data overrun\n");
945 s
->in2_data
[s
->in_index
++] = val
;
946 if (s
->in_index
== s
->needed_bytes
) {
958 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
963 static uint32_t dsp_read(void *opaque
, uint32_t nport
)
965 SB16State
*s
= opaque
;
966 int iport
, retval
, ack
= 0;
968 iport
= nport
- s
->port
;
971 case 0x06: /* reset */
975 case 0x0a: /* read data */
976 if (s
->out_data_len
) {
977 retval
= s
->out_data
[--s
->out_data_len
];
978 s
->last_read_byte
= retval
;
982 dolog ("empty output buffer for command %#x\n",
985 retval
= s
->last_read_byte
;
990 case 0x0c: /* 0 can write */
991 retval
= s
->can_write
? 0 : 0x80;
994 case 0x0d: /* timer interrupt clear */
995 /* dolog ("timer interrupt clear\n"); */
999 case 0x0e: /* data available status | irq 8 ack */
1000 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1001 if (s
->mixer_regs
[0x82] & 1) {
1003 s
->mixer_regs
[0x82] &= ~1;
1004 qemu_irq_lower (s
->pic
);
1008 case 0x0f: /* irq 16 ack */
1010 if (s
->mixer_regs
[0x82] & 2) {
1012 s
->mixer_regs
[0x82] &= ~2;
1013 qemu_irq_lower (s
->pic
);
1022 ldebug ("read %#x -> %#x\n", nport
, retval
);
1028 dolog ("warning: dsp_read %#x error\n", nport
);
1032 static void reset_mixer (SB16State
*s
)
1036 memset (s
->mixer_regs
, 0xff, 0x7f);
1037 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1039 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1040 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1041 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1042 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1044 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1045 s
->mixer_regs
[0x0c] = 0;
1047 /* d5=output filt, d1=stereo switch */
1048 s
->mixer_regs
[0x0e] = 0;
1050 /* voice volume L d5,d7, R d1,d3 */
1051 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1053 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1055 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1057 for (i
= 0x30; i
< 0x48; i
++) {
1058 s
->mixer_regs
[i
] = 0x20;
1062 static void mixer_write_indexb(void *opaque
, uint32_t nport
, uint32_t val
)
1064 SB16State
*s
= opaque
;
1066 s
->mixer_nreg
= val
;
1069 static void mixer_write_datab(void *opaque
, uint32_t nport
, uint32_t val
)
1071 SB16State
*s
= opaque
;
1074 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1076 switch (s
->mixer_nreg
) {
1083 int irq
= irq_of_magic (val
);
1084 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1095 dma
= ctz32 (val
& 0xf);
1096 hdma
= ctz32 (val
& 0xf0);
1097 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1099 "attempt to change DMA "
1100 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1101 dma
, s
->dma
, hdma
, s
->hdma
, val
);
1111 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1116 if (s
->mixer_nreg
>= 0x80) {
1117 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1122 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1125 static uint32_t mixer_read(void *opaque
, uint32_t nport
)
1127 SB16State
*s
= opaque
;
1130 #ifndef DEBUG_SB16_MOST
1131 if (s
->mixer_nreg
!= 0x82) {
1132 ldebug ("mixer_read[%#x] -> %#x\n",
1133 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1136 ldebug ("mixer_read[%#x] -> %#x\n",
1137 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1139 return s
->mixer_regs
[s
->mixer_nreg
];
1142 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1143 int dma_len
, int len
)
1145 IsaDma
*isa_dma
= nchan
== s
->dma
? s
->isa_dma
: s
->isa_hdma
;
1146 IsaDmaClass
*k
= ISADMA_GET_CLASS(isa_dma
);
1148 uint8_t tmpbuf
[4096];
1154 int left
= dma_len
- dma_pos
;
1158 to_copy
= audio_MIN (temp
, left
);
1159 if (to_copy
> sizeof (tmpbuf
)) {
1160 to_copy
= sizeof (tmpbuf
);
1163 copied
= k
->read_memory(isa_dma
, nchan
, tmpbuf
, dma_pos
, to_copy
);
1164 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1167 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1178 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1180 SB16State
*s
= opaque
;
1181 int till
, copy
, written
, free
;
1183 if (s
->block_size
<= 0) {
1184 dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1185 s
->block_size
, nchan
, dma_pos
, dma_len
);
1189 if (s
->left_till_irq
< 0) {
1190 s
->left_till_irq
= s
->block_size
;
1194 free
= s
->audio_free
& ~s
->align
;
1195 if ((free
<= 0) || !dma_len
) {
1204 till
= s
->left_till_irq
;
1206 #ifdef DEBUG_SB16_MOST
1207 dolog ("pos:%06d %d till:%d len:%d\n",
1208 dma_pos
, free
, till
, dma_len
);
1212 if (s
->dma_auto
== 0) {
1217 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1218 dma_pos
= (dma_pos
+ written
) % dma_len
;
1219 s
->left_till_irq
-= written
;
1221 if (s
->left_till_irq
<= 0) {
1222 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1223 qemu_irq_raise (s
->pic
);
1224 if (s
->dma_auto
== 0) {
1230 #ifdef DEBUG_SB16_MOST
1231 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1232 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1236 while (s
->left_till_irq
<= 0) {
1237 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1243 static void SB_audio_callback (void *opaque
, int free
)
1245 SB16State
*s
= opaque
;
1246 s
->audio_free
= free
;
1249 static int sb16_post_load (void *opaque
, int version_id
)
1251 SB16State
*s
= opaque
;
1254 AUD_close_out (&s
->card
, s
->voice
);
1258 if (s
->dma_running
) {
1260 struct audsettings as
;
1265 as
.nchannels
= 1 << s
->fmt_stereo
;
1269 s
->voice
= AUD_open_out (
1280 speaker (s
, s
->speaker
);
1285 static const VMStateDescription vmstate_sb16
= {
1288 .minimum_version_id
= 1,
1289 .post_load
= sb16_post_load
,
1290 .fields
= (VMStateField
[]) {
1291 VMSTATE_UINT32 (irq
, SB16State
),
1292 VMSTATE_UINT32 (dma
, SB16State
),
1293 VMSTATE_UINT32 (hdma
, SB16State
),
1294 VMSTATE_UINT32 (port
, SB16State
),
1295 VMSTATE_UINT32 (ver
, SB16State
),
1296 VMSTATE_INT32 (in_index
, SB16State
),
1297 VMSTATE_INT32 (out_data_len
, SB16State
),
1298 VMSTATE_INT32 (fmt_stereo
, SB16State
),
1299 VMSTATE_INT32 (fmt_signed
, SB16State
),
1300 VMSTATE_INT32 (fmt_bits
, SB16State
),
1301 VMSTATE_UINT32 (fmt
, SB16State
),
1302 VMSTATE_INT32 (dma_auto
, SB16State
),
1303 VMSTATE_INT32 (block_size
, SB16State
),
1304 VMSTATE_INT32 (fifo
, SB16State
),
1305 VMSTATE_INT32 (freq
, SB16State
),
1306 VMSTATE_INT32 (time_const
, SB16State
),
1307 VMSTATE_INT32 (speaker
, SB16State
),
1308 VMSTATE_INT32 (needed_bytes
, SB16State
),
1309 VMSTATE_INT32 (cmd
, SB16State
),
1310 VMSTATE_INT32 (use_hdma
, SB16State
),
1311 VMSTATE_INT32 (highspeed
, SB16State
),
1312 VMSTATE_INT32 (can_write
, SB16State
),
1313 VMSTATE_INT32 (v2x6
, SB16State
),
1315 VMSTATE_UINT8 (csp_param
, SB16State
),
1316 VMSTATE_UINT8 (csp_value
, SB16State
),
1317 VMSTATE_UINT8 (csp_mode
, SB16State
),
1318 VMSTATE_UINT8 (csp_param
, SB16State
),
1319 VMSTATE_BUFFER (csp_regs
, SB16State
),
1320 VMSTATE_UINT8 (csp_index
, SB16State
),
1321 VMSTATE_BUFFER (csp_reg83
, SB16State
),
1322 VMSTATE_INT32 (csp_reg83r
, SB16State
),
1323 VMSTATE_INT32 (csp_reg83w
, SB16State
),
1325 VMSTATE_BUFFER (in2_data
, SB16State
),
1326 VMSTATE_BUFFER (out_data
, SB16State
),
1327 VMSTATE_UINT8 (test_reg
, SB16State
),
1328 VMSTATE_UINT8 (last_read_byte
, SB16State
),
1330 VMSTATE_INT32 (nzero
, SB16State
),
1331 VMSTATE_INT32 (left_till_irq
, SB16State
),
1332 VMSTATE_INT32 (dma_running
, SB16State
),
1333 VMSTATE_INT32 (bytes_per_second
, SB16State
),
1334 VMSTATE_INT32 (align
, SB16State
),
1336 VMSTATE_INT32 (mixer_nreg
, SB16State
),
1337 VMSTATE_BUFFER (mixer_regs
, SB16State
),
1339 VMSTATE_END_OF_LIST ()
1343 static const MemoryRegionPortio sb16_ioport_list
[] = {
1344 { 4, 1, 1, .write
= mixer_write_indexb
},
1345 { 5, 1, 1, .read
= mixer_read
, .write
= mixer_write_datab
},
1346 { 6, 1, 1, .read
= dsp_read
, .write
= dsp_write
},
1347 { 10, 1, 1, .read
= dsp_read
},
1348 { 12, 1, 1, .write
= dsp_write
},
1349 { 12, 4, 1, .read
= dsp_read
},
1350 PORTIO_END_OF_LIST (),
1354 static void sb16_initfn (Object
*obj
)
1356 SB16State
*s
= SB16 (obj
);
1361 static void sb16_realizefn (DeviceState
*dev
, Error
**errp
)
1363 ISADevice
*isadev
= ISA_DEVICE (dev
);
1364 SB16State
*s
= SB16 (dev
);
1367 isa_init_irq (isadev
, &s
->pic
, s
->irq
);
1369 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1370 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1371 s
->mixer_regs
[0x82] = 2 << 5;
1374 s
->csp_regs
[9] = 0xf8;
1377 s
->aux_ts
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, aux_timer
, s
);
1379 dolog ("warning: Could not create auxiliary timer\n");
1382 isa_register_portio_list(isadev
, &s
->portio_list
, s
->port
,
1383 sb16_ioport_list
, s
, "sb16");
1385 s
->isa_hdma
= isa_get_dma(isa_bus_from_device(isadev
), s
->hdma
);
1386 k
= ISADMA_GET_CLASS(s
->isa_hdma
);
1387 k
->register_channel(s
->isa_hdma
, s
->hdma
, SB_read_DMA
, s
);
1389 s
->isa_dma
= isa_get_dma(isa_bus_from_device(isadev
), s
->dma
);
1390 k
= ISADMA_GET_CLASS(s
->isa_dma
);
1391 k
->register_channel(s
->isa_dma
, s
->dma
, SB_read_DMA
, s
);
1395 AUD_register_card ("sb16", &s
->card
);
1398 static int SB16_init (ISABus
*bus
)
1400 isa_create_simple (bus
, TYPE_SB16
);
1404 static Property sb16_properties
[] = {
1405 DEFINE_PROP_UINT32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1406 DEFINE_PROP_UINT32 ("iobase", SB16State
, port
, 0x220),
1407 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1408 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1409 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1410 DEFINE_PROP_END_OF_LIST (),
1413 static void sb16_class_initfn (ObjectClass
*klass
, void *data
)
1415 DeviceClass
*dc
= DEVICE_CLASS (klass
);
1417 dc
->realize
= sb16_realizefn
;
1418 set_bit(DEVICE_CATEGORY_SOUND
, dc
->categories
);
1419 dc
->desc
= "Creative Sound Blaster 16";
1420 dc
->vmsd
= &vmstate_sb16
;
1421 dc
->props
= sb16_properties
;
1424 static const TypeInfo sb16_info
= {
1426 .parent
= TYPE_ISA_DEVICE
,
1427 .instance_size
= sizeof (SB16State
),
1428 .instance_init
= sb16_initfn
,
1429 .class_init
= sb16_class_initfn
,
1432 static void sb16_register_types (void)
1434 type_register_static (&sb16_info
);
1435 isa_register_soundhw("sb16", "Creative Sound Blaster 16", SB16_init
);
1438 type_init (sb16_register_types
)