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"
28 #include "qemu-timer.h"
30 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
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.";
57 } conf
= {5, 4, 5, 1, 5, 0x220};
59 typedef struct SB16State
{
91 uint8_t csp_regs
[256];
100 uint8_t last_read_byte
;
106 int bytes_per_second
;
114 uint8_t mixer_regs
[256];
117 static void SB_audio_callback (void *opaque
, int free
);
119 static int magic_of_irq (int irq
)
131 dolog ("bad irq %d\n", irq
);
136 static int irq_of_magic (int magic
)
148 dolog ("bad irq magic %d\n", magic
);
154 static void log_dsp (SB16State
*dsp
)
156 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
157 dsp
->fmt_stereo
? "Stereo" : "Mono",
158 dsp
->fmt_signed
? "Signed" : "Unsigned",
160 dsp
->dma_auto
? "Auto" : "Single",
168 static void speaker (SB16State
*s
, int on
)
171 /* AUD_enable (s->voice, on); */
174 static void control (SB16State
*s
, int hold
)
176 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
177 s
->dma_running
= hold
;
179 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
183 AUD_set_active_out (s
->voice
, 1);
186 DMA_release_DREQ (dma
);
187 AUD_set_active_out (s
->voice
, 0);
191 static void aux_timer (void *opaque
)
193 SB16State
*s
= opaque
;
195 qemu_irq_raise (s
->pic
[s
->irq
]);
201 static void continue_dma8 (SB16State
*s
)
209 as
.nchannels
= 1 << s
->fmt_stereo
;
213 s
->voice
= AUD_open_out (
226 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
232 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
233 if (-1 == s
->time_const
) {
238 int tmp
= (256 - s
->time_const
);
239 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
243 s
->block_size
= dma_len
<< s
->fmt_stereo
;
246 /* This is apparently the only way to make both Act1/PL
247 and SecondReality/FC work
249 Act1 sets block size via command 0x48 and it's an odd number
250 SR does the same with even number
251 Both use stereo, and Creatives own documentation states that
252 0x48 sets block size in bytes less one.. go figure */
253 s
->block_size
&= ~s
->fmt_stereo
;
256 s
->freq
>>= s
->fmt_stereo
;
257 s
->left_till_irq
= s
->block_size
;
258 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
259 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
260 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
261 s
->align
= (1 << s
->fmt_stereo
) - 1;
263 if (s
->block_size
& s
->align
) {
264 dolog ("warning: misaligned block size %d, alignment %d\n",
265 s
->block_size
, s
->align
+ 1);
268 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
269 "dma %d, auto %d, fifo %d, high %d\n",
270 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
271 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
277 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
279 s
->use_hdma
= cmd
< 0xc0;
280 s
->fifo
= (cmd
>> 1) & 1;
281 s
->dma_auto
= (cmd
>> 2) & 1;
282 s
->fmt_signed
= (d0
>> 4) & 1;
283 s
->fmt_stereo
= (d0
>> 5) & 1;
295 if (-1 != s
->time_const
) {
297 int tmp
= 256 - s
->time_const
;
298 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
300 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
301 s
->freq
= 1000000 / ((255 - s
->time_const
));
306 s
->block_size
= dma_len
+ 1;
307 s
->block_size
<<= (s
->fmt_bits
== 16);
309 /* It is clear that for DOOM and auto-init this value
310 shouldn't take stereo into account, while Miles Sound Systems
311 setsound.exe with single transfer mode wouldn't work without it
312 wonders of SB16 yet again */
313 s
->block_size
<<= s
->fmt_stereo
;
316 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
317 "dma %d, auto %d, fifo %d, high %d\n",
318 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
319 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
321 if (16 == s
->fmt_bits
) {
323 s
->fmt
= AUD_FMT_S16
;
326 s
->fmt
= AUD_FMT_U16
;
338 s
->left_till_irq
= s
->block_size
;
340 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
342 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
343 if (s
->block_size
& s
->align
) {
344 dolog ("warning: misaligned block size %d, alignment %d\n",
345 s
->block_size
, s
->align
+ 1);
354 as
.nchannels
= 1 << s
->fmt_stereo
;
358 s
->voice
= AUD_open_out (
372 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
374 ldebug ("outdata %#x\n", val
);
375 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
376 s
->out_data
[s
->out_data_len
++] = val
;
380 static inline uint8_t dsp_get_data (SB16State
*s
)
383 return s
->in2_data
[--s
->in_index
];
386 dolog ("buffer underflow\n");
391 static void command (SB16State
*s
, uint8_t cmd
)
393 ldebug ("command %#x\n", cmd
);
395 if (cmd
> 0xaf && cmd
< 0xd0) {
397 dolog ("ADC not yet supported (command %#x)\n", cmd
);
405 dolog ("%#x wrong bits\n", cmd
);
414 dsp_out_data (s
, 0x10); /* s->csp_param); */
426 /* __asm__ ("int3"); */
434 dsp_out_data (s
, 0xf8);
450 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
451 dma_cmd8 (s
, DMA8_AUTO
, -1);
454 case 0x20: /* Direct ADC, Juice/PL */
455 dsp_out_data (s
, 0xff);
459 dolog ("0x35 - MIDI command not implemented\n");
481 dsp_out_data (s
, 0xaa);
484 case 0x47: /* Continue Auto-Initialize DMA 16bit */
492 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
493 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
496 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
498 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
501 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
503 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
506 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
508 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
512 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
513 dolog ("not implemented\n");
518 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
520 dolog ("not implemented\n");
529 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
532 case 0xd0: /* halt DMA operation. 8bit */
536 case 0xd1: /* speaker on */
540 case 0xd3: /* speaker off */
544 case 0xd4: /* continue DMA operation. 8bit */
545 /* KQ6 (or maybe Sierras audblst.drv in general) resets
546 the frequency between halt/continue */
550 case 0xd5: /* halt DMA operation. 16bit */
554 case 0xd6: /* continue DMA operation. 16bit */
558 case 0xd9: /* exit auto-init DMA after this block. 16bit */
562 case 0xda: /* exit auto-init DMA after this block. 8bit */
566 case 0xe0: /* DSP identification */
571 dsp_out_data (s
, s
->ver
& 0xff);
572 dsp_out_data (s
, s
->ver
>> 8);
582 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
583 dsp_out_data (s
, e3
[i
]);
587 case 0xe4: /* write test reg */
592 dolog ("Attempt to probe for ESS (0xe7)?\n");
595 case 0xe8: /* read test reg */
596 dsp_out_data (s
, s
->test_reg
);
601 dsp_out_data (s
, 0xaa);
602 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
603 qemu_irq_raise (s
->pic
[s
->irq
]);
614 case 0xfc: /* FIXME */
619 dolog ("Unrecognized command %#x\n", cmd
);
624 if (!s
->needed_bytes
) {
629 if (!s
->needed_bytes
) {
638 dolog ("warning: command %#x,%d is not truly understood yet\n",
639 cmd
, s
->needed_bytes
);
644 static uint16_t dsp_get_lohi (SB16State
*s
)
646 uint8_t hi
= dsp_get_data (s
);
647 uint8_t lo
= dsp_get_data (s
);
648 return (hi
<< 8) | lo
;
651 static uint16_t dsp_get_hilo (SB16State
*s
)
653 uint8_t lo
= dsp_get_data (s
);
654 uint8_t hi
= dsp_get_data (s
);
655 return (hi
<< 8) | lo
;
658 static void complete (SB16State
*s
)
661 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
662 s
->cmd
, s
->in_index
, s
->needed_bytes
);
664 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
665 d2
= dsp_get_data (s
);
666 d1
= dsp_get_data (s
);
667 d0
= dsp_get_data (s
);
670 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
674 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
676 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
682 s
->csp_mode
= dsp_get_data (s
);
685 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
689 s
->csp_param
= dsp_get_data (s
);
690 s
->csp_value
= dsp_get_data (s
);
691 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
697 d0
= dsp_get_data (s
);
698 d1
= dsp_get_data (s
);
699 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
701 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
702 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
706 s
->csp_regs
[d1
] = d0
;
711 d0
= dsp_get_data (s
);
712 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
713 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
715 ldebug ("0x83[%d] -> %#x\n",
717 s
->csp_reg83
[s
->csp_reg83w
% 4]);
718 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
722 dsp_out_data (s
, s
->csp_regs
[d0
]);
727 d0
= dsp_get_data (s
);
728 dolog ("cmd 0x10 d0=%#x\n", d0
);
732 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
736 s
->time_const
= dsp_get_data (s
);
737 ldebug ("set time const %d\n", s
->time_const
);
740 case 0x42: /* FT2 sets output freq with this, go figure */
742 dolog ("cmd 0x42 might not do what it think it should\n");
745 s
->freq
= dsp_get_hilo (s
);
746 ldebug ("set freq %d\n", s
->freq
);
750 s
->block_size
= dsp_get_lohi (s
) + 1;
751 ldebug ("set dma block len %d\n", s
->block_size
);
758 /* ADPCM stuff, ignore */
763 int freq
, samples
, bytes
;
766 freq
= s
->freq
> 0 ? s
->freq
: 11025;
767 samples
= dsp_get_lohi (s
) + 1;
768 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
769 ticks
= (bytes
* ticks_per_sec
) / freq
;
770 if (ticks
< ticks_per_sec
/ 1024) {
771 qemu_irq_raise (s
->pic
[s
->irq
]);
777 qemu_get_clock (vm_clock
) + ticks
781 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
786 d0
= dsp_get_data (s
);
788 ldebug ("E0 data = %#x\n", d0
);
789 dsp_out_data (s
, ~d0
);
793 d0
= dsp_get_data (s
);
794 ldebug ("E2 = %#x\n", d0
);
798 s
->test_reg
= dsp_get_data (s
);
802 d0
= dsp_get_data (s
);
803 ldebug ("command 0xf9 with %#x\n", d0
);
806 dsp_out_data (s
, 0xff);
810 dsp_out_data (s
, 0x07);
814 dsp_out_data (s
, 0x38);
818 dsp_out_data (s
, 0x00);
824 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
834 static void legacy_reset (SB16State
*s
)
848 s
->voice
= AUD_open_out (
857 /* Not sure about that... */
858 /* AUD_set_active_out (s->voice, 1); */
861 static void reset (SB16State
*s
)
863 qemu_irq_lower (s
->pic
[s
->irq
]);
865 qemu_irq_raise (s
->pic
[s
->irq
]);
866 qemu_irq_lower (s
->pic
[s
->irq
]);
869 s
->mixer_regs
[0x82] = 0;
873 s
->left_till_irq
= 0;
881 dsp_out_data(s
, 0xaa);
887 static IO_WRITE_PROTO (dsp_write
)
889 SB16State
*s
= opaque
;
892 iport
= nport
- s
->port
;
894 ldebug ("write %#x <- %#x\n", nport
, val
);
900 if (0 && s
->highspeed
) {
902 qemu_irq_lower (s
->pic
[s
->irq
]);
913 case 0x03: /* FreeBSD kludge */
918 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
921 case 0xb8: /* Panic */
926 dsp_out_data (s
, 0x38);
937 case 0x0c: /* write data or command | write status */
938 /* if (s->highspeed) */
941 if (0 == s
->needed_bytes
) {
944 if (0 == s
->needed_bytes
) {
950 if (s
->in_index
== sizeof (s
->in2_data
)) {
951 dolog ("in data overrun\n");
954 s
->in2_data
[s
->in_index
++] = val
;
955 if (s
->in_index
== s
->needed_bytes
) {
967 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
972 static IO_READ_PROTO (dsp_read
)
974 SB16State
*s
= opaque
;
975 int iport
, retval
, ack
= 0;
977 iport
= nport
- s
->port
;
980 case 0x06: /* reset */
984 case 0x0a: /* read data */
985 if (s
->out_data_len
) {
986 retval
= s
->out_data
[--s
->out_data_len
];
987 s
->last_read_byte
= retval
;
991 dolog ("empty output buffer for command %#x\n",
994 retval
= s
->last_read_byte
;
999 case 0x0c: /* 0 can write */
1000 retval
= s
->can_write
? 0 : 0x80;
1003 case 0x0d: /* timer interrupt clear */
1004 /* dolog ("timer interrupt clear\n"); */
1008 case 0x0e: /* data available status | irq 8 ack */
1009 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1010 if (s
->mixer_regs
[0x82] & 1) {
1012 s
->mixer_regs
[0x82] &= 1;
1013 qemu_irq_lower (s
->pic
[s
->irq
]);
1017 case 0x0f: /* irq 16 ack */
1019 if (s
->mixer_regs
[0x82] & 2) {
1021 s
->mixer_regs
[0x82] &= 2;
1022 qemu_irq_lower (s
->pic
[s
->irq
]);
1031 ldebug ("read %#x -> %#x\n", nport
, retval
);
1037 dolog ("warning: dsp_read %#x error\n", nport
);
1041 static void reset_mixer (SB16State
*s
)
1045 memset (s
->mixer_regs
, 0xff, 0x7f);
1046 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1048 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1049 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1050 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1051 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1053 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1054 s
->mixer_regs
[0x0c] = 0;
1056 /* d5=output filt, d1=stereo switch */
1057 s
->mixer_regs
[0x0e] = 0;
1059 /* voice volume L d5,d7, R d1,d3 */
1060 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1062 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1064 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1066 for (i
= 0x30; i
< 0x48; i
++) {
1067 s
->mixer_regs
[i
] = 0x20;
1071 static IO_WRITE_PROTO(mixer_write_indexb
)
1073 SB16State
*s
= opaque
;
1075 s
->mixer_nreg
= val
;
1078 static IO_WRITE_PROTO(mixer_write_datab
)
1080 SB16State
*s
= opaque
;
1083 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1085 switch (s
->mixer_nreg
) {
1092 int irq
= irq_of_magic (val
);
1093 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1104 dma
= lsbindex (val
& 0xf);
1105 hdma
= lsbindex (val
& 0xf0);
1106 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1108 "attempt to change DMA "
1109 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1110 dma
, s
->dma
, hdma
, s
->hdma
, val
);
1120 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1125 if (s
->mixer_nreg
>= 0x80) {
1126 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1131 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1134 static IO_WRITE_PROTO(mixer_write_indexw
)
1136 mixer_write_indexb (opaque
, nport
, val
& 0xff);
1137 mixer_write_datab (opaque
, nport
, (val
>> 8) & 0xff);
1140 static IO_READ_PROTO(mixer_read
)
1142 SB16State
*s
= opaque
;
1145 #ifndef DEBUG_SB16_MOST
1146 if (s
->mixer_nreg
!= 0x82) {
1147 ldebug ("mixer_read[%#x] -> %#x\n",
1148 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1151 ldebug ("mixer_read[%#x] -> %#x\n",
1152 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1154 return s
->mixer_regs
[s
->mixer_nreg
];
1157 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1158 int dma_len
, int len
)
1161 uint8_t tmpbuf
[4096];
1167 int left
= dma_len
- dma_pos
;
1171 to_copy
= audio_MIN (temp
, left
);
1172 if (to_copy
> sizeof (tmpbuf
)) {
1173 to_copy
= sizeof (tmpbuf
);
1176 copied
= DMA_read_memory (nchan
, tmpbuf
, dma_pos
, to_copy
);
1177 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1180 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1191 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1193 SB16State
*s
= opaque
;
1194 int till
, copy
, written
, free
;
1196 if (s
->left_till_irq
< 0) {
1197 s
->left_till_irq
= s
->block_size
;
1201 free
= s
->audio_free
& ~s
->align
;
1202 if ((free
<= 0) || !dma_len
) {
1211 till
= s
->left_till_irq
;
1213 #ifdef DEBUG_SB16_MOST
1214 dolog ("pos:%06d %d till:%d len:%d\n",
1215 dma_pos
, free
, till
, dma_len
);
1219 if (0 == s
->dma_auto
) {
1224 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1225 dma_pos
= (dma_pos
+ written
) % dma_len
;
1226 s
->left_till_irq
-= written
;
1228 if (s
->left_till_irq
<= 0) {
1229 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1230 qemu_irq_raise (s
->pic
[s
->irq
]);
1231 if (0 == s
->dma_auto
) {
1237 #ifdef DEBUG_SB16_MOST
1238 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1239 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1243 while (s
->left_till_irq
<= 0) {
1244 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1250 static void SB_audio_callback (void *opaque
, int free
)
1252 SB16State
*s
= opaque
;
1253 s
->audio_free
= free
;
1256 static void SB_save (QEMUFile
*f
, void *opaque
)
1258 SB16State
*s
= opaque
;
1260 qemu_put_be32s (f
, &s
->irq
);
1261 qemu_put_be32s (f
, &s
->dma
);
1262 qemu_put_be32s (f
, &s
->hdma
);
1263 qemu_put_be32s (f
, &s
->port
);
1264 qemu_put_be32s (f
, &s
->ver
);
1265 qemu_put_be32s (f
, &s
->in_index
);
1266 qemu_put_be32s (f
, &s
->out_data_len
);
1267 qemu_put_be32s (f
, &s
->fmt_stereo
);
1268 qemu_put_be32s (f
, &s
->fmt_signed
);
1269 qemu_put_be32s (f
, &s
->fmt_bits
);
1270 qemu_put_be32s (f
, &s
->fmt
);
1271 qemu_put_be32s (f
, &s
->dma_auto
);
1272 qemu_put_be32s (f
, &s
->block_size
);
1273 qemu_put_be32s (f
, &s
->fifo
);
1274 qemu_put_be32s (f
, &s
->freq
);
1275 qemu_put_be32s (f
, &s
->time_const
);
1276 qemu_put_be32s (f
, &s
->speaker
);
1277 qemu_put_be32s (f
, &s
->needed_bytes
);
1278 qemu_put_be32s (f
, &s
->cmd
);
1279 qemu_put_be32s (f
, &s
->use_hdma
);
1280 qemu_put_be32s (f
, &s
->highspeed
);
1281 qemu_put_be32s (f
, &s
->can_write
);
1282 qemu_put_be32s (f
, &s
->v2x6
);
1284 qemu_put_8s (f
, &s
->csp_param
);
1285 qemu_put_8s (f
, &s
->csp_value
);
1286 qemu_put_8s (f
, &s
->csp_mode
);
1287 qemu_put_8s (f
, &s
->csp_param
);
1288 qemu_put_buffer (f
, s
->csp_regs
, 256);
1289 qemu_put_8s (f
, &s
->csp_index
);
1290 qemu_put_buffer (f
, s
->csp_reg83
, 4);
1291 qemu_put_be32s (f
, &s
->csp_reg83r
);
1292 qemu_put_be32s (f
, &s
->csp_reg83w
);
1294 qemu_put_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1295 qemu_put_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1296 qemu_put_8s (f
, &s
->test_reg
);
1297 qemu_put_8s (f
, &s
->last_read_byte
);
1299 qemu_put_be32s (f
, &s
->nzero
);
1300 qemu_put_be32s (f
, &s
->left_till_irq
);
1301 qemu_put_be32s (f
, &s
->dma_running
);
1302 qemu_put_be32s (f
, &s
->bytes_per_second
);
1303 qemu_put_be32s (f
, &s
->align
);
1305 qemu_put_be32s (f
, &s
->mixer_nreg
);
1306 qemu_put_buffer (f
, s
->mixer_regs
, 256);
1309 static int SB_load (QEMUFile
*f
, void *opaque
, int version_id
)
1311 SB16State
*s
= opaque
;
1313 if (version_id
!= 1) {
1317 qemu_get_be32s (f
, &s
->irq
);
1318 qemu_get_be32s (f
, &s
->dma
);
1319 qemu_get_be32s (f
, &s
->hdma
);
1320 qemu_get_be32s (f
, &s
->port
);
1321 qemu_get_be32s (f
, &s
->ver
);
1322 qemu_get_be32s (f
, &s
->in_index
);
1323 qemu_get_be32s (f
, &s
->out_data_len
);
1324 qemu_get_be32s (f
, &s
->fmt_stereo
);
1325 qemu_get_be32s (f
, &s
->fmt_signed
);
1326 qemu_get_be32s (f
, &s
->fmt_bits
);
1327 qemu_get_be32s (f
, &s
->fmt
);
1328 qemu_get_be32s (f
, &s
->dma_auto
);
1329 qemu_get_be32s (f
, &s
->block_size
);
1330 qemu_get_be32s (f
, &s
->fifo
);
1331 qemu_get_be32s (f
, &s
->freq
);
1332 qemu_get_be32s (f
, &s
->time_const
);
1333 qemu_get_be32s (f
, &s
->speaker
);
1334 qemu_get_be32s (f
, &s
->needed_bytes
);
1335 qemu_get_be32s (f
, &s
->cmd
);
1336 qemu_get_be32s (f
, &s
->use_hdma
);
1337 qemu_get_be32s (f
, &s
->highspeed
);
1338 qemu_get_be32s (f
, &s
->can_write
);
1339 qemu_get_be32s (f
, &s
->v2x6
);
1341 qemu_get_8s (f
, &s
->csp_param
);
1342 qemu_get_8s (f
, &s
->csp_value
);
1343 qemu_get_8s (f
, &s
->csp_mode
);
1344 qemu_get_8s (f
, &s
->csp_param
);
1345 qemu_get_buffer (f
, s
->csp_regs
, 256);
1346 qemu_get_8s (f
, &s
->csp_index
);
1347 qemu_get_buffer (f
, s
->csp_reg83
, 4);
1348 qemu_get_be32s (f
, &s
->csp_reg83r
);
1349 qemu_get_be32s (f
, &s
->csp_reg83w
);
1351 qemu_get_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1352 qemu_get_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1353 qemu_get_8s (f
, &s
->test_reg
);
1354 qemu_get_8s (f
, &s
->last_read_byte
);
1356 qemu_get_be32s (f
, &s
->nzero
);
1357 qemu_get_be32s (f
, &s
->left_till_irq
);
1358 qemu_get_be32s (f
, &s
->dma_running
);
1359 qemu_get_be32s (f
, &s
->bytes_per_second
);
1360 qemu_get_be32s (f
, &s
->align
);
1362 qemu_get_be32s (f
, &s
->mixer_nreg
);
1363 qemu_get_buffer (f
, s
->mixer_regs
, 256);
1366 AUD_close_out (&s
->card
, s
->voice
);
1370 if (s
->dma_running
) {
1377 as
.nchannels
= 1 << s
->fmt_stereo
;
1381 s
->voice
= AUD_open_out (
1392 speaker (s
, s
->speaker
);
1397 int SB16_init (AudioState
*audio
, qemu_irq
*pic
)
1401 static const uint8_t dsp_write_ports
[] = {0x6, 0xc};
1402 static const uint8_t dsp_read_ports
[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1405 dolog ("No audio state\n");
1409 s
= qemu_mallocz (sizeof (*s
));
1411 dolog ("Could not allocate memory for SB16 (%zu bytes)\n",
1420 s
->hdma
= conf
.hdma
;
1421 s
->port
= conf
.port
;
1422 s
->ver
= conf
.ver_lo
| (conf
.ver_hi
<< 8);
1424 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1425 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1426 s
->mixer_regs
[0x82] = 2 << 5;
1429 s
->csp_regs
[9] = 0xf8;
1432 s
->aux_ts
= qemu_new_timer (vm_clock
, aux_timer
, s
);
1434 dolog ("warning: Could not create auxiliary timer\n");
1437 for (i
= 0; i
< LENOFA (dsp_write_ports
); i
++) {
1438 register_ioport_write (s
->port
+ dsp_write_ports
[i
], 1, 1, dsp_write
, s
);
1441 for (i
= 0; i
< LENOFA (dsp_read_ports
); i
++) {
1442 register_ioport_read (s
->port
+ dsp_read_ports
[i
], 1, 1, dsp_read
, s
);
1445 register_ioport_write (s
->port
+ 0x4, 1, 1, mixer_write_indexb
, s
);
1446 register_ioport_write (s
->port
+ 0x4, 1, 2, mixer_write_indexw
, s
);
1447 register_ioport_read (s
->port
+ 0x5, 1, 1, mixer_read
, s
);
1448 register_ioport_write (s
->port
+ 0x5, 1, 1, mixer_write_datab
, s
);
1450 DMA_register_channel (s
->hdma
, SB_read_DMA
, s
);
1451 DMA_register_channel (s
->dma
, SB_read_DMA
, s
);
1454 register_savevm ("sb16", 0, 1, SB_save
, SB_load
, s
);
1455 AUD_register_card (audio
, "sb16", &s
->card
);