Fixed the GUS and added configuration addresses and OPL for the WSS ISA card.
This commit is contained in:
@@ -111,8 +111,8 @@ typedef struct gus_t
|
||||
uint8_t usrr;
|
||||
} gus_t;
|
||||
|
||||
static int gus_gf1_irqs[8] = {0, 2, 5, 3, 7, 11, 12, 15};
|
||||
static int gus_midi_irqs[8] = {0, 2, 5, 3, 7, 11, 12, 15};
|
||||
static int gus_gf1_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15};
|
||||
static int gus_midi_irqs[8] = {-1, 2, 5, 3, 7, 11, 12, 15};
|
||||
static int gus_dmas[8] = {-1, 1, 3, 5, 6, 7, -1, -1};
|
||||
|
||||
int gusfreqs[]=
|
||||
@@ -135,7 +135,7 @@ void pollgusirqs(gus_t *gus)
|
||||
gus->irqstatus2=0x60|c;
|
||||
if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
|
||||
gus->irqstatus|=0x20;
|
||||
if (gus->irq != 0)
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
return;
|
||||
}
|
||||
@@ -143,16 +143,13 @@ void pollgusirqs(gus_t *gus)
|
||||
{
|
||||
gus->irqstatus2=0xA0|c;
|
||||
gus->irqstatus|=0x40;
|
||||
if (gus->irq != 0)
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
return;
|
||||
}
|
||||
}
|
||||
gus->irqstatus2=0xE0;
|
||||
if (!gus->irqstatus) {
|
||||
if (gus->irq != 0)
|
||||
picintc(1 << gus->irq);
|
||||
}
|
||||
if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq);
|
||||
}
|
||||
|
||||
void gus_midi_update_int_status(gus_t *gus)
|
||||
@@ -174,7 +171,7 @@ void gus_midi_update_int_status(gus_t *gus)
|
||||
else
|
||||
gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE;
|
||||
|
||||
if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != 0))
|
||||
if ((gus->midi_status & MIDI_INT_MASTER) && (gus->irq_midi != -1))
|
||||
{
|
||||
picint(1 << gus->irq_midi);
|
||||
}
|
||||
@@ -221,6 +218,9 @@ void writegus(uint16_t addr, uint8_t val, void *p)
|
||||
} else
|
||||
gus->midi_status |= MIDI_INT_TRANSMIT;
|
||||
break;
|
||||
case 0x302: /*Voice select*/
|
||||
gus->voice=val&31;
|
||||
break;
|
||||
case 0x303: /*Global select*/
|
||||
gus->global=val;
|
||||
break;
|
||||
@@ -463,9 +463,9 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
}
|
||||
break;
|
||||
case 0x307: /*DRAM access*/
|
||||
gus->addr&=0xFFFFF;
|
||||
if (gus->addr < gus->gus_end_ram)
|
||||
gus->ram[gus->addr]=val;
|
||||
gus->addr&=0xFFFFF;
|
||||
break;
|
||||
case 0x208: case 0x388:
|
||||
gus->adcommand = val;
|
||||
@@ -480,7 +480,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
{
|
||||
if (gus->sb_nmi)
|
||||
nmi = 1;
|
||||
else
|
||||
else if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
}
|
||||
@@ -516,65 +516,20 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
{
|
||||
case 0:
|
||||
if (gus->latch_enable & 0x40) {
|
||||
// GUS SDK: IRQ Control Register
|
||||
// Channel 1 GF1 IRQ selector (bits 2-0)
|
||||
// 0=reserved, do not use
|
||||
// 1=IRQ2
|
||||
// 2=IRQ5
|
||||
// 3=IRQ3
|
||||
// 4=IRQ7
|
||||
// 5=IRQ11
|
||||
// 6=IRQ12
|
||||
// 7=IRQ15
|
||||
// Channel 2 MIDI IRQ selector (bits 5-3)
|
||||
// 0=no interrupt
|
||||
// 1=IRQ2
|
||||
// 2=IRQ5
|
||||
// 3=IRQ3
|
||||
// 4=IRQ7
|
||||
// 5=IRQ11
|
||||
// 6=IRQ12
|
||||
// 7=IRQ15
|
||||
// Combine both IRQs using channel 1 (bit 6)
|
||||
// Reserved (bit 7)
|
||||
//
|
||||
// "If both channels are sharing an IRQ, channel 2's IRQ must be set to 0 and turn on bit 6. A
|
||||
// bus conflict will occur if both latches are programmed with the same IRQ #."
|
||||
if ((val & 7) != 0)
|
||||
gus->irq = gus_gf1_irqs[val & 7];
|
||||
|
||||
if (val & 0x40) // "Combine both IRQs"
|
||||
if (val & 0x40)
|
||||
{
|
||||
if (gus->irq == -1)
|
||||
gus->irq = gus->irq_midi = gus_gf1_irqs[(val >> 3) & 7];
|
||||
else
|
||||
gus->irq_midi = gus->irq;
|
||||
}
|
||||
else
|
||||
gus->irq_midi = gus_midi_irqs[(val >> 3) & 7];
|
||||
|
||||
gus->sb_nmi = val & 0x80;
|
||||
} else {
|
||||
// GUS SDK: DMA Control Register
|
||||
// Channel 1 (bits 2-0)
|
||||
// 0=NO DMA
|
||||
// 1=DMA1
|
||||
// 2=DMA3
|
||||
// 3=DMA5
|
||||
// 4=DMA6
|
||||
// 5=DMA7
|
||||
// 6=?
|
||||
// 7=?
|
||||
// Channel 2 (bits 5-3)
|
||||
// 0=NO DMA
|
||||
// 1=DMA1
|
||||
// 2=DMA3
|
||||
// 3=DMA5
|
||||
// 4=DMA6
|
||||
// 5=DMA7
|
||||
// 6=?
|
||||
// 7=?
|
||||
// Combine both DMA channels using channel 1 (bit 6)
|
||||
// Reserved (bit 7)
|
||||
//
|
||||
// "If both channels are sharing an DMA, channel 2's DMA must be set to 0 and turn on bit 6. A
|
||||
// bus conflict will occur if both latches are programmed with the same DMA #."
|
||||
if (gus_dmas[val & 7] != -1)
|
||||
gus->dma = gus_dmas[val & 7];
|
||||
}
|
||||
break;
|
||||
@@ -599,11 +554,12 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
break;
|
||||
|
||||
case 0x206:
|
||||
if (gus->sb_ctrl & 0x20) {
|
||||
gus->ad_status |= 0x08;
|
||||
if (gus->sb_ctrl & 0x20)
|
||||
{
|
||||
if (gus->sb_nmi)
|
||||
nmi = 1;
|
||||
else if (gus->irq != 0)
|
||||
else if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
break;
|
||||
@@ -616,7 +572,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
{
|
||||
if (gus->sb_nmi)
|
||||
nmi = 1;
|
||||
else if (gus->irq != 0)
|
||||
else if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
/*FALLTHROUGH*/
|
||||
@@ -668,26 +624,22 @@ uint8_t readgus(uint16_t addr, void *p)
|
||||
break;
|
||||
|
||||
case 0x200:
|
||||
val = 0xff;
|
||||
break;
|
||||
return 0;
|
||||
|
||||
case 0x206: /*IRQ status*/
|
||||
val = gus->irqstatus & ~0x10;
|
||||
if (gus->ad_status & 0x19)
|
||||
val |= 0x10;
|
||||
break;
|
||||
return val;
|
||||
|
||||
case 0x20F:
|
||||
val = 0;
|
||||
break;
|
||||
return 0;
|
||||
|
||||
case 0x302:
|
||||
val = gus->voice;
|
||||
break;
|
||||
return gus->voice;
|
||||
|
||||
case 0x303:
|
||||
val = gus->global;
|
||||
break;
|
||||
return gus->global;
|
||||
|
||||
case 0x304: /*Global low*/
|
||||
switch (gus->global)
|
||||
@@ -769,8 +721,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
||||
}
|
||||
break;
|
||||
case 0x306: case 0x706: /*Revision level*/
|
||||
val = 0xff;
|
||||
break;
|
||||
return 0xff; /*Pre 3.7 - no mixer*/
|
||||
case 0x307: /*DRAM access*/
|
||||
val=gus->ram[gus->addr];
|
||||
gus->addr&=0xFFFFF;
|
||||
@@ -778,7 +729,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
||||
val = gus->ram[gus->addr];
|
||||
else
|
||||
val = 0;
|
||||
break;
|
||||
return val;
|
||||
case 0x309: return 0;
|
||||
|
||||
case 0x20b:
|
||||
@@ -848,7 +799,7 @@ void gus_poll_timer_1(void *p)
|
||||
gus->ad_status |= 0x40;
|
||||
if (gus->tctrl&4)
|
||||
{
|
||||
if (gus->irq != 0)
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
gus->ad_status |= 0x04;
|
||||
gus->irqstatus |= 0x04;
|
||||
@@ -859,7 +810,7 @@ void gus_poll_timer_1(void *p)
|
||||
{
|
||||
gus->irqnext=0;
|
||||
gus->irqstatus|=0x80;
|
||||
if (gus->irq != 0)
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
|
||||
@@ -880,7 +831,7 @@ void gus_poll_timer_2(void *p)
|
||||
gus->ad_status |= 0x20;
|
||||
if (gus->tctrl&8)
|
||||
{
|
||||
if (gus->irq != 0)
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
gus->ad_status |= 0x02;
|
||||
gus->irqstatus |= 0x08;
|
||||
@@ -891,7 +842,7 @@ void gus_poll_timer_2(void *p)
|
||||
{
|
||||
gus->irqnext=0;
|
||||
gus->irqstatus|=0x80;
|
||||
if (gus->irq != 0)
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
}
|
||||
|
@@ -99,18 +99,22 @@ static void wss_get_buffer(int32_t *buffer, int len, void *p)
|
||||
void *wss_init(const device_t *info)
|
||||
{
|
||||
wss_t *wss = malloc(sizeof(wss_t));
|
||||
|
||||
memset(wss, 0, sizeof(wss_t));
|
||||
|
||||
uint16_t addr = device_get_config_hex16("base");
|
||||
wss->opl_enabled = device_get_config_int("opl");
|
||||
|
||||
opl3_init(&wss->opl);
|
||||
ad1848_init(&wss->ad1848);
|
||||
|
||||
ad1848_setirq(&wss->ad1848, 7);
|
||||
ad1848_setdma(&wss->ad1848, 3);
|
||||
|
||||
if (wss->opl_enabled)
|
||||
io_sethandler(0x0388, 0x0004, opl3_read, NULL, NULL, opl3_write, NULL, NULL, &wss->opl);
|
||||
io_sethandler(0x0530, 0x0004, wss_read, NULL, NULL, wss_write, NULL, NULL, wss);
|
||||
io_sethandler(0x0534, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &wss->ad1848);
|
||||
|
||||
io_sethandler(addr, 0x0004, wss_read, NULL, NULL, wss_write, NULL, NULL, wss);
|
||||
io_sethandler(addr+4, 0x0004, ad1848_read, NULL, NULL, ad1848_write, NULL, NULL, &wss->ad1848);
|
||||
|
||||
sound_add_handler(wss_get_buffer, wss);
|
||||
|
||||
@@ -198,15 +202,45 @@ void wss_speed_changed(void *p)
|
||||
ad1848_speed_changed(&wss->ad1848);
|
||||
}
|
||||
|
||||
static const device_config_t wss_config[] =
|
||||
{
|
||||
{
|
||||
"base", "Address", CONFIG_HEX16, "", 0x530,
|
||||
{
|
||||
{
|
||||
"0x530", 0x530
|
||||
},
|
||||
{
|
||||
"0x604", 0x604
|
||||
},
|
||||
{
|
||||
"0xe80", 0xe80
|
||||
},
|
||||
{
|
||||
"0xf40", 0xf40
|
||||
},
|
||||
{
|
||||
""
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"opl", "Enable OPL", CONFIG_BINARY, "", 1
|
||||
},
|
||||
{
|
||||
"", "", -1
|
||||
}
|
||||
};
|
||||
|
||||
const device_t wss_device =
|
||||
{
|
||||
"Windows Sound System",
|
||||
DEVICE_ISA, 0,
|
||||
DEVICE_ISA | DEVICE_AT, 0,
|
||||
wss_init, wss_close, NULL,
|
||||
NULL,
|
||||
wss_speed_changed,
|
||||
NULL,
|
||||
NULL
|
||||
wss_config
|
||||
};
|
||||
|
||||
const device_t ncr_business_audio_device =
|
||||
|
Reference in New Issue
Block a user