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 (
258 0 /* little endian */
266 static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
268 s->use_hdma = cmd < 0xc0;
269 s->fifo = (cmd >> 1) & 1;
270 s->dma_auto = (cmd >> 2) & 1;
271 s->fmt_signed = (d0 >> 4) & 1;
272 s->fmt_stereo = (d0 >> 5) & 1;
284 if (-1 != s->time_const) {
286 int tmp = 256 - s->time_const;
287 s->freq = (1000000 + (tmp / 2)) / tmp;
289 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
290 s->freq = 1000000 / ((255 - s->time_const));
295 s->block_size = dma_len + 1;
296 s->block_size <<= (s->fmt_bits == 16);
298 /* It is clear that for DOOM and auto-init this value
299 shouldn't take stereo into account, while Miles Sound Systems
300 setsound.exe with single transfer mode wouldn't work without it
301 wonders of SB16 yet again */
302 s->block_size <<= s->fmt_stereo;
305 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
306 "dma %d, auto %d, fifo %d, high %d\n",
307 s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
308 s->block_size, s->dma_auto, s->fifo, s->highspeed);
310 if (16 == s->fmt_bits) {
312 s->fmt = AUD_FMT_S16;
315 s->fmt = AUD_FMT_U16;
327 s->left_till_irq = s->block_size;
329 s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
331 s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
332 if (s->block_size & s->align) {
333 dolog ("warning: misaligned block size %d, alignment %d\n",
334 s->block_size, s->align + 1);
343 as.nchannels = 1 << s->fmt_stereo;
346 s->voice = AUD_open_out (
353 0 /* little endian */
361 static inline void dsp_out_data (SB16State *s, uint8_t val)
363 ldebug ("outdata %#x\n", val);
364 if ((size_t) s->out_data_len < sizeof (s->out_data)) {
365 s->out_data[s->out_data_len++] = val;
369 static inline uint8_t dsp_get_data (SB16State *s)
372 return s->in2_data[--s->in_index];
375 dolog ("buffer underflow\n");
380 static void command (SB16State *s, uint8_t cmd)
382 ldebug ("command %#x\n", cmd);
384 if (cmd > 0xaf && cmd < 0xd0) {
386 dolog ("ADC not yet supported (command %#x)\n", cmd);
394 dolog ("%#x wrong bits\n", cmd);
403 dsp_out_data (s, 0x10); /* s->csp_param); */
415 /* __asm__ ("int3"); */
423 dsp_out_data (s, 0xf8);
439 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
443 case 0x20: /* Direct ADC, Juice/PL */
444 dsp_out_data (s, 0xff);
448 dolog ("0x35 - MIDI command not implemented\n");
470 dsp_out_data (s, 0xaa);
473 case 0x47: /* Continue Auto-Initialize DMA 16bit */
481 s->needed_bytes = 2; /* DMA DAC, 4-bit ADPCM */
482 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
485 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
487 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
490 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
492 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
495 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
497 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
501 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
502 dolog ("not implemented\n");
507 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
509 dolog ("not implemented\n");
518 dma_cmd8 (s, ((cmd & 1) == 0) | DMA8_HIGH, -1);
521 case 0xd0: /* halt DMA operation. 8bit */
525 case 0xd1: /* speaker on */
529 case 0xd3: /* speaker off */
533 case 0xd4: /* continue DMA operation. 8bit */
537 case 0xd5: /* halt DMA operation. 16bit */
541 case 0xd6: /* continue DMA operation. 16bit */
545 case 0xd9: /* exit auto-init DMA after this block. 16bit */
549 case 0xda: /* exit auto-init DMA after this block. 8bit */
553 case 0xe0: /* DSP identification */
558 dsp_out_data (s, s->ver & 0xff);
559 dsp_out_data (s, s->ver >> 8);
569 for (i = sizeof (e3) - 1; i >= 0; --i)
570 dsp_out_data (s, e3[i]);
574 case 0xe4: /* write test reg */
579 dolog ("Attempt to probe for ESS (0xe7)?\n");
582 case 0xe8: /* read test reg */
583 dsp_out_data (s, s->test_reg);
588 dsp_out_data (s, 0xaa);
589 s->mixer_regs[0x82] |= (cmd == 0xf2) ? 1 : 2;
590 pic_set_irq (s->irq, 1);
601 case 0xfc: /* FIXME */
606 dolog ("Unrecognized command %#x\n", cmd);
611 if (!s->needed_bytes) {
616 if (!s->needed_bytes) {
625 dolog ("warning: command %#x,%d is not truly understood yet\n",
626 cmd, s->needed_bytes);
631 static uint16_t dsp_get_lohi (SB16State *s)
633 uint8_t hi = dsp_get_data (s);
634 uint8_t lo = dsp_get_data (s);
635 return (hi << 8) | lo;
638 static uint16_t dsp_get_hilo (SB16State *s)
640 uint8_t lo = dsp_get_data (s);
641 uint8_t hi = dsp_get_data (s);
642 return (hi << 8) | lo;
645 static void complete (SB16State *s)
648 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
649 s->cmd, s->in_index, s->needed_bytes);
651 if (s->cmd > 0xaf && s->cmd < 0xd0) {
652 d2 = dsp_get_data (s);
653 d1 = dsp_get_data (s);
654 d0 = dsp_get_data (s);
657 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
661 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
663 dma_cmd (s, s->cmd, d0, d1 + (d2 << 8));
669 s->csp_mode = dsp_get_data (s);
672 ldebug ("CSP command 0x04: mode=%#x\n", s->csp_mode);
676 s->csp_param = dsp_get_data (s);
677 s->csp_value = dsp_get_data (s);
678 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
684 d0 = dsp_get_data (s);
685 d1 = dsp_get_data (s);
686 ldebug ("write CSP register %d <- %#x\n", d1, d0);
688 ldebug ("0x83[%d] <- %#x\n", s->csp_reg83r, d0);
689 s->csp_reg83[s->csp_reg83r % 4] = d0;
693 s->csp_regs[d1] = d0;
698 d0 = dsp_get_data (s);
699 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
700 d0, s->csp_regs[d0], s->csp_mode);
702 ldebug ("0x83[%d] -> %#x\n",
704 s->csp_reg83[s->csp_reg83w % 4]);
705 dsp_out_data (s, s->csp_reg83[s->csp_reg83w % 4]);
709 dsp_out_data (s, s->csp_regs[d0]);
714 d0 = dsp_get_data (s);
715 dolog ("cmd 0x10 d0=%#x\n", d0);
719 dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
723 s->time_const = dsp_get_data (s);
724 ldebug ("set time const %d\n", s->time_const);
727 case 0x42: /* FT2 sets output freq with this, go figure */
729 dolog ("cmd 0x42 might not do what it think it should\n");
732 s->freq = dsp_get_hilo (s);
733 ldebug ("set freq %d\n", s->freq);
737 s->block_size = dsp_get_lohi (s) + 1;
738 ldebug ("set dma block len %d\n", s->block_size);
745 /* ADPCM stuff, ignore */
750 int freq, samples, bytes;
753 freq = s->freq > 0 ? s->freq : 11025;
754 samples = dsp_get_lohi (s) + 1;
755 bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
756 ticks = (bytes * ticks_per_sec) / freq;
757 if (ticks < ticks_per_sec / 1024) {
758 pic_set_irq (s->irq, 1);
764 qemu_get_clock (vm_clock) + ticks
768 ldebug ("mix silence %d %d %lld\n", samples, bytes, ticks);
773 d0 = dsp_get_data (s);
775 ldebug ("E0 data = %#x\n", d0);
776 dsp_out_data (s, ~d0);
780 d0 = dsp_get_data (s);
781 ldebug ("E2 = %#x\n", d0);
785 s->test_reg = dsp_get_data (s);
789 d0 = dsp_get_data (s);
790 ldebug ("command 0xf9 with %#x\n", d0);
793 dsp_out_data (s, 0xff);
797 dsp_out_data (s, 0x07);
801 dsp_out_data (s, 0x38);
805 dsp_out_data (s, 0x00);
811 dolog ("complete: unrecognized command %#x\n", s->cmd);
821 static void reset (SB16State *s)
823 pic_set_irq (s->irq, 0);
825 pic_set_irq (s->irq, 1);
826 pic_set_irq (s->irq, 0);
829 s->mixer_regs[0x82] = 0;
833 s->left_till_irq = 0;
841 dsp_out_data(s, 0xaa);
846 static IO_WRITE_PROTO (dsp_write)
848 SB16State *s = opaque;
851 iport = nport - s->port;
853 ldebug ("write %#x <- %#x\n", nport, val);
859 if (0 && s->highspeed) {
861 pic_set_irq (s->irq, 0);
872 case 0x03: /* FreeBSD kludge */
877 s->v2x6 = 0; /* Prince of Persia, csp.sys, diagnose.exe */
880 case 0xb8: /* Panic */
885 dsp_out_data (s, 0x38);
896 case 0x0c: /* write data or command | write status */
897 /* if (s->highspeed) */
900 if (0 == s->needed_bytes) {
903 if (0 == s->needed_bytes) {
909 if (s->in_index == sizeof (s->in2_data)) {
910 dolog ("in data overrun\n");
913 s->in2_data[s->in_index++] = val;
914 if (s->in_index == s->needed_bytes) {
926 ldebug ("(nport=%#x, val=%#x)\n", nport, val);
931 static IO_READ_PROTO (dsp_read)
933 SB16State *s = opaque;
934 int iport, retval, ack = 0;
936 iport = nport - s->port;
939 case 0x06: /* reset */
943 case 0x0a: /* read data */
944 if (s->out_data_len) {
945 retval = s->out_data[--s->out_data_len];
946 s->last_read_byte = retval;
950 dolog ("empty output buffer for command %#x\n",
953 retval = s->last_read_byte;
958 case 0x0c: /* 0 can write */
959 retval = s->can_write ? 0 : 0x80;
962 case 0x0d: /* timer interrupt clear */
963 /* dolog ("timer interrupt clear\n"); */
967 case 0x0e: /* data available status | irq 8 ack */
968 retval = (!s->out_data_len || s->highspeed) ? 0 : 0x80;
969 if (s->mixer_regs[0x82] & 1) {
971 s->mixer_regs[0x82] &= 1;
972 pic_set_irq (s->irq, 0);
976 case 0x0f: /* irq 16 ack */
978 if (s->mixer_regs[0x82] & 2) {
980 s->mixer_regs[0x82] &= 2;
981 pic_set_irq (s->irq, 0);
990 ldebug ("read %#x -> %#x\n", nport, retval);
996 dolog ("warning: dsp_read %#x error\n", nport);
1000 static void reset_mixer (SB16State *s)
1004 memset (s->mixer_regs, 0xff, 0x7f);
1005 memset (s->mixer_regs + 0x83, 0xff, sizeof (s->mixer_regs) - 0x83);
1007 s->mixer_regs[0x02] = 4; /* master volume 3bits */
1008 s->mixer_regs[0x06] = 4; /* MIDI volume 3bits */
1009 s->mixer_regs[0x08] = 0; /* CD volume 3bits */
1010 s->mixer_regs[0x0a] = 0; /* voice volume 2bits */
1012 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1013 s->mixer_regs[0x0c] = 0;
1015 /* d5=output filt, d1=stereo switch */
1016 s->mixer_regs[0x0e] = 0;
1018 /* voice volume L d5,d7, R d1,d3 */
1019 s->mixer_regs[0x04] = (4 << 5) | (4 << 1);
1021 s->mixer_regs[0x22] = (4 << 5) | (4 << 1);
1023 s->mixer_regs[0x26] = (4 << 5) | (4 << 1);
1025 for (i = 0x30; i < 0x48; i++) {
1026 s->mixer_regs[i] = 0x20;
1030 static IO_WRITE_PROTO(mixer_write_indexb)
1032 SB16State *s = opaque;
1034 s->mixer_nreg = val;
1037 static IO_WRITE_PROTO(mixer_write_datab)
1039 SB16State *s = opaque;
1042 ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
1044 switch (s->mixer_nreg) {
1051 int irq = irq_of_magic (val);
1052 ldebug ("setting irq to %d (val=%#x)\n", irq, val);
1063 dma = lsbindex (val & 0xf);
1064 hdma = lsbindex (val & 0xf0);
1065 if (dma != s->dma || hdma != s->hdma) {
1067 "attempt to change DMA "
1068 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1069 dma, s->dma, hdma, s->hdma, val);
1079 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1084 if (s->mixer_nreg >= 0x80) {
1085 ldebug ("attempt to write mixer[%#x] <- %#x\n", s->mixer_nreg, val);
1090 s->mixer_regs[s->mixer_nreg] = val;
1093 static IO_WRITE_PROTO(mixer_write_indexw)
1095 mixer_write_indexb (opaque, nport, val & 0xff);
1096 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
1099 static IO_READ_PROTO(mixer_read)
1101 SB16State *s = opaque;
1104 #ifndef DEBUG_SB16_MOST
1105 if (s->mixer_nreg != 0x82) {
1106 ldebug ("mixer_read[%#x] -> %#x\n",
1107 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1110 ldebug ("mixer_read[%#x] -> %#x\n",
1111 s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
1113 return s->mixer_regs[s->mixer_nreg];
1116 static int write_audio (SB16State *s, int nchan, int dma_pos,
1117 int dma_len, int len)
1120 uint8_t tmpbuf[4096];
1126 int left = dma_len - dma_pos;
1130 to_copy = audio_MIN (temp, left);
1131 if (to_copy > sizeof (tmpbuf)) {
1132 to_copy = sizeof (tmpbuf);
1135 copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
1136 copied = AUD_write (s->voice, tmpbuf, copied);
1139 dma_pos = (dma_pos + copied) % dma_len;
1150 static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
1152 SB16State *s = opaque;
1153 int till, copy, written, free;
1155 if (s->left_till_irq < 0) {
1156 s->left_till_irq = s->block_size;
1160 free = s->audio_free & ~s->align;
1161 if ((free <= 0) || !dma_len) {
1170 till = s->left_till_irq;
1172 #ifdef DEBUG_SB16_MOST
1173 dolog ("pos:%06d %d till:%d len:%d\n",
1174 dma_pos, free, till, dma_len);
1178 if (0 == s->dma_auto) {
1183 written = write_audio (s, nchan, dma_pos, dma_len, copy);
1184 dma_pos = (dma_pos + written) % dma_len;
1185 s->left_till_irq -= written;
1187 if (s->left_till_irq <= 0) {
1188 s->mixer_regs[0x82] |= (nchan & 4) ? 2 : 1;
1189 pic_set_irq (s->irq, 1);
1190 if (0 == s->dma_auto) {
1196 #ifdef DEBUG_SB16_MOST
1197 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1198 dma_pos, free, dma_len, s->left_till_irq, copy, written,
1202 while (s->left_till_irq <= 0) {
1203 s->left_till_irq = s->block_size + s->left_till_irq;
1209 static void SB_audio_callback (void *opaque, int free)
1211 SB16State *s = opaque;
1212 s->audio_free = free;
1215 static void SB_save (QEMUFile *f, void *opaque)
1217 SB16State *s = opaque;
1219 qemu_put_be32s (f, &s->irq);
1220 qemu_put_be32s (f, &s->dma);
1221 qemu_put_be32s (f, &s->hdma);
1222 qemu_put_be32s (f, &s->port);
1223 qemu_put_be32s (f, &s->ver);
1224 qemu_put_be32s (f, &s->in_index);
1225 qemu_put_be32s (f, &s->out_data_len);
1226 qemu_put_be32s (f, &s->fmt_stereo);
1227 qemu_put_be32s (f, &s->fmt_signed);
1228 qemu_put_be32s (f, &s->fmt_bits);
1229 qemu_put_be32s (f, &s->fmt);
1230 qemu_put_be32s (f, &s->dma_auto);
1231 qemu_put_be32s (f, &s->block_size);
1232 qemu_put_be32s (f, &s->fifo);
1233 qemu_put_be32s (f, &s->freq);
1234 qemu_put_be32s (f, &s->time_const);
1235 qemu_put_be32s (f, &s->speaker);
1236 qemu_put_be32s (f, &s->needed_bytes);
1237 qemu_put_be32s (f, &s->cmd);
1238 qemu_put_be32s (f, &s->use_hdma);
1239 qemu_put_be32s (f, &s->highspeed);
1240 qemu_put_be32s (f, &s->can_write);
1241 qemu_put_be32s (f, &s->v2x6);
1243 qemu_put_8s (f, &s->csp_param);
1244 qemu_put_8s (f, &s->csp_value);
1245 qemu_put_8s (f, &s->csp_mode);
1246 qemu_put_8s (f, &s->csp_param);
1247 qemu_put_buffer (f, s->csp_regs, 256);
1248 qemu_put_8s (f, &s->csp_index);
1249 qemu_put_buffer (f, s->csp_reg83, 4);
1250 qemu_put_be32s (f, &s->csp_reg83r);
1251 qemu_put_be32s (f, &s->csp_reg83w);
1253 qemu_put_buffer (f, s->in2_data, sizeof (s->in2_data));
1254 qemu_put_buffer (f, s->out_data, sizeof (s->out_data));
1255 qemu_put_8s (f, &s->test_reg);
1256 qemu_put_8s (f, &s->last_read_byte);
1258 qemu_put_be32s (f, &s->nzero);
1259 qemu_put_be32s (f, &s->left_till_irq);
1260 qemu_put_be32s (f, &s->dma_running);
1261 qemu_put_be32s (f, &s->bytes_per_second);
1262 qemu_put_be32s (f, &s->align);
1264 qemu_put_be32s (f, &s->mixer_nreg);
1265 qemu_put_buffer (f, s->mixer_regs, 256);
1268 static int SB_load (QEMUFile *f, void *opaque, int version_id)
1270 SB16State *s = opaque;
1272 if (version_id != 1) {
1276 qemu_get_be32s (f, &s->irq);
1277 qemu_get_be32s (f, &s->dma);
1278 qemu_get_be32s (f, &s->hdma);
1279 qemu_get_be32s (f, &s->port);
1280 qemu_get_be32s (f, &s->ver);
1281 qemu_get_be32s (f, &s->in_index);
1282 qemu_get_be32s (f, &s->out_data_len);
1283 qemu_get_be32s (f, &s->fmt_stereo);
1284 qemu_get_be32s (f, &s->fmt_signed);
1285 qemu_get_be32s (f, &s->fmt_bits);
1286 qemu_get_be32s (f, &s->fmt);
1287 qemu_get_be32s (f, &s->dma_auto);
1288 qemu_get_be32s (f, &s->block_size);
1289 qemu_get_be32s (f, &s->fifo);
1290 qemu_get_be32s (f, &s->freq);
1291 qemu_get_be32s (f, &s->time_const);
1292 qemu_get_be32s (f, &s->speaker);
1293 qemu_get_be32s (f, &s->needed_bytes);
1294 qemu_get_be32s (f, &s->cmd);
1295 qemu_get_be32s (f, &s->use_hdma);
1296 qemu_get_be32s (f, &s->highspeed);
1297 qemu_get_be32s (f, &s->can_write);
1298 qemu_get_be32s (f, &s->v2x6);
1300 qemu_get_8s (f, &s->csp_param);
1301 qemu_get_8s (f, &s->csp_value);
1302 qemu_get_8s (f, &s->csp_mode);
1303 qemu_get_8s (f, &s->csp_param);
1304 qemu_get_buffer (f, s->csp_regs, 256);
1305 qemu_get_8s (f, &s->csp_index);
1306 qemu_get_buffer (f, s->csp_reg83, 4);
1307 qemu_get_be32s (f, &s->csp_reg83r);
1308 qemu_get_be32s (f, &s->csp_reg83w);
1310 qemu_get_buffer (f, s->in2_data, sizeof (s->in2_data));
1311 qemu_get_buffer (f, s->out_data, sizeof (s->out_data));
1312 qemu_get_8s (f, &s->test_reg);
1313 qemu_get_8s (f, &s->last_read_byte);
1315 qemu_get_be32s (f, &s->nzero);
1316 qemu_get_be32s (f, &s->left_till_irq);
1317 qemu_get_be32s (f, &s->dma_running);
1318 qemu_get_be32s (f, &s->bytes_per_second);
1319 qemu_get_be32s (f, &s->align);
1321 qemu_get_be32s (f, &s->mixer_nreg);
1322 qemu_get_buffer (f, s->mixer_regs, 256);
1325 AUD_close_out (&s->card, s->voice);
1329 if (s->dma_running) {
1336 as.nchannels = 1 << s->fmt_stereo;
1339 s->voice = AUD_open_out (
1346 0 /* little endian */
1351 speaker (s, s->speaker);
1356 int SB16_init (AudioState *audio)
1360 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
1361 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1364 dolog ("No audio state\n");
1368 s = qemu_mallocz (sizeof (*s));
1370 dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
1378 s->hdma = conf.hdma;
1379 s->port = conf.port;
1380 s->ver = conf.ver_lo | (conf.ver_hi << 8);
1382 s->mixer_regs[0x80] = magic_of_irq (s->irq);
1383 s->mixer_regs[0x81] = (1 << s->dma) | (1 << s->hdma);
1384 s->mixer_regs[0x82] = 2 << 5;
1387 s->csp_regs[9] = 0xf8;
1390 s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
1392 dolog ("warning: Could not create auxiliary timer\n");
1395 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
1396 register_ioport_write (s->port + dsp_write_ports[i], 1, 1, dsp_write, s);
1399 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
1400 register_ioport_read (s->port + dsp_read_ports[i], 1, 1, dsp_read, s);
1403 register_ioport_write (s->port + 0x4, 1, 1, mixer_write_indexb, s);
1404 register_ioport_write (s->port + 0x4, 1, 2, mixer_write_indexw, s);
1405 register_ioport_read (s->port + 0x5, 1, 1, mixer_read, s);
1406 register_ioport_write (s->port + 0x5, 1, 1, mixer_write_datab, s);
1408 DMA_register_channel (s->hdma, SB_read_DMA, s);
1409 DMA_register_channel (s->dma, SB_read_DMA, s);
1412 register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
1413 AUD_register_card (audio, "sb16", &s->card);