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
26 #include "audio/audio.h"
29 #include "qemu-timer.h"
30 #include "host-utils.h"
32 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
35 /* #define DEBUG_SB16_MOST */
38 #define ldebug(...) dolog (__VA_ARGS__)
43 #define IO_READ_PROTO(name) \
44 uint32_t name (void *opaque, uint32_t nport)
45 #define IO_WRITE_PROTO(name) \
46 void name (void *opaque, uint32_t nport, uint32_t val)
48 static const char e3
[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
50 typedef struct SB16State
{
83 uint8_t csp_regs
[256];
92 uint8_t last_read_byte
;
106 uint8_t mixer_regs
[256];
109 static void SB_audio_callback (void *opaque
, int free
);
111 static int magic_of_irq (int irq
)
123 dolog ("bad irq %d\n", irq
);
128 static int irq_of_magic (int magic
)
140 dolog ("bad irq magic %d\n", magic
);
146 static void log_dsp (SB16State
*dsp
)
148 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
149 dsp
->fmt_stereo
? "Stereo" : "Mono",
150 dsp
->fmt_signed
? "Signed" : "Unsigned",
152 dsp
->dma_auto
? "Auto" : "Single",
160 static void speaker (SB16State
*s
, int on
)
163 /* AUD_enable (s->voice, on); */
166 static void control (SB16State
*s
, int hold
)
168 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
169 s
->dma_running
= hold
;
171 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
175 AUD_set_active_out (s
->voice
, 1);
178 DMA_release_DREQ (dma
);
179 AUD_set_active_out (s
->voice
, 0);
183 static void aux_timer (void *opaque
)
185 SB16State
*s
= opaque
;
187 qemu_irq_raise (s
->pic
);
193 static void continue_dma8 (SB16State
*s
)
196 struct audsettings as
;
201 as
.nchannels
= 1 << s
->fmt_stereo
;
205 s
->voice
= AUD_open_out (
218 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
224 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
225 if (-1 == s
->time_const
) {
230 int tmp
= (256 - s
->time_const
);
231 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
235 s
->block_size
= dma_len
<< s
->fmt_stereo
;
238 /* This is apparently the only way to make both Act1/PL
239 and SecondReality/FC work
241 Act1 sets block size via command 0x48 and it's an odd number
242 SR does the same with even number
243 Both use stereo, and Creatives own documentation states that
244 0x48 sets block size in bytes less one.. go figure */
245 s
->block_size
&= ~s
->fmt_stereo
;
248 s
->freq
>>= s
->fmt_stereo
;
249 s
->left_till_irq
= s
->block_size
;
250 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
251 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
252 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
253 s
->align
= (1 << s
->fmt_stereo
) - 1;
255 if (s
->block_size
& s
->align
) {
256 dolog ("warning: misaligned block size %d, alignment %d\n",
257 s
->block_size
, s
->align
+ 1);
260 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
261 "dma %d, auto %d, fifo %d, high %d\n",
262 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
263 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
269 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
271 s
->use_hdma
= cmd
< 0xc0;
272 s
->fifo
= (cmd
>> 1) & 1;
273 s
->dma_auto
= (cmd
>> 2) & 1;
274 s
->fmt_signed
= (d0
>> 4) & 1;
275 s
->fmt_stereo
= (d0
>> 5) & 1;
287 if (-1 != s
->time_const
) {
289 int tmp
= 256 - s
->time_const
;
290 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
292 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
293 s
->freq
= 1000000 / ((255 - s
->time_const
));
298 s
->block_size
= dma_len
+ 1;
299 s
->block_size
<<= (s
->fmt_bits
== 16);
301 /* It is clear that for DOOM and auto-init this value
302 shouldn't take stereo into account, while Miles Sound Systems
303 setsound.exe with single transfer mode wouldn't work without it
304 wonders of SB16 yet again */
305 s
->block_size
<<= s
->fmt_stereo
;
308 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
309 "dma %d, auto %d, fifo %d, high %d\n",
310 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
311 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
313 if (16 == s
->fmt_bits
) {
315 s
->fmt
= AUD_FMT_S16
;
318 s
->fmt
= AUD_FMT_U16
;
330 s
->left_till_irq
= s
->block_size
;
332 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
334 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
335 if (s
->block_size
& s
->align
) {
336 dolog ("warning: misaligned block size %d, alignment %d\n",
337 s
->block_size
, s
->align
+ 1);
341 struct audsettings as
;
346 as
.nchannels
= 1 << s
->fmt_stereo
;
350 s
->voice
= AUD_open_out (
364 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
366 ldebug ("outdata %#x\n", val
);
367 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
368 s
->out_data
[s
->out_data_len
++] = val
;
372 static inline uint8_t dsp_get_data (SB16State
*s
)
375 return s
->in2_data
[--s
->in_index
];
378 dolog ("buffer underflow\n");
383 static void command (SB16State
*s
, uint8_t cmd
)
385 ldebug ("command %#x\n", cmd
);
387 if (cmd
> 0xaf && cmd
< 0xd0) {
389 dolog ("ADC not yet supported (command %#x)\n", cmd
);
397 dolog ("%#x wrong bits\n", cmd
);
406 dsp_out_data (s
, 0x10); /* s->csp_param); */
418 /* __asm__ ("int3"); */
426 dsp_out_data (s
, 0xf8);
442 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
443 dma_cmd8 (s
, DMA8_AUTO
, -1);
446 case 0x20: /* Direct ADC, Juice/PL */
447 dsp_out_data (s
, 0xff);
451 dolog ("0x35 - MIDI command not implemented\n");
473 dsp_out_data (s
, 0xaa);
476 case 0x47: /* Continue Auto-Initialize DMA 16bit */
484 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
485 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
488 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
490 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
493 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
495 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
498 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
500 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
504 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
505 dolog ("not implemented\n");
510 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
512 dolog ("not implemented\n");
521 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
524 case 0xd0: /* halt DMA operation. 8bit */
528 case 0xd1: /* speaker on */
532 case 0xd3: /* speaker off */
536 case 0xd4: /* continue DMA operation. 8bit */
537 /* KQ6 (or maybe Sierras audblst.drv in general) resets
538 the frequency between halt/continue */
542 case 0xd5: /* halt DMA operation. 16bit */
546 case 0xd6: /* continue DMA operation. 16bit */
550 case 0xd9: /* exit auto-init DMA after this block. 16bit */
554 case 0xda: /* exit auto-init DMA after this block. 8bit */
558 case 0xe0: /* DSP identification */
563 dsp_out_data (s
, s
->ver
& 0xff);
564 dsp_out_data (s
, s
->ver
>> 8);
574 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
575 dsp_out_data (s
, e3
[i
]);
579 case 0xe4: /* write test reg */
584 dolog ("Attempt to probe for ESS (0xe7)?\n");
587 case 0xe8: /* read test reg */
588 dsp_out_data (s
, s
->test_reg
);
593 dsp_out_data (s
, 0xaa);
594 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
595 qemu_irq_raise (s
->pic
);
606 case 0xfc: /* FIXME */
611 dolog ("Unrecognized command %#x\n", cmd
);
616 if (!s
->needed_bytes
) {
621 if (!s
->needed_bytes
) {
630 dolog ("warning: command %#x,%d is not truly understood yet\n",
631 cmd
, s
->needed_bytes
);
636 static uint16_t dsp_get_lohi (SB16State
*s
)
638 uint8_t hi
= dsp_get_data (s
);
639 uint8_t lo
= dsp_get_data (s
);
640 return (hi
<< 8) | lo
;
643 static uint16_t dsp_get_hilo (SB16State
*s
)
645 uint8_t lo
= dsp_get_data (s
);
646 uint8_t hi
= dsp_get_data (s
);
647 return (hi
<< 8) | lo
;
650 static void complete (SB16State
*s
)
653 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
654 s
->cmd
, s
->in_index
, s
->needed_bytes
);
656 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
657 d2
= dsp_get_data (s
);
658 d1
= dsp_get_data (s
);
659 d0
= dsp_get_data (s
);
662 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
666 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
668 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
674 s
->csp_mode
= dsp_get_data (s
);
677 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
681 s
->csp_param
= dsp_get_data (s
);
682 s
->csp_value
= dsp_get_data (s
);
683 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
689 d0
= dsp_get_data (s
);
690 d1
= dsp_get_data (s
);
691 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
693 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
694 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
698 s
->csp_regs
[d1
] = d0
;
703 d0
= dsp_get_data (s
);
704 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
705 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
707 ldebug ("0x83[%d] -> %#x\n",
709 s
->csp_reg83
[s
->csp_reg83w
% 4]);
710 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
714 dsp_out_data (s
, s
->csp_regs
[d0
]);
719 d0
= dsp_get_data (s
);
720 dolog ("cmd 0x10 d0=%#x\n", d0
);
724 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
728 s
->time_const
= dsp_get_data (s
);
729 ldebug ("set time const %d\n", s
->time_const
);
732 case 0x42: /* FT2 sets output freq with this, go figure */
734 dolog ("cmd 0x42 might not do what it think it should\n");
737 s
->freq
= dsp_get_hilo (s
);
738 ldebug ("set freq %d\n", s
->freq
);
742 s
->block_size
= dsp_get_lohi (s
) + 1;
743 ldebug ("set dma block len %d\n", s
->block_size
);
750 /* ADPCM stuff, ignore */
755 int freq
, samples
, bytes
;
758 freq
= s
->freq
> 0 ? s
->freq
: 11025;
759 samples
= dsp_get_lohi (s
) + 1;
760 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
761 ticks
= muldiv64 (bytes
, get_ticks_per_sec (), freq
);
762 if (ticks
< get_ticks_per_sec () / 1024) {
763 qemu_irq_raise (s
->pic
);
769 qemu_get_clock (vm_clock
) + ticks
773 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
778 d0
= dsp_get_data (s
);
780 ldebug ("E0 data = %#x\n", d0
);
781 dsp_out_data (s
, ~d0
);
785 d0
= dsp_get_data (s
);
786 ldebug ("E2 = %#x\n", d0
);
790 s
->test_reg
= dsp_get_data (s
);
794 d0
= dsp_get_data (s
);
795 ldebug ("command 0xf9 with %#x\n", d0
);
798 dsp_out_data (s
, 0xff);
802 dsp_out_data (s
, 0x07);
806 dsp_out_data (s
, 0x38);
810 dsp_out_data (s
, 0x00);
816 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
826 static void legacy_reset (SB16State
*s
)
828 struct audsettings as
;
840 s
->voice
= AUD_open_out (
849 /* Not sure about that... */
850 /* AUD_set_active_out (s->voice, 1); */
853 static void reset (SB16State
*s
)
855 qemu_irq_lower (s
->pic
);
857 qemu_irq_raise (s
->pic
);
858 qemu_irq_lower (s
->pic
);
861 s
->mixer_regs
[0x82] = 0;
865 s
->left_till_irq
= 0;
873 dsp_out_data (s
, 0xaa);
879 static IO_WRITE_PROTO (dsp_write
)
881 SB16State
*s
= opaque
;
884 iport
= nport
- s
->port
;
886 ldebug ("write %#x <- %#x\n", nport
, val
);
898 case 0x03: /* FreeBSD kludge */
903 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
906 case 0xb8: /* Panic */
911 dsp_out_data (s
, 0x38);
922 case 0x0c: /* write data or command | write status */
923 /* if (s->highspeed) */
926 if (0 == s
->needed_bytes
) {
929 if (0 == s
->needed_bytes
) {
935 if (s
->in_index
== sizeof (s
->in2_data
)) {
936 dolog ("in data overrun\n");
939 s
->in2_data
[s
->in_index
++] = val
;
940 if (s
->in_index
== s
->needed_bytes
) {
952 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
957 static IO_READ_PROTO (dsp_read
)
959 SB16State
*s
= opaque
;
960 int iport
, retval
, ack
= 0;
962 iport
= nport
- s
->port
;
965 case 0x06: /* reset */
969 case 0x0a: /* read data */
970 if (s
->out_data_len
) {
971 retval
= s
->out_data
[--s
->out_data_len
];
972 s
->last_read_byte
= retval
;
976 dolog ("empty output buffer for command %#x\n",
979 retval
= s
->last_read_byte
;
984 case 0x0c: /* 0 can write */
985 retval
= s
->can_write
? 0 : 0x80;
988 case 0x0d: /* timer interrupt clear */
989 /* dolog ("timer interrupt clear\n"); */
993 case 0x0e: /* data available status | irq 8 ack */
994 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
995 if (s
->mixer_regs
[0x82] & 1) {
997 s
->mixer_regs
[0x82] &= 1;
998 qemu_irq_lower (s
->pic
);
1002 case 0x0f: /* irq 16 ack */
1004 if (s
->mixer_regs
[0x82] & 2) {
1006 s
->mixer_regs
[0x82] &= 2;
1007 qemu_irq_lower (s
->pic
);
1016 ldebug ("read %#x -> %#x\n", nport
, retval
);
1022 dolog ("warning: dsp_read %#x error\n", nport
);
1026 static void reset_mixer (SB16State
*s
)
1030 memset (s
->mixer_regs
, 0xff, 0x7f);
1031 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1033 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1034 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1035 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1036 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1038 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1039 s
->mixer_regs
[0x0c] = 0;
1041 /* d5=output filt, d1=stereo switch */
1042 s
->mixer_regs
[0x0e] = 0;
1044 /* voice volume L d5,d7, R d1,d3 */
1045 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1047 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1049 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1051 for (i
= 0x30; i
< 0x48; i
++) {
1052 s
->mixer_regs
[i
] = 0x20;
1056 static IO_WRITE_PROTO (mixer_write_indexb
)
1058 SB16State
*s
= opaque
;
1060 s
->mixer_nreg
= val
;
1063 static IO_WRITE_PROTO (mixer_write_datab
)
1065 SB16State
*s
= opaque
;
1068 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1070 switch (s
->mixer_nreg
) {
1077 int irq
= irq_of_magic (val
);
1078 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1089 dma
= ctz32 (val
& 0xf);
1090 hdma
= ctz32 (val
& 0xf0);
1091 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1093 "attempt to change DMA "
1094 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1095 dma
, s
->dma
, hdma
, s
->hdma
, val
);
1105 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1110 if (s
->mixer_nreg
>= 0x80) {
1111 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1116 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1119 static IO_WRITE_PROTO (mixer_write_indexw
)
1121 mixer_write_indexb (opaque
, nport
, val
& 0xff);
1122 mixer_write_datab (opaque
, nport
, (val
>> 8) & 0xff);
1125 static IO_READ_PROTO (mixer_read
)
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
)
1146 uint8_t tmpbuf
[4096];
1152 int left
= dma_len
- dma_pos
;
1156 to_copy
= audio_MIN (temp
, left
);
1157 if (to_copy
> sizeof (tmpbuf
)) {
1158 to_copy
= sizeof (tmpbuf
);
1161 copied
= DMA_read_memory (nchan
, tmpbuf
, dma_pos
, to_copy
);
1162 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1165 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1176 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1178 SB16State
*s
= opaque
;
1179 int till
, copy
, written
, free
;
1181 if (s
->block_size
<= 0) {
1182 dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1183 s
->block_size
, nchan
, dma_pos
, dma_len
);
1187 if (s
->left_till_irq
< 0) {
1188 s
->left_till_irq
= s
->block_size
;
1192 free
= s
->audio_free
& ~s
->align
;
1193 if ((free
<= 0) || !dma_len
) {
1202 till
= s
->left_till_irq
;
1204 #ifdef DEBUG_SB16_MOST
1205 dolog ("pos:%06d %d till:%d len:%d\n",
1206 dma_pos
, free
, till
, dma_len
);
1210 if (0 == s
->dma_auto
) {
1215 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1216 dma_pos
= (dma_pos
+ written
) % dma_len
;
1217 s
->left_till_irq
-= written
;
1219 if (s
->left_till_irq
<= 0) {
1220 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1221 qemu_irq_raise (s
->pic
);
1222 if (0 == s
->dma_auto
) {
1228 #ifdef DEBUG_SB16_MOST
1229 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1230 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1234 while (s
->left_till_irq
<= 0) {
1235 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1241 static void SB_audio_callback (void *opaque
, int free
)
1243 SB16State
*s
= opaque
;
1244 s
->audio_free
= free
;
1247 static void SB_save (QEMUFile
*f
, void *opaque
)
1249 SB16State
*s
= opaque
;
1251 qemu_put_be32 (f
, s
->irq
);
1252 qemu_put_be32 (f
, s
->dma
);
1253 qemu_put_be32 (f
, s
->hdma
);
1254 qemu_put_be32 (f
, s
->port
);
1255 qemu_put_be32 (f
, s
->ver
);
1256 qemu_put_be32 (f
, s
->in_index
);
1257 qemu_put_be32 (f
, s
->out_data_len
);
1258 qemu_put_be32 (f
, s
->fmt_stereo
);
1259 qemu_put_be32 (f
, s
->fmt_signed
);
1260 qemu_put_be32 (f
, s
->fmt_bits
);
1261 qemu_put_be32s (f
, &s
->fmt
);
1262 qemu_put_be32 (f
, s
->dma_auto
);
1263 qemu_put_be32 (f
, s
->block_size
);
1264 qemu_put_be32 (f
, s
->fifo
);
1265 qemu_put_be32 (f
, s
->freq
);
1266 qemu_put_be32 (f
, s
->time_const
);
1267 qemu_put_be32 (f
, s
->speaker
);
1268 qemu_put_be32 (f
, s
->needed_bytes
);
1269 qemu_put_be32 (f
, s
->cmd
);
1270 qemu_put_be32 (f
, s
->use_hdma
);
1271 qemu_put_be32 (f
, s
->highspeed
);
1272 qemu_put_be32 (f
, s
->can_write
);
1273 qemu_put_be32 (f
, s
->v2x6
);
1275 qemu_put_8s (f
, &s
->csp_param
);
1276 qemu_put_8s (f
, &s
->csp_value
);
1277 qemu_put_8s (f
, &s
->csp_mode
);
1278 qemu_put_8s (f
, &s
->csp_param
);
1279 qemu_put_buffer (f
, s
->csp_regs
, 256);
1280 qemu_put_8s (f
, &s
->csp_index
);
1281 qemu_put_buffer (f
, s
->csp_reg83
, 4);
1282 qemu_put_be32 (f
, s
->csp_reg83r
);
1283 qemu_put_be32 (f
, s
->csp_reg83w
);
1285 qemu_put_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1286 qemu_put_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1287 qemu_put_8s (f
, &s
->test_reg
);
1288 qemu_put_8s (f
, &s
->last_read_byte
);
1290 qemu_put_be32 (f
, s
->nzero
);
1291 qemu_put_be32 (f
, s
->left_till_irq
);
1292 qemu_put_be32 (f
, s
->dma_running
);
1293 qemu_put_be32 (f
, s
->bytes_per_second
);
1294 qemu_put_be32 (f
, s
->align
);
1296 qemu_put_be32 (f
, s
->mixer_nreg
);
1297 qemu_put_buffer (f
, s
->mixer_regs
, 256);
1300 static int SB_load (QEMUFile
*f
, void *opaque
, int version_id
)
1302 SB16State
*s
= opaque
;
1304 if (version_id
!= 1) {
1308 s
->irq
=qemu_get_be32 (f
);
1309 s
->dma
=qemu_get_be32 (f
);
1310 s
->hdma
=qemu_get_be32 (f
);
1311 s
->port
=qemu_get_be32 (f
);
1312 s
->ver
=qemu_get_be32 (f
);
1313 s
->in_index
=qemu_get_be32 (f
);
1314 s
->out_data_len
=qemu_get_be32 (f
);
1315 s
->fmt_stereo
=qemu_get_be32 (f
);
1316 s
->fmt_signed
=qemu_get_be32 (f
);
1317 s
->fmt_bits
=qemu_get_be32 (f
);
1318 qemu_get_be32s (f
, &s
->fmt
);
1319 s
->dma_auto
=qemu_get_be32 (f
);
1320 s
->block_size
=qemu_get_be32 (f
);
1321 s
->fifo
=qemu_get_be32 (f
);
1322 s
->freq
=qemu_get_be32 (f
);
1323 s
->time_const
=qemu_get_be32 (f
);
1324 s
->speaker
=qemu_get_be32 (f
);
1325 s
->needed_bytes
=qemu_get_be32 (f
);
1326 s
->cmd
=qemu_get_be32 (f
);
1327 s
->use_hdma
=qemu_get_be32 (f
);
1328 s
->highspeed
=qemu_get_be32 (f
);
1329 s
->can_write
=qemu_get_be32 (f
);
1330 s
->v2x6
=qemu_get_be32 (f
);
1332 qemu_get_8s (f
, &s
->csp_param
);
1333 qemu_get_8s (f
, &s
->csp_value
);
1334 qemu_get_8s (f
, &s
->csp_mode
);
1335 qemu_get_8s (f
, &s
->csp_param
);
1336 qemu_get_buffer (f
, s
->csp_regs
, 256);
1337 qemu_get_8s (f
, &s
->csp_index
);
1338 qemu_get_buffer (f
, s
->csp_reg83
, 4);
1339 s
->csp_reg83r
=qemu_get_be32 (f
);
1340 s
->csp_reg83w
=qemu_get_be32 (f
);
1342 qemu_get_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1343 qemu_get_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1344 qemu_get_8s (f
, &s
->test_reg
);
1345 qemu_get_8s (f
, &s
->last_read_byte
);
1347 s
->nzero
=qemu_get_be32 (f
);
1348 s
->left_till_irq
=qemu_get_be32 (f
);
1349 s
->dma_running
=qemu_get_be32 (f
);
1350 s
->bytes_per_second
=qemu_get_be32 (f
);
1351 s
->align
=qemu_get_be32 (f
);
1353 s
->mixer_nreg
=qemu_get_be32 (f
);
1354 qemu_get_buffer (f
, s
->mixer_regs
, 256);
1357 AUD_close_out (&s
->card
, s
->voice
);
1361 if (s
->dma_running
) {
1363 struct audsettings as
;
1368 as
.nchannels
= 1 << s
->fmt_stereo
;
1372 s
->voice
= AUD_open_out (
1383 speaker (s
, s
->speaker
);
1388 static int sb16_initfn (ISADevice
*dev
)
1390 static const uint8_t dsp_write_ports
[] = {0x6, 0xc};
1391 static const uint8_t dsp_read_ports
[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1395 s
= DO_UPCAST (SB16State
, dev
, dev
);
1398 isa_init_irq (dev
, &s
->pic
, s
->irq
);
1400 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1401 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1402 s
->mixer_regs
[0x82] = 2 << 5;
1405 s
->csp_regs
[9] = 0xf8;
1408 s
->aux_ts
= qemu_new_timer (vm_clock
, aux_timer
, s
);
1410 dolog ("warning: Could not create auxiliary timer\n");
1413 for (i
= 0; i
< ARRAY_SIZE (dsp_write_ports
); i
++) {
1414 register_ioport_write (s
->port
+ dsp_write_ports
[i
], 1, 1, dsp_write
, s
);
1417 for (i
= 0; i
< ARRAY_SIZE (dsp_read_ports
); i
++) {
1418 register_ioport_read (s
->port
+ dsp_read_ports
[i
], 1, 1, dsp_read
, s
);
1421 register_ioport_write (s
->port
+ 0x4, 1, 1, mixer_write_indexb
, s
);
1422 register_ioport_write (s
->port
+ 0x4, 1, 2, mixer_write_indexw
, s
);
1423 register_ioport_read (s
->port
+ 0x5, 1, 1, mixer_read
, s
);
1424 register_ioport_write (s
->port
+ 0x5, 1, 1, mixer_write_datab
, s
);
1426 DMA_register_channel (s
->hdma
, SB_read_DMA
, s
);
1427 DMA_register_channel (s
->dma
, SB_read_DMA
, s
);
1430 register_savevm ("sb16", 0, 1, SB_save
, SB_load
, s
);
1431 AUD_register_card ("sb16", &s
->card
);
1435 int SB16_init (qemu_irq
*pic
)
1437 isa_create_simple ("sb16");
1441 static ISADeviceInfo sb16_info
= {
1442 .qdev
.name
= "sb16",
1443 .qdev
.desc
= "Creative Sound Blaster 16",
1444 .qdev
.size
= sizeof (SB16State
),
1445 .init
= sb16_initfn
,
1446 .qdev
.props
= (Property
[]) {
1447 DEFINE_PROP_HEX32 ("version", SB16State
, ver
, 0x0405), /* 4.5 */
1448 DEFINE_PROP_HEX32 ("iobase", SB16State
, port
, 0x220),
1449 DEFINE_PROP_UINT32 ("irq", SB16State
, irq
, 5),
1450 DEFINE_PROP_UINT32 ("dma", SB16State
, dma
, 1),
1451 DEFINE_PROP_UINT32 ("dma16", SB16State
, hdma
, 5),
1452 DEFINE_PROP_END_OF_LIST (),
1456 static void sb16_register (void)
1458 isa_qdev_register (&sb16_info
);
1460 device_init (sb16_register
)