mirror of https://github.com/xqemu/xqemu.git
qdev/isa: convert gravis ultrasound
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
This commit is contained in:
parent
f8ba784657
commit
9df34396d5
75
hw/gus.c
75
hw/gus.c
|
@ -54,16 +54,18 @@ static struct {
|
||||||
} conf = {0x240, 7, 3, 44100};
|
} conf = {0x240, 7, 3, 44100};
|
||||||
|
|
||||||
typedef struct GUSState {
|
typedef struct GUSState {
|
||||||
|
ISADevice dev;
|
||||||
GUSEmuState emu;
|
GUSEmuState emu;
|
||||||
QEMUSoundCard card;
|
QEMUSoundCard card;
|
||||||
int freq;
|
uint32_t freq;
|
||||||
|
uint32_t port;
|
||||||
int pos, left, shift, irqs;
|
int pos, left, shift, irqs;
|
||||||
GUSsample *mixbuf;
|
GUSsample *mixbuf;
|
||||||
uint8_t himem[1024 * 1024 + 32 + 4096];
|
uint8_t himem[1024 * 1024 + 32 + 4096];
|
||||||
int samples;
|
int samples;
|
||||||
SWVoiceOut *voice;
|
SWVoiceOut *voice;
|
||||||
int64_t last_ticks;
|
int64_t last_ticks;
|
||||||
qemu_irq *pic;
|
qemu_irq pic;
|
||||||
} GUSState;
|
} GUSState;
|
||||||
|
|
||||||
IO_READ_PROTO (gus_readb)
|
IO_READ_PROTO (gus_readb)
|
||||||
|
@ -168,8 +170,8 @@ reset:
|
||||||
int GUS_irqrequest (GUSEmuState *emu, int hwirq, int n)
|
int GUS_irqrequest (GUSEmuState *emu, int hwirq, int n)
|
||||||
{
|
{
|
||||||
GUSState *s = emu->opaque;
|
GUSState *s = emu->opaque;
|
||||||
/* qemu_irq_lower (s->pic[hwirq]); */
|
/* qemu_irq_lower (s->pic); */
|
||||||
qemu_irq_raise (s->pic[hwirq]);
|
qemu_irq_raise (s->pic);
|
||||||
s->irqs += n;
|
s->irqs += n;
|
||||||
ldebug ("irqrequest %d %d %d\n", hwirq, n, s->irqs);
|
ldebug ("irqrequest %d %d %d\n", hwirq, n, s->irqs);
|
||||||
return n;
|
return n;
|
||||||
|
@ -179,7 +181,7 @@ void GUS_irqclear (GUSEmuState *emu, int hwirq)
|
||||||
{
|
{
|
||||||
GUSState *s = emu->opaque;
|
GUSState *s = emu->opaque;
|
||||||
ldebug ("irqclear %d %d\n", hwirq, s->irqs);
|
ldebug ("irqclear %d %d\n", hwirq, s->irqs);
|
||||||
qemu_irq_lower (s->pic[hwirq]);
|
qemu_irq_lower (s->pic);
|
||||||
s->irqs -= 1;
|
s->irqs -= 1;
|
||||||
#ifdef IRQ_STORM
|
#ifdef IRQ_STORM
|
||||||
if (s->irqs > 0) {
|
if (s->irqs > 0) {
|
||||||
|
@ -250,16 +252,14 @@ static int GUS_load (QEMUFile *f, void *opaque, int version_id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GUS_init (qemu_irq *pic)
|
static int gus_initfn (ISADevice *dev)
|
||||||
{
|
{
|
||||||
GUSState *s;
|
GUSState *s = DO_UPCAST(GUSState, dev, dev);
|
||||||
struct audsettings as;
|
struct audsettings as;
|
||||||
|
|
||||||
s = qemu_mallocz (sizeof (*s));
|
|
||||||
|
|
||||||
AUD_register_card ("gus", &s->card);
|
AUD_register_card ("gus", &s->card);
|
||||||
|
|
||||||
as.freq = conf.freq;
|
as.freq = s->freq;
|
||||||
as.nchannels = 2;
|
as.nchannels = 2;
|
||||||
as.fmt = AUD_FMT_S16;
|
as.fmt = AUD_FMT_S16;
|
||||||
as.endianness = GUS_ENDIANNESS;
|
as.endianness = GUS_ENDIANNESS;
|
||||||
|
@ -283,34 +283,57 @@ int GUS_init (qemu_irq *pic)
|
||||||
s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
|
s->samples = AUD_get_buffer_size_out (s->voice) >> s->shift;
|
||||||
s->mixbuf = qemu_mallocz (s->samples << s->shift);
|
s->mixbuf = qemu_mallocz (s->samples << s->shift);
|
||||||
|
|
||||||
register_ioport_write (conf.port, 1, 1, gus_writeb, s);
|
register_ioport_write (s->port, 1, 1, gus_writeb, s);
|
||||||
register_ioport_write (conf.port, 1, 2, gus_writew, s);
|
register_ioport_write (s->port, 1, 2, gus_writew, s);
|
||||||
|
|
||||||
register_ioport_read ((conf.port + 0x100) & 0xf00, 1, 1, gus_readb, s);
|
register_ioport_read ((s->port + 0x100) & 0xf00, 1, 1, gus_readb, s);
|
||||||
register_ioport_read ((conf.port + 0x100) & 0xf00, 1, 2, gus_readw, s);
|
register_ioport_read ((s->port + 0x100) & 0xf00, 1, 2, gus_readw, s);
|
||||||
|
|
||||||
register_ioport_write (conf.port + 6, 10, 1, gus_writeb, s);
|
register_ioport_write (s->port + 6, 10, 1, gus_writeb, s);
|
||||||
register_ioport_write (conf.port + 6, 10, 2, gus_writew, s);
|
register_ioport_write (s->port + 6, 10, 2, gus_writew, s);
|
||||||
register_ioport_read (conf.port + 6, 10, 1, gus_readb, s);
|
register_ioport_read (s->port + 6, 10, 1, gus_readb, s);
|
||||||
register_ioport_read (conf.port + 6, 10, 2, gus_readw, s);
|
register_ioport_read (s->port + 6, 10, 2, gus_readw, s);
|
||||||
|
|
||||||
|
|
||||||
register_ioport_write (conf.port + 0x100, 8, 1, gus_writeb, s);
|
register_ioport_write (s->port + 0x100, 8, 1, gus_writeb, s);
|
||||||
register_ioport_write (conf.port + 0x100, 8, 2, gus_writew, s);
|
register_ioport_write (s->port + 0x100, 8, 2, gus_writew, s);
|
||||||
register_ioport_read (conf.port + 0x100, 8, 1, gus_readb, s);
|
register_ioport_read (s->port + 0x100, 8, 1, gus_readb, s);
|
||||||
register_ioport_read (conf.port + 0x100, 8, 2, gus_readw, s);
|
register_ioport_read (s->port + 0x100, 8, 2, gus_readw, s);
|
||||||
|
|
||||||
DMA_register_channel (conf.dma, GUS_read_DMA, s);
|
DMA_register_channel (conf.dma, GUS_read_DMA, s);
|
||||||
s->emu.gusirq = conf.irq;
|
|
||||||
s->emu.gusdma = conf.dma;
|
|
||||||
s->emu.himemaddr = s->himem;
|
s->emu.himemaddr = s->himem;
|
||||||
s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
|
s->emu.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
|
||||||
s->emu.opaque = s;
|
s->emu.opaque = s;
|
||||||
s->freq = conf.freq;
|
isa_init_irq(dev, &s->pic, s->emu.gusirq);
|
||||||
s->pic = pic;
|
|
||||||
|
|
||||||
AUD_set_active_out (s->voice, 1);
|
AUD_set_active_out (s->voice, 1);
|
||||||
|
|
||||||
register_savevm ("gus", 0, 2, GUS_save, GUS_load, s);
|
register_savevm ("gus", 0, 2, GUS_save, GUS_load, s);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GUS_init (qemu_irq *pic)
|
||||||
|
{
|
||||||
|
isa_create_simple("gus");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ISADeviceInfo gus_info = {
|
||||||
|
.qdev.name = "gus",
|
||||||
|
.qdev.desc = "Creative Sound Blaster 16",
|
||||||
|
.qdev.size = sizeof (GUSState),
|
||||||
|
.init = gus_initfn,
|
||||||
|
.qdev.props = (Property[]) {
|
||||||
|
DEFINE_PROP_UINT32 ("freq", GUSState, freq, 44100),
|
||||||
|
DEFINE_PROP_HEX32 ("iobase", GUSState, port, 0x240),
|
||||||
|
DEFINE_PROP_UINT32 ("irq", GUSState, emu.gusirq, 7),
|
||||||
|
DEFINE_PROP_UINT32 ("dma", GUSState, emu.gusdma, 3),
|
||||||
|
DEFINE_PROP_END_OF_LIST (),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void gus_register(void)
|
||||||
|
{
|
||||||
|
isa_qdev_register(&gus_info);
|
||||||
|
}
|
||||||
|
device_init(gus_register)
|
||||||
|
|
|
@ -46,8 +46,8 @@ typedef struct _GUSEmuState
|
||||||
{
|
{
|
||||||
GUSbyte *himemaddr; /* 1024*1024 bytes used for storing uploaded samples (+32 additional bytes for read padding) */
|
GUSbyte *himemaddr; /* 1024*1024 bytes used for storing uploaded samples (+32 additional bytes for read padding) */
|
||||||
GUSbyte *gusdatapos; /* (gusdataend-gusdata) bytes used for storing emulated GF1/mixer register states (32*32+4 bytes in initial GUSemu32 version) */
|
GUSbyte *gusdatapos; /* (gusdataend-gusdata) bytes used for storing emulated GF1/mixer register states (32*32+4 bytes in initial GUSemu32 version) */
|
||||||
int gusirq;
|
uint32_t gusirq;
|
||||||
int gusdma;
|
uint32_t gusdma;
|
||||||
unsigned int timer1fraction;
|
unsigned int timer1fraction;
|
||||||
unsigned int timer2fraction;
|
unsigned int timer2fraction;
|
||||||
void *opaque;
|
void *opaque;
|
||||||
|
|
Loading…
Reference in New Issue