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:
Miran Grča
2021-05-30 23:43:25 +02:00
committed by GitHub
6 changed files with 71 additions and 36 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

@@ -23,6 +23,7 @@
#define FLAG_EXT_WRITE 4
#define FLAG_LATCH8 8
#define FLAG_NOSKEW 16
#define FLAG_ADDR_BY16 32
typedef struct {

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

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

View File

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

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