Merge branch 'master' of https://github.com/86Box/86Box
This commit is contained in:
@@ -111,8 +111,8 @@ typedef struct gus_t
|
|||||||
uint8_t usrr;
|
uint8_t usrr;
|
||||||
} gus_t;
|
} gus_t;
|
||||||
|
|
||||||
static int gus_gf1_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] = {0, 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};
|
static int gus_dmas[8] = {-1, 1, 3, 5, 6, 7, -1, -1};
|
||||||
|
|
||||||
int gusfreqs[]=
|
int gusfreqs[]=
|
||||||
@@ -135,7 +135,7 @@ void pollgusirqs(gus_t *gus)
|
|||||||
gus->irqstatus2=0x60|c;
|
gus->irqstatus2=0x60|c;
|
||||||
if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
|
if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
|
||||||
gus->irqstatus|=0x20;
|
gus->irqstatus|=0x20;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -143,16 +143,13 @@ void pollgusirqs(gus_t *gus)
|
|||||||
{
|
{
|
||||||
gus->irqstatus2=0xA0|c;
|
gus->irqstatus2=0xA0|c;
|
||||||
gus->irqstatus|=0x40;
|
gus->irqstatus|=0x40;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
gus->irqstatus2=0xE0;
|
gus->irqstatus2=0xE0;
|
||||||
if (!gus->irqstatus) {
|
if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq);
|
||||||
if (gus->irq != 0)
|
|
||||||
picintc(1 << gus->irq);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void gus_midi_update_int_status(gus_t *gus)
|
void gus_midi_update_int_status(gus_t *gus)
|
||||||
@@ -174,7 +171,7 @@ void gus_midi_update_int_status(gus_t *gus)
|
|||||||
else
|
else
|
||||||
gus->irqstatus &= ~GUS_INT_MIDI_RECEIVE;
|
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);
|
picint(1 << gus->irq_midi);
|
||||||
}
|
}
|
||||||
@@ -221,6 +218,9 @@ void writegus(uint16_t addr, uint8_t val, void *p)
|
|||||||
} else
|
} else
|
||||||
gus->midi_status |= MIDI_INT_TRANSMIT;
|
gus->midi_status |= MIDI_INT_TRANSMIT;
|
||||||
break;
|
break;
|
||||||
|
case 0x302: /*Voice select*/
|
||||||
|
gus->voice=val&31;
|
||||||
|
break;
|
||||||
case 0x303: /*Global select*/
|
case 0x303: /*Global select*/
|
||||||
gus->global=val;
|
gus->global=val;
|
||||||
break;
|
break;
|
||||||
@@ -463,9 +463,9 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x307: /*DRAM access*/
|
case 0x307: /*DRAM access*/
|
||||||
gus->addr&=0xFFFFF;
|
|
||||||
if (gus->addr < gus->gus_end_ram)
|
if (gus->addr < gus->gus_end_ram)
|
||||||
gus->ram[gus->addr]=val;
|
gus->ram[gus->addr]=val;
|
||||||
|
gus->addr&=0xFFFFF;
|
||||||
break;
|
break;
|
||||||
case 0x208: case 0x388:
|
case 0x208: case 0x388:
|
||||||
gus->adcommand = val;
|
gus->adcommand = val;
|
||||||
@@ -480,7 +480,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
{
|
{
|
||||||
if (gus->sb_nmi)
|
if (gus->sb_nmi)
|
||||||
nmi = 1;
|
nmi = 1;
|
||||||
else
|
else if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -516,65 +516,20 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
if (gus->latch_enable & 0x40) {
|
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];
|
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;
|
gus->irq_midi = gus->irq;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
gus->irq_midi = gus_midi_irqs[(val >> 3) & 7];
|
gus->irq_midi = gus_midi_irqs[(val >> 3) & 7];
|
||||||
|
|
||||||
gus->sb_nmi = val & 0x80;
|
gus->sb_nmi = val & 0x80;
|
||||||
} else {
|
} 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];
|
gus->dma = gus_dmas[val & 7];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -599,11 +554,12 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x206:
|
case 0x206:
|
||||||
if (gus->sb_ctrl & 0x20) {
|
|
||||||
gus->ad_status |= 0x08;
|
gus->ad_status |= 0x08;
|
||||||
|
if (gus->sb_ctrl & 0x20)
|
||||||
|
{
|
||||||
if (gus->sb_nmi)
|
if (gus->sb_nmi)
|
||||||
nmi = 1;
|
nmi = 1;
|
||||||
else if (gus->irq != 0)
|
else if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -616,7 +572,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
|||||||
{
|
{
|
||||||
if (gus->sb_nmi)
|
if (gus->sb_nmi)
|
||||||
nmi = 1;
|
nmi = 1;
|
||||||
else if (gus->irq != 0)
|
else if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
/*FALLTHROUGH*/
|
/*FALLTHROUGH*/
|
||||||
@@ -668,26 +624,22 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x200:
|
case 0x200:
|
||||||
val = 0xff;
|
return 0;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x206: /*IRQ status*/
|
case 0x206: /*IRQ status*/
|
||||||
val = gus->irqstatus & ~0x10;
|
val = gus->irqstatus & ~0x10;
|
||||||
if (gus->ad_status & 0x19)
|
if (gus->ad_status & 0x19)
|
||||||
val |= 0x10;
|
val |= 0x10;
|
||||||
break;
|
return val;
|
||||||
|
|
||||||
case 0x20F:
|
case 0x20F:
|
||||||
val = 0;
|
return 0;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x302:
|
case 0x302:
|
||||||
val = gus->voice;
|
return gus->voice;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x303:
|
case 0x303:
|
||||||
val = gus->global;
|
return gus->global;
|
||||||
break;
|
|
||||||
|
|
||||||
case 0x304: /*Global low*/
|
case 0x304: /*Global low*/
|
||||||
switch (gus->global)
|
switch (gus->global)
|
||||||
@@ -769,8 +721,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0x306: case 0x706: /*Revision level*/
|
case 0x306: case 0x706: /*Revision level*/
|
||||||
val = 0xff;
|
return 0xff; /*Pre 3.7 - no mixer*/
|
||||||
break;
|
|
||||||
case 0x307: /*DRAM access*/
|
case 0x307: /*DRAM access*/
|
||||||
val=gus->ram[gus->addr];
|
val=gus->ram[gus->addr];
|
||||||
gus->addr&=0xFFFFF;
|
gus->addr&=0xFFFFF;
|
||||||
@@ -778,7 +729,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
|||||||
val = gus->ram[gus->addr];
|
val = gus->ram[gus->addr];
|
||||||
else
|
else
|
||||||
val = 0;
|
val = 0;
|
||||||
break;
|
return val;
|
||||||
case 0x309: return 0;
|
case 0x309: return 0;
|
||||||
|
|
||||||
case 0x20b:
|
case 0x20b:
|
||||||
@@ -848,7 +799,7 @@ void gus_poll_timer_1(void *p)
|
|||||||
gus->ad_status |= 0x40;
|
gus->ad_status |= 0x40;
|
||||||
if (gus->tctrl&4)
|
if (gus->tctrl&4)
|
||||||
{
|
{
|
||||||
if (gus->irq != 0)
|
if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
gus->ad_status |= 0x04;
|
gus->ad_status |= 0x04;
|
||||||
gus->irqstatus |= 0x04;
|
gus->irqstatus |= 0x04;
|
||||||
@@ -859,7 +810,7 @@ void gus_poll_timer_1(void *p)
|
|||||||
{
|
{
|
||||||
gus->irqnext=0;
|
gus->irqnext=0;
|
||||||
gus->irqstatus|=0x80;
|
gus->irqstatus|=0x80;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -880,7 +831,7 @@ void gus_poll_timer_2(void *p)
|
|||||||
gus->ad_status |= 0x20;
|
gus->ad_status |= 0x20;
|
||||||
if (gus->tctrl&8)
|
if (gus->tctrl&8)
|
||||||
{
|
{
|
||||||
if (gus->irq != 0)
|
if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
picint(1 << gus->irq);
|
||||||
gus->ad_status |= 0x02;
|
gus->ad_status |= 0x02;
|
||||||
gus->irqstatus |= 0x08;
|
gus->irqstatus |= 0x08;
|
||||||
@@ -891,7 +842,7 @@ void gus_poll_timer_2(void *p)
|
|||||||
{
|
{
|
||||||
gus->irqnext=0;
|
gus->irqnext=0;
|
||||||
gus->irqstatus|=0x80;
|
gus->irqstatus|=0x80;
|
||||||
if (gus->irq != 0)
|
if (gus->irq != -1)
|
||||||
picint(1 << gus->irq);
|
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)
|
void *wss_init(const device_t *info)
|
||||||
{
|
{
|
||||||
wss_t *wss = malloc(sizeof(wss_t));
|
wss_t *wss = malloc(sizeof(wss_t));
|
||||||
|
|
||||||
memset(wss, 0, 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);
|
opl3_init(&wss->opl);
|
||||||
ad1848_init(&wss->ad1848);
|
ad1848_init(&wss->ad1848);
|
||||||
|
|
||||||
ad1848_setirq(&wss->ad1848, 7);
|
ad1848_setirq(&wss->ad1848, 7);
|
||||||
ad1848_setdma(&wss->ad1848, 3);
|
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(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);
|
sound_add_handler(wss_get_buffer, wss);
|
||||||
|
|
||||||
@@ -198,15 +202,45 @@ void wss_speed_changed(void *p)
|
|||||||
ad1848_speed_changed(&wss->ad1848);
|
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 =
|
const device_t wss_device =
|
||||||
{
|
{
|
||||||
"Windows Sound System",
|
"Windows Sound System",
|
||||||
DEVICE_ISA, 0,
|
DEVICE_ISA | DEVICE_AT, 0,
|
||||||
wss_init, wss_close, NULL,
|
wss_init, wss_close, NULL,
|
||||||
NULL,
|
NULL,
|
||||||
wss_speed_changed,
|
wss_speed_changed,
|
||||||
NULL,
|
NULL,
|
||||||
NULL
|
wss_config
|
||||||
};
|
};
|
||||||
|
|
||||||
const device_t ncr_business_audio_device =
|
const device_t ncr_business_audio_device =
|
||||||
|
Reference in New Issue
Block a user