From fee0ea1d245903fd16ba0d5c0b0ab295cfe660a3 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 30 May 2021 22:07:22 +0200 Subject: [PATCH] Ported the x87 fix from the other emulator as well as the GUS one. Fixed 15bpp mode in all cards. --- src/cpu/x87_ops_misc.h | 2 + src/sound/snd_gus.c | 84 ++++++++++++++++++++++++------------- src/video/vid_svga_render.c | 4 +- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/cpu/x87_ops_misc.h b/src/cpu/x87_ops_misc.h index bd8b1a851..c902d12c8 100644 --- a/src/cpu/x87_ops_misc.h +++ b/src/cpu/x87_ops_misc.h @@ -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*/ diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index 40a0a405b..fe94ebf2f 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -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) diff --git a/src/video/vid_svga_render.c b/src/video/vid_svga_render.c index 530b4e2c3..7cd9fa8b1 100644 --- a/src/video/vid_svga_render.c +++ b/src/video/vid_svga_render.c @@ -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; }