PCI and IRQ rework, pci.c rewritten from ground up, fixes numerous issues such as the bridge being added when the number of normal PCI devices equals the number of normal PCI slots, Windows 95 PCI operation on Intel 430NX, sharing of PCI IRQ's with non-PCI level-triggered devices, having both configuration mechanisms operating at the same time (ALi M1435), etc., and makes the code much more readable.
This commit is contained in:
@@ -98,6 +98,9 @@ typedef struct gus_t {
|
||||
|
||||
int irqnext;
|
||||
|
||||
uint8_t irq_state;
|
||||
uint8_t midi_irq_state;
|
||||
|
||||
pc_timer_t timer_1;
|
||||
pc_timer_t timer_2;
|
||||
|
||||
@@ -157,8 +160,10 @@ double vol16bit[4096];
|
||||
void
|
||||
gus_update_int_status(gus_t *gus)
|
||||
{
|
||||
int irq_pending = 0;
|
||||
int midi_irq_pending = 0;
|
||||
int irq_pending = 0;
|
||||
int midi_irq_pending = 0;
|
||||
int intr_pending = 0;
|
||||
int midi_intr_pending = 0;
|
||||
|
||||
gus->irqstatus &= ~0x60;
|
||||
gus->irqstatus2 = 0xE0;
|
||||
@@ -187,24 +192,35 @@ gus_update_int_status(gus_t *gus)
|
||||
|
||||
midi_irq_pending = gus->midi_status & MIDI_INT_MASTER;
|
||||
|
||||
if (gus->irq == gus->irq_midi && gus->irq != -1) {
|
||||
if (gus->irq == gus->irq_midi) {
|
||||
if (irq_pending || midi_irq_pending)
|
||||
picintlevel(1 << gus->irq);
|
||||
intr_pending = 1;
|
||||
else
|
||||
picintc(1 << gus->irq);
|
||||
intr_pending = 0;
|
||||
} else {
|
||||
if (gus->irq != -1) {
|
||||
if (irq_pending)
|
||||
picintlevel(1 << gus->irq);
|
||||
else
|
||||
picintc(1 << gus->irq);
|
||||
}
|
||||
if (gus->irq_midi != -1) {
|
||||
if (midi_irq_pending)
|
||||
picintlevel(1 << gus->irq_midi);
|
||||
else
|
||||
picintc(1 << gus->irq_midi);
|
||||
}
|
||||
if (irq_pending)
|
||||
intr_pending = 1;
|
||||
else
|
||||
intr_pending = 0;
|
||||
|
||||
if (midi_irq_pending)
|
||||
midi_intr_pending = 1;
|
||||
else
|
||||
midi_intr_pending = 0;
|
||||
}
|
||||
|
||||
if (gus->irq != -1) {
|
||||
if (intr_pending)
|
||||
picintlevel(1 << gus->irq, &gus->irq_state);
|
||||
else
|
||||
picintclevel(1 << gus->irq, &gus->irq_state);
|
||||
}
|
||||
|
||||
if (gus->irq_midi != -1) {
|
||||
if (midi_intr_pending)
|
||||
picintlevel(1 << gus->irq_midi, &gus->midi_irq_state);
|
||||
else
|
||||
picintclevel(1 << gus->irq_midi, &gus->midi_irq_state);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1174,6 +1190,103 @@ gus_input_sysex(void *p, uint8_t *buffer, uint32_t len, int abort)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
gus_reset(void *p)
|
||||
{
|
||||
gus_t *gus = (gus_t *) p;
|
||||
int c;
|
||||
double out = 1.0;
|
||||
|
||||
if (gus == NULL)
|
||||
return;
|
||||
|
||||
memset(gus->ram, 0x00, (gus->gus_end_ram));
|
||||
|
||||
for (c = 0; c < 32; c++) {
|
||||
gus->ctrl[c] = 1;
|
||||
gus->rctrl[c] = 1;
|
||||
gus->rfreq[c] = 63 * 512;
|
||||
}
|
||||
|
||||
for (c = 4095; c >= 0; c--) {
|
||||
vol16bit[c] = out;
|
||||
out /= 1.002709201; /* 0.0235 dB Steps */
|
||||
}
|
||||
|
||||
gus->voices = 14;
|
||||
|
||||
gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0));
|
||||
|
||||
gus->t1l = gus->t2l = 0xff;
|
||||
|
||||
gus->global = 0;
|
||||
gus->addr = 0;
|
||||
gus->dmaaddr = 0;
|
||||
gus->voice = 0;
|
||||
memset(gus->start, 0x00, 32 * sizeof(uint32_t));
|
||||
memset(gus->end, 0x00, 32 * sizeof(uint32_t));
|
||||
memset(gus->cur, 0x00, 32 * sizeof(uint32_t));
|
||||
memset(gus->startx, 0x00, 32 * sizeof(uint32_t));
|
||||
memset(gus->endx, 0x00, 32 * sizeof(uint32_t));
|
||||
memset(gus->curx, 0x00, 32 * sizeof(uint32_t));
|
||||
memset(gus->rstart, 0x00, 32 * sizeof(int));
|
||||
memset(gus->rend, 0x00, 32 * sizeof(int));
|
||||
memset(gus->rcur, 0x00, 32 * sizeof(int));
|
||||
memset(gus->freq, 0x00, 32 * sizeof(uint16_t));
|
||||
memset(gus->curvol, 0x00, 32 * sizeof(int));
|
||||
memset(gus->pan_l, 0x00, 32 * sizeof(int));
|
||||
memset(gus->pan_r, 0x00, 32 * sizeof(int));
|
||||
gus->t1on = 0;
|
||||
gus->t2on = 0;
|
||||
gus->tctrl = 0;
|
||||
gus->t1 = 0;
|
||||
gus->t2 = 0;
|
||||
gus->irqstatus = 0;
|
||||
gus->irqstatus2 = 0;
|
||||
gus->adcommand = 0;
|
||||
memset(gus->waveirqs, 0x00, 32 * sizeof(int));
|
||||
memset(gus->rampirqs, 0x00, 32 * sizeof(int));
|
||||
gus->dmactrl = 0;
|
||||
|
||||
gus->uart_out = 1;
|
||||
|
||||
gus->sb_2xa = 0;
|
||||
gus->sb_2xc = 0;
|
||||
gus->sb_2xe = 0;
|
||||
gus->sb_ctrl = 0;
|
||||
gus->sb_nmi = 0;
|
||||
|
||||
gus->reg_ctrl = 0;
|
||||
|
||||
gus->ad_status = 0;
|
||||
gus->ad_data = 0;
|
||||
gus->ad_timer_ctrl = 0;
|
||||
|
||||
gus->midi_ctrl = 0;
|
||||
gus->midi_status = 0;
|
||||
memset(gus->midi_queue, 0x00, 64 * sizeof(uint8_t));
|
||||
gus->midi_data = 0;
|
||||
gus->midi_r = 0;
|
||||
gus->midi_w = 0;
|
||||
gus->uart_in = 0;
|
||||
gus->uart_out = 0;
|
||||
gus->sysex = 0;
|
||||
|
||||
gus->gp1 = 0;
|
||||
gus->gp2 = 0;
|
||||
gus->gp1_addr = 0;
|
||||
gus->gp2_addr = 0;
|
||||
|
||||
gus->usrr = 0;
|
||||
|
||||
gus->max_ctrl = 0;
|
||||
|
||||
gus->irq_state = 0;
|
||||
gus->midi_irq_state = 0;
|
||||
|
||||
gus_update_int_status(gus);
|
||||
}
|
||||
|
||||
void *
|
||||
gus_init(UNUSED(const device_t *info))
|
||||
{
|
||||
@@ -1181,7 +1294,7 @@ gus_init(UNUSED(const device_t *info))
|
||||
double out = 1.0;
|
||||
uint8_t gus_ram = device_get_config_int("gus_ram");
|
||||
gus_t *gus = malloc(sizeof(gus_t));
|
||||
memset(gus, 0, sizeof(gus_t));
|
||||
memset(gus, 0x00, sizeof(gus_t));
|
||||
|
||||
gus->gus_end_ram = 1 << (18 + gus_ram);
|
||||
gus->ram = (uint8_t *) malloc(gus->gus_end_ram);
|
||||
@@ -1359,7 +1472,7 @@ const device_t gus_device = {
|
||||
.local = 0,
|
||||
.init = gus_init,
|
||||
.close = gus_close,
|
||||
.reset = NULL,
|
||||
.reset = gus_reset,
|
||||
{ .available = NULL },
|
||||
.speed_changed = gus_speed_changed,
|
||||
.force_redraw = NULL,
|
||||
|
||||
Reference in New Issue
Block a user