2 * QEMU Soundblaster 16 emulation
4 * Copyright (c) 2003 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 MIN(a, b) ((a)>(b)?(b):(a))
27 #define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
29 #define log(...) do { \
30 fprintf (stderr, "sb16: " __VA_ARGS__); \
31 fputc ('\n', stderr); \
34 /* #define DEBUG_SB16 */
36 #define lwarn(...) fprintf (stderr, "sb16: " __VA_ARGS__)
37 #define linfo(...) fprintf (stderr, "sb16: " __VA_ARGS__)
38 #define ldebug(...) fprintf (stderr, "sb16: " __VA_ARGS__)
45 #define IO_READ_PROTO(name) \
46 uint32_t name (void *opaque, uint32_t nport)
47 #define IO_WRITE_PROTO(name) \
48 void name (void *opaque, uint32_t nport, uint32_t val)
50 static const char e3[] = "COPYRIGHT (C) CREATIVE TECHNOLOGY LTD, 1992.";
60 } sb = {5, 4, 5, 1, 5, 0x220, -1};
62 static int mix_block, noirq;
64 typedef struct SB16State {
90 uint8_t mixer_regs[256];
93 /* XXX: suppress that and use a context */
94 static struct SB16State dsp;
96 static void log_dsp (SB16State *dsp)
98 linfo ("%c:%c:%d:%c:dmabuf=%d:pos=%d:freq=%d:timeconst=%d:speaker=%d\n",
99 dsp->fmt_stereo ? 'S' : 'M',
100 dsp->fmt_signed ? 'S' : 'U',
102 dsp->dma_auto ? 'a' : 's',
103 dsp->dma_buffer_size,
110 static void control (int hold)
112 linfo ("%d high %d\n", hold, dsp.use_hdma);
115 DMA_hold_DREQ (sb.hdma);
117 DMA_hold_DREQ (sb.dma);
121 DMA_release_DREQ (sb.hdma);
123 DMA_release_DREQ (sb.dma);
127 static void dma_cmd (uint8_t cmd, uint8_t d0, int dma_len)
132 dsp.use_hdma = cmd < 0xc0;
133 dsp.fifo = (cmd >> 1) & 1;
134 dsp.dma_auto = (cmd >> 2) & 1;
146 dsp.fmt_signed = (d0 >> 4) & 1;
147 dsp.fmt_stereo = (d0 >> 5) & 1;
149 if (-1 != dsp.time_const) {
152 tmp = 256 - dsp.time_const;
153 dsp.freq = (1000000 + (tmp / 2)) / tmp;
155 bps = 1 << (16 == dsp.fmt_bits);
158 dsp.dma_buffer_size = (dma_len + 1) * bps;
160 linfo ("frequency %d, stereo %d, signed %d, bits %d, size %d, auto %d\n",
161 dsp.freq, dsp.fmt_stereo, dsp.fmt_signed, dsp.fmt_bits,
162 dsp.dma_buffer_size, dsp.dma_auto);
164 if (16 == dsp.fmt_bits) {
165 if (dsp.fmt_signed) {
173 if (dsp.fmt_signed) {
182 dsp.left_till_irq = dsp.dma_buffer_size;
185 mix_block = sb.mix_block;
190 align = bps << dsp.fmt_stereo;
191 mix_block = ((dsp.freq * align) / 100) & ~(align - 1);
194 AUD_reset (dsp.freq, 1 << dsp.fmt_stereo, fmt);
199 static inline void dsp_out_data(SB16State *dsp, int val)
201 if (dsp->out_data_len < sizeof(dsp->out_data))
202 dsp->out_data[dsp->out_data_len++] = val;
205 static void command (SB16State *dsp, uint8_t cmd)
207 linfo ("%#x\n", cmd);
209 if (cmd > 0xaf && cmd < 0xd0) {
218 log("%#x wrong bits", cmd);
221 dsp->needed_bytes = 3;
228 /* IMS uses those when probing for sound devices */
232 dsp->needed_bytes = 1;
237 dsp->needed_bytes = 2;
241 dsp->needed_bytes = 1;
242 dsp_out_data (dsp, 0);
246 dsp->needed_bytes = 1;
250 dsp->needed_bytes = 2;
251 dsp->dma_buffer_size = 0;
255 dsp_out_data(dsp, 0xff);
259 lwarn ("MIDI commands not implemented\n");
264 dsp->time_const = -1;
265 dsp->needed_bytes = 1;
271 dsp->time_const = -1;
272 dsp->needed_bytes = 2;
275 case 0x47: /* Continue Auto-Initialize DMA 16bit */
279 dsp->needed_bytes = 2;
282 case 0x27: /* ????????? */
296 /* if (dsp->fmt_signed) d0 |= 16; */
297 /* if (dsp->fmt_stereo) d0 |= 32; */
298 dma_cmd (cmd == 0x90 ? 0xc4 : 0xc0, d0, -1);
338 dsp->needed_bytes = 1;
342 dsp_out_data(dsp, sb.ver_lo);
343 dsp_out_data(dsp, sb.ver_hi);
349 for (i = sizeof (e3) - 1; i >= 0; --i)
350 dsp_out_data (dsp, e3[i]);
355 dsp_out_data(dsp, 0xaa);
356 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
357 pic_set_irq (sb.irq, 1);
361 log("%#x is unknown", cmd);
372 static void complete (SB16State *dsp)
374 linfo ("complete command %#x, in_index %d, needed_bytes %d\n",
375 dsp->cmd, dsp->in_index, dsp->needed_bytes);
377 if (dsp->cmd > 0xaf && dsp->cmd < 0xd0) {
380 d0 = dsp->in_data[0];
381 d1 = dsp->in_data[1];
382 d2 = dsp->in_data[2];
384 ldebug ("d0 = %d, d1 = %d, d2 = %d\n",
386 dma_cmd (dsp->cmd, d0, d1 + (d2 << 8));
405 d0 = dsp->in_data[0];
406 d1 = dsp->in_data[1];
408 save_left = dsp->left_till_irq;
409 save_pos = dsp->dma_pos;
410 dma_cmd (0xc0, 0, d0 + (d1 << 8));
411 dsp->left_till_irq = save_left;
412 dsp->dma_pos = save_pos;
414 linfo ("set buffer size data[%d, %d] %d pos %d\n",
415 d0, d1, dsp->dma_buffer_size, dsp->dma_pos);
420 dsp->time_const = dsp->in_data[0];
421 linfo ("set time const %d\n", dsp->time_const);
426 dsp->freq = dsp->in_data[1] + (dsp->in_data[0] << 8);
427 linfo ("set freq %#x, %#x = %d\n",
428 dsp->in_data[1], dsp->in_data[0], dsp->freq);
432 dsp->dma_buffer_size = dsp->in_data[1] + (dsp->in_data[0] << 8);
433 linfo ("set dma len %#x, %#x = %d\n",
434 dsp->in_data[1], dsp->in_data[0], dsp->dma_buffer_size);
438 dsp->out_data_len = 0;
439 linfo ("data = %#x\n", dsp->in_data[0]);
440 dsp_out_data(dsp, dsp->in_data[0] ^ 0xff);
444 log ("unrecognized command %#x", dsp->cmd);
453 static IO_WRITE_PROTO (dsp_write)
455 SB16State *dsp = opaque;
458 iport = nport - sb.port;
460 ldebug ("write %#x %#x\n", nport, iport);
466 else if ((1 == val) && (0 == dsp->v2x6)) {
468 dsp_out_data(dsp, 0xaa);
474 case 0xc: /* write data or command | write status */
475 if (0 == dsp->needed_bytes) {
477 if (0 == dsp->needed_bytes) {
482 dsp->in_data[dsp->in_index++] = val;
483 if (dsp->in_index == dsp->needed_bytes) {
484 dsp->needed_bytes = 0;
493 log ("(nport=%#x, val=%#x)", nport, val);
498 static IO_READ_PROTO (dsp_read)
500 SB16State *dsp = opaque;
503 iport = nport - sb.port;
507 case 0x6: /* reset */
510 case 0xa: /* read data */
511 if (dsp->out_data_len) {
512 retval = dsp->out_data[--dsp->out_data_len];
514 log("empty output buffer");
519 case 0xc: /* 0 can write */
523 case 0xd: /* timer interrupt clear */
524 log("timer interrupt clear");
527 case 0xe: /* data available status | irq 8 ack */
528 /* XXX drop pic irq line here? */
530 retval = (0 == dsp->out_data_len) ? 0 : 0x80;
531 dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
532 pic_set_irq (sb.irq, 0);
535 case 0xf: /* irq 16 ack */
536 /* XXX drop pic irq line here? */
539 dsp->mixer_regs[0x82] &= ~dsp->mixer_regs[0x80];
540 pic_set_irq (sb.irq, 0);
547 if ((0xc != iport) && (0xe != iport)) {
548 ldebug ("nport=%#x iport %#x = %#x\n",
549 nport, iport, retval);
558 static IO_WRITE_PROTO(mixer_write_indexb)
560 SB16State *dsp = opaque;
561 dsp->mixer_nreg = val;
564 static IO_WRITE_PROTO(mixer_write_datab)
566 SB16State *dsp = opaque;
568 if (dsp->mixer_nreg > 0x83)
570 dsp->mixer_regs[dsp->mixer_nreg] = val;
573 static IO_WRITE_PROTO(mixer_write_indexw)
575 mixer_write_indexb (opaque, nport, val & 0xff);
576 mixer_write_datab (opaque, nport, (val >> 8) & 0xff);
579 static IO_READ_PROTO(mixer_read)
581 SB16State *dsp = opaque;
582 return dsp->mixer_regs[dsp->mixer_nreg];
587 if (0 == dsp.speaker)
593 static int write_audio (uint32_t addr, int len, int size)
596 uint8_t tmpbuf[4096];
607 left_till_end = len - dsp.dma_pos;
609 to_copy = MIN (temp, left_till_end);
610 if (to_copy > sizeof(tmpbuf))
611 to_copy = sizeof(tmpbuf);
612 cpu_physical_memory_read(addr + dsp.dma_pos, tmpbuf, to_copy);
613 copied = AUD_write (tmpbuf, to_copy);
616 dsp.dma_pos += copied;
618 if (dsp.dma_pos == len) {
624 if (copied != to_copy)
631 static int SB_read_DMA (void *opaque, target_ulong addr, int size)
633 SB16State *dsp = opaque;
634 int free, till, copy, written;
636 if (0 == dsp->speaker)
639 if (dsp->left_till_irq < 0) {
640 dsp->left_till_irq += dsp->dma_buffer_size;
644 free = AUD_get_free ();
646 if ((free <= 0) || (0 == size)) {
651 copy = MIN (free, mix_block);
657 till = dsp->left_till_irq;
659 ldebug ("addr:%#010x free:%d till:%d size:%d\n",
660 addr, free, till, size);
662 if (0 == dsp->dma_auto) {
667 written = write_audio (addr, size, copy);
668 dsp->left_till_irq -= written;
669 AUD_adjust_estimate (free - written);
671 if (dsp->left_till_irq <= 0) {
672 dsp->mixer_regs[0x82] |= dsp->mixer_regs[0x80];
674 ldebug ("request irq\n");
675 pic_set_irq(sb.irq, 1);
678 if (0 == dsp->dma_auto) {
683 ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
684 dsp->dma_pos, free, size, dsp->left_till_irq, copy,
685 dsp->dma_buffer_size);
687 if (dsp->left_till_irq <= 0) {
688 dsp->left_till_irq += dsp->dma_buffer_size;
694 static int magic_of_irq (int irq)
706 log ("bad irq %d", irq);
712 static int irq_of_magic (int magic)
724 log ("bad irq magic %d", magic);
730 void SB16_init (void)
734 static const uint8_t dsp_write_ports[] = {0x6, 0xc};
735 static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
737 memset(s->mixer_regs, 0xff, sizeof(s->mixer_regs));
739 s->mixer_regs[0x0e] = ~0;
740 s->mixer_regs[0x80] = magic_of_irq (sb.irq);
741 s->mixer_regs[0x81] = 0x20 | (sb.dma << 1);
743 for (i = 0x30; i < 0x48; i++) {
744 s->mixer_regs[i] = 0x20;
747 for (i = 0; i < LENOFA (dsp_write_ports); i++) {
748 register_ioport_write (sb.port + dsp_write_ports[i], 1, 1, dsp_write, s);
751 for (i = 0; i < LENOFA (dsp_read_ports); i++) {
752 register_ioport_read (sb.port + dsp_read_ports[i], 1, 1, dsp_read, s);
755 register_ioport_write (sb.port + 0x4, 1, 1, mixer_write_indexb, s);
756 register_ioport_write (sb.port + 0x4, 1, 2, mixer_write_indexw, s);
757 register_ioport_read (sb.port + 0x5, 1, 1, mixer_read, s);
758 register_ioport_write (sb.port + 0x5, 1, 1, mixer_write_datab, s);
760 DMA_register_channel (sb.hdma, SB_read_DMA, s);
761 DMA_register_channel (sb.dma, SB_read_DMA, s);