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 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
28 #define dolog(...) AUD_log ("sb16", __VA_ARGS__)
31 /* #define DEBUG_SB16_MOST */
34 #define ldebug(...) dolog (__VA_ARGS__)
39 #define IO_READ_PROTO(name) \
40 uint32_t name (void *opaque, uint32_t nport)
41 #define IO_WRITE_PROTO(name) \
42 void name (void *opaque, uint32_t nport, uint32_t val)
44 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
53 } conf = {5, 4, 5, 1, 5, 0x220};
55 typedef struct SB16State {
86 uint8_t csp_regs[256];
95 uint8_t last_read_byte;
101 int bytes_per_second;
109 uint8_t mixer_regs[256];
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 s->dma_running = hold;
174 ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
178 AUD_set_active_out (s->voice, 1);
181 DMA_release_DREQ (dma);
182 AUD_set_active_out (s->voice, 0);
186 static void aux_timer (void *opaque)
188 SB16State *s = opaque;
190 pic_set_irq (s->irq, 1);
196 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
202 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
203 if (-1 == s->time_const) {
207 int tmp = (256 - s->time_const);
208 s->freq = (1000000 + (tmp / 2)) / tmp;
212 s->block_size = dma_len << s->fmt_stereo;
215 /* This is apparently the only way to make both Act1/PL
216 and SecondReality/FC work
218 Act1 sets block size via command 0x48 and it's an odd number
219 SR does the same with even number
220 Both use stereo, and Creatives own documentation states that
221 0x48 sets block size in bytes less one.. go figure */
222 s->block_size &= ~s->fmt_stereo;
225 s->freq >>= s->fmt_stereo;
226 s->left_till_irq = s->block_size;
227 s->bytes_per_second = (s->freq << s->fmt_stereo);
228 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
229 s->dma_auto = (mask & DMA8_AUTO) != 0;
230 s->align = (1 << s->fmt_stereo) - 1;
232 if (s->block_size & s->align) {
233 dolog ("warning: misaligned block size %d, alignment %d\n",
234 s->block_size, s->align + 1);
237 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
238 "dma %d, auto %d, fifo %d, high %d\n",
239 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
240 s->block_size, s->dma_auto, s->fifo, s->highspeed);
248 as.nchannels = 1 << s->fmt_stereo;
251 s->voice = AUD_open_out (
265 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
267 s->use_hdma = cmd < 0xc0;
268 s->fifo = (cmd >> 1) & 1;
269 s->dma_auto = (cmd >> 2) & 1;
270 s->fmt_signed = (d0 >> 4) & 1;
271 s->fmt_stereo = (d0 >> 5) & 1;
283 if (-1 != s->time_const) {
285 int tmp = 256 - s->time_const;
286 s->freq = (1000000 + (tmp / 2)) / tmp;
288 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
289 s->freq = 1000000 / ((255 - s->time_const));
294 s->block_size = dma_len + 1;
295 s->block_size <<= (s->fmt_bits == 16);
297 /* It is clear that for DOOM and auto-init this value
298 shouldn't take stereo into account, while Miles Sound Systems
299 setsound.exe with single transfer mode wouldn't work without it
300 wonders of SB16 yet again */
301 s->block_size <<= s->fmt_stereo;
304 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
305 "dma %d, auto %d, fifo %d, high %d\n",
306 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
307 s->block_size, s->dma_auto, s->fifo, s->highspeed);
309 if (16 == s->fmt_bits) {
311 s->fmt = AUD_FMT_S16;
314 s->fmt = AUD_FMT_U16;
326 s->left_till_irq = s->block_size;
328 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
330 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
331 if (s->block_size & s->align) {
332 dolog ("warning: misaligned block size %d, alignment %d\n",
333 s->block_size, s->align + 1);
342 as.nchannels = 1 << s->fmt_stereo;
345 s->voice = AUD_open_out (
359 static inline void dsp_out_data (SB16State *s, uint8_t val)
361 ldebug ("outdata %#x\n", val);
362 if ((size_t) s->out_data_len < sizeof (s->out_data)) {
363 s->out_data[s->out_data_len++] = val;
367 static inline uint8_t dsp_get_data (SB16State *s)
370 return s->in2_data[--s->in_index];
373 dolog ("buffer underflow\n");
378 static void command (SB16State *s, uint8_t cmd)
380 ldebug ("command %#x\n", cmd);
382 if (cmd > 0xaf && cmd < 0xd0) {
384 dolog ("ADC not yet supported (command %#x)\n", cmd);
392 dolog ("%#x wrong bits\n", cmd);
401 dsp_out_data (s, 0x10); /* s->csp_param); */
413 /* __asm__ ("int3"); */
421 dsp_out_data (s, 0xf8);
437 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
441 case 0x20: /* Direct ADC, Juice/PL */
442 dsp_out_data (s, 0xff);
446 dolog ("0x35 - MIDI command not implemented\n");
468 dsp_out_data (s, 0xaa);
471 case 0x47: /* Continue Auto-Initialize DMA 16bit */
479 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
480 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
483 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
485 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
488 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
490 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
493 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
495 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
499 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
500 dolog ("not implemented\n");
505 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
507 dolog ("not implemented\n");
516 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
519 case 0xd0: /* halt DMA operation. 8bit */
523 case 0xd1: /* speaker on */
527 case 0xd3: /* speaker off */
531 case 0xd4: /* continue DMA operation. 8bit */
535 case 0xd5: /* halt DMA operation. 16bit */
539 case 0xd6: /* continue DMA operation. 16bit */
543 case 0xd9: /* exit auto-init DMA after this block. 16bit */
547 case 0xda: /* exit auto-init DMA after this block. 8bit */
551 case 0xe0: /* DSP identification */
556 dsp_out_data (s, s->ver & 0xff);
557 dsp_out_data (s, s->ver >> 8);
567 for (i = sizeof (e3) - 1; i >= 0; --i)
568 dsp_out_data (s, e3[i]);
572 case 0xe4: /* write test reg */
577 dolog ("Attempt to probe for ESS (0xe7)?\n");
580 case 0xe8: /* read test reg */
581 dsp_out_data (s, s->test_reg);
586 dsp_out_data (s, 0xaa);
587 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
588 pic_set_irq (s->irq, 1);
599 case 0xfc: /* FIXME */
604 dolog ("Unrecognized command %#x\n", cmd);
609 if (!s->needed_bytes) {
614 if (!s->needed_bytes) {
623 dolog ("warning: command %#x,%d is not truly understood yet\n",
624 cmd, s->needed_bytes);
629 static uint16_t dsp_get_lohi (SB16State *s)
631 uint8_t hi = dsp_get_data (s);
632 uint8_t lo = dsp_get_data (s);
633 return (hi << 8) | lo;
636 static uint16_t dsp_get_hilo (SB16State *s)
638 uint8_t lo = dsp_get_data (s);
639 uint8_t hi = dsp_get_data (s);
640 return (hi << 8) | lo;
643 static void complete (SB16State *s)
646 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
647 s->cmd, s->in_index, s->needed_bytes);
649 if (s->cmd > 0xaf && s->cmd < 0xd0) {
650 d2 = dsp_get_data (s);
651 d1 = dsp_get_data (s);
652 d0 = dsp_get_data (s);
655 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
659 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
661 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
667 s->csp_mode = dsp_get_data (s);
670 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
674 s->csp_param = dsp_get_data (s);
675 s->csp_value = dsp_get_data (s);
676 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
682 d0 = dsp_get_data (s);
683 d1 = dsp_get_data (s);
684 ldebug ("write CSP register %d <- %#x\n", d1, d0);
686 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
687 s->csp_reg83[s->csp_reg83r % 4] = d0;
691 s->csp_regs[d1] = d0;
696 d0 = dsp_get_data (s);
697 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
698 d0, s->csp_regs[d0], s->csp_mode);
700 ldebug ("0x83[%d] -> %#x\n",
702 s->csp_reg83[s->csp_reg83w % 4]);
703 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
707 dsp_out_data (s, s->csp_regs[d0]);
712 d0 = dsp_get_data (s);
713 dolog ("cmd 0x10 d0=%#x\n", d0);
717 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
721 s->time_const = dsp_get_data (s);
722 ldebug ("set time const %d\n", s->time_const);
725 case 0x42: /* FT2 sets output freq with this, go figure */
727 dolog ("cmd 0x42 might not do what it think it should\n");
730 s->freq = dsp_get_hilo (s);
731 ldebug ("set freq %d\n", s->freq);
735 s->block_size = dsp_get_lohi (s) + 1;
736 ldebug ("set dma block len %d\n", s->block_size);
743 /* ADPCM stuff, ignore */
748 int freq, samples, bytes;
751 freq = s->freq > 0 ? s->freq : 11025;
752 samples = dsp_get_lohi (s) + 1;
753 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
754 ticks = (bytes * ticks_per_sec) / freq;
755 if (ticks < ticks_per_sec / 1024) {
756 pic_set_irq (s->irq, 1);
762 qemu_get_clock (vm_clock) + ticks
766 ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
771 d0 = dsp_get_data (s);
773 ldebug ("E0 data = %#x\n", d0);
774 dsp_out_data (s, ~d0);
778 d0 = dsp_get_data (s);
779 ldebug ("E2 = %#x\n", d0);
783 s->test_reg = dsp_get_data (s);
787 d0 = dsp_get_data (s);
788 ldebug ("command 0xf9 with %#x\n", d0);
791 dsp_out_data (s, 0xff);
795 dsp_out_data (s, 0x07);
799 dsp_out_data (s, 0x38);
803 dsp_out_data (s, 0x00);
809 dolog ("complete: unrecognized command %#x\n", s->cmd);
819 static void reset (SB16State *s)
821 pic_set_irq (s->irq, 0);
823 pic_set_irq (s->irq, 1);
824 pic_set_irq (s->irq, 0);
827 s->mixer_regs[0x82] = 0;
831 s->left_till_irq = 0;
839 dsp_out_data(s, 0xaa);
844 static IO_WRITE_PROTO (dsp_write)
846 SB16State *s = opaque;
849 iport = nport - s->port;
851 ldebug ("write %#x <- %#x\n", nport, val);
857 if (0 && s->highspeed) {
859 pic_set_irq (s->irq, 0);
870 case 0x03: /* FreeBSD kludge */
875 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
878 case 0xb8: /* Panic */
883 dsp_out_data (s, 0x38);
894 case 0x0c: /* write data or command | write status */
895 /* if (s->highspeed) */
898 if (0 == s->needed_bytes) {
901 if (0 == s->needed_bytes) {
907 if (s->in_index == sizeof (s->in2_data)) {
908 dolog ("in data overrun\n");
911 s->in2_data[s->in_index++] = val;
912 if (s->in_index == s->needed_bytes) {
924 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
929 static IO_READ_PROTO (dsp_read)
931 SB16State *s = opaque;
932 int iport, retval, ack = 0;
934 iport = nport - s->port;
937 case 0x06: /* reset */
941 case 0x0a: /* read data */
942 if (s->out_data_len) {
943 retval = s->out_data[--s->out_data_len];
944 s->last_read_byte = retval;
948 dolog ("empty output buffer for command %#x\n",
951 retval = s->last_read_byte;
956 case 0x0c: /* 0 can write */
957 retval = s->can_write ? 0 : 0x80;
960 case 0x0d: /* timer interrupt clear */
961 /* dolog ("timer interrupt clear\n"); */
965 case 0x0e: /* data available status | irq 8 ack */
966 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
967 if (s->mixer_regs[0x82] & 1) {
969 s->mixer_regs[0x82] &= 1;
970 pic_set_irq (s->irq, 0);
974 case 0x0f: /* irq 16 ack */
976 if (s->mixer_regs[0x82] & 2) {
978 s->mixer_regs[0x82] &= 2;
979 pic_set_irq (s->irq, 0);
988 ldebug ("read %#x -> %#x\n", nport, retval);
994 dolog ("warning: dsp_read %#x error\n", nport);
998 static void reset_mixer (SB16State *s)
1002 memset (s->mixer_regs, 0xff, 0x7f);
1003 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1005 s->mixer_regs[0x02] = 4; /* master volume 3bits */
1006 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
1007 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
1008 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1010 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1011 s->mixer_regs[0x0c] = 0;
1013 /* d5=output filt, d1=stereo switch */
1014 s->mixer_regs[0x0e] = 0;
1016 /* voice volume L d5,d7, R d1,d3 */
1017 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1019 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1021 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1023 for (i = 0x30; i < 0x48; i++) {
1024 s->mixer_regs[i] = 0x20;
1028 static IO_WRITE_PROTO(mixer_write_indexb)
1030 SB16State *s = opaque;
1032 s->mixer_nreg = val;
1035 static IO_WRITE_PROTO(mixer_write_datab)
1037 SB16State *s = opaque;
1040 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1042 switch (s->mixer_nreg) {
1049 int irq = irq_of_magic (val);
1050 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1061 dma = lsbindex (val & 0xf);
1062 hdma = lsbindex (val & 0xf0);
1063 if (dma != s->dma || hdma != s->hdma) {
1065 "attempt to change DMA "
1066 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1067 dma, s->dma, hdma, s->hdma, val);
1077 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1082 if (s->mixer_nreg >= 0x80) {
1083 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1088 s->mixer_regs[s->mixer_nreg] = val;
1091 static IO_WRITE_PROTO(mixer_write_indexw)
1093 mixer_write_indexb (opaque, nport, val & 0xff);
1094 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1097 static IO_READ_PROTO(mixer_read)
1099 SB16State *s = opaque;
1102 #ifndef DEBUG_SB16_MOST
1103 if (s->mixer_nreg != 0x82) {
1104 ldebug ("mixer_read[%#x] -> %#x\n",
1105 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1108 ldebug ("mixer_read[%#x] -> %#x\n",
1109 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1111 return s->mixer_regs[s->mixer_nreg];
1114 static int write_audio (SB16State *s, int nchan, int dma_pos,
1115 int dma_len, int len)
1118 uint8_t tmpbuf[4096];
1124 int left = dma_len - dma_pos;
1128 to_copy = audio_MIN (temp, left);
1129 if (to_copy > sizeof (tmpbuf)) {
1130 to_copy = sizeof (tmpbuf);
1133 copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1134 copied = AUD_write (s->voice, tmpbuf, copied);
1137 dma_pos = (dma_pos + copied) % dma_len;
1148 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1150 SB16State *s = opaque;
1151 int till, copy, written, free;
1153 if (s->left_till_irq < 0) {
1154 s->left_till_irq = s->block_size;
1158 free = s->audio_free & ~s->align;
1159 if ((free <= 0) || !dma_len) {
1168 till = s->left_till_irq;
1170 #ifdef DEBUG_SB16_MOST
1171 dolog ("pos:%06d %d till:%d len:%d\n",
1172 dma_pos, free, till, dma_len);
1176 if (0 == s->dma_auto) {
1181 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1182 dma_pos = (dma_pos + written) % dma_len;
1183 s->left_till_irq -= written;
1185 if (s->left_till_irq <= 0) {
1186 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1187 pic_set_irq (s->irq, 1);
1188 if (0 == s->dma_auto) {
1194 #ifdef DEBUG_SB16_MOST
1195 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1196 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1200 while (s->left_till_irq <= 0) {
1201 s->left_till_irq = s->block_size + s->left_till_irq;
1207 static void SB_audio_callback (void *opaque, int free)
1209 SB16State *s = opaque;
1210 s->audio_free = free;
1213 static void SB_save (QEMUFile *f, void *opaque)
1215 SB16State *s = opaque;
1217 qemu_put_be32s (f, &s->irq);
1218 qemu_put_be32s (f, &s->dma);
1219 qemu_put_be32s (f, &s->hdma);
1220 qemu_put_be32s (f, &s->port);
1221 qemu_put_be32s (f, &s->ver);
1222 qemu_put_be32s (f, &s->in_index);
1223 qemu_put_be32s (f, &s->out_data_len);
1224 qemu_put_be32s (f, &s->fmt_stereo);
1225 qemu_put_be32s (f, &s->fmt_signed);
1226 qemu_put_be32s (f, &s->fmt_bits);
1227 qemu_put_be32s (f, &s->fmt);
1228 qemu_put_be32s (f, &s->dma_auto);
1229 qemu_put_be32s (f, &s->block_size);
1230 qemu_put_be32s (f, &s->fifo);
1231 qemu_put_be32s (f, &s->freq);
1232 qemu_put_be32s (f, &s->time_const);
1233 qemu_put_be32s (f, &s->speaker);
1234 qemu_put_be32s (f, &s->needed_bytes);
1235 qemu_put_be32s (f, &s->cmd);
1236 qemu_put_be32s (f, &s->use_hdma);
1237 qemu_put_be32s (f, &s->highspeed);
1238 qemu_put_be32s (f, &s->can_write);
1239 qemu_put_be32s (f, &s->v2x6);
1241 qemu_put_8s (f, &s->csp_param);
1242 qemu_put_8s (f, &s->csp_value);
1243 qemu_put_8s (f, &s->csp_mode);
1244 qemu_put_8s (f, &s->csp_param);
1245 qemu_put_buffer (f, s->csp_regs, 256);
1246 qemu_put_8s (f, &s->csp_index);
1247 qemu_put_buffer (f, s->csp_reg83, 4);
1248 qemu_put_be32s (f, &s->csp_reg83r);
1249 qemu_put_be32s (f, &s->csp_reg83w);
1251 qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1252 qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1253 qemu_put_8s (f, &s->test_reg);
1254 qemu_put_8s (f, &s->last_read_byte);
1256 qemu_put_be32s (f, &s->nzero);
1257 qemu_put_be32s (f, &s->left_till_irq);
1258 qemu_put_be32s (f, &s->dma_running);
1259 qemu_put_be32s (f, &s->bytes_per_second);
1260 qemu_put_be32s (f, &s->align);
1262 qemu_put_be32s (f, &s->mixer_nreg);
1263 qemu_put_buffer (f, s->mixer_regs, 256);
1266 static int SB_load (QEMUFile *f, void *opaque, int version_id)
1268 SB16State *s = opaque;
1270 if (version_id != 1) {
1274 qemu_get_be32s (f, &s->irq);
1275 qemu_get_be32s (f, &s->dma);
1276 qemu_get_be32s (f, &s->hdma);
1277 qemu_get_be32s (f, &s->port);
1278 qemu_get_be32s (f, &s->ver);
1279 qemu_get_be32s (f, &s->in_index);
1280 qemu_get_be32s (f, &s->out_data_len);
1281 qemu_get_be32s (f, &s->fmt_stereo);
1282 qemu_get_be32s (f, &s->fmt_signed);
1283 qemu_get_be32s (f, &s->fmt_bits);
1284 qemu_get_be32s (f, &s->fmt);
1285 qemu_get_be32s (f, &s->dma_auto);
1286 qemu_get_be32s (f, &s->block_size);
1287 qemu_get_be32s (f, &s->fifo);
1288 qemu_get_be32s (f, &s->freq);
1289 qemu_get_be32s (f, &s->time_const);
1290 qemu_get_be32s (f, &s->speaker);
1291 qemu_get_be32s (f, &s->needed_bytes);
1292 qemu_get_be32s (f, &s->cmd);
1293 qemu_get_be32s (f, &s->use_hdma);
1294 qemu_get_be32s (f, &s->highspeed);
1295 qemu_get_be32s (f, &s->can_write);
1296 qemu_get_be32s (f, &s->v2x6);
1298 qemu_get_8s (f, &s->csp_param);
1299 qemu_get_8s (f, &s->csp_value);
1300 qemu_get_8s (f, &s->csp_mode);
1301 qemu_get_8s (f, &s->csp_param);
1302 qemu_get_buffer (f, s->csp_regs, 256);
1303 qemu_get_8s (f, &s->csp_index);
1304 qemu_get_buffer (f, s->csp_reg83, 4);
1305 qemu_get_be32s (f, &s->csp_reg83r);
1306 qemu_get_be32s (f, &s->csp_reg83w);
1308 qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1309 qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1310 qemu_get_8s (f, &s->test_reg);
1311 qemu_get_8s (f, &s->last_read_byte);
1313 qemu_get_be32s (f, &s->nzero);
1314 qemu_get_be32s (f, &s->left_till_irq);
1315 qemu_get_be32s (f, &s->dma_running);
1316 qemu_get_be32s (f, &s->bytes_per_second);
1317 qemu_get_be32s (f, &s->align);
1319 qemu_get_be32s (f, &s->mixer_nreg);
1320 qemu_get_buffer (f, s->mixer_regs, 256);
1323 AUD_close_out (&s->card, s->voice);
1327 if (s->dma_running) {
1334 as.nchannels = 1 << s->fmt_stereo;
1337 s->voice = AUD_open_out (
1348 speaker (s, s->speaker);
1353 int SB16_init (AudioState *audio)
1357 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1358 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1361 dolog ("No audio state\n");
1365 s = qemu_mallocz (sizeof (*s));
1367 dolog ("Could not allocate memory for SB16 (%d bytes)\n",
1375 s->hdma = conf.hdma;
1376 s->port = conf.port;
1377 s->ver = conf.ver_lo | (conf.ver_hi << 8);
1379 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1380 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1381 s->mixer_regs[0x82] = 2 << 5;
1384 s->csp_regs[9] = 0xf8;
1387 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1389 dolog ("warning: Could not create auxiliary timer\n");
1392 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1393 register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1396 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1397 register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1400 register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1401 register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1402 register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1403 register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1405 DMA_register_channel (s->hdma, SB_read_DMA, s);
1406 DMA_register_channel (s->dma, SB_read_DMA, s);
1409 register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1410 AUD_register_card (audio, "sb16", &s->card);