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