Merge pull request #1459 from 86Box/tc1995
Ported the x87 fix from the other emulator as well as the GUS one.
This commit is contained in:
@@ -787,6 +787,8 @@ static int opFLDCW_a32(uint32_t fetchdat)
|
||||
static int FSTENV()
|
||||
{
|
||||
FP_ENTER();
|
||||
cpu_state.npxs = (cpu_state.npxs & ~(7 << 11)) | ((cpu_state.TOP & 7) << 11);
|
||||
|
||||
switch ((cr0 & 1) | (cpu_state.op32 & 0x100))
|
||||
{
|
||||
case 0x000: /*16-bit real mode*/
|
||||
|
@@ -23,6 +23,7 @@
|
||||
#define FLAG_EXT_WRITE 4
|
||||
#define FLAG_LATCH8 8
|
||||
#define FLAG_NOSKEW 16
|
||||
#define FLAG_ADDR_BY16 32
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@@ -130,33 +130,66 @@ int gusfreqs[]=
|
||||
|
||||
double vol16bit[4096];
|
||||
|
||||
void pollgusirqs(gus_t *gus)
|
||||
void gus_update_int_status(gus_t *gus)
|
||||
{
|
||||
int c;
|
||||
int irq_pending = 0;
|
||||
int midi_irq_pending = 0;
|
||||
|
||||
gus->irqstatus&=~0x60;
|
||||
gus->irqstatus2=0xE0;
|
||||
for (c=0;c<32;c++)
|
||||
{
|
||||
if (gus->waveirqs[c])
|
||||
{
|
||||
gus->irqstatus2=0x60|c;
|
||||
if (gus->rampirqs[c]) gus->irqstatus2 |= 0x80;
|
||||
if (gus->rampirqs[c])
|
||||
gus->irqstatus2 |= 0x80;
|
||||
gus->irqstatus|=0x20;
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
return;
|
||||
irq_pending = 1;
|
||||
break;
|
||||
}
|
||||
if (gus->rampirqs[c])
|
||||
{
|
||||
gus->irqstatus2=0xA0|c;
|
||||
gus->irqstatus|=0x40;
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
return;
|
||||
irq_pending = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((gus->tctrl & 4) && (gus->irqstatus & 0x04))
|
||||
irq_pending = 1; /*Timer 1 interrupt pending*/
|
||||
if ((gus->tctrl & 8) && (gus->irqstatus & 0x08))
|
||||
irq_pending = 1; /*Timer 2 interrupt pending*/
|
||||
if ((gus->irqstatus & 0x80) && (gus->dmactrl & 0x20))
|
||||
irq_pending = 1; /*DMA TC interrupt pending*/
|
||||
|
||||
midi_irq_pending = gus->midi_status & MIDI_INT_MASTER;
|
||||
|
||||
if (gus->irq == gus->irq_midi && gus->irq != -1)
|
||||
{
|
||||
if (irq_pending || midi_irq_pending)
|
||||
picintlevel(1 << gus->irq);
|
||||
else
|
||||
picintc(1 << gus->irq);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
gus->irqstatus2=0xE0;
|
||||
if (!gus->irqstatus && gus->irq != -1) picintc(1 << gus->irq);
|
||||
}
|
||||
|
||||
void gus_midi_update_int_status(gus_t *gus)
|
||||
@@ -178,10 +211,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 != -1))
|
||||
{
|
||||
picint(1 << gus->irq_midi);
|
||||
}
|
||||
gus_update_int_status(gus);
|
||||
}
|
||||
|
||||
void writegus(uint16_t addr, uint8_t val, void *p)
|
||||
@@ -283,6 +313,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
||||
break;
|
||||
case 0x45: /*Timer control*/
|
||||
gus->tctrl=val;
|
||||
gus_update_int_status(gus);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -295,7 +326,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xF807F00)|((val<<7)<<8);
|
||||
old = gus->waveirqs[gus->voice];
|
||||
gus->waveirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0;
|
||||
if (gus->waveirqs[gus->voice] != old)
|
||||
pollgusirqs(gus);
|
||||
gus_update_int_status(gus);
|
||||
break;
|
||||
case 1: /*Frequency control*/
|
||||
gus->freq[gus->voice]=(gus->freq[gus->voice]&0xFF)|(val<<8);
|
||||
@@ -347,7 +378,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
gus->rctrl[gus->voice] = val & 0x7F;
|
||||
gus->rampirqs[gus->voice] = ((val & 0xa0) == 0xa0) ? 1 : 0;
|
||||
if (gus->rampirqs[gus->voice] != old)
|
||||
pollgusirqs(gus);
|
||||
gus_update_int_status(gus);
|
||||
break;
|
||||
|
||||
case 0xE:
|
||||
@@ -396,7 +427,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
break;
|
||||
}
|
||||
gus->dmactrl=val&~0x40;
|
||||
if (val&0x20) gus->irqnext=1;
|
||||
gus->irqnext=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -427,7 +458,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
break;
|
||||
}
|
||||
gus->dmactrl=val&~0x40;
|
||||
if (val&0x20) gus->irqnext=1;
|
||||
gus->irqnext=1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -457,6 +488,7 @@ gus->curx[gus->voice]=(gus->curx[gus->voice]&0xFFF8000)|((val&0x7F)<<8);
|
||||
}
|
||||
gus->tctrl=val;
|
||||
gus->sb_ctrl = val;
|
||||
gus_update_int_status(gus);
|
||||
break;
|
||||
case 0x46: /*Timer 1*/
|
||||
gus->t1 = gus->t1l = val;
|
||||
@@ -699,7 +731,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
||||
val=gus->irqstatus2;
|
||||
gus->rampirqs[gus->irqstatus2&0x1F]=0;
|
||||
gus->waveirqs[gus->irqstatus2&0x1F]=0;
|
||||
pollgusirqs(gus);
|
||||
gus_update_int_status(gus);
|
||||
return val;
|
||||
|
||||
case 0x00: case 0x01: case 0x02: case 0x03:
|
||||
@@ -739,7 +771,7 @@ uint8_t readgus(uint16_t addr, void *p)
|
||||
val=gus->irqstatus2;
|
||||
gus->rampirqs[gus->irqstatus2&0x1F]=0;
|
||||
gus->waveirqs[gus->irqstatus2&0x1F]=0;
|
||||
pollgusirqs(gus);
|
||||
gus_update_int_status(gus);
|
||||
return val;
|
||||
|
||||
case 0x41: /*DMA control*/
|
||||
@@ -844,8 +876,6 @@ void gus_poll_timer_1(void *p)
|
||||
gus->ad_status |= 0x40;
|
||||
if (gus->tctrl&4)
|
||||
{
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
gus->ad_status |= 0x04;
|
||||
gus->irqstatus |= 0x04;
|
||||
}
|
||||
@@ -855,11 +885,10 @@ void gus_poll_timer_1(void *p)
|
||||
{
|
||||
gus->irqnext=0;
|
||||
gus->irqstatus|=0x80;
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
|
||||
gus_midi_update_int_status(gus);
|
||||
gus_update_int_status(gus);
|
||||
}
|
||||
|
||||
void gus_poll_timer_2(void *p)
|
||||
@@ -876,8 +905,6 @@ void gus_poll_timer_2(void *p)
|
||||
gus->ad_status |= 0x20;
|
||||
if (gus->tctrl&8)
|
||||
{
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
gus->ad_status |= 0x02;
|
||||
gus->irqstatus |= 0x08;
|
||||
}
|
||||
@@ -887,9 +914,8 @@ void gus_poll_timer_2(void *p)
|
||||
{
|
||||
gus->irqnext=0;
|
||||
gus->irqstatus|=0x80;
|
||||
if (gus->irq != -1)
|
||||
picint(1 << gus->irq);
|
||||
}
|
||||
gus_update_int_status(gus);
|
||||
}
|
||||
|
||||
static void gus_update(gus_t *gus)
|
||||
@@ -1069,7 +1095,7 @@ void gus_poll_wave(void *p)
|
||||
}
|
||||
|
||||
if (update_irqs)
|
||||
pollgusirqs(gus);
|
||||
gus_update_int_status(gus);
|
||||
}
|
||||
|
||||
static void gus_get_buffer(int32_t *buffer, int len, void *p)
|
||||
|
@@ -901,6 +901,8 @@ gd54xx_out(uint16_t addr, uint8_t val, void *p)
|
||||
svga->adv_flags |= FLAG_EXT_WRITE;
|
||||
if (svga->gdcreg[0xb] & 0x08)
|
||||
svga->adv_flags |= FLAG_LATCH8;
|
||||
if (svga->gdcreg[0xb] & 0x10)
|
||||
svga->adv_flags |= FLAG_ADDR_BY16;
|
||||
gd54xx_recalc_banking(gd54xx);
|
||||
break;
|
||||
|
||||
@@ -1994,7 +1996,7 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr)
|
||||
|
||||
switch (svga->writemode) {
|
||||
case 4:
|
||||
if (svga->gdcreg[0xb] & 0x10) {
|
||||
if (svga->adv_flags & FLAG_ADDR_BY16) {
|
||||
addr <<= 2;
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
@@ -2016,7 +2018,7 @@ gd54xx_write_modes45(svga_t *svga, uint8_t val, uint32_t addr)
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (svga->gdcreg[0xb] & 0x10) {
|
||||
if (svga->adv_flags & FLAG_ADDR_BY16) {
|
||||
addr <<= 2;
|
||||
addr &= svga->decode_mask;
|
||||
|
||||
|
@@ -1056,9 +1056,11 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p)
|
||||
}
|
||||
|
||||
if (!(svga->gdcreg[6] & 1))
|
||||
svga->fullchange = 2;
|
||||
svga->fullchange = 2;
|
||||
|
||||
if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4))
|
||||
if ((svga->adv_flags & FLAG_ADDR_BY16) && (svga->writemode == 4 || svga->writemode == 5))
|
||||
addr <<= 4;
|
||||
else if ((svga->adv_flags & FLAG_ADDR_BY8) && (svga->writemode < 4))
|
||||
addr <<= 3;
|
||||
else if (((svga->chain4 && svga->packed_chain4) || svga->fb_only) && (svga->writemode < 4)) {
|
||||
writemask2 = 1 << (addr & 3);
|
||||
@@ -1244,7 +1246,9 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p)
|
||||
latch_addr = (addr << count) & svga->decode_mask;
|
||||
count = (1 << count);
|
||||
|
||||
if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
if (svga->adv_flags & FLAG_ADDR_BY16)
|
||||
addr <<= 4;
|
||||
else if (svga->adv_flags & FLAG_ADDR_BY8)
|
||||
addr <<= 3;
|
||||
else if ((svga->chain4 && svga->packed_chain4) || svga->fb_only) {
|
||||
addr &= svga->decode_mask;
|
||||
|
@@ -906,8 +906,8 @@ svga_render_15bpp_lowres(svga_t *svga)
|
||||
*p++ = video_15to32[dat >> 16];
|
||||
} else
|
||||
memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
|
||||
svga->ma += 4;
|
||||
}
|
||||
svga->ma += 4;
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
@@ -966,8 +966,8 @@ svga_render_15bpp_highres(svga_t *svga)
|
||||
*p++ = video_15to32[dat >> 16];
|
||||
} else
|
||||
memset(&(p[x]), 0x00, 2 * sizeof(uint32_t));
|
||||
svga->ma += 4;
|
||||
}
|
||||
svga->ma += 4;
|
||||
}
|
||||
svga->ma &= svga->vram_display_mask;
|
||||
}
|
||||
|
Reference in New Issue
Block a user