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 dolog(...) AUD_log ("sb16", __VA_ARGS__)
33 /* #define DEBUG_SB16_MOST */
36 #define ldebug(...) dolog (__VA_ARGS__)
41 #define IO_READ_PROTO(name) \
42 uint32_t name (void *opaque, uint32_t nport)
43 #define IO_WRITE_PROTO(name) \
44 void name (void *opaque, uint32_t nport, uint32_t val)
46 static const char e3
[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
55 } conf
= {5, 4, 5, 1, 5, 0x220};
57 typedef struct SB16State
{
89 uint8_t csp_regs
[256];
98 uint8_t last_read_byte
;
104 int bytes_per_second
;
112 uint8_t mixer_regs
[256];
115 static void SB_audio_callback (void *opaque
, int free
);
117 static int magic_of_irq (int irq
)
129 dolog ("bad irq %d\n", irq
);
134 static int irq_of_magic (int magic
)
146 dolog ("bad irq magic %d\n", magic
);
152 static void log_dsp (SB16State
*dsp
)
154 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
155 dsp
->fmt_stereo
? "Stereo" : "Mono",
156 dsp
->fmt_signed
? "Signed" : "Unsigned",
158 dsp
->dma_auto
? "Auto" : "Single",
166 static void speaker (SB16State
*s
, int on
)
169 /* AUD_enable (s->voice, on); */
172 static void control (SB16State
*s
, int hold
)
174 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
175 s
->dma_running
= hold
;
177 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
181 AUD_set_active_out (s
->voice
, 1);
184 DMA_release_DREQ (dma
);
185 AUD_set_active_out (s
->voice
, 0);
189 static void aux_timer (void *opaque
)
191 SB16State
*s
= opaque
;
193 qemu_irq_raise (s
->pic
);
199 static void continue_dma8 (SB16State
*s
)
202 struct audsettings as
;
207 as
.nchannels
= 1 << s
->fmt_stereo
;
211 s
->voice
= AUD_open_out (
224 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
230 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
231 if (-1 == s
->time_const
) {
236 int tmp
= (256 - s
->time_const
);
237 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
241 s
->block_size
= dma_len
<< s
->fmt_stereo
;
244 /* This is apparently the only way to make both Act1/PL
245 and SecondReality/FC work
247 Act1 sets block size via command 0x48 and it's an odd number
248 SR does the same with even number
249 Both use stereo, and Creatives own documentation states that
250 0x48 sets block size in bytes less one.. go figure */
251 s
->block_size
&= ~s
->fmt_stereo
;
254 s
->freq
>>= s
->fmt_stereo
;
255 s
->left_till_irq
= s
->block_size
;
256 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
257 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
258 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
259 s
->align
= (1 << s
->fmt_stereo
) - 1;
261 if (s
->block_size
& s
->align
) {
262 dolog ("warning: misaligned block size %d, alignment %d\n",
263 s
->block_size
, s
->align
+ 1);
266 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
267 "dma %d, auto %d, fifo %d, high %d\n",
268 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
269 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
275 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
277 s
->use_hdma
= cmd
< 0xc0;
278 s
->fifo
= (cmd
>> 1) & 1;
279 s
->dma_auto
= (cmd
>> 2) & 1;
280 s
->fmt_signed
= (d0
>> 4) & 1;
281 s
->fmt_stereo
= (d0
>> 5) & 1;
293 if (-1 != s
->time_const
) {
295 int tmp
= 256 - s
->time_const
;
296 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
298 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
299 s
->freq
= 1000000 / ((255 - s
->time_const
));
304 s
->block_size
= dma_len
+ 1;
305 s
->block_size
<<= (s
->fmt_bits
== 16);
307 /* It is clear that for DOOM and auto-init this value
308 shouldn't take stereo into account, while Miles Sound Systems
309 setsound.exe with single transfer mode wouldn't work without it
310 wonders of SB16 yet again */
311 s
->block_size
<<= s
->fmt_stereo
;
314 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
315 "dma %d, auto %d, fifo %d, high %d\n",
316 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
317 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
319 if (16 == s
->fmt_bits
) {
321 s
->fmt
= AUD_FMT_S16
;
324 s
->fmt
= AUD_FMT_U16
;
336 s
->left_till_irq
= s
->block_size
;
338 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
340 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
341 if (s
->block_size
& s
->align
) {
342 dolog ("warning: misaligned block size %d, alignment %d\n",
343 s
->block_size
, s
->align
+ 1);
347 struct audsettings as
;
352 as
.nchannels
= 1 << s
->fmt_stereo
;
356 s
->voice
= AUD_open_out (
370 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
372 ldebug ("outdata %#x\n", val
);
373 if ((size_t) s
->out_data_len
< sizeof (s
->out_data
)) {
374 s
->out_data
[s
->out_data_len
++] = val
;
378 static inline uint8_t dsp_get_data (SB16State
*s
)
381 return s
->in2_data
[--s
->in_index
];
384 dolog ("buffer underflow\n");
389 static void command (SB16State
*s
, uint8_t cmd
)
391 ldebug ("command %#x\n", cmd
);
393 if (cmd
> 0xaf && cmd
< 0xd0) {
395 dolog ("ADC not yet supported (command %#x)\n", cmd
);
403 dolog ("%#x wrong bits\n", cmd
);
412 dsp_out_data (s
, 0x10); /* s->csp_param); */
424 /* __asm__ ("int3"); */
432 dsp_out_data (s
, 0xf8);
448 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
449 dma_cmd8 (s
, DMA8_AUTO
, -1);
452 case 0x20: /* Direct ADC, Juice/PL */
453 dsp_out_data (s
, 0xff);
457 dolog ("0x35 - MIDI command not implemented\n");
479 dsp_out_data (s
, 0xaa);
482 case 0x47: /* Continue Auto-Initialize DMA 16bit */
490 s
->needed_bytes
= 2; /* DMA DAC, 4-bit ADPCM */
491 dolog ("0x75 - DMA DAC, 4-bit ADPCM not implemented\n");
494 case 0x75: /* DMA DAC, 4-bit ADPCM Reference */
496 dolog ("0x74 - DMA DAC, 4-bit ADPCM Reference not implemented\n");
499 case 0x76: /* DMA DAC, 2.6-bit ADPCM */
501 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM not implemented\n");
504 case 0x77: /* DMA DAC, 2.6-bit ADPCM Reference */
506 dolog ("0x74 - DMA DAC, 2.6-bit ADPCM Reference not implemented\n");
510 dolog ("0x7d - Autio-Initialize DMA DAC, 4-bit ADPCM Reference\n");
511 dolog ("not implemented\n");
516 "0x7d - Autio-Initialize DMA DAC, 2.6-bit ADPCM Reference\n"
518 dolog ("not implemented\n");
527 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
530 case 0xd0: /* halt DMA operation. 8bit */
534 case 0xd1: /* speaker on */
538 case 0xd3: /* speaker off */
542 case 0xd4: /* continue DMA operation. 8bit */
543 /* KQ6 (or maybe Sierras audblst.drv in general) resets
544 the frequency between halt/continue */
548 case 0xd5: /* halt DMA operation. 16bit */
552 case 0xd6: /* continue DMA operation. 16bit */
556 case 0xd9: /* exit auto-init DMA after this block. 16bit */
560 case 0xda: /* exit auto-init DMA after this block. 8bit */
564 case 0xe0: /* DSP identification */
569 dsp_out_data (s
, s
->ver
& 0xff);
570 dsp_out_data (s
, s
->ver
>> 8);
580 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
581 dsp_out_data (s
, e3
[i
]);
585 case 0xe4: /* write test reg */
590 dolog ("Attempt to probe for ESS (0xe7)?\n");
593 case 0xe8: /* read test reg */
594 dsp_out_data (s
, s
->test_reg
);
599 dsp_out_data (s
, 0xaa);
600 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
601 qemu_irq_raise (s
->pic
);
612 case 0xfc: /* FIXME */
617 dolog ("Unrecognized command %#x\n", cmd
);
622 if (!s
->needed_bytes
) {
627 if (!s
->needed_bytes
) {
636 dolog ("warning: command %#x,%d is not truly understood yet\n",
637 cmd
, s
->needed_bytes
);
642 static uint16_t dsp_get_lohi (SB16State
*s
)
644 uint8_t hi
= dsp_get_data (s
);
645 uint8_t lo
= dsp_get_data (s
);
646 return (hi
<< 8) | lo
;
649 static uint16_t dsp_get_hilo (SB16State
*s
)
651 uint8_t lo
= dsp_get_data (s
);
652 uint8_t hi
= dsp_get_data (s
);
653 return (hi
<< 8) | lo
;
656 static void complete (SB16State
*s
)
659 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
660 s
->cmd
, s
->in_index
, s
->needed_bytes
);
662 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
663 d2
= dsp_get_data (s
);
664 d1
= dsp_get_data (s
);
665 d0
= dsp_get_data (s
);
668 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
672 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
674 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
680 s
->csp_mode
= dsp_get_data (s
);
683 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
687 s
->csp_param
= dsp_get_data (s
);
688 s
->csp_value
= dsp_get_data (s
);
689 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
695 d0
= dsp_get_data (s
);
696 d1
= dsp_get_data (s
);
697 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
699 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
700 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
704 s
->csp_regs
[d1
] = d0
;
709 d0
= dsp_get_data (s
);
710 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
711 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
713 ldebug ("0x83[%d] -> %#x\n",
715 s
->csp_reg83
[s
->csp_reg83w
% 4]);
716 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
720 dsp_out_data (s
, s
->csp_regs
[d0
]);
725 d0
= dsp_get_data (s
);
726 dolog ("cmd 0x10 d0=%#x\n", d0
);
730 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
734 s
->time_const
= dsp_get_data (s
);
735 ldebug ("set time const %d\n", s
->time_const
);
738 case 0x42: /* FT2 sets output freq with this, go figure */
740 dolog ("cmd 0x42 might not do what it think it should\n");
743 s
->freq
= dsp_get_hilo (s
);
744 ldebug ("set freq %d\n", s
->freq
);
748 s
->block_size
= dsp_get_lohi (s
) + 1;
749 ldebug ("set dma block len %d\n", s
->block_size
);
756 /* ADPCM stuff, ignore */
761 int freq
, samples
, bytes
;
764 freq
= s
->freq
> 0 ? s
->freq
: 11025;
765 samples
= dsp_get_lohi (s
) + 1;
766 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
767 ticks
= (bytes
* ticks_per_sec
) / freq
;
768 if (ticks
< ticks_per_sec
/ 1024) {
769 qemu_irq_raise (s
->pic
);
775 qemu_get_clock (vm_clock
) + ticks
779 ldebug ("mix silence %d %d %" PRId64
"\n", samples
, bytes
, ticks
);
784 d0
= dsp_get_data (s
);
786 ldebug ("E0 data = %#x\n", d0
);
787 dsp_out_data (s
, ~d0
);
791 d0
= dsp_get_data (s
);
792 ldebug ("E2 = %#x\n", d0
);
796 s
->test_reg
= dsp_get_data (s
);
800 d0
= dsp_get_data (s
);
801 ldebug ("command 0xf9 with %#x\n", d0
);
804 dsp_out_data (s
, 0xff);
808 dsp_out_data (s
, 0x07);
812 dsp_out_data (s
, 0x38);
816 dsp_out_data (s
, 0x00);
822 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
832 static void legacy_reset (SB16State
*s
)
834 struct audsettings as
;
846 s
->voice
= AUD_open_out (
855 /* Not sure about that... */
856 /* AUD_set_active_out (s->voice, 1); */
859 static void reset (SB16State
*s
)
861 qemu_irq_lower (s
->pic
);
863 qemu_irq_raise (s
->pic
);
864 qemu_irq_lower (s
->pic
);
867 s
->mixer_regs
[0x82] = 0;
871 s
->left_till_irq
= 0;
879 dsp_out_data(s
, 0xaa);
885 static IO_WRITE_PROTO (dsp_write
)
887 SB16State
*s
= opaque
;
890 iport
= nport
- s
->port
;
892 ldebug ("write %#x <- %#x\n", nport
, val
);
898 if (0 && s
->highspeed
) {
900 qemu_irq_lower (s
->pic
);
911 case 0x03: /* FreeBSD kludge */
916 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
919 case 0xb8: /* Panic */
924 dsp_out_data (s
, 0x38);
935 case 0x0c: /* write data or command | write status */
936 /* if (s->highspeed) */
939 if (0 == s
->needed_bytes
) {
942 if (0 == s
->needed_bytes
) {
948 if (s
->in_index
== sizeof (s
->in2_data
)) {
949 dolog ("in data overrun\n");
952 s
->in2_data
[s
->in_index
++] = val
;
953 if (s
->in_index
== s
->needed_bytes
) {
965 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
970 static IO_READ_PROTO (dsp_read
)
972 SB16State
*s
= opaque
;
973 int iport
, retval
, ack
= 0;
975 iport
= nport
- s
->port
;
978 case 0x06: /* reset */
982 case 0x0a: /* read data */
983 if (s
->out_data_len
) {
984 retval
= s
->out_data
[--s
->out_data_len
];
985 s
->last_read_byte
= retval
;
989 dolog ("empty output buffer for command %#x\n",
992 retval
= s
->last_read_byte
;
997 case 0x0c: /* 0 can write */
998 retval
= s
->can_write
? 0 : 0x80;
1001 case 0x0d: /* timer interrupt clear */
1002 /* dolog ("timer interrupt clear\n"); */
1006 case 0x0e: /* data available status | irq 8 ack */
1007 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
1008 if (s
->mixer_regs
[0x82] & 1) {
1010 s
->mixer_regs
[0x82] &= 1;
1011 qemu_irq_lower (s
->pic
);
1015 case 0x0f: /* irq 16 ack */
1017 if (s
->mixer_regs
[0x82] & 2) {
1019 s
->mixer_regs
[0x82] &= 2;
1020 qemu_irq_lower (s
->pic
);
1029 ldebug ("read %#x -> %#x\n", nport
, retval
);
1035 dolog ("warning: dsp_read %#x error\n", nport
);
1039 static void reset_mixer (SB16State
*s
)
1043 memset (s
->mixer_regs
, 0xff, 0x7f);
1044 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
1046 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
1047 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
1048 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
1049 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
1051 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
1052 s
->mixer_regs
[0x0c] = 0;
1054 /* d5=output filt, d1=stereo switch */
1055 s
->mixer_regs
[0x0e] = 0;
1057 /* voice volume L d5,d7, R d1,d3 */
1058 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
1060 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
1062 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
1064 for (i
= 0x30; i
< 0x48; i
++) {
1065 s
->mixer_regs
[i
] = 0x20;
1069 static IO_WRITE_PROTO (mixer_write_indexb
)
1071 SB16State
*s
= opaque
;
1073 s
->mixer_nreg
= val
;
1076 static IO_WRITE_PROTO (mixer_write_datab
)
1078 SB16State
*s
= opaque
;
1081 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
1083 switch (s
->mixer_nreg
) {
1090 int irq
= irq_of_magic (val
);
1091 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
1102 dma
= lsbindex (val
& 0xf);
1103 hdma
= lsbindex (val
& 0xf0);
1104 if (dma
!= s
->dma
|| hdma
!= s
->hdma
) {
1106 "attempt to change DMA "
1107 "8bit %d(%d), 16bit %d(%d) (val=%#x)\n",
1108 dma
, s
->dma
, hdma
, s
->hdma
, val
);
1118 dolog ("attempt to write into IRQ status register (val=%#x)\n",
1123 if (s
->mixer_nreg
>= 0x80) {
1124 ldebug ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
1129 s
->mixer_regs
[s
->mixer_nreg
] = val
;
1132 static IO_WRITE_PROTO (mixer_write_indexw
)
1134 mixer_write_indexb (opaque
, nport
, val
& 0xff);
1135 mixer_write_datab (opaque
, nport
, (val
>> 8) & 0xff);
1138 static IO_READ_PROTO (mixer_read
)
1140 SB16State
*s
= opaque
;
1143 #ifndef DEBUG_SB16_MOST
1144 if (s
->mixer_nreg
!= 0x82) {
1145 ldebug ("mixer_read[%#x] -> %#x\n",
1146 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1149 ldebug ("mixer_read[%#x] -> %#x\n",
1150 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
1152 return s
->mixer_regs
[s
->mixer_nreg
];
1155 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1156 int dma_len
, int len
)
1159 uint8_t tmpbuf
[4096];
1165 int left
= dma_len
- dma_pos
;
1169 to_copy
= audio_MIN (temp
, left
);
1170 if (to_copy
> sizeof (tmpbuf
)) {
1171 to_copy
= sizeof (tmpbuf
);
1174 copied
= DMA_read_memory (nchan
, tmpbuf
, dma_pos
, to_copy
);
1175 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1178 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1189 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1191 SB16State
*s
= opaque
;
1192 int till
, copy
, written
, free
;
1194 if (s
->block_size
<= 0) {
1195 dolog ("invalid block size=%d nchan=%d dma_pos=%d dma_len=%d\n",
1196 s
->block_size
, nchan
, dma_pos
, dma_len
);
1200 if (s
->left_till_irq
< 0) {
1201 s
->left_till_irq
= s
->block_size
;
1205 free
= s
->audio_free
& ~s
->align
;
1206 if ((free
<= 0) || !dma_len
) {
1215 till
= s
->left_till_irq
;
1217 #ifdef DEBUG_SB16_MOST
1218 dolog ("pos:%06d %d till:%d len:%d\n",
1219 dma_pos
, free
, till
, dma_len
);
1223 if (0 == s
->dma_auto
) {
1228 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1229 dma_pos
= (dma_pos
+ written
) % dma_len
;
1230 s
->left_till_irq
-= written
;
1232 if (s
->left_till_irq
<= 0) {
1233 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1234 qemu_irq_raise (s
->pic
);
1235 if (0 == s
->dma_auto
) {
1241 #ifdef DEBUG_SB16_MOST
1242 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1243 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1247 while (s
->left_till_irq
<= 0) {
1248 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1254 static void SB_audio_callback (void *opaque
, int free
)
1256 SB16State
*s
= opaque
;
1257 s
->audio_free
= free
;
1260 static void SB_save (QEMUFile
*f
, void *opaque
)
1262 SB16State
*s
= opaque
;
1264 qemu_put_be32 (f
, s
->irq
);
1265 qemu_put_be32 (f
, s
->dma
);
1266 qemu_put_be32 (f
, s
->hdma
);
1267 qemu_put_be32 (f
, s
->port
);
1268 qemu_put_be32 (f
, s
->ver
);
1269 qemu_put_be32 (f
, s
->in_index
);
1270 qemu_put_be32 (f
, s
->out_data_len
);
1271 qemu_put_be32 (f
, s
->fmt_stereo
);
1272 qemu_put_be32 (f
, s
->fmt_signed
);
1273 qemu_put_be32 (f
, s
->fmt_bits
);
1274 qemu_put_be32s (f
, &s
->fmt
);
1275 qemu_put_be32 (f
, s
->dma_auto
);
1276 qemu_put_be32 (f
, s
->block_size
);
1277 qemu_put_be32 (f
, s
->fifo
);
1278 qemu_put_be32 (f
, s
->freq
);
1279 qemu_put_be32 (f
, s
->time_const
);
1280 qemu_put_be32 (f
, s
->speaker
);
1281 qemu_put_be32 (f
, s
->needed_bytes
);
1282 qemu_put_be32 (f
, s
->cmd
);
1283 qemu_put_be32 (f
, s
->use_hdma
);
1284 qemu_put_be32 (f
, s
->highspeed
);
1285 qemu_put_be32 (f
, s
->can_write
);
1286 qemu_put_be32 (f
, s
->v2x6
);
1288 qemu_put_8s (f
, &s
->csp_param
);
1289 qemu_put_8s (f
, &s
->csp_value
);
1290 qemu_put_8s (f
, &s
->csp_mode
);
1291 qemu_put_8s (f
, &s
->csp_param
);
1292 qemu_put_buffer (f
, s
->csp_regs
, 256);
1293 qemu_put_8s (f
, &s
->csp_index
);
1294 qemu_put_buffer (f
, s
->csp_reg83
, 4);
1295 qemu_put_be32 (f
, s
->csp_reg83r
);
1296 qemu_put_be32 (f
, s
->csp_reg83w
);
1298 qemu_put_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1299 qemu_put_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1300 qemu_put_8s (f
, &s
->test_reg
);
1301 qemu_put_8s (f
, &s
->last_read_byte
);
1303 qemu_put_be32 (f
, s
->nzero
);
1304 qemu_put_be32 (f
, s
->left_till_irq
);
1305 qemu_put_be32 (f
, s
->dma_running
);
1306 qemu_put_be32 (f
, s
->bytes_per_second
);
1307 qemu_put_be32 (f
, s
->align
);
1309 qemu_put_be32 (f
, s
->mixer_nreg
);
1310 qemu_put_buffer (f
, s
->mixer_regs
, 256);
1313 static int SB_load (QEMUFile
*f
, void *opaque
, int version_id
)
1315 SB16State
*s
= opaque
;
1317 if (version_id
!= 1) {
1321 s
->irq
=qemu_get_be32 (f
);
1322 s
->dma
=qemu_get_be32 (f
);
1323 s
->hdma
=qemu_get_be32 (f
);
1324 s
->port
=qemu_get_be32 (f
);
1325 s
->ver
=qemu_get_be32 (f
);
1326 s
->in_index
=qemu_get_be32 (f
);
1327 s
->out_data_len
=qemu_get_be32 (f
);
1328 s
->fmt_stereo
=qemu_get_be32 (f
);
1329 s
->fmt_signed
=qemu_get_be32 (f
);
1330 s
->fmt_bits
=qemu_get_be32 (f
);
1331 qemu_get_be32s (f
, &s
->fmt
);
1332 s
->dma_auto
=qemu_get_be32 (f
);
1333 s
->block_size
=qemu_get_be32 (f
);
1334 s
->fifo
=qemu_get_be32 (f
);
1335 s
->freq
=qemu_get_be32 (f
);
1336 s
->time_const
=qemu_get_be32 (f
);
1337 s
->speaker
=qemu_get_be32 (f
);
1338 s
->needed_bytes
=qemu_get_be32 (f
);
1339 s
->cmd
=qemu_get_be32 (f
);
1340 s
->use_hdma
=qemu_get_be32 (f
);
1341 s
->highspeed
=qemu_get_be32 (f
);
1342 s
->can_write
=qemu_get_be32 (f
);
1343 s
->v2x6
=qemu_get_be32 (f
);
1345 qemu_get_8s (f
, &s
->csp_param
);
1346 qemu_get_8s (f
, &s
->csp_value
);
1347 qemu_get_8s (f
, &s
->csp_mode
);
1348 qemu_get_8s (f
, &s
->csp_param
);
1349 qemu_get_buffer (f
, s
->csp_regs
, 256);
1350 qemu_get_8s (f
, &s
->csp_index
);
1351 qemu_get_buffer (f
, s
->csp_reg83
, 4);
1352 s
->csp_reg83r
=qemu_get_be32 (f
);
1353 s
->csp_reg83w
=qemu_get_be32 (f
);
1355 qemu_get_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1356 qemu_get_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1357 qemu_get_8s (f
, &s
->test_reg
);
1358 qemu_get_8s (f
, &s
->last_read_byte
);
1360 s
->nzero
=qemu_get_be32 (f
);
1361 s
->left_till_irq
=qemu_get_be32 (f
);
1362 s
->dma_running
=qemu_get_be32 (f
);
1363 s
->bytes_per_second
=qemu_get_be32 (f
);
1364 s
->align
=qemu_get_be32 (f
);
1366 s
->mixer_nreg
=qemu_get_be32 (f
);
1367 qemu_get_buffer (f
, s
->mixer_regs
, 256);
1370 AUD_close_out (&s
->card
, s
->voice
);
1374 if (s
->dma_running
) {
1376 struct audsettings as
;
1381 as
.nchannels
= 1 << s
->fmt_stereo
;
1385 s
->voice
= AUD_open_out (
1396 speaker (s
, s
->speaker
);
1401 int SB16_init (qemu_irq
*pic
)
1405 static const uint8_t dsp_write_ports
[] = {0x6, 0xc};
1406 static const uint8_t dsp_read_ports
[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1408 s
= qemu_mallocz (sizeof (*s
));
1411 s
->pic
= isa_reserve_irq(conf
.irq
);
1413 s
->hdma
= conf
.hdma
;
1414 s
->port
= conf
.port
;
1415 s
->ver
= conf
.ver_lo
| (conf
.ver_hi
<< 8);
1417 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1418 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1419 s
->mixer_regs
[0x82] = 2 << 5;
1422 s
->csp_regs
[9] = 0xf8;
1425 s
->aux_ts
= qemu_new_timer (vm_clock
, aux_timer
, s
);
1427 dolog ("warning: Could not create auxiliary timer\n");
1430 for (i
= 0; i
< ARRAY_SIZE (dsp_write_ports
); i
++) {
1431 register_ioport_write (s
->port
+ dsp_write_ports
[i
], 1, 1, dsp_write
, s
);
1434 for (i
= 0; i
< ARRAY_SIZE (dsp_read_ports
); i
++) {
1435 register_ioport_read (s
->port
+ dsp_read_ports
[i
], 1, 1, dsp_read
, s
);
1438 register_ioport_write (s
->port
+ 0x4, 1, 1, mixer_write_indexb
, s
);
1439 register_ioport_write (s
->port
+ 0x4, 1, 2, mixer_write_indexw
, s
);
1440 register_ioport_read (s
->port
+ 0x5, 1, 1, mixer_read
, s
);
1441 register_ioport_write (s
->port
+ 0x5, 1, 1, mixer_write_datab
, s
);
1443 DMA_register_channel (s
->hdma
, SB_read_DMA
, s
);
1444 DMA_register_channel (s
->dma
, SB_read_DMA
, s
);
1447 register_savevm ("sb16", 0, 1, SB_save
, SB_load
, s
);
1448 AUD_register_card ("sb16", &s
->card
);