]>
git.proxmox.com Git - qemu.git/blob - hw/sb16.c
bca5795eac6083a4809eccc018ee98c17e56a340
2 * QEMU Soundblaster 16 emulation
4 * Copyright (c) 2003-2004 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
;
104 QEMUTimer
*ts
, *aux_ts
;
107 uint8_t mixer_regs
[256];
110 /* XXX: suppress that and use a context */
111 static struct SB16State dsp
;
113 static int magic_of_irq (int irq
)
125 dolog ("bad irq %d\n", irq
);
130 static int irq_of_magic (int magic
)
142 dolog ("bad irq magic %d\n", magic
);
148 static void log_dsp (SB16State
*dsp
)
150 ldebug ("%s:%s:%d:%s:dmasize=%d:freq=%d:const=%d:speaker=%d\n",
151 dsp
->fmt_stereo
? "Stereo" : "Mono",
152 dsp
->fmt_signed
? "Signed" : "Unsigned",
154 dsp
->dma_auto
? "Auto" : "Single",
162 static void speaker (SB16State
*s
, int on
)
165 /* AUD_enable (s->voice, on); */
168 static void control (SB16State
*s
, int hold
)
170 int dma
= s
->use_hdma
? s
->hdma
: s
->dma
;
171 s
->dma_running
= hold
;
173 ldebug ("hold %d high %d dma %d\n", hold
, s
->use_hdma
, dma
);
177 AUD_enable (s
->voice
, 1);
180 DMA_release_DREQ (dma
);
181 AUD_enable (s
->voice
, 0);
185 static void aux_timer (void *opaque
)
187 SB16State
*s
= opaque
;
189 pic_set_irq (s
->irq
, 1);
195 static void dma_cmd8 (SB16State
*s
, int mask
, int dma_len
)
201 s
->fmt_stereo
= (s
->mixer_regs
[0x0e] & 2) != 0;
202 if (-1 == s
->time_const
) {
206 int tmp
= (256 - s
->time_const
);
207 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
211 s
->block_size
= dma_len
<< s
->fmt_stereo
;
213 /* This is apparently the only way to make both Act1/PL
214 and SecondReality/FC work
216 Act1 sets block size via command 0x48 and it's an odd number
217 SR does the same with even number
218 Both use stereo, and Creatives own documentation states that
219 0x48 sets block size in bytes less one.. go figure */
220 s
->block_size
&= ~s
->fmt_stereo
;
223 s
->freq
>>= s
->fmt_stereo
;
224 s
->left_till_irq
= s
->block_size
;
225 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
);
226 /* s->highspeed = (mask & DMA8_HIGH) != 0; */
227 s
->dma_auto
= (mask
& DMA8_AUTO
) != 0;
228 s
->align
= (1 << s
->fmt_stereo
) - 1;
230 if (s
->block_size
& s
->align
)
231 dolog ("warning: unaligned buffer\n");
233 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
234 "dma %d, auto %d, fifo %d, high %d\n",
235 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
236 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
239 s
->voice
= AUD_open (s
->voice
, "sb16", s
->freq
,
240 1 << s
->fmt_stereo
, s
->fmt
);
246 static void dma_cmd (SB16State
*s
, uint8_t cmd
, uint8_t d0
, int dma_len
)
248 s
->use_hdma
= cmd
< 0xc0;
249 s
->fifo
= (cmd
>> 1) & 1;
250 s
->dma_auto
= (cmd
>> 2) & 1;
251 s
->fmt_signed
= (d0
>> 4) & 1;
252 s
->fmt_stereo
= (d0
>> 5) & 1;
264 if (-1 != s
->time_const
) {
266 int tmp
= 256 - s
->time_const
;
267 s
->freq
= (1000000 + (tmp
/ 2)) / tmp
;
269 /* s->freq = 1000000 / ((255 - s->time_const) << s->fmt_stereo); */
270 s
->freq
= 1000000 / ((255 - s
->time_const
));
275 s
->block_size
= dma_len
+ 1;
276 s
->block_size
<<= (s
->fmt_bits
== 16);
278 /* It is clear that for DOOM and auto-init this value
279 shouldn't take stereo into account, while Miles Sound Systems
280 setsound.exe with single transfer mode wouldn't work without it
281 wonders of SB16 yet again */
282 s
->block_size
<<= s
->fmt_stereo
;
285 ldebug ("freq %d, stereo %d, sign %d, bits %d, "
286 "dma %d, auto %d, fifo %d, high %d\n",
287 s
->freq
, s
->fmt_stereo
, s
->fmt_signed
, s
->fmt_bits
,
288 s
->block_size
, s
->dma_auto
, s
->fifo
, s
->highspeed
);
290 if (16 == s
->fmt_bits
) {
292 s
->fmt
= AUD_FMT_S16
;
295 s
->fmt
= AUD_FMT_U16
;
307 s
->left_till_irq
= s
->block_size
;
309 s
->bytes_per_second
= (s
->freq
<< s
->fmt_stereo
) << (s
->fmt_bits
== 16);
311 s
->align
= (1 << (s
->fmt_stereo
+ (s
->fmt_bits
== 16))) - 1;
312 if (s
->block_size
& s
->align
)
313 dolog ("warning: unaligned buffer\n");
316 s
->voice
= AUD_open (s
->voice
, "sb16", s
->freq
,
317 1 << s
->fmt_stereo
, s
->fmt
);
323 static inline void dsp_out_data (SB16State
*s
, uint8_t val
)
325 ldebug ("outdata %#x\n", val
);
326 if (s
->out_data_len
< sizeof (s
->out_data
))
327 s
->out_data
[s
->out_data_len
++] = val
;
330 static inline uint8_t dsp_get_data (SB16State
*s
)
333 return s
->in2_data
[--s
->in_index
];
335 dolog ("buffer underflow\n");
340 static void command (SB16State
*s
, uint8_t cmd
)
342 ldebug ("command %#x\n", cmd
);
344 if (cmd
> 0xaf && cmd
< 0xd0) {
346 dolog ("ADC not yet supported (command %#x)\n", cmd
);
354 dolog ("%#x wrong bits\n", cmd
);
361 dsp_out_data (s
, 0x10); /* s->csp_param); */
373 /* __asm__ ("int3"); */
381 dsp_out_data (s
, 0xf8);
397 case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
401 case 0x20: /* Direct ADC, Juice/PL */
402 dsp_out_data (s
, 0xff);
406 dolog ("MIDI command(0x35) not implemented\n");
428 dsp_out_data (s
, 0xaa);
431 case 0x47: /* Continue Auto-Initialize DMA 16bit */
444 dma_cmd8 (s
, ((cmd
& 1) == 0) | DMA8_HIGH
, -1);
447 case 0xd0: /* halt DMA operation. 8bit */
451 case 0xd1: /* speaker on */
455 case 0xd3: /* speaker off */
459 case 0xd4: /* continue DMA operation. 8bit */
463 case 0xd5: /* halt DMA operation. 16bit */
467 case 0xd6: /* continue DMA operation. 16bit */
471 case 0xd9: /* exit auto-init DMA after this block. 16bit */
475 case 0xda: /* exit auto-init DMA after this block. 8bit */
484 dsp_out_data (s
, s
->ver
& 0xff);
485 dsp_out_data (s
, s
->ver
>> 8);
495 for (i
= sizeof (e3
) - 1; i
>= 0; --i
)
496 dsp_out_data (s
, e3
[i
]);
500 case 0xe4: /* write test reg */
505 dolog ("Attempt to probe for ESS (0xe7)?\n");
508 case 0xe8: /* read test reg */
509 dsp_out_data (s
, s
->test_reg
);
514 dsp_out_data (s
, 0xaa);
515 s
->mixer_regs
[0x82] |= (cmd
== 0xf2) ? 1 : 2;
516 pic_set_irq (s
->irq
, 1);
527 case 0xfc: /* FIXME */
532 dolog ("unrecognized command %#x\n", cmd
);
538 if (!s
->needed_bytes
)
543 dolog ("warning: command %#x,%d is not truly understood yet\n",
544 cmd
, s
->needed_bytes
);
549 static uint16_t dsp_get_lohi (SB16State
*s
)
551 uint8_t hi
= dsp_get_data (s
);
552 uint8_t lo
= dsp_get_data (s
);
553 return (hi
<< 8) | lo
;
556 static uint16_t dsp_get_hilo (SB16State
*s
)
558 uint8_t lo
= dsp_get_data (s
);
559 uint8_t hi
= dsp_get_data (s
);
560 return (hi
<< 8) | lo
;
563 static void complete (SB16State
*s
)
566 ldebug ("complete command %#x, in_index %d, needed_bytes %d\n",
567 s
->cmd
, s
->in_index
, s
->needed_bytes
);
569 if (s
->cmd
> 0xaf && s
->cmd
< 0xd0) {
570 d2
= dsp_get_data (s
);
571 d1
= dsp_get_data (s
);
572 d0
= dsp_get_data (s
);
575 dolog ("ADC params cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
579 ldebug ("cmd = %#x d0 = %d, d1 = %d, d2 = %d\n",
581 dma_cmd (s
, s
->cmd
, d0
, d1
+ (d2
<< 8));
587 s
->csp_mode
= dsp_get_data (s
);
590 ldebug ("CSP command 0x04: mode=%#x\n", s
->csp_mode
);
594 s
->csp_param
= dsp_get_data (s
);
595 s
->csp_value
= dsp_get_data (s
);
596 ldebug ("CSP command 0x05: param=%#x value=%#x\n",
602 d0
= dsp_get_data (s
);
603 d1
= dsp_get_data (s
);
604 ldebug ("write CSP register %d <- %#x\n", d1
, d0
);
606 ldebug ("0x83[%d] <- %#x\n", s
->csp_reg83r
, d0
);
607 s
->csp_reg83
[s
->csp_reg83r
% 4] = d0
;
611 s
->csp_regs
[d1
] = d0
;
615 d0
= dsp_get_data (s
);
616 ldebug ("read CSP register %#x -> %#x, mode=%#x\n",
617 d0
, s
->csp_regs
[d0
], s
->csp_mode
);
619 ldebug ("0x83[%d] -> %#x\n",
621 s
->csp_reg83
[s
->csp_reg83w
% 4]);
622 dsp_out_data (s
, s
->csp_reg83
[s
->csp_reg83w
% 4]);
626 dsp_out_data (s
, s
->csp_regs
[d0
]);
630 d0
= dsp_get_data (s
);
631 dolog ("cmd 0x10 d0=%#x\n", d0
);
635 dma_cmd8 (s
, 0, dsp_get_lohi (s
) + 1);
639 s
->time_const
= dsp_get_data (s
);
640 ldebug ("set time const %d\n", s
->time_const
);
643 case 0x42: /* FT2 sets output freq with this, go figure */
644 dolog ("cmd 0x42 might not do what it think it should\n");
647 s
->freq
= dsp_get_hilo (s
);
648 ldebug ("set freq %d\n", s
->freq
);
652 s
->block_size
= dsp_get_lohi (s
) + 1;
653 ldebug ("set dma block len %d\n", s
->block_size
);
658 int freq
, samples
, bytes
;
661 freq
= s
->freq
> 0 ? s
->freq
: 11025;
662 samples
= dsp_get_lohi (s
) + 1;
663 bytes
= samples
<< s
->fmt_stereo
<< (s
->fmt_bits
== 16);
664 ticks
= (bytes
* ticks_per_sec
) / freq
;
665 if (ticks
< ticks_per_sec
/ 1024)
666 pic_set_irq (s
->irq
, 1);
668 qemu_mod_timer (s
->aux_ts
, qemu_get_clock (vm_clock
) + ticks
);
669 ldebug ("mix silence %d %d %lld\n", samples
, bytes
, ticks
);
674 d0
= dsp_get_data (s
);
676 ldebug ("E0 data = %#x\n", d0
);
677 dsp_out_data(s
, ~d0
);
681 d0
= dsp_get_data (s
);
682 ldebug ("E2 = %#x\n", d0
);
686 s
->test_reg
= dsp_get_data (s
);
690 d0
= dsp_get_data (s
);
691 ldebug ("command 0xf9 with %#x\n", d0
);
694 dsp_out_data (s
, 0xff);
698 dsp_out_data (s
, 0x07);
702 dsp_out_data (s
, 0x38);
706 dsp_out_data (s
, 0x00);
712 dolog ("complete: unrecognized command %#x\n", s
->cmd
);
722 static void reset (SB16State
*s
)
724 pic_set_irq (s
->irq
, 0);
726 pic_set_irq (s
->irq
, 1);
727 pic_set_irq (s
->irq
, 0);
730 s
->mixer_regs
[0x82] = 0;
734 s
->left_till_irq
= 0;
741 dsp_out_data(s
, 0xaa);
746 static IO_WRITE_PROTO (dsp_write
)
748 SB16State
*s
= opaque
;
751 iport
= nport
- s
->port
;
753 ldebug ("write %#x <- %#x\n", nport
, val
);
759 if (0 && s
->highspeed
) {
761 pic_set_irq (s
->irq
, 0);
771 case 0x03: /* FreeBSD kludge */
776 s
->v2x6
= 0; /* Prince of Persia, csp.sys, diagnose.exe */
779 case 0xb8: /* Panic */
784 dsp_out_data (s
, 0x38);
795 case 0x0c: /* write data or command | write status */
796 /* if (s->highspeed) */
799 if (0 == s
->needed_bytes
) {
802 if (0 == s
->needed_bytes
) {
808 if (s
->in_index
== sizeof (s
->in2_data
)) {
809 dolog ("in data overrun\n");
812 s
->in2_data
[s
->in_index
++] = val
;
813 if (s
->in_index
== s
->needed_bytes
) {
825 ldebug ("(nport=%#x, val=%#x)\n", nport
, val
);
830 static IO_READ_PROTO (dsp_read
)
832 SB16State
*s
= opaque
;
833 int iport
, retval
, ack
= 0;
835 iport
= nport
- s
->port
;
838 case 0x06: /* reset */
842 case 0x0a: /* read data */
843 if (s
->out_data_len
) {
844 retval
= s
->out_data
[--s
->out_data_len
];
845 s
->last_read_byte
= retval
;
848 dolog ("empty output buffer\n");
849 retval
= s
->last_read_byte
;
854 case 0x0c: /* 0 can write */
855 retval
= s
->can_write
? 0 : 0x80;
858 case 0x0d: /* timer interrupt clear */
859 /* dolog ("timer interrupt clear\n"); */
863 case 0x0e: /* data available status | irq 8 ack */
864 retval
= (!s
->out_data_len
|| s
->highspeed
) ? 0 : 0x80;
865 if (s
->mixer_regs
[0x82] & 1) {
867 s
->mixer_regs
[0x82] &= 1;
868 pic_set_irq (s
->irq
, 0);
872 case 0x0f: /* irq 16 ack */
874 if (s
->mixer_regs
[0x82] & 2) {
876 s
->mixer_regs
[0x82] &= 2;
877 pic_set_irq (s
->irq
, 0);
886 ldebug ("read %#x -> %#x\n", nport
, retval
);
891 dolog ("WARNING dsp_read %#x error\n", nport
);
895 static void reset_mixer (SB16State
*s
)
899 memset (s
->mixer_regs
, 0xff, 0x7f);
900 memset (s
->mixer_regs
+ 0x83, 0xff, sizeof (s
->mixer_regs
) - 0x83);
902 s
->mixer_regs
[0x02] = 4; /* master volume 3bits */
903 s
->mixer_regs
[0x06] = 4; /* MIDI volume 3bits */
904 s
->mixer_regs
[0x08] = 0; /* CD volume 3bits */
905 s
->mixer_regs
[0x0a] = 0; /* voice volume 2bits */
907 /* d5=input filt, d3=lowpass filt, d1,d2=input source */
908 s
->mixer_regs
[0x0c] = 0;
910 /* d5=output filt, d1=stereo switch */
911 s
->mixer_regs
[0x0e] = 0;
913 /* voice volume L d5,d7, R d1,d3 */
914 s
->mixer_regs
[0x04] = (4 << 5) | (4 << 1);
916 s
->mixer_regs
[0x22] = (4 << 5) | (4 << 1);
918 s
->mixer_regs
[0x26] = (4 << 5) | (4 << 1);
920 for (i
= 0x30; i
< 0x48; i
++) {
921 s
->mixer_regs
[i
] = 0x20;
925 static IO_WRITE_PROTO(mixer_write_indexb
)
927 SB16State
*s
= opaque
;
931 static IO_WRITE_PROTO(mixer_write_datab
)
933 SB16State
*s
= opaque
;
935 ldebug ("mixer_write [%#x] <- %#x\n", s
->mixer_nreg
, val
);
936 if (s
->mixer_nreg
> sizeof (s
->mixer_regs
))
939 switch (s
->mixer_nreg
) {
946 int irq
= irq_of_magic (val
);
947 ldebug ("setting irq to %d (val=%#x)\n", irq
, val
);
957 dma
= lsbindex (val
& 0xf);
958 hdma
= lsbindex (val
& 0xf0);
959 dolog ("attempt to set DMA register 8bit %d, 16bit %d (val=%#x)\n",
969 dolog ("attempt to write into IRQ status register (val=%#x)\n",
974 if (s
->mixer_nreg
>= 0x80)
975 dolog ("attempt to write mixer[%#x] <- %#x\n", s
->mixer_nreg
, val
);
979 s
->mixer_regs
[s
->mixer_nreg
] = val
;
982 static IO_WRITE_PROTO(mixer_write_indexw
)
984 mixer_write_indexb (opaque
, nport
, val
& 0xff);
985 mixer_write_datab (opaque
, nport
, (val
>> 8) & 0xff);
988 static IO_READ_PROTO(mixer_read
)
990 SB16State
*s
= opaque
;
991 #ifndef DEBUG_SB16_MOST
992 if (s
->mixer_nreg
!= 0x82)
994 ldebug ("mixer_read[%#x] -> %#x\n",
995 s
->mixer_nreg
, s
->mixer_regs
[s
->mixer_nreg
]);
996 return s
->mixer_regs
[s
->mixer_nreg
];
999 static int write_audio (SB16State
*s
, int nchan
, int dma_pos
,
1000 int dma_len
, int len
)
1003 uint8_t tmpbuf
[4096];
1009 int left
= dma_len
- dma_pos
;
1010 int to_copy
, copied
;
1012 to_copy
= audio_MIN (temp
, left
);
1013 if (to_copy
> sizeof(tmpbuf
))
1014 to_copy
= sizeof(tmpbuf
);
1016 copied
= DMA_read_memory (nchan
, tmpbuf
, dma_pos
, to_copy
);
1017 copied
= AUD_write (s
->voice
, tmpbuf
, copied
);
1020 dma_pos
= (dma_pos
+ copied
) % dma_len
;
1030 static int SB_read_DMA (void *opaque
, int nchan
, int dma_pos
, int dma_len
)
1032 SB16State
*s
= opaque
;
1033 int free
, rfree
, till
, copy
, written
, elapsed
;
1035 if (s
->left_till_irq
< 0) {
1036 s
->left_till_irq
= s
->block_size
;
1039 elapsed
= AUD_calc_elapsed (s
->voice
);
1040 free
= elapsed
;/* AUD_get_free (s->voice); */
1042 free
= audio_MIN (free
, elapsed
) & ~s
->align
;
1044 if ((free
<= 0) || !dma_len
) {
1049 till
= s
->left_till_irq
;
1051 #ifdef DEBUG_SB16_MOST
1052 dolog ("pos:%06d free:%d,%d till:%d len:%d\n",
1053 dma_pos
, free
, AUD_get_free (s
->voice
), till
, dma_len
);
1057 if (0 == s
->dma_auto
) {
1062 written
= write_audio (s
, nchan
, dma_pos
, dma_len
, copy
);
1063 dma_pos
= (dma_pos
+ written
) % dma_len
;
1064 s
->left_till_irq
-= written
;
1066 if (s
->left_till_irq
<= 0) {
1067 s
->mixer_regs
[0x82] |= (nchan
& 4) ? 2 : 1;
1068 pic_set_irq (s
->irq
, 1);
1069 if (0 == s
->dma_auto
) {
1075 #ifdef DEBUG_SB16_MOST
1076 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
1077 dma_pos
, free
, dma_len
, s
->left_till_irq
, copy
, written
,
1081 while (s
->left_till_irq
<= 0) {
1082 s
->left_till_irq
= s
->block_size
+ s
->left_till_irq
;
1085 AUD_adjust (s
->voice
, written
);
1089 void SB_timer (void *opaque
)
1091 SB16State
*s
= opaque
;
1093 qemu_mod_timer (s
->ts
, qemu_get_clock (vm_clock
) + 1);
1096 static void SB_save (QEMUFile
*f
, void *opaque
)
1098 SB16State
*s
= opaque
;
1100 qemu_put_be32s (f
, &s
->irq
);
1101 qemu_put_be32s (f
, &s
->dma
);
1102 qemu_put_be32s (f
, &s
->hdma
);
1103 qemu_put_be32s (f
, &s
->port
);
1104 qemu_put_be32s (f
, &s
->ver
);
1105 qemu_put_be32s (f
, &s
->in_index
);
1106 qemu_put_be32s (f
, &s
->out_data_len
);
1107 qemu_put_be32s (f
, &s
->fmt_stereo
);
1108 qemu_put_be32s (f
, &s
->fmt_signed
);
1109 qemu_put_be32s (f
, &s
->fmt_bits
);
1110 qemu_put_be32s (f
, &s
->fmt
);
1111 qemu_put_be32s (f
, &s
->dma_auto
);
1112 qemu_put_be32s (f
, &s
->block_size
);
1113 qemu_put_be32s (f
, &s
->fifo
);
1114 qemu_put_be32s (f
, &s
->freq
);
1115 qemu_put_be32s (f
, &s
->time_const
);
1116 qemu_put_be32s (f
, &s
->speaker
);
1117 qemu_put_be32s (f
, &s
->needed_bytes
);
1118 qemu_put_be32s (f
, &s
->cmd
);
1119 qemu_put_be32s (f
, &s
->use_hdma
);
1120 qemu_put_be32s (f
, &s
->highspeed
);
1121 qemu_put_be32s (f
, &s
->can_write
);
1122 qemu_put_be32s (f
, &s
->v2x6
);
1124 qemu_put_8s (f
, &s
->csp_param
);
1125 qemu_put_8s (f
, &s
->csp_value
);
1126 qemu_put_8s (f
, &s
->csp_mode
);
1127 qemu_put_8s (f
, &s
->csp_param
);
1128 qemu_put_buffer (f
, s
->csp_regs
, 256);
1129 qemu_put_8s (f
, &s
->csp_index
);
1130 qemu_put_buffer (f
, s
->csp_reg83
, 4);
1131 qemu_put_be32s (f
, &s
->csp_reg83r
);
1132 qemu_put_be32s (f
, &s
->csp_reg83w
);
1134 qemu_put_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1135 qemu_put_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1136 qemu_put_8s (f
, &s
->test_reg
);
1137 qemu_put_8s (f
, &s
->last_read_byte
);
1139 qemu_put_be32s (f
, &s
->nzero
);
1140 qemu_put_be32s (f
, &s
->left_till_irq
);
1141 qemu_put_be32s (f
, &s
->dma_running
);
1142 qemu_put_be32s (f
, &s
->bytes_per_second
);
1143 qemu_put_be32s (f
, &s
->align
);
1145 qemu_put_be32s (f
, &s
->mixer_nreg
);
1146 qemu_put_buffer (f
, s
->mixer_regs
, 256);
1149 static int SB_load (QEMUFile
*f
, void *opaque
, int version_id
)
1151 SB16State
*s
= opaque
;
1153 if (version_id
!= 1)
1156 qemu_get_be32s (f
, &s
->irq
);
1157 qemu_get_be32s (f
, &s
->dma
);
1158 qemu_get_be32s (f
, &s
->hdma
);
1159 qemu_get_be32s (f
, &s
->port
);
1160 qemu_get_be32s (f
, &s
->ver
);
1161 qemu_get_be32s (f
, &s
->in_index
);
1162 qemu_get_be32s (f
, &s
->out_data_len
);
1163 qemu_get_be32s (f
, &s
->fmt_stereo
);
1164 qemu_get_be32s (f
, &s
->fmt_signed
);
1165 qemu_get_be32s (f
, &s
->fmt_bits
);
1166 qemu_get_be32s (f
, &s
->fmt
);
1167 qemu_get_be32s (f
, &s
->dma_auto
);
1168 qemu_get_be32s (f
, &s
->block_size
);
1169 qemu_get_be32s (f
, &s
->fifo
);
1170 qemu_get_be32s (f
, &s
->freq
);
1171 qemu_get_be32s (f
, &s
->time_const
);
1172 qemu_get_be32s (f
, &s
->speaker
);
1173 qemu_get_be32s (f
, &s
->needed_bytes
);
1174 qemu_get_be32s (f
, &s
->cmd
);
1175 qemu_get_be32s (f
, &s
->use_hdma
);
1176 qemu_get_be32s (f
, &s
->highspeed
);
1177 qemu_get_be32s (f
, &s
->can_write
);
1178 qemu_get_be32s (f
, &s
->v2x6
);
1180 qemu_get_8s (f
, &s
->csp_param
);
1181 qemu_get_8s (f
, &s
->csp_value
);
1182 qemu_get_8s (f
, &s
->csp_mode
);
1183 qemu_get_8s (f
, &s
->csp_param
);
1184 qemu_get_buffer (f
, s
->csp_regs
, 256);
1185 qemu_get_8s (f
, &s
->csp_index
);
1186 qemu_get_buffer (f
, s
->csp_reg83
, 4);
1187 qemu_get_be32s (f
, &s
->csp_reg83r
);
1188 qemu_get_be32s (f
, &s
->csp_reg83w
);
1190 qemu_get_buffer (f
, s
->in2_data
, sizeof (s
->in2_data
));
1191 qemu_get_buffer (f
, s
->out_data
, sizeof (s
->out_data
));
1192 qemu_get_8s (f
, &s
->test_reg
);
1193 qemu_get_8s (f
, &s
->last_read_byte
);
1195 qemu_get_be32s (f
, &s
->nzero
);
1196 qemu_get_be32s (f
, &s
->left_till_irq
);
1197 qemu_get_be32s (f
, &s
->dma_running
);
1198 qemu_get_be32s (f
, &s
->bytes_per_second
);
1199 qemu_get_be32s (f
, &s
->align
);
1201 qemu_get_be32s (f
, &s
->mixer_nreg
);
1202 qemu_get_buffer (f
, s
->mixer_regs
, 256);
1205 AUD_close (s
->voice
);
1209 if (s
->dma_running
) {
1211 s
->voice
= AUD_open (s
->voice
, "sb16", s
->freq
,
1212 1 << s
->fmt_stereo
, s
->fmt
);
1215 speaker (s
, s
->speaker
);
1220 void SB16_init (void)
1222 SB16State
*s
= &dsp
;
1224 static const uint8_t dsp_write_ports
[] = {0x6, 0xc};
1225 static const uint8_t dsp_read_ports
[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
1227 s
->ts
= qemu_new_timer (vm_clock
, SB_timer
, s
);
1233 s
->hdma
= conf
.hdma
;
1234 s
->port
= conf
.port
;
1235 s
->ver
= conf
.ver_lo
| (conf
.ver_hi
<< 8);
1237 s
->mixer_regs
[0x80] = magic_of_irq (s
->irq
);
1238 s
->mixer_regs
[0x81] = (1 << s
->dma
) | (1 << s
->hdma
);
1239 s
->mixer_regs
[0x82] = 2 << 5;
1242 s
->csp_regs
[9] = 0xf8;
1245 s
->aux_ts
= qemu_new_timer (vm_clock
, aux_timer
, s
);
1249 for (i
= 0; i
< LENOFA (dsp_write_ports
); i
++) {
1250 register_ioport_write (s
->port
+ dsp_write_ports
[i
], 1, 1, dsp_write
, s
);
1253 for (i
= 0; i
< LENOFA (dsp_read_ports
); i
++) {
1254 register_ioport_read (s
->port
+ dsp_read_ports
[i
], 1, 1, dsp_read
, s
);
1257 register_ioport_write (s
->port
+ 0x4, 1, 1, mixer_write_indexb
, s
);
1258 register_ioport_write (s
->port
+ 0x4, 1, 2, mixer_write_indexw
, s
);
1259 register_ioport_read (s
->port
+ 0x5, 1, 1, mixer_read
, s
);
1260 register_ioport_write (s
->port
+ 0x5, 1, 1, mixer_write_datab
, s
);
1262 DMA_register_channel (s
->hdma
, SB_read_DMA
, s
);
1263 DMA_register_channel (s
->dma
, SB_read_DMA
, s
);
1266 qemu_mod_timer (s
->ts
, qemu_get_clock (vm_clock
) + 1);
1267 register_savevm ("sb16", 0, 1, SB_save
, SB_load
, s
);