mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-28 05:50:37 +00:00
audio fix (malc)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1137 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
9e89a4be8e
commit
15b6147000
65
hw/sb16.c
65
hw/sb16.c
@ -26,15 +26,16 @@
|
||||
#define LENOFA(a) ((int) (sizeof(a)/sizeof(a[0])))
|
||||
|
||||
#define dolog(...) AUD_log ("sb16", __VA_ARGS__)
|
||||
|
||||
/* #define DEBUG */
|
||||
/* #define DEBUG_SB16_MOST */
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ldebug(...) dolog (__VA_ARGS__)
|
||||
#else
|
||||
#define ldebug(...)
|
||||
#endif
|
||||
|
||||
/* #define DEBUG */
|
||||
/* #define DEBUG_SB16_MOST */
|
||||
|
||||
#define IO_READ_PROTO(name) \
|
||||
uint32_t name (void *opaque, uint32_t nport)
|
||||
#define IO_WRITE_PROTO(name) \
|
||||
@ -206,8 +207,18 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len)
|
||||
s->freq = (1000000 + (tmp / 2)) / tmp;
|
||||
}
|
||||
|
||||
if (-1 != dma_len)
|
||||
s->block_size = dma_len + 1;
|
||||
if (dma_len != -1)
|
||||
s->block_size = dma_len << s->fmt_stereo;
|
||||
else {
|
||||
/* This is apparently the only way to make both Act1/PL
|
||||
and SecondReality/FC work
|
||||
|
||||
Act1 sets block size via command 0x48 and it's an odd number
|
||||
SR does the same with even number
|
||||
Both use stereo, and Creatives own documentation states that
|
||||
0x48 sets block size in bytes less one.. go figure */
|
||||
s->block_size &= ~s->fmt_stereo;
|
||||
}
|
||||
|
||||
s->freq >>= s->fmt_stereo;
|
||||
s->left_till_irq = s->block_size;
|
||||
@ -216,6 +227,9 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len)
|
||||
s->dma_auto = (mask & DMA8_AUTO) != 0;
|
||||
s->align = (1 << s->fmt_stereo) - 1;
|
||||
|
||||
if (s->block_size & s->align)
|
||||
dolog ("warning: unaligned buffer\n");
|
||||
|
||||
ldebug ("freq %d, stereo %d, sign %d, bits %d, "
|
||||
"dma %d, auto %d, fifo %d, high %d\n",
|
||||
s->freq, s->fmt_stereo, s->fmt_signed, s->fmt_bits,
|
||||
@ -260,8 +274,13 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
|
||||
|
||||
s->block_size = dma_len + 1;
|
||||
s->block_size <<= (s->fmt_bits == 16);
|
||||
if (!s->dma_auto) /* Miles Sound System ? */
|
||||
if (!s->dma_auto) {
|
||||
/* It is clear that for DOOM and auto-init this value
|
||||
shouldn't take stereo into account, while Miles Sound Systems
|
||||
setsound.exe with single transfer mode wouldn't work without it
|
||||
wonders of SB16 yet again */
|
||||
s->block_size <<= s->fmt_stereo;
|
||||
}
|
||||
|
||||
ldebug ("freq %d, stereo %d, sign %d, bits %d, "
|
||||
"dma %d, auto %d, fifo %d, high %d\n",
|
||||
@ -290,6 +309,8 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
|
||||
s->bytes_per_second = (s->freq << s->fmt_stereo) << (s->fmt_bits == 16);
|
||||
s->highspeed = 0;
|
||||
s->align = (1 << (s->fmt_stereo + (s->fmt_bits == 16))) - 1;
|
||||
if (s->block_size & s->align)
|
||||
dolog ("warning: unaligned buffer\n");
|
||||
|
||||
if (s->freq)
|
||||
s->voice = AUD_open (s->voice, "sb16", s->freq,
|
||||
@ -373,6 +394,10 @@ static void command (SB16State *s, uint8_t cmd)
|
||||
s->block_size = 0;
|
||||
break;
|
||||
|
||||
case 0x1c: /* Auto-Initialize DMA DAC, 8-bit */
|
||||
control (s, 1);
|
||||
break;
|
||||
|
||||
case 0x20: /* Direct ADC, Juice/PL */
|
||||
dsp_out_data (s, 0xff);
|
||||
goto warn;
|
||||
@ -607,9 +632,7 @@ static void complete (SB16State *s)
|
||||
break;
|
||||
|
||||
case 0x14:
|
||||
dma_cmd8 (s, 0, dsp_get_lohi (s));
|
||||
/* s->can_write = 0; */
|
||||
/* qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + (ticks_per_sec * 320) / 1000000); */
|
||||
dma_cmd8 (s, 0, dsp_get_lohi (s) + 1);
|
||||
break;
|
||||
|
||||
case 0x40:
|
||||
@ -626,22 +649,20 @@ static void complete (SB16State *s)
|
||||
break;
|
||||
|
||||
case 0x48:
|
||||
s->block_size = dsp_get_lohi (s);
|
||||
/* s->highspeed = 1; */
|
||||
s->block_size = dsp_get_lohi (s) + 1;
|
||||
ldebug ("set dma block len %d\n", s->block_size);
|
||||
break;
|
||||
|
||||
case 0x80:
|
||||
{
|
||||
int samples, bytes;
|
||||
int freq, samples, bytes;
|
||||
int64_t ticks;
|
||||
|
||||
if (-1 == s->freq)
|
||||
s->freq = 11025;
|
||||
samples = dsp_get_lohi (s);
|
||||
freq = s->freq > 0 ? s->freq : 11025;
|
||||
samples = dsp_get_lohi (s) + 1;
|
||||
bytes = samples << s->fmt_stereo << (s->fmt_bits == 16);
|
||||
ticks = bytes ? (ticks_per_sec / (s->freq / bytes)) : 0;
|
||||
if (!bytes || ticks < ticks_per_sec / 1024)
|
||||
ticks = (bytes * ticks_per_sec) / freq;
|
||||
if (ticks < ticks_per_sec / 1024)
|
||||
pic_set_irq (s->irq, 1);
|
||||
else
|
||||
qemu_mod_timer (s->aux_ts, qemu_get_clock (vm_clock) + ticks);
|
||||
@ -658,7 +679,7 @@ static void complete (SB16State *s)
|
||||
|
||||
case 0xe2:
|
||||
d0 = dsp_get_data (s);
|
||||
dolog ("E2 = %#x\n", d0);
|
||||
ldebug ("E2 = %#x\n", d0);
|
||||
break;
|
||||
|
||||
case 0xe4:
|
||||
@ -967,6 +988,9 @@ static IO_WRITE_PROTO(mixer_write_indexw)
|
||||
static IO_READ_PROTO(mixer_read)
|
||||
{
|
||||
SB16State *s = opaque;
|
||||
#ifndef DEBUG_SB16_MOST
|
||||
if (s->mixer_nreg != 0x82)
|
||||
#endif
|
||||
ldebug ("mixer_read[%#x] -> %#x\n",
|
||||
s->mixer_nreg, s->mixer_regs[s->mixer_nreg]);
|
||||
return s->mixer_regs[s->mixer_nreg];
|
||||
@ -1049,8 +1073,9 @@ static int SB_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len)
|
||||
}
|
||||
|
||||
#ifdef DEBUG_SB16_MOST
|
||||
ldebug ("pos %5d free %5d size %5d till % 5d copy %5d dma size %5d\n",
|
||||
dma_pos, free, dma_len, s->left_till_irq, copy, s->block_size);
|
||||
ldebug ("pos %5d free %5d size %5d till % 5d copy %5d written %5d size %5d\n",
|
||||
dma_pos, free, dma_len, s->left_till_irq, copy, written,
|
||||
s->block_size);
|
||||
#endif
|
||||
|
||||
while (s->left_till_irq <= 0) {
|
||||
|
Loading…
Reference in New Issue
Block a user