Ported the x87 fix from the other emulator as well as the GUS one.

Fixed 15bpp mode in all cards.
This commit is contained in:
TC1995
2021-05-30 22:07:22 +02:00
parent 35350a753f
commit fee0ea1d24
3 changed files with 59 additions and 31 deletions

View File

@@ -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*/

View File

@@ -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)

View File

@@ -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;
}