Commit 9df34396 authored by Gerd Hoffmann's avatar Gerd Hoffmann Committed by malc
Browse files

qdev/isa: convert gravis ultrasound



Signed-off-by: default avatarGerd Hoffmann <kraxel@redhat.com>
parent f8ba7846
Loading
Loading
Loading
Loading
+49 −26
Original line number Diff line number Diff line
@@ -54,16 +54,18 @@ static struct {
} conf = {0x240, 7, 3, 44100};

typedef struct GUSState {
    ISADevice dev;
    GUSEmuState emu;
    QEMUSoundCard card;
    int freq;
    uint32_t freq;
    uint32_t port;
    int pos, left, shift, irqs;
    GUSsample *mixbuf;
    uint8_t himem[1024 * 1024 + 32 + 4096];
    int samples;
    SWVoiceOut *voice;
    int64_t last_ticks;
    qemu_irq *pic;
    qemu_irq pic;
} GUSState;

IO_READ_PROTO (gus_readb)
@@ -168,8 +170,8 @@ reset:
int GUS_irqrequest (GUSEmuState *emu, int hwirq, int n)
{
    GUSState *s = emu->opaque;
    /* qemu_irq_lower (s->pic[hwirq]); */
    qemu_irq_raise (s->pic[hwirq]);
    /* qemu_irq_lower (s->pic); */
    qemu_irq_raise (s->pic);
    s->irqs += n;
    ldebug ("irqrequest %d %d %d\n", hwirq, n, s->irqs);
    return n;
@@ -179,7 +181,7 @@ void GUS_irqclear (GUSEmuState *emu, int hwirq)
{
    GUSState *s = emu->opaque;
    ldebug ("irqclear %d %d\n", hwirq, s->irqs);
    qemu_irq_lower (s->pic[hwirq]);
    qemu_irq_lower (s->pic);
    s->irqs -= 1;
#ifdef IRQ_STORM
    if (s->irqs > 0) {
@@ -250,16 +252,14 @@ static int GUS_load (QEMUFile *f, void *opaque, int version_id)
    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;

    s = qemu_mallocz (sizeof (*s));

    AUD_register_card ("gus", &s->card);

    as.freq = conf.freq;
    as.freq = s->freq;
    as.nchannels = 2;
    as.fmt = AUD_FMT_S16;
    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->mixbuf = qemu_mallocz (s->samples << s->shift);

    register_ioport_write (conf.port, 1, 1, gus_writeb, s);
    register_ioport_write (conf.port, 1, 2, gus_writew, s);
    register_ioport_write (s->port, 1, 1, gus_writeb, 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 ((conf.port + 0x100) & 0xf00, 1, 2, gus_readw, s);
    register_ioport_read ((s->port + 0x100) & 0xf00, 1, 1, gus_readb, 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 (conf.port + 6, 10, 2, gus_writew, s);
    register_ioport_read (conf.port + 6, 10, 1, gus_readb, s);
    register_ioport_read (conf.port + 6, 10, 2, gus_readw, s);
    register_ioport_write (s->port + 6, 10, 1, gus_writeb, s);
    register_ioport_write (s->port + 6, 10, 2, gus_writew, s);
    register_ioport_read (s->port + 6, 10, 1, gus_readb, 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 (conf.port + 0x100, 8, 2, gus_writew, s);
    register_ioport_read (conf.port + 0x100, 8, 1, gus_readb, s);
    register_ioport_read (conf.port + 0x100, 8, 2, gus_readw, s);
    register_ioport_write (s->port + 0x100, 8, 1, gus_writeb, s);
    register_ioport_write (s->port + 0x100, 8, 2, gus_writew, s);
    register_ioport_read (s->port + 0x100, 8, 1, gus_readb, s);
    register_ioport_read (s->port + 0x100, 8, 2, gus_readw, 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.gusdatapos = s->emu.himemaddr + 1024 * 1024 + 32;
    s->emu.opaque = s;
    s->freq = conf.freq;
    s->pic = pic;
    isa_init_irq(dev, &s->pic, s->emu.gusirq);

    AUD_set_active_out (s->voice, 1);

    register_savevm ("gus", 0, 2, GUS_save, GUS_load, s);
    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)
+2 −2
Original line number Diff line number Diff line
@@ -46,8 +46,8 @@ typedef struct _GUSEmuState
{
 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) */
 int gusirq;
 int gusdma;
 uint32_t gusirq;
 uint32_t gusdma;
 unsigned int timer1fraction;
 unsigned int timer2fraction;
 void *opaque;