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 {
85 uint8_t csp_regs[256];
94 uint8_t last_read_byte;
100 int bytes_per_second;
108 uint8_t mixer_regs[256];
111 /* XXX: suppress that and use a context */
112 static struct SB16State dsp;
114 static void SB_audio_callback (void *opaque, int free);
116 static int magic_of_irq (int irq)
128 dolog ("bad irq %d\n", irq);
133 static int irq_of_magic (int magic)
145 dolog ("bad irq magic %d\n", magic);
151 static void log_dsp (SB16State *dsp)
153 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
154 dsp->fmt_stereo ? "Stereo" : "Mono",
155 dsp->fmt_signed ? "Signed" : "Unsigned",
157 dsp->dma_auto ? "Auto" : "Single",
165 static void speaker (SB16State *s, int on)
168 /* AUD_enable (s->voice, on); */
171 static void control (SB16State *s, int hold)
173 int dma = s->use_hdma ? s->hdma : s->dma;
174 s->dma_running = hold;
176 ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma);
180 AUD_set_active_out (s->voice, 1);
183 DMA_release_DREQ (dma);
184 AUD_set_active_out (s->voice, 0);
188 static void aux_timer (void *opaque)
190 SB16State *s = opaque;
192 pic_set_irq (s->irq, 1);
198 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
204 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
205 if (-1 == s->time_const) {
209 int tmp = (256 - s->time_const);
210 s->freq = (1000000 + (tmp / 2)) / tmp;
214 s->block_size = dma_len << s->fmt_stereo;
217 /* This is apparently the only way to make both Act1/PL
218 and SecondReality/FC work
220 Act1 sets block size via command 0x48 and it's an odd number
221 SR does the same with even number
222 Both use stereo, and Creatives own documentation states that
223 0x48 sets block size in bytes less one.. go figure */
224 s->block_size &= ~s->fmt_stereo;
227 s->freq >>= s->fmt_stereo;
228 s->left_till_irq = s->block_size;
229 s->bytes_per_second = (s->freq << s->fmt_stereo);
230 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
231 s->dma_auto = (mask & DMA8_AUTO) != 0;
232 s->align = (1 << s->fmt_stereo) - 1;
234 if (s->block_size & s->align) {
235 dolog ("warning: misaligned block size %d, alignment %d\n",
236 s->block_size, s->align + 1);
239 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
240 "dma %d, auto %d, fifo %d, high %d\n",
241 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
242 s->block_size, s->dma_auto, s->fifo, s->highspeed);
246 s->voice = AUD_open_out (
261 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
263 s->use_hdma = cmd < 0xc0;
264 s->fifo = (cmd >> 1) & 1;
265 s->dma_auto = (cmd >> 2) & 1;
266 s->fmt_signed = (d0 >> 4) & 1;
267 s->fmt_stereo = (d0 >> 5) & 1;
279 if (-1 != s->time_const) {
281 int tmp = 256 - s->time_const;
282 s->freq = (1000000 + (tmp / 2)) / tmp;
284 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
285 s->freq = 1000000 / ((255 - s->time_const));
290 s->block_size = dma_len + 1;
291 s->block_size <<= (s->fmt_bits == 16);
293 /* It is clear that for DOOM and auto-init this value
294 shouldn't take stereo into account, while Miles Sound Systems
295 setsound.exe with single transfer mode wouldn't work without it
296 wonders of SB16 yet again */
297 s->block_size <<= s->fmt_stereo;
300 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
301 "dma %d, auto %d, fifo %d, high %d\n",
302 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
303 s->block_size, s->dma_auto, s->fifo, s->highspeed);
305 if (16 == s->fmt_bits) {
307 s->fmt = AUD_FMT_S16;
310 s->fmt = AUD_FMT_U16;
322 s->left_till_irq = s->block_size;
324 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
326 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
327 if (s->block_size & s->align) {
328 dolog ("warning: misaligned block size %d, alignment %d\n",
329 s->block_size, s->align + 1);
334 s->voice = AUD_open_out (
349 static inline void dsp_out_data (SB16State *s, uint8_t val)
351 ldebug ("outdata %#x\n", val);
352 if (s->out_data_len < sizeof (s->out_data)) {
353 s->out_data[s->out_data_len++] = val;
357 static inline uint8_t dsp_get_data (SB16State *s)
360 return s->in2_data[--s->in_index];
363 dolog ("buffer underflow\n");
368 static void command (SB16State *s, uint8_t cmd)
370 ldebug ("command %#x\n", cmd);
372 if (cmd > 0xaf && cmd < 0xd0) {
374 dolog ("ADC not yet supported (command %#x)\n", cmd);
382 dolog ("%#x wrong bits\n", cmd);
391 dsp_out_data (s, 0x10); /* s->csp_param); */
403 /* __asm__ ("int3"); */
411 dsp_out_data (s, 0xf8);
427 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
431 case 0x20: /* Direct ADC, Juice/PL */
432 dsp_out_data (s, 0xff);
436 dolog ("0x35 - MIDI command not implemented\n");
458 dsp_out_data (s, 0xaa);
461 case 0x47: /* Continue Auto-Initialize DMA 16bit */
469 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
470 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
473 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
475 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
478 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
480 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
483 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
485 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
489 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
490 dolog ("not implemented\n");
495 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
497 dolog ("not implemented\n");
506 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
509 case 0xd0: /* halt DMA operation. 8bit */
513 case 0xd1: /* speaker on */
517 case 0xd3: /* speaker off */
521 case 0xd4: /* continue DMA operation. 8bit */
525 case 0xd5: /* halt DMA operation. 16bit */
529 case 0xd6: /* continue DMA operation. 16bit */
533 case 0xd9: /* exit auto-init DMA after this block. 16bit */
537 case 0xda: /* exit auto-init DMA after this block. 8bit */
541 case 0xe0: /* DSP identification */
546 dsp_out_data (s, s->ver & 0xff);
547 dsp_out_data (s, s->ver >> 8);
557 for (i = sizeof (e3) - 1; i >= 0; --i)
558 dsp_out_data (s, e3[i]);
562 case 0xe4: /* write test reg */
567 dolog ("Attempt to probe for ESS (0xe7)?\n");
570 case 0xe8: /* read test reg */
571 dsp_out_data (s, s->test_reg);
576 dsp_out_data (s, 0xaa);
577 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
578 pic_set_irq (s->irq, 1);
589 case 0xfc: /* FIXME */
594 dolog ("Unrecognized command %#x\n", cmd);
599 if (!s->needed_bytes) {
604 if (!s->needed_bytes) {
613 dolog ("warning: command %#x,%d is not truly understood yet\n",
614 cmd, s->needed_bytes);
619 static uint16_t dsp_get_lohi (SB16State *s)
621 uint8_t hi = dsp_get_data (s);
622 uint8_t lo = dsp_get_data (s);
623 return (hi << 8) | lo;
626 static uint16_t dsp_get_hilo (SB16State *s)
628 uint8_t lo = dsp_get_data (s);
629 uint8_t hi = dsp_get_data (s);
630 return (hi << 8) | lo;
633 static void complete (SB16State *s)
636 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
637 s->cmd, s->in_index, s->needed_bytes);
639 if (s->cmd > 0xaf && s->cmd < 0xd0) {
640 d2 = dsp_get_data (s);
641 d1 = dsp_get_data (s);
642 d0 = dsp_get_data (s);
645 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
649 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
651 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
657 s->csp_mode = dsp_get_data (s);
660 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
664 s->csp_param = dsp_get_data (s);
665 s->csp_value = dsp_get_data (s);
666 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
672 d0 = dsp_get_data (s);
673 d1 = dsp_get_data (s);
674 ldebug ("write CSP register %d <- %#x\n", d1, d0);
676 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
677 s->csp_reg83[s->csp_reg83r % 4] = d0;
681 s->csp_regs[d1] = d0;
686 d0 = dsp_get_data (s);
687 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
688 d0, s->csp_regs[d0], s->csp_mode);
690 ldebug ("0x83[%d] -> %#x\n",
692 s->csp_reg83[s->csp_reg83w % 4]);
693 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
697 dsp_out_data (s, s->csp_regs[d0]);
702 d0 = dsp_get_data (s);
703 dolog ("cmd 0x10 d0=%#x\n", d0);
707 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
711 s->time_const = dsp_get_data (s);
712 ldebug ("set time const %d\n", s->time_const);
715 case 0x42: /* FT2 sets output freq with this, go figure */
717 dolog ("cmd 0x42 might not do what it think it should\n");
720 s->freq = dsp_get_hilo (s);
721 ldebug ("set freq %d\n", s->freq);
725 s->block_size = dsp_get_lohi (s) + 1;
726 ldebug ("set dma block len %d\n", s->block_size);
733 /* ADPCM stuff, ignore */
738 int freq, samples, bytes;
741 freq = s->freq > 0 ? s->freq : 11025;
742 samples = dsp_get_lohi (s) + 1;
743 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
744 ticks = (bytes * ticks_per_sec) / freq;
745 if (ticks < ticks_per_sec / 1024) {
746 pic_set_irq (s->irq, 1);
752 qemu_get_clock (vm_clock) + ticks
756 ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
761 d0 = dsp_get_data (s);
763 ldebug ("E0 data = %#x\n", d0);
764 dsp_out_data (s, ~d0);
768 d0 = dsp_get_data (s);
769 ldebug ("E2 = %#x\n", d0);
773 s->test_reg = dsp_get_data (s);
777 d0 = dsp_get_data (s);
778 ldebug ("command 0xf9 with %#x\n", d0);
781 dsp_out_data (s, 0xff);
785 dsp_out_data (s, 0x07);
789 dsp_out_data (s, 0x38);
793 dsp_out_data (s, 0x00);
799 dolog ("complete: unrecognized command %#x\n", s->cmd);
809 static void reset (SB16State *s)
811 pic_set_irq (s->irq, 0);
813 pic_set_irq (s->irq, 1);
814 pic_set_irq (s->irq, 0);
817 s->mixer_regs[0x82] = 0;
821 s->left_till_irq = 0;
829 dsp_out_data(s, 0xaa);
834 static IO_WRITE_PROTO (dsp_write)
836 SB16State *s = opaque;
839 iport = nport - s->port;
841 ldebug ("write %#x <- %#x\n", nport, val);
847 if (0 && s->highspeed) {
849 pic_set_irq (s->irq, 0);
860 case 0x03: /* FreeBSD kludge */
865 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
868 case 0xb8: /* Panic */
873 dsp_out_data (s, 0x38);
884 case 0x0c: /* write data or command | write status */
885 /* if (s->highspeed) */
888 if (0 == s->needed_bytes) {
891 if (0 == s->needed_bytes) {
897 if (s->in_index == sizeof (s->in2_data)) {
898 dolog ("in data overrun\n");
901 s->in2_data[s->in_index++] = val;
902 if (s->in_index == s->needed_bytes) {
914 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
919 static IO_READ_PROTO (dsp_read)
921 SB16State *s = opaque;
922 int iport, retval, ack = 0;
924 iport = nport - s->port;
927 case 0x06: /* reset */
931 case 0x0a: /* read data */
932 if (s->out_data_len) {
933 retval = s->out_data[--s->out_data_len];
934 s->last_read_byte = retval;
938 dolog ("empty output buffer for command %#x\n",
941 retval = s->last_read_byte;
946 case 0x0c: /* 0 can write */
947 retval = s->can_write ? 0 : 0x80;
950 case 0x0d: /* timer interrupt clear */
951 /* dolog ("timer interrupt clear\n"); */
955 case 0x0e: /* data available status | irq 8 ack */
956 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
957 if (s->mixer_regs[0x82] & 1) {
959 s->mixer_regs[0x82] &= 1;
960 pic_set_irq (s->irq, 0);
964 case 0x0f: /* irq 16 ack */
966 if (s->mixer_regs[0x82] & 2) {
968 s->mixer_regs[0x82] &= 2;
969 pic_set_irq (s->irq, 0);
978 ldebug ("read %#x -> %#x\n", nport, retval);
984 dolog ("warning: dsp_read %#x error\n", nport);
988 static void reset_mixer (SB16State *s)
992 memset (s->mixer_regs, 0xff, 0x7f);
993 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
995 s->mixer_regs[0x02] = 4; /* master volume 3bits */
996 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
997 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
998 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1000 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1001 s->mixer_regs[0x0c] = 0;
1003 /* d5=output filt, d1=stereo switch */
1004 s->mixer_regs[0x0e] = 0;
1006 /* voice volume L d5,d7, R d1,d3 */
1007 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1009 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1011 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1013 for (i = 0x30; i < 0x48; i++) {
1014 s->mixer_regs[i] = 0x20;
1018 static IO_WRITE_PROTO(mixer_write_indexb)
1020 SB16State *s = opaque;
1021 s->mixer_nreg = val;
1024 static IO_WRITE_PROTO(mixer_write_datab)
1026 SB16State *s = opaque;
1028 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1029 if (s->mixer_nreg > sizeof (s->mixer_regs)) {
1033 switch (s->mixer_nreg) {
1040 int irq = irq_of_magic (val);
1041 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1052 dma = lsbindex (val & 0xf);
1053 hdma = lsbindex (val & 0xf0);
1054 if (dma != s->dma || hdma != s->hdma) {
1056 "attempt to change DMA "
1057 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1058 dma, s->dma, hdma, s->hdma, val);
1068 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1073 if (s->mixer_nreg >= 0x80) {
1074 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1079 s->mixer_regs[s->mixer_nreg] = val;
1082 static IO_WRITE_PROTO(mixer_write_indexw)
1084 mixer_write_indexb (opaque, nport, val & 0xff);
1085 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1088 static IO_READ_PROTO(mixer_read)
1090 SB16State *s = opaque;
1091 #ifndef DEBUG_SB16_MOST
1092 if (s->mixer_nreg != 0x82) {
1093 ldebug ("mixer_read[%#x] -> %#x\n",
1094 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1097 ldebug ("mixer_read[%#x] -> %#x\n",
1098 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1100 return s->mixer_regs[s->mixer_nreg];
1103 static int write_audio (SB16State *s, int nchan, int dma_pos,
1104 int dma_len, int len)
1107 uint8_t tmpbuf[4096];
1113 int left = dma_len - dma_pos;
1114 int to_copy, copied;
1116 to_copy = audio_MIN (temp, left);
1117 if (to_copy > sizeof(tmpbuf)) {
1118 to_copy = sizeof(tmpbuf);
1121 copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1122 copied = AUD_write (s->voice, tmpbuf, copied);
1125 dma_pos = (dma_pos + copied) % dma_len;
1136 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1138 SB16State *s = opaque;
1139 int till, copy, written, free;
1141 if (s->left_till_irq < 0) {
1142 s->left_till_irq = s->block_size;
1146 free = s->audio_free & ~s->align;
1147 if ((free <= 0) || !dma_len) {
1156 till = s->left_till_irq;
1158 #ifdef DEBUG_SB16_MOST
1159 dolog ("pos:%06d %d till:%d len:%d\n",
1160 dma_pos, free, till, dma_len);
1164 if (0 == s->dma_auto) {
1169 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1170 dma_pos = (dma_pos + written) % dma_len;
1171 s->left_till_irq -= written;
1173 if (s->left_till_irq <= 0) {
1174 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1175 pic_set_irq (s->irq, 1);
1176 if (0 == s->dma_auto) {
1182 #ifdef DEBUG_SB16_MOST
1183 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1184 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1188 while (s->left_till_irq <= 0) {
1189 s->left_till_irq = s->block_size + s->left_till_irq;
1195 static void SB_audio_callback (void *opaque, int free)
1197 SB16State *s = opaque;
1198 s->audio_free = free;
1201 static void SB_save (QEMUFile *f, void *opaque)
1203 SB16State *s = opaque;
1205 qemu_put_be32s (f, &s->irq);
1206 qemu_put_be32s (f, &s->dma);
1207 qemu_put_be32s (f, &s->hdma);
1208 qemu_put_be32s (f, &s->port);
1209 qemu_put_be32s (f, &s->ver);
1210 qemu_put_be32s (f, &s->in_index);
1211 qemu_put_be32s (f, &s->out_data_len);
1212 qemu_put_be32s (f, &s->fmt_stereo);
1213 qemu_put_be32s (f, &s->fmt_signed);
1214 qemu_put_be32s (f, &s->fmt_bits);
1215 qemu_put_be32s (f, &s->fmt);
1216 qemu_put_be32s (f, &s->dma_auto);
1217 qemu_put_be32s (f, &s->block_size);
1218 qemu_put_be32s (f, &s->fifo);
1219 qemu_put_be32s (f, &s->freq);
1220 qemu_put_be32s (f, &s->time_const);
1221 qemu_put_be32s (f, &s->speaker);
1222 qemu_put_be32s (f, &s->needed_bytes);
1223 qemu_put_be32s (f, &s->cmd);
1224 qemu_put_be32s (f, &s->use_hdma);
1225 qemu_put_be32s (f, &s->highspeed);
1226 qemu_put_be32s (f, &s->can_write);
1227 qemu_put_be32s (f, &s->v2x6);
1229 qemu_put_8s (f, &s->csp_param);
1230 qemu_put_8s (f, &s->csp_value);
1231 qemu_put_8s (f, &s->csp_mode);
1232 qemu_put_8s (f, &s->csp_param);
1233 qemu_put_buffer (f, s->csp_regs, 256);
1234 qemu_put_8s (f, &s->csp_index);
1235 qemu_put_buffer (f, s->csp_reg83, 4);
1236 qemu_put_be32s (f, &s->csp_reg83r);
1237 qemu_put_be32s (f, &s->csp_reg83w);
1239 qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1240 qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1241 qemu_put_8s (f, &s->test_reg);
1242 qemu_put_8s (f, &s->last_read_byte);
1244 qemu_put_be32s (f, &s->nzero);
1245 qemu_put_be32s (f, &s->left_till_irq);
1246 qemu_put_be32s (f, &s->dma_running);
1247 qemu_put_be32s (f, &s->bytes_per_second);
1248 qemu_put_be32s (f, &s->align);
1250 qemu_put_be32s (f, &s->mixer_nreg);
1251 qemu_put_buffer (f, s->mixer_regs, 256);
1254 static int SB_load (QEMUFile *f, void *opaque, int version_id)
1256 SB16State *s = opaque;
1258 if (version_id != 1) {
1262 qemu_get_be32s (f, &s->irq);
1263 qemu_get_be32s (f, &s->dma);
1264 qemu_get_be32s (f, &s->hdma);
1265 qemu_get_be32s (f, &s->port);
1266 qemu_get_be32s (f, &s->ver);
1267 qemu_get_be32s (f, &s->in_index);
1268 qemu_get_be32s (f, &s->out_data_len);
1269 qemu_get_be32s (f, &s->fmt_stereo);
1270 qemu_get_be32s (f, &s->fmt_signed);
1271 qemu_get_be32s (f, &s->fmt_bits);
1272 qemu_get_be32s (f, &s->fmt);
1273 qemu_get_be32s (f, &s->dma_auto);
1274 qemu_get_be32s (f, &s->block_size);
1275 qemu_get_be32s (f, &s->fifo);
1276 qemu_get_be32s (f, &s->freq);
1277 qemu_get_be32s (f, &s->time_const);
1278 qemu_get_be32s (f, &s->speaker);
1279 qemu_get_be32s (f, &s->needed_bytes);
1280 qemu_get_be32s (f, &s->cmd);
1281 qemu_get_be32s (f, &s->use_hdma);
1282 qemu_get_be32s (f, &s->highspeed);
1283 qemu_get_be32s (f, &s->can_write);
1284 qemu_get_be32s (f, &s->v2x6);
1286 qemu_get_8s (f, &s->csp_param);
1287 qemu_get_8s (f, &s->csp_value);
1288 qemu_get_8s (f, &s->csp_mode);
1289 qemu_get_8s (f, &s->csp_param);
1290 qemu_get_buffer (f, s->csp_regs, 256);
1291 qemu_get_8s (f, &s->csp_index);
1292 qemu_get_buffer (f, s->csp_reg83, 4);
1293 qemu_get_be32s (f, &s->csp_reg83r);
1294 qemu_get_be32s (f, &s->csp_reg83w);
1296 qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1297 qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1298 qemu_get_8s (f, &s->test_reg);
1299 qemu_get_8s (f, &s->last_read_byte);
1301 qemu_get_be32s (f, &s->nzero);
1302 qemu_get_be32s (f, &s->left_till_irq);
1303 qemu_get_be32s (f, &s->dma_running);
1304 qemu_get_be32s (f, &s->bytes_per_second);
1305 qemu_get_be32s (f, &s->align);
1307 qemu_get_be32s (f, &s->mixer_nreg);
1308 qemu_get_buffer (f, s->mixer_regs, 256);
1311 AUD_close_out (s->voice);
1315 if (s->dma_running) {
1318 s->voice = AUD_open_out (
1330 speaker (s, s->speaker);
1335 void SB16_init (void)
1337 SB16State *s = &dsp;
1339 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1340 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1345 s->hdma = conf.hdma;
1346 s->port = conf.port;
1347 s->ver = conf.ver_lo | (conf.ver_hi << 8);
1349 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1350 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1351 s->mixer_regs[0x82] = 2 << 5;
1354 s->csp_regs[9] = 0xf8;
1357 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1359 dolog ("Can not create auxiliary timer\n");
1362 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1363 register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1366 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1367 register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1370 register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1371 register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1372 register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1373 register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1375 DMA_register_channel (s->hdma, SB_read_DMA, s);
1376 DMA_register_channel (s->dma, SB_read_DMA, s);
1379 register_savevm ("sb16", 0, 1, SB_save, SB_load, s);