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 continue_dma8 (SB16State *s)
204 as.nchannels = 1 << s->fmt_stereo;
207 s->voice = AUD_open_out (
214 0 /* little endian */
221 static void dma_cmd8 (SB16State *s, int mask, int dma_len)
227 s->fmt_stereo = (s->mixer_regs[0x0e] & 2) != 0;
228 if (-1 == s->time_const) {
233 int tmp = (256 - s->time_const);
234 s->freq = (1000000 + (tmp / 2)) / tmp;
238 s->block_size = dma_len << s->fmt_stereo;
241 /* This is apparently the only way to make both Act1/PL
242 and SecondReality/FC work
244 Act1 sets block size via command 0x48 and it's an odd number
245 SR does the same with even number
246 Both use stereo, and Creatives own documentation states that
247 0x48 sets block size in bytes less one.. go figure */
248 s->block_size &= ~s->fmt_stereo;
251 s->freq >>= s->fmt_stereo;
252 s->left_till_irq = s->block_size;
253 s->bytes_per_second = (s->freq << s->fmt_stereo);
254 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
255 s->dma_auto = (mask & DMA8_AUTO) != 0;
256 s->align = (1 << s->fmt_stereo) - 1;
258 if (s->block_size & s->align) {
259 dolog ("warning: misaligned block size %d, alignment %d\n",
260 s->block_size, s->align + 1);
263 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
264 "dma %d, auto %d, fifo %d, high %d\n",
265 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
266 s->block_size, s->dma_auto, s->fifo, s->highspeed);
272 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
274 s->use_hdma = cmd < 0xc0;
275 s->fifo = (cmd >> 1) & 1;
276 s->dma_auto = (cmd >> 2) & 1;
277 s->fmt_signed = (d0 >> 4) & 1;
278 s->fmt_stereo = (d0 >> 5) & 1;
290 if (-1 != s->time_const) {
292 int tmp = 256 - s->time_const;
293 s->freq = (1000000 + (tmp / 2)) / tmp;
295 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
296 s->freq = 1000000 / ((255 - s->time_const));
301 s->block_size = dma_len + 1;
302 s->block_size <<= (s->fmt_bits == 16);
304 /* It is clear that for DOOM and auto-init this value
305 shouldn't take stereo into account, while Miles Sound Systems
306 setsound.exe with single transfer mode wouldn't work without it
307 wonders of SB16 yet again */
308 s->block_size <<= s->fmt_stereo;
311 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
312 "dma %d, auto %d, fifo %d, high %d\n",
313 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
314 s->block_size, s->dma_auto, s->fifo, s->highspeed);
316 if (16 == s->fmt_bits) {
318 s->fmt = AUD_FMT_S16;
321 s->fmt = AUD_FMT_U16;
333 s->left_till_irq = s->block_size;
335 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
337 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
338 if (s->block_size & s->align) {
339 dolog ("warning: misaligned block size %d, alignment %d\n",
340 s->block_size, s->align + 1);
349 as.nchannels = 1 << s->fmt_stereo;
352 s->voice = AUD_open_out (
359 0 /* little endian */
367 static inline void dsp_out_data (SB16State *s, uint8_t val)
369 ldebug ("outdata %#x\n", val);
370 if ((size_t) s->out_data_len < sizeof (s->out_data)) {
371 s->out_data[s->out_data_len++] = val;
375 static inline uint8_t dsp_get_data (SB16State *s)
378 return s->in2_data[--s->in_index];
381 dolog ("buffer underflow\n");
386 static void command (SB16State *s, uint8_t cmd)
388 ldebug ("command %#x\n", cmd);
390 if (cmd > 0xaf && cmd < 0xd0) {
392 dolog ("ADC not yet supported (command %#x)\n", cmd);
400 dolog ("%#x wrong bits\n", cmd);
409 dsp_out_data (s, 0x10); /* s->csp_param); */
421 /* __asm__ ("int3"); */
429 dsp_out_data (s, 0xf8);
445 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
446 dma_cmd8 (s, DMA8_AUTO, -1);
449 case 0x20: /* Direct ADC, Juice/PL */
450 dsp_out_data (s, 0xff);
454 dolog ("0x35 - MIDI command not implemented\n");
476 dsp_out_data (s, 0xaa);
479 case 0x47: /* Continue Auto-Initialize DMA 16bit */
487 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
488 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
491 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
493 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
496 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
498 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
501 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
503 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
507 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
508 dolog ("not implemented\n");
513 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
515 dolog ("not implemented\n");
524 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
527 case 0xd0: /* halt DMA operation. 8bit */
531 case 0xd1: /* speaker on */
535 case 0xd3: /* speaker off */
539 case 0xd4: /* continue DMA operation. 8bit */
540 /* KQ6 (or maybe Sierras audblst.drv in general) resets
541 the frequency between halt/continue */
545 case 0xd5: /* halt DMA operation. 16bit */
549 case 0xd6: /* continue DMA operation. 16bit */
553 case 0xd9: /* exit auto-init DMA after this block. 16bit */
557 case 0xda: /* exit auto-init DMA after this block. 8bit */
561 case 0xe0: /* DSP identification */
566 dsp_out_data (s, s->ver & 0xff);
567 dsp_out_data (s, s->ver >> 8);
577 for (i = sizeof (e3) - 1; i >= 0; --i)
578 dsp_out_data (s, e3[i]);
582 case 0xe4: /* write test reg */
587 dolog ("Attempt to probe for ESS (0xe7)?\n");
590 case 0xe8: /* read test reg */
591 dsp_out_data (s, s->test_reg);
596 dsp_out_data (s, 0xaa);
597 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
598 pic_set_irq (s->irq, 1);
609 case 0xfc: /* FIXME */
614 dolog ("Unrecognized command %#x\n", cmd);
619 if (!s->needed_bytes) {
624 if (!s->needed_bytes) {
633 dolog ("warning: command %#x,%d is not truly understood yet\n",
634 cmd, s->needed_bytes);
639 static uint16_t dsp_get_lohi (SB16State *s)
641 uint8_t hi = dsp_get_data (s);
642 uint8_t lo = dsp_get_data (s);
643 return (hi << 8) | lo;
646 static uint16_t dsp_get_hilo (SB16State *s)
648 uint8_t lo = dsp_get_data (s);
649 uint8_t hi = dsp_get_data (s);
650 return (hi << 8) | lo;
653 static void complete (SB16State *s)
656 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
657 s->cmd, s->in_index, s->needed_bytes);
659 if (s->cmd > 0xaf && s->cmd < 0xd0) {
660 d2 = dsp_get_data (s);
661 d1 = dsp_get_data (s);
662 d0 = dsp_get_data (s);
665 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
669 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
671 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
677 s->csp_mode = dsp_get_data (s);
680 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
684 s->csp_param = dsp_get_data (s);
685 s->csp_value = dsp_get_data (s);
686 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
692 d0 = dsp_get_data (s);
693 d1 = dsp_get_data (s);
694 ldebug ("write CSP register %d <- %#x\n", d1, d0);
696 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
697 s->csp_reg83[s->csp_reg83r % 4] = d0;
701 s->csp_regs[d1] = d0;
706 d0 = dsp_get_data (s);
707 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
708 d0, s->csp_regs[d0], s->csp_mode);
710 ldebug ("0x83[%d] -> %#x\n",
712 s->csp_reg83[s->csp_reg83w % 4]);
713 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
717 dsp_out_data (s, s->csp_regs[d0]);
722 d0 = dsp_get_data (s);
723 dolog ("cmd 0x10 d0=%#x\n", d0);
727 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
731 s->time_const = dsp_get_data (s);
732 ldebug ("set time const %d\n", s->time_const);
735 case 0x42: /* FT2 sets output freq with this, go figure */
737 dolog ("cmd 0x42 might not do what it think it should\n");
740 s->freq = dsp_get_hilo (s);
741 ldebug ("set freq %d\n", s->freq);
745 s->block_size = dsp_get_lohi (s) + 1;
746 ldebug ("set dma block len %d\n", s->block_size);
753 /* ADPCM stuff, ignore */
758 int freq, samples, bytes;
761 freq = s->freq > 0 ? s->freq : 11025;
762 samples = dsp_get_lohi (s) + 1;
763 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
764 ticks = (bytes * ticks_per_sec) / freq;
765 if (ticks < ticks_per_sec / 1024) {
766 pic_set_irq (s->irq, 1);
772 qemu_get_clock (vm_clock) + ticks
776 ldebug ("mix silence %d %d %" PRId64 "\n", samples, bytes, ticks);
781 d0 = dsp_get_data (s);
783 ldebug ("E0 data = %#x\n", d0);
784 dsp_out_data (s, ~d0);
788 d0 = dsp_get_data (s);
789 ldebug ("E2 = %#x\n", d0);
793 s->test_reg = dsp_get_data (s);
797 d0 = dsp_get_data (s);
798 ldebug ("command 0xf9 with %#x\n", d0);
801 dsp_out_data (s, 0xff);
805 dsp_out_data (s, 0x07);
809 dsp_out_data (s, 0x38);
813 dsp_out_data (s, 0x00);
819 dolog ("complete: unrecognized command %#x\n", s->cmd);
829 static void legacy_reset (SB16State *s)
842 s->voice = AUD_open_out (
849 0 /* little endian */
852 /* Not sure about that... */
853 /* AUD_set_active_out (s->voice, 1); */
856 static void reset (SB16State *s)
858 pic_set_irq (s->irq, 0);
860 pic_set_irq (s->irq, 1);
861 pic_set_irq (s->irq, 0);
864 s->mixer_regs[0x82] = 0;
868 s->left_till_irq = 0;
876 dsp_out_data(s, 0xaa);
882 static IO_WRITE_PROTO (dsp_write)
884 SB16State *s = opaque;
887 iport = nport - s->port;
889 ldebug ("write %#x <- %#x\n", nport, val);
895 if (0 && s->highspeed) {
897 pic_set_irq (s->irq, 0);
908 case 0x03: /* FreeBSD kludge */
913 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
916 case 0xb8: /* Panic */
921 dsp_out_data (s, 0x38);
932 case 0x0c: /* write data or command | write status */
933 /* if (s->highspeed) */
936 if (0 == s->needed_bytes) {
939 if (0 == s->needed_bytes) {
945 if (s->in_index == sizeof (s->in2_data)) {
946 dolog ("in data overrun\n");
949 s->in2_data[s->in_index++] = val;
950 if (s->in_index == s->needed_bytes) {
962 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
967 static IO_READ_PROTO (dsp_read)
969 SB16State *s = opaque;
970 int iport, retval, ack = 0;
972 iport = nport - s->port;
975 case 0x06: /* reset */
979 case 0x0a: /* read data */
980 if (s->out_data_len) {
981 retval = s->out_data[--s->out_data_len];
982 s->last_read_byte = retval;
986 dolog ("empty output buffer for command %#x\n",
989 retval = s->last_read_byte;
994 case 0x0c: /* 0 can write */
995 retval = s->can_write ? 0 : 0x80;
998 case 0x0d: /* timer interrupt clear */
999 /* dolog ("timer interrupt clear\n"); */
1003 case 0x0e: /* data available status | irq 8 ack */
1004 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
1005 if (s->mixer_regs[0x82] & 1) {
1007 s->mixer_regs[0x82] &= 1;
1008 pic_set_irq (s->irq, 0);
1012 case 0x0f: /* irq 16 ack */
1014 if (s->mixer_regs[0x82] & 2) {
1016 s->mixer_regs[0x82] &= 2;
1017 pic_set_irq (s->irq, 0);
1026 ldebug ("read %#x -> %#x\n", nport, retval);
1032 dolog ("warning: dsp_read %#x error\n", nport);
1036 static void reset_mixer (SB16State *s)
1040 memset (s->mixer_regs, 0xff, 0x7f);
1041 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1043 s->mixer_regs[0x02] = 4; /* master volume 3bits */
1044 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
1045 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
1046 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1048 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1049 s->mixer_regs[0x0c] = 0;
1051 /* d5=output filt, d1=stereo switch */
1052 s->mixer_regs[0x0e] = 0;
1054 /* voice volume L d5,d7, R d1,d3 */
1055 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1057 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1059 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1061 for (i = 0x30; i < 0x48; i++) {
1062 s->mixer_regs[i] = 0x20;
1066 static IO_WRITE_PROTO(mixer_write_indexb)
1068 SB16State *s = opaque;
1070 s->mixer_nreg = val;
1073 static IO_WRITE_PROTO(mixer_write_datab)
1075 SB16State *s = opaque;
1078 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1080 switch (s->mixer_nreg) {
1087 int irq = irq_of_magic (val);
1088 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1099 dma = lsbindex (val & 0xf);
1100 hdma = lsbindex (val & 0xf0);
1101 if (dma != s->dma || hdma != s->hdma) {
1103 "attempt to change DMA "
1104 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1105 dma, s->dma, hdma, s->hdma, val);
1115 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1120 if (s->mixer_nreg >= 0x80) {
1121 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1126 s->mixer_regs[s->mixer_nreg] = val;
1129 static IO_WRITE_PROTO(mixer_write_indexw)
1131 mixer_write_indexb (opaque, nport, val & 0xff);
1132 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1135 static IO_READ_PROTO(mixer_read)
1137 SB16State *s = opaque;
1140 #ifndef DEBUG_SB16_MOST
1141 if (s->mixer_nreg != 0x82) {
1142 ldebug ("mixer_read[%#x] -> %#x\n",
1143 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1146 ldebug ("mixer_read[%#x] -> %#x\n",
1147 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1149 return s->mixer_regs[s->mixer_nreg];
1152 static int write_audio (SB16State *s, int nchan, int dma_pos,
1153 int dma_len, int len)
1156 uint8_t tmpbuf[4096];
1162 int left = dma_len - dma_pos;
1166 to_copy = audio_MIN (temp, left);
1167 if (to_copy > sizeof (tmpbuf)) {
1168 to_copy = sizeof (tmpbuf);
1171 copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1172 copied = AUD_write (s->voice, tmpbuf, copied);
1175 dma_pos = (dma_pos + copied) % dma_len;
1186 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1188 SB16State *s = opaque;
1189 int till, copy, written, free;
1191 if (s->left_till_irq < 0) {
1192 s->left_till_irq = s->block_size;
1196 free = s->audio_free & ~s->align;
1197 if ((free <= 0) || !dma_len) {
1206 till = s->left_till_irq;
1208 #ifdef DEBUG_SB16_MOST
1209 dolog ("pos:%06d %d till:%d len:%d\n",
1210 dma_pos, free, till, dma_len);
1214 if (0 == s->dma_auto) {
1219 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1220 dma_pos = (dma_pos + written) % dma_len;
1221 s->left_till_irq -= written;
1223 if (s->left_till_irq <= 0) {
1224 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1225 pic_set_irq (s->irq, 1);
1226 if (0 == s->dma_auto) {
1232 #ifdef DEBUG_SB16_MOST
1233 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1234 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1238 while (s->left_till_irq <= 0) {
1239 s->left_till_irq = s->block_size + s->left_till_irq;
1245 static void SB_audio_callback (void *opaque, int free)
1247 SB16State *s = opaque;
1248 s->audio_free = free;
1251 static void SB_save (QEMUFile *f, void *opaque)
1253 SB16State *s = opaque;
1255 qemu_put_be32s (f, &s->irq);
1256 qemu_put_be32s (f, &s->dma);
1257 qemu_put_be32s (f, &s->hdma);
1258 qemu_put_be32s (f, &s->port);
1259 qemu_put_be32s (f, &s->ver);
1260 qemu_put_be32s (f, &s->in_index);
1261 qemu_put_be32s (f, &s->out_data_len);
1262 qemu_put_be32s (f, &s->fmt_stereo);
1263 qemu_put_be32s (f, &s->fmt_signed);
1264 qemu_put_be32s (f, &s->fmt_bits);
1265 qemu_put_be32s (f, &s->fmt);
1266 qemu_put_be32s (f, &s->dma_auto);
1267 qemu_put_be32s (f, &s->block_size);
1268 qemu_put_be32s (f, &s->fifo);
1269 qemu_put_be32s (f, &s->freq);
1270 qemu_put_be32s (f, &s->time_const);
1271 qemu_put_be32s (f, &s->speaker);
1272 qemu_put_be32s (f, &s->needed_bytes);
1273 qemu_put_be32s (f, &s->cmd);
1274 qemu_put_be32s (f, &s->use_hdma);
1275 qemu_put_be32s (f, &s->highspeed);
1276 qemu_put_be32s (f, &s->can_write);
1277 qemu_put_be32s (f, &s->v2x6);
1279 qemu_put_8s (f, &s->csp_param);
1280 qemu_put_8s (f, &s->csp_value);
1281 qemu_put_8s (f, &s->csp_mode);
1282 qemu_put_8s (f, &s->csp_param);
1283 qemu_put_buffer (f, s->csp_regs, 256);
1284 qemu_put_8s (f, &s->csp_index);
1285 qemu_put_buffer (f, s->csp_reg83, 4);
1286 qemu_put_be32s (f, &s->csp_reg83r);
1287 qemu_put_be32s (f, &s->csp_reg83w);
1289 qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1290 qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1291 qemu_put_8s (f, &s->test_reg);
1292 qemu_put_8s (f, &s->last_read_byte);
1294 qemu_put_be32s (f, &s->nzero);
1295 qemu_put_be32s (f, &s->left_till_irq);
1296 qemu_put_be32s (f, &s->dma_running);
1297 qemu_put_be32s (f, &s->bytes_per_second);
1298 qemu_put_be32s (f, &s->align);
1300 qemu_put_be32s (f, &s->mixer_nreg);
1301 qemu_put_buffer (f, s->mixer_regs, 256);
1304 static int SB_load (QEMUFile *f, void *opaque, int version_id)
1306 SB16State *s = opaque;
1308 if (version_id != 1) {
1312 qemu_get_be32s (f, &s->irq);
1313 qemu_get_be32s (f, &s->dma);
1314 qemu_get_be32s (f, &s->hdma);
1315 qemu_get_be32s (f, &s->port);
1316 qemu_get_be32s (f, &s->ver);
1317 qemu_get_be32s (f, &s->in_index);
1318 qemu_get_be32s (f, &s->out_data_len);
1319 qemu_get_be32s (f, &s->fmt_stereo);
1320 qemu_get_be32s (f, &s->fmt_signed);
1321 qemu_get_be32s (f, &s->fmt_bits);
1322 qemu_get_be32s (f, &s->fmt);
1323 qemu_get_be32s (f, &s->dma_auto);
1324 qemu_get_be32s (f, &s->block_size);
1325 qemu_get_be32s (f, &s->fifo);
1326 qemu_get_be32s (f, &s->freq);
1327 qemu_get_be32s (f, &s->time_const);
1328 qemu_get_be32s (f, &s->speaker);
1329 qemu_get_be32s (f, &s->needed_bytes);
1330 qemu_get_be32s (f, &s->cmd);
1331 qemu_get_be32s (f, &s->use_hdma);
1332 qemu_get_be32s (f, &s->highspeed);
1333 qemu_get_be32s (f, &s->can_write);
1334 qemu_get_be32s (f, &s->v2x6);
1336 qemu_get_8s (f, &s->csp_param);
1337 qemu_get_8s (f, &s->csp_value);
1338 qemu_get_8s (f, &s->csp_mode);
1339 qemu_get_8s (f, &s->csp_param);
1340 qemu_get_buffer (f, s->csp_regs, 256);
1341 qemu_get_8s (f, &s->csp_index);
1342 qemu_get_buffer (f, s->csp_reg83, 4);
1343 qemu_get_be32s (f, &s->csp_reg83r);
1344 qemu_get_be32s (f, &s->csp_reg83w);
1346 qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1347 qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1348 qemu_get_8s (f, &s->test_reg);
1349 qemu_get_8s (f, &s->last_read_byte);
1351 qemu_get_be32s (f, &s->nzero);
1352 qemu_get_be32s (f, &s->left_till_irq);
1353 qemu_get_be32s (f, &s->dma_running);
1354 qemu_get_be32s (f, &s->bytes_per_second);
1355 qemu_get_be32s (f, &s->align);
1357 qemu_get_be32s (f, &s->mixer_nreg);
1358 qemu_get_buffer (f, s->mixer_regs, 256);
1361 AUD_close_out (&s->card, s->voice);
1365 if (s->dma_running) {
1372 as.nchannels = 1 << s->fmt_stereo;
1375 s->voice = AUD_open_out (
1382 0 /* little endian */
1387 speaker (s, s->speaker);
1392 int SB16_init (AudioState *audio)
1396 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1397 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1400 dolog ("No audio state\n");
1404 s = qemu_mallocz (sizeof (*s));
1406 dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
1414 s->hdma = conf.hdma;
1415 s->port = conf.port;
1416 s->ver = conf.ver_lo | (conf.ver_hi << 8);
1418 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1419 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1420 s->mixer_regs[0x82] = 2 << 5;
1423 s->csp_regs[9] = 0xf8;
1426 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1428 dolog ("warning: Could not create auxiliary timer\n");
1431 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1432 register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1435 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1436 register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1439 register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1440 register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1441 register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1442 register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1444 DMA_register_channel (s->hdma, SB_read_DMA, s);
1445 DMA_register_channel (s->dma, SB_read_DMA, s);
1448 register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1449 AUD_register_card (audio, "sb16", &s->card);