From 1bd872d43a62b4936bc81f12ca46d30e1dcae576 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 20:40:09 +0200 Subject: [PATCH 01/44] AdLib Gold: corrected (more or less) the timer period to allow the sound card to behave more normally instead of locking up the emulator in certain instances (e.g.: jukebox of the card's DOS utilities). --- src/sound/snd_adlibgold.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_adlibgold.c b/src/sound/snd_adlibgold.c index c1b2c3867..e4330cba3 100644 --- a/src/sound/snd_adlibgold.c +++ b/src/sound/snd_adlibgold.c @@ -20,7 +20,7 @@ typedef struct adgold_t { int adgold_irq_status; - int irq, dma, hdma; + int irq, dma; uint8_t adgold_eeprom[0x1a]; @@ -547,6 +547,7 @@ adgold_read(uint16_t addr, void *p) temp = adgold->adgold_mma_status; adgold->adgold_mma_status &= ~0xf3; /*JUKEGOLD expects timer status flags to auto-clear*/ adgold_update_irq_status(adgold); + picintc(1 << adgold->irq); break; case 5: if (adgold->adgold_mma_addr >= 0xf) @@ -652,7 +653,8 @@ adgold_timer_poll(void *p) { adgold_t *adgold = (adgold_t *) p; - timer_advance_u64(&adgold->adgold_mma_timer_count, (uint64_t) ((double) TIMER_USEC * 1.88964)); + /*A small timer period will result in hangs.*/ + timer_on_auto(&adgold->adgold_mma_timer_count, 4.88964); if (adgold->adgold_midi_ctrl & 0x3f) { if ((adgold->adgold_midi_ctrl & 0x3f) != 0x3f) { @@ -925,7 +927,7 @@ adgold_init(const device_t *info) adgold->adgold_eeprom[0x10] = 0xff; adgold->adgold_eeprom[0x11] = 0x20; adgold->adgold_eeprom[0x12] = 0x00; - adgold->adgold_eeprom[0x13] = 0xa0; + adgold->adgold_eeprom[0x13] = 0x00; adgold->adgold_eeprom[0x14] = 0x00; adgold->adgold_eeprom[0x15] = 0x388 / 8; /*Present at 388-38f*/ adgold->adgold_eeprom[0x16] = 0x00; @@ -957,6 +959,7 @@ adgold_init(const device_t *info) break; } adgold->adgold_eeprom[0x13] |= (adgold->dma << 3); + adgold->adgold_eeprom[0x14] |= (adgold->dma << 4); memcpy(adgold->adgold_38x_regs, adgold->adgold_eeprom, 0x19); adgold->vol_l = attenuation[adgold->adgold_eeprom[0x04] & 0x3f]; adgold->vol_r = attenuation[adgold->adgold_eeprom[0x05] & 0x3f]; From 01c05781e23800cb454ecf288dc53faeb561f83d Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 20:46:12 +0200 Subject: [PATCH 02/44] Tseng ET4000W32/i: corrected (in the best possible way) the mouse cursor shape (under NT) when it's at the top edges while not affecting the proper shape in other operating systems. --- src/video/vid_et4000w32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index e9ea4d111..4016067ab 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -277,7 +277,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) svga->hwcursor.ena = !!(et4000->regs[0xF7] & 0x80); svga->hwcursor.xoff = et4000->regs[0xE2]; svga->hwcursor.yoff = et4000->regs[0xE6]; - svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && et4000->regs[0xe2] && et4000->regs[0xe6])) ? 128 : 64; + svga->hwcursor.cur_xsize = svga->hwcursor.cur_ysize = ((et4000->regs[0xEF] & 4) || ((et4000->type == ET4000W32) && (et4000->regs[0xe2] >= 0x1f) && (et4000->regs[0xe6] >= 0x1f))) ? 128 : 64; if (et4000->type == ET4000W32) { if ((svga->bpp == 15) || (svga->bpp == 16)) { From 81918a19d12d5a2bdd5c2544823ae3499066554d Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 21:05:22 +0200 Subject: [PATCH 03/44] SCSI CD-ROM: some vendor specific commands for Toshiba and others now have more correct speed. PCSCSI PCI: re-implemented SCSI bus reset. --- src/scsi/scsi_cdrom.c | 14 ++++++++++++-- src/scsi/scsi_pcscsi.c | 14 +++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/scsi/scsi_cdrom.c b/src/scsi/scsi_cdrom.c index b20a4b4ab..d100902d2 100644 --- a/src/scsi/scsi_cdrom.c +++ b/src/scsi/scsi_cdrom.c @@ -976,7 +976,9 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) break; case 0xc6: case 0xc7: - if ((!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433"))) { + if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_DRIVEXM_3433") || + !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-3301TA_0272") || + !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "TOSHIBA_CD-ROM_XM-5701TA_3136")) { bytes_per_second = 176.0 * 1024.0; bytes_per_second *= (double) dev->drv->cur_speed; } @@ -1000,7 +1002,15 @@ scsi_cdrom_command_common(scsi_cdrom_t *dev) break; case 0xc3: if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-541_1.0i") || - !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00")) { + !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "SONY_CD-ROM_CDU-76S_1.00") || + !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "PIONEER_CD-ROM_DRM-604X_2403")) { + bytes_per_second = 176.0 * 1024.0; + bytes_per_second *= (double) dev->drv->cur_speed; + } + break; + case 0xde: + if (!strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE74_1.00") || + !strcmp(cdrom_drive_types[dev->drv->type].internal_name, "NEC_CD-ROM_DRIVE464_1.05")) { bytes_per_second = 176.0 * 1024.0; bytes_per_second *= (double) dev->drv->cur_speed; } diff --git a/src/scsi/scsi_pcscsi.c b/src/scsi/scsi_pcscsi.c index f3dc6ebaf..c0244ed4f 100644 --- a/src/scsi/scsi_pcscsi.c +++ b/src/scsi/scsi_pcscsi.c @@ -379,9 +379,9 @@ esp_get_cmd(esp_t *dev, uint32_t maxlen) dma_set_drq(dev->DmaChannel, 0); } else { esp_pci_dma_memory_rw(dev, buf, dmalen, WRITE_TO_DEVICE); - dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); - fifo8_push_all(&dev->cmdfifo, buf, dmalen); } + dmalen = MIN(fifo8_num_free(&dev->cmdfifo), dmalen); + fifo8_push_all(&dev->cmdfifo, buf, dmalen); } else { dmalen = MIN(fifo8_num_used(&dev->fifo), maxlen); esp_log("ESP Get command, dmalen = %i\n", dmalen); @@ -545,6 +545,8 @@ esp_hard_reset(esp_t *dev) dev->do_cmd = 0; dev->rregs[ESP_CFG1] = dev->mca ? dev->HostID : 7; esp_log("ESP Reset\n"); + for (uint8_t i = 0; i < 16; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); timer_stop(&dev->timer); } @@ -569,7 +571,6 @@ esp_do_nodma(esp_t *dev, scsi_device_t *sd) esp_do_cmd(dev); } else { dev->cmdfifo_cdb_offset = fifo8_num_used(&dev->cmdfifo); - ; esp_log("CDB offset = %i used\n", dev->cmdfifo_cdb_offset); dev->rregs[ESP_RSTAT] = STAT_TC | STAT_CD; @@ -665,7 +666,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) count = tdbc = esp_get_tc(dev); - if (dev->mca) { /*See the comment in the esp_do_busid_cmd() function.*/ + if (dev->mca) { if (sd->buffer_length < 0) { if (dev->dma_enabled) goto done; @@ -713,7 +714,7 @@ esp_do_dma(esp_t *dev, scsi_device_t *sd) return; } - esp_log("ESP SCSI dmaleft = %d, async_len = %i, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length); + esp_log("ESP SCSI dmaleft = %d, buffer length = %d\n", esp_get_tc(dev), sd->buffer_length); /* Make sure count is never bigger than buffer_length. */ if (count > dev->xfer_counter) @@ -1082,6 +1083,9 @@ esp_reg_write(esp_t *dev, uint32_t saddr, uint32_t val) esp_pci_soft_reset(dev); break; case CMD_BUSRESET: + for (uint8_t i = 0; i < 16; i++) + scsi_device_reset(&scsi_devices[dev->bus][i]); + if (!(dev->wregs[ESP_CFG1] & CFG1_RESREPT)) { dev->rregs[ESP_RINTR] |= INTR_RST; esp_log("ESP Bus Reset with IRQ\n"); From 92db594d6b769f20a75bc89f2034e0767a6264b4 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 21:14:19 +0200 Subject: [PATCH 04/44] ATI Mach64GX/VT2: Corrected the 24bpp accelerated mode in terms of colors and bitblt so that it could be glitchless. Corrected 8bpp mode under Win2000 as well so that it no longer glitches. VT2 is PCI only, so use its PCI timings only. Small cosmetic fixes in the if's of the linear apertures of said card. 24bpp mode will be unthreaded while the rest of the bpp's is left intact, this is due to desyncing in 24bpp mode in NT 3.1's 24bpp drivers. --- src/video/vid_ati_mach64.c | 277 ++++++++++++++++++++++++------------- 1 file changed, 181 insertions(+), 96 deletions(-) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 273dbdcf6..fee3e94f8 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -172,7 +172,7 @@ typedef struct mach64_t { uint32_t write_mask; uint32_t chain_mask; - uint32_t linear_base, old_linear_base; + uint32_t linear_base; uint32_t io_base; struct @@ -185,6 +185,7 @@ typedef struct mach64_t { int src_x_start, src_y_start; int xinc, yinc; int x_count, y_count; + int xx_count; int src_x_count, src_y_count; int src_width1, src_height1; int src_width2, src_height2; @@ -487,35 +488,35 @@ mach64_recalctimings(svga_t *svga) case BPP_4: if (mach64->type != MACH64_GX) svga->render = svga_render_4bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; break; case BPP_8: if (mach64->type != MACH64_GX) svga->render = svga_render_8bpp_highres; - svga->hdisp *= 8; - svga->rowoffset /= 2; + svga->hdisp <<= 3; + svga->rowoffset >>= 1; break; case BPP_15: if (mach64->type != MACH64_GX) svga->render = svga_render_15bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; break; case BPP_16: if (mach64->type != MACH64_GX) svga->render = svga_render_16bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; break; case BPP_24: if (mach64->type != MACH64_GX) svga->render = svga_render_24bpp_highres; - svga->hdisp *= 8; + svga->hdisp <<= 3; svga->rowoffset = (svga->rowoffset * 3) / 2; break; case BPP_32: if (mach64->type != MACH64_GX) svga->render = svga_render_32bpp_highres; - svga->hdisp *= 8; - svga->rowoffset *= 2; + svga->hdisp <<= 3; + svga->rowoffset <<= 1; break; } @@ -530,7 +531,7 @@ mach64_updatemapping(mach64_t *mach64) { svga_t *svga = &mach64->svga; - if (!(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { + if (mach64->pci && !(mach64->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)) { mach64_log("Update mapping - PCI disabled\n"); mem_mapping_disable(&svga->mapping); mem_mapping_disable(&mach64->linear_mapping); @@ -543,47 +544,60 @@ mach64_updatemapping(mach64_t *mach64) mem_mapping_disable(&mach64->mmio_mapping); switch (svga->gdcreg[6] & 0xc) { case 0x0: /*128k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_handler(&svga->mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); + mem_mapping_set_p(&svga->mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); mem_mapping_enable(&mach64->mmio_mapping); svga->banked_mask = 0xffff; break; case 0x4: /*64k at A0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); - mem_mapping_set_p(&mach64->svga.mapping, mach64); + mem_mapping_set_handler(&svga->mapping, mach64_read, mach64_readw, mach64_readl, mach64_write, mach64_writew, mach64_writel); + mem_mapping_set_p(&svga->mapping, mach64); mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); svga->banked_mask = 0xffff; break; case 0x8: /*32k at B0000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&svga->mapping, svga); mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); svga->banked_mask = 0x7fff; break; case 0xC: /*32k at B8000*/ - mem_mapping_set_handler(&mach64->svga.mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); - mem_mapping_set_p(&mach64->svga.mapping, svga); + mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel); + mem_mapping_set_p(&svga->mapping, svga); mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); svga->banked_mask = 0x7fff; break; } + + mach64_log("Mach64 linear aperture = %08x.\n", mach64->linear_base); if (mach64->linear_base) { if (mach64->type == MACH64_GX) { if ((mach64->config_cntl & 3) == 2) { /*8 MB aperture*/ mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - } else { + } else if ((mach64->config_cntl & 3) == 1) { /*4 MB aperture*/ mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (4 << 20) - 0x4000); mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((4 << 20) - 0x4000), 0x4000); + } else { + /*Disable aperture on reserved values*/ + mem_mapping_disable(&mach64->linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping); } } else { - /*2*8 MB aperture*/ - mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); - mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); + if ((mach64->config_cntl & 3) == 2) { + /*2*8 MB aperture*/ + mem_mapping_set_addr(&mach64->linear_mapping, mach64->linear_base, (8 << 20) - 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping, mach64->linear_base + ((8 << 20) - 0x4000), 0x4000); + mem_mapping_set_addr(&mach64->mmio_linear_mapping_2, mach64->linear_base + ((16 << 20) - 0x4000), 0x4000); + } else { + /*Disable aperture on reserved values*/ + mem_mapping_disable(&mach64->linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping); + mem_mapping_disable(&mach64->mmio_linear_mapping_2); + } } } else { mem_mapping_disable(&mach64->linear_mapping); @@ -621,7 +635,7 @@ mach64_wait_fifo_idle(mach64_t *mach64) } #define READ8(addr, var) \ - switch ((addr) &3) { \ + switch ((addr) & 3) { \ case 0: \ ret = (var) &0xff; \ break; \ @@ -637,7 +651,7 @@ mach64_wait_fifo_idle(mach64_t *mach64) } #define WRITE8(addr, var, val) \ - switch ((addr) &3) { \ + switch ((addr) & 3) { \ case 0: \ var = (var & 0xffffff00) | (val); \ break; \ @@ -1181,8 +1195,13 @@ mach64_start_fill(mach64_t *mach64) { mach64->accel.dst_x = 0; mach64->accel.dst_y = 0; + mach64->accel.dst_x_start = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y_start = mach64->dst_y_x & 0xfff; + if (((mach64->dst_y_x >> 16) & 0x1000)) + mach64->accel.dst_x_start |= ~0xfff; + mach64->accel.dst_y_start = mach64->dst_y_x & 0x3fff; + if (mach64->dst_y_x & 0x4000) + mach64->accel.dst_y_start |= ~0x3fff; mach64->accel.dst_width = (mach64->dst_height_width >> 16) & 0x1fff; mach64->accel.dst_height = mach64->dst_height_width & 0x1fff; @@ -1193,11 +1212,18 @@ mach64_start_fill(mach64_t *mach64) } mach64->accel.x_count = mach64->accel.dst_width; + mach64->accel.xx_count = 0; mach64->accel.src_x = 0; mach64->accel.src_y = 0; + mach64->accel.src_x_start = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y_start = mach64->src_y_x & 0xfff; + if (((mach64->src_y_x >> 16) & 0x1000)) + mach64->accel.src_x_start |= ~0xfff; + mach64->accel.src_y_start = mach64->src_y_x & 0x3fff; + if (mach64->src_y_x & 0x4000) + mach64->accel.src_y_start |= ~0x3fff; + if (mach64->src_cntl & SRC_LINEAR_EN) mach64->accel.src_x_count = 0x7ffffff; /*Essentially infinite*/ else @@ -1219,11 +1245,11 @@ mach64_start_fill(mach64_t *mach64) mach64->src_height1_width1, mach64->src_height2_width2); - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) << 3; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) << 3; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) << 3; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) << 3; mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; mach64->accel.mix_bg = mach64->dp_mix & 0x1f; @@ -1308,16 +1334,24 @@ void mach64_start_line(mach64_t *mach64) { mach64->accel.dst_x = (mach64->dst_y_x >> 16) & 0xfff; - mach64->accel.dst_y = mach64->dst_y_x & 0xfff; + if (((mach64->dst_y_x >> 16) & 0x1000)) + mach64->accel.dst_x |= ~0xfff; + mach64->accel.dst_y = mach64->dst_y_x & 0x3fff; + if (mach64->dst_y_x & 0x4000) + mach64->accel.dst_y |= ~0x3fff; mach64->accel.src_x = (mach64->src_y_x >> 16) & 0xfff; - mach64->accel.src_y = mach64->src_y_x & 0xfff; + if (((mach64->src_y_x >> 16) & 0x1000)) + mach64->accel.src_x |= ~0xfff; + mach64->accel.src_y = mach64->src_y_x & 0x3fff; + if (mach64->src_y_x & 0x4000) + mach64->accel.src_y |= ~0x3fff; - mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) * 8; - mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) * 8; + mach64->accel.src_pitch = (mach64->src_off_pitch >> 22) << 3; + mach64->accel.src_offset = (mach64->src_off_pitch & 0xfffff) << 3; - mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) * 8; - mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) * 8; + mach64->accel.dst_pitch = (mach64->dst_off_pitch >> 22) << 3; + mach64->accel.dst_offset = (mach64->dst_off_pitch & 0xfffff) << 3; mach64->accel.mix_fg = (mach64->dp_mix >> 16) & 0x1f; mach64->accel.mix_bg = mach64->dp_mix & 0x1f; @@ -1344,9 +1378,6 @@ mach64_start_line(mach64_t *mach64) else mach64->accel.dst_offset >>= mach64->accel.dst_size; - /* mach64->accel.src_pitch *= mach64_inc[mach64->accel.src_pix_width]; - mach64->accel.dst_pitch *= mach64_inc[mach64->accel.dst_pix_width];*/ - mach64->accel.source_host = ((mach64->dp_src & 7) == SRC_HOST) || (((mach64->dp_src >> 8) & 7) == SRC_HOST); for (uint8_t y = 0; y < 8; y++) { @@ -1446,6 +1477,7 @@ mach64_start_line(mach64_t *mach64) break; \ case 0x17: \ dest_dat = (dest_dat + src_dat) >> 1; \ + break; \ } #define WRITE(addr, width) \ @@ -1483,24 +1515,31 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mach64_log("mach64_blit : return as not busy\n"); return; } + switch (mach64->accel.op) { case OP_RECT: while (count) { + uint8_t write_mask = 0; uint32_t src_dat = 0; uint32_t dest_dat; uint32_t host_dat = 0; uint32_t old_dest_dat; int mix = 0; - int dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; - int dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0xfff; + int dst_x; + int dst_y; int src_x; - int src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0xfff; + int src_y; + + dst_x = (mach64->accel.dst_x + mach64->accel.dst_x_start) & 0xfff; + dst_y = (mach64->accel.dst_y + mach64->accel.dst_y_start) & 0x3fff; if (mach64->src_cntl & SRC_LINEAR_EN) src_x = mach64->accel.src_x; else src_x = (mach64->accel.src_x + mach64->accel.src_x_start) & 0xfff; + src_y = (mach64->accel.src_y + mach64->accel.src_y_start) & 0x3fff; + if (mach64->accel.source_host) { host_dat = cpu_dat; switch (mach64->accel.host_size) { @@ -1525,7 +1564,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mix = cpu_dat & 1; cpu_dat >>= 1; } else { - mix = cpu_dat >> 31; + mix = cpu_dat >> 0x1f; cpu_dat <<= 1; } break; @@ -1544,7 +1583,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) break; } - if (dst_x >= mach64->accel.sc_left && dst_x <= mach64->accel.sc_right && dst_y >= mach64->accel.sc_top && dst_y <= mach64->accel.sc_bottom) { + if ((dst_x) >= mach64->accel.sc_left && (dst_x) <= mach64->accel.sc_right && (dst_y) >= mach64->accel.sc_top && (dst_y) <= mach64->accel.sc_bottom) { switch (mix ? mach64->accel.source_fg : mach64->accel.source_bg) { case SRC_HOST: src_dat = host_dat; @@ -1553,24 +1592,42 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) READ(mach64->accel.src_offset + (src_y * mach64->accel.src_pitch) + src_x, src_dat, mach64->accel.src_size); break; case SRC_FG: - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - if ((mach64->accel.x_count % 3) == 2) - src_dat = mach64->accel.dp_frgd_clr & 0xff; - else if ((mach64->accel.x_count % 3) == 1) - src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; - else if ((mach64->accel.x_count % 3) == 0) - src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->accel.xinc == -1) { + if ((mach64->accel.xx_count % 3) == 2) + src_dat = mach64->accel.dp_frgd_clr & 0xff; + else if ((mach64->accel.xx_count % 3) == 1) + src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; + else + src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + } else { + if ((mach64->accel.xx_count % 3) == 2) + src_dat = (mach64->accel.dp_frgd_clr >> 16) & 0xff; + else if ((mach64->accel.xx_count % 3) == 1) + src_dat = (mach64->accel.dp_frgd_clr >> 8) & 0xff; + else + src_dat = mach64->accel.dp_frgd_clr & 0xff; + } } else src_dat = mach64->accel.dp_frgd_clr; break; case SRC_BG: - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) == (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - if ((mach64->accel.x_count % 3) == 2) - src_dat = mach64->accel.dp_bkgd_clr & 0xff; - else if ((mach64->accel.x_count % 3) == 1) - src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; - else if ((mach64->accel.x_count % 3) == 0) - src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->accel.xinc == -1) { + if ((mach64->accel.xx_count % 3) == 2) + src_dat = mach64->accel.dp_bkgd_clr & 0xff; + else if ((mach64->accel.xx_count % 3) == 1) + src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; + else + src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + } else { + if ((mach64->accel.xx_count % 3) == 2) + src_dat = (mach64->accel.dp_bkgd_clr >> 16) & 0xff; + else if ((mach64->accel.xx_count % 3) == 1) + src_dat = (mach64->accel.dp_bkgd_clr >> 8) & 0xff; + else + src_dat = mach64->accel.dp_bkgd_clr & 0xff; + } } else src_dat = mach64->accel.dp_bkgd_clr; break; @@ -1595,7 +1652,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) } if (!(mach64->dst_cntl & DST_POLYGON_EN) || mach64->accel.poly_draw) { - READ(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, dest_dat, mach64->accel.dst_size); + READ(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), dest_dat, mach64->accel.dst_size); switch (mach64->accel.clr_cmp_fn) { case 1: /*TRUE*/ @@ -1612,19 +1669,30 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) { old_dest_dat = dest_dat; MIX - dest_dat - = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); + + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + if (mach64->accel.xinc == -1) { + if ((mach64->accel.xx_count % 3) == 2) + write_mask = mach64->accel.write_mask & 0xff; + else if ((mach64->accel.xx_count % 3) == 1) + write_mask = (mach64->accel.write_mask >> 8) & 0xff; + else + write_mask = (mach64->accel.write_mask >> 16) & 0xff; + } else { + if ((mach64->accel.xx_count % 3) == 2) + write_mask = (mach64->accel.write_mask >> 16) & 0xff; + else if ((mach64->accel.xx_count % 3) == 1) + write_mask = (mach64->accel.write_mask >> 8) & 0xff; + else + write_mask = mach64->accel.write_mask & 0xff; + } + dest_dat = (dest_dat & write_mask) | (old_dest_dat & ~write_mask); + } else { + dest_dat = (dest_dat & mach64->accel.write_mask) | (old_dest_dat & ~mach64->accel.write_mask); + } } - WRITE(mach64->accel.dst_offset + (dst_y * mach64->accel.dst_pitch) + dst_x, mach64->accel.dst_size); - } - } - - if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { - if ((mach64->dst_cntl & (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) != (DST_LAST_PEL | DST_X_DIR | DST_Y_DIR | DST_24_ROT_EN)) { - mach64->accel.dp_frgd_clr = ((mach64->accel.dp_frgd_clr >> 8) & 0xffff) | (mach64->accel.dp_frgd_clr << 16); - mach64->accel.dp_bkgd_clr = ((mach64->accel.dp_bkgd_clr >> 8) & 0xffff) | (mach64->accel.dp_bkgd_clr << 16); - mach64->accel.write_mask = ((mach64->accel.write_mask >> 8) & 0xffff) | (mach64->accel.write_mask << 16); + WRITE(mach64->accel.dst_offset + ((dst_y) * mach64->accel.dst_pitch) + (dst_x), mach64->accel.dst_size); } } @@ -1636,14 +1704,18 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) mach64->accel.src_x = 0; if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { mach64->accel.src_x_start = (mach64->src_y_x_start >> 16) & 0xfff; + if ((mach64->src_y_x_start >> 16) & 0x1000) + mach64->accel.src_x_start |= ~0xfff; mach64->accel.src_x_count = mach64->accel.src_width2; } else mach64->accel.src_x_count = mach64->accel.src_width1; } } + mach64->accel.xx_count++; mach64->accel.x_count--; if (mach64->accel.x_count <= 0) { + mach64->accel.xx_count = 0; mach64->accel.x_count = mach64->accel.dst_width; mach64->accel.dst_x = 0; mach64->accel.dst_y += mach64->accel.yinc; @@ -1657,7 +1729,9 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (mach64->accel.src_y_count <= 0) { mach64->accel.src_y = 0; if ((mach64->src_cntl & (SRC_PATT_ROT_EN | SRC_PATT_EN)) == (SRC_PATT_ROT_EN | SRC_PATT_EN)) { - mach64->accel.src_y_start = mach64->src_y_x_start & 0xfff; + mach64->accel.src_y_start = mach64->src_y_x_start & 0x3fff; + if (mach64->src_y_x_start & 0x4000) + mach64->accel.src_y_start |= ~0x3fff; mach64->accel.src_y_count = mach64->accel.src_height2; } else mach64->accel.src_y_count = mach64->accel.src_height1; @@ -1702,7 +1776,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (mach64->accel.source_host) { host_dat = cpu_dat; - switch (mach64->accel.src_size) { + switch (mach64->accel.host_size) { case 0: cpu_dat >>= 8; count -= 8; @@ -1783,9 +1857,8 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) MIX - if (!(mach64->dst_cntl & DST_Y_MAJOR)) - { - if (x == 0) + if (!(mach64->dst_cntl & DST_Y_MAJOR)) { + if (!x) dest_dat &= ~1; } else { @@ -1831,7 +1904,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (mach64->accel.source_host) { host_dat = cpu_dat; - switch (mach64->accel.src_size) { + switch (mach64->accel.host_size) { case 0: cpu_dat >>= 8; count -= 8; @@ -1909,7 +1982,7 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) MIX - WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); + WRITE(mach64->accel.dst_offset + (mach64->accel.dst_y * mach64->accel.dst_pitch) + mach64->accel.dst_x, mach64->accel.dst_size); } mach64->accel.x_count--; @@ -2347,6 +2420,7 @@ mach64_ext_readb(uint32_t addr, void *p) mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 22) << 4); else mach64->config_cntl = (mach64->config_cntl & ~0x3ff0) | ((mach64->linear_base >> 24) << 4); + READ8(addr, mach64->config_cntl); break; case 0xe0: @@ -2667,11 +2741,15 @@ mach64_ext_readb(uint32_t addr, void *p) case 0x310: case 0x311: - if (!FIFO_EMPTY) - wake_fifo_thread(mach64); - ret = 0; - if (FIFO_FULL) - ret = 0xff; + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) { + ret = 0; + } else { + if (!FIFO_EMPTY) + wake_fifo_thread(mach64); + ret = 0; + if (FIFO_FULL) + ret = 0xff; + } break; case 0x320: @@ -2697,7 +2775,10 @@ mach64_ext_readb(uint32_t addr, void *p) break; case 0x338: - ret = FIFO_EMPTY ? 0 : 1; + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) + ret = 0; + else + ret = FIFO_EMPTY ? 0 : 1; break; default: @@ -2876,7 +2957,10 @@ mach64_ext_writeb(uint32_t addr, uint8_t val, void *p) mach64_log("nmach64_ext_writeb: addr=%04x val=%02x\n", addr, val); } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) + mach64_accel_write_fifo(mach64, addr & 0x3ff, val); + else + mach64_queue(mach64, addr & 0x3ff, val, FIFO_WRITE_BYTE); } else switch (addr & 0x3ff) { case 0x00: @@ -3099,7 +3183,10 @@ mach64_ext_writew(uint32_t addr, uint16_t val, void *p) mach64_ext_writeb(addr, val, p); mach64_ext_writeb(addr + 1, val >> 8, p); } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) + mach64_accel_write_fifo_w(mach64, addr & 0x3fe, val); + else + mach64_queue(mach64, addr & 0x3fe, val, FIFO_WRITE_WORD); } else switch (addr & 0x3fe) { default: @@ -3120,7 +3207,10 @@ mach64_ext_writel(uint32_t addr, uint32_t val, void *p) mach64_ext_writew(addr, val, p); mach64_ext_writew(addr + 2, val >> 16, p); } else if (addr & 0x300) { - mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); + if (((mach64->crtc_gen_cntl >> 8) & 7) == BPP_24) + mach64_accel_write_fifo_l(mach64, addr & 0x3fc, val); + else + mach64_queue(mach64, addr & 0x3fc, val, FIFO_WRITE_DWORD); } else switch (addr & 0x3fc) { default: @@ -4210,9 +4300,8 @@ mach64_common_init(const device_t *info) mach64_io_set(mach64); - if (info->flags & DEVICE_PCI) { + if (info->flags & DEVICE_PCI) mach64->card = pci_add_card(PCI_ADD_VIDEO, mach64_pci_read, mach64_pci_write, mach64); - } mach64->pci_regs[PCI_REG_COMMAND] = 3; mach64->pci_regs[0x30] = 0x00; @@ -4252,7 +4341,7 @@ mach64gx_init(const device_t *info) mach64->type = MACH64_GX; mach64->pci = !!(info->flags & DEVICE_PCI); mach64->pci_id = (int) 'X' | ((int) 'G' << 8); - mach64->config_chip_id = 0x020000d7; + mach64->config_chip_id = 0x000000d7; mach64->dac_cntl = 5 << 16; /*ATI 68860 RAMDAC*/ mach64->config_stat0 = (5 << 9) | (3 << 3); /*ATI-68860, 256Kx16 DRAM*/ if (info->flags & DEVICE_PCI) @@ -4282,10 +4371,7 @@ mach64vt2_init(const device_t *info) mach64_t *mach64 = mach64_common_init(info); svga_t *svga = &mach64->svga; - if (info->flags & DEVICE_PCI) - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); - else - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_vlb); + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_mach64_pci); mach64->type = MACH64_VT2; mach64->pci = 1; @@ -4299,8 +4385,7 @@ mach64vt2_init(const device_t *info) rom_init(&mach64->bios_rom, BIOS_ROMVT2_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); - if (info->flags & DEVICE_PCI) - mem_mapping_disable(&mach64->bios_rom.mapping); + mem_mapping_disable(&mach64->bios_rom.mapping); svga->vblank_start = mach64_vblank_start; From f9d5ab39b3be718130a92056271a227263bb57fd Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 21:46:15 +0200 Subject: [PATCH 05/44] CPU with softfloat: Added softfloat versions of the i686 FX opcodes while preserving the existing non-softfloat ones. --- src/cpu/x86_ops_i686.h | 132 +++++++++++++++++++++++++++++++++++++++++ src/cpu/x87.c | 73 +++++++++++++++++++++++ src/cpu/x87.h | 2 + 3 files changed, 207 insertions(+) diff --git a/src/cpu/x86_ops_i686.h b/src/cpu/x86_ops_i686.h index 9e00249ca..f2b07a1c4 100644 --- a/src/cpu/x86_ops_i686.h +++ b/src/cpu/x86_ops_i686.h @@ -43,6 +43,132 @@ opSYSEXIT(uint32_t fetchdat) return ret; } +static int +sf_fx_save_stor_common(uint32_t fetchdat, int bits) +{ + uint8_t fxinst = 0; + uint32_t tag_byte; + unsigned index; + floatx80 reg; + + if (CPUID < 0x650) + return ILLEGAL(fetchdat); + + FP_ENTER(); + + if (bits == 32) { + fetch_ea_32(fetchdat); + } else { + fetch_ea_16(fetchdat); + } + + if (cpu_state.eaaddr & 0xf) { + x386_dynarec_log("Effective address %08X not on 16-byte boundary\n", cpu_state.eaaddr); + x86gpf(NULL, 0); + return cpu_state.abrt; + } + + fxinst = (rmdat >> 3) & 7; + + if ((fxinst > 1) || (cpu_mod == 3)) { + x86illegal(); + return cpu_state.abrt; + } + + FP_ENTER(); + + if (fxinst == 1) { + /* FXRSTOR */ + fpu_state.cwd = readmemw(easeg, cpu_state.eaaddr); + fpu_state.swd = readmemw(easeg, cpu_state.eaaddr + 2); + fpu_state.tos = (fpu_state.swd >> 11) & 7; + + /* always set bit 6 as '1 */ + fpu_state.cwd = (fpu_state.cwd & ~FPU_CW_Reserved_Bits) | 0x0040; + + /* Restore x87 FPU Opcode */ + /* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */ + fpu_state.foo = readmemw(easeg, cpu_state.eaaddr + 6) & 0x7FF; + + fpu_state.fip = readmeml(easeg, cpu_state.eaaddr + 8); + fpu_state.fcs = readmemw(easeg, cpu_state.eaaddr + 12); + + tag_byte = readmemb(easeg, cpu_state.eaaddr + 4); + + fpu_state.fdp = readmeml(easeg, cpu_state.eaaddr + 16); + fpu_state.fds = readmemw(easeg, cpu_state.eaaddr + 20); + + /* load i387 register file */ + for (index = 0; index < 8; index++) { + reg.fraction = readmemq(easeg, cpu_state.eaaddr + (index * 16) + 32); + reg.exp = readmemw(easeg, cpu_state.eaaddr + (index * 16) + 40); + + // update tag only if it is not empty + FPU_save_regi_tag(reg, IS_TAG_EMPTY(index) ? X87_TAG_EMPTY : FPU_tagof(reg), index); + } + + fpu_state.tag = unpack_FPU_TW(tag_byte); + + /* check for unmasked exceptions */ + if (fpu_state.swd & ~fpu_state.cwd & FPU_CW_Exceptions_Mask) { + /* set the B and ES bits in the status-word */ + fpu_state.swd |= (FPU_SW_Summary | FPU_SW_Backward); + } else { + /* clear the B and ES bits in the status-word */ + fpu_state.swd &= ~(FPU_SW_Summary | FPU_SW_Backward); + } + + CLOCK_CYCLES((cr0 & 1) ? 34 : 44); + } else { + /* FXSAVE */ + writememw(easeg, cpu_state.eaaddr, i387_get_control_word()); + writememw(easeg, cpu_state.eaaddr + 2, i387_get_status_word()); + writememw(easeg, cpu_state.eaaddr + 4, pack_FPU_TW(fpu_state.tag)); + + /* x87 FPU Opcode (16 bits) */ + /* The lower 11 bits contain the FPU opcode, upper 5 bits are reserved */ + writememw(easeg, cpu_state.eaaddr + 6, fpu_state.foo); + + /* + * x87 FPU IP Offset (32/64 bits) + * The contents of this field differ depending on the current + * addressing mode (16/32/64 bit) when the FXSAVE instruction was executed: + * + 64-bit mode - 64-bit IP offset + * + 32-bit mode - 32-bit IP offset + * + 16-bit mode - low 16 bits are IP offset; high 16 bits are reserved. + * x87 CS FPU IP Selector + * + 16 bit, in 16/32 bit mode only + */ + writememl(easeg, cpu_state.eaaddr + 8, fpu_state.fip); + writememl(easeg, cpu_state.eaaddr + 12, fpu_state.fcs); + + /* + * x87 FPU Instruction Operand (Data) Pointer Offset (32/64 bits) + * The contents of this field differ depending on the current + * addressing mode (16/32 bit) when the FXSAVE instruction was executed: + * + 64-bit mode - 64-bit offset + * + 32-bit mode - 32-bit offset + * + 16-bit mode - low 16 bits are offset; high 16 bits are reserved. + * x87 DS FPU Instruction Operand (Data) Pointer Selector + * + 16 bit, in 16/32 bit mode only + */ + writememl(easeg, cpu_state.eaaddr + 16, fpu_state.fdp); + writememl(easeg, cpu_state.eaaddr + 20, fpu_state.fds); + + /* store i387 register file */ + for (index = 0; index < 8; index++) { + const floatx80 fp = FPU_read_regi(index); + + writememq(easeg, cpu_state.eaaddr + (index * 16) + 32, fp.fraction); + writememw(easeg, cpu_state.eaaddr + (index * 16) + 40, fp.exp); + } + + CLOCK_CYCLES((cr0 & 1) ? 56 : 67); + } + + return cpu_state.abrt; +} + static int fx_save_stor_common(uint32_t fetchdat, int bits) { @@ -253,12 +379,18 @@ fx_save_stor_common(uint32_t fetchdat, int bits) static int opFXSAVESTOR_a16(uint32_t fetchdat) { + if (fpu_softfloat) + return sf_fx_save_stor_common(fetchdat, 16); + return fx_save_stor_common(fetchdat, 16); } static int opFXSAVESTOR_a32(uint32_t fetchdat) { + if (fpu_softfloat) + return sf_fx_save_stor_common(fetchdat, 32); + return fx_save_stor_common(fetchdat, 32); } diff --git a/src/cpu/x87.c b/src/cpu/x87.c index 98ceb105b..181b7b9ca 100644 --- a/src/cpu/x87.c +++ b/src/cpu/x87.c @@ -439,6 +439,79 @@ FPU_tagof(const floatx80 reg) return X87_TAG_VALID; } +uint8_t +pack_FPU_TW(uint16_t twd) +{ + uint8_t tag_byte = 0; + + if ((twd & 0x0003) != 0x0003) tag_byte |= 0x01; + if ((twd & 0x000c) != 0x000c) tag_byte |= 0x02; + if ((twd & 0x0030) != 0x0030) tag_byte |= 0x04; + if ((twd & 0x00c0) != 0x00c0) tag_byte |= 0x08; + if ((twd & 0x0300) != 0x0300) tag_byte |= 0x10; + if ((twd & 0x0c00) != 0x0c00) tag_byte |= 0x20; + if ((twd & 0x3000) != 0x3000) tag_byte |= 0x40; + if ((twd & 0xc000) != 0xc000) tag_byte |= 0x80; + + return tag_byte; +} + +uint16_t +unpack_FPU_TW(uint16_t tag_byte) +{ + uint32_t twd = 0; + + /* FTW + * + * Note that the original format for FTW can be recreated from the stored + * FTW valid bits and the stored 80-bit FP data (assuming the stored data + * was not the contents of MMX registers) using the following table: + + | Exponent | Exponent | Fraction | J,M bits | FTW valid | x87 FTW | + | all 1s | all 0s | all 0s | | | | + ------------------------------------------------------------------- + | 0 | 0 | 0 | 0x | 1 | S 10 | + | 0 | 0 | 0 | 1x | 1 | V 00 | + ------------------------------------------------------------------- + | 0 | 0 | 1 | 00 | 1 | S 10 | + | 0 | 0 | 1 | 10 | 1 | V 00 | + ------------------------------------------------------------------- + | 0 | 1 | 0 | 0x | 1 | S 10 | + | 0 | 1 | 0 | 1x | 1 | S 10 | + ------------------------------------------------------------------- + | 0 | 1 | 1 | 00 | 1 | Z 01 | + | 0 | 1 | 1 | 10 | 1 | S 10 | + ------------------------------------------------------------------- + | 1 | 0 | 0 | 1x | 1 | S 10 | + | 1 | 0 | 0 | 1x | 1 | S 10 | + ------------------------------------------------------------------- + | 1 | 0 | 1 | 00 | 1 | S 10 | + | 1 | 0 | 1 | 10 | 1 | S 10 | + ------------------------------------------------------------------- + | all combinations above | 0 | E 11 | + + * + * The J-bit is defined to be the 1-bit binary integer to the left of + * the decimal place in the significand. + * + * The M-bit is defined to be the most significant bit of the fractional + * portion of the significand (i.e., the bit immediately to the right of + * the decimal place). When the M-bit is the most significant bit of the + * fractional portion of the significand, it must be 0 if the fraction + * is all 0's. + */ + + for (int index = 7; index >= 0; index--, twd <<= 2, tag_byte <<= 1) { + if (tag_byte & 0x80) { + const floatx80 *fpu_reg = &fpu_state.st_space[index & 7]; + twd |= FPU_tagof(*fpu_reg); + } else { + twd |= X87_TAG_EMPTY; + } + } + + return (twd >> 2); +} #ifdef ENABLE_808X_LOG void diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 5d460bc4b..8fab28ce8 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -141,6 +141,8 @@ void FPU_stack_underflow(uint32_t fetchdat, int stnr, int pop_stack); int FPU_handle_NaN32(floatx80 a, float32 b, floatx80 *r, struct float_status_t *status); int FPU_handle_NaN64(floatx80 a, float64 b, floatx80 *r, struct float_status_t *status); int FPU_tagof(const floatx80 reg); +uint8_t pack_FPU_TW(uint16_t twd); +uint16_t unpack_FPU_TW(uint16_t tag_byte); static __inline uint16_t i387_get_control_word(void) From 19fa6c8f8b7476f212cf024f1e74f47ce3db6c90 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 22:14:56 +0200 Subject: [PATCH 06/44] Machine features and fixes: Revamped and refactored the Compaq AT clone code, including a more correct Plasma emulation and undev branch the Deskpro 386 while adding the September 1986 and January 1988 bioses. Added Compaq AT KBC strictly for the Deskpro 386 with the right settings, including the FPU bit. The generic AMI/Quadtel/Phoenix IBM AT's don't issue the speed problems of the pure IBM AT beyond 8Mhz, so don't limit them to 8Mhz. --- src/device/kbc_at.c | 20 +- src/include/86box/keyboard.h | 1 + src/include/86box/machine.h | 3 +- src/machine/m_at_compaq.c | 678 ++++++++++++++++++----------------- src/machine/machine_table.c | 66 +++- 5 files changed, 425 insertions(+), 343 deletions(-) diff --git a/src/device/kbc_at.c b/src/device/kbc_at.c index 37ccf3555..ee5a6d17e 100644 --- a/src/device/kbc_at.c +++ b/src/device/kbc_at.c @@ -82,7 +82,8 @@ #define KBC_VEN_NCR 0x24 #define KBC_VEN_ALI 0x28 #define KBC_VEN_SIEMENS 0x2c -#define KBC_VEN_MASK 0x3c +#define KBC_VEN_COMPAQ 0x30 +#define KBC_VEN_MASK 0x7c #define FLAG_CLOCK 0x01 #define FLAG_CACHE 0x02 @@ -981,6 +982,8 @@ write64_generic(void *priv, uint8_t val) } else if (((dev->flags & KBC_TYPE_MASK) >= KBC_TYPE_PS2_1) && ((dev->flags & KBC_TYPE_MASK) < KBC_TYPE_GREEN)) /* (B0 or F0) | (0x08 or 0x0c) */ kbc_delay_to_ob(dev, ((dev->p1 | fixed_bits) & 0xf0) | (((dev->flags & KBC_VEN_MASK) == KBC_VEN_ACER) ? 0x08 : 0x0c), 0, 0x00); + else if (kbc_ven == KBC_VEN_COMPAQ) + kbc_delay_to_ob(dev, dev->p1 | (hasfpu ? 0x00 : 0x04), 0, 0x00); else /* (B0 or F0) | (0x04 or 0x44) */ kbc_delay_to_ob(dev, dev->p1 | fixed_bits, 0, 0x00); @@ -1968,6 +1971,7 @@ kbc_at_init(const device_t *info) case KBC_VEN_GENERIC: case KBC_VEN_NCR: case KBC_VEN_IBM_PS1: + case KBC_VEN_COMPAQ: dev->write64_ven = write64_generic; break; @@ -2141,6 +2145,20 @@ const device_t keyboard_at_ncr_device = { .config = NULL }; +const device_t keyboard_at_compaq_device = { + .name = "PC/AT Keyboard (Compaq)", + .internal_name = "keyboard_at_compaq", + .flags = DEVICE_KBC, + .local = KBC_TYPE_ISA | KBC_VEN_COMPAQ, + .init = kbc_at_init, + .close = kbc_at_close, + .reset = kbc_at_reset, + { .available = NULL }, + .speed_changed = NULL, + .force_redraw = NULL, + .config = NULL +}; + const device_t keyboard_ps2_device = { .name = "PS/2 Keyboard", .internal_name = "keyboard_ps2", diff --git a/src/include/86box/keyboard.h b/src/include/86box/keyboard.h index 392539c73..f09507601 100644 --- a/src/include/86box/keyboard.h +++ b/src/include/86box/keyboard.h @@ -234,6 +234,7 @@ extern const device_t keyboard_at_tg_ami_device; extern const device_t keyboard_at_toshiba_device; extern const device_t keyboard_at_olivetti_device; extern const device_t keyboard_at_ncr_device; +extern const device_t keyboard_at_compaq_device; extern const device_t keyboard_ps2_device; extern const device_t keyboard_ps2_ps1_device; extern const device_t keyboard_ps2_ps1_pci_device; diff --git a/src/include/86box/machine.h b/src/include/86box/machine.h index cee90649f..7e17c270f 100644 --- a/src/include/86box/machine.h +++ b/src/include/86box/machine.h @@ -544,9 +544,8 @@ extern int machine_at_cmdpc_init(const machine_t *); extern int machine_at_portableii_init(const machine_t *); extern int machine_at_portableiii_init(const machine_t *); extern int machine_at_portableiii386_init(const machine_t *); -#if defined(DEV_BRANCH) && defined(USE_DESKPRO386) extern int machine_at_deskpro386_init(const machine_t *); -#endif +extern int machine_at_deskpro386_01_1988_init(const machine_t *); /* m_at_socket4.c */ extern void machine_at_premiere_common_init(const machine_t *, int); diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index dd8370a4f..0b96495be 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -31,6 +31,7 @@ #include <86box/mem.h> #include <86box/rom.h> #include <86box/device.h> +#include <86box/keyboard.h> #include <86box/fdd.h> #include <86box/fdc.h> #include <86box/fdc_ext.h> @@ -41,22 +42,28 @@ #include <86box/vid_cga.h> #include <86box/vid_cga_comp.h> + +static video_timings_t timing_compaq_plasma = { .type = VIDEO_ISA, .write_b = 8, .write_w = 16, .write_l = 32, .read_b = 8, .read_w = 16, .read_l = 32 }; + enum { COMPAQ_PORTABLEII = 0, COMPAQ_PORTABLEIII, COMPAQ_PORTABLEIII386, - COMPAQ_DESKPRO386 + COMPAQ_DESKPRO386, + COMPAQ_DESKPRO386_01_1988 }; #define CGA_RGB 0 #define CGA_COMPOSITE 1 -#define COMPOSITE_OLD 0 -#define COMPOSITE_NEW 1 - /*Very rough estimate*/ #define VID_CLOCK (double) (651 * 416 * 60) +static uint8_t cga_crtcmask[32] = { + 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, + 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; + /* Mapping of attributes to colours */ static uint32_t amber; static uint32_t black; @@ -72,6 +79,8 @@ static uint32_t normcols[256][2]; */ static int8_t cpq_st_display_internal = -1; +static uint8_t mdaattr[256][2][2]; + static void compaq_plasma_display_set(uint8_t internal) { @@ -85,21 +94,13 @@ compaq_plasma_display_get(void) } typedef struct compaq_plasma_t { - mem_mapping_t plasma_mapping; cga_t cga; uint8_t port_23c6; uint8_t internal_monitor; - uint8_t attrmap; /* Attribute mapping register */ - int linepos, displine; - uint8_t *vram; - uint64_t dispontime, dispofftime; - int dispon, fullchange; + uint8_t attrmap; } compaq_plasma_t; -static uint8_t cga_crtcmask[32] = { - 0xff, 0xff, 0xff, 0xff, 0x7f, 0x1f, 0x7f, 0x7f, 0xf3, 0x1f, 0x7f, 0x1f, 0x3f, 0xff, 0x3f, 0xff, - 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; +static int compaq_machine_type = 0; /* Compaq Deskpro 386 remaps RAM from 0xA0000-0xFFFFF to 0xFA0000-0xFFFFFF */ static mem_mapping_t ram_mapping; @@ -121,8 +122,18 @@ compaq_plasma_recalctimings(compaq_plasma_t *self) disptime = 651; _dispontime = 640; _dispofftime = disptime - _dispontime; - self->dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); - self->dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); + self->cga.dispontime = (uint64_t) (_dispontime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); + self->cga.dispofftime = (uint64_t) (_dispofftime * (cpuclock / VID_CLOCK) * (double) (1ULL << 32)); +} + +static void +compaq_plasma_waitstates(void *p) +{ + int ws_array[16] = { 3, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8, 4, 5, 6, 7, 8 }; + int ws; + + ws = ws_array[cycles & 0xf]; + sub_cycles(ws); } static void @@ -130,7 +141,8 @@ compaq_plasma_write(uint32_t addr, uint8_t val, void *priv) { compaq_plasma_t *self = (compaq_plasma_t *) priv; - self->vram[addr & 0x7fff] = val; + self->cga.vram[addr & 0x7fff] = val; + compaq_plasma_waitstates(&self->cga); } static uint8_t @@ -139,206 +151,12 @@ compaq_plasma_read(uint32_t addr, void *priv) compaq_plasma_t *self = (compaq_plasma_t *) priv; uint8_t ret; - ret = (self->vram[addr & 0x7fff]); + compaq_plasma_waitstates(&self->cga); + ret = (self->cga.vram[addr & 0x7fff]); return ret; } -/* Draw a row of text in 80-column mode */ -static void -compaq_plasma_text80(compaq_plasma_t *self) -{ - uint32_t cols[2]; - int c; - uint8_t chr; - uint8_t attr; - int drawcursor; - int cursorline; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; - - sc = (self->displine) & 15; - addr = ((ma & ~1) + (self->displine >> 4) * 80) * 2; - ma += (self->displine >> 4) * 80; - - if ((self->cga.crtc[10] & 0x60) == 0x20) - cursorline = 0; - else - cursorline = ((self->cga.crtc[10] & 0x0F) * 2 <= sc) && ((self->cga.crtc[11] & 0x0F) * 2 >= sc); - - for (uint8_t x = 0; x < 80; x++) { - chr = self->vram[(addr + 2 * x) & 0x7FFF]; - attr = self->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); - - blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - - if (self->cga.cgamode & 0x20) { /* Blink */ - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) - cols[1] = cols[0]; - } else { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) - ((uint32_t *) buffer32->line[self->displine])[(x << 3) + c] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } else { - for (c = 0; c < 8; c++) - ((uint32_t *) buffer32->line[self->displine])[(x << 3) + c] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - ++ma; - } -} - -/* Draw a row of text in 40-column mode */ -static void -compaq_plasma_text40(compaq_plasma_t *self) -{ - uint32_t cols[2]; - int c; - uint8_t chr; - uint8_t attr; - int drawcursor; - int cursorline; - int blink; - uint16_t addr; - uint8_t sc; - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; - - sc = (self->displine) & 15; - addr = ((ma & ~1) + (self->displine >> 4) * 40) * 2; - ma += (self->displine >> 4) * 40; - - if ((self->cga.crtc[10] & 0x60) == 0x20) - cursorline = 0; - else - cursorline = ((self->cga.crtc[10] & 0x0F) * 2 <= sc) && ((self->cga.crtc[11] & 0x0F) * 2 >= sc); - - for (uint8_t x = 0; x < 40; x++) { - chr = self->vram[(addr + 2 * x) & 0x7FFF]; - attr = self->vram[(addr + 2 * x + 1) & 0x7FFF]; - drawcursor = ((ma == ca) && cursorline && (self->cga.cgamode & 8) && (self->cga.cgablink & 16)); - - blink = ((self->cga.cgablink & 16) && (self->cga.cgamode & 0x20) && (attr & 0x80) && !drawcursor); - - if (self->cga.cgamode & 0x20) { /* Blink */ - cols[1] = blinkcols[attr][1]; - cols[0] = blinkcols[attr][0]; - if (blink) - cols[1] = cols[0]; - } else { - cols[1] = normcols[attr][1]; - cols[0] = normcols[attr][0]; - } - if (drawcursor) { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); - } - } else { - for (c = 0; c < 8; c++) { - ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2] = ((uint32_t *) buffer32->line[self->displine])[(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; - } - } - ++ma; - } -} - -/* Draw a line in CGA 640x200 or Compaq Plasma 640x400 mode */ -static void -compaq_plasma_cgaline6(compaq_plasma_t *self) -{ - uint8_t dat; - uint32_t ink = 0; - uint16_t addr; - uint32_t fg = (self->cga.cgacol & 0x0F) ? amber : black; - uint32_t bg = black; - - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - - if ((self->cga.crtc[9] == 3) || (self->port_23c6 & 1)) /* 640*400 */ { - addr = ((self->displine) & 1) * 0x2000 + ((self->displine >> 1) & 1) * 0x4000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1); - } else { - addr = ((self->displine >> 1) & 1) * 0x2000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1); - } - for (uint8_t x = 0; x < 80; x++) { - dat = self->vram[addr & 0x7FFF]; - addr++; - - for (uint8_t c = 0; c < 8; c++) { - ink = (dat & 0x80) ? fg : bg; - if (!(self->cga.cgamode & 8)) - ink = black; - ((uint32_t *) buffer32->line[self->displine])[x * 8 + c] = ink; - dat <<= 1; - } - } -} - -/* Draw a line in CGA 320x200 mode. Here the CGA colours are converted to - * dither patterns: colour 1 to 25% grey, colour 2 to 50% grey */ -static void -compaq_plasma_cgaline4(compaq_plasma_t *self) -{ - uint8_t dat; - uint8_t pattern; - uint32_t ink0 = 0; - uint32_t ink1 = 0; - uint16_t addr; - - uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; - - /* 320*200 */ - addr = ((self->displine >> 1) & 1) * 0x2000 + (self->displine >> 2) * 80 + ((ma & ~1) << 1); - - for (uint8_t x = 0; x < 80; x++) { - dat = self->vram[addr & 0x7FFF]; - addr++; - - for (uint8_t c = 0; c < 4; c++) { - pattern = (dat & 0xC0) >> 6; - if (!(self->cga.cgamode & 8)) - pattern = 0; - - switch (pattern & 3) { - case 0: - ink0 = ink1 = black; - break; - case 1: - if (self->displine & 1) { - ink0 = black; - ink1 = black; - } else { - ink0 = amber; - ink1 = black; - } - break; - case 2: - if (self->displine & 1) { - ink0 = black; - ink1 = amber; - } else { - ink0 = amber; - ink1 = black; - } - break; - case 3: - ink0 = ink1 = amber; - break; - } - ((uint32_t *) buffer32->line[self->displine])[x * 8 + 2 * c] = ink0; - ((uint32_t *) buffer32->line[self->displine])[x * 8 + 2 * c + 1] = ink1; - dat <<= 2; - } - } -} - static void compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) { @@ -348,7 +166,7 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) switch (addr) { /* Emulated CRTC, register select */ case 0x3d4: - self->cga.crtcreg = val & 31; + cga_out(addr, val, &self->cga); break; /* Emulated CRTC, value */ @@ -366,33 +184,26 @@ compaq_plasma_out(uint16_t addr, uint8_t val, void *priv) if (old != val) { if (self->cga.crtcreg < 0xe || self->cga.crtcreg > 0x10) { - self->fullchange = changeframecount; + self->cga.fullchange = changeframecount; compaq_plasma_recalctimings(self); } } break; - case 0x3d8: - self->cga.cgamode = val; - break; - case 0x3d9: - self->cga.cgacol = val; + cga_out(addr, val, &self->cga); break; case 0x13c6: - if (val & 8) - compaq_plasma_display_set(1); - else - compaq_plasma_display_set(0); + compaq_plasma_display_set((val & 8) ? 1 : 0); break; case 0x23c6: self->port_23c6 = val; if (val & 8) /* Disable internal CGA */ - mem_mapping_disable(&self->plasma_mapping); + mem_mapping_disable(&self->cga.mapping); else - mem_mapping_enable(&self->plasma_mapping); + mem_mapping_enable(&self->cga.mapping); break; } } @@ -405,31 +216,38 @@ compaq_plasma_in(uint16_t addr, void *priv) switch (addr) { case 0x3d4: - ret = self->cga.crtcreg; + case 0x3da: + ret = cga_in(addr, &self->cga); break; case 0x3d5: if (self->cga.crtcreg == 0x12) { - ret = self->attrmap & 0x0F; + ret = self->attrmap & 0x0f; if (self->internal_monitor) ret |= 0x30; /* Plasma / CRT */ } else - ret = self->cga.crtc[self->cga.crtcreg]; - break; - - case 0x3da: - ret = self->cga.cgastat; + ret = cga_in(addr, &self->cga); break; case 0x13c6: - if (compaq_plasma_display_get()) - ret = 8; - else - ret = 0; + ret = compaq_plasma_display_get() ? 8 : 0; + ret |= 4; + break; + + case 0x1bc6: + ret = 0; + if (compaq_plasma_display_get()) { + if ((self->cga.cgamode & 0x12) == 0x12) { + if (self->port_23c6 & 8) + ret |= 0x40; + else + ret |= 0x20; + } + } break; case 0x23c6: - ret = self->port_23c6; + ret = 0; break; } @@ -440,56 +258,243 @@ static void compaq_plasma_poll(void *p) { compaq_plasma_t *self = (compaq_plasma_t *) p; + uint8_t chr, attr; + uint8_t sc; + uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; + uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; + uint16_t dat; + uint16_t addr; + int drawcursor; + int x, c; + int cursorline; + int blink = 0; + int underline = 0; + uint32_t ink = 0; + uint32_t fg = (self->cga.cgacol & 0x0f) ? amber : black; + uint32_t bg = black; + uint32_t cols[2]; + uint8_t dat2, pattern; + uint32_t ink0 = 0, ink1 = 0; /* Switch between internal plasma and external CRT display. */ - if (cpq_st_display_internal != -1 && cpq_st_display_internal != self->internal_monitor) { + if ((cpq_st_display_internal != -1) && (cpq_st_display_internal != self->internal_monitor)) { self->internal_monitor = cpq_st_display_internal; compaq_plasma_recalctimings(self); } + /* graphic mode and not mode 40h */ if (!self->internal_monitor && !(self->port_23c6 & 1)) { cga_poll(&self->cga); return; } - if (!self->linepos) { - timer_advance_u64(&self->cga.timer, self->dispofftime); + /* mode 40h or text mode */ + if (!self->cga.linepos) { + timer_advance_u64(&self->cga.timer, self->cga.dispofftime); self->cga.cgastat |= 1; - self->linepos = 1; - if (self->dispon) { - if (self->displine == 0) + self->cga.linepos = 1; + if (self->cga.cgadispon) { + if (self->cga.displine == 0) { video_wait_for_buffer(); + } + if (self->cga.cgamode & 2) { + if (self->cga.cgamode & 0x10) { + /* 640x400 mode */ + if (self->port_23c6 & 1) /* 640*400 */ { + addr = ((self->cga.displine) & 1) * 0x2000 + ((self->cga.displine >> 1) & 1) * 0x4000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); + } else { + addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); + } + for (x = 0; x < 80; x++) { + dat2 = self->cga.vram[(addr & 0x7FFF)]; + addr++; - /* Graphics */ - if (self->cga.cgamode & 0x02) { - if (self->cga.cgamode & 0x10) - compaq_plasma_cgaline6(self); + for (c = 0; c < 8; c++) { + ink = (dat2 & 0x80) ? fg : bg; + if (!(self->cga.cgamode & 8)) + ink = black; + ((uint32_t *) buffer32->line[self->cga.displine])[x * 8 + c] = ink; + dat2 <<= 1; + } + } + } else { + addr = ((self->cga.displine >> 1) & 1) * 0x2000 + (self->cga.displine >> 2) * 80 + ((ma & ~1) << 1); + for (x = 0; x < 80; x++) { + dat2 = self->cga.vram[(addr & 0x7fff)]; + addr++; + + for (c = 0; c < 4; c++) { + pattern = (dat2 & 0xC0) >> 6; + if (!(self->cga.cgamode & 8)) + pattern = 0; + + switch (pattern & 3) { + case 0: + ink0 = ink1 = black; + break; + case 1: + if (self->cga.displine & 1) { + ink0 = black; + ink1 = black; + } else { + ink0 = amber; + ink1 = black; + } + break; + case 2: + if (self->cga.displine & 1) { + ink0 = black; + ink1 = amber; + } else { + ink0 = amber; + ink1 = black; + } + break; + case 3: + ink0 = ink1 = amber; + break; + } + buffer32->line[self->cga.displine][x * 8 + 2 * c] = ink0; + buffer32->line[self->cga.displine][x * 8 + 2 * c + 1] = ink1; + dat2 <<= 2; + } + } + } + } else if (self->cga.cgamode & 1) { + /* 80-col */ + sc = self->cga.displine & 0x0f; + addr = ((ma & ~1) + (self->cga.displine >> 4) * 80) * 2; + ma += (self->cga.displine >> 4) * 80; + + if ((self->cga.crtc[0x0a] & 0x60) == 0x20) + cursorline = 0; else - compaq_plasma_cgaline4(self); - } else if (self->cga.cgamode & 0x01) /* High-res text */ - compaq_plasma_text80(self); - else - compaq_plasma_text40(self); + cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); + + /* for each text column */ + for (x = 0; x < 80; x++) { + /* video output enabled */ + if (self->cga.cgamode & 8) { + chr = self->cga.vram[(addr + 2 * x) & 0x7fff]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff]; + } else + chr = attr = 0; + /* check if cursor has to be drawn */ + drawcursor = ((ma == ca) && cursorline && self->cga.cursoron); + underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); + if (underline) { + /* set forecolor to white */ + attr |= 7; + } + blink = 0; + /* blink active */ + if (self->cga.cgamode & 0x20) { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + /* attribute 7 active and not cursor */ + if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + blink = 1; + } + } else { + /* Set intensity bit */ + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + blink = (attr & 0x80) * 8 + 7 + 16; + } + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (sc == 7)) { + /* for each pixel in character width */ + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } else { + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 3) + c] = cols[(fontdatm[chr + self->cga.fontbase][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + + ++ma; + } + } else { /* 40-col */ + sc = self->cga.displine & 0x0f; + addr = ((ma & ~1) + (self->cga.displine >> 4) * 40) * 2; + ma += (self->cga.displine >> 4) * 40; + + if ((self->cga.crtc[0x0a] & 0x60) == 0x20) + cursorline = 0; + else + cursorline = ((self->cga.crtc[0x0a] & 0x0f) * 2 <= sc) && ((self->cga.crtc[0x0b] & 0x0F) * 2 >= sc); + + for (x = 0; x < 40; x++) { + if (self->cga.cgamode & 8) { + chr = self->cga.vram[(addr + 2 * x) & 0x7fff]; + attr = self->cga.vram[(addr + 2 * x + 1) & 0x7fff]; + } else { + chr = attr = 0; + } + drawcursor = ((ma == ca) && cursorline && self->cga.cursoron); + underline = ((self->port_23c6 & 0x40) && (attr & 0x1) && !(attr & 0x6)); + if (underline) { + /* set forecolor to white */ + attr |= 7; + } + blink = 0; + /* blink active */ + if (self->cga.cgamode & 0x20) { + cols[1] = blinkcols[attr][1]; + cols[0] = blinkcols[attr][0]; + /* attribute 7 active and not cursor */ + if ((self->cga.cgablink & 8) && (attr & 0x80) && !self->cga.drawcursor) { + /* set blinking */ + cols[1] = cols[0]; + blink = 1; + } + } else { + /* Set intensity bit */ + cols[1] = normcols[attr][1]; + cols[0] = normcols[attr][0]; + blink = (attr & 0x80) * 8 + 7 + 16; + } + /* character underline active and 7th row of pixels in character height being drawn */ + if (underline && (sc == 7)) { + /* for each pixel in character width */ + for (c = 0; c < 8; c++) + buffer32->line[self->cga.displine][(x << 4) + (c * 2)] = buffer32->line[self->cga.displine][(x << 4) + (c * 2) + 1] = mdaattr[attr][blink][1]; + } else if (drawcursor) { + for (c = 0; c < 8; c++) { + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0] ^ (amber ^ black); + } + } else { + for (c = 0; c < 8; c++) { + buffer32->line[self->cga.displine][(x << 4) + c * 2] = buffer32->line[self->cga.displine][(x << 4) + c * 2 + 1] = cols[(fontdatm[chr][sc] & (1 << (c ^ 7))) ? 1 : 0]; + } + } + ++ma; + } + } } - self->displine++; + self->cga.displine++; /* Hardcode a fixed refresh rate and VSYNC timing */ - if (self->displine == 400) { /* Start of VSYNC */ + if (self->cga.displine == 400) { /* Start of VSYNC */ self->cga.cgastat |= 8; - self->dispon = 0; + self->cga.cgadispon = 0; } - if (self->displine == 416) { /* End of VSYNC */ - self->displine = 0; + if (self->cga.displine == 416) { /* End of VSYNC */ + self->cga.displine = 0; self->cga.cgastat &= ~8; - self->dispon = 1; + self->cga.cgadispon = 1; } } else { - if (self->dispon) + if (self->cga.cgadispon) self->cga.cgastat &= ~1; - timer_advance_u64(&self->cga.timer, self->dispontime); - self->linepos = 0; + timer_advance_u64(&self->cga.timer, self->cga.dispontime); + self->cga.linepos = 0; - if (self->displine == 400) { + if (self->cga.displine == 400) { /* Hardcode 640x400 window size */ if ((640 != xsize) || (400 != ysize) || video_force_resize_get()) { xsize = 640; @@ -515,14 +520,41 @@ compaq_plasma_poll(void *p) video_bpp = 1; else video_bpp = 2; - } else video_bpp = 0; + self->cga.cgablink++; } } } +static void +compaq_plasma_mdaattr_rebuild(void) +{ + int c; + + for (c = 0; c < 256; c++) { + mdaattr[c][0][0] = mdaattr[c][1][0] = mdaattr[c][1][1] = 16; + if (c & 8) + mdaattr[c][0][1] = 15 + 16; + else + mdaattr[c][0][1] = 7 + 16; + } + + mdaattr[0x70][0][1] = 16; + mdaattr[0x70][0][0] = mdaattr[0x70][1][0] = mdaattr[0x70][1][1] = 16 + 15; + mdaattr[0xF0][0][1] = 16; + mdaattr[0xF0][0][0] = mdaattr[0xF0][1][0] = mdaattr[0xF0][1][1] = 16 + 15; + mdaattr[0x78][0][1] = 16 + 7; + mdaattr[0x78][0][0] = mdaattr[0x78][1][0] = mdaattr[0x78][1][1] = 16 + 15; + mdaattr[0xF8][0][1] = 16 + 7; + mdaattr[0xF8][0][0] = mdaattr[0xF8][1][0] = mdaattr[0xF8][1][1] = 16 + 15; + mdaattr[0x00][0][1] = mdaattr[0x00][1][1] = 16; + mdaattr[0x08][0][1] = mdaattr[0x08][1][1] = 16; + mdaattr[0x80][0][1] = mdaattr[0x80][1][1] = 16; + mdaattr[0x88][0][1] = mdaattr[0x88][1][1] = 16; +} + static void compaq_plasma_recalcattrs(compaq_plasma_t *self) { @@ -537,10 +569,10 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self) * are bold */ /* Set up colours */ - amber = makecol(0xff, 0x7D, 0x00); - black = makecol(0x64, 0x19, 0x00); + amber = makecol(0xff, 0x7d, 0x00); + black = makecol(0x64, 0x0c, 0x00); - /* Initialise the attribute mapping. Start by defaulting everything + /* Initialize the attribute mapping. Start by defaulting everything * to black on amber, and with bold set by bit 3 */ for (n = 0; n < 256; n++) { blinkcols[n][0] = normcols[n][0] = amber; @@ -607,36 +639,37 @@ compaq_plasma_recalcattrs(compaq_plasma_t *self) static void * compaq_plasma_init(const device_t *info) { - int display_type; compaq_plasma_t *self = malloc(sizeof(compaq_plasma_t)); memset(self, 0, sizeof(compaq_plasma_t)); - display_type = device_get_config_int("display_type"); - self->cga.composite = (display_type != CGA_RGB); - self->cga.revision = device_get_config_int("composite_type"); + video_inform(VIDEO_FLAG_TYPE_CGA, &timing_compaq_plasma); + loadfont_ex("roms/machines/portableiii/K Combined.bin", 1, 0x4bb2); - self->vram = malloc(0x8000); + self->cga.composite = 0; + self->cga.revision = 0; + + self->cga.vram = malloc(0x8000); self->internal_monitor = 1; cga_comp_init(self->cga.revision); timer_add(&self->cga.timer, compaq_plasma_poll, self, 1); - mem_mapping_add(&self->plasma_mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self); + mem_mapping_add(&self->cga.mapping, 0xb8000, 0x08000, compaq_plasma_read, NULL, NULL, compaq_plasma_write, NULL, NULL, NULL /*self->cga.vram*/, MEM_MAPPING_EXTERNAL, self); io_sethandler(0x03d0, 0x0010, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); io_sethandler(0x13c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); + io_sethandler(0x1bc6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); io_sethandler(0x23c6, 0x0001, compaq_plasma_in, NULL, NULL, compaq_plasma_out, NULL, NULL, self); /* Default attribute mapping is 4 */ self->attrmap = 4; compaq_plasma_recalcattrs(self); - self->cga.cgastat = 0xF4; - self->cga.vram = self->vram; - + self->cga.cgastat = 0xf4; overscan_x = overscan_y = 16; self->cga.rgb_type = device_get_config_int("rgb_type"); cga_palette = (self->cga.rgb_type << 1); cgapal_rebuild(); + compaq_plasma_mdaattr_rebuild(); return self; } @@ -646,8 +679,7 @@ compaq_plasma_close(void *p) { compaq_plasma_t *self = (compaq_plasma_t *) p; - free(self->vram); - + free(self->cga.vram); free(self); } @@ -661,38 +693,10 @@ compaq_plasma_speed_changed(void *p) const device_config_t compaq_plasma_config[] = { // clang-format off - { - .name = "display_type", - .description = "Display type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = CGA_RGB, - .file_filter = "", - .spinner = { 0 }, - .selection = { - { .description = "RGB", .value = CGA_RGB }, - { .description = "Composite", .value = CGA_COMPOSITE }, - { .description = "" } - } - }, - { - .name = "composite_type", - .description = "Composite type", - .type = CONFIG_SELECTION, - .default_string = "", - .default_int = COMPOSITE_OLD, - .file_filter = "", - .spinner = { 0 }, - { - { .description = "Old", .value = COMPOSITE_OLD }, - { .description = "New", .value = COMPOSITE_NEW }, - { .description = "" } - } - }, { .name = "rgb_type", - .description = "RGB type", - .type = CONFIG_SELECTION, + .description = "RGB type", + .type = CONFIG_SELECTION, .default_string = "", .default_int = 0, .file_filter = "", @@ -702,7 +706,6 @@ const device_config_t compaq_plasma_config[] = { { .description = "Green Monochrome", .value = 1 }, { .description = "Amber Monochrome", .value = 2 }, { .description = "Gray Monochrome", .value = 3 }, - { .description = "Color (no brown)", .value = 4 }, { .description = "" } } }, @@ -781,26 +784,36 @@ write_raml(uint32_t addr, uint32_t val, void *priv) static void machine_at_compaq_init(const machine_t *model, int type) { - if (type != COMPAQ_DESKPRO386) + compaq_machine_type = type; + + if ((type != COMPAQ_DESKPRO386) && (type != COMPAQ_DESKPRO386_01_1988)) mem_remap_top(384); if (fdc_type == FDC_INTERNAL) device_add(&fdc_at_device); - mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, - read_ram, read_ramw, read_raml, - write_ram, write_ramw, write_raml, - 0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL); + if ((type == COMPAQ_DESKPRO386) || (type == COMPAQ_DESKPRO386_01_1988) || (type == COMPAQ_PORTABLEIII386)) + mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, + read_ram, read_ramw, read_raml, + write_ram, write_ramw, write_raml, + 0xa0000 + ram, MEM_MAPPING_EXTERNAL, NULL); + else + mem_mapping_add(&ram_mapping, 0xfa0000, 0x60000, + read_ram, read_ramw, read_raml, + write_ram, write_ramw, write_raml, + 0xa0000 + ram, MEM_MAPPING_INTERNAL, NULL); video_reset(gfxcard[0]); switch (type) { case COMPAQ_PORTABLEII: + machine_at_init(model); break; case COMPAQ_PORTABLEIII: if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); + machine_at_init(model); break; case COMPAQ_PORTABLEIII386: @@ -808,15 +821,17 @@ machine_at_compaq_init(const machine_t *model, int type) device_add(&ide_isa_device); if (gfxcard[0] == VID_INTERNAL) device_add(&compaq_plasma_device); + machine_at_init(model); break; case COMPAQ_DESKPRO386: + case COMPAQ_DESKPRO386_01_1988: if (hdc_current == 1) device_add(&ide_isa_device); + machine_at_common_init(model); + device_add(&keyboard_at_compaq_device); break; } - - machine_at_init(model); } int @@ -841,9 +856,9 @@ machine_at_portableiii_init(const machine_t *model) { int ret; - ret = bios_load_interleavedr("roms/machines/portableiii/Compaq Portable III - BIOS - 106779-002 - Even.bin", - "roms/machines/portableiii/Compaq Portable III - BIOS - 106778-002 - Odd.bin", - 0x000f8000, 65536, 0); + ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin", + 0x000f8000, 65536, 0); + if (bios_only || !ret) return ret; @@ -858,9 +873,8 @@ machine_at_portableiii386_init(const machine_t *model) { int ret; - ret = bios_load_interleavedr("roms/machines/portableiii/Compaq Portable III - BIOS - 106779-002 - Even.bin", - "roms/machines/portableiii/Compaq Portable III - BIOS - 106778-002 - Odd.bin", - 0x000f8000, 65536, 0); + ret = bios_load_linearr("roms/machines/portableiii/K Combined.bin", + 0x000f8000, 65536, 0); if (bios_only || !ret) return ret; @@ -870,14 +884,13 @@ machine_at_portableiii386_init(const machine_t *model) return ret; } -#if defined(DEV_BRANCH) && defined(USE_DESKPRO386) int machine_at_deskpro386_init(const machine_t *model) { int ret; ret = bios_load_linearr("roms/machines/deskpro386/1986-09-04-HI.json.bin", - 0x000fc000, 65536, 0); + 0x000f8000, 65536, 0); if (bios_only || !ret) return ret; @@ -886,4 +899,19 @@ machine_at_deskpro386_init(const machine_t *model) return ret; } -#endif + +int +machine_at_deskpro386_01_1988_init(const machine_t *model) +{ + int ret; + + ret = bios_load_linearr("roms/machines/deskpro386/1988-01-28.json.bin", + 0x000f8000, 65536, 0); + + if (bios_only || !ret) + return ret; + + machine_at_compaq_init(model, COMPAQ_DESKPRO386_01_1988); + + return ret; +} diff --git a/src/machine/machine_table.c b/src/machine/machine_table.c index 053ca791b..5c52f7de0 100644 --- a/src/machine/machine_table.c +++ b/src/machine/machine_table.c @@ -2587,8 +2587,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 8000000, + .min_bus = 0, + .max_bus = 0, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2904,8 +2904,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 8000000, + .min_bus = 0, + .max_bus = 0, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -2943,8 +2943,8 @@ const machine_t machines[] = { .cpu = { .package = CPU_PKG_286, .block = CPU_BLOCK_NONE, - .min_bus = 6000000, - .max_bus = 8000000, + .min_bus = 0, + .max_bus = 0, .min_voltage = 0, .max_voltage = 0, .min_multi = 0, @@ -4670,9 +4670,8 @@ const machine_t machines[] = { .net_device = NULL }, /* Uses Compaq KBC firmware. */ -#if defined(DEV_BRANCH) && defined(USE_DESKPRO386) { - .name = "[ISA] Compaq Deskpro 386", + .name = "[ISA] Compaq Deskpro 386 (September 1986)", .internal_name = "deskpro386", .type = MACHINE_TYPE_386DX, .chipset = MACHINE_CHIPSET_DISCRETE, @@ -4692,13 +4691,51 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_APM, + .flags = MACHINE_IDE, .ram = { - .min = 1024, - .max = 14336, - .step = 1024 + .min = 640, + .max = 16384, + .step = 128 }, - .nvrmask = 127, + .nvrmask = 63, + .kbc_device = NULL, + .kbc_p1 = 0, + .gpio = 0, + .device = NULL, + .fdc_device = NULL, + .sio_device = NULL, + .vid_device = NULL, + .snd_device = NULL, + .net_device = NULL + }, + { + .name = "[ISA] Compaq Deskpro 386 (January 1988)", + .internal_name = "deskpro386_01_1988", + .type = MACHINE_TYPE_386DX, + .chipset = MACHINE_CHIPSET_DISCRETE, + .init = machine_at_deskpro386_01_1988_init, + .pad = 0, + .pad0 = 0, + .pad1 = MACHINE_AVAILABLE, + .pad2 = 0, + .cpu = { + .package = CPU_PKG_386DX, + .block = CPU_BLOCK_NONE, + .min_bus = 0, + .max_bus = 0, + .min_voltage = 0, + .max_voltage = 0, + .min_multi = 0, + .max_multi = 0 + }, + .bus_flags = MACHINE_AT, + .flags = MACHINE_IDE, + .ram = { + .min = 640, + .max = 16384, + .step = 128 + }, + .nvrmask = 63, .kbc_device = NULL, .kbc_p1 = 0, .gpio = 0, @@ -4709,7 +4746,6 @@ const machine_t machines[] = { .snd_device = NULL, .net_device = NULL }, -#endif /* defined(DEV_BRANCH) && defined(USE_DESKPRO386) */ { .name = "[ISA] Compaq Portable III (386)", .internal_name = "portableiii386", @@ -4731,7 +4767,7 @@ const machine_t machines[] = { .max_multi = 0 }, .bus_flags = MACHINE_AT, - .flags = MACHINE_IDE | MACHINE_VIDEO | MACHINE_APM, + .flags = MACHINE_IDE | MACHINE_VIDEO, .ram = { .min = 1024, .max = 14336, From cb06b9e78fc3c804bf8baa1eeeed095be18269fb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 23:38:04 +0200 Subject: [PATCH 07/44] Video features and fixes: Added the Mach8 and Mach32 ISA/VLB/PCI cards (initial implementation and MCA coming soon for the Mach32) and their corresponding EEPROM's. Added INMOS XGA ISA card and updated the SVGA core to reflect its mapping as well as the Mach8/32 mapping when in 8514 monitor mode. Mark the XGA button as already checked and locked when a standalone XGA BIOS card is present like the INMOS one. (QT only) Same concept as above, but applies to the Mach8 and 32 for the 8514 option as well. (QT only) --- src/include/86box/vid_8514a.h | 12 +- src/include/86box/vid_ati_eeprom.h | 1 + src/include/86box/vid_svga.h | 5 +- src/include/86box/vid_xga.h | 5 +- src/include/86box/vid_xga_device.h | 5 + src/include/86box/video.h | 15 +- src/qt/qt_settingsdisplay.cpp | 28 +- src/video/CMakeLists.txt | 2 +- src/video/vid_8514a.c | 594 ++- src/video/vid_ati_eeprom.c | 20 + src/video/vid_ati_mach8.c | 5568 ++++++++++++++++++++++++++++ src/video/vid_svga.c | 130 +- src/video/vid_table.c | 18 + src/video/vid_xga.c | 527 ++- src/win/Makefile.mingw | 1 + 15 files changed, 6648 insertions(+), 283 deletions(-) create mode 100644 src/video/vid_ati_mach8.c diff --git a/src/include/86box/vid_8514a.h b/src/include/86box/vid_8514a.h index e6510e3f1..b21da9fba 100644 --- a/src/include/86box/vid_8514a.h +++ b/src/include/86box/vid_8514a.h @@ -24,6 +24,8 @@ typedef struct ibm8514_t { int force_old_addr; int type; + int local; + int bpp; uint32_t vram_size; uint32_t vram_mask; @@ -32,6 +34,7 @@ typedef struct ibm8514_t { uint8_t dac_mask, dac_status; uint32_t *map8; int dac_addr, dac_pos, dac_r, dac_g; + int internal_pitch; struct { uint16_t subsys_cntl; @@ -58,7 +61,7 @@ typedef struct ibm8514_t { uint8_t pix_trans[2]; int poly_draw; int ssv_state; - int x1, x2, y1, y2; + int16_t x1, x2, x3, y1, y2; int sys_cnt, sys_cnt2; int temp_cnt; int16_t cx, cy, oldcy; @@ -80,6 +83,7 @@ typedef struct ibm8514_t { uint16_t scratch; int fill_state, xdir, ydir; + uint32_t ge_offset; } accel; uint16_t test; @@ -90,7 +94,7 @@ typedef struct ibm8514_t { dispon, hdisp_on, linecountff, vc, linepos, oddeven, cursoron, blink, scrollcache, firstline, lastline, firstline_draw, lastline_draw, - displine, fullchange, x_add, y_add; + displine, fullchange; uint32_t ma, maback; uint8_t *vram, *changedvram, linedbl; @@ -103,11 +107,13 @@ typedef struct ibm8514_t { int disp_cntl, interlace; uint8_t subsys_cntl, subsys_stat; - volatile int force_busy, force_busy2; + atomic_int force_busy, force_busy2; int blitter_busy; uint64_t blitter_time; uint64_t status_time; int pitch; + int ext_pitch; + int ext_crt_pitch; } ibm8514_t; #endif /*VIDEO_8514A_H*/ diff --git a/src/include/86box/vid_ati_eeprom.h b/src/include/86box/vid_ati_eeprom.h index 1fa083eaa..7de5170d8 100644 --- a/src/include/86box/vid_ati_eeprom.h +++ b/src/include/86box/vid_ati_eeprom.h @@ -43,6 +43,7 @@ typedef struct ati_eeprom_t { } ati_eeprom_t; void ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type); +void ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn); void ati_eeprom_write(ati_eeprom_t *eeprom, int ena, int clk, int dat); int ati_eeprom_read(ati_eeprom_t *eeprom); diff --git a/src/include/86box/vid_svga.h b/src/include/86box/vid_svga.h index 93fb9f17c..f8dafdd20 100644 --- a/src/include/86box/vid_svga.h +++ b/src/include/86box/vid_svga.h @@ -31,8 +31,9 @@ # define FLAG_NOSKEW 16 # define FLAG_ADDR_BY16 32 # define FLAG_RAMDAC_SHIFT 64 -# define FLAG_128K_MASK 128 - +# define FLAG_ATI 128 +# define FLAG_S3_911_16BIT 256 +# define FLAG_512K_MASK 512 struct monitor_t; typedef struct { diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 069718b9f..550ae7cd6 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -36,6 +36,7 @@ typedef struct xga_t { mem_mapping_t linear_mapping; mem_mapping_t video_mapping; rom_t bios_rom; + rom_t vga_bios_rom; xga_hwcursor_t hwcursor, hwcursor_latch; PALETTE extpal; @@ -57,7 +58,7 @@ typedef struct xga_t { uint8_t clk_sel_1, clk_sel_2; uint8_t hwc_control; uint8_t bus_arb; - uint8_t select_pos_isa; + uint8_t isa_pos_enable; uint8_t hwcursor_oddeven; uint8_t cfg_reg_instance; uint8_t rowcount; @@ -70,6 +71,8 @@ typedef struct xga_t { uint8_t sprite_data[1024]; uint8_t scrollcache; uint8_t direct_color; + uint8_t dma_channel; + uint8_t instance_isa, instance_num, ext_mem_addr; uint8_t *vram, *changedvram; int16_t hwc_pos_x; diff --git a/src/include/86box/vid_xga_device.h b/src/include/86box/vid_xga_device.h index a92c6d3c6..7aa274d30 100644 --- a/src/include/86box/vid_xga_device.h +++ b/src/include/86box/vid_xga_device.h @@ -17,6 +17,11 @@ #ifndef VIDEO_XGA_DEVICE_H #define VIDEO_XGA_DEVICE_H +extern int xga_has_vga; + +#ifdef EMU_DEVICE_H extern const device_t xga_device; extern const device_t xga_isa_device; +extern const device_t inmos_isa_device; +#endif #endif /*VIDEO_XGA_DEVICE_H*/ diff --git a/src/include/86box/video.h b/src/include/86box/video.h index fb7800685..b915fe35d 100644 --- a/src/include/86box/video.h +++ b/src/include/86box/video.h @@ -60,8 +60,10 @@ enum { #define VIDEO_FLAG_TYPE_CGA 0 #define VIDEO_FLAG_TYPE_MDA 1 #define VIDEO_FLAG_TYPE_SPECIAL 2 -#define VIDEO_FLAG_TYPE_NONE 3 -#define VIDEO_FLAG_TYPE_MASK 3 +#define VIDEO_FLAG_TYPE_8514 3 +#define VIDEO_FLAG_TYPE_XGA 4 +#define VIDEO_FLAG_TYPE_NONE 5 +#define VIDEO_FLAG_TYPE_MASK 7 typedef struct video_timings_t { int type; @@ -206,6 +208,7 @@ extern double cpuclock; extern int emu_fps; extern int frames; extern int readflash; +extern int ibm8514_has_vga; /* Function handler pointers. */ extern void (*video_recalctimings)(void); @@ -232,6 +235,8 @@ extern int video_card_get_flags(int card); extern int video_is_mda(void); extern int video_is_cga(void); extern int video_is_ega_vga(void); +extern int video_is_8514(void); +extern int video_is_xga(void); extern void video_inform_monitor(int type, const video_timings_t *ptr, int monitor_index); extern int video_get_type_monitor(int monitor_index); @@ -290,8 +295,12 @@ extern uint32_t video_color_transform(uint32_t color); /* IBM XGA */ extern void xga_device_add(void); -/* IBM 8514/A and generic clones*/ +/* IBM 8514/A and clones*/ extern void ibm8514_device_add(void); +extern const device_t mach8_isa_device; +extern const device_t mach32_isa_device; +extern const device_t mach32_vlb_device; +extern const device_t mach32_pci_device; /* ATi Mach64 */ extern const device_t mach64gx_isa_device; diff --git a/src/qt/qt_settingsdisplay.cpp b/src/qt/qt_settingsdisplay.cpp index e64dc74dd..5f2f81c58 100644 --- a/src/qt/qt_settingsdisplay.cpp +++ b/src/qt/qt_settingsdisplay.cpp @@ -36,7 +36,7 @@ SettingsDisplay::SettingsDisplay(QWidget *parent) { ui->setupUi(this); - videoCard[0] = gfxcard[0]; + videoCard[0] = gfxcard[0]; videoCard[1] = gfxcard[1]; onCurrentMachineChanged(machine); } @@ -102,6 +102,11 @@ SettingsDisplay::onCurrentMachineChanged(int machineId) ui->comboBoxVideoSecondary->setEnabled(true); ui->pushButtonConfigureSecondary->setEnabled(true); } + if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_8514) + ibm8514_has_vga = 0; + if (video_card_get_flags(gfxcard[0]) != VIDEO_FLAG_TYPE_XGA) + xga_has_vga = 0; + ui->comboBoxVideo->setCurrentIndex(selectedRow); if (gfxcard[1] == 0) ui->pushButtonConfigureSecondary->setEnabled(false); @@ -123,10 +128,12 @@ SettingsDisplay::on_pushButtonConfigureVoodoo_clicked() void SettingsDisplay::on_pushButtonConfigureXga_clicked() { - if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { - DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); - } else { - DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); + if (!xga_has_vga) { + if (machine_has_bus(machineId, MACHINE_BUS_MCA) > 0) { + DeviceConfig::ConfigureDevice(&xga_device, 0, qobject_cast(Settings::settings)); + } else { + DeviceConfig::ConfigureDevice(&xga_isa_device, 0, qobject_cast(Settings::settings)); + } } } @@ -139,7 +146,6 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) auto curVideoCard_2 = videoCard[1]; videoCard[0] = ui->comboBoxVideo->currentData().toInt(); ui->pushButtonConfigure->setEnabled(video_card_has_config(videoCard[0]) > 0); - bool machineHasPci = machine_has_bus(machineId, MACHINE_BUS_PCI) > 0; ui->checkBoxVoodoo->setEnabled(machineHasPci); if (machineHasPci) { @@ -149,16 +155,16 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) bool hasIsa16 = machine_has_bus(machineId, MACHINE_BUS_ISA16) > 0; bool has_MCA = machine_has_bus(machineId, MACHINE_BUS_MCA) > 0; - ui->checkBox8514->setEnabled(hasIsa16 || has_MCA); + ui->checkBox8514->setEnabled((hasIsa16 || has_MCA) && !ibm8514_has_vga); if (hasIsa16 || has_MCA) { ui->checkBox8514->setChecked(ibm8514_enabled); } - ui->checkBoxXga->setEnabled(hasIsa16 || has_MCA); + ui->checkBoxXga->setEnabled((hasIsa16 || has_MCA) && !xga_has_vga); if (hasIsa16 || has_MCA) ui->checkBoxXga->setChecked(xga_enabled); - ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked()); + ui->pushButtonConfigureXga->setEnabled((hasIsa16 || has_MCA) && ui->checkBoxXga->isChecked() && !xga_has_vga); int c = 2; @@ -187,7 +193,7 @@ SettingsDisplay::on_comboBoxVideo_currentIndexChanged(int index) c++; } - if (videoCard[1] == 0 || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { + if ((videoCard[1] == 0) || (machine_has_flags(machineId, MACHINE_VIDEO_ONLY) > 0)) { ui->comboBoxVideoSecondary->setCurrentIndex(0); ui->pushButtonConfigureSecondary->setEnabled(false); } @@ -202,7 +208,7 @@ SettingsDisplay::on_checkBoxVoodoo_stateChanged(int state) void SettingsDisplay::on_checkBoxXga_stateChanged(int state) { - ui->pushButtonConfigureXga->setEnabled(state == Qt::Checked); + ui->pushButtonConfigureXga->setEnabled((state == Qt::Checked) && !xga_has_vga); } void diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt index b37e81134..3d3d2d466 100644 --- a/src/video/CMakeLists.txt +++ b/src/video/CMakeLists.txt @@ -18,7 +18,7 @@ add_library(vid OBJECT agpgart.c video.c vid_table.c vid_cga.c vid_cga_comp.c vid_incolor.c vid_colorplus.c vid_genius.c vid_pgc.c vid_im1024.c vid_sigma.c vid_wy700.c vid_ega.c vid_ega_render.c vid_svga.c vid_8514a.c vid_svga_render.c vid_ddc.c vid_vga.c vid_ati_eeprom.c vid_ati18800.c - vid_ati28800.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c + vid_ati28800.c vid_ati_mach8.c vid_ati_mach64.c vid_ati68860_ramdac.c vid_bt48x_ramdac.c vid_av9194.c vid_icd2061.c vid_ics2494.c vid_ics2595.c vid_cl54xx.c vid_et3000.c vid_et4000.c vid_sc1148x_ramdac.c vid_sc1502x_ramdac.c vid_et4000w32.c vid_stg_ramdac.c vid_ht216.c vid_oak_oti.c vid_paradise.c diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 9ec196d86..115105d7a 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -7,13 +7,13 @@ * This file is part of the 86Box distribution. * * Emulation of the 8514/A card from IBM for the MCA bus and - * generic ISA bus clones without vendor extensions. + * ISA bus clones. * * * * Authors: TheCollector1995. * - * Copyright 2022 TheCollector1995. + * Copyright 2022-2023 TheCollector1995. */ #include #include @@ -21,6 +21,7 @@ #include #include #include +#include #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/device.h> @@ -42,17 +43,53 @@ static void ibm8514_accel_outw(uint16_t port, uint16_t val, void *p); static uint8_t ibm8514_accel_inb(uint16_t port, void *p); static uint16_t ibm8514_accel_inw(uint16_t port, void *p); +#ifdef ENABLE_IBM8514_LOG +int ibm8514_do_log = ENABLE_IBM8514_LOG; + +static void +ibm8514_log(const char *fmt, ...) +{ + va_list ap; + + if (ibm8514_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define ibm8514_log(fmt, ...) +#endif + #define READ_PIXTRANS_WORD(cx, n) \ if ((cmd <= 1) || (cmd == 5)) { \ - temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + if (dev->local) { \ + temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \ + temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ + } else { \ + temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ } else { \ - temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ - temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + if (dev->local) { \ + temp = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \ + temp |= (svga->vram[(dev->accel.dest + (cx) + (n + 1)) & svga->vram_mask] << 8); \ + } else { \ + temp = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[(dev->accel.dest + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ } #define READ(addr, dat) \ - dat = dev->vram[(addr) & (dev->vram_mask)]; + if (dev->local) { \ + if ((svga->bpp == 15) || (svga->bpp == 16)) { \ + dat = vram_w[(addr) & (svga->vram_mask >> 1)]; \ + } else { \ + dat = (svga->vram[(addr) & (svga->vram_mask)]); \ + } \ + } else { \ + dat = (dev->vram[(addr) & (dev->vram_mask)]); \ + } #define MIX(mixmode, dest_dat, src_dat) \ { \ @@ -157,8 +194,20 @@ static uint16_t ibm8514_accel_inw(uint16_t port, void *p); } #define WRITE(addr, dat) \ - dev->vram[((addr)) & (dev->vram_mask)] = dat; \ - dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; + if (dev->local) { \ + if ((svga->bpp == 15) || (svga->bpp == 16)) { \ + vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \ + svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \ + } else { \ + svga->vram[((addr)) & (svga->vram_mask)] = dat; \ + svga->changedvram[(((addr)) & (svga->vram_mask)) >> 12] = changeframecount; \ + } \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } + +int ibm8514_has_vga = 0; int ibm8514_cpu_src(svga_t *svga) @@ -557,10 +606,11 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.short_stroke = val; dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); @@ -573,15 +623,16 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) break; case 0x9ee9: case 0xdee9: + dev->accel.ssv_state = 1; if (len == 1) { dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; if (dev->accel.cmd & 0x1000) { ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); @@ -701,10 +752,14 @@ ibm8514_accel_out_fifo(svga_t *svga, uint16_t port, uint32_t val, int len) dev->accel.multifunc_cntl = val; dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; if ((dev->accel.multifunc_cntl >> 12) == 1) { - dev->accel.clip_top = val & 0x3ff; + dev->accel.clip_top = val & 0x7ff; + if (val & 0x400) + dev->accel.clip_top |= ~0x3ff; } if ((dev->accel.multifunc_cntl >> 12) == 2) { - dev->accel.clip_left = val & 0x3ff; + dev->accel.clip_left = val & 0x7ff; + if (val & 0x400) + dev->accel.clip_left |= ~0x3ff; } if (port == 0xfee8) dev->accel.cmd_back = 1; @@ -820,24 +875,24 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x2e9: if (len != 1) { dev->htotal = (dev->htotal & 0xff) | (val << 8); - // pclog("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); + ibm8514_log("IBM 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); svga_recalctimings(svga); } break; case 0x6e8: dev->hdisp = val; - // pclog("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + ibm8514_log("IBM 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); svga_recalctimings(svga); break; case 0xae8: - // pclog("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + ibm8514_log("IBM 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); svga_recalctimings(svga); break; case 0xee8: - // pclog("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + ibm8514_log("IBM 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); svga_recalctimings(svga); break; @@ -852,7 +907,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x12e9: if (len == 1) { dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8); - // pclog("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); + ibm8514_log("IBM 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); svga_recalctimings(svga); } break; @@ -868,7 +923,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x16e9: if (len == 1) { dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8); - // pclog("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + ibm8514_log("IBM 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); svga_recalctimings(svga); } break; @@ -884,21 +939,21 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) case 0x1ae9: if (len == 1) { dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8); - // pclog("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); + ibm8514_log("IBM 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); svga_recalctimings(svga); } break; case 0x1ee8: dev->vsyncwidth = val; - // pclog("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + ibm8514_log("IBM 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); svga_recalctimings(svga); break; case 0x22e8: dev->disp_cntl = val & 0x7e; dev->interlace = !!(val & 0x10); - // pclog("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); + ibm8514_log("IBM 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); svga_recalctimings(svga); break; @@ -922,7 +977,7 @@ ibm8514_accel_out(uint16_t port, uint32_t val, svga_t *svga, int len) dev->accel.advfunc_cntl = val & 7; ibm8514_on = (dev->accel.advfunc_cntl & 1); vga_on = !ibm8514_on; - //pclog("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); + ibm8514_log("IBM 8514/A: VGA ON = %i, val = %02x\n", vga_on, val); svga_recalctimings(svga); break; } @@ -1105,26 +1160,33 @@ void ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, svga_t *svga, int len) { ibm8514_t *dev = &svga->dev8514; - uint8_t src_dat = 0; - uint8_t dest_dat; - uint8_t old_dest_dat; - int frgd_mix; - int bkgd_mix; - uint16_t clip_b = dev->accel.multifunc[3] & 0x7ff; - uint16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + uint16_t *vram_w = (uint16_t *)svga->vram; + uint16_t src_dat = 0, dest_dat, old_dest_dat; + int frgd_mix, bkgd_mix; + uint16_t clip_b = dev->accel.multifunc[3]; + uint16_t clip_r = dev->accel.multifunc[4]; int pixcntl = (dev->accel.multifunc[0x0a] >> 6) & 3; - uint8_t mix_mask = 0x80; - uint8_t compare = dev->accel.color_cmp & 0xff; + uint16_t mix_mask = ((svga->bpp == 8) || (svga->bpp == 24)) ? 0x80 : 0x8000; + uint16_t compare = dev->accel.color_cmp; int compare_mode = dev->accel.multifunc[0x0a] & 0x38; int cmd = dev->accel.cmd >> 13; - uint8_t wrt_mask = dev->accel.wrt_mask & 0xff; - uint8_t rd_mask = ((dev->accel.rd_mask & 0x01) << 7) | ((dev->accel.rd_mask & 0xfe) >> 1); - uint8_t rd_mask_polygon = dev->accel.rd_mask & 0xff; - uint8_t frgd_color = dev->accel.frgd_color; - uint8_t bkgd_color = dev->accel.bkgd_color; + uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t rd_mask = dev->accel.rd_mask; + uint16_t rd_mask_polygon = dev->accel.rd_mask; + uint16_t frgd_color = dev->accel.frgd_color; + uint16_t bkgd_color = dev->accel.bkgd_color; uint32_t old_mix_dat; int and3 = dev->accel.cur_x & 3; - uint8_t poly_src = 0; + uint16_t poly_src = 0; + + if ((svga->bpp == 8) || (svga->bpp == 24)) { + compare &= 0xff; + frgd_color &= 0xff; + bkgd_color &= 0xff; + rd_mask = ((dev->accel.rd_mask & 0x01) << 7) | ((dev->accel.rd_mask & 0xfe) >> 1); + rd_mask &= 0xff; + rd_mask_polygon &= 0xff; + } if (dev->accel.cmd & 0x100) { dev->force_busy = 1; @@ -1147,6 +1209,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat } else { count >>= 3; } + + if (((svga->bpp == 15) || (svga->bpp == 16))) { + if ((dev->accel.cmd & 0x200) && (count == 2)) + count >>= 1; + } } if (pixcntl == 1) { @@ -1246,7 +1313,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -1255,17 +1322,26 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); if (dev->accel.ssv_draw) { - WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + if ((dev->accel.cmd & 4) && dev->accel.ssv_len) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } } } } mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (!dev->accel.ssv_len) break; @@ -1303,10 +1379,116 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.ssv_len--; } + } else { + while (count-- && (dev->accel.ssv_len >= 0)) { + if ((dev->accel.cx >= dev->accel.clip_left && dev->accel.cx <= clip_r && dev->accel.cy >= dev->accel.clip_top && dev->accel.cy <= clip_b)) { + switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { + case 0: + src_dat = bkgd_color; + break; + case 1: + src_dat = frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + src_dat = 0; + break; + } - dev->accel.cur_x = dev->accel.cx; - dev->accel.cur_y = dev->accel.cy; + READ((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + + if ((compare_mode == 0) || ((compare_mode == 0x10) && (dest_dat >= compare)) || ((compare_mode == 0x18) && (dest_dat < compare)) || ((compare_mode == 0x20) && (dest_dat != compare)) || ((compare_mode == 0x28) && (dest_dat == compare)) || ((compare_mode == 0x30) && (dest_dat <= compare)) || ((compare_mode == 0x38) && (dest_dat > compare))) { + old_dest_dat = dest_dat; + MIX(mix_dat & mix_mask, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + + if (dev->accel.ssv_draw) { + if ((dev->accel.cmd & 4) && dev->accel.ssv_len) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } else if (!(dev->accel.cmd & 4)) { + WRITE((dev->accel.cy * dev->pitch) + dev->accel.cx, dest_dat); + } + } + } + } + + mix_dat <<= 1; + mix_dat |= 1; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; + + if (!dev->accel.ssv_len) + break; + + if (dev->accel.err_term >= dev->accel.maj_axis_pcnt) { + dev->accel.err_term += dev->accel.destx_distp; + /*Step minor axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cy--; + break; + case 0x20: + dev->accel.cy--; + break; + case 0x40: + dev->accel.cx--; + break; + case 0x60: + dev->accel.cx++; + break; + case 0x80: + dev->accel.cy++; + break; + case 0xa0: + dev->accel.cy++; + break; + case 0xc0: + dev->accel.cx--; + break; + case 0xe0: + dev->accel.cx++; + break; + } + } else + dev->accel.err_term += dev->accel.desty_axstp; + + /*Step major axis*/ + switch (dev->accel.cmd & 0xe0) { + case 0x00: + dev->accel.cx--; + break; + case 0x20: + dev->accel.cx++; + break; + case 0x40: + dev->accel.cy--; + break; + case 0x60: + dev->accel.cy--; + break; + case 0x80: + dev->accel.cx--; + break; + case 0xa0: + dev->accel.cx++; + break; + case 0xc0: + dev->accel.cy++; + break; + case 0xe0: + dev->accel.cy++; + break; + } + + dev->accel.ssv_len--; + } } + dev->accel.cur_x = dev->accel.cx; + dev->accel.cur_y = dev->accel.cy; break; case 1: /*Draw line*/ @@ -1315,11 +1497,11 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) { - dev->accel.cx |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) { + dev->accel.cx |= ~0x5ff; } - if (dev->accel.cur_y & 0x400) { - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_y >= 0x600) { + dev->accel.cy |= ~0x5ff; } dev->accel.sy = dev->accel.maj_axis_pcnt; @@ -1392,7 +1574,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -1477,7 +1659,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.sy == 0) { break; @@ -1538,7 +1723,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -1561,7 +1746,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.temp_cnt--; mix_dat >>= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.sy == 0) { break; @@ -1654,7 +1842,7 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -1677,7 +1865,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.sy == 0) { break; @@ -1767,14 +1958,18 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.fill_state = 0; if (cmd == 4) @@ -1822,7 +2017,10 @@ ibm8514_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat if (!(dev->accel.cmd & 0x40) && (frgd_mix == 2) && (bkgd_mix == 2) && (pixcntl == 0) && (cmd == 2)) { if (!(dev->accel.sx & 1)) { dev->accel.output = 1; - dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; + if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + dev->accel.newdest_out = (dev->accel.ge_offset << 2) + ((dev->accel.cy + 1) * dev->pitch); + else + dev->accel.newdest_out = (dev->accel.cy + 1) * dev->pitch; } } } @@ -1864,7 +2062,7 @@ rect_fill_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -1939,7 +2137,10 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; switch (dev->accel.cmd & 0xe0) { case 0x00: @@ -2033,7 +2234,7 @@ rect_fill_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -2052,7 +2253,10 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2077,7 +2281,11 @@ rect_fill_pix: else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2107,7 +2315,7 @@ rect_fill_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -2125,7 +2333,10 @@ rect_fill_pix: } } mix_dat >>= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2148,9 +2359,9 @@ rect_fill_pix: if (dev->accel.cmd & 2) { if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; } } @@ -2159,7 +2370,11 @@ rect_fill_pix: else dev->accel.cy--; - dev->accel.dest = dev->accel.cy * dev->pitch; + if (dev->local && dev->accel.ge_offset && (svga->bpp == 24)) + dev->accel.dest = (dev->accel.ge_offset << 2) + (dev->accel.cy * dev->pitch); + else + dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.sy--; return; } @@ -2262,7 +2477,10 @@ rect_fill_pix: } mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2333,7 +2551,7 @@ rect_fill_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -2358,7 +2576,10 @@ rect_fill_pix: mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) dev->accel.cx++; @@ -2671,8 +2892,12 @@ rect_fill: if (!cpu_input) { dev->accel.cx = dev->accel.cur_x; dev->accel.cy = dev->accel.cur_y; - dev->accel.oldcy = dev->accel.cy; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; + dev->accel.oldcy = dev->accel.cy; dev->accel.sy = 0; if (ibm8514_cpu_src(svga)) { @@ -2687,9 +2912,6 @@ rect_fill: } while (count-- && (dev->accel.sy >= 0)) { - if (dev->accel.cur_x > 1023) - dev->accel.cx = 0; - if ((dev->accel.cx) >= dev->accel.clip_left && ((dev->accel.cx) <= clip_r) && (dev->accel.cy) >= dev->accel.clip_top && (dev->accel.cy) <= clip_b) { switch ((mix_dat & mix_mask) ? frgd_mix : bkgd_mix) { case 0: @@ -2699,7 +2921,7 @@ rect_fill: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: src_dat = 0; @@ -2726,7 +2948,10 @@ rect_fill: mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.sy == dev->accel.maj_axis_pcnt) { break; @@ -2813,21 +3038,21 @@ rect_fill: dev->accel.sx = dev->accel.maj_axis_pcnt & 0x7ff; dev->accel.sy = dev->accel.multifunc[0] & 0x7ff; - dev->accel.dx = dev->accel.destx_distp & 0x3ff; - dev->accel.dy = dev->accel.desty_axstp & 0x3ff; + dev->accel.dx = dev->accel.destx_distp; + dev->accel.dy = dev->accel.desty_axstp; - if (dev->accel.destx_distp & 0x400) - dev->accel.dx |= ~0x3ff; - if (dev->accel.desty_axstp & 0x400) - dev->accel.dy |= ~0x3ff; + if (dev->accel.destx_distp >= 0x600) + dev->accel.dx |= ~0x5ff; + if (dev->accel.desty_axstp >= 0x600) + dev->accel.dy |= ~0x5ff; - dev->accel.cx = dev->accel.cur_x & 0x3ff; - dev->accel.cy = dev->accel.cur_y & 0x3ff; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - if (dev->accel.cur_y & 0x400) - dev->accel.cy |= ~0x3ff; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + if (dev->accel.cur_y >= 0x600) + dev->accel.cy |= ~0x5ff; dev->accel.src = dev->accel.cy * dev->pitch; dev->accel.dest = dev->accel.dy * dev->pitch; @@ -2876,7 +3101,7 @@ bitblt_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: READ(dev->accel.src + dev->accel.cx, src_dat); @@ -2900,12 +3125,18 @@ bitblt_pix: mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; - - if (dev->accel.cmd & 0x20) - dev->accel.cx++; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; else + cpu_dat >>= 8; + + if (dev->accel.cmd & 0x20) { + dev->accel.dx++; + dev->accel.cx++; + } else { + dev->accel.dx--; dev->accel.cx--; + } dev->accel.sx--; if (dev->accel.sx < 0) { @@ -2916,16 +3147,23 @@ bitblt_pix: } if (dev->accel.cmd & 0x20) { + dev->accel.dx -= (dev->accel.sx) + 1; dev->accel.cx -= (dev->accel.sx) + 1; - } else + } else { + dev->accel.dx += (dev->accel.sx) + 1; dev->accel.cx += (dev->accel.sx) + 1; + } - if (dev->accel.cmd & 0x80) + if (dev->accel.cmd & 0x80) { + dev->accel.dy++; dev->accel.cy++; - else + } else { + dev->accel.dy--; dev->accel.cy--; + } - dev->accel.dest = dev->accel.cy * dev->pitch; + dev->accel.src = dev->accel.cy * dev->pitch; + dev->accel.dest = dev->accel.dy * dev->pitch; dev->accel.sy--; return; } @@ -2952,7 +3190,7 @@ bitblt_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: READ(dev->accel.src + dev->accel.cx, src_dat); @@ -2974,7 +3212,10 @@ bitblt_pix: } } mix_dat >>= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) { dev->accel.dx++; @@ -3003,12 +3244,12 @@ bitblt_pix: if (dev->accel.cmd & 2) { if (dev->accel.cmd & 0x1000) { - dev->accel.cx = dev->accel.cur_x & 0x3ff; - if (dev->accel.cur_x & 0x400) - dev->accel.cx |= ~0x3ff; - dev->accel.dx = dev->accel.destx_distp & 0x3ff; - if (dev->accel.destx_distp & 0x400) - dev->accel.dx |= ~0x3ff; + dev->accel.cx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.dx = dev->accel.destx_distp; + if (dev->accel.destx_distp >= 0x600) + dev->accel.dx |= ~0x5ff; } } @@ -3056,7 +3297,7 @@ bitblt_pix: src_dat = frgd_color; break; case 2: - src_dat = cpu_dat & 0xff; + src_dat = cpu_dat; break; case 3: READ(dev->accel.src + dev->accel.cx, src_dat); @@ -3079,7 +3320,10 @@ bitblt_pix: } mix_dat <<= 1; mix_dat |= 1; - cpu_dat >>= 8; + if ((svga->bpp == 15) || (svga->bpp == 16)) + cpu_dat >>= 16; + else + cpu_dat >>= 8; if (dev->accel.cmd & 0x20) { dev->accel.dx++; @@ -3123,7 +3367,7 @@ bitblt: count = dev->accel.maj_axis_pcnt + 1; dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { mix_dat >>= 8; dev->accel.temp_cnt = 8; } @@ -3197,7 +3441,7 @@ bitblt: } else { dev->accel.temp_cnt = 8; while (count-- && dev->accel.sy >= 0) { - if (dev->accel.temp_cnt == 0) { + if (!dev->accel.temp_cnt) { dev->accel.temp_cnt = 8; mix_dat = old_mix_dat; } @@ -3269,6 +3513,32 @@ bitblt: } } } else { + if ((svga->bpp == 24) && dev->local && (dev->accel.cmd == 0xc2b5)) { + int64_t x, cx, dx; + + cx = (int64_t)dev->accel.cx; + dx = (int64_t)dev->accel.dx; + + while (1) { + if (((dx) >= (((int64_t)dev->accel.clip_left) * 3) && (dx) <= (((uint64_t)clip_r) * 3) && dev->accel.dy >= (dev->accel.clip_top << 1) && dev->accel.dy <= (clip_b << 1))) { + READ(dev->accel.src + (dev->accel.ge_offset << 2) + cx, src_dat); + READ(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); + + dest_dat = (src_dat & wrt_mask) | (dest_dat & ~wrt_mask); + + WRITE(dev->accel.dest + (dev->accel.ge_offset << 2) + dx, dest_dat); + } + + cx++; + dx++; + + dev->accel.sx--; + if (dev->accel.sx < 0) + return; + } + return; + } + while (count-- && dev->accel.sy >= 0) { if (dev->accel.dx >= dev->accel.clip_left && dev->accel.dx <= clip_r && dev->accel.dy >= dev->accel.clip_top && dev->accel.dy <= clip_b) { if (pixcntl == 3) { @@ -3309,7 +3579,13 @@ bitblt: MIX(mix_dat & mix_mask, dest_dat, src_dat); dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); - WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + if (dev->accel.cmd & 4) { + if (dev->accel.sx > 0) { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat); + } } } mix_dat <<= 1; @@ -3547,7 +3823,7 @@ ibm8514_recalctimings(svga_t *svga) if (ibm8514_on) { dev->h_disp = (dev->hdisp + 1) << 3; - dev->pitch = dev->h_disp; + dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; dev->h_total = (dev->htotal + 1); dev->v_total = (dev->vtotal + 1); dev->v_syncstart = (dev->vsyncstart + 1); @@ -3555,46 +3831,9 @@ ibm8514_recalctimings(svga_t *svga) dev->dispend = ((dev->vdisp >> 1) + 1); if (dev->dispend == 766) dev->dispend = 768; - //pclog("HDISP = %d, VTOTAL = %d, DISPEND = %d, hires = %02x\n", dev->h_disp, dev->v_total, dev->dispend, dev->accel.advfunc_cntl & 4); - { -#if 0 - if (dev->dispend == 480) { - dev->h_disp = 640; - dev->rowoffset = 128; - dev->pitch = 1024; - } else if ((dev->dispend == 600) || (dev->dispend == 598)) { - dev->h_disp = 800; - dev->rowoffset = 128; - dev->dispend = 600; - dev->pitch = 1024; - if (!dev->vtotal) - dev->v_total = 816; - if (!dev->vsyncstart) - dev->v_syncstart = dev->dispend; - } else { - if (dev->accel.advfunc_cntl & 4) { - if (!dev->hdisp) { - dev->rowoffset = 128; - dev->h_disp = 1024; - dev->pitch = dev->h_disp; - } - if (!dev->vtotal) - dev->v_total = 816; - if (!dev->vsyncstart) - dev->v_syncstart = dev->dispend; - } else { - dev->rowoffset = 128; - dev->h_disp = 640; - dev->dispend = 480; - dev->pitch = 1024; - if (!dev->vtotal) - dev->v_total = 816; - if (!dev->vsyncstart) - dev->v_syncstart = dev->dispend; - } - } -#endif - } + + if (dev->dispend == 598) + dev->dispend = 600; if (dev->accel.advfunc_cntl & 4) { if (!vga_on && dev->ibm_mode) { @@ -3617,15 +3856,21 @@ ibm8514_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } - dev->rowoffset = 0x80; - dev->pitch = 1024; - // pclog("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); + if (ibm8514_has_vga) { + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + } else + dev->rowoffset = 128; + + ibm8514_log("1024x768 clock mode, hdisp = %d, htotal = %d, vtotal = %d, vsyncstart = %d, interlace = %02x\n", dev->h_disp, dev->h_total, dev->v_total, dev->v_syncstart, dev->interlace); svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; } else { if (!vga_on && dev->ibm_mode) { - dev->h_disp = 640; - dev->dispend = 480; + if (dev->h_disp == 1024) { + dev->h_disp = 640; + dev->dispend = 480; + } } if (dev->interlace) { @@ -3636,15 +3881,19 @@ ibm8514_recalctimings(svga_t *svga) dev->v_syncstart >>= 1; dev->v_total >>= 1; } - dev->rowoffset = 0x80; - dev->pitch = 1024; + + if (ibm8514_has_vga) { + dev->pitch = dev->ext_pitch; + dev->rowoffset = dev->ext_crt_pitch; + } else + dev->rowoffset = 128; svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; } svga->render = ibm8514_render_8bpp; - //pclog("Pitch = %d, mode = %d.\n", dev->pitch, dev->ibm_mode); + ibm8514_log("BPP=%d, Pitch = %d, rowoffset = %d, crtc13 = %02x, mode = %d, highres bit = %02x, has_vga? = %d.\n", dev->bpp, dev->pitch, dev->rowoffset, svga->crtc[0x13], dev->ibm_mode, dev->accel.advfunc_cntl & 4, ibm8514_has_vga); } - // pclog("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); + ibm8514_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", dev->hdisp, dev->vtotal, dev->htotal, dev->dispend, dev->rowoffset, dev->split, dev->vsyncstart, dev->split); } static uint8_t @@ -3697,6 +3946,7 @@ static void dev->type = info->flags; dev->ibm_mode = 1; + dev->bpp = 8; ibm8514_io_set(svga); @@ -3770,7 +4020,7 @@ const device_t ibm8514_mca_device = { void ibm8514_device_add(void) { - if (!ibm8514_enabled) + if (!ibm8514_enabled || (ibm8514_enabled && ibm8514_has_vga)) return; if (machine_has_bus(machine, MACHINE_BUS_MCA)) diff --git a/src/video/vid_ati_eeprom.c b/src/video/vid_ati_eeprom.c index 2e10216e4..10b37212d 100644 --- a/src/video/vid_ati_eeprom.c +++ b/src/video/vid_ati_eeprom.c @@ -45,6 +45,26 @@ ati_eeprom_load(ati_eeprom_t *eeprom, char *fn, int type) fclose(f); } +void +ati_eeprom_load_mach8(ati_eeprom_t *eeprom, char *fn) +{ + FILE *f; + int size; + eeprom->type = 0; + strncpy(eeprom->fn, fn, sizeof(eeprom->fn) - 1); + f = nvr_fopen(eeprom->fn, "rb"); + size = 128; + if (!f) { /*The ATI Graphics Ultra bios expects an immediate write to nvram if none is present at boot time otherwise + it would hang the machine.*/ + memset(eeprom->data, 0, size); + f = nvr_fopen(eeprom->fn, "wb"); + fwrite(eeprom->data, 1, size, f); + } + if (fread(eeprom->data, 1, size, f) != size) + memset(eeprom->data, 0, size); + fclose(f); +} + void ati_eeprom_save(ati_eeprom_t *eeprom) { diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c new file mode 100644 index 000000000..c8996e0eb --- /dev/null +++ b/src/video/vid_ati_mach8.c @@ -0,0 +1,5568 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Emulation of the 8514/A-compatible Mach8 and Mach32 graphics + * chips from ATI for the ISA/VLB/MCA/PCI buses. + * + * + * + * Authors: TheCollector1995. + * + * Copyright 2022-2023 TheCollector1995. + */ +#include +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H +#include <86box/86box.h> +#include <86box/device.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/timer.h> +#include <86box/mca.h> +#include <86box/pci.h> +#include <86box/rom.h> +#include <86box/plat.h> +#include <86box/thread.h> +#include <86box/video.h> +#include <86box/i2c.h> +#include <86box/vid_ddc.h> +#include <86box/vid_svga.h> +#include <86box/vid_svga_render.h> +#include <86box/vid_ati_eeprom.h> + +#define BIOS_MACH8_ROM_PATH "roms/video/mach8/BIOS.BIN" +#define BIOS_MACH32_ISA_ROM_PATH "roms/video/mach32/MACH32ISA.VBI" +#define BIOS_MACH32_VLB_ROM_PATH "roms/video/mach32/MACH32VLB.VBI" +#define BIOS_MACH32_PCI_ROM_PATH "roms/video/mach32/MACH32PCI.BIN" + +typedef struct mach_t { + ati_eeprom_t eeprom; + svga_t svga; + + rom_t bios_rom; + mem_mapping_t mmio_linear_mapping; + + int mca_bus; + int pci_bus; + int vlb_bus; + uint8_t regs[256]; + uint8_t pci_regs[256]; + uint8_t int_line; + int card; + int index; + + uint32_t memory; + + uint16_t config1; + uint16_t config2; + + uint8_t pos_regs[8]; + uint8_t cursor_col_0, cursor_col_1; + uint8_t ext_cur_col_0_r, ext_cur_col_1_r; + uint8_t ext_cur_col_0_g, ext_cur_col_1_g; + uint16_t cursor_offset_lo, cursor_offset_hi; + uint16_t cursor_x, cursor_y; + uint16_t misc; + uint16_t memory_aperture; + uint16_t local_cntl; + uint32_t linear_base; + uint8_t ap_size; + uint8_t bank_w, bank_r; + + struct { + uint8_t line_idx; + int16_t line_array[6]; + uint8_t patt_idx; + uint8_t patt_len; + uint8_t pix_trans[2]; + uint8_t eeprom_control; + uint16_t dest_x_end; + uint16_t dest_x_start; + uint16_t dest_y_end; + uint16_t src_x_end; + uint16_t src_x_start; + uint16_t src_x, src_y; + int16_t bres_count; + uint16_t clock_sel; + uint16_t crt_offset_lo; + uint16_t crt_offset_hi; + uint16_t dest_cmp_fn; + uint16_t dp_config; + uint16_t ext_ge_config; + uint16_t ge_offset_lo; + uint16_t ge_offset_hi; + uint16_t linedraw_opt; + uint16_t max_waitstates; + uint8_t patt_data_idx; + uint8_t patt_data[0x18]; + uint16_t scan_to_x; + uint16_t scratch0; + uint16_t scratch1; + uint16_t test; + uint16_t pattern; + uint8_t test2[2], test3[2]; + int src_y_dir; + int cmd_type; + int block_write_mono_pattern_enable; + int mono_pattern_enable; + int16_t cx_end_line, cy_end_line; + int16_t cx, cx_end, cy_end, dx, dx_end, dy_end; + int16_t dx_start, dy_start; + int16_t cy, sx_start, sx_end; + int16_t sx, x_count, xx_count, xxx_count; + int16_t sy, y_count; + int16_t err; + int16_t width, src_width; + int16_t height; + int poly_src, temp_cnt; + int stepx, stepy, src_stepx; + uint8_t color_pattern[16]; + uint8_t color_pattern_full[32]; + uint16_t color_pattern_word[8]; + int mono_pattern[8][8]; + uint32_t ge_offset; + uint32_t crt_offset; + uint32_t patt_len_reg; + int poly_fill; + uint16_t dst_clr_cmp_mask; + int clip_overrun; + int color_pattern_idx; + } accel; + + atomic_int force_busy, force_busy2; +} mach_t; + +static video_timings_t timing_gfxultra_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; +static video_timings_t timing_mach32_vlb = { .type = VIDEO_BUS, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; +static video_timings_t timing_mach32_pci = { .type = VIDEO_PCI, .write_b = 2, .write_w = 2, .write_l = 1, .read_b = 20, .read_w = 20, .read_l = 21 }; + + +static void mach_accel_outb(uint16_t port, uint8_t val, void *p); +static void mach_accel_outw(uint16_t port, uint16_t val, void *p); +static uint8_t mach_accel_inb(uint16_t port, void *p); +static uint16_t mach_accel_inw(uint16_t port, void *p); + +static void mach32_updatemapping(mach_t *mach); + +#ifdef ENABLE_MACH_LOG +int mach_do_log = ENABLE_MACH_LOG; + +static void +mach_log(const char *fmt, ...) +{ + va_list ap; + + if (mach_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define mach_log(fmt, ...) +#endif + +#define READ_PIXTRANS_BYTE_IO(cx, n, vgacore) \ + if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ + if (vgacore) { \ + if ((svga->bpp == 15) || (svga->bpp == 16)) \ + if (n == 0) \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (svga->vram_mask >> 1)] & 0xff; \ + else \ + mach->accel.pix_trans[(n)] = vram_w[(dev->accel.dest + (cx) + (n)) & (svga->vram_mask >> 1)] >> 8; \ + else \ + mach->accel.pix_trans[(n)] = svga->vram[(dev->accel.dest + (cx) + (n)) & svga->vram_mask]; \ + } else \ + mach->accel.pix_trans[(n)] = dev->vram[(dev->accel.dest + (cx) + (n)) & dev->vram_mask]; \ + } + +#define READ_PIXTRANS_WORD(cx, n, vgacore) \ + if ((cmd == 0) || (cmd == 1) || (cmd == 5) || (mach->accel.cmd_type == -1)) { \ + if (vgacore) { \ + if ((svga->bpp == 15) || (svga->bpp == 16)) { \ + temp = vram_w[((dev->accel.cy * dev->pitch) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + } else { \ + temp = svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & svga->vram_mask]; \ + temp |= (svga->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ + } \ + } else { \ + temp = dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.cy * dev->pitch) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((mach->accel.cmd_type == 2) || (mach->accel.cmd_type == 5)) { \ + if ((svga->bpp == 8) || (svga->bpp == 24)) { \ + if (vgacore) { \ + temp = svga->vram[((dev->accel.dest) + (cx) + (n)) & svga->vram_mask]; \ + temp |= (svga->vram[((dev->accel.dest) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ + } else { \ + temp = dev->vram[((dev->accel.dest) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((dev->accel.dest) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ + temp = vram_w[((dev->accel.dest) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + } \ + } else if ((mach->accel.cmd_type == 3) || (mach->accel.cmd_type == 4)) { \ + if ((svga->bpp == 8) || (svga->bpp == 24)) { \ + if (vgacore) { \ + temp = svga->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & svga->vram_mask]; \ + temp |= (svga->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & svga->vram_mask] << 8); \ + } else { \ + temp = dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & dev->vram_mask]; \ + temp |= (dev->vram[((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n + 1)) & dev->vram_mask] << 8); \ + } \ + } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ + temp = vram_w[((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (cx) + (n)) & (svga->vram_mask >> 1)]; \ + } \ + } + +#define READ(addr, dat, vgacore) \ + if ((svga->bpp == 8) || (svga->bpp == 24)) \ + dat = vgacore ? (svga->vram[(addr) & (svga->vram_mask)]) : (dev->vram[(addr) & (dev->vram_mask)]); \ + else if ((svga->bpp == 15) || (svga->bpp == 16)) \ + dat = vram_w[(addr) & (svga->vram_mask >> 1)]; + +#define MIX(mixmode, dest_dat, src_dat) \ + { \ + switch ((mixmode) ? (dev->accel.frgd_mix & 0x1f) : (dev->accel.bkgd_mix & 0x1f)) { \ + case 0x00: \ + dest_dat = ~dest_dat; \ + break; \ + case 0x01: \ + dest_dat = 0; \ + break; \ + case 0x02: \ + dest_dat = ~0; \ + break; \ + case 0x03: \ + dest_dat = dest_dat; \ + break; \ + case 0x04: \ + dest_dat = ~src_dat; \ + break; \ + case 0x05: \ + dest_dat = src_dat ^ dest_dat; \ + break; \ + case 0x06: \ + dest_dat = ~(src_dat ^ dest_dat); \ + break; \ + case 0x07: \ + dest_dat = src_dat; \ + break; \ + case 0x08: \ + dest_dat = ~(src_dat & dest_dat); \ + break; \ + case 0x09: \ + dest_dat = ~src_dat | dest_dat; \ + break; \ + case 0x0a: \ + dest_dat = src_dat | ~dest_dat; \ + break; \ + case 0x0b: \ + dest_dat = src_dat | dest_dat; \ + break; \ + case 0x0c: \ + dest_dat = src_dat & dest_dat; \ + break; \ + case 0x0d: \ + dest_dat = src_dat & ~dest_dat; \ + break; \ + case 0x0e: \ + dest_dat = ~src_dat & dest_dat; \ + break; \ + case 0x0f: \ + dest_dat = ~(src_dat | dest_dat); \ + break; \ + case 0x10: \ + dest_dat = MIN(src_dat, dest_dat); \ + break; \ + case 0x11: \ + dest_dat = dest_dat - src_dat; \ + break; \ + case 0x12: \ + dest_dat = src_dat - dest_dat; \ + break; \ + case 0x13: \ + dest_dat = src_dat + dest_dat; \ + break; \ + case 0x14: \ + dest_dat = MAX(src_dat, dest_dat); \ + break; \ + case 0x15: \ + dest_dat = (dest_dat - src_dat) / 2; \ + break; \ + case 0x16: \ + dest_dat = (src_dat - dest_dat) / 2; \ + break; \ + case 0x17: \ + dest_dat = (dest_dat + src_dat) / 2; \ + break; \ + case 0x18: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x19: \ + dest_dat = MAX(0, (dest_dat - src_dat)); \ + break; \ + case 0x1a: \ + dest_dat = MAX(0, (src_dat - dest_dat)); \ + break; \ + case 0x1b: \ + dest_dat = MIN(0xff, (dest_dat + src_dat)); \ + break; \ + case 0x1c: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1d: \ + dest_dat = MAX(0, (dest_dat - src_dat)) / 2; \ + break; \ + case 0x1e: \ + dest_dat = MAX(0, (src_dat - dest_dat)) / 2; \ + break; \ + case 0x1f: \ + dest_dat = (0xff < (src_dat + dest_dat)) ? 0xff : ((src_dat + dest_dat) / 2); \ + break; \ + } \ + } + + +#define WRITE(addr, dat, vgacore) \ + if ((svga->bpp == 8) || (svga->bpp == 24)) { \ + if (vgacore) { \ + svga->vram[((addr)) & (svga->vram_mask)] = dat; \ + svga->changedvram[(((addr)) & (svga->vram_mask)) >> 12] = changeframecount; \ + } else { \ + dev->vram[((addr)) & (dev->vram_mask)] = dat; \ + dev->changedvram[(((addr)) & (dev->vram_mask)) >> 12] = changeframecount; \ + } \ + } else if ((svga->bpp == 15) || (svga->bpp == 16)) { \ + vram_w[((addr)) & (svga->vram_mask >> 1)] = dat; \ + svga->changedvram[(((addr)) & (svga->vram_mask >> 1)) >> 11] = changeframecount; \ + } + + +static int +mach_pixel_write(mach_t *mach) +{ + if (mach->accel.dp_config & 1) + return 1; + + return 0; +} + +static int +mach_pixel_read(mach_t *mach) +{ + if (mach->accel.dp_config & 1) + return 0; + + return 1; +} + +static void +mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint32_t cpu_dat, mach_t *mach, ibm8514_t *dev, int len) +{ + svga_t *svga = &mach->svga; + int compare_mode; + int poly_src = 0; + uint16_t rd_mask = dev->accel.rd_mask; + uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t dest_cmp_clr = dev->accel.color_cmp; + int frgd_sel, bkgd_sel, mono_src; + int compare = 0; + uint16_t src_dat = 0, dest_dat; + uint16_t old_dest_dat; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint16_t mix = 0; + int16_t clip_l = dev->accel.clip_left & 0x7ff; + int16_t clip_t = dev->accel.clip_top & 0x7ff; + int16_t clip_r = dev->accel.multifunc[4] & 0x7ff; + int16_t clip_b = dev->accel.multifunc[3] & 0x7ff; + uint32_t mono_dat0 = 0, mono_dat1 = 0; + + if ((svga->bpp == 8) || (svga->bpp == 24)) { + rd_mask &= 0xff; + dest_cmp_clr &= 0xff; + } + + compare_mode = (mach->accel.dest_cmp_fn >> 3) & 7; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + mach->accel.ge_offset = (mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16)); + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + mach->force_busy = 1; + mach->force_busy2 = 1; + dev->force_busy = 1; + dev->force_busy2 = 1; + } + + if (cpu_input) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + if ((mach->accel.dp_config & 0x200) && (count == 2)) { + count >>= 1; + } + } + } + + if ((svga->bpp == 8) || (svga->bpp == 15) || (svga->bpp == 16) || (svga->bpp == 24)) { + if (svga->bpp == 24) + mach_log("24BPP: CMDType=%d, cwh(%d,%d,%d,%d), dpconfig=%04x\n", cmd_type, clip_l, clip_r, clip_t, clip_b, mach->accel.dp_config); + else + mach_log("BPP=%d, CMDType = %d, offs=%08x, DPCONFIG = %04x, cnt = %d, input = %d, mono_src = %d, frgdsel = %d, dstx = %d, dstxend = %d, pitch = %d, extcrt = %d, rw = %x, monpattern = %x.\n", svga->bpp, cmd_type, mach->accel.ge_offset, mach->accel.dp_config, count, cpu_input, mono_src, frgd_sel, dev->accel.cur_x, mach->accel.dest_x_end, dev->ext_pitch, dev->ext_crt_pitch, mach->accel.dp_config & 1, mach->accel.mono_pattern_enable); + } + + switch (cmd_type) { + case 1: /*Extended Raw Linedraw from bres_count register (0x96ee)*/ + if (!cpu_input) { + dev->accel.dx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.dx |= ~0x5ff; + dev->accel.dy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.dy |= ~0x5ff; + + dev->accel.cx = dev->accel.destx_distp; + if (dev->accel.destx_distp >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = dev->accel.desty_axstp; + if (dev->accel.desty_axstp >= 0x600) + dev->accel.cy |= ~0x5ff; + + mach->accel.width = mach->accel.bres_count; + dev->accel.sx = 0; + mach->accel.poly_fill = 0; + + mach->accel.color_pattern_idx = ((dev->accel.cx + (dev->accel.cy << 3)) & mach->accel.patt_len); + + mach->accel.stepx = (mach->accel.linedraw_opt & 0x20) ? 1 : -1; + mach->accel.stepy = (mach->accel.linedraw_opt & 0x80) ? 1 : -1; + + mach_log("Extended bresenham, CUR(%d,%d), DEST(%d,%d), width = %d, options = %04x, dpconfig = %04x, opt_ena = %03x.\n", dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy, mach->accel.width, mach->accel.linedraw_opt, mach->accel.dp_config, mach->accel.max_waitstates & 0x100); + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (frgd_sel == 5) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + + /*The destination coordinates should match the pattern index.*/ + if (mach->accel.color_pattern_idx != mach->accel.patt_idx) + mach->accel.color_pattern_idx = mach->accel.patt_idx; + } + + if (mono_src == 1) { + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10]; + dev->accel.temp_cnt = 8; + } + + if (mach->accel.linedraw_opt & 0x08) { /*Vector Line*/ + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } + mix = (mix & rd_mask) == rd_mask; + break; + } + + if ((((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b))) { + if (mach->accel.linedraw_opt & 0x02) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + } + poly_src = ((poly_src & rd_mask) == rd_mask); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + + if (!mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if (mach->accel.linedraw_opt & 0x04) { + if (dev->accel.sx < mach->accel.width) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } + } + } else { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } + } + } + } + + if ((mono_src == 1) && !count) + break; + else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) + break; + + if (svga->bpp == 8) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + switch (mach->accel.linedraw_opt & 0xe0) { + case 0x00: + dev->accel.cx++; + dev->accel.dx++; + break; + case 0x20: + dev->accel.cx++; + dev->accel.dx++; + dev->accel.cy--; + dev->accel.dy--; + break; + case 0x40: + dev->accel.cy--; + dev->accel.dy--; + break; + case 0x60: + dev->accel.cx--; + dev->accel.dx--; + dev->accel.cy--; + dev->accel.dy--; + break; + case 0x80: + dev->accel.cx--; + dev->accel.dx--; + break; + case 0xa0: + dev->accel.cx--; + dev->accel.dx--; + dev->accel.cy++; + dev->accel.dy++; + break; + case 0xc0: + dev->accel.cy++; + dev->accel.dy++; + break; + case 0xe0: + dev->accel.cx++; + dev->accel.dx++; + dev->accel.cy++; + dev->accel.dy++; + break; + } + + dev->accel.sx++; + } + } else { /*Bresenham*/ + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } + mix = (mix & rd_mask) == rd_mask; + break; + } + + if ((((dev->accel.dx) >= clip_l) && ((dev->accel.dx) <= clip_r) && ((dev->accel.dy) >= clip_t) && ((dev->accel.dy) <= clip_b))) { + if (mach->accel.linedraw_opt & 0x02) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), poly_src, dev->local); + } + poly_src = ((poly_src & rd_mask) == rd_mask); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + + if (!mach->accel.poly_fill || !(mach->accel.linedraw_opt & 0x02)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), mix, dev->local); + } + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.dx) + ((dev->accel.dy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if (mach->accel.linedraw_opt & 0x04) { + if (dev->accel.sx < mach->accel.width) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } + } + } else { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.dy) * (dev->pitch)) + (dev->accel.dx), dest_dat, dev->local); + } + } + } + } + + if ((mono_src == 1) && !count) + break; + else if ((mono_src != 1) && (dev->accel.sx >= mach->accel.width)) + break; + + if (svga->bpp == 8) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (mach->accel.linedraw_opt & 0x40) { + dev->accel.dy += mach->accel.stepy; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cy += mach->accel.stepy; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.dx += mach->accel.stepx; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cx += mach->accel.stepx; + } else { + dev->accel.err_term += dev->accel.desty_axstp; + } + } else { + dev->accel.dx += mach->accel.stepx; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cx += mach->accel.stepx; + + if (dev->accel.err_term >= 0) { + dev->accel.err_term += dev->accel.destx_distp; + dev->accel.dy += mach->accel.stepy; + if ((frgd_sel == 3) || (bkgd_sel == 3)) + dev->accel.cy += mach->accel.stepy; + } else { + dev->accel.err_term += dev->accel.desty_axstp; + } + } + + dev->accel.sx++; + } + } + dev->accel.cur_x = dev->accel.dx; + dev->accel.cur_y = dev->accel.dy; + break; + + case 2: /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ + if (!cpu_input) { + mach->accel.stepx = 0; + mach->accel.stepy = 0; + + dev->accel.dx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.dx |= ~0x5ff; + + dev->accel.dy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.dy |= ~0x5ff; + + /*Destination Width*/ + if (mach->accel.dest_x_start != dev->accel.dx) + mach->accel.dest_x_start = dev->accel.dx; + + mach->accel.dx_start = mach->accel.dest_x_start; + if (mach->accel.dest_x_start >= 0x600) + mach->accel.dx_start |= ~0x5ff; + + mach->accel.dx_end = mach->accel.dest_x_end; + if (mach->accel.dest_x_end >= 0x600) + mach->accel.dx_end |= ~0x5ff; + + if (mach->accel.dx_end > mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_end - mach->accel.dx_start); + mach->accel.stepx = 1; + } else if (mach->accel.dx_end < mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end); + mach->accel.stepx = -1; + if (dev->accel.dx > 0) + dev->accel.dx--; + mach_log("BitBLT: Dst Negative X, dxstart = %d, end = %d, width = %d, dx = %d, dpconfig = %04x.\n", mach->accel.dest_x_start, mach->accel.dest_x_end, mach->accel.width, dev->accel.dx, mach->accel.dp_config); + } else { + mach->accel.stepx = 1; + mach->accel.width = 0; + mach_log("BitBLT: Dst Indeterminate X, dpconfig = %04x, destxend = %d, destxstart = %d.\n", mach->accel.dp_config, mach->accel.dest_x_end, mach->accel.dest_x_start); + } + + dev->accel.sx = 0; + mach->accel.poly_fill = 0; + mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); + if ((svga->bpp == 24) && (mono_src != 1)) { + if (mach->accel.color_pattern_idx == mach->accel.patt_len) + mach->accel.color_pattern_idx = mach->accel.patt_data_idx; + } else if ((svga->bpp == 24) && (frgd_sel == 5) && (mono_src == 1) && (mach->accel.patt_len_reg & 0x4000)) + mach->accel.color_pattern_idx = 0; + + /*Height*/ + mach->accel.dy_start = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + mach->accel.dy_start |= ~0x5ff; + mach->accel.dy_end = mach->accel.dest_y_end; + if (mach->accel.dest_y_end >= 0x600) + mach->accel.dy_end |= ~0x5ff; + + if (mach->accel.dy_end > mach->accel.dy_start) { + mach->accel.height = (mach->accel.dy_end - mach->accel.dy_start); + mach->accel.stepy = 1; + } else if (mach->accel.dy_end < mach->accel.dy_start) { + mach->accel.height = (mach->accel.dy_start - mach->accel.dy_end); + mach->accel.stepy = -1; + } else { + mach->accel.height = 0; + mach->accel.stepy = 1; + } + + dev->accel.sy = 0; + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + + mach->accel.src_stepx = 0; + + /*Source Width*/ + dev->accel.cx = mach->accel.src_x; + if (mach->accel.src_x >= 0x600) + dev->accel.cx |= ~0x5ff; + + dev->accel.cy = mach->accel.src_y; + if (mach->accel.src_y >= 0x600) + dev->accel.cy |= ~0x5ff; + + mach->accel.sx_start = mach->accel.src_x_start; + if (mach->accel.src_x_start >= 0x600) + mach->accel.sx_start |= ~0x5ff; + + mach->accel.sx_end = mach->accel.src_x_end; + if (mach->accel.src_x_end >= 0x600) + mach->accel.sx_end |= ~0x5ff; + + if (mach->accel.sx_end > mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_end - mach->accel.sx_start); + mach->accel.src_stepx = 1; + mach_log("BitBLT: Src Positive X: wh(%d,%d), srcwidth = %d, coordinates: %d,%d px, start: %d, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_start, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + } else if (mach->accel.sx_end < mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_start - mach->accel.sx_end); + mach->accel.src_stepx = -1; + if (dev->accel.cx > 0) + dev->accel.cx--; + mach_log("BitBLT: Src Negative X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + } else { + mach->accel.src_stepx = 1; + mach->accel.src_width = 0; + mach_log("BitBLT: Src Indeterminate X: width = %d, coordinates: %d,%d px, end: %d px, stepx = %d, dpconfig = %04x, oddwidth = %d.\n", mach->accel.src_width, dev->accel.cx, dev->accel.cy, mach->accel.src_x_end, mach->accel.src_stepx, mach->accel.dp_config, mach->accel.src_width & 1); + } + mach->accel.sx = 0; + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + + if ((svga->bpp == 24) && (frgd_sel == 5)) { + mach_log("BitBLT=%04x, WH(%d,%d), SRCWidth=%d, c(%d,%d), s(%d,%d).\n", mach->accel.dp_config, mach->accel.width, mach->accel.height, mach->accel.src_width, dev->accel.dx, dev->accel.dy, dev->accel.cx, dev->accel.cy); + } else + mach_log("BitBLT=%04x, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, mach->accel.width, mach->accel.height, (mach->accel.ge_offset << 2)); + + if (mono_src == 1) { + if ((mach->accel.mono_pattern_enable) && !(mach->accel.patt_len_reg & 0x4000)) { + mono_dat0 = mach->accel.patt_data[0x10]; + mono_dat0 |= (mach->accel.patt_data[0x11] << 8); + mono_dat0 |= (mach->accel.patt_data[0x12] << 16); + mono_dat0 |= (mach->accel.patt_data[0x13] << 24); + mono_dat1 = mach->accel.patt_data[0x14]; + mono_dat1 |= (mach->accel.patt_data[0x15] << 8); + mono_dat1 |= (mach->accel.patt_data[0x16] << 16); + mono_dat1 |= (mach->accel.patt_data[0x17] << 24); + + for (uint8_t y = 0; y < 8; y++) { + for (uint8_t x = 0; x < 8; x++) { + uint32_t temp = (y & 4) ? mono_dat1 : mono_dat0; + mach->accel.mono_pattern[y][7 - x] = (temp >> (x + ((y & 3) << 3))) & 1; + } + } + } + } + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (mono_src == 1) { + if (!mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10] ^ ((mach->accel.patt_idx & 1) ? 0xff : 0); + dev->accel.temp_cnt = 8; + } + } + + if (frgd_sel == 5) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + for (int x = 0; x <= mach->accel.patt_len; x += 2) { + mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] = (mach->accel.patt_data[x & mach->accel.patt_len] & 0xff); + mach->accel.color_pattern_word[x + (mach->accel.color_pattern_idx & 1)] |= (mach->accel.patt_data[(x + 1) & mach->accel.patt_len] << 8); + } + } else { + if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x]; + mach_log("BITBLT: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); + } + } else { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + } + } + + /*The destination coordinates should match the pattern index.*/ + if (mach->accel.color_pattern_idx != mach->accel.patt_idx) + mach->accel.color_pattern_idx = mach->accel.patt_idx; + } + + if ((mach->accel.dy_end == mach->accel.dy_start)) { + mach_log("No DEST.\n"); + return; + } + + if ((mono_src == 3) || (bkgd_sel == 3) || (frgd_sel == 3)) { + if (mach->accel.sx_end == mach->accel.sx_start) { + mach_log("No SRC.\n"); + return; + } + } + + if (cpu_input) { + if (mach->accel.dp_config == 0x3251) { + if (dev->accel.sy == mach->accel.height) + return; + } + } + + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (mach->accel.mono_pattern_enable) { + mix = mach->accel.mono_pattern[dev->accel.dy & 7][dev->accel.dx & 7]; + } else { + if ((svga->bpp == 24) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) + mix = 1; + else { + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + READ(dev->accel.src + ((dev->accel.cx)), mix, dev->local); + mix = (mix & rd_mask) == rd_mask; + break; + } + + if (((dev->accel.dx) >= (clip_l) && (dev->accel.dx) <= (clip_r) && + (dev->accel.dy) >= (clip_t) && (dev->accel.dy) <= (clip_b))) { + if (mach->accel.dp_config & 0x02) { + READ(dev->accel.src + (dev->accel.cx), poly_src, dev->local); + poly_src = ((poly_src & rd_mask) == rd_mask); + if (poly_src) + mach->accel.poly_fill = !mach->accel.poly_fill; + } + + if (!mach->accel.poly_fill || !(mach->accel.dp_config & 0x02)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + READ(dev->accel.src + (dev->accel.cx), src_dat, dev->local); + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + src_dat = mach->accel.color_pattern_word[mach->accel.color_pattern_idx]; + } else { + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + } + } else + src_dat = 0; + break; + } + } + + if ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if (dev->accel.sy & 1) { + READ(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat, dev->local); + } else { + READ(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + } + } else { + READ(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + if ((svga->bpp == 24) && (mono_src == 1) && (frgd_sel == 5) && (mach->accel.patt_len_reg & 0x4000)) { + if (dev->accel.sy & 1) { + WRITE(dev->accel.dest + dev->accel.dx - dev->ext_pitch, dest_dat, dev->local); + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + } + } else { + WRITE(dev->accel.dest + dev->accel.dx, dest_dat, dev->local); + } + } + } + + if ((svga->bpp == 8) || (svga->bpp == 24)) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if ((mono_src == 3) || (frgd_sel == 3) || (bkgd_sel == 3)) { + dev->accel.cx += mach->accel.src_stepx; + mach->accel.sx++; + if (mach->accel.sx >= mach->accel.src_width) { + mach->accel.sx = 0; + if (mach->accel.src_stepx == -1) + dev->accel.cx += mach->accel.src_width; + else + dev->accel.cx -= mach->accel.src_width; + dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + } + } + + dev->accel.dx += mach->accel.stepx; + + if ((svga->bpp == 8) || ((svga->bpp == 24) && (mach->accel.patt_len >= 3) && (mono_src != 1))) + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + + if ((svga->bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mach->accel.patt_len >= 3) && (mono_src != 1)) { + mach->accel.color_pattern_idx = mach->accel.patt_data_idx; + } else if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + if (mach->accel.patt_len == 2) { + mach->accel.color_pattern_idx++; + if (mach->accel.color_pattern_idx == 3) + mach->accel.color_pattern_idx = 0; + } else { + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + } + } else if ((svga->bpp == 24) && (mach->accel.patt_len_reg & 0x4000) && (frgd_sel == 5)) { + mach->accel.color_pattern_idx++; + if (mach->accel.color_pattern_idx == 3) + mach->accel.color_pattern_idx = 0; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + } + + dev->accel.sx++; + if (dev->accel.sx >= mach->accel.width) { + mach->accel.poly_fill = 0; + dev->accel.sx = 0; + if (mach->accel.stepx == -1) + dev->accel.dx += mach->accel.width; + else + dev->accel.dx -= mach->accel.width; + + dev->accel.dy += mach->accel.stepy; + dev->accel.sy++; + + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else { + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + } + if ((mono_src == 1) && (svga->bpp == 24) && (frgd_sel == 5)) + mach->accel.color_pattern_idx = 0; + else + mach->accel.color_pattern_idx = ((dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len); + + if ((svga->bpp == 24) && (mach->accel.color_pattern_idx == mach->accel.patt_len) && (mono_src != 1)) + mach->accel.color_pattern_idx = 0; + if ((mono_src == 1) && !mach->accel.mono_pattern_enable && !(mach->accel.patt_len_reg & 0x4000)) { + dev->accel.cur_x = dev->accel.dx; + dev->accel.cur_y = dev->accel.dy; + return; + } + if (dev->accel.sy >= mach->accel.height) { + if ((mono_src == 2) || (mono_src == 3) || (frgd_sel == 2) || (frgd_sel == 3) || (bkgd_sel == 2) || (bkgd_sel == 3)) + return; + if ((mono_src == 1) && (frgd_sel == 5) && (svga->bpp == 24) && (mach->accel.patt_len_reg & 0x4000)) + return; + dev->accel.cur_x = dev->accel.dx; + dev->accel.cur_y = dev->accel.dy; + return; + } + } + } + break; + + case 3: /*Direct Linedraw (Polyline) from linedraw indexes (0xfeee)*/ + case 4: + if (!cpu_input) { + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x >= 0x600) { + mach_log("Linedraw XOver = %d.\n", dev->accel.cur_x); + dev->accel.cx |= ~0x5ff; + } + if (dev->accel.cur_y >= 0x600) { + mach_log("Linedraw YOver = %d.\n", dev->accel.cur_y); + dev->accel.cy |= ~0x5ff; + } + + dev->accel.dx = ABS(mach->accel.cx_end_line - dev->accel.cx) << 1; + dev->accel.dy = ABS(mach->accel.cy_end_line - dev->accel.cy) << 1; + + mach->accel.stepx = (mach->accel.cx_end_line < dev->accel.cx) ? -1 : 1; + mach->accel.stepy = (mach->accel.cy_end_line < dev->accel.cy) ? -1 : 1; + + dev->accel.sx = 0; + + mach_log("Linedraw: c(%d,%d), d(%d,%d), cend(%d,%d).\n", dev->accel.cur_x, dev->accel.cur_y, dev->accel.dx, dev->accel.dy, mach->accel.cx_end_line, mach->accel.cy_end_line); + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (frgd_sel == 5) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + } + + if (mono_src == 1) { + mix_dat = mach->accel.patt_data[0x10]; + dev->accel.temp_cnt = 8; + } + + count = (dev->accel.dx > dev->accel.dy) ? (dev->accel.dx >> 1) : (dev->accel.dy >> 1); + mach->accel.width = count; + + if (dev->accel.dx > dev->accel.dy) { + mach->accel.err = (dev->accel.dy - dev->accel.dx) >> 1; + if (mono_src == 1) { + while (count--) { + if (!dev->accel.temp_cnt) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + + if ((((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b))) { + mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (!count) + break; + + if (svga->bpp == 8) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (mach->accel.err >= 0) { + dev->accel.cy += mach->accel.stepy; + mach->accel.err -= dev->accel.dx; + } + dev->accel.cx += mach->accel.stepx; + mach->accel.err += dev->accel.dy; + } + } else { + while (count--) { + switch (mono_src) { + case 0: + case 3: + mix = 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + } + + if ((((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b))) { + mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if (mach->accel.linedraw_opt & 0x04) { + if (dev->accel.sx < mach->accel.width) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + } + } else { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (dev->accel.sx >= mach->accel.width) + break; + + if (svga->bpp == 8) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (mach->accel.err >= 0) { + dev->accel.cy += mach->accel.stepy; + mach->accel.err -= dev->accel.dx; + } + dev->accel.cx += mach->accel.stepx; + mach->accel.err += dev->accel.dy; + + dev->accel.sx++; + } + } + } else { + mach->accel.err = (dev->accel.dx - dev->accel.dy) >> 1; + if (mono_src == 1) { + while (count--) { + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + + if ((((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b))) { + mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (!count) + break; + + if (svga->bpp == 8) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (mach->accel.err >= 0) { + dev->accel.cx += mach->accel.stepx; + mach->accel.err -= dev->accel.dy; + } + dev->accel.cy += mach->accel.stepy; + mach->accel.err += dev->accel.dx; + } + } else { + while (count--) { + switch (mono_src) { + case 0: + case 3: + mix = 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + } + + if ((((dev->accel.cx) >= clip_l) && ((dev->accel.cx) <= clip_r) && ((dev->accel.cy) >= clip_t) && ((dev->accel.cy) <= clip_b))) { + mach->accel.clip_overrun = 0; + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + src_dat = 0; + } + break; + case 5: + if (mix) { + src_dat = mach->accel.color_pattern[((dev->accel.cx) + ((dev->accel.cy) << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) { + READ((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + READ((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if ((mach->accel.dp_config & 0x10) && (cmd_type == 3)) { + if (mach->accel.linedraw_opt & 0x04) { + if (dev->accel.sx < mach->accel.width) { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + } + } else { + if ((svga->bpp == 15) || (svga->bpp == 16)) { + WRITE((mach->accel.ge_offset << 1) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } else { + WRITE((mach->accel.ge_offset << 2) + ((dev->accel.cy) * (dev->pitch)) + (dev->accel.cx), dest_dat, dev->local); + } + } + } + } else + mach->accel.clip_overrun = ((mach->accel.clip_overrun + 1) & 0x0f); + + if (dev->accel.sx >= mach->accel.width) + break; + + if (svga->bpp == 8) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + if (mach->accel.err >= 0) { + dev->accel.cx += mach->accel.stepx; + mach->accel.err -= dev->accel.dy; + } + dev->accel.cy += mach->accel.stepy; + mach->accel.err += dev->accel.dx; + + dev->accel.sx++; + } + } + } + mach->accel.line_array[(cmd_type == 4) ? 4 : 0] = dev->accel.cx; + mach->accel.line_array[(cmd_type == 4) ? 5 : 1] = dev->accel.cy; + dev->accel.cur_x = mach->accel.line_array[(cmd_type == 4) ? 4 : 0]; + dev->accel.cur_y = mach->accel.line_array[(cmd_type == 4) ? 5 : 1]; + break; + + case 5: /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ + if (!cpu_input) { + mach->accel.stepx = 0; + mach->accel.stepy = 0; + + dev->accel.dx = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + dev->accel.dx |= ~0x5ff; + dev->accel.dy = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + dev->accel.dy |= ~0x5ff; + + /*Destination Width*/ + mach->accel.dx_start = dev->accel.cur_x; + if (dev->accel.cur_x >= 0x600) + mach->accel.dx_start |= ~0x5ff; + mach->accel.dx_end = mach->accel.scan_to_x; + if (mach->accel.scan_to_x >= 0x600) + mach->accel.dx_end |= ~0x5ff; + + if (mach->accel.dx_end > mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_end - mach->accel.dx_start); + mach->accel.stepx = 1; + } else if (mach->accel.dx_end < mach->accel.dx_start) { + mach->accel.width = (mach->accel.dx_start - mach->accel.dx_end); + mach->accel.stepx = -1; + if (dev->accel.dx > 0) + dev->accel.dx--; + } else { + mach->accel.stepx = 1; + mach->accel.width = 0; + } + + dev->accel.sx = 0; + if ((svga->bpp == 24) && (mach->accel.patt_len < 0x17)) + mach->accel.color_pattern_idx = 0; + + /*Step Y*/ + mach->accel.dy_start = dev->accel.cur_y; + if (dev->accel.cur_y >= 0x600) + mach->accel.dy_start |= ~0x5ff; + mach->accel.dy_end = mach->accel.dest_y_end; + if (mach->accel.dest_y_end >= 0x600) + mach->accel.dy_end |= ~0x5ff; + + if (mach->accel.dy_end > mach->accel.dy_end) { + mach->accel.stepy = 1; + } else if (mach->accel.dy_end < mach->accel.dy_end) { + mach->accel.stepy = -1; + } else { + mach->accel.stepy = 0; + } + + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + + mach->accel.src_stepx = 0; + + /*Source Width*/ + dev->accel.cx = mach->accel.src_x; + if (mach->accel.src_x >= 0x600) + dev->accel.cx |= ~0x5ff; + dev->accel.cy = mach->accel.src_y; + if (mach->accel.src_y >= 0x600) + dev->accel.cy |= ~0x5ff; + + mach->accel.sx_start = mach->accel.src_x_start; + if (mach->accel.src_x_start >= 0x600) + mach->accel.sx_start |= ~0x5ff; + + mach->accel.sx_end = mach->accel.src_x_end; + if (mach->accel.src_x_end >= 0x600) + mach->accel.sx_end |= ~0x5ff; + + if (mach->accel.sx_end > mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_end - mach->accel.sx_start); + mach->accel.src_stepx = 1; + } else if (mach->accel.sx_end < mach->accel.sx_start) { + mach->accel.src_width = (mach->accel.sx_start - mach->accel.sx_end); + mach->accel.src_stepx = -1; + if (dev->accel.cx > 0) + dev->accel.cx--; + } else { + mach->accel.src_stepx = 1; + mach->accel.src_width = 0; + } + + mach->accel.sx = 0; + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + + if ((svga->bpp == 24) && (frgd_sel == 5)) { + if (mach->accel.patt_len == 0x17) + mach->accel.color_pattern_idx = 0; + dev->accel.x1 = dev->accel.dx + mach->accel.width; + if (dev->accel.x1 == dev->pitch) { + dev->accel.x2 = mach->accel.width & 1; + } else if ((dev->accel.x1 == mach->accel.width) && (dev->accel.dy & 1) && !dev->accel.y1 && dev->accel.x2) { + if (mach->accel.patt_len == 0x17) + mach->accel.color_pattern_idx = 3; + dev->accel.x3 = 1; + } else + dev->accel.x3 = 0; + } else + mach_log("ScanToX=%04x, Pitch=%d, C(%d,%d), SRCWidth=%d, WH(%d,%d), geoffset=%08x.\n", mach->accel.dp_config, dev->ext_pitch, dev->accel.cx, dev->accel.cy, mach->accel.src_width, mach->accel.width, mach->accel.height, (mach->accel.ge_offset << 1)); + + dev->accel.y1 = 0; + + if ((mono_src == 2) || (bkgd_sel == 2) || (frgd_sel == 2) || mach_pixel_read(mach)) { + if (mach_pixel_write(mach)) { + dev->data_available = 0; + dev->data_available2 = 0; + return; + } else if (mach_pixel_read(mach)) { + dev->data_available = 1; + dev->data_available2 = 1; + return; + } + } + } + + if (mono_src == 1) { + count = mach->accel.width; + mix_dat = mach->accel.patt_data[0x10]; + dev->accel.temp_cnt = 8; + } + + if (frgd_sel == 5) { + if (svga->bpp != 24) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x & mach->accel.patt_len]; + } + } else { + if (mach->accel.patt_len == 0x17) { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern_full[x] = mach->accel.patt_data[x]; + mach_log("ScanToX: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern_full[x], mach->accel.patt_data_idx, mach->accel.patt_len); + } + } else { + for (int x = 0; x <= mach->accel.patt_len; x++) { + mach->accel.color_pattern[x] = mach->accel.patt_data[x]; + mach_log("ScanToX: Color Pattern 24bpp[%d]=%02x, dataidx=%d, pattlen=%d.\n", x, mach->accel.color_pattern[x], mach->accel.patt_data_idx, mach->accel.patt_len); + } + } + } + } + + while (count--) { + switch (mono_src) { + case 0: + mix = 1; + break; + case 1: + if (dev->accel.temp_cnt == 0) { + dev->accel.temp_cnt = 8; + mix_dat >>= 8; + } + mix = (mix_dat & 0x80); + dev->accel.temp_cnt--; + mix_dat <<= 1; + mix_dat |= 1; + break; + case 2: + if (mach->accel.dp_config & 0x1000) { + mix = mix_dat >> 0x1f; + mix_dat <<= 1; + } else { + if (mach->accel.dp_config & 0x200) { + mix = mix_dat & 1; + mix_dat >>= 1; + } else { + mix = mix_dat & 0x80; + mix_dat <<= 1; + mix_dat |= 1; + } + } + break; + case 3: + READ(dev->accel.src + (dev->accel.cx), mix, dev->local); + mix = (mix & rd_mask) == rd_mask; + break; + } + + if ((dev->accel.dx) >= (clip_l) && (dev->accel.dx) <= (clip_r) && + (dev->accel.dy) >= (clip_t) && (dev->accel.dy) <= (clip_b)) { + switch (mix ? frgd_sel : bkgd_sel) { + case 0: + src_dat = dev->accel.bkgd_color; + break; + case 1: + src_dat = dev->accel.frgd_color; + break; + case 2: + src_dat = cpu_dat; + break; + case 3: + if (mach_pixel_read(mach)) + src_dat = cpu_dat; + else { + READ(dev->accel.src + (dev->accel.cx), src_dat, dev->local); + if (mono_src == 3) { + src_dat = (src_dat & rd_mask) == rd_mask; + } + } + break; + case 5: + if (mix) { + if (svga->bpp == 24) { + if (mach->accel.patt_len == 0x17) + src_dat = mach->accel.color_pattern_full[mach->accel.color_pattern_idx]; + else + src_dat = mach->accel.color_pattern[mach->accel.color_pattern_idx]; + } else + src_dat = mach->accel.color_pattern[(dev->accel.dx + (dev->accel.dy << 3)) & mach->accel.patt_len]; + } else + src_dat = 0; + break; + } + + READ(dev->accel.dest + (dev->accel.dx), dest_dat, dev->local); + + switch (compare_mode) { + case 1: + compare = 1; + break; + case 2: + compare = ((dest_dat) >= dest_cmp_clr) ? 0 : 1; + break; + case 3: + compare = ((dest_dat) < dest_cmp_clr) ? 0 : 1; + break; + case 4: + compare = ((dest_dat) != dest_cmp_clr) ? 0 : 1; + break; + case 5: + compare = ((dest_dat) == dest_cmp_clr) ? 0 : 1; + break; + case 6: + compare = ((dest_dat) <= dest_cmp_clr) ? 0 : 1; + break; + case 7: + compare = ((dest_dat) > dest_cmp_clr) ? 0 : 1; + break; + } + + if (!compare) { + if (mach_pixel_write(mach)) { + old_dest_dat = dest_dat; + MIX(mix, dest_dat, src_dat); + dest_dat = (dest_dat & wrt_mask) | (old_dest_dat & ~wrt_mask); + } + } + + if (mach->accel.dp_config & 0x10) { + WRITE(dev->accel.dest + (dev->accel.dx), dest_dat, dev->local); + } + } + + if ((svga->bpp == 8) || (svga->bpp == 24)) + cpu_dat >>= 8; + else + cpu_dat >>= 16; + + dev->accel.cx += mach->accel.src_stepx; + mach->accel.sx++; + if (mach->accel.sx >= mach->accel.src_width) { + mach->accel.sx = 0; + if (mach->accel.src_stepx == -1) { + dev->accel.cx += mach->accel.src_width; + } else + dev->accel.cx -= mach->accel.src_width; + dev->accel.cy += (mach->accel.src_y_dir ? 1 : -1); + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.src = (mach->accel.ge_offset << 1) + (dev->accel.cy * (dev->pitch)); + else + dev->accel.src = (mach->accel.ge_offset << 2) + (dev->accel.cy * (dev->pitch)); + } + + dev->accel.dx += mach->accel.stepx; + if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17)) { + mach->accel.color_pattern_idx++; + if (dev->accel.x3) { + if (mach->accel.color_pattern_idx == 9) + mach->accel.color_pattern_idx = 3; + } else { + if (mach->accel.color_pattern_idx == 6) + mach->accel.color_pattern_idx = 0; + } + } else if ((svga->bpp == 24) && (mach->accel.patt_len < 3)) { + mach->accel.color_pattern_idx++; + if (mach->accel.color_pattern_idx == 3) + mach->accel.color_pattern_idx = 0; + } else + mach->accel.color_pattern_idx = (mach->accel.color_pattern_idx + mach->accel.stepx) & mach->accel.patt_len; + + dev->accel.sx++; + if (dev->accel.sx >= mach->accel.width) { + dev->accel.sx = 0; + dev->accel.dy += mach->accel.stepy; + if ((svga->bpp == 15) || (svga->bpp == 16)) + dev->accel.dest = (mach->accel.ge_offset << 1) + (dev->accel.dy * (dev->pitch)); + else + dev->accel.dest = (mach->accel.ge_offset << 2) + (dev->accel.dy * (dev->pitch)); + if (mach->accel.line_idx == 2) { + mach->accel.line_array[0] = dev->accel.dx; + mach->accel.line_array[4] = dev->accel.dx; + } + return; + } + } + break; + } +} + +static void +mach_accel_out_pixtrans(mach_t *mach, ibm8514_t *dev, uint16_t port, uint16_t val, uint16_t len) +{ + int frgd_sel, bkgd_sel, mono_src; + + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + if ((mach->accel.dp_config & 4) && (mach->accel.cmd_type != 5)) { + val = (val >> 8) | (val << 8); + } + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if ((mono_src == 2)) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if ((mach->accel.dp_config & 0x1000) && dev->local) + val = (val >> 8) | (val << 8); + mach_accel_start(mach->accel.cmd_type, 1, 8, val | (val << 16), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, val | (val << 16), mach, dev, len); + break; + case 0x200: /*16-bit size*/ + if ((mono_src == 2)) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + val = (val >> 8) | (val << 8); + mach_accel_start(mach->accel.cmd_type, 1, 16, val | (val << 16), 0, mach, dev, len); + } else { + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev, len); + } + } else { + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, val | (val << 16), mach, dev, len); + } + break; + } +} + +static void +mach_out(uint16_t addr, uint8_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; + uint8_t old; + uint8_t rs2; + + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x1ce: + mach->index = val; + break; + case 0x1cf: + old = mach->regs[mach->index]; + mach->regs[mach->index] = val; + mach_log("ATI VGA write reg=0x%02X, val=0x%02X\n", mach->index, val); + switch (mach->index) { + case 0xa3: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xa7: + if ((old ^ val) & 0x80) + svga_recalctimings(svga); + break; + case 0xad: + if (dev->local) { + if ((old ^ val) & 0x0c) + svga_recalctimings(svga); + } + break; + case 0xb0: + if ((old ^ val) & 0x60) + svga_recalctimings(svga); + break; + case 0xae: + case 0xb2: + case 0xbe: + mach_log("ATI VGA write reg=0x%02X, val=0x%02X\n", mach->index, val); + if (mach->regs[0xbe] & 0x08) { /* Read/write bank mode */ + mach->bank_r = (((mach->regs[0xb2] & 1) << 3) | ((mach->regs[0xb2] & 0xe0) >> 5)); + mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); + if (dev->local) { + mach->bank_r |= (((mach->regs[0xae] & 0x0c) << 2)); + mach->bank_w |= (((mach->regs[0xae] & 3) << 4)); + } + if (ibm8514_on) + mach_log("Separate B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); + } else { /* Single bank mode */ + mach->bank_w = ((mach->regs[0xb2] & 0x1e) >> 1); + if (dev->local) { + mach->bank_w |= (((mach->regs[0xae] & 3) << 4)); + } + mach->bank_r = mach->bank_w; + if (ibm8514_on) + mach_log("Single B2Bank = %02x, AEbank = %02x.\n", mach->regs[0xb2], mach->regs[0xae]); + } + svga->read_bank = mach->bank_r << 16; + svga->write_bank = mach->bank_w << 16; + + if (mach->index == 0xbe) { + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + } + break; + case 0xbd: + if ((old ^ val) & 4) { + mach32_updatemapping(mach); + } + break; + case 0xb3: + ati_eeprom_write(&mach->eeprom, val & 8, val & 2, val & 1); + break; + case 0xb6: + if ((old ^ val) & 0x10) + svga_recalctimings(svga); + break; + case 0xb8: + if (dev->local) { + if ((old ^ val) & 0x40) + svga_recalctimings(svga); + } else { + if ((old ^ val) & 0xc0) + svga_recalctimings(svga); + } + break; + case 0xb9: + if ((old ^ val) & 2) + svga_recalctimings(svga); + break; + } + break; + + case 0x2ea: + case 0x2eb: + case 0x2ec: + case 0x2ed: + rs2 = !!(mach->accel.ext_ge_config & 0x1000); + if (dev->local) { + if (mach->pci_bus) + ati68860_ramdac_out((addr & 3) | (rs2 << 2), val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + } else + svga_out(addr, val, svga); + return; + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + rs2 = !!(mach->accel.ext_ge_config & 0x1000); + if (dev->local) { + if (mach->pci_bus) + ati68860_ramdac_out((addr & 3) | (rs2 << 2), val, svga->ramdac, svga); + else + svga_out(addr, val, svga); + } else + svga_out(addr, val, svga); + return; + + case 0x3CF: + if (svga->gdcaddr == 6) { + uint8_t old_val = svga->gdcreg[6]; + svga->gdcreg[6] = val; + if ((svga->gdcreg[6] & 0xc) != (old_val & 0xc)) + mach32_updatemapping(mach); + return; + } + break; + + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + } + svga_out(addr, val, svga); +} + +static uint8_t +mach_in(uint16_t addr, void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; + uint8_t temp; + uint8_t rs2; + + if (((addr & 0xFFF0) == 0x3D0 || (addr & 0xFFF0) == 0x3B0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x1ce: + temp = mach->index; + break; + case 0x1cf: + switch (mach->index) { + case 0xa8: + temp = (svga->vc >> 8) & 3; + break; + case 0xa9: + temp = svga->vc & 0xff; + break; + case 0xb0: + temp = mach->regs[0xb0] | 0x80; + if (dev->local) { /*Mach32 VGA 1MB memory*/ + temp |= 0x08; + temp &= ~0x10; + } else { /*ATI 28800 VGA 512kB memory*/ + temp &= ~0x08; + temp |= 0x10; + } + break; + case 0xb7: + temp = mach->regs[0xb7] & ~8; + if (ati_eeprom_read(&mach->eeprom)) + temp |= 8; + break; + + default: + temp = mach->regs[mach->index]; + break; + } + break; + + case 0x2ea: + case 0x2eb: + case 0x2ec: + case 0x2ed: + rs2 = !!(mach->accel.ext_ge_config & 0x1000); + if (dev->local) { + if (mach->pci_bus) + return ati68860_ramdac_in((addr & 3) | (rs2 << 2), svga->ramdac, svga); + else + return svga_in(addr, svga); + } + return svga_in(addr, svga); + + case 0x3C6: + case 0x3C7: + case 0x3C8: + case 0x3C9: + rs2 = !!(mach->accel.ext_ge_config & 0x1000); + if (dev->local) { + if (mach->pci_bus) + return ati68860_ramdac_in((addr & 3) | (rs2 << 2), svga->ramdac, svga); + else + return svga_in(addr, svga); + } + return svga_in(addr, svga); + + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + temp = svga->crtc[svga->crtcreg]; + break; + case 0x3DA: + svga->attrff = 0; + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x38; + else + svga->cgastat ^= 0x38; + return svga->cgastat; + + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} + +static void +mach_recalctimings(svga_t *svga) +{ + mach_t *mach = (mach_t *) svga->p; + ibm8514_t *dev = &svga->dev8514; + + if (vga_on && !ibm8514_on) { + switch (((mach->regs[0xbe] & 0x10) >> 1) | ((mach->regs[0xb9] & 2) << 1) | ((svga->miscout & 0x0c) >> 2)) { + case 0x00: + svga->clock = (cpuclock * (double) (1ull << 32)) / 42954000.0; + break; + case 0x01: + svga->clock = (cpuclock * (double) (1ull << 32)) / 48771000.0; + break; + case 0x02: + mach_log("clock 2\n"); + break; + case 0x03: + svga->clock = (cpuclock * (double) (1ull << 32)) / 36000000.0; + break; + case 0x04: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 0x05: + svga->clock = (cpuclock * (double) (1ull << 32)) / 56640000.0; + break; + case 0x06: + mach_log("clock 2\n"); + break; + case 0x07: + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + break; + case 0x08: + svga->clock = (cpuclock * (double) (1ull << 32)) / 30240000.0; + break; + case 0x09: + svga->clock = (cpuclock * (double) (1ull << 32)) / 32000000.0; + break; + case 0x0A: + svga->clock = (cpuclock * (double) (1ull << 32)) / 37500000.0; + break; + case 0x0B: + svga->clock = (cpuclock * (double) (1ull << 32)) / 39000000.0; + break; + case 0x0C: + svga->clock = (cpuclock * (double) (1ull << 32)) / 50350000.0; + break; + case 0x0D: + svga->clock = (cpuclock * (double) (1ull << 32)) / 56644000.0; + break; + case 0x0E: + svga->clock = (cpuclock * (double) (1ull << 32)) / 75000000.0; + break; + case 0x0F: + svga->clock = (cpuclock * (double) (1ull << 32)) / 65000000.0; + break; + default: + break; + } + } + + if (mach->regs[0xa3] & 0x10) + svga->ma_latch |= 0x10000; + + if (mach->regs[0xb0] & 0x40) + svga->ma_latch |= 0x20000; + + if (dev->local) { + if (mach->regs[0xad] & 0x04) + svga->ma_latch |= 0x40000; + + if (mach->regs[0xad] & 0x08) + svga->ma_latch |= 0x80000; + + if (mach->regs[0xb8] & 0x40) + svga->clock *= 2; + } else { + switch (mach->regs[0xb8] & 0xc0) { + case 0x40: + svga->clock *= 2; + break; + case 0x80: + svga->clock *= 3; + break; + case 0xc0: + svga->clock *= 4; + break; + } + } + + if (mach->regs[0xa7] & 0x80) + svga->clock *= 3; + + if (mach->regs[0xb6] & 0x10) { + svga->hdisp <<= 1; + svga->htotal <<= 1; + svga->rowoffset <<= 1; + svga->gdcreg[5] &= ~0x40; + } + + if (mach->regs[0xb0] & 0x20) { + svga->gdcreg[5] |= 0x40; + } + + if (vga_on && !ibm8514_on) { + if (!svga->scrblank && (svga->crtc[0x17] & 0x80) && svga->attr_palette_enable) { + if ((svga->gdcreg[6] & 1) || (svga->attrregs[0x10] & 1)) { + switch (svga->gdcreg[5] & 0x60) { + case 0x00: + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_4bpp_lowres; + else + svga->render = svga_render_4bpp_highres; + break; + case 0x20: /*4 colours*/ + if (svga->seqregs[1] & 8) /*Low res (320)*/ + svga->render = svga_render_2bpp_lowres; + else + svga->render = svga_render_2bpp_highres; + break; + case 0x40: + case 0x60: /*256+ colours*/ + switch (svga->bpp) { + case 8: + svga->map8 = svga->pallook; + if (svga->lowres) + svga->render = svga_render_8bpp_lowres; + else { + svga->render = svga_render_8bpp_highres; + svga->ma_latch <<= 1; + svga->rowoffset <<= 1; + } + break; + + } + break; + } + } + } + } else if (dev->local) { + if (ibm8514_on) { + svga->hdisp_time = svga->hdisp = (dev->hdisp + 1) << 3; + dev->pitch = (dev->accel.advfunc_cntl & 4) ? 1024 : 640; + svga->htotal = (dev->htotal + 1); + svga->vtotal = (dev->vtotal + 1); + svga->vsyncstart = (dev->vsyncstart + 1); + svga->rowcount = !!(dev->disp_cntl & 0x08); + svga->dispend = ((dev->vdisp >> 1) + 1); + svga->interlace = dev->interlace; + svga->split = 0xffffff; + svga->vblankstart = svga->dispend; + + if (svga->dispend == 766) { + svga->dispend = 768; + svga->vblankstart = svga->dispend; + } + + if (svga->dispend == 598) { + svga->dispend = 600; + svga->vblankstart = svga->dispend; + } + + if (dev->accel.advfunc_cntl & 4) { + if (dev->ibm_mode) { + if (svga->hdisp == 8) { + svga->hdisp = 1024; + svga->dispend = 768; + svga->vtotal = 1536; + svga->vsyncstart = 1536; + } + } + + if (svga->interlace) { + svga->dispend >>= 1; + svga->vsyncstart >>= 2; + svga->vtotal >>= 2; + } else { + svga->vsyncstart >>= 1; + svga->vtotal >>= 1; + } + + dev->pitch = dev->ext_pitch; + svga->rowoffset = dev->ext_crt_pitch; + + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; + } else { + if (dev->ibm_mode) { + if ((svga->hdisp == 1024) && !dev->internal_pitch) { + svga->hdisp = 640; + svga->dispend = 480; + } + } + + if (svga->interlace) { + svga->dispend >>= 1; + svga->vsyncstart >>= 2; + svga->vtotal >>= 2; + } else { + svga->vsyncstart >>= 1; + svga->vtotal >>= 1; + } + + dev->pitch = dev->ext_pitch; + svga->rowoffset = dev->ext_crt_pitch; + + svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0; + } + switch (svga->bpp) { + case 8: + default: + svga->render = svga_render_8bpp_highres; + break; + case 15: + svga->render = svga_render_15bpp_highres; + break; + case 16: + svga->render = svga_render_16bpp_highres; + break; + case 24: + svga->render = svga_render_24bpp_highres; + break; + } + mach_log("BPP=%d, VRAM Mask=%08x, NormalPitch=%d, CRTPitch=%d, VSYNCSTART=%d, VTOTAL=%d, ROWCOUNT=%d, mode=%d, highres bit=%x, has_vga?=%d, override=%d.\n", svga->bpp, svga->vram_mask, dev->pitch, dev->ext_crt_pitch, svga->vsyncstart, svga->vtotal, svga->rowcount, dev->ibm_mode, dev->accel.advfunc_cntl & 4, ibm8514_has_vga, svga->override); + } + mach_log("8514 enabled, hdisp=%d, vtotal=%d, htotal=%d, dispend=%d, rowoffset=%d, split=%d, vsyncstart=%d, split=%08x\n", svga->hdisp, svga->vtotal, svga->htotal, svga->dispend, svga->rowoffset, svga->split, svga->vsyncstart, svga->split); + } +} + +static void +mach_accel_out_fifo(mach_t *mach, svga_t *svga, ibm8514_t *dev, uint16_t port, uint32_t val, int len) +{ + int frgd_sel, bkgd_sel, mono_src; + switch (port) { + case 0x82e8: + case 0xc2e8: + if (len == 1) { + dev->accel.cur_y = (dev->accel.cur_y & 0x700) | val; + } else { + dev->accel.cur_y = val & 0x7ff; + } + break; + case 0x82e9: + case 0xc2e9: + if (len == 1) { + dev->accel.cur_y = (dev->accel.cur_y & 0xff) | ((val & 0x07) << 8); + } + break; + + case 0x86e8: + case 0xc6e8: + if (len == 1) { + dev->accel.cur_x = (dev->accel.cur_x & 0x700) | val; + } else { + dev->accel.cur_x = val & 0x7ff; + } + break; + case 0x86e9: + case 0xc6e9: + if (len == 1) { + dev->accel.cur_x = (dev->accel.cur_x & 0xff) | ((val & 0x07) << 8); + } + break; + + case 0x8ae8: + case 0xcae8: + if (len == 1) + dev->accel.desty_axstp = (dev->accel.desty_axstp & 0x3f00) | val; + else { + mach->accel.src_y = val; + dev->accel.desty_axstp = val & 0x3fff; + if (val & 0x2000) + dev->accel.desty_axstp |= ~0x1fff; + } + break; + case 0x8ae9: + case 0xcae9: + if (len == 1) { + dev->accel.desty_axstp = (dev->accel.desty_axstp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + dev->accel.desty_axstp |= ~0x1fff; + } + break; + + case 0x8ee8: + case 0xcee8: + if (len == 1) + dev->accel.destx_distp = (dev->accel.destx_distp & 0x3f00) | val; + else { + mach->accel.src_x = val; + dev->accel.destx_distp = val & 0x3fff; + if (val & 0x2000) + dev->accel.destx_distp |= ~0x1fff; + } + break; + case 0x8ee9: + case 0xcee9: + if (len == 1) { + dev->accel.destx_distp = (dev->accel.destx_distp & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + dev->accel.destx_distp |= ~0x1fff; + } + break; + + case 0x92e8: + if (len != 1) + dev->test = val; + case 0xd2e8: + mach_log("92E8 = %04x\n", val); + if (len == 1) + dev->accel.err_term = (dev->accel.err_term & 0x3f00) | val; + else { + dev->accel.err_term = val & 0x3fff; + if (val & 0x2000) + dev->accel.err_term |= ~0x1fff; + } + break; + case 0x92e9: + case 0xd2e9: + if (len == 1) { + dev->accel.err_term = (dev->accel.err_term & 0xff) | ((val & 0x3f) << 8); + if (val & 0x20) + dev->accel.err_term |= ~0x1fff; + } + break; + + case 0x96e8: + case 0xd6e8: + if (len == 1) + dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0x0700) | val; + else { + mach->accel.test = val & 0x1fff; + dev->accel.maj_axis_pcnt = val & 0x07ff; + } + break; + case 0x96e9: + case 0xd6e9: + if (len == 1) { + dev->accel.maj_axis_pcnt = (dev->accel.maj_axis_pcnt & 0xff) | ((val & 0x07) << 8); + } + break; + + case 0x9ae8: + case 0xdae8: + dev->accel.ssv_state = 0; + if (len == 1) + dev->accel.cmd = (dev->accel.cmd & 0xff00) | val; + else { + dev->data_available = 0; + dev->data_available2 = 0; + dev->accel.cmd = val; + mach_log("CMD8514 = %04x.\n", val); + mach->accel.cmd_type = -1; + if (port == 0xdae8) { + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + } + ibm8514_accel_start(-1, 0, -1, 0, svga, len); + } + break; + case 0x9ae9: + case 0xdae9: + if (len == 1) { + dev->data_available = 0; + dev->data_available2 = 0; + dev->accel.cmd = (dev->accel.cmd & 0xff) | (val << 8); + mach->accel.cmd_type = -1; + if (port == 0xdae9) { + if (dev->accel.cmd & 0x100) + dev->accel.cmd_back = 0; + } + ibm8514_accel_start(-1, 0, -1, 0, svga, len); + } + break; + + case 0x9ee8: + case 0xdee8: + dev->accel.ssv_state = 1; + if (len == 1) + dev->accel.short_stroke = (dev->accel.short_stroke & 0xff00) | val; + else { + dev->accel.short_stroke = val; + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x >= 0x600) { + dev->accel.cx |= ~0x5ff; + } + if (dev->accel.cur_y >= 0x600) { + dev->accel.cy |= ~0x5ff; + } + + if (dev->accel.cmd & 0x1000) { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + } else { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + } + } + break; + case 0x9ee9: + case 0xdee9: + if (len == 1) { + dev->accel.short_stroke = (dev->accel.short_stroke & 0xff) | (val << 8); + dev->accel.cx = dev->accel.cur_x; + dev->accel.cy = dev->accel.cur_y; + + if (dev->accel.cur_x >= 0x600) { + dev->accel.cx |= ~0x5ff; + } + if (dev->accel.cur_y >= 0x600) { + dev->accel.cy |= ~0x5ff; + } + + if (dev->accel.cmd & 0x1000) { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + } else { + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke >> 8, len); + ibm8514_short_stroke_start(-1, 0, -1, 0, svga, dev->accel.short_stroke & 0xff, len); + } + } + break; + + case 0xa2e8: + case 0xe2e8: + if (port == 0xe2e8) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; + else + dev->accel.bkgd_color = val; + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[1] = val; + } + } else { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach_accel_out_pixtrans(mach, dev, port, val, len); + } else { + if (ibm8514_cpu_dest(svga)) + break; + ibm8514_accel_out_pixtrans(svga, port, val, len); + } + } + } + } else { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0x00ff) | val; + else + dev->accel.bkgd_color = val; + } + break; + case 0xa2e9: + case 0xe2e9: + if (port == 0xe2e9) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[0] = val; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev, len); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + break; + } + } + } + } + } else { + if (len == 1) + dev->accel.bkgd_color = (dev->accel.bkgd_color & 0xff00) | (val << 8); + } + break; + + case 0xa6e8: + case 0xe6e8: + if (port == 0xe6e8) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; + else + dev->accel.frgd_color = val; + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[1] = val; + } + } else { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach_accel_out_pixtrans(mach, dev, port, val, len); + } else { + if (ibm8514_cpu_dest(svga)) + break; + ibm8514_accel_out_pixtrans(svga, port, val, len); + } + } + } + } else { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0x00ff) | val; + else + dev->accel.frgd_color = val; + } + break; + case 0xa6e9: + case 0xe6e9: + if (port == 0xe6e9) { + if (dev->accel.cmd_back) { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); + } else { + if (len == 1) { + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) + break; + mach->accel.pix_trans[0] = val; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev, len); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + break; + } + } + } + } + } else { + if (len == 1) + dev->accel.frgd_color = (dev->accel.frgd_color & 0xff00) | (val << 8); + } + break; + + case 0xaae8: + case 0xeae8: + if (len == 1) + dev->accel.wrt_mask = (dev->accel.wrt_mask & 0x00ff) | val; + else + dev->accel.wrt_mask = val; + break; + case 0xaae9: + case 0xeae9: + if (len == 1) + dev->accel.wrt_mask = (dev->accel.wrt_mask & 0xff00) | (val << 8); + break; + + case 0xaee8: + case 0xeee8: + if (len == 1) + dev->accel.rd_mask = (dev->accel.rd_mask & 0x00ff) | val; + else + dev->accel.rd_mask = val; + break; + case 0xaee9: + case 0xeee9: + if (len == 1) + dev->accel.rd_mask = (dev->accel.rd_mask & 0xff00) | (val << 8); + break; + + case 0xb2e8: + case 0xf2e8: + if (len == 1) + dev->accel.color_cmp = (dev->accel.color_cmp & 0x00ff) | val; + else + dev->accel.color_cmp = val; + break; + case 0xb2e9: + case 0xf2e9: + if (len == 1) + dev->accel.color_cmp = (dev->accel.color_cmp & 0xff00) | (val << 8); + break; + + case 0xb6e8: + case 0xf6e8: + dev->accel.bkgd_mix = val & 0xff; + break; + + case 0xbae8: + case 0xfae8: + dev->accel.frgd_mix = val & 0xff; + break; + + case 0xbee8: + case 0xfee8: + if (len == 1) + dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff00) | val; + else { + dev->accel.multifunc_cntl = val; + dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; + if ((dev->accel.multifunc_cntl >> 12) == 1) { + dev->accel.clip_top = val & 0x7ff; + } + if ((dev->accel.multifunc_cntl >> 12) == 2) { + dev->accel.clip_left = val & 0x7ff; + } + if ((dev->accel.multifunc_cntl >> 12) == 3) { + dev->accel.multifunc[3] = val & 0x7ff; + } + if ((dev->accel.multifunc_cntl >> 12) == 4) { + dev->accel.multifunc[4] = val & 0x7ff; + } + mach_log("CLIPBOTTOM=%d, CLIPRIGHT=%d, bpp=%d, pitch=%d.\n", dev->accel.multifunc[3], dev->accel.multifunc[4], svga->bpp, dev->pitch); + if ((dev->accel.multifunc_cntl >> 12) == 5) { + if (!dev->local || !dev->ext_crt_pitch) + dev->ext_crt_pitch = 128; + svga_recalctimings(svga); + } + if (port == 0xfee8) + dev->accel.cmd_back = 1; + else + dev->accel.cmd_back = 0; + } + break; + case 0xbee9: + case 0xfee9: + if (len == 1) { + dev->accel.multifunc_cntl = (dev->accel.multifunc_cntl & 0xff) | (val << 8); + dev->accel.multifunc[dev->accel.multifunc_cntl >> 12] = dev->accel.multifunc_cntl & 0xfff; + if ((dev->accel.multifunc_cntl >> 12) == 1) { + dev->accel.clip_top = dev->accel.multifunc_cntl & 0x7ff; + } + if ((dev->accel.multifunc_cntl >> 12) == 2) { + dev->accel.clip_left = dev->accel.multifunc_cntl & 0x7ff; + } + if ((dev->accel.multifunc_cntl >> 12) == 5) { + if (!dev->local || !dev->ext_crt_pitch) + dev->ext_crt_pitch = 128; + svga_recalctimings(svga); + } + if (port == 0xfee9) + dev->accel.cmd_back = 1; + else + dev->accel.cmd_back = 0; + } + break; + +/*ATI Mach8/32 specific registers*/ + case 0x82ee: + mach->accel.patt_data_idx = val & 0x1f; + mach_log("Pattern Data Index = %d.\n", val & 0x1f); + break; + + case 0x8eee: + if (len == 1) { + mach->accel.patt_data[mach->accel.patt_data_idx] = val; + } else { + mach->accel.patt_data[mach->accel.patt_data_idx] = val & 0xff; + mach->accel.patt_data[mach->accel.patt_data_idx + 1] = (val >> 8) & 0xff; + if (mach->accel.mono_pattern_enable) + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 0x17; + else { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + mono_src = (mach->accel.dp_config >> 5) & 3; + if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + mach->accel.patt_data_idx += 2; + dev->accel.y1 = 1; + } else { + if (svga->bpp == 24) + mach->accel.patt_data_idx += 2; + else + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; + + } + mach_log("ExtCONFIG = %04x, Pattern Mono = %04x, selidx = %d, dataidx = %d, bit 0 = %02x len = %d.\n", mach->accel.ext_ge_config, val, mach->accel.patt_idx, mach->accel.patt_data_idx, val & 1, mach->accel.patt_len); + } + } + break; + case 0x8eef: + if (len == 1) { + mach->accel.patt_data[mach->accel.patt_data_idx + 1] = val; + if (mach->accel.mono_pattern_enable) + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & 7; + else { + frgd_sel = (mach->accel.dp_config >> 13) & 7; + if ((svga->bpp == 24) && (mach->accel.patt_len == 0x17) && (frgd_sel == 5)) { + mach->accel.patt_data_idx += 2; + dev->accel.y1 = 1; + } else + mach->accel.patt_data_idx = (mach->accel.patt_data_idx + 2) & mach->accel.patt_len; + } + } + break; + + case 0x96ee: + if (len == 1) + mach->accel.bres_count = (mach->accel.bres_count & 0x700) | val; + else { + mach->accel.bres_count = val & 0x7ff; + mach_log("96EE line draw.\n"); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 1; + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + } + break; + case 0x96ef: + if (len == 1) { + mach->accel.bres_count = (mach->accel.bres_count & 0xff) | ((val & 0x07) << 8); + mach_log("96EE (2) line draw.\n"); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 1; + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + } + break; + + case 0x9aee: + mach->accel.line_idx = val & 0x07; + break; + + case 0xa2ee: + mach_log("Line OPT = %04x\n", val); + if (len == 1) + mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0xff00) | val; + else { + mach->accel.linedraw_opt = val; + } + break; + case 0xa2ef: + if (len == 1) { + mach->accel.linedraw_opt = (mach->accel.linedraw_opt & 0x00ff) | (val << 8); + } + break; + + case 0xa6ee: + if (len == 1) + mach->accel.dest_x_start = (mach->accel.dest_x_start & 0x700) | val; + else + mach->accel.dest_x_start = val & 0x7ff; + break; + case 0xa6ef: + if (len == 1) + mach->accel.dest_x_start = (mach->accel.dest_x_start & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xaaee: + if (len == 1) + mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x700) | val; + else { + mach->accel.dest_x_end = val & 0x7ff; + } + break; + case 0xaaef: + if (len == 1) + mach->accel.dest_x_end = (mach->accel.dest_x_end & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xaeee: + mach_log("AEEE write val = %04x.\n", val); + if (len == 1) + mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x700) | val; + else { + mach->accel.dest_y_end = val & 0x7ff; + if ((val + 1) == 0x10000) { + mach_log("Dest_Y_end overflow val = %04x\n", val); + mach->accel.dest_y_end = 0; + } + dev->data_available = 0; + dev->data_available2 = 0; + mach_log("BitBLT = %04x.\n", mach->accel.dp_config); + mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + } + break; + case 0xaeef: + if (len == 1) { + mach->accel.dest_y_end = (mach->accel.dest_y_end & 0x0ff) | ((val & 0x07) << 8); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 2; /*Non-conforming BitBLT from dest_y_end register (0xaeee)*/ + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + } + break; + + case 0xb2ee: + if (len == 1) + mach->accel.src_x_start = (mach->accel.src_x_start & 0x700) | val; + else + mach->accel.src_x_start = val & 0x7ff; + break; + case 0xb2ef: + if (len == 1) + mach->accel.src_x_start = (mach->accel.src_x_start & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xb6ee: + dev->accel.bkgd_mix = val & 0xff; + break; + + case 0xbaee: + dev->accel.frgd_mix = val & 0xff; + break; + + case 0xbeee: + if (len == 1) + mach->accel.src_x_end = (mach->accel.src_x_end & 0x700) | val; + else { + mach->accel.src_x_end = val & 0x7ff; + } + break; + case 0xbeef: + if (len == 1) + mach->accel.src_x_end = (mach->accel.src_x_end & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xc2ee: + mach->accel.src_y_dir = val & 1; + break; + + case 0xc6ee: + mach->accel.cmd_type = 0; + mach_log("TODO: Short Stroke.\n"); + break; + + case 0xcaee: + mach_log("CAEE write val = %04x.\n", val); + if (len == 1) + mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x700) | val; + else { + mach->accel.scan_to_x = (val & 0x7ff); + if ((val + 1) == 0x10000) { + mach_log("Scan_to_X overflow val = %04x\n", val); + mach->accel.scan_to_x = 0; + } + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ + mach_log("ScanToX = %04x.\n", mach->accel.dp_config); + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + } + break; + case 0xcaef: + if (len == 1) { + mach->accel.scan_to_x = (mach->accel.scan_to_x & 0x0ff) | ((val & 0x07) << 8); + dev->data_available = 0; + dev->data_available2 = 0; + mach->accel.cmd_type = 5; /*Horizontal Raster Draw from scan_to_x register (0xcaee)*/ + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + } + break; + + case 0xceee: + mach_log("CEEE write val = %04x.\n", val); + if (len == 1) + mach->accel.dp_config = (mach->accel.dp_config & 0xff00) | val; + else { + mach->accel.dp_config = val; + } + break; + case 0xceef: + if (len == 1) { + mach->accel.dp_config = (mach->accel.dp_config & 0x00ff) | (val << 8); + } + break; + + case 0xd2ee: + mach->accel.patt_len = val & 0x1f; + mach_log("Pattern Length = %d, val = %04x.\n", val & 0x1f, val); + mach->accel.mono_pattern_enable = !!(val & 0x80); + if (len != 1) { + mach->accel.patt_len_reg = val; + } else { + mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0xff00) | val; + } + break; + case 0xd2ef: + if (len == 1) + mach->accel.patt_len_reg = (mach->accel.patt_len_reg & 0x00ff) | (val << 8); + break; + + case 0xd6ee: + mach->accel.patt_idx = val & 0x1f; + mach_log("Pattern Index = %d, val = %02x.\n", val & 0x1f, val); + break; + + case 0xdaee: + mach_log("DAEE (extclipl) write val = %d\n", val); + if (len == 1) + dev->accel.clip_left = (dev->accel.clip_left & 0x700) | val; + else { + dev->accel.clip_left = val & 0x7ff; + } + break; + case 0xdaef: + if (len == 1) + dev->accel.clip_left = (dev->accel.clip_left & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xdeee: + mach_log("DEEE (extclipt) write val = %d\n", val); + if (len == 1) + dev->accel.clip_top = (dev->accel.clip_top & 0x700) | val; + else { + dev->accel.clip_top = val & 0x7ff; + } + break; + case 0xdeef: + if (len == 1) + dev->accel.clip_top = (dev->accel.clip_top & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xe2ee: + mach_log("E2EE (extclipr) write val = %d\n", val); + if (len == 1) + dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x700) | val; + else { + dev->accel.multifunc[4] = val & 0x7ff; + } + break; + case 0xe2ef: + if (len == 1) + dev->accel.multifunc[4] = (dev->accel.multifunc[4] & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xe6ee: + mach_log("E6EE (extclipb) write val = %d\n", val); + if (len == 1) + dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x700) | val; + else { + dev->accel.multifunc[3] = val & 0x7ff; + } + break; + case 0xe6ef: + if (len == 1) + dev->accel.multifunc[3] = (dev->accel.multifunc[3] & 0x0ff) | ((val & 0x07) << 8); + break; + + case 0xeeee: + if (len == 1) + mach->accel.dest_cmp_fn = (mach->accel.dest_cmp_fn & 0xff00) | val; + else + mach->accel.dest_cmp_fn = val; + break; + case 0xeeef: + if (len == 1) + mach->accel.dest_cmp_fn = (mach->accel.dest_cmp_fn & 0x00ff) | (val << 8); + break; + + case 0xf2ee: + mach_log("F2EE.\n"); + if (len == 1) + mach->accel.dst_clr_cmp_mask = (mach->accel.dst_clr_cmp_mask & 0xff00) | val; + else + mach->accel.dst_clr_cmp_mask = val; + break; + case 0xf2ef: + if (len == 1) + mach->accel.dst_clr_cmp_mask = (mach->accel.dst_clr_cmp_mask & 0x00ff) | (val << 8); + break; + + case 0xfeee: + if (mach->accel.dp_config == 0x2231 || mach->accel.dp_config == 0x2211) + mach_log("FEEE val = %d, lineidx = %d, DPCONFIG = %04x, CPUCX = %04x.\n", val, mach->accel.line_idx, mach->accel.dp_config, CX); + if (len != 1) { + mach->accel.line_array[mach->accel.line_idx] = val; + dev->accel.cur_x = mach->accel.line_array[(mach->accel.line_idx == 4) ? 4 : 0]; + dev->accel.cur_y = mach->accel.line_array[(mach->accel.line_idx == 5) ? 5 : 1]; + mach->accel.cx_end_line = mach->accel.line_array[2]; + mach->accel.cy_end_line = mach->accel.line_array[3]; + if ((mach->accel.line_idx == 3) || (mach->accel.line_idx == 5)) { + mach->accel.cmd_type = (mach->accel.line_idx == 5) ? 4 : 3; + mach_accel_start(mach->accel.cmd_type, 0, -1, -1, 0, mach, dev, len); + mach->accel.line_idx = (mach->accel.line_idx == 5) ? 4 : 2; + break; + } + mach->accel.line_idx++; + } + break; + } +} + +static void +mach_accel_out(uint16_t port, uint32_t val, mach_t *mach, int len) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; + + mach_log("Port accel out = %04x, val = %04x, len = %d.\n", port, val, len); + + if (port & 0x8000) { + mach_accel_out_fifo(mach, svga, dev, port, val, len); + } else { + switch (port) { + case 0x2e8: + if (len == 1) + dev->htotal = (dev->htotal & 0xff00) | val; + else { + dev->htotal = val; + svga_recalctimings(svga); + } + break; + case 0x2e9: + if (len != 1) { + dev->htotal = (dev->htotal & 0xff) | (val << 8); + mach_log("ATI 8514/A: H_TOTAL write 02E8 = %d\n", dev->htotal + 1); + svga_recalctimings(svga); + } + break; + + case 0x6e8: + dev->hdisp = val; + mach_log("ATI 8514/A: H_DISP write 06E8 = %d\n", dev->hdisp + 1); + svga_recalctimings(svga); + break; + + case 0xae8: + mach_log("ATI 8514/A: H_SYNC_STRT write 0AE8 = %d\n", val + 1); + svga_recalctimings(svga); + break; + + case 0xee8: + mach_log("ATI 8514/A: H_SYNC_WID write 0EE8 = %d\n", val + 1); + svga_recalctimings(svga); + break; + + case 0x12e8: + if (len == 1) + dev->vtotal = (dev->vtotal & 0x1f00) | val; + else { + dev->vtotal = val & 0x1fff; + svga_recalctimings(svga); + } + break; + case 0x12e9: + if (len == 1) { + dev->vtotal = (dev->vtotal & 0xff) | ((val & 0x1f) << 8); + mach_log("ATI 8514/A: V_TOTAL write 12E8 = %d\n", dev->vtotal); + svga_recalctimings(svga); + } + break; + + case 0x16e8: + if (len == 1) + dev->vdisp = (dev->vdisp & 0x1f00) | val; + else { + dev->vdisp = val & 0x1fff; + svga_recalctimings(svga); + } + break; + case 0x16e9: + if (len == 1) { + dev->vdisp = (dev->vdisp & 0xff) | ((val & 0x1f) << 8); + mach_log("ATI 8514/A: V_DISP write 16E8 = %d\n", dev->vdisp); + svga_recalctimings(svga); + } + break; + + case 0x1ae8: + if (len == 1) + dev->vsyncstart = (dev->vsyncstart & 0x1f00) | val; + else { + dev->vsyncstart = val & 0x1fff; + svga_recalctimings(svga); + } + break; + case 0x1ae9: + if (len == 1) { + dev->vsyncstart = (dev->vsyncstart & 0xff) | ((val & 0x1f) << 8); + mach_log("ATI 8514/A: V_SYNC_STRT write 1AE8 = %d\n", dev->vsyncstart); + svga_recalctimings(svga); + } + break; + + case 0x1ee8: + dev->vsyncwidth = val; + mach_log("ATI 8514/A: V_SYNC_WID write 1EE8 = %02x\n", val); + svga_recalctimings(svga); + break; + + case 0x22e8: + dev->disp_cntl = val & 0x7e; + dev->interlace = !!(val & 0x10); + mach_log("ATI 8514/A: DISP_CNTL write 22E8 = %02x, SCANMODULOS = %d\n", dev->disp_cntl, dev->scanmodulos); + svga_recalctimings(svga); + break; + + case 0x42e8: + if (len == 1) { + dev->subsys_stat &= ~val; + } else { + dev->subsys_stat &= ~(val & 0xff); + dev->subsys_cntl = (val >> 8); + mach_log("CNTL = %02x.\n", val >> 8); + } + break; + case 0x42e9: + if (len == 1) { + dev->subsys_cntl = val; + mach_log("CNTL = %02x.\n", val); + } + break; + + case 0x4ae8: + mach_log("ATI 8514/A: VGA ON (0x4ae8) = %i, val = %02x\n", vga_on, val); + if (!val) + break; + if (!dev->local || !dev->ext_crt_pitch) + dev->ext_crt_pitch = 128; + dev->accel.advfunc_cntl = val & 7; + ibm8514_on = (dev->accel.advfunc_cntl & 1); + vga_on = !ibm8514_on; + dev->ibm_mode = 1; + if (ibm8514_on) + svga->adv_flags |= FLAG_ATI; + else + svga->adv_flags &= ~FLAG_ATI; + svga_recalctimings(svga); + break; + + /*ATI Mach8/32 specific registers*/ + case 0x6ee: + mach_log("6EE write val = %02x, len = %d.\n", val, len); + break; + + case 0x6ef: + mach_log("6EF write val = %02x, len = %d.\n", val, len); + break; + + case 0xaee: + if (len == 1) + mach->cursor_offset_lo = (mach->cursor_offset_lo & 0xff00) | val; + else { + mach_log("AEE val=%02x.\n", val); + mach->cursor_offset_lo = val; + svga->hwcursor.addr = mach->cursor_offset_lo << 2; + } + break; + case 0xaef: + if (len == 1) { + mach->cursor_offset_lo = (mach->cursor_offset_lo & 0x00ff) | (val << 8); + svga->hwcursor.addr = mach->cursor_offset_lo << 2; + } + break; + + case 0xeee: + mach->cursor_offset_hi = val & 0x0f; + if (len != 1) { + svga->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16))) << 2; + svga->hwcursor.ena = !!(val & 0x8000); + } + mach_log("EEE val=%08x.\n", svga->hwcursor.addr); + break; + case 0xeef: + if (len == 1) { + svga->hwcursor.addr = ((mach->cursor_offset_lo | (mach->cursor_offset_hi << 16))) << 2; + svga->hwcursor.ena = !!(val & 0x80); + } + break; + + case 0x12ee: + if (len == 1) { + svga->hwcursor.x = (svga->hwcursor.x & 0x700) | val; + } else { + svga->hwcursor.x = val & 0x7ff; + mach_log("X = %03x.\n", val); + } + break; + case 0x12ef: + if (len == 1) { + svga->hwcursor.x = (svga->hwcursor.x & 0x0ff) | ((val & 0x07) << 8); + } + break; + + case 0x16ee: + if (len == 1) { + svga->hwcursor.y = (svga->hwcursor.y & 0xf00) | val; + } else { + svga->hwcursor.y = val & 0xfff; + } + break; + case 0x16ef: + if (len == 1) { + svga->hwcursor.y = (svga->hwcursor.y & 0x0ff) | ((val & 0x0f) << 8); + } + break; + + case 0x1aee: + if (len != 1) { + mach->cursor_col_0 = val & 0xff; + mach->cursor_col_1 = (val >> 8) & 0xff; + } else + mach->cursor_col_0 = val; + break; + case 0x1aef: + if (len == 1) + mach->cursor_col_1 = val; + break; + + case 0x1eee: + if (len != 1) { + svga->hwcursor.xoff = val & 0x3f; + svga->hwcursor.yoff = (val >> 8) & 0x3f; + } else + svga->hwcursor.xoff = val & 0x3f; + break; + case 0x1eef: + if (len == 1) + svga->hwcursor.yoff = val & 0x3f; + break; + + case 0x2aee: + mach_log("2AEE write val = %04x\n", val); + if (len == 1) + mach->accel.crt_offset_lo = (mach->accel.crt_offset_lo & 0xff00) | val; + else + mach->accel.crt_offset_lo = val; + break; + case 0x2aef: + if (len == 1) + mach->accel.crt_offset_lo = (mach->accel.crt_offset_lo & 0x00ff) | (val << 8); + break; + + case 0x2eee: + mach_log("2EEE write val = %04x\n", val); + if (len == 1) + mach->accel.crt_offset_hi = (mach->accel.crt_offset_hi & 0xff00) | val; + else + mach->accel.crt_offset_hi = val; + break; + case 0x2eef: + if (len == 1) + mach->accel.crt_offset_hi = (mach->accel.crt_offset_hi & 0x00ff) | (val << 8); + break; + + case 0x26ee: + mach_log("CRT Pitch = %d, original val = %d.\n", val << 3, val); + dev->ext_crt_pitch = val; + dev->internal_pitch = val; + if (svga->bpp > 8) { + if (svga->bpp == 24) + dev->ext_crt_pitch *= 3; + else + dev->ext_crt_pitch <<= 1; + } + if (dev->local) { + if (!ibm8514_on) { + ibm8514_on ^= 1; + svga->adv_flags |= FLAG_ATI; + } + } + svga_recalctimings(svga); + break; + + case 0x32ee: + if (len == 1) { + mach->local_cntl = (mach->local_cntl & 0xff00) | val; + } else { + mach->local_cntl = val; + mach32_updatemapping(mach); + } + break; + + case 0x32ef: + if (len == 1) { + mach->local_cntl = (mach->local_cntl & 0x00ff) | (val << 8); + mach32_updatemapping(mach); + } + break; + + case 0x36ee: + if (len == 1) { + mach->misc = (mach->misc & 0xff00) | (val); + } else { + mach->misc = val; + } + break; + case 0x36ef: + if (len == 1) { + mach->misc = (mach->misc & 0x00ff) | (val << 8); + } + break; + + case 0x3aee: + if (len == 1) { + mach->ext_cur_col_0_g = val; + } else { + mach->ext_cur_col_0_g = val & 0xff; + mach->ext_cur_col_0_r = (val >> 8) & 0xff; + } + break; + case 0x3aef: + if (len == 1) { + mach->ext_cur_col_0_r = val; + } + break; + + case 0x3eee: + if (len == 1) { + mach->ext_cur_col_1_g = val; + } else { + mach->ext_cur_col_1_g = val & 0xff; + mach->ext_cur_col_1_r = (val >> 8) & 0xff; + } + break; + case 0x3eef: + if (len == 1) { + mach->ext_cur_col_1_r = val; + } + break; + + case 0x42ee: + mach->accel.test2[0] = val; + break; + case 0x42ef: + mach->accel.test2[1] = val; + break; + + case 0x46ee: + mach->accel.test3[0] = val; + break; + case 0x46ef: + mach->accel.test3[1] = val; + break; + + case 0x4aee: + if (len == 1) + mach->accel.clock_sel = (mach->accel.clock_sel & 0xff00) | val; + else { + mach->accel.clock_sel = val; + ibm8514_on = (mach->accel.clock_sel & 1); + vga_on = !ibm8514_on; + dev->ibm_mode = 0; + if (ibm8514_on) + svga->adv_flags |= FLAG_ATI; + else + svga->adv_flags &= ~FLAG_ATI; + mach_log("ATI 8514/A: VGA ON (0x4aee) = %i, val = %04x\n", vga_on, val); + svga_recalctimings(svga); + } + break; + case 0x4aef: + if (len == 1) { + mach->accel.clock_sel = (mach->accel.clock_sel & 0x00ff) | (val << 8); + ibm8514_on = (mach->accel.clock_sel & 1); + vga_on = !ibm8514_on; + dev->ibm_mode = 0; + if (ibm8514_on) + svga->adv_flags |= FLAG_ATI; + else + svga->adv_flags &= ~FLAG_ATI; + mach_log("ATI 8514/A: VGA ON (0x4aef) = %i, val = %04x\n", vga_on, mach->accel.clock_sel); + svga_recalctimings(svga); + } + break; + + case 0x52ee: + if (len == 1) + mach->accel.scratch0 = (mach->accel.scratch0 & 0xff00) | val; + else + mach->accel.scratch0 = val; + break; + case 0x52ef: + if (len == 1) + mach->accel.scratch0 = (mach->accel.scratch0 & 0x00ff) | (val << 8); + break; + + case 0x56ee: + if (len == 1) + mach->accel.scratch1 = (mach->accel.scratch1 & 0xff00) | val; + else + mach->accel.scratch1 = val; + break; + case 0x56ef: + if (len == 1) + mach->accel.scratch1 = (mach->accel.scratch1 & 0x00ff) | (val << 8); + break; + + case 0x5aee: + mach_log("Shadow set = %04x\n", val); + break; + case 0x5aef: + mach_log("Shadow + 1 set = %02x\n", val); + break; + + case 0x5eee: + mach_log("Memory Aperture = %04x, len = %d.\n", val, len); + if (len == 1) { + mach->memory_aperture = (mach->memory_aperture & 0xff00) | val; + } else { + mach->memory_aperture = val; + if (!mach->pci_bus) + mach->linear_base = (mach->memory_aperture & 0xff00) << 12; + + mach32_updatemapping(mach); + } + break; + + case 0x5eef: + if (len == 1) { + mach->memory_aperture = (mach->memory_aperture & 0x00ff) | (val << 8); + if (!mach->pci_bus) + mach->linear_base = (mach->memory_aperture & 0xff00) << 12; + + mach32_updatemapping(mach); + } + break; + + case 0x62ee: + mach_log("62EE write val = %04x, len = %d.\n", val, len); + break; + + case 0x66ee: + mach_log("66EE write val = %04x, len = %d.\n", val, len); + break; + + case 0x6aee: + mach_log("6AEE write val = %04x.\n", val & 0x400); + if (len == 1) + mach->accel.max_waitstates = (mach->accel.max_waitstates & 0xff00) | val; + else { + mach->accel.max_waitstates = val; + } + break; + case 0x6aef: + if (len == 1) + mach->accel.max_waitstates = (mach->accel.max_waitstates & 0x00ff) | (val << 8); + break; + + case 0x6eee: + mach_log("6EEE write val = %04x\n", val); + if (len == 1) + mach->accel.ge_offset_lo = (mach->accel.ge_offset_lo & 0xff00) | val; + else { + mach->accel.ge_offset_lo = val; + dev->accel.ge_offset = mach->accel.ge_offset_lo; + } + break; + case 0x6eef: + if (len == 1) { + mach->accel.ge_offset_lo = (mach->accel.ge_offset_lo & 0x00ff) | (val << 8); + dev->accel.ge_offset = mach->accel.ge_offset_lo; + } + break; + + case 0x72ee: + mach_log("72EE write val = %04x\n", val); + if (len == 1) + mach->accel.ge_offset_hi = (mach->accel.ge_offset_hi & 0xff00) | val; + else { + mach->accel.ge_offset_hi = val; + dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); + } + break; + case 0x72ef: + if (len == 1) { + mach->accel.ge_offset_hi = (mach->accel.ge_offset_hi & 0x00ff) | (val << 8); + dev->accel.ge_offset = mach->accel.ge_offset_lo | (mach->accel.ge_offset_hi << 16); + } + break; + + case 0x76ee: + mach_log("76EE write val=%d shifted, normal=%d.\n", val << 3, val); + dev->ext_pitch = val << 3; + svga_recalctimings(svga); + break; + + case 0x7aee: + mach_log("7AEE write val = %04x, len = %d.\n", val, len); + if (len == 1) + mach->accel.ext_ge_config = (mach->accel.ext_ge_config & 0xff00) | val; + else { + mach->accel.ext_ge_config = val; + dev->ext_crt_pitch = dev->internal_pitch; + switch (mach->accel.ext_ge_config & 0x30) { + case 0: + case 0x10: + svga->bpp = 8; + break; + case 0x20: + if ((mach->accel.ext_ge_config & 0xc0) == 0x40) + svga->bpp = 16; + else + svga->bpp = 15; + + dev->ext_crt_pitch <<= 1; + break; + case 0x30: + svga->bpp = 24; + dev->ext_crt_pitch *= 3; + break; + } + if (mach->accel.ext_ge_config & 0x800) { + svga_recalctimings(svga); + } + if (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)) + svga_recalctimings(svga); + } + break; + case 0x7aef: + mach_log("7AEF write val = %02x.\n", val); + if (len == 1) { + mach->accel.ext_ge_config = (mach->accel.ext_ge_config & 0x00ff) | (val << 8); + dev->ext_crt_pitch = dev->internal_pitch; + switch (mach->accel.ext_ge_config & 0x30) { + case 0: + case 0x10: + svga->bpp = 8; + break; + case 0x20: + if ((mach->accel.ext_ge_config & 0xc0) == 0x40) + svga->bpp = 16; + else + svga->bpp = 15; + + dev->ext_crt_pitch <<= 1; + break; + case 0x30: + svga->bpp = 24; + dev->ext_crt_pitch *= 3; + break; + } + if (mach->accel.ext_ge_config & 0x800) { + svga_recalctimings(svga); + } + if (!(mach->accel.ext_ge_config & 0x8000) && !(mach->accel.ext_ge_config & 0x800)) + svga_recalctimings(svga); + } + break; + + case 0x7eee: + mach->accel.eeprom_control = val; + break; + } + } +} + +static uint32_t +mach_accel_in(uint16_t port, mach_t *mach, int len) +{ + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; + uint16_t *vram_w = (uint16_t *) svga->vram; + uint16_t temp = 0; + int cmd; + int vpos = dev->displine + svga->y_add; + int vblankend = svga->vblankstart + svga->crtc[0x16]; + int frgd_sel, bkgd_sel, mono_src; + + switch (port) { + case 0x2e8: + if (dev->local) { + vpos = svga->displine + svga->y_add; + if (vblankend > svga->vtotal) { + vblankend -= svga->vtotal; + if (vpos >= svga->vblankstart || vpos <= vblankend) + temp |= 2; + } else { + if (vpos >= svga->vblankstart && vpos <= vblankend) + temp |= 2; + } + } else { + vpos = dev->displine + svga->y_add; + if (vblankend > dev->vtotal) { + vblankend -= dev->vtotal; + if (vpos >= svga->vblankstart || vpos <= vblankend) + temp |= 2; + } else { + if (vpos >= svga->vblankstart && vpos <= vblankend) + temp |= 2; + } + } + break; + + case 0x6e8: + temp = dev->hdisp; + break; + + case 0x22e8: + temp = dev->disp_cntl; + break; + + case 0x26e8: + if (len == 1) + temp = dev->htotal & 0xff; + else + temp = dev->htotal; + break; + case 0x26e9: + if (len == 1) + temp = dev->htotal >> 8; + break; + + case 0x2ee8: + temp = dev->subsys_cntl; + break; + + case 0x42e8: + if (dev->local) { + vpos = svga->displine + svga->y_add; + if (vblankend > svga->vtotal) { + vblankend -= svga->vtotal; + if (vpos >= svga->vblankstart || vpos <= vblankend) + dev->subsys_stat |= 1; + } else { + if (vpos >= svga->vblankstart && vpos <= vblankend) + dev->subsys_stat |= 1; + } + } else { + vpos = dev->displine + svga->y_add; + if (vblankend > dev->vtotal) { + vblankend -= dev->vtotal; + if (vpos >= svga->vblankstart || vpos <= vblankend) + dev->subsys_stat |= 1; + } else { + if (vpos >= svga->vblankstart && vpos <= vblankend) + dev->subsys_stat |= 1; + } + } + + if (len != 1) { + temp = dev->subsys_stat | 0xa0 | 0x8000; + } else { + temp = dev->subsys_stat | 0xa0; + } + break; + + case 0x4ae8: + temp = dev->accel.advfunc_cntl; + break; + + case 0x42e9: + if (len == 1) { + temp = dev->subsys_stat >> 8; + temp |= 0x80; + } + break; + + case 0x82e8: + case 0xc2e8: + if (len != 1) { + temp = dev->accel.cur_y; + } + break; + + case 0x86e8: + case 0xc6e8: + if (len != 1) { + temp = dev->accel.cur_x; + } + break; + + case 0x92e8: + if (len != 1) { + temp = dev->test; + } + break; + + case 0x96e8: + if (len != 1) { + temp = dev->accel.maj_axis_pcnt; + } + break; + + case 0x9ae8: + case 0xdae8: + if (len != 1) { + if (dev->force_busy) + temp |= 0x200; /*Hardware busy*/ + dev->force_busy = 0; + if (dev->data_available) { + temp |= 0x100; /*Read Data available*/ + if (mach->accel.cmd_type >= 0) { + switch (mach->accel.cmd_type) { + case 2: + if (dev->accel.sy >= mach->accel.height) + dev->data_available = 0; + break; + case 5: + if (dev->accel.sx >= mach->accel.width) + dev->data_available = 0; + break; + default: + if (dev->accel.sy < 0) + dev->data_available = 0; + break; + } + } else { + if (dev->accel.sy < 0) + dev->data_available = 0; + } + } + } + mach_log("[%04X:%08X]: 9AE8: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); + break; + case 0x9ae9: + case 0xdae9: + if (len == 1) { + if (dev->force_busy2) + temp |= 2; /*Hardware busy*/ + dev->force_busy2 = 0; + if (dev->data_available2) { + temp |= 1; /*Read Data available*/ + if (mach->accel.cmd_type >= 0) { + switch (mach->accel.cmd_type) { + case 2: + if (dev->accel.sy >= mach->accel.height) + dev->data_available2 = 0; + break; + case 5: + if (dev->accel.sx >= mach->accel.width) + dev->data_available2 = 0; + break; + default: + if (dev->accel.sy < 0) + dev->data_available2 = 0; + break; + } + } else { + if (dev->accel.sy < 0) + dev->data_available2 = 0; + } + } + } + mach_log("[%04X:%08X]: 9AE9: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); + break; + + case 0xe2e8: + case 0xe6e8: + if (mach->accel.cmd_type >= 0) { + if (mach_pixel_read(mach)) { + cmd = -1; + if (len == 1) { + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 1, dev->local) + + temp = mach->accel.pix_trans[1]; + } else { + if (mach->accel.cmd_type == 3) { + READ_PIXTRANS_WORD(dev->accel.cx, 0, dev->local) + } else { + READ_PIXTRANS_WORD(dev->accel.dx, 0, dev->local) + } + mach_accel_out_pixtrans(mach, dev, port, temp, len); + } + } + } else { + if (ibm8514_cpu_dest(svga)) { + cmd = (dev->accel.cmd >> 13); + if (len == 1) { + ; // READ_PIXTRANS_BYTE_IO(0) + } else { + READ_PIXTRANS_WORD(dev->accel.cx, 0, dev->local) + if (dev->accel.input && !dev->accel.odd_in && !dev->accel.sx) { + temp &= ~0xff00; + if (dev->local) + temp |= (svga->vram[(dev->accel.newdest_in + dev->accel.cur_x) & svga->vram_mask] << 8); + else + temp |= (dev->vram[(dev->accel.newdest_in + dev->accel.cur_x) & dev->vram_mask] << 8); + } + if (dev->subsys_stat & 1) { + dev->force_busy = 1; + dev->data_available = 1; + } + } + ibm8514_accel_out_pixtrans(svga, port, temp, len); + } + } + break; + case 0xe2e9: + case 0xe6e9: + if (mach->accel.cmd_type >= 0) { + mach_log("%04x pixtrans read, len=%d.\n", port, len); + if (mach_pixel_read(mach)) { + if (len == 1) { + cmd = -1; + READ_PIXTRANS_BYTE_IO(dev->accel.dx, 0, dev->local) + + temp = mach->accel.pix_trans[0]; + frgd_sel = (mach->accel.dp_config >> 13) & 7; + bkgd_sel = (mach->accel.dp_config >> 7) & 3; + mono_src = (mach->accel.dp_config >> 5) & 3; + + switch (mach->accel.dp_config & 0x200) { + case 0x000: /*8-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + mach_accel_start(mach->accel.cmd_type, 1, 8, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 1, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + break; + case 0x200: /*16-bit size*/ + if (mono_src == 2) { + if ((frgd_sel != 2) && (bkgd_sel != 2)) { + if (mach->accel.dp_config & 0x1000) + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[1] | (mach->accel.pix_trans[0] << 8), 0, mach, dev, len); + else + mach_accel_start(mach->accel.cmd_type, 1, 16, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), 0, mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + } else + mach_accel_start(mach->accel.cmd_type, 1, 2, -1, mach->accel.pix_trans[0] | (mach->accel.pix_trans[1] << 8), mach, dev, len); + break; + } + } + } + } + break; + + case 0xbee8: + case 0xfee8: + if (len != 1) { + mach_log("Multifunc_cntl = %d.\n", dev->accel.multifunc_cntl >> 12); + switch ((dev->accel.multifunc_cntl >> 12) & 0x0f) { + case 0: + temp = dev->accel.multifunc[0]; + break; + case 1: + temp = dev->accel.clip_top; + break; + case 2: + temp = dev->accel.clip_left; + break; + case 3: + temp = dev->accel.multifunc[3]; + break; + case 4: + temp = dev->accel.multifunc[4]; + break; + case 5: + temp = dev->accel.multifunc[5]; + break; + case 8: + temp = dev->accel.multifunc[8]; + break; + case 9: + temp = dev->accel.multifunc[9]; + break; + case 0x0a: + temp = dev->accel.multifunc[0x0a]; + break; + } + } + break; + +/*ATI Mach8/32 specific registers*/ + case 0x12ee: + if (len == 1) + temp = mach->config1 & 0xff; + else + temp = mach->config1; + break; + case 0x12ef: + if (len == 1) + temp = mach->config1 >> 8; + break; + + case 0x16ee: + if (len == 1) + temp = mach->config2 & 0xff; + else + temp = mach->config2; + break; + case 0x16ef: + if (len == 1) + temp = mach->config2 >> 8; + break; + + case 0x32ee: + if (len == 1) + temp = mach->local_cntl & 0xff; + else + temp = mach->local_cntl; + break; + case 0x32ef: + if (len == 1) + temp = mach->local_cntl >> 8; + break; + + case 0x36ee: + if (len == 1) + temp = mach->misc & 0xff; + else + temp = mach->misc; + break; + case 0x36ef: + if (len == 1) + temp = mach->misc >> 8; + break; + + case 0x42ee: + temp = mach->accel.test2[0]; + break; + case 0x42ef: + temp = mach->accel.test2[1]; + break; + + case 0x46ee: + temp = mach->accel.test3[0]; + break; + case 0x46ef: + temp = mach->accel.test3[1]; + break; + + case 0x4aee: + if (len == 1) + temp = mach->accel.clock_sel & 0xff; + else + temp = mach->accel.clock_sel; + break; + case 0x4aef: + if (len == 1) + temp = mach->accel.clock_sel >> 8; + break; + + case 0x52ee: + if (len == 1) + temp = mach->accel.scratch0 & 0xff; + else + temp = mach->accel.scratch0; + break; + case 0x52ef: + if (len == 1) + temp = mach->accel.scratch0 >> 8; + break; + + case 0x56ee: + if (len == 1) + temp = mach->accel.scratch1 & 0xff; + else + temp = mach->accel.scratch1; + break; + case 0x56ef: + if (len == 1) + temp = mach->accel.scratch1 >> 8; + break; + + case 0x5eee: + if (mach->pci_bus) + mach->memory_aperture = (mach->memory_aperture & ~0xfff0) | ((mach->linear_base >> 20) << 4); + + if (len == 1) + temp = mach->memory_aperture & 0xff; + else + temp = mach->memory_aperture; + break; + case 0x5eef: + if (len == 1) + temp = mach->memory_aperture >> 8; + break; + + case 0x62ee: + temp = mach->accel.clip_overrun; + if (len != 1) { + if (mach->force_busy) + temp |= 0x2000; + mach->force_busy = 0; + if (ati_eeprom_read(&mach->eeprom)) + temp |= 0x4000; + } + mach_log("[%04X:%08X]: 62EE: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); + break; + case 0x62ef: + if (len == 1) { + if (mach->force_busy2) + temp |= 0x20; + mach->force_busy2 = 0; + if (ati_eeprom_read(&mach->eeprom)) + temp |= 0x40; + } + mach_log("[%04X:%08X]: 62EF: Temp = %04x, len = %d\n\n", CS, cpu_state.pc, temp, len); + break; + + case 0x6aee: + if (len == 1) + temp = mach->accel.max_waitstates & 0xff; + else + temp = mach->accel.max_waitstates; + break; + case 0x6aef: + if (len == 1) + temp = mach->accel.max_waitstates >> 8; + break; + + case 0x72ee: + if (len == 1) + temp = dev->accel.clip_left & 0xff; + else + temp = dev->accel.clip_left; + break; + case 0x72ef: + if (len == 1) + temp = dev->accel.clip_left >> 8; + break; + + case 0x76ee: + if (len == 1) + temp = dev->accel.clip_top & 0xff; + else + temp = dev->accel.clip_top; + break; + case 0x76ef: + if (len == 1) + temp = dev->accel.clip_top >> 8; + break; + + case 0x7aee: + if (len == 1) + temp = dev->accel.multifunc[4] & 0xff; + else + temp = dev->accel.multifunc[4]; + break; + case 0x7aef: + if (len == 1) + temp = dev->accel.multifunc[4] >> 8; + break; + + case 0x7eee: + if (len == 1) + temp = dev->accel.multifunc[3] & 0xff; + else + temp = dev->accel.multifunc[3]; + break; + case 0x7eef: + if (len == 1) + temp = dev->accel.multifunc[3] >> 8; + break; + + case 0x82ee: + temp = mach->accel.patt_data_idx; + break; + + case 0x8eee: + if (len == 1) + temp = mach->accel.ext_ge_config & 0xff; + else + temp = mach->accel.ext_ge_config; + break; + case 0x8eef: + if (len == 1) + temp = mach->accel.ext_ge_config >> 8; + break; + + case 0x92ee: + temp = mach->accel.eeprom_control; + break; + + case 0x96ee: + if (len == 1) { + temp = dev->accel.maj_axis_pcnt & 0xff; + } else { + temp = dev->accel.maj_axis_pcnt; + if ((mach->accel.test == 0x1555) || (mach->accel.test == 0x0aaa)) + temp = mach->accel.test; + } + break; + case 0x96ef: + if (len == 1) + temp = dev->accel.maj_axis_pcnt >> 8; + break; + + case 0xa2ee: + if (len == 1) + temp = mach->accel.linedraw_opt & 0xff; + else { + temp = mach->accel.linedraw_opt; + } + break; + case 0xa2ef: + if (len == 1) + temp = mach->accel.linedraw_opt >> 8; + break; + + case 0xb2ee: + if (len == 1) + temp = dev->hdisp; + else { + temp = dev->hdisp & 0xff; + temp |= (dev->htotal << 8); + mach_log("HDISP read=%d, HTOTAL read=%d.\n", temp & 0xff, temp >> 8); + } + break; + case 0xb2ef: + if (len == 1) { + temp = dev->htotal; + } + break; + + case 0xc2ee: + if (len == 1) + temp = dev->vtotal & 0xff; + else { + temp = dev->vtotal; + mach_log("VTOTAL read=%d.\n", temp); + } + break; + case 0xc2ef: + if (len == 1) + temp = dev->vtotal >> 8; + break; + + case 0xc6ee: + if (len == 1) + temp = dev->vdisp & 0xff; + else { + temp = dev->vdisp; + mach_log("VDISP read=%d.\n", temp); + } + break; + case 0xc6ef: + if (len == 1) + temp = dev->vdisp >> 8; + break; + + case 0xcaee: + if (len == 1) + temp = dev->vsyncstart & 0xff; + else + temp = dev->vsyncstart; + break; + case 0xcaef: + if (len == 1) + temp = dev->vsyncstart >> 8; + break; + + case 0xceee: + if (len == 1) + temp = svga->vc & 0xff; + else + temp = svga->vc & 0x7ff; + break; + case 0xceef: + if (len == 1) + temp = (svga->vc >> 8) & 7; + break; + + case 0xdaee: + if (len != 1) { + temp = mach->accel.src_x; + if (dev->local) { + temp &= 0x7ff; + } + } else + temp = dev->accel.destx_distp & 0xff; + break; + case 0xdaef: + if (len == 1) + temp = dev->accel.destx_distp >> 8; + break; + + case 0xdeee: + if (len != 1) { + temp = mach->accel.src_y; + if (dev->local) + temp &= 0x7ff; + } else + temp = dev->accel.desty_axstp & 0xff; + break; + case 0xdeef: + if (len == 1) + temp = dev->accel.desty_axstp >> 8; + break; + + case 0xfaee: + if (len != 1) { + if (mach->pci_bus) + temp = 0x0017; + else + temp = 0x22f7; + } else { + if (mach->pci_bus) + temp = 0x17; + else + temp = 0xf7; + } + break; + case 0xfaef: + if (len == 1) { + if (mach->pci_bus) + temp = 0x00; + else + temp = 0x22; + } + break; + } + if (port != 0x9ae8 && port != 0x9ae9 && port != 0x62ee && port != 0x9aee) { + mach_log("Port accel in = %04x, temp = %04x, len = %d, mode = %d.\n", port, temp, len, dev->ibm_mode); + } + return temp; +} + +static void +mach_accel_outb(uint16_t port, uint8_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + mach_accel_out(port, val, mach, 1); +} + +static void +mach_accel_outw(uint16_t port, uint16_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + mach_accel_out(port, val, mach, 2); +} + +static uint8_t +mach_accel_inb(uint16_t port, void *p) +{ + mach_t *mach = (mach_t *) p; + return mach_accel_in(port, mach, 1); +} + +static uint16_t +mach_accel_inw(uint16_t port, void *p) +{ + mach_t *mach = (mach_t *) p; + return mach_accel_in(port, mach, 2); +} + +static void +mach32_ap_writeb(uint32_t addr, uint8_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + uint8_t port_dword = addr & 0xfc; + + if (((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + mach_log("Port WORDB Write=%04x.\n", 0x02ee + (port_dword << 8)); + mach_accel_outb(0x02ee + (addr & 1) + (port_dword << 8), val, mach); + } else { + mach_log("Port WORDB Write=%04x.\n", 0x02e8 + (port_dword << 8)); + mach_accel_outb(0x02e8 + (addr & 1) + (port_dword << 8), val, mach); + } + } else { + mach_log("Linear WORDB Write=%08x.\n", addr); + svga_write_linear(addr, val, &mach->svga); + } +} + +static void +mach32_ap_writew(uint32_t addr, uint16_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + uint8_t port_dword = addr & 0xfc; + + if (((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + mach_log("Port WORDW Write=%04x.\n", 0x02ee + (port_dword << 8)); + mach_accel_outw(0x02ee + (port_dword << 8), val, mach); + } else { + mach_log("Port WORDW Write=%04x.\n", 0x02e8 + (port_dword << 8)); + mach_accel_outw(0x02e8 + (port_dword << 8), val, mach); + } + } else { + mach_log("Linear WORDW Write=%08x.\n", addr); + svga_writew_linear(addr, val, &mach->svga); + } +} + +static void +mach32_ap_writel(uint32_t addr, uint32_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + uint8_t port_dword = addr & 0xfc; + + if (((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + mach_log("Port WORDL Write=%04x.\n", 0x02ee + (port_dword << 8)); + mach_accel_outw(0x02ee + (port_dword << 8), val & 0xffff, mach); + mach_accel_outw(0x02ee + (port_dword << 8) + 4, val >> 16, mach); + } else { + mach_log("Port WORDL Write=%04x.\n", 0x02e8 + (port_dword << 8)); + mach_accel_outw(0x02e8 + (port_dword << 8), val & 0xffff, mach); + mach_accel_outw(0x02e8 + (port_dword << 8) + 4, val >> 16, mach); + } + } else { + mach_log("Linear WORDL Write=%08x, val=%08x, mode=%d, rop=%02x.\n", addr, val, mach->svga.writemode, mach->svga.gdcreg[3] & 0x18); + svga_writel_linear(addr, val, &mach->svga); + } +} + +static uint8_t +mach32_ap_readb(uint32_t addr, void *p) +{ + mach_t *mach = (mach_t *) p; + uint8_t temp; + uint8_t port_dword = addr & 0xfc; + + if (((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + temp = mach_accel_inb(0x02ee + (addr & 1) + (port_dword << 8), mach); + } else { + temp = mach_accel_inb(0x02e8 + (addr & 1) + (port_dword << 8), mach); + } + } else + temp = svga_read_linear(addr, &mach->svga); + + return temp; +} + +static uint16_t +mach32_ap_readw(uint32_t addr, void *p) +{ + mach_t *mach = (mach_t *) p; + uint16_t temp; + uint8_t port_dword = addr & 0xfc; + + if (((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + temp = mach_accel_inw(0x02ee + (port_dword << 8), mach); + } else { + temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); + } + } else + temp = svga_readw_linear(addr, &mach->svga); + + return temp; +} + +static uint32_t +mach32_ap_readl(uint32_t addr, void *p) +{ + mach_t *mach = (mach_t *) p; + uint32_t temp; + uint8_t port_dword = addr & 0xfc; + + if (((addr >= ((mach->ap_size << 20) - 0x200)) && (addr < (mach->ap_size << 20)))) { + if (addr & 0x100) { + temp = mach_accel_inw(0x02ee + (port_dword << 8), mach); + temp |= (mach_accel_inw(0x02ee + (port_dword << 8) + 4, mach) << 8); + } else { + temp = mach_accel_inw(0x02e8 + (port_dword << 8), mach); + temp |= (mach_accel_inw(0x02e8 + (port_dword << 8) + 4, mach) << 8); + } + } else + temp = svga_readl_linear(addr, &mach->svga); + + return temp; +} + +static void +mach32_updatemapping(mach_t *mach) +{ + svga_t *svga = &mach->svga; + + if ((mach->pci_bus && (!(mach->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM)))) { + mem_mapping_disable(&svga->mapping); + mem_mapping_disable(&mach->mmio_linear_mapping); + return; + } + + if (mach->regs[0xbd] & 4) { + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + mach_log("Bit 2 of BD.\n"); + } else { + switch (svga->gdcreg[6] & 0x0c) { + case 0x0: /*128k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000); + svga->banked_mask = 0xffff; + break; + case 0x4: /*64k at A0000*/ + mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000); + svga->banked_mask = 0xffff; + break; + case 0x8: /*32k at B0000*/ + mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000); + svga->banked_mask = 0x7fff; + break; + case 0xC: /*32k at B8000*/ + mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000); + svga->banked_mask = 0x7fff; + break; + } + } + + mach_log("Linear base = %08x, aperture = %04x, localcntl = %02x svgagdc = %x.\n", mach->linear_base, mach->memory_aperture, mach->local_cntl, svga->gdcreg[6] & 0x0c); + if (mach->linear_base) { + if (((mach->memory_aperture & 3) == 1) && !mach->pci_bus) { + /*1 MB aperture*/ + mach->ap_size = 1; + mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); + } else { + /*4 MB aperture*/ + mach->ap_size = 4; + mem_mapping_set_addr(&mach->mmio_linear_mapping, mach->linear_base, mach->ap_size << 20); + } + /*Force IBM/ATI mode on when the MMIO registers are loaded.*/ + if (mach->local_cntl & 0x20) { + if (!ibm8514_on) { + ibm8514_on ^= 1; + svga->adv_flags |= FLAG_ATI; + svga_recalctimings(svga); + } + } + } else { + mach->ap_size = 4; + mem_mapping_disable(&mach->mmio_linear_mapping); + } +} + +static void +mach32_hwcursor_draw(svga_t *svga, int displine) +{ + mach_t *mach = (mach_t *) svga->p; + uint16_t dat; + int comb; + int offset = svga->hwcursor_latch.x - svga->hwcursor_latch.xoff; + uint32_t color0, color1; + + if (svga->bpp == 8) { + color0 = svga->pallook[mach->cursor_col_0]; + color1 = svga->pallook[mach->cursor_col_1]; + mach_log("8BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); + } else if (svga->bpp == 15) { + color0 = video_15to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; + color1 = video_15to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; + mach_log("15BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); + } else if (svga->bpp == 16) { + color0 = video_16to32[((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0) & 0xffff]; + color1 = video_16to32[((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1) & 0xffff]; + mach_log("16BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); + } else { + color0 = ((mach->ext_cur_col_0_r << 16) | (mach->ext_cur_col_0_g << 8) | mach->cursor_col_0); + color1 = ((mach->ext_cur_col_1_r << 16) | (mach->ext_cur_col_1_g << 8) | mach->cursor_col_1); + mach_log("24BPP: Offset = %x, XOFF = %02x, YOFF = %02x.\n", offset, svga->hwcursor_latch.xoff, svga->hwcursor_latch.yoff); + } + + if (svga->interlace && svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; + + for (int x = 0; x < 64; x += 8) { + dat = svga->vram[svga->hwcursor_latch.addr & svga->vram_mask] | (svga->vram[(svga->hwcursor_latch.addr + 1) & svga->vram_mask] << 8); + for (int xx = 0; xx < 8; xx++) { + comb = (dat >> (xx << 1)) & 0x03; + if (offset >= svga->hwcursor_latch.x) { + switch (comb) { + case 0: + ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color0; + break; + case 1: + ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] = color1; + break; + case 3: + ((uint32_t *) svga->monitor->target_buffer->line[displine])[offset + svga->x_add] ^= 0xffffff; + break; + } + } + offset++; + } + svga->hwcursor_latch.addr += 2; + } + if (svga->interlace && !svga->hwcursor_oddeven) + svga->hwcursor_latch.addr += 16; +} + +static void +mach_io_remove(mach_t *mach) +{ + io_removehandler(0x01ce, 2, + mach_in, NULL, NULL, + mach_out, NULL, NULL, mach); + io_removehandler(0x03c0, 32, + mach_in, NULL, NULL, + mach_out, NULL, NULL, mach); + + io_removehandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x2ea, 0x0004, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_removehandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + + io_removehandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + + io_removehandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_removehandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); +} + +static void +mach_io_set(mach_t *mach) +{ + io_sethandler(0x01ce, 2, + mach_in, NULL, NULL, + mach_out, NULL, NULL, mach); + io_sethandler(0x03c0, 32, + mach_in, NULL, NULL, + mach_out, NULL, NULL, mach); + + io_sethandler(0x2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x2ea, 0x0004, mach_in, NULL, NULL, mach_out, NULL, NULL, mach); + io_sethandler(0x6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x12e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x16e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x1ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x1ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x22e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x26e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x2ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x42e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x4ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x52e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x56e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x5ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x5ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x82e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x86e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x8ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x8ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x92e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x96e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x9ae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x9ee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xa2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xa6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xaae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xaee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xb2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xb6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xbae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xbee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xe2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + + io_sethandler(0xc2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xc6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xcae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xcee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xd2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xd6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xdae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xdee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xe6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xeae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xeee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xf2e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xf6e8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xfae8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xfee8, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + + io_sethandler(0x06ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x0aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x0eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x12ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x16ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x1aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x1eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x26ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x2aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x2eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x32ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x36ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x3aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x3eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x42ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x46ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x4aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x52ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x56ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x5aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x5eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x62ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x66ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x6aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x6eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x72ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x76ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x7aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x7eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x82ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x8eee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x92ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x96ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0x9aee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xa2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xa6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xaaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xaeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xb2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xb6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xbaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xbeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xc2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xc6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xcaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xceee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xd2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xd6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xdaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xdeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xe2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xe6ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xeeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xf2ee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xfaee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); + io_sethandler(0xfeee, 0x0002, mach_accel_inb, mach_accel_inw, NULL, mach_accel_outb, mach_accel_outw, NULL, mach); +} + +static uint8_t +mach32_pci_read(int func, int addr, void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + uint8_t ret = 0x00; + + switch (addr) { + case 0x00: + ret = 0x02; /*ATI*/ + break; + case 0x01: + ret = 0x10; + break; + + case 0x02: + ret = 0x58; + break; + case 0x03: + ret = 0x41; + break; + + case PCI_REG_COMMAND: + ret = mach->pci_regs[PCI_REG_COMMAND] | 0x80; /*Respond to IO and memory accesses*/ + break; + + case 0x07: + ret = 0x01; /*Medium DEVSEL timing*/ + break; + + case 0x0a: + ret = 0x00; /*Supports VGA interface*/ + break; + case 0x0b: + ret = 0x03; + break; + + case 0x10: + ret = 0x00; /*Linear frame buffer address*/ + break; + case 0x11: + ret = 0x00; + break; + case 0x12: + ret = mach->linear_base >> 16; + break; + case 0x13: + ret = mach->linear_base >> 24; + break; + + case 0x30: + ret = (mach->pci_regs[0x30] & 0x01); /*BIOS ROM address*/ + break; + case 0x31: + ret = 0x00; + break; + case 0x32: + ret = mach->pci_regs[0x32]; + break; + case 0x33: + ret = mach->pci_regs[0x33]; + break; + + case 0x3c: + ret = mach->int_line; + break; + case 0x3d: + ret = PCI_INTA; + break; + } + + return ret; +} + +static void +mach32_pci_write(int func, int addr, uint8_t val, void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + + switch (addr) { + case PCI_REG_COMMAND: + mach->pci_regs[PCI_REG_COMMAND] = val & 0x27; + mach_io_remove(mach); + if (val & PCI_COMMAND_IO) { + mach_io_set(mach); + } + mach32_updatemapping(mach); + break; + + case 0x12: + mach->linear_base = (mach->linear_base & 0xff000000) | ((val & 0xc0) << 16); + mach32_updatemapping(mach); + break; + case 0x13: + mach->linear_base = (mach->linear_base & 0xc00000) | (val << 24); + mach32_updatemapping(mach); + break; + + case 0x30: + case 0x32: + case 0x33: + mach->pci_regs[addr] = val; + if (mach->pci_regs[0x30] & 0x01) { + uint32_t bios_addr = (mach->pci_regs[0x32] << 16) | (mach->pci_regs[0x33] << 24); + mach_log("Mach32 bios_rom enabled at %08x\n", bios_addr); + mem_mapping_set_addr(&mach->bios_rom.mapping, bios_addr, 0x8000); + } else { + mach_log("Mach32 bios_rom disabled\n"); + mem_mapping_disable(&mach->bios_rom.mapping); + } + return; + + case 0x3c: + mach->int_line = val; + break; + } +} + +static void * +mach8_init(const device_t *info) +{ + mach_t *mach; + svga_t *svga; + ibm8514_t *dev; + uint32_t memory; + + mach = malloc(sizeof(mach_t)); + memset(mach, 0x00, sizeof(mach_t)); + + svga = &mach->svga; + dev = &svga->dev8514; + + mach->pci_bus = !!(info->flags & DEVICE_PCI); + mach->vlb_bus = !!(info->flags & DEVICE_VLB); + dev->local = info->local; + dev->vram_size = (1024 << 10); + dev->vram = calloc(dev->vram_size, 1); + dev->changedvram = calloc(dev->vram_size >> 12, 1); + dev->vram_mask = dev->vram_size - 1; + dev->map8 = svga->pallook; + memory = device_get_config_int("memory"); + + if (dev->local) { + if (mach->vlb_bus) + rom_init(&mach->bios_rom, + BIOS_MACH32_VLB_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + else if (mach->pci_bus) + rom_init(&mach->bios_rom, + BIOS_MACH32_PCI_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + else + rom_init(&mach->bios_rom, + BIOS_MACH32_ISA_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + } else { + rom_init(&mach->bios_rom, + BIOS_MACH8_ROM_PATH, + 0xc0000, 0x8000, 0x7fff, + 0, MEM_MAPPING_EXTERNAL); + } + + svga_init(info, svga, mach, dev->local ? (memory << 10) : (512 << 10), /*default: 512kB for Mach8, 2MB for Mach32*/ + mach_recalctimings, + mach_in, mach_out, + dev->local ? mach32_hwcursor_draw : NULL, + NULL); + + if (dev->local) { + switch (memory) { + case 1024: + mach->misc |= 0x04; + break; + case 2048: + mach->misc |= 0x08; + break; + case 4096: + mach->misc |= 0x0c; + break; + } + svga->hwcursor.cur_ysize = 64; + mach->config1 = 0x20; + mach->config2 = 0x08; + /*Fake the RAMDAC to give the VLB/MCA variants full 24-bit support until said RAMDAC is implemented.*/ + if (mach->vlb_bus) { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_vlb); + mach->config1 |= 0x0c; + mach->config1 |= 0x0400; + } else if (mach->pci_bus) { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_mach32_pci); + mach->config1 |= 0x0e; + mach->config1 |= 0x0a00; + mach->config2 |= 0x2000; + svga->ramdac = device_add(&ati68860_ramdac_device); + } else { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); + } + mem_mapping_add(&mach->mmio_linear_mapping, 0, 0, mach32_ap_readb, mach32_ap_readw, mach32_ap_readl, mach32_ap_writeb, mach32_ap_writew, mach32_ap_writel, NULL, MEM_MAPPING_EXTERNAL, mach); + mem_mapping_disable(&mach->mmio_linear_mapping); + } else { + video_inform(VIDEO_FLAG_TYPE_8514, &timing_gfxultra_isa); + mach->config1 = 0x02 | 0x20 | 0x80; + mach->config2 = 0x02; + dev->ext_pitch = 1024; + } + + svga->force_old_addr = 1; + svga->miscout = 1; + svga->bpp = 8; + svga->packed_chain4 = 1; + ibm8514_enabled = 1; + ibm8514_has_vga = 1; + dev->ibm_mode = 1; + dev->rowoffset = 128; + mach_io_set(mach); + + if (dev->local) { + svga->decode_mask = (4 << 20) - 1; + mach->cursor_col_1 = 0xff; + mach->ext_cur_col_1_r = 0xff; + mach->ext_cur_col_1_g = 0xff; + dev->ext_crt_pitch = 128; + if (mach->vlb_bus) + ati_eeprom_load(&mach->eeprom, "mach32_vlb.nvr", 1); + else if (mach->pci_bus) { + ati_eeprom_load(&mach->eeprom, "mach32_pci.nvr", 1); + mem_mapping_disable(&mach->bios_rom.mapping); + mach->card = pci_add_card(PCI_ADD_VIDEO, mach32_pci_read, mach32_pci_write, mach); + mach->pci_regs[PCI_REG_COMMAND] = 0x83; + mach->pci_regs[0x30] = 0x00; + mach->pci_regs[0x32] = 0x0c; + mach->pci_regs[0x33] = 0x00; + } else + ati_eeprom_load(&mach->eeprom, "mach32.nvr", 1); + } else { + ati_eeprom_load_mach8(&mach->eeprom, "mach8.nvr"); + } + + return (mach); +} + +static int +mach8_available(void) +{ + return rom_present(BIOS_MACH8_ROM_PATH); +} + +static int +mach32_isa_available(void) +{ + return rom_present(BIOS_MACH32_ISA_ROM_PATH); +} + +static int +mach32_vlb_available(void) +{ + return rom_present(BIOS_MACH32_VLB_ROM_PATH); +} + +static int +mach32_pci_available(void) +{ + return rom_present(BIOS_MACH32_PCI_ROM_PATH); +} + +static void +mach_close(void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + ibm8514_t *dev = &svga->dev8514; + + if (dev) { + free(dev->vram); + free(dev->changedvram); + } + + svga_close(svga); + free(mach); +} + +static void +mach_speed_changed(void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + + svga_recalctimings(svga); +} + +static void +mach_force_redraw(void *p) +{ + mach_t *mach = (mach_t *) p; + svga_t *svga = &mach->svga; + + svga->fullchange = changeframecount; +} + +// clang-format off +static const device_config_t mach32_config[] = { + { + .name = "memory", + .description = "Memory size", + .type = CONFIG_SELECTION, + .default_int = 2048, + .selection = { + { + .description = "512 KB", + .value = 512 + }, + { + .description = "1 MB", + .value = 1024 + }, + { + .description = "2 MB", + .value = 2048 + }, + { + .description = "4 MB", + .value = 4096 + }, + { + .description = "" + } + } + }, + { + .type = CONFIG_END + } +}; + +const device_t mach8_isa_device = { + .name = "ATI Mach8 (ISA)", + .internal_name = "mach8_isa", + .flags = DEVICE_ISA, + .local = 0, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach8_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = NULL +}; + +const device_t mach32_isa_device = { + .name = "ATI Mach32 (ISA)", + .internal_name = "mach32_isa", + .flags = DEVICE_ISA, + .local = 1, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_isa_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; + +const device_t mach32_vlb_device = { + .name = "ATI Mach32 (VLB)", + .internal_name = "mach32_vlb", + .flags = DEVICE_VLB, + .local = 1, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_vlb_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; + +const device_t mach32_pci_device = { + .name = "ATI Mach32 (PCI)", + .internal_name = "mach32_pci", + .flags = DEVICE_PCI, + .local = 1, + .init = mach8_init, + .close = mach_close, + .reset = NULL, + { .available = mach32_pci_available }, + .speed_changed = mach_speed_changed, + .force_redraw = mach_force_redraw, + .config = mach32_config +}; diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index d8829eb2f..913a052ff 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -41,6 +41,7 @@ #include <86box/video.h> #include <86box/vid_svga.h> #include <86box/vid_svga_render.h> +#include <86box/vid_xga_device.h> void svga_doblit(int wx, int wy, svga_t *svga); @@ -131,7 +132,7 @@ svga_out(uint16_t addr, uint8_t val, void *p) if (svga->attraddr < 16) svga->fullchange = svga->monitor->mon_changeframecount; if (svga->attraddr == 0x10 || svga->attraddr == 0x14 || svga->attraddr < 0x10) { - for (uint8_t c = 0; c < 16; c++) { + for (int c = 0; c < 16; c++) { if (svga->attrregs[0x10] & 0x80) { svga->egapal[c] = (svga->attrregs[c] & 0xf) | ((svga->attrregs[0x14] & 0xf) << 4); } else { @@ -165,6 +166,12 @@ svga_out(uint16_t addr, uint8_t val, void *p) io_sethandler(0x03a0, 0x0020, svga->video_in, NULL, NULL, svga->video_out, NULL, NULL, svga->p); svga_recalctimings(svga); break; + case 0x3c3: + if (xga_enabled) { + svga->xga.on = (val & 0x01) ? 0 : 1; + vga_on = !svga->xga.on; + } + break; case 0x3c4: svga->seqaddr = val; break; @@ -407,7 +414,7 @@ svga_set_ramdac_type(svga_t *svga, int type) if (svga->ramdac_type != type) { svga->ramdac_type = type; - for (uint16_t c = 0; c < 256; c++) { + for (int c = 0; c < 256; c++) { if (svga->ramdac_type == RAMDAC_8BIT) svga->pallook[c] = makecol32(svga->vgapal[c].r, svga->vgapal[c].g, svga->vgapal[c].b); else @@ -583,8 +590,14 @@ svga_recalctimings(svga_t *svga) svga->recalctimings_ex(svga); } } else { - if (ibm8514_enabled) - ibm8514_recalctimings(svga); + if (ibm8514_enabled) { + if (svga->dev8514.local) { + if (svga->recalctimings_ex) { + svga->recalctimings_ex(svga); + } + } else + ibm8514_recalctimings(svga); + } if (xga_enabled) xga_recalctimings(svga); } @@ -597,8 +610,13 @@ svga_recalctimings(svga_t *svga) crtcconst = svga->clock * svga->char_width; - disptime = svga->htotal; - _dispontime = svga->hdisp_time; + if (ibm8514_on && !svga->dev8514.local) { + disptime = svga->dev8514.h_total; + _dispontime = svga->dev8514.h_disp; + } else { + disptime = svga->htotal; + _dispontime = svga->hdisp_time; + } if (svga->seqregs[1] & 8) { disptime *= 2; @@ -678,16 +696,20 @@ void svga_poll(void *p) { svga_t *svga = (svga_t *) p; + ibm8514_t *dev = &svga->dev8514; uint32_t x; uint32_t blink_delay; int wx; int wy; int ret; int old_ma; + int linecountff = 0; if (!vga_on && ibm8514_enabled && ibm8514_on) { - ibm8514_poll(&svga->dev8514, svga); - return; + if (!dev->local) { + ibm8514_poll(dev, svga); + return; + } } else if (!vga_on && xga_enabled && svga->xga.on) { xga_poll(&svga->xga, svga); return; @@ -695,22 +717,22 @@ svga_poll(void *p) if (!svga->linepos) { if (svga->displine == svga->hwcursor_latch.y && svga->hwcursor_latch.ena) { - svga->hwcursor_on = svga->hwcursor.cur_ysize - svga->hwcursor_latch.yoff; + svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff; svga->hwcursor_oddeven = 0; } if (svga->displine == (svga->hwcursor_latch.y + 1) && svga->hwcursor_latch.ena && svga->interlace) { - svga->hwcursor_on = svga->hwcursor.cur_ysize - (svga->hwcursor_latch.yoff + 1); + svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - (svga->hwcursor_latch.yoff + 1); svga->hwcursor_oddeven = 1; } if (svga->displine == svga->dac_hwcursor_latch.y && svga->dac_hwcursor_latch.ena) { - svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - svga->dac_hwcursor_latch.yoff; + svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - svga->dac_hwcursor_latch.yoff; svga->dac_hwcursor_oddeven = 0; } if (svga->displine == (svga->dac_hwcursor_latch.y + 1) && svga->dac_hwcursor_latch.ena && svga->interlace) { - svga->dac_hwcursor_on = svga->dac_hwcursor.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); + svga->dac_hwcursor_on = svga->dac_hwcursor_latch.cur_ysize - (svga->dac_hwcursor_latch.yoff + 1); svga->dac_hwcursor_oddeven = 1; } @@ -783,8 +805,14 @@ svga_poll(void *p) if ((svga->sc == (svga->crtc[11] & 31)) || (svga->sc == svga->rowcount)) svga->con = 0; if (svga->dispon) { - if (svga->linedbl && !svga->linecountff) { - svga->linecountff = 1; + /*Real IBM 8514/A or compatibility mode doesn't have linedbl, so skip those.*/ + if (dev->local && ibm8514_on) { + svga->linedbl = 0; + svga->linecountff = 0; + linecountff = 1; + } + if (svga->linedbl && !svga->linecountff && !linecountff) { + svga->linecountff = 1; svga->ma = svga->maback; } else if (svga->sc == svga->rowcount) { svga->linecountff = 0; @@ -793,23 +821,24 @@ svga_poll(void *p) svga->maback += (svga->rowoffset << 3); if (svga->interlace) svga->maback += (svga->rowoffset << 3); + svga->maback &= svga->vram_display_mask; svga->ma = svga->maback; } else { svga->linecountff = 0; svga->sc++; - svga->sc &= 31; + svga->sc &= 0x1f; svga->ma = svga->maback; } } - svga->hsync_divisor = !svga->hsync_divisor; + svga->hsync_divisor ^= 1; if (svga->hsync_divisor && (svga->crtc[0x17] & 4)) return; svga->vc++; - svga->vc &= 2047; + svga->vc &= 0x7ff; if (svga->vc == svga->split) { ret = 1; @@ -835,6 +864,7 @@ svga_poll(void *p) if (svga->vc == svga->dispend) { if (svga->vblank_start) svga->vblank_start(svga); + svga->dispon = 0; blink_delay = (svga->crtc[11] & 0x60) >> 5; if (svga->crtc[10] & 0x20) @@ -846,6 +876,7 @@ svga_poll(void *p) if (!(svga->gdcreg[6] & 1) && !(svga->blink & 15)) svga->fullchange = 2; + svga->blink = (svga->blink + 1) & 0x7f; for (x = 0; x < ((svga->vram_mask + 1) >> 12); x++) { @@ -888,12 +919,18 @@ svga_poll(void *p) svga->monitor->mon_changeframecount = svga->interlace ? 3 : 2; svga->vslines = 0; - if (svga->interlace && svga->oddeven) - svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); - else - svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); + if ((dev->local && vga_on) || !dev->local) { + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1) + ((svga->crtc[5] & 0x60) >> 5); + else + svga->ma = svga->maback = svga->ma_latch + ((svga->crtc[5] & 0x60) >> 5); + } else if (dev->local && ibm8514_on) { + if (svga->interlace && svga->oddeven) + svga->ma = svga->maback = svga->ma_latch + (svga->rowoffset << 1); + else + svga->ma = svga->maback = svga->ma_latch; + } svga->ca = ((svga->crtc[0xe] << 8) | svga->crtc[0xf]) + ((svga->crtc[0xb] & 0x60) >> 5) + svga->ca_adj; - svga->ma = (svga->ma << 2); svga->maback = (svga->maback << 2); svga->ca = (svga->ca << 2); @@ -958,9 +995,9 @@ svga_init(const device_t *info, svga_t *svga, void *p, int memsize, svga->monitor_index = monitor_index_global; svga->monitor = &monitors[svga->monitor_index]; - for (uint16_t c = 0; c < 256; c++) { + for (int c = 0; c < 256; c++) { e = c; - for (uint8_t d = 0; d < 8; d++) { + for (int d = 0; d < 8; d++) { svga_rotate[d][c] = e; e = (e >> 1) | ((e & 1) ? 0x80 : 0); } @@ -1100,7 +1137,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (!linear) { if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { + if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ svga->xga.test = val; svga->xga.a5_test = 1; @@ -1108,7 +1145,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) } else if (val == 0x5a) { svga->xga.test = val; return; - } else if (val == 0x12 || val == 0x34) { + } else if ((val == 0x12) || (val == 0x34)) { addr += svga->xga.write_bank; svga->xga.vram[addr & svga->xga.vram_mask] = val; svga->xga.linear_endian_reverse = 1; @@ -1145,10 +1182,18 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (addr & 1) writemask2 <<= 1; addr &= ~1; - addr <<= 2; - } else - addr <<= 2; - + if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { + addr &= svga->vram_mask; + } else + addr <<= 2; + } else { + if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { + writemask2 = 1 << (addr & 3); + addr &= ~3; + addr &= svga->vram_mask; + } else + addr <<= 2; + } addr &= svga->decode_mask; if (svga->translate_address) @@ -1303,7 +1348,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) if (!linear) { if (xga_enabled) { - if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { + if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl >= 1)) { if (svga->xga.test == 0xa5) { /*Memory size test of XGA*/ svga->xga.on = 1; vga_on = !svga->xga.on; @@ -1312,7 +1357,7 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) svga->xga.on = 1; vga_on = !svga->xga.on; return svga->xga.test; - } else if (addr == 0xa0000 || addr == 0xa0010) { + } else if ((addr == 0xa0000) || (addr == 0xa0010)) { addr += svga->xga.read_bank; return svga->xga.vram[addr & svga->xga.vram_mask]; } @@ -1354,11 +1399,24 @@ svga_read_common(uint32_t addr, uint8_t linear, void *p) } else if (svga->chain2_read) { readplane = (readplane & 2) | (addr & 1); addr &= ~1; - addr <<= 2; - } else - addr <<= 2; - + if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) + addr &= svga->vram_mask; + else + addr <<= 2; + } else { + if (linear && ibm8514_on && (svga->adv_flags & FLAG_ATI)) { + addr &= svga->decode_mask; + if (addr >= svga->vram_max) + return 0xff; + latch_addr = (addr & svga->vram_mask) & ~3; + for (uint8_t i = 0; i < count; i++) + svga->latch.b[i] = svga->vram[latch_addr | i]; + return svga->vram[addr & svga->vram_mask]; + } else + addr <<= 2; + } addr &= svga->decode_mask; + if (svga->translate_address) { latch_addr = svga->translate_address(latch_addr, p); addr = svga->translate_address(addr, p); diff --git a/src/video/vid_table.c b/src/video/vid_table.c index a2cead1ec..aaf407ca4 100644 --- a/src/video/vid_table.c +++ b/src/video/vid_table.c @@ -36,6 +36,7 @@ #include <86box/vid_ega.h> #include <86box/vid_colorplus.h> #include <86box/vid_mda.h> +#include <86box/vid_xga_device.h> typedef struct { const device_t *device; @@ -79,6 +80,8 @@ video_cards[] = { { &vid_none_device }, { &vid_internal_device }, { &atiega_device }, + { &mach8_isa_device, VIDEO_FLAG_TYPE_8514 }, + { &mach32_isa_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_isa_device }, { &ati28800k_device }, { &ati18800_vga88_device }, @@ -112,6 +115,7 @@ video_cards[] = { { &hercules_device, VIDEO_FLAG_TYPE_MDA }, { &herculesplus_device, VIDEO_FLAG_TYPE_MDA }, { &incolor_device }, + { &inmos_isa_device, VIDEO_FLAG_TYPE_XGA }, { &im1024_device }, { &iskra_ega_device }, { &et4000_kasan_isa_device }, @@ -154,6 +158,7 @@ video_cards[] = { { &gd5428_mca_device }, { &et4000_mca_device }, { &radius_svga_multiview_mca_device }, + { &mach32_pci_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_pci_device }, { &mach64vt2_device }, { &et4000w32p_videomagic_revb_pci_device }, @@ -211,6 +216,7 @@ video_cards[] = { { &voodoo_3_1000_device }, { &voodoo_3_2000_device }, { &voodoo_3_3000_device }, + { &mach32_vlb_device, VIDEO_FLAG_TYPE_8514 }, { &mach64gx_vlb_device }, { &et4000w32i_vlb_device }, { &et4000w32p_videomagic_revb_vlb_device }, @@ -431,3 +437,15 @@ video_is_ega_vga(void) { return (video_get_type() == VIDEO_FLAG_TYPE_SPECIAL); } + +int +video_is_8514(void) +{ + return (video_get_type() == VIDEO_FLAG_TYPE_8514); +} + +int +video_is_xga(void) +{ + return (video_get_type() == VIDEO_FLAG_TYPE_XGA); +} diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 0c795d132..7933e74a8 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -37,6 +37,7 @@ #define XGA_BIOS_PATH "roms/video/xga/XGA_37F9576_Ver200.BIN" #define XGA2_BIOS_PATH "roms/video/xga/xga2_v300.bin" +#define INMOS_XGA_BIOS_PATH "roms/video/xga/InMOS XGA - Fairchild NM27C256Q-150.BIN" static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; @@ -44,16 +45,86 @@ static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .writ static void xga_ext_outb(uint16_t addr, uint8_t val, void *p); static uint8_t xga_ext_inb(uint16_t addr, void *p); +int xga_has_vga = 0; + +void +svga_xga_out(uint16_t addr, uint8_t val, void *p) +{ + svga_t *svga = (svga_t *)p; + uint8_t old; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3D4: + svga->crtcreg = val & 0x3f; + return; + case 0x3D5: + if (svga->crtcreg & 0x20) + return; + if ((svga->crtcreg < 7) && (svga->crtc[0x11] & 0x80)) + return; + if ((svga->crtcreg == 7) && (svga->crtc[0x11] & 0x80)) + val = (svga->crtc[7] & ~0x10) | (val & 0x10); + old = svga->crtc[svga->crtcreg]; + svga->crtc[svga->crtcreg] = val; + if (old != val) { + if (svga->crtcreg < 0xe || svga->crtcreg > 0x10) { + if ((svga->crtcreg == 0xc) || (svga->crtcreg == 0xd)) { + svga->fullchange = 3; + svga->ma_latch = ((svga->crtc[0xc] << 8) | svga->crtc[0xd]) + ((svga->crtc[8] & 0x60) >> 5); + } else { + svga->fullchange = changeframecount; + svga_recalctimings(svga); + } + } + } + break; + } + svga_out(addr, val, svga); +} + +uint8_t +svga_xga_in(uint16_t addr, void *p) +{ + svga_t *svga = (svga_t *)p; + uint8_t temp; + + if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) + addr ^= 0x60; + + switch (addr) { + case 0x3D4: + temp = svga->crtcreg; + break; + case 0x3D5: + if (svga->crtcreg & 0x20) + temp = 0xff; + else + temp = svga->crtc[svga->crtcreg]; + break; + default: + temp = svga_in(addr, svga); + break; + } + return temp; +} + void xga_updatemapping(svga_t *svga) { xga_t *xga = &svga->xga; - //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, opmodereset1 = %d, access mode = %x, map = %x.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->op_mode_reset, xga->access_mode, svga->gdcreg[6] & 0x0c); + //pclog("OpMode = %x, linear base = %08x, aperture cntl = %d, access mode = %x, map = %x, endian reverse = %d, a5test = %d, XGA on = %d.\n", xga->op_mode, xga->linear_base, xga->aperture_cntl, xga->access_mode, svga->gdcreg[6] & 0x0c, xga->linear_endian_reverse, xga->a5_test, xga->on); if (((xga->op_mode & 7) >= 4) || ((xga->op_mode & 7) == 0)) { - if (xga->aperture_cntl == 1) { + if ((xga->aperture_cntl == 1) || (xga->aperture_cntl == 2)) { mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + if (xga->aperture_cntl == 1) + mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); + else + mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); + mem_mapping_enable(&xga->video_mapping); xga->banked_mask = 0xffff; if (!xga->linear_endian_reverse) @@ -63,38 +134,23 @@ xga_updatemapping(svga_t *svga) mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); mem_mapping_enable(&xga->video_mapping); xga->banked_mask = 0xffff; - if (xga->pos_regs[4] & 1) - mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); - else if (xga->base_addr_1mb) + if (xga->base_addr_1mb) mem_mapping_set_addr(&xga->linear_mapping, xga->base_addr_1mb, 0x100000); else mem_mapping_set_addr(&xga->linear_mapping, xga->linear_base, 0x400000); if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && xga->on) xga->linear_endian_reverse = 1; - else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on) + else if (((xga->op_mode & 7) == 0) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test && !xga->on) { xga->linear_endian_reverse = 1; - xga->on = 0; - vga_on = !xga->on; - } else { - mem_mapping_disable(&svga->mapping); - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - mem_mapping_disable(&xga->linear_mapping); + } + if (xga->a5_test && (xga->access_mode & 8) && !xga->linear_endian_reverse) { + xga->on = 0; + vga_on = !xga->on; + } } - } else { - xga->on = 0; - vga_on = !xga->on; - mem_mapping_disable(&svga->mapping); - if (xga->aperture_cntl == 2) - mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); - else - mem_mapping_set_addr(&xga->video_mapping, 0xa0000, 0x10000); - mem_mapping_enable(&xga->video_mapping); - xga->banked_mask = 0xffff; - mem_mapping_disable(&xga->linear_mapping); - //pclog("XGA opmode (not extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl); + //pclog("XGA opmode (extended) = %d, disp mode = %d, aperture = %d.\n", xga->op_mode & 7, xga->disp_cntl_2 & 7, xga->aperture_cntl); } + //pclog("VGA on = %d.\n", vga_on); } void @@ -126,19 +182,19 @@ xga_recalctimings(svga_t *svga) xga->ma_latch = xga->disp_start_addr; - switch (xga->clk_sel_1 & 0x0c) { + switch ((xga->clk_sel_1 >> 2) & 3) { case 0: if (xga->clk_sel_2 & 0x80) { - svga->clock = (cpuclock * (double) (1ULL << 32)) / 41539000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 41539000.0; } else { - svga->clock = (cpuclock * (double) (1ULL << 32)) / 25175000.0; + svga->clock = (cpuclock * (double) (1ull << 32)) / 25175000.0; } break; - case 4: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 28322000.0; + case 1: + svga->clock = (cpuclock * (double) (1ull << 32)) / 28322000.0; break; - case 0x0c: - svga->clock = (cpuclock * (double) (1ULL << 32)) / 44900000.0; + case 3: + svga->clock = (cpuclock * (double) (1ull << 32)) / 44900000.0; break; } } @@ -309,7 +365,7 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) if ((xga->sprite_pos >= 0) && (xga->sprite_pos <= 16)) { if ((xga->op_mode & 7) >= 5) xga->cursor_data_on = 1; - else if (xga->sprite_pos >= 1) + else if ((xga->sprite_pos >= 1) || ((xga->disp_cntl_2 & 7) > 3)) xga->cursor_data_on = 1; else if (xga->aperture_cntl == 0) { if (xga->linear_endian_reverse && !(xga->access_mode & 8)) @@ -474,7 +530,10 @@ xga_ext_inb(uint16_t addr, void *p) case 0x0f: switch (xga->regs_idx) { case 4: - ret = (xga->bus & DEVICE_MCA) ? 1 : 0; + if (xga->bus & DEVICE_MCA) + ret = 0x01; /*32-bit MCA*/ + else + ret = 0x10; /*16-bit ISA*/ break; case 0x10: ret = xga->htotal & 0xff; @@ -653,6 +712,16 @@ xga_ext_inb(uint16_t addr, void *p) ret = xga->clk_sel_2; break; + case 0x74: + if (xga->bus & DEVICE_MCA) + ret = xga->regs[xga->regs_idx]; + else { + ret = (xga->dma_channel << 1); + if (xga->dma_channel) + ret |= 1; + } + break; + default: ret = xga->regs[xga->regs_idx]; break; @@ -678,15 +747,35 @@ xga_ext_inb(uint16_t addr, void *p) dat = xga->vram[(addr + 1) & (xga->vram_mask - 1)] & 0xff; \ dat |= (xga->vram[(addr) & (xga->vram_mask - 1)] << 8); +#define READL(addr, dat) \ + dat = *(uint32_t *) &xga->vram[(addr) & (xga->vram_mask)]; + +#define READL_REVERSE(addr, dat) \ + dat = xga->vram[(addr + 3) & (xga->vram_mask - 3)] & 0xff; \ + dat |= (xga->vram[(addr + 2) & (xga->vram_mask - 3)] << 8); \ + dat |= (xga->vram[(addr + 1) & (xga->vram_mask - 3)] << 16); \ + dat |= (xga->vram[(addr) & (xga->vram_mask - 3)] << 24); + #define WRITEW(addr, dat) \ *(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; +#define WRITEL(addr, dat) \ + *(uint32_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; + #define WRITEW_REVERSE(addr, dat) \ xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \ xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; +#define WRITEL_REVERSE(addr, dat) \ + xga->vram[((addr + 3)) & (xga->vram_mask - 3)] = dat & 0xff; \ + xga->vram[((addr + 2)) & (xga->vram_mask - 3)] = dat >> 8; \ + xga->vram[((addr + 1)) & (xga->vram_mask - 3)] = dat >> 16; \ + xga->vram[((addr)) & (xga->vram_mask - 3)] = dat >> 24; \ + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; + #define ROP(mix, d, s) \ { \ switch ((mix) ? (xga->accel.frgd_mix & 0x1f) : (xga->accel.bkgd_mix & 0x1f)) { \ @@ -859,6 +948,23 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int byte = mem_readw_phys(addr); } return byte; + case 5: /*24-bit*/ + addr += (y * (width << 2)); + addr += (x << 2); + if (!skip) { + if ((xga->accel.px_map_format[map] & 8)) { + if (xga->linear_endian_reverse) { + READL(addr, byte); + } else { + READL_REVERSE(addr, byte); + } + } else { + READL(addr, byte); + } + } else { + byte = mem_readl_phys(addr); + } + return byte; } return 0; @@ -936,6 +1042,22 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } mem_writew_phys(addr, pixel); break; + case 5: /*24-bit*/ + addr += (y * (width) << 2); + addr += (x << 2); + if (!skip) { + if ((xga->accel.px_map_format[map] & 8)) { + if (xga->linear_endian_reverse) { + WRITEL(addr, pixel); + } else { + WRITEL_REVERSE(addr, pixel); + } + } else { + WRITEL(addr, pixel); + } + } + mem_writel_phys(addr, pixel); + break; } } @@ -1447,6 +1569,10 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) if (addr >= 0x1800) { switch (addr & 0x7f) { + case 0x11: + xga->accel.control = val; + break; + case 0x12: xga->accel.px_map_idx = val & 3; break; @@ -1923,11 +2049,21 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) uint8_t temp = 0; addr &= 0x1fff; - if (addr < 0x1800) { - temp = xga->bios_rom.rom[addr]; + if (!xga_has_vga) + temp = xga->bios_rom.rom[addr]; + else + temp = xga->vga_bios_rom.rom[addr]; } else { switch (addr & 0x7f) { + case 0x11: + temp = xga->accel.control; + if (xga->accel.control & 0x08) + temp |= 0x10; + else + temp &= ~0x10; + break; + case 0x20: temp = xga->accel.bres_err_term & 0xff; break; @@ -2092,8 +2228,9 @@ xga_render_overscan_left(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; + uint32_t *line_ptr = svga->monitor->target_buffer->line[xga->displine + svga->y_add]; for (int i = 0; i < svga->x_add; i++) - buffer32->line[xga->displine + svga->y_add][i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; } static void @@ -2107,9 +2244,10 @@ xga_render_overscan_right(xga_t *xga, svga_t *svga) if (svga->scrblank || (xga->h_disp == 0)) return; - right = (overscan_x >> 1); + uint32_t *line_ptr = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp]; + right = (overscan_x >> 1); for (int i = 0; i < right; i++) - buffer32->line[xga->displine + svga->y_add][svga->x_add + xga->h_disp + i] = svga->overscan_color; + *line_ptr++ = svga->overscan_color; } static void @@ -2122,7 +2260,7 @@ xga_render_8bpp(xga_t *xga, svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; + p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2159,7 +2297,7 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) return; if (xga->changedvram[xga->ma >> 12] || xga->changedvram[(xga->ma >> 12) + 1] || svga->fullchange) { - p = &buffer32->line[xga->displine + svga->y_add][svga->x_add]; + p = &svga->monitor->target_buffer->line[xga->displine + svga->y_add][svga->x_add]; if (xga->firstline_draw == 2000) xga->firstline_draw = xga->displine; @@ -2524,7 +2662,7 @@ xga_poll(xga_t *xga, svga_t *svga) } xga->vc++; - xga->vc &= 2047; + xga->vc &= 0x7ff; if (xga->vc == xga->split) { if (xga->interlace && xga->oddeven) @@ -2683,8 +2821,149 @@ static uint8_t xga_pos_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; + uint8_t ret; - return (xga_mca_read(addr, svga)); + if (xga_has_vga) { + switch (addr) { + case 0x0100: + case 0x0101: + if (xga->instance_isa == xga->instance_num) + ret = xga->pos_regs[addr & 7]; + else + ret = 0xff; + break; + case 0x0102: + case 0x0105: + ret = xga->pos_regs[addr & 7]; + break; + case 0x0106: + ret = xga->pos_idx >> 8; + break; + case 0x0107: + ret = xga->pos_idx & 0xff; + break; + case 0x0103: + if (!(xga->pos_idx & 3)) { + ret = xga->pos_regs[3]; + } else + ret = 0; + //pclog("POS IDX for 0103 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); + break; + case 0x0104: + switch (xga->pos_idx & 3) { + case 0: + ret = xga->pos_regs[4]; + break; + case 1: + ret = xga->pos_regs[0]; + break; + case 2: + ret = xga->pos_regs[1]; + break; + case 3: + ret = 0; + break; + } + //pclog("POS IDX for 0104 = %d, ret = %02x.\n", xga->pos_idx & 3, ret); + break; + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + if (xga->instance_isa == xga->instance_num) + ret = xga->instance_isa; + else + ret = 0; + + ret |= xga->isa_pos_enable; + break; + } + } else { + switch (addr) { + case 0x0100: + case 0x0101: + ret = xga->pos_regs[addr & 7]; + break; + case 0x0103: + ret = xga->pos_regs[3] | 7; + ret |= (xga->dma_channel << 3); + break; + case 0x0102: + case 0x0104: + case 0x0105: + case 0x0106: + case 0x0107: + ret = (xga_mca_read(addr, svga)); + break; + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + if (xga->instance_isa == xga->instance_num) + ret = xga->instance_isa; + else + ret = 0; + + ret |= xga->isa_pos_enable; + break; + } + } + return ret; +} + +static void +xga_pos_out(uint16_t addr, uint8_t val, void *priv) +{ + svga_t *svga = (svga_t *) priv; + xga_t *xga = &svga->xga; + + if (xga_has_vga) { + switch (addr) { + case 0x0106: + xga->pos_idx = (xga->pos_idx & 0x00ff) | (val << 8); + break; + case 0x0107: + xga->pos_idx = (xga->pos_idx & 0xff00) | (val); + //pclog("POS IDX Write = %04x.\n", xga->pos_idx); + break; + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + xga->isa_pos_enable = val & 0x08; + break; + } + } else { + switch (addr) { + case 0x0108: + case 0x0109: + case 0x010a: + case 0x010b: + case 0x010c: + case 0x010d: + case 0x010e: + case 0x010f: + xga->instance_num = addr & 7; + xga->isa_pos_enable = val & 0x08; + break; + } + } } static void @@ -2700,7 +2979,10 @@ static void uint32_t temp; uint8_t *rom = NULL; + xga->ext_mem_addr = device_get_config_hex16("ext_mem_addr"); + xga->instance_isa = device_get_config_int("instance"); xga->type = device_get_config_int("type"); + xga->dma_channel = device_get_config_int("dma"); xga->bus = info->flags; xga->vram_size = (1024 << 10); @@ -2739,12 +3021,16 @@ static void xga->rom_addr = 0; rom_init(&xga->bios_rom, xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, 0xc0000, 0x2000, 0x1fff, 0, MEM_MAPPING_EXTERNAL); } else { - video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa); - xga->pos_regs[2] = 1 | 0x0c | 0xf0; + if (xga_has_vga) { + rom_init(&xga->vga_bios_rom, INMOS_XGA_BIOS_PATH, 0xc0000, 0x8000, 0x7fff, 0, MEM_MAPPING_EXTERNAL); + } else + video_inform(VIDEO_FLAG_TYPE_SPECIAL, &timing_xga_isa); + + xga->pos_regs[2] = 1 | (xga->instance_isa << 1) | xga->ext_mem_addr; xga->instance = (xga->pos_regs[2] & 0x0e) >> 1; xga->pos_regs[4] = 1 | 2; xga->linear_base = ((xga->pos_regs[4] & 0xfe) * 0x1000000) + (xga->instance << 22); - xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); + xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); } mem_mapping_add(&xga->video_mapping, 0, 0, xga_readb, xga_readw, xga_readl, @@ -2755,7 +3041,7 @@ static void NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&xga->memio_mapping, 0, 0, xga_memio_readb, xga_memio_readw, xga_memio_readl, xga_memio_writeb, xga_memio_writew, xga_memio_writel, - xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); + xga_has_vga ? xga->vga_bios_rom.rom : xga->bios_rom.rom, MEM_MAPPING_EXTERNAL, svga); mem_mapping_disable(&xga->video_mapping); mem_mapping_disable(&xga->linear_mapping); @@ -2768,13 +3054,41 @@ static void mca_add(xga_mca_read, xga_mca_write, xga_mca_feedb, xga_mca_reset, svga); } else { io_sethandler(0x0100, 0x0008, xga_pos_in, NULL, NULL, NULL, NULL, NULL, svga); + if (xga_has_vga) + io_sethandler(0x0106, 0x0002, NULL, NULL, NULL, xga_pos_out, NULL, NULL, svga); + io_sethandler(0x2100 + (xga->instance << 4), 0x0010, xga_ext_inb, NULL, NULL, xga_ext_outb, NULL, NULL, svga); + io_sethandler(0x0108, 0x0008, xga_pos_in, NULL, NULL, xga_pos_out, NULL, NULL, svga); mem_mapping_set_addr(&xga->memio_mapping, xga->rom_addr + 0x1c00 + (xga->instance * 0x80), 0x80); } - return svga; } +static void + * + svga_xga_init(const device_t *info) +{ + svga_t *svga = malloc(sizeof(svga_t)); + memset(svga, 0, sizeof(svga_t)); + + video_inform(VIDEO_FLAG_TYPE_XGA, &timing_xga_isa); + + svga_init(info, svga, svga, 1 << 18, /*256kB*/ + NULL, + svga_xga_in, svga_xga_out, + NULL, + NULL); + + io_sethandler(0x03c0, 0x0020, svga_xga_in, NULL, NULL, svga_xga_out, NULL, NULL, svga); + + svga->bpp = 8; + svga->miscout = 1; + xga_has_vga = 1; + xga_enabled = 1; + + return xga_init(info); +} + static void xga_close(void *p) { @@ -2793,6 +3107,12 @@ xga_available(void) return rom_present(XGA_BIOS_PATH) && rom_present(XGA2_BIOS_PATH); } +static int +inmos_xga_available(void) +{ + return rom_present(INMOS_XGA_BIOS_PATH); +} + static void xga_speed_changed(void *p) { @@ -2809,7 +3129,7 @@ xga_force_redraw(void *p) svga->fullchange = svga->monitor->mon_changeframecount; } -static const device_config_t xga_configuration[] = { +static const device_config_t xga_mca_configuration[] = { // clang-format off { .name = "type", @@ -2835,6 +3155,91 @@ static const device_config_t xga_configuration[] = { // clang-format on }; +static const device_config_t xga_isa_configuration[] = { + // clang-format off + { + .name = "type", + .description = "XGA type", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { + .description = "XGA-1", + .value = 0 + }, + { + .description = "XGA-2", + .value = 1 + }, + { .description = "" } + } + }, + { + .name = "instance", + .description = "Instance", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 6, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "0 (2100h-210Fh)", .value = 0 }, + { .description = "1 (2110h-211Fh)", .value = 1 }, + { .description = "2 (2120h-212Fh)", .value = 2 }, + { .description = "3 (2130h-213Fh)", .value = 3 }, + { .description = "4 (2140h-214Fh)", .value = 4 }, + { .description = "5 (2150h-215Fh)", .value = 5 }, + { .description = "6 (2160h-216Fh)", .value = 6 }, + { .description = "7 (2170h-217Fh)", .value = 7 }, + { .description = "" } + }, + }, + { + .name = "ext_mem_addr", + .description = "MMIO address", + .type = CONFIG_HEX16, + .default_string = "", + .default_int = 0x00f0, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "C800h", .value = 0x0040 }, + { .description = "CA00h", .value = 0x0050 }, + { .description = "CC00h", .value = 0x0060 }, + { .description = "CE00h", .value = 0x0070 }, + { .description = "D000h", .value = 0x0080 }, + { .description = "D200h", .value = 0x0090 }, + { .description = "D400h", .value = 0x00a0 }, + { .description = "D600h", .value = 0x00b0 }, + { .description = "D800h", .value = 0x00c0 }, + { .description = "DA00h", .value = 0x00d0 }, + { .description = "DC00h", .value = 0x00e0 }, + { .description = "DE00h", .value = 0x00f0 }, + { .description = "" } + }, + }, + { + .name = "dma", + .description = "DMA channel", + .type = CONFIG_SELECTION, + .default_string = "", + .default_int = 7, + .file_filter = "", + .spinner = { 0 }, + .selection = { + { .description = "Disabled", .value = 0 }, + { .description = "DMA 6", .value = 6 }, + { .description = "DMA 7", .value = 7 }, + { .description = "" } + }, + }, + { .name = "", .description = "", .type = CONFIG_END } +// clang-format on +}; + const device_t xga_device = { .name = "XGA (MCA)", .internal_name = "xga_mca", @@ -2846,7 +3251,7 @@ const device_t xga_device = { { .available = xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = xga_configuration + .config = xga_mca_configuration }; const device_t xga_isa_device = { @@ -2860,13 +3265,27 @@ const device_t xga_isa_device = { { .available = xga_available }, .speed_changed = xga_speed_changed, .force_redraw = xga_force_redraw, - .config = xga_configuration + .config = xga_isa_configuration +}; + +const device_t inmos_isa_device = { + .name = "INMOS XGA (ISA)", + .internal_name = "inmos_xga_isa", + .flags = DEVICE_ISA | DEVICE_AT, + .local = 0, + .init = svga_xga_init, + .close = xga_close, + .reset = xga_reset, + { .available = inmos_xga_available }, + .speed_changed = xga_speed_changed, + .force_redraw = xga_force_redraw, + .config = xga_isa_configuration }; void xga_device_add(void) { - if (!xga_enabled) + if (!xga_enabled || (xga_has_vga && xga_enabled)) return; if (machine_has_bus(machine, MACHINE_BUS_MCA)) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 9c18ae72a..6946eff04 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -711,6 +711,7 @@ VIDOBJ := agpgart.o video.o \ vid_vga.o \ vid_ati_eeprom.o \ vid_ati18800.o vid_ati28800.o \ + vid_ati_mach8.o \ vid_ati_mach64.o vid_ati68860_ramdac.o \ vid_bt48x_ramdac.o \ vid_av9194.o vid_icd2061.o vid_ics2494.o vid_ics2595.o \ From ac762f6a8617a8953cee0df3b994a9e3ccb4b4fe Mon Sep 17 00:00:00 2001 From: TC1995 Date: Fri, 14 Jul 2023 23:57:50 +0200 Subject: [PATCH 08/44] S3 Pre-ViRGE changes: Cosmetic cleanups and fixed the 512KB and 1MB settings of the 864/964+ chips, thus no longer thinking they were 2MB. --- src/video/vid_s3.c | 61 +++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 453972402..7f840d134 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -498,7 +498,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; #define READ_PIXTRANS_WORD \ - if (s3->bpp == 0 && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ } else { \ @@ -506,7 +506,7 @@ static void s3_visionx68_video_engine_op(uint32_t cpu_dat, s3_t *s3); } #define READ_PIXTRANS_LONG \ - if (s3->bpp == 0 && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ temp = svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx)) & s3->vram_mask]; \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 1)) & s3->vram_mask] << 8); \ temp |= (svga->vram[dword_remap(svga, (s3->accel.dest + s3->accel.cx + 2)) & s3->vram_mask] << 16); \ @@ -2671,6 +2671,7 @@ s3_out(uint16_t addr, uint8_t val, void *p) return; if ((s3->chip <= S3_86C924) && (svga->crtcreg >= 0x50)) return; + old = svga->crtc[svga->crtcreg]; svga->crtc[svga->crtcreg] = val; @@ -3075,7 +3076,7 @@ s3_recalctimings(svga_t *svga) svga->rowoffset |= 0x100; } if (!svga->rowoffset) - svga->rowoffset = 256; + svga->rowoffset = 0x100; if ((s3->chip == S3_VISION964) || (s3->chip == S3_86C928)) { if (s3->card_type == S3_ELSAWIN2KPROX_964) @@ -3120,7 +3121,7 @@ s3_recalctimings(svga_t *svga) } } else { if (s3->card_type == S3_NUMBER9_9FX_531) { - if (svga->hdisp == 1600 && s3->width == 1600) + if ((svga->hdisp == 1600) && (s3->width == 1600)) s3->width = 800; } } @@ -3131,10 +3132,10 @@ s3_recalctimings(svga_t *svga) } } - if ((svga->crtc[0x43] & 0x08) && (s3->color_16bit == 0) && (s3->chip <= S3_86C805)) { + if ((svga->crtc[0x43] & 0x08) && !s3->color_16bit && (s3->chip <= S3_86C805)) { s3->color_16bit = 1; - s3->width = 1024; - } else if (!(svga->crtc[0x43] & 0x08) && (s3->color_16bit == 1) && (s3->chip <= S3_86C805)) { + s3->width = 1024; + } else if (!(svga->crtc[0x43] & 0x08) && s3->color_16bit && (s3->chip <= S3_86C805)) { s3->color_16bit = 0; if (s3->chip <= S3_86C924) { if (s3->accel.advfunc_cntl & 4) @@ -4808,9 +4809,9 @@ polygon_setup(s3_t *s3) } #define READ(addr, dat) \ - if (s3->bpp == 0 && !s3->color_16bit) \ + if ((s3->bpp == 0) && !s3->color_16bit) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ - else if (s3->bpp == 1 || s3->color_16bit) \ + else if ((s3->bpp == 1) || s3->color_16bit) \ dat = vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)]; \ else if (s3->bpp == 2) \ dat = svga->vram[dword_remap(svga, addr) & s3->vram_mask]; \ @@ -5660,10 +5661,10 @@ polygon_setup(s3_t *s3) } #define WRITE(addr, dat) \ - if (s3->bpp == 0 && !s3->color_16bit) { \ + if ((s3->bpp == 0) && !s3->color_16bit) { \ svga->vram[dword_remap(svga, addr) & s3->vram_mask] = dat; \ svga->changedvram[(dword_remap(svga, addr) & s3->vram_mask) >> 12] = svga->monitor->mon_changeframecount; \ - } else if (s3->bpp == 1 || s3->color_16bit) { \ + } else if ((s3->bpp == 1) || s3->color_16bit) { \ vram_w[dword_remap_w(svga, addr) & (s3->vram_mask >> 1)] = dat; \ svga->changedvram[(dword_remap_w(svga, addr) & (s3->vram_mask >> 1)) >> 11] = svga->monitor->mon_changeframecount; \ } else if (s3->bpp == 2) { \ @@ -6123,7 +6124,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dat_count = 0; if (cpu_input && (((s3->accel.multifunc[0xa] & 0xc0) != 0x80) || (!(s3->accel.cmd & 2)))) { - if ((s3->bpp == 3) && count == 2) { + if ((s3->bpp == 3) && (count == 2)) { if (s3->accel.dat_count) { cpu_dat = ((cpu_dat & 0xffff) << 16) | s3->accel.dat_buf; count = 4; @@ -6133,20 +6134,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.dat_count = 1; } } - if (s3->bpp == 1 || s3->color_16bit) + if ((s3->bpp == 1) || s3->color_16bit) count >>= 1; if (s3->bpp == 3) count >>= 2; } - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) rd_mask &= 0xff; - else if (s3->bpp == 1 || s3->color_16bit) + else if ((s3->bpp == 1) || s3->color_16bit) rd_mask &= 0xffff; - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) compare &= 0xff; - if (s3->bpp == 1 || s3->color_16bit) + if ((s3->bpp == 1) || s3->color_16bit) compare &= 0xffff; switch (s3->accel.cmd & 0x600) { @@ -6212,6 +6213,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ cpu_dat >>= 8; else cpu_dat >>= 16; + if (!s3->accel.ssv_len) break; @@ -6259,18 +6261,16 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cx = s3->accel.cur_x & 0x7ff; s3->accel.cy = s3->accel.cur_y & 0x7ff; - if (s3->accel.cur_x & 0x800) { + if (s3->accel.cur_x & 0x800) s3->accel.cx |= ~0x7ff; - } - if (s3->accel.cur_y & 0x800) { + + if (s3->accel.cur_y & 0x800) s3->accel.cy |= ~0x7ff; - } s3->accel.sy = s3->accel.maj_axis_pcnt; - if (s3_cpu_src(s3)) { + if (s3_cpu_src(s3)) return; /*Wait for data from CPU*/ - } } frgd_mix = (s3->accel.frgd_mix >> 5) & 3; bkgd_mix = (s3->accel.bkgd_mix >> 5) & 3; @@ -6305,11 +6305,10 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat <<= 1; mix_dat |= 1; - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; - else { + else cpu_dat >>= 16; - } if (!s3->accel.sy) { break; @@ -6351,13 +6350,13 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ s3->accel.cur_y = s3->accel.cy; } else /*Bresenham*/ { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && count == 16) { /*Stupid undocumented 0xB2E8 on 911/924*/ + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && (count == 16)) { /*Stupid undocumented 0xB2E8 on 911/924*/ count = s3->accel.maj_axis_pcnt + 1; s3->accel.temp_cnt = 16; } while (count-- && s3->accel.sy >= 0) { - if (s3->accel.b2e8_pix && s3_cpu_src(s3) && s3->accel.temp_cnt == 0) { + if (s3->accel.b2e8_pix && s3_cpu_src(s3) && !s3->accel.temp_cnt) { mix_dat >>= 16; s3->accel.temp_cnt = 16; } @@ -6567,7 +6566,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ mix_dat |= 1; } - if (s3->bpp == 0 && !s3->color_16bit) + if ((s3->bpp == 0) && !s3->color_16bit) cpu_dat >>= 8; else { cpu_dat >>= 16; @@ -8021,7 +8020,7 @@ s3_init(const device_t *info) switch (vram) { case 0: /* 512 kB */ svga->vram_mask = (1 << 19) - 1; - svga->vram_max = 2 << 20; + svga->vram_max = 1 << 19; break; case 1: /* 1 MB */ /* VRAM in first MB, mirrored in 2nd MB, 3rd and 4th MBs are open bus. @@ -8029,7 +8028,7 @@ s3_init(const device_t *info) This works with the #9 9FX BIOS, and matches how my real Trio64 behaves, but does not work with the Phoenix EDO BIOS. Possibly an FPM/EDO difference? */ svga->vram_mask = (1 << 20) - 1; - svga->vram_max = 2 << 20; + svga->vram_max = 1 << 20; break; case 2: default: /*2 MB */ From 5d07468a67f60d462f0c7cdb992a96c8074419c1 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 15 Jul 2023 00:06:57 +0200 Subject: [PATCH 09/44] S3 ViRGE change: Attempt at fixing a small but breaking bug reported by a Discord user. --- src/video/vid_s3_virge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_s3_virge.c b/src/video/vid_s3_virge.c index feaba7fe8..1eb1fa855 100644 --- a/src/video/vid_s3_virge.c +++ b/src/video/vid_s3_virge.c @@ -3372,7 +3372,7 @@ s3_virge_triangle(virge_t *virge, s3d_t *s3d_tri) state.base_w = s3d_tri->tws; tex_base = s3d_tri->tex_base; - for (uint8_t c = 9; c >= 0; c--) { + for (int c = 9; c >= 0; c--) { state.texture[c] = (uint16_t *) &virge->svga.vram[tex_base]; if (c <= state.max_d) tex_base += ((1 << (c * 2)) * tex_size[(s3d_tri->cmd_set >> 5) & 7]) / 2; From e676796367957dfa23e8b432ca0c091a655804fb Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sat, 15 Jul 2023 00:28:39 +0200 Subject: [PATCH 10/44] SoftFloat MMX: Added softfloat versions of the MMX instructions while preserving the non-softfloat ones. --- src/cpu/x86_ops_mmx.h | 5 +- src/cpu/x86_ops_mmx_arith.h | 1146 ++++++++++++++++++++++++++--------- src/cpu/x86_ops_mmx_cmp.h | 336 +++++++--- src/cpu/x86_ops_mmx_logic.h | 136 ++++- src/cpu/x86_ops_mmx_mov.h | 342 ++++++++--- src/cpu/x86_ops_mmx_pack.h | 570 ++++++++++++----- src/cpu/x86_ops_mmx_shift.h | 690 ++++++++++++++++----- 7 files changed, 2481 insertions(+), 744 deletions(-) diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index d270b728f..9942f653f 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -5,7 +5,10 @@ #define MMX_GETSRC() \ if (cpu_mod == 3) { \ - src = cpu_state.MM[cpu_rm]; \ + if (fpu_softfloat) \ + src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; \ + else \ + src = cpu_state.MM[cpu_rm]; \ CLOCK_CYCLES(1); \ } else { \ SEG_CHECK_READ(cpu_state.ea_seg); \ diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index e473f8ec5..eef1fe853 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,40 +1,76 @@ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; + if (fpu_softfloat) { + dst.b[0] += src.b[0]; + dst.b[1] += src.b[1]; + dst.b[2] += src.b[2]; + dst.b[3] += src.b[3]; + dst.b[4] += src.b[4]; + dst.b[5] += src.b[5]; + dst.b[6] += src.b[6]; + dst.b[7] += src.b[7]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + } return 0; } static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; + if (fpu_softfloat) { + dst.b[0] += src.b[0]; + dst.b[1] += src.b[1]; + dst.b[2] += src.b[2]; + dst.b[3] += src.b[3]; + dst.b[4] += src.b[4]; + dst.b[5] += src.b[5]; + dst.b[6] += src.b[6]; + dst.b[7] += src.b[7]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] += src.b[0]; + cpu_state.MM[cpu_reg].b[1] += src.b[1]; + cpu_state.MM[cpu_reg].b[2] += src.b[2]; + cpu_state.MM[cpu_reg].b[3] += src.b[3]; + cpu_state.MM[cpu_reg].b[4] += src.b[4]; + cpu_state.MM[cpu_reg].b[5] += src.b[5]; + cpu_state.MM[cpu_reg].b[6] += src.b[6]; + cpu_state.MM[cpu_reg].b[7] += src.b[7]; + } return 0; } @@ -42,61 +78,111 @@ opPADDB_a32(uint32_t fetchdat) static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; + if (fpu_softfloat) { + dst.w[0] += src.w[0]; + dst.w[1] += src.w[1]; + dst.w[2] += src.w[2]; + dst.w[3] += src.w[3]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + } return 0; } static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; + if (fpu_softfloat) { + dst.w[0] += src.w[0]; + dst.w[1] += src.w[1]; + dst.w[2] += src.w[2]; + dst.w[3] += src.w[3]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] += src.w[0]; + cpu_state.MM[cpu_reg].w[1] += src.w[1]; + cpu_state.MM[cpu_reg].w[2] += src.w[2]; + cpu_state.MM[cpu_reg].w[3] += src.w[3]; + } return 0; } static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + if (fpu_softfloat) { + dst.l[0] += src.l[0]; + dst.l[1] += src.l[1]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + } return 0; } static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; + if (fpu_softfloat) { + dst.l[0] += src.l[0]; + dst.l[1] += src.l[1]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] += src.l[0]; + cpu_state.MM[cpu_reg].l[1] += src.l[1]; + } return 0; } @@ -104,40 +190,82 @@ opPADDD_a32(uint32_t fetchdat) static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.sb[0] = SSATB(dst.sb[0] + src.sb[0]); + dst.sb[1] = SSATB(dst.sb[1] + src.sb[1]); + dst.sb[2] = SSATB(dst.sb[2] + src.sb[2]); + dst.sb[3] = SSATB(dst.sb[3] + src.sb[3]); + dst.sb[4] = SSATB(dst.sb[4] + src.sb[4]); + dst.sb[5] = SSATB(dst.sb[5] + src.sb[5]); + dst.sb[6] = SSATB(dst.sb[6] + src.sb[6]); + dst.sb[7] = SSATB(dst.sb[7] + src.sb[7]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + } return 0; } static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.sb[0] = SSATB(dst.sb[0] + src.sb[0]); + dst.sb[1] = SSATB(dst.sb[1] + src.sb[1]); + dst.sb[2] = SSATB(dst.sb[2] + src.sb[2]); + dst.sb[3] = SSATB(dst.sb[3] + src.sb[3]); + dst.sb[4] = SSATB(dst.sb[4] + src.sb[4]); + dst.sb[5] = SSATB(dst.sb[5] + src.sb[5]); + dst.sb[6] = SSATB(dst.sb[6] + src.sb[6]); + dst.sb[7] = SSATB(dst.sb[7] + src.sb[7]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); + } return 0; } @@ -145,40 +273,82 @@ opPADDSB_a32(uint32_t fetchdat) static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.b[0] = USATB(dst.b[0] + src.b[0]); + dst.b[1] = USATB(dst.b[1] + src.b[1]); + dst.b[2] = USATB(dst.b[2] + src.b[2]); + dst.b[3] = USATB(dst.b[3] + src.b[3]); + dst.b[4] = USATB(dst.b[4] + src.b[4]); + dst.b[5] = USATB(dst.b[5] + src.b[5]); + dst.b[6] = USATB(dst.b[6] + src.b[6]); + dst.b[7] = USATB(dst.b[7] + src.b[7]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + } return 0; } static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.b[0] = USATB(dst.b[0] + src.b[0]); + dst.b[1] = USATB(dst.b[1] + src.b[1]); + dst.b[2] = USATB(dst.b[2] + src.b[2]); + dst.b[3] = USATB(dst.b[3] + src.b[3]); + dst.b[4] = USATB(dst.b[4] + src.b[4]); + dst.b[5] = USATB(dst.b[5] + src.b[5]); + dst.b[6] = USATB(dst.b[6] + src.b[6]); + dst.b[7] = USATB(dst.b[7] + src.b[7]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); + } return 0; } @@ -186,32 +356,66 @@ opPADDUSB_a32(uint32_t fetchdat) static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.sw[0] = SSATW(dst.sw[0] + src.sw[0]); + dst.sw[1] = SSATW(dst.sw[1] + src.sw[1]); + dst.sw[2] = SSATW(dst.sw[2] + src.sw[2]); + dst.sw[3] = SSATW(dst.sw[3] + src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + } return 0; } static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.sw[0] = SSATW(dst.sw[0] + src.sw[0]); + dst.sw[1] = SSATW(dst.sw[1] + src.sw[1]); + dst.sw[2] = SSATW(dst.sw[2] + src.sw[2]); + dst.sw[3] = SSATW(dst.sw[3] + src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); + } return 0; } @@ -219,32 +423,66 @@ opPADDSW_a32(uint32_t fetchdat) static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.w[0] = USATW(dst.w[0] + src.w[0]); + dst.w[1] = USATW(dst.w[1] + src.w[1]); + dst.w[2] = USATW(dst.w[2] + src.w[2]); + dst.w[3] = USATW(dst.w[3] + src.w[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + } return 0; } static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.w[0] = USATW(dst.w[0] + src.w[0]); + dst.w[1] = USATW(dst.w[1] + src.w[1]); + dst.w[2] = USATW(dst.w[2] + src.w[2]); + dst.w[3] = USATW(dst.w[3] + src.w[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); + } return 0; } @@ -252,42 +490,86 @@ opPADDUSW_a32(uint32_t fetchdat) static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + if (dst.l[0] == 0x80008000 && src.l[0] == 0x80008000) + dst.l[0] = 0x80000000; + else + dst.sl[0] = ((int32_t) dst.sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst.sw[1] * (int32_t) src.sw[1]); + + if (dst.l[1] == 0x80008000 && src.l[1] == 0x80008000) + dst.l[1] = 0x80000000; + else + dst.sl[1] = ((int32_t) dst.sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst.sw[3] * (int32_t) src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + } return 0; } static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + if (dst.l[0] == 0x80008000 && src.l[0] == 0x80008000) + dst.l[0] = 0x80000000; + else + dst.sl[0] = ((int32_t) dst.sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst.sw[1] * (int32_t) src.sw[1]); + + if (dst.l[1] == 0x80008000 && src.l[1] == 0x80008000) + dst.l[1] = 0x80000000; + else + dst.sl[1] = ((int32_t) dst.sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst.sw[3] * (int32_t) src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) + cpu_state.MM[cpu_reg].l[0] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); + + if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) + cpu_state.MM[cpu_reg].l[1] = 0x80000000; + else + cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); + } return 0; } @@ -295,56 +577,100 @@ opPMADDWD_a32(uint32_t fetchdat) static int opPMULLW_a16(uint32_t fetchdat) { + uint32_t p1, p2, p3, p4; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); + MMX_GETSRC(); + + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + p1 = (uint32_t)(dst.w[0]) * (uint32_t)(src.w[0]); + p2 = (uint32_t)(dst.w[1]) * (uint32_t)(src.w[1]); + p3 = (uint32_t)(dst.w[2]) * (uint32_t)(src.w[2]); + p4 = (uint32_t)(dst.w[3]) * (uint32_t)(src.w[3]); + + dst.w[0] = p1 & 0xffff; + dst.w[1] = p2 & 0xffff; + dst.w[2] = p3 & 0xffff; + dst.w[3] = p4 & 0xffff; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } } return 0; } static int opPMULLW_a32(uint32_t fetchdat) { + uint32_t p1, p2, p3, p4; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); + MMX_GETSRC(); + + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + p1 = (uint32_t)(dst.w[0]) * (uint32_t)(src.w[0]); + p2 = (uint32_t)(dst.w[1]) * (uint32_t)(src.w[1]); + p3 = (uint32_t)(dst.w[2]) * (uint32_t)(src.w[2]); + p4 = (uint32_t)(dst.w[3]) * (uint32_t)(src.w[3]); + + dst.w[0] = p1 & 0xffff; + dst.w[1] = p2 & 0xffff; + dst.w[2] = p3 & 0xffff; + dst.w[3] = p4 & 0xffff; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; + cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; + cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; + cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] *= src.w[0]; + cpu_state.MM[cpu_reg].w[1] *= src.w[1]; + cpu_state.MM[cpu_reg].w[2] *= src.w[2]; + cpu_state.MM[cpu_reg].w[3] *= src.w[3]; + CLOCK_CYCLES(2); + } } return 0; } @@ -352,56 +678,100 @@ opPMULLW_a32(uint32_t fetchdat) static int opPMULHW_a16(uint32_t fetchdat) { + int32_t p1, p2, p3, p4; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; - CLOCK_CYCLES(2); + MMX_GETSRC(); + + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + p1 = (int32_t)(dst.w[0]) * (int32_t)(src.sw[0]); + p2 = (int32_t)(dst.w[1]) * (int32_t)(src.sw[1]); + p3 = (int32_t)(dst.w[2]) * (int32_t)(src.sw[2]); + p4 = (int32_t)(dst.w[3]) * (int32_t)(src.sw[3]); + + dst.w[0] = (uint16_t)(p1 >> 16); + dst.w[1] = (uint16_t)(p2 >> 16); + dst.w[2] = (uint16_t)(p3 >> 16); + dst.w[3] = (uint16_t)(p4 >> 16); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } } return 0; } static int opPMULHW_a32(uint32_t fetchdat) { + int32_t p1, p2, p3, p4; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } else { - MMX_REG src; + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; - CLOCK_CYCLES(2); + MMX_GETSRC(); + + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + p1 = (int32_t)(dst.w[0]) * (int32_t)(src.sw[0]); + p2 = (int32_t)(dst.w[1]) * (int32_t)(src.sw[1]); + p3 = (int32_t)(dst.w[2]) * (int32_t)(src.sw[2]); + p4 = (int32_t)(dst.w[3]) * (int32_t)(src.sw[3]); + + dst.w[0] = (uint16_t)(p1 >> 16); + dst.w[1] = (uint16_t)(p2 >> 16); + dst.w[2] = (uint16_t)(p3 >> 16); + dst.w[3] = (uint16_t)(p4 >> 16); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; + cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; + cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; + cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(2); + } } return 0; } @@ -409,252 +779,484 @@ opPMULHW_a32(uint32_t fetchdat) static int opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] -= src.b[0]; + dst.b[1] -= src.b[1]; + dst.b[2] -= src.b[2]; + dst.b[3] -= src.b[3]; + dst.b[4] -= src.b[4]; + dst.b[5] -= src.b[5]; + dst.b[6] -= src.b[6]; + dst.b[7] -= src.b[7]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; + } return 0; } static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] -= src.b[0]; + dst.b[1] -= src.b[1]; + dst.b[2] -= src.b[2]; + dst.b[3] -= src.b[3]; + dst.b[4] -= src.b[4]; + dst.b[5] -= src.b[5]; + dst.b[6] -= src.b[6]; + dst.b[7] -= src.b[7]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] -= src.b[0]; + cpu_state.MM[cpu_reg].b[1] -= src.b[1]; + cpu_state.MM[cpu_reg].b[2] -= src.b[2]; + cpu_state.MM[cpu_reg].b[3] -= src.b[3]; + cpu_state.MM[cpu_reg].b[4] -= src.b[4]; + cpu_state.MM[cpu_reg].b[5] -= src.b[5]; + cpu_state.MM[cpu_reg].b[6] -= src.b[6]; + cpu_state.MM[cpu_reg].b[7] -= src.b[7]; + } return 0; } static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] -= src.w[0]; + dst.w[1] -= src.w[1]; + dst.w[2] -= src.w[2]; + dst.w[3] -= src.w[3]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; + } return 0; } static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] -= src.w[0]; + dst.w[1] -= src.w[1]; + dst.w[2] -= src.w[2]; + dst.w[3] -= src.w[3]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] -= src.w[0]; + cpu_state.MM[cpu_reg].w[1] -= src.w[1]; + cpu_state.MM[cpu_reg].w[2] -= src.w[2]; + cpu_state.MM[cpu_reg].w[3] -= src.w[3]; + } return 0; } static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] -= src.l[0]; + dst.l[1] -= src.l[1]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; + } return 0; } static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] -= src.l[0]; + dst.l[1] -= src.l[1]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] -= src.l[0]; + cpu_state.MM[cpu_reg].l[1] -= src.l[1]; + } return 0; } static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src; - pclog("opPSUBSB_a16(%08X)\n", fetchdat); + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.sb[0] = SSATB(dst.sb[0] - src.sb[0]); + dst.sb[1] = SSATB(dst.sb[1] - src.sb[1]); + dst.sb[2] = SSATB(dst.sb[2] - src.sb[2]); + dst.sb[3] = SSATB(dst.sb[3] - src.sb[3]); + dst.sb[4] = SSATB(dst.sb[4] - src.sb[4]); + dst.sb[5] = SSATB(dst.sb[5] - src.sb[5]); + dst.sb[6] = SSATB(dst.sb[6] - src.sb[6]); + dst.sb[7] = SSATB(dst.sb[7] - src.sb[7]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); + } return 0; } static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src; - pclog("opPSUBSB_a32(%08X)\n", fetchdat); + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.sb[0] = SSATB(dst.sb[0] - src.sb[0]); + dst.sb[1] = SSATB(dst.sb[1] - src.sb[1]); + dst.sb[2] = SSATB(dst.sb[2] - src.sb[2]); + dst.sb[3] = SSATB(dst.sb[3] - src.sb[3]); + dst.sb[4] = SSATB(dst.sb[4] - src.sb[4]); + dst.sb[5] = SSATB(dst.sb[5] - src.sb[5]); + dst.sb[6] = SSATB(dst.sb[6] - src.sb[6]); + dst.sb[7] = SSATB(dst.sb[7] - src.sb[7]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); + } return 0; } static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst, result; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + result.q = 0; + result.b[0] = USATB(dst.b[0] - src.b[0]); + result.b[1] = USATB(dst.b[1] - src.b[1]); + result.b[2] = USATB(dst.b[2] - src.b[2]); + result.b[3] = USATB(dst.b[3] - src.b[3]); + result.b[4] = USATB(dst.b[4] - src.b[4]); + result.b[5] = USATB(dst.b[5] - src.b[5]); + result.b[6] = USATB(dst.b[6] - src.b[6]); + result.b[7] = USATB(dst.b[7] - src.b[7]); + + fpu_state.st_space[cpu_reg].fraction = result.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); + } return 0; } static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst, result; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + result.q = 0; + result.b[0] = USATB(dst.b[0] - src.b[0]); + result.b[1] = USATB(dst.b[1] - src.b[1]); + result.b[2] = USATB(dst.b[2] - src.b[2]); + result.b[3] = USATB(dst.b[3] - src.b[3]); + result.b[4] = USATB(dst.b[4] - src.b[4]); + result.b[5] = USATB(dst.b[5] - src.b[5]); + result.b[6] = USATB(dst.b[6] - src.b[6]); + result.b[7] = USATB(dst.b[7] - src.b[7]); + + fpu_state.st_space[cpu_reg].fraction = result.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); + cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); + cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); + cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); + } return 0; } static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.sw[0] = SSATW(dst.sw[0] - src.sw[0]); + dst.sw[1] = SSATW(dst.sw[1] - src.sw[1]); + dst.sw[2] = SSATW(dst.sw[2] - src.sw[2]); + dst.sw[3] = SSATW(dst.sw[3] - src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); + } return 0; } static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.sw[0] = SSATW(dst.sw[0] - src.sw[0]); + dst.sw[1] = SSATW(dst.sw[1] - src.sw[1]); + dst.sw[2] = SSATW(dst.sw[2] - src.sw[2]); + dst.sw[3] = SSATW(dst.sw[3] - src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); + } return 0; } static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst, result; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + result.q = 0; + result.w[0] = USATW(dst.w[0] - src.w[0]); + result.w[1] = USATW(dst.w[1] - src.w[1]); + result.w[2] = USATW(dst.w[2] - src.w[2]); + result.w[3] = USATW(dst.w[3] - src.w[3]); + + fpu_state.st_space[cpu_reg].fraction = result.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + } return 0; } static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst, result; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + result.q = 0; + result.w[0] = USATW(dst.w[0] - src.w[0]); + result.w[1] = USATW(dst.w[1] - src.w[1]); + result.w[2] = USATW(dst.w[2] - src.w[2]); + result.w[3] = USATW(dst.w[3] - src.w[3]); + + fpu_state.st_space[cpu_reg].fraction = result.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); + cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); + cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); + cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); + } return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index 40ae66a9c..cdee0cfb5 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,217 +1,393 @@ static int opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = (dst.b[0] == src.b[0]) ? 0xff : 0; + dst.b[1] = (dst.b[1] == src.b[1]) ? 0xff : 0; + dst.b[2] = (dst.b[2] == src.b[2]) ? 0xff : 0; + dst.b[3] = (dst.b[3] == src.b[3]) ? 0xff : 0; + dst.b[4] = (dst.b[4] == src.b[4]) ? 0xff : 0; + dst.b[5] = (dst.b[5] == src.b[5]) ? 0xff : 0; + dst.b[6] = (dst.b[6] == src.b[6]) ? 0xff : 0; + dst.b[7] = (dst.b[7] == src.b[7]) ? 0xff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + } return 0; } static int opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = (dst.b[0] == src.b[0]) ? 0xff : 0; + dst.b[1] = (dst.b[1] == src.b[1]) ? 0xff : 0; + dst.b[2] = (dst.b[2] == src.b[2]) ? 0xff : 0; + dst.b[3] = (dst.b[3] == src.b[3]) ? 0xff : 0; + dst.b[4] = (dst.b[4] == src.b[4]) ? 0xff : 0; + dst.b[5] = (dst.b[5] == src.b[5]) ? 0xff : 0; + dst.b[6] = (dst.b[6] == src.b[6]) ? 0xff : 0; + dst.b[7] = (dst.b[7] == src.b[7]) ? 0xff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; + } return 0; } static int opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = (dst.sb[0] > src.sb[0]) ? 0xff : 0; + dst.b[1] = (dst.sb[1] > src.sb[1]) ? 0xff : 0; + dst.b[2] = (dst.sb[2] > src.sb[2]) ? 0xff : 0; + dst.b[3] = (dst.sb[3] > src.sb[3]) ? 0xff : 0; + dst.b[4] = (dst.sb[4] > src.sb[4]) ? 0xff : 0; + dst.b[5] = (dst.sb[5] > src.sb[5]) ? 0xff : 0; + dst.b[6] = (dst.sb[6] > src.sb[6]) ? 0xff : 0; + dst.b[7] = (dst.sb[7] > src.sb[7]) ? 0xff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + } return 0; } static int opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = (dst.sb[0] > src.sb[0]) ? 0xff : 0; + dst.b[1] = (dst.sb[1] > src.sb[1]) ? 0xff : 0; + dst.b[2] = (dst.sb[2] > src.sb[2]) ? 0xff : 0; + dst.b[3] = (dst.sb[3] > src.sb[3]) ? 0xff : 0; + dst.b[4] = (dst.sb[4] > src.sb[4]) ? 0xff : 0; + dst.b[5] = (dst.sb[5] > src.sb[5]) ? 0xff : 0; + dst.b[6] = (dst.sb[6] > src.sb[6]) ? 0xff : 0; + dst.b[7] = (dst.sb[7] > src.sb[7]) ? 0xff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; + cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; + } return 0; } static int opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] = (dst.w[0] == src.w[0]) ? 0xffff : 0; + dst.w[1] = (dst.w[1] == src.w[1]) ? 0xffff : 0; + dst.w[2] = (dst.w[2] == src.w[2]) ? 0xffff : 0; + dst.w[3] = (dst.w[3] == src.w[3]) ? 0xffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + } return 0; } static int opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] = (dst.w[0] == src.w[0]) ? 0xffff : 0; + dst.w[1] = (dst.w[1] == src.w[1]) ? 0xffff : 0; + dst.w[2] = (dst.w[2] == src.w[2]) ? 0xffff : 0; + dst.w[3] = (dst.w[3] == src.w[3]) ? 0xffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; + } return 0; } static int opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] = (dst.sw[0] > src.sw[0]) ? 0xffff : 0; + dst.w[1] = (dst.sw[1] > src.sw[1]) ? 0xffff : 0; + dst.w[2] = (dst.sw[2] > src.sw[2]) ? 0xffff : 0; + dst.w[3] = (dst.sw[3] > src.sw[3]) ? 0xffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + } return 0; } static int opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] = (dst.sw[0] > src.sw[0]) ? 0xffff : 0; + dst.w[1] = (dst.sw[1] > src.sw[1]) ? 0xffff : 0; + dst.w[2] = (dst.sw[2] > src.sw[2]) ? 0xffff : 0; + dst.w[3] = (dst.sw[3] > src.sw[3]) ? 0xffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; + cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; + } return 0; } static int opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] = (dst.l[0] == src.l[0]) ? 0xffffffff : 0; + dst.l[1] = (dst.l[1] == src.l[1]) ? 0xffffffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + } return 0; } static int opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] = (dst.l[0] == src.l[0]) ? 0xffffffff : 0; + dst.l[1] = (dst.l[1] == src.l[1]) ? 0xffffffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; + } return 0; } static int opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] = (dst.sl[0] > src.sl[0]) ? 0xffffffff : 0; + dst.l[1] = (dst.sl[1] > src.sl[1]) ? 0xffffffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + } return 0; } static int opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src; - + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] = (dst.sl[0] > src.sl[0]) ? 0xffffffff : 0; + dst.l[1] = (dst.sl[1] > src.sl[1]) ? 0xffffffff : 0; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; + cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; + } return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index c22c820c1..19f8a3e04 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,99 +1,203 @@ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q &= src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q &= src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q &= src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q &= src.q; + return 0; } static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q = ~dst.q & src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } static int opPANDN_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q = ~dst.q & src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; + return 0; } static int opPOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q |= src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q |= src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q |= src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q |= src.q; + return 0; } static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q ^= src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].q ^= src.q; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.q ^= src.q; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else + cpu_state.MM[cpu_reg].q ^= src.q; + return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index bb51573e6..fad58898f 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -1,48 +1,94 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat) { + uint32_t dst; + MMX_REG op; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op.l[0] = cpu_state.regs[cpu_rm].l; + op.l[1] = 0; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op.l[0] = dst; + op.l[1] = 0; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(2); + } } else { - uint32_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; - - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(2); + } } return 0; } static int opMOVD_l_mm_a32(uint32_t fetchdat) { + uint32_t dst; + MMX_REG op; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op.l[0] = cpu_state.regs[cpu_rm].l; + op.l[1] = 0; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op.l[0] = dst; + op.l[1] = 0; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(2); + } } else { - uint32_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; - - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].l[0] = dst; + cpu_state.MM[cpu_reg].l[1] = 0; + CLOCK_CYCLES(2); + } } return 0; } @@ -50,38 +96,80 @@ opMOVD_l_mm_a32(uint32_t fetchdat) static int opMOVD_mm_l_a16(uint32_t fetchdat) { + MMX_REG op; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + cpu_state.regs[cpu_rm].l = op.l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + writememl(easeg, cpu_state.eaaddr, op.l[0]); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + CLOCK_CYCLES(2); + } } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } } return 0; } static int opMOVD_mm_l_a32(uint32_t fetchdat) { + MMX_REG op; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + cpu_state.regs[cpu_rm].l = op.l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + writememl(easeg, cpu_state.eaaddr, op.l[0]); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + CLOCK_CYCLES(2); + } } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } } return 0; } @@ -137,42 +225,88 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat) static int opMOVQ_q_mm_a16(uint32_t fetchdat) { + uint64_t dst; + MMX_REG src, op; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; + op.q = src.q; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op.q = dst; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(2); + } } else { - uint64_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } } return 0; } static int opMOVQ_q_mm_a32(uint32_t fetchdat) { + uint64_t dst; + MMX_REG src, op; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; + op.q = src.q; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + op.q = dst; + fpu_state.st_space[cpu_reg].fraction = op.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(2); + } } else { - uint64_t dst; - - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + cpu_state.MM[cpu_reg].q = dst; + CLOCK_CYCLES(2); + } } return 0; } @@ -183,16 +317,34 @@ opMOVQ_mm_q_a16(uint32_t fetchdat) MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + fpu_state.st_space[cpu_rm].fraction = fpu_state.st_space[cpu_reg].fraction; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, fpu_state.st_space[cpu_reg].fraction); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + CLOCK_CYCLES(2); + } } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } } return 0; } @@ -202,16 +354,34 @@ opMOVQ_mm_q_a32(uint32_t fetchdat) MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + if (cpu_mod == 3) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + fpu_state.st_space[cpu_rm].fraction = fpu_state.st_space[cpu_reg].fraction; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, fpu_state.st_space[cpu_reg].fraction); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + CLOCK_CYCLES(2); + } } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + if (cpu_mod == 3) { + cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); + if (cpu_state.abrt) + return 1; + CLOCK_CYCLES(2); + } } return 0; } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index f0180db91..25bc85a9a 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -1,44 +1,92 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { + uint32_t usrc; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + if (cpu_mod == 3) { + src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[1] = src.l[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[1] = src.l[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(2); + } } else { - uint32_t src; + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + usrc = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = usrc; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].l[1] = src; - - CLOCK_CYCLES(2); + CLOCK_CYCLES(2); + } } return 0; } static int opPUNPCKLDQ_a32(uint32_t fetchdat) { + uint32_t usrc; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + if (cpu_mod == 3) { + src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[1] = src.l[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[1] = src.l[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + CLOCK_CYCLES(2); + } } else { - uint32_t src; + if (cpu_mod == 3) { + cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + usrc = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + cpu_state.MM[cpu_reg].l[1] = usrc; - SEG_CHECK_READ(cpu_state.ea_seg); - src = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].l[1] = src; - - CLOCK_CYCLES(2); + CLOCK_CYCLES(2); + } } return 0; } @@ -46,177 +94,321 @@ opPUNPCKLDQ_a32(uint32_t fetchdat) static int opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); MMX_GETSRC(); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] = dst.l[1]; + dst.l[1] = src.l[1]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; + } return 0; } static int opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); MMX_GETSRC(); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.l[0] = dst.l[1]; + dst.l[1] = src.l[1]; + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; + cpu_state.MM[cpu_reg].l[1] = src.l[1]; + } return 0; } static int opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[7] = src.b[3]; + dst.b[6] = dst.b[3]; + dst.b[5] = src.b[2]; + dst.b[4] = dst.b[2]; + dst.b[3] = src.b[1]; + dst.b[2] = dst.b[1]; + dst.b[1] = src.b[0]; + dst.b[0] = dst.b[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + } return 0; } static int opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[7] = src.b[3]; + dst.b[6] = dst.b[3]; + dst.b[5] = src.b[2]; + dst.b[4] = dst.b[2]; + dst.b[3] = src.b[1]; + dst.b[2] = dst.b[1]; + dst.b[1] = src.b[0]; + dst.b[0] = dst.b[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[7] = src.b[3]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; + cpu_state.MM[cpu_reg].b[5] = src.b[2]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; + cpu_state.MM[cpu_reg].b[3] = src.b[1]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; + cpu_state.MM[cpu_reg].b[1] = src.b[0]; + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; + } return 0; } static int opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = dst.b[4]; + dst.b[1] = src.b[4]; + dst.b[2] = dst.b[5]; + dst.b[3] = src.b[5]; + dst.b[4] = dst.b[6]; + dst.b[5] = src.b[6]; + dst.b[6] = dst.b[7]; + dst.b[7] = src.b[7]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; + } return 0; } static int opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = dst.b[4]; + dst.b[1] = src.b[4]; + dst.b[2] = dst.b[5]; + dst.b[3] = src.b[5]; + dst.b[4] = dst.b[6]; + dst.b[5] = src.b[6]; + dst.b[6] = dst.b[7]; + dst.b[7] = src.b[7]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; + cpu_state.MM[cpu_reg].b[1] = src.b[4]; + cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; + cpu_state.MM[cpu_reg].b[3] = src.b[5]; + cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; + cpu_state.MM[cpu_reg].b[5] = src.b[6]; + cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; + cpu_state.MM[cpu_reg].b[7] = src.b[7]; + } return 0; } static int opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[3] = src.w[1]; + dst.w[2] = dst.w[1]; + dst.w[1] = src.w[0]; + dst.w[0] = dst.w[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + } return 0; } static int opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[3] = src.w[1]; + dst.w[2] = dst.w[1]; + dst.w[1] = src.w[0]; + dst.w[0] = dst.w[0]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[3] = src.w[1]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; + cpu_state.MM[cpu_reg].w[1] = src.w[0]; + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; + } return 0; } static int opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_16(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] = dst.w[2]; + dst.w[1] = src.w[2]; + dst.w[2] = dst.w[3]; + dst.w[3] = src.w[3]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; + } return 0; } static int opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src; + MMX_REG src, dst; MMX_ENTER(); fetch_ea_32(fetchdat); + if (fpu_softfloat) + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; - + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.w[0] = dst.w[2]; + dst.w[1] = src.w[2]; + dst.w[2] = dst.w[3]; + dst.w[3] = src.w[3]; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; + cpu_state.MM[cpu_reg].w[1] = src.w[2]; + cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; + cpu_state.MM[cpu_reg].w[3] = src.w[3]; + } return 0; } @@ -228,17 +420,35 @@ opPACKSSWB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.sb[0] = SSATB(dst.sw[0]); + dst.sb[1] = SSATB(dst.sw[1]); + dst.sb[2] = SSATB(dst.sw[2]); + dst.sb[3] = SSATB(dst.sw[3]); + dst.sb[4] = SSATB(src.sw[0]); + dst.sb[5] = SSATB(src.sw[1]); + dst.sb[6] = SSATB(src.sw[2]); + dst.sb[7] = SSATB(src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + dst = cpu_state.MM[cpu_reg]; + + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + } return 0; } static int @@ -249,17 +459,35 @@ opPACKSSWB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.sb[0] = SSATB(dst.sw[0]); + dst.sb[1] = SSATB(dst.sw[1]); + dst.sb[2] = SSATB(dst.sw[2]); + dst.sb[3] = SSATB(dst.sw[3]); + dst.sb[4] = SSATB(src.sw[0]); + dst.sb[5] = SSATB(src.sw[1]); + dst.sb[6] = SSATB(src.sw[2]); + dst.sb[7] = SSATB(src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + dst = cpu_state.MM[cpu_reg]; + + cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); + cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); + cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); + cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); + cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); + cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); + cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); + cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); + } return 0; } @@ -271,17 +499,35 @@ opPACKUSWB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = USATB(dst.sw[0]); + dst.b[1] = USATB(dst.sw[1]); + dst.b[2] = USATB(dst.sw[2]); + dst.b[3] = USATB(dst.sw[3]); + dst.b[4] = USATB(src.sw[0]); + dst.b[5] = USATB(src.sw[1]); + dst.b[6] = USATB(src.sw[2]); + dst.b[7] = USATB(src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + dst = cpu_state.MM[cpu_reg]; + + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + } return 0; } static int @@ -292,17 +538,35 @@ opPACKUSWB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + dst.b[0] = USATB(dst.sw[0]); + dst.b[1] = USATB(dst.sw[1]); + dst.b[2] = USATB(dst.sw[2]); + dst.b[3] = USATB(dst.sw[3]); + dst.b[4] = USATB(src.sw[0]); + dst.b[5] = USATB(src.sw[1]); + dst.b[6] = USATB(src.sw[2]); + dst.b[7] = USATB(src.sw[3]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + dst = cpu_state.MM[cpu_reg]; + + cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); + cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); + cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); + cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); + cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); + cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); + cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); + cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); + } return 0; } @@ -314,13 +578,28 @@ opPACKSSDW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.sw[0] = SSATW(dst.sl[0]); + dst.sw[1] = SSATW(dst.sl[1]); + dst.sw[2] = SSATW(src.sl[0]); + dst.sw[3] = SSATW(src.sl[1]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + dst = cpu_state.MM[cpu_reg]; + + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + } return 0; } static int @@ -331,12 +610,27 @@ opPACKSSDW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); MMX_GETSRC(); - dst = cpu_state.MM[cpu_reg]; - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + + dst.sw[0] = SSATW(dst.sl[0]); + dst.sw[1] = SSATW(dst.sl[1]); + dst.sw[2] = SSATW(src.sl[0]); + dst.sw[3] = SSATW(src.sl[1]); + + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + dst = cpu_state.MM[cpu_reg]; + + cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); + cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); + cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); + cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); + } return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index c9ddc9b93..a3ede0021 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -16,37 +16,80 @@ opPSxxW_imm(uint32_t fetchdat) int reg = fetchdat & 7; int op = fetchdat & 0x38; int shift = (fetchdat >> 8) & 0xff; + MMX_REG dst; cpu_state.pc += 2; MMX_ENTER(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } switch (op) { case 0x10: /*PSRLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; + if (fpu_softfloat) { + if (shift > 15) + dst.q = 0; + else { + dst.w[0] >>= shift; + dst.w[1] >>= shift; + dst.w[2] >>= shift; + dst.w[3] >>= shift; + } + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] >>= shift; + cpu_state.MM[reg].w[1] >>= shift; + cpu_state.MM[reg].w[2] >>= shift; + cpu_state.MM[reg].w[3] >>= shift; + } } break; case 0x20: /*PSRAW*/ - if (shift > 15) - shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; + if (fpu_softfloat) { + if (shift > 15) + shift = 15; + dst.sw[0] >>= shift; + dst.sw[1] >>= shift; + dst.sw[2] >>= shift; + dst.sw[3] >>= shift; + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 15) + shift = 15; + cpu_state.MM[reg].sw[0] >>= shift; + cpu_state.MM[reg].sw[1] >>= shift; + cpu_state.MM[reg].sw[2] >>= shift; + cpu_state.MM[reg].sw[3] >>= shift; + } break; case 0x30: /*PSLLW*/ - if (shift > 15) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; + if (fpu_softfloat) { + if (shift > 15) + dst.q = 0; + else { + dst.w[0] <<= shift; + dst.w[1] <<= shift; + dst.w[2] <<= shift; + dst.w[3] <<= shift; + } + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 15) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].w[0] <<= shift; + cpu_state.MM[reg].w[1] <<= shift; + cpu_state.MM[reg].w[2] <<= shift; + cpu_state.MM[reg].w[3] <<= shift; + } } break; default: @@ -62,127 +105,239 @@ opPSxxW_imm(uint32_t fetchdat) static int opPSLLW_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 15) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.w[0] <<= shift; + dst.w[1] <<= shift; + dst.w[2] <<= shift; + dst.w[3] <<= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } } - return 0; } static int opPSLLW_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 15) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.w[0] <<= shift; + dst.w[1] <<= shift; + dst.w[2] <<= shift; + dst.w[3] <<= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] <<= shift; + cpu_state.MM[cpu_reg].w[1] <<= shift; + cpu_state.MM[cpu_reg].w[2] <<= shift; + cpu_state.MM[cpu_reg].w[3] <<= shift; + } } - return 0; } static int opPSRLW_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 15) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.w[0] >>= shift; + dst.w[1] >>= shift; + dst.w[2] >>= shift; + dst.w[3] >>= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } } - return 0; } static int opPSRLW_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 15) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.w[0] >>= shift; + dst.w[1] >>= shift; + dst.w[2] >>= shift; + dst.w[3] >>= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 15) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].w[0] >>= shift; + cpu_state.MM[cpu_reg].w[1] >>= shift; + cpu_state.MM[cpu_reg].w[2] >>= shift; + cpu_state.MM[cpu_reg].w[3] >>= shift; + } } - return 0; } static int opPSRAW_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 15) - shift = 15; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 15) { + src.q = 15; + } + shift = src.b[0]; + dst.sw[0] >>= shift; + dst.sw[1] >>= shift; + dst.sw[2] >>= shift; + dst.sw[3] >>= shift; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; + if (shift > 15) + shift = 15; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + } return 0; } static int opPSRAW_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 15) - shift = 15; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 15) { + src.q = 15; + } + shift = src.b[0]; + dst.sw[0] >>= shift; + dst.sw[1] >>= shift; + dst.sw[2] >>= shift; + dst.sw[3] >>= shift; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; + if (shift > 15) + shift = 15; + cpu_state.MM[cpu_reg].sw[0] >>= shift; + cpu_state.MM[cpu_reg].sw[1] >>= shift; + cpu_state.MM[cpu_reg].sw[2] >>= shift; + cpu_state.MM[cpu_reg].sw[3] >>= shift; + } return 0; } @@ -192,31 +347,68 @@ opPSxxD_imm(uint32_t fetchdat) int reg = fetchdat & 7; int op = fetchdat & 0x38; int shift = (fetchdat >> 8) & 0xff; + MMX_REG dst; cpu_state.pc += 2; MMX_ENTER(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } switch (op) { case 0x10: /*PSRLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; + if (fpu_softfloat) { + if (shift > 31) + dst.q = 0; + else { + dst.l[0] >>= shift; + dst.l[1] >>= shift; + } + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] >>= shift; + cpu_state.MM[reg].l[1] >>= shift; + } } break; case 0x20: /*PSRAD*/ - if (shift > 31) - shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; + if (fpu_softfloat) { + if (shift > 31) + shift = 31; + dst.sl[0] >>= shift; + dst.sl[1] >>= shift; + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 31) + shift = 31; + cpu_state.MM[reg].sl[0] >>= shift; + cpu_state.MM[reg].sl[1] >>= shift; + } break; case 0x30: /*PSLLD*/ - if (shift > 31) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; + if (fpu_softfloat) { + if (shift > 31) + dst.q = 0; + else { + dst.l[0] <<= shift; + dst.l[1] <<= shift; + } + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 31) + cpu_state.MM[reg].q = 0; + else { + cpu_state.MM[reg].l[0] <<= shift; + cpu_state.MM[reg].l[1] <<= shift; + } } break; default: @@ -232,115 +424,215 @@ opPSxxD_imm(uint32_t fetchdat) static int opPSLLD_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 31) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.l[0] <<= shift; + dst.l[1] <<= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } } - return 0; } static int opPSLLD_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 31) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.l[0] <<= shift; + dst.l[1] <<= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] <<= shift; + cpu_state.MM[cpu_reg].l[1] <<= shift; + } } - return 0; } static int opPSRLD_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 31) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.l[0] >>= shift; + dst.l[1] >>= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } } - return 0; } static int opPSRLD_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 31) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.l[0] >>= shift; + dst.l[1] >>= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + + if (shift > 31) + cpu_state.MM[cpu_reg].q = 0; + else { + cpu_state.MM[cpu_reg].l[0] >>= shift; + cpu_state.MM[cpu_reg].l[1] >>= shift; + } } - return 0; } static int opPSRAD_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 31) - shift = 31; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 31) { + src.q = 31; + } + shift = src.b[0]; + dst.sl[0] >>= shift; + dst.sl[1] >>= shift; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; + if (shift > 31) + shift = 31; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + } return 0; } static int opPSRAD_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 31) - shift = 31; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 31) { + src.q = 31; + } + shift = src.b[0]; + dst.sl[0] >>= shift; + dst.sl[1] >>= shift; + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; + if (shift > 31) + shift = 31; + cpu_state.MM[cpu_reg].sl[0] >>= shift; + cpu_state.MM[cpu_reg].sl[1] >>= shift; + } return 0; } @@ -350,27 +642,59 @@ opPSxxQ_imm(uint32_t fetchdat) int reg = fetchdat & 7; int op = fetchdat & 0x38; int shift = (fetchdat >> 8) & 0xff; + MMX_REG dst; cpu_state.pc += 2; MMX_ENTER(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[reg].fraction; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } switch (op) { case 0x10: /*PSRLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q >>= shift; + if (fpu_softfloat) { + if (shift > 63) + dst.q = 0; + else + dst.q >>= shift; + + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q >>= shift; + } break; case 0x20: /*PSRAW*/ if (shift > 63) shift = 63; - cpu_state.MM[reg].sq >>= shift; + + if (fpu_softfloat) { + dst.sq >>= shift; + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else + cpu_state.MM[reg].sq >>= shift; break; case 0x30: /*PSLLW*/ - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q <<= shift; + if (fpu_softfloat) { + if (shift > 63) + dst.q = 0; + else + dst.q <<= shift; + + fpu_state.st_space[reg].fraction = dst.q; + fpu_state.st_space[reg].exp = 0xffff; + } else { + if (shift > 63) + cpu_state.MM[reg].q = 0; + else + cpu_state.MM[reg].q <<= shift; + } break; default: cpu_state.pc = cpu_state.oldpc; @@ -385,69 +709,133 @@ opPSxxQ_imm(uint32_t fetchdat) static int opPSLLQ_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 63) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.q <<= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + } return 0; } static int opPSLLQ_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 63) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.q <<= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q <<= shift; + } return 0; } static int opPSRLQ_a16(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 63) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.q >>= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + } return 0; } static int opPSRLQ_a32(uint32_t fetchdat) { + MMX_REG src, dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - MMX_GETSHIFT(); + if (fpu_softfloat) { + dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + MMX_GETSRC(); - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + if (src.q > 63) { + dst.q = 0; + } else { + shift = src.b[0]; + dst.q >>= shift; + } + fpu_state.st_space[cpu_reg].fraction = dst.q; + fpu_state.st_space[cpu_reg].exp = 0xffff; + } else { + MMX_GETSHIFT(); + if (shift > 63) + cpu_state.MM[cpu_reg].q = 0; + else + cpu_state.MM[cpu_reg].q >>= shift; + } return 0; } From 840b65c577d7e1b1735ea1ff07eba49f6932f94e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 15 Jul 2023 03:11:59 +0200 Subject: [PATCH 11/44] Fixed warnings into .h files. --- src/cpu/x86_ops_mmx_arith.h | 68 ++++++++++++++++++------------------- src/cpu/x86_ops_mmx_logic.h | 16 ++++----- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index eef1fe853..3077dbae0 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,7 +1,7 @@ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -39,7 +39,7 @@ opPADDB_a16(uint32_t fetchdat) static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -78,7 +78,7 @@ opPADDB_a32(uint32_t fetchdat) static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -107,7 +107,7 @@ opPADDW_a16(uint32_t fetchdat) static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -137,7 +137,7 @@ opPADDW_a32(uint32_t fetchdat) static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -163,7 +163,7 @@ opPADDD_a16(uint32_t fetchdat) static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -190,7 +190,7 @@ opPADDD_a32(uint32_t fetchdat) static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -231,7 +231,7 @@ opPADDSB_a16(uint32_t fetchdat) static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -273,7 +273,7 @@ opPADDSB_a32(uint32_t fetchdat) static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -314,7 +314,7 @@ opPADDUSB_a16(uint32_t fetchdat) static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -356,7 +356,7 @@ opPADDUSB_a32(uint32_t fetchdat) static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -389,7 +389,7 @@ opPADDSW_a16(uint32_t fetchdat) static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -423,7 +423,7 @@ opPADDSW_a32(uint32_t fetchdat) static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -456,7 +456,7 @@ opPADDUSW_a16(uint32_t fetchdat) static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -490,7 +490,7 @@ opPADDUSW_a32(uint32_t fetchdat) static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -533,7 +533,7 @@ opPMADDWD_a16(uint32_t fetchdat) static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -578,7 +578,7 @@ static int opPMULLW_a16(uint32_t fetchdat) { uint32_t p1, p2, p3, p4; - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -628,7 +628,7 @@ static int opPMULLW_a32(uint32_t fetchdat) { uint32_t p1, p2, p3, p4; - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -679,7 +679,7 @@ static int opPMULHW_a16(uint32_t fetchdat) { int32_t p1, p2, p3, p4; - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -729,7 +729,7 @@ static int opPMULHW_a32(uint32_t fetchdat) { int32_t p1, p2, p3, p4; - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -779,7 +779,7 @@ opPMULHW_a32(uint32_t fetchdat) static int opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -818,7 +818,7 @@ opPSUBB_a16(uint32_t fetchdat) static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -858,7 +858,7 @@ opPSUBB_a32(uint32_t fetchdat) static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -889,7 +889,7 @@ opPSUBW_a16(uint32_t fetchdat) static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -921,7 +921,7 @@ opPSUBW_a32(uint32_t fetchdat) static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -948,7 +948,7 @@ opPSUBD_a16(uint32_t fetchdat) static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -976,7 +976,7 @@ opPSUBD_a32(uint32_t fetchdat) static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -1015,7 +1015,7 @@ opPSUBSB_a16(uint32_t fetchdat) static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -1055,7 +1055,7 @@ opPSUBSB_a32(uint32_t fetchdat) static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src, dst, result; + MMX_REG src, dst = { 0 }, result; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -1095,7 +1095,7 @@ opPSUBUSB_a16(uint32_t fetchdat) static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src, dst, result; + MMX_REG src, dst = { 0 }, result; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -1136,7 +1136,7 @@ opPSUBUSB_a32(uint32_t fetchdat) static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -1167,7 +1167,7 @@ opPSUBSW_a16(uint32_t fetchdat) static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -1199,7 +1199,7 @@ opPSUBSW_a32(uint32_t fetchdat) static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src, dst, result; + MMX_REG src, dst = { 0 }, result; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -1231,7 +1231,7 @@ opPSUBUSW_a16(uint32_t fetchdat) static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src, dst, result; + MMX_REG src, dst = { 0 }, result; MMX_ENTER(); fetch_ea_32(fetchdat); diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index 19f8a3e04..9a9a9ee01 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,7 +1,7 @@ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -26,7 +26,7 @@ opPAND_a16(uint32_t fetchdat) static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -52,7 +52,7 @@ opPAND_a32(uint32_t fetchdat) static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -77,7 +77,7 @@ opPANDN_a16(uint32_t fetchdat) static int opPANDN_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -103,7 +103,7 @@ opPANDN_a32(uint32_t fetchdat) static int opPOR_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -128,7 +128,7 @@ opPOR_a16(uint32_t fetchdat) static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); @@ -154,7 +154,7 @@ opPOR_a32(uint32_t fetchdat) static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_16(fetchdat); @@ -179,7 +179,7 @@ opPXOR_a16(uint32_t fetchdat) static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src, dst = { 0 }; MMX_ENTER(); fetch_ea_32(fetchdat); From 324e5860a0865f1eb9ee1672b40ae76bfbc441aa Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 15 Jul 2023 03:14:13 +0200 Subject: [PATCH 12/44] The beginnings of the port of MartyPC's 808x emulation. --- src/cpu/808x/CMakeLists.txt | 16 +++ src/cpu/808x/queue.c | 190 ++++++++++++++++++++++++++++++++++++ src/cpu/808x/queue.h | 43 ++++++++ src/cpu/CMakeLists.txt | 3 + src/win/Makefile.mingw | 6 +- 5 files changed, 256 insertions(+), 2 deletions(-) create mode 100644 src/cpu/808x/CMakeLists.txt create mode 100644 src/cpu/808x/queue.c create mode 100644 src/cpu/808x/queue.h diff --git a/src/cpu/808x/CMakeLists.txt b/src/cpu/808x/CMakeLists.txt new file mode 100644 index 000000000..72aced128 --- /dev/null +++ b/src/cpu/808x/CMakeLists.txt @@ -0,0 +1,16 @@ +# +# 86Box A hypervisor and IBM PC system emulator that specializes in +# running old operating systems and software designed for IBM +# PC systems and compatibles from 1981 through fairly recent +# system designs based on the PCI bus. +# +# This file is part of the 86Box distribution. +# +# CMake build script. +# +# Authors: David Hrdlička, +# +# Copyright 2020-2021 David Hrdlička. +# + +add_library(808x.c OBJECT queue.c) diff --git a/src/cpu/808x/queue.c b/src/cpu/808x/queue.c new file mode 100644 index 000000000..2eebde0ce --- /dev/null +++ b/src/cpu/808x/queue.c @@ -0,0 +1,190 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * 808x CPU emulation, mostly ported from reenigne's XTCE, which + * is cycle-accurate. + * + * Authors: gloriouscow, + * Miran Grca, + * + * Copyright 2023 gloriouscow. + * Copyright 2023 Miran Grca. + */ +#include +#include +#include +#include +#include +#include + +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include "x86.h" +#include <86box/machine.h> +#include <86box/io.h> +#include <86box/mem.h> +#include <86box/rom.h> +#include <86box/nmi.h> +#include <86box/pic.h> +#include <86box/ppi.h> +#include <86box/timer.h> +#include <86box/gdbstub.h> +// #include "808x.h" +#include "queue.h" + +/* TODO: Move to cpu.h so this can eventually be reused for 286+ as well. */ +#define QUEUE_MAX 6 + +typedef struct queue_t +{ + size_t size; + size_t len; + size_t back; + size_t front; + uint8_t q[QUEUE_MAX]; + uint16_t preload; + queue_delay_t delay; +} queue_t; + +static queue_t queue; + +#ifdef ENABLE_QUEUE_LOG +int queue_do_log = ENABLE_QUEUE_LOG; + +static void +queue_log(const char *fmt, ...) +{ + va_list ap; + + if (queue_do_log) { + va_start(ap, fmt); + pclog_ex(fmt, ap); + va_end(ap); + } +} +#else +# define queue_log(fmt, ...) +#endif + +void +queue_set_size(size_t size) +{ + if (size > QUEUE_MAX) + fatal("Requested prefetch queue of %i bytes is too big\n", size); + + queue.size = size; +} + +size_t +queue_get_len(void) +{ + return queue.len; +} + +int +queue_is_full(void) +{ + return (queue.len != queue.size); +} + +uint16_t +queue_get_preload(void) +{ + uint16_t ret = queue.preload; + queue.preload = 0x0000; + + return ret; +} + +int +queue_has_preload(void) +{ + return (queue.preload & FLAG_PRELOADED) ? 1 : 0; +} + +void +queue_set_preload(void) +{ + uint8_t byte; + + if (queue.len > 0) { + byte = queue_pop(); + queue.preload = ((uint16_t) byte) | FLAG_PRELOADED; + } else + fatal("Tried to preload with empty queue\n"); +} + +void +queue_push8(uint8_t byte) +{ + if (queue.len < queue.size) { + queue.q[queue.front] = byte; + queue.front = (queue.front + 1) % queue.size; + queue.len++; + + if (queue.len == 3) + queue.delay = DELAY_WRITE; + else + queue.delay = DELAY_NONE; + } else + fatal("Queue overrun\n"); +} + +void +queue_push16(uint16_t word) +{ + queue_push8((uint8_t) (word & 0xff)); + queue_push8((uint8_t) ((word >> 8) & 0xff)); +} + +uint8_t +queue_pop(void) +{ + uint8_t byte = 0xff; + + if (queue.len > 0) { + byte = queue.q[queue.back]; + + queue.back = (queue.back + 1) % queue.size; + queue.len--; + + if (queue.len >= 3) + queue.delay = DELAY_READ; + else + queue.delay = DELAY_NONE; + } else + fatal("Queue underrun\n"); + + return byte; +} + +queue_delay_t +queue_get_delay(void) +{ + return queue.delay; +} + +void +queue_flush(void) +{ + memset(&queue, 0x00, sizeof(queue_t)); + + queue.delay = DELAY_NONE; +} + +void +queue_init(void) +{ + queue_flush(); + + if (is8086) + queue_set_size(6); + else + queue_set_size(4); +} diff --git a/src/cpu/808x/queue.h b/src/cpu/808x/queue.h new file mode 100644 index 000000000..544455784 --- /dev/null +++ b/src/cpu/808x/queue.h @@ -0,0 +1,43 @@ +/* + * 86Box A hypervisor and IBM PC system emulator that specializes in + * running old operating systems and software designed for IBM + * PC systems and compatibles from 1981 through fairly recent + * system designs based on the PCI bus. + * + * This file is part of the 86Box distribution. + * + * Prefetch queue implementation header. + * + * Authors: gloriouscow, + * Miran Grca, + * + * Copyright 2023 gloriouscow. + * Copyright 2023 Miran Grca. + */ +#ifndef EMU_QUEUE_H +#define EMU_QUEUE_H + +typedef enum queue_delay_t +{ + DELAY_READ, + DELAY_WRITE, + DELAY_NONE +} queue_delay_t; + +#define FLAG_PRELOADED 0x8000 + +extern void queue_set_size(size_t size); +extern size_t queue_get_len(void); +extern int queue_is_full(void); +extern uint16_t queue_get_preload(void); +extern int queue_has_preload(void); +extern void queue_set_preload(void); +extern void queue_push8(uint8_t byte); +extern void queue_push16(uint16_t word); +extern uint8_t queue_pop(void); +extern queue_delay_t queue_get_delay(void); +extern void queue_flush(void); + +extern void queue_init(void); + +#endif /*EMU_QUEUE_H*/ diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index 18aa06023..d1011504e 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -35,3 +35,6 @@ endif() add_subdirectory(softfloat) target_link_libraries(86Box softfloat) + +add_subdirectory(808x) +target_link_libraries(86Box 808x) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 6946eff04..c5f6c61ce 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -242,7 +242,7 @@ PROG := 86Box # Nothing should need changing from here on.. # ######################################################################### VPATH := $(EXPATH) . $(CODEGEN) minitrace cpu cpu/softfloat \ - cdrom chipset device disk disk/minivhd floppy \ + cpu/808x cdrom chipset device disk disk/minivhd floppy \ game machine mem printer \ sio sound \ sound/munt sound/munt/c_interface sound/munt/sha1 \ @@ -547,6 +547,8 @@ MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma. MEMOBJ := catalyst_flash.o i2c_eeprom.o intel_flash.o mem.o rom.o row.o smram.o spd.o sst_flash.o +CPU808XOBJ := queue.o + CPUOBJ := $(DYNARECOBJ) \ $(CGTOBJ) \ cpu.o cpu_table.o fpu.o x86.o \ @@ -773,7 +775,7 @@ ifeq ($(RTMIDI), y) SNDOBJ += midi_rtmidi.o endif -OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ +OBJ := $(MAINOBJ) $(CPU808XOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \ $(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \ $(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \ $(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ) From c1452654b0206810f04b258e2e3c9a6ffb5938d5 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Jul 2023 21:20:09 -0300 Subject: [PATCH 13/44] qt: Don't release keys during auto-repeat, closes #2712 --- src/qt/qt_mainwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/qt_mainwindow.cpp b/src/qt/qt_mainwindow.cpp index 30276922f..04317800d 100644 --- a/src/qt/qt_mainwindow.cpp +++ b/src/qt/qt_mainwindow.cpp @@ -1299,7 +1299,7 @@ MainWindow::keyReleaseEvent(QKeyEvent *event) fs_on_signal = false; } - if (!send_keyboard_input) + if (!send_keyboard_input || event->isAutoRepeat()) return; #ifdef Q_OS_MACOS From 21e20f1ea209cccddf187078f2b8ddf1a341906c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 02:24:36 +0200 Subject: [PATCH 14/44] MMX clean-ups, part 1. --- src/cpu/x86_ops_mmx_arith.h | 1221 ++++++++++++++--------------------- src/cpu/x86_ops_mmx_cmp.h | 372 +++++------ src/cpu/x86_ops_mmx_logic.h | 112 ++-- src/cpu/x86_ops_mmx_mov.h | 462 ++++++------- src/cpu/x86_ops_mmx_pack.h | 672 +++++++++---------- src/cpu/x86_ops_mmx_shift.h | 854 ++++++++++-------------- 6 files changed, 1595 insertions(+), 2098 deletions(-) diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index 3077dbae0..3ebe960f9 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -1,76 +1,54 @@ static int opPADDB_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); - if (fpu_softfloat) { - dst.b[0] += src.b[0]; - dst.b[1] += src.b[1]; - dst.b[2] += src.b[2]; - dst.b[3] += src.b[3]; - dst.b[4] += src.b[4]; - dst.b[5] += src.b[5]; - dst.b[6] += src.b[6]; - dst.b[7] += src.b[7]; + dst->b[0] += src.b[0]; + dst->b[1] += src.b[1]; + dst->b[2] += src.b[2]; + dst->b[3] += src.b[3]; + dst->b[4] += src.b[4]; + dst->b[5] += src.b[5]; + dst->b[6] += src.b[6]; + dst->b[7] += src.b[7]; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - } return 0; } static int opPADDB_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); - if (fpu_softfloat) { - dst.b[0] += src.b[0]; - dst.b[1] += src.b[1]; - dst.b[2] += src.b[2]; - dst.b[3] += src.b[3]; - dst.b[4] += src.b[4]; - dst.b[5] += src.b[5]; - dst.b[6] += src.b[6]; - dst.b[7] += src.b[7]; + dst->b[0] += src.b[0]; + dst->b[1] += src.b[1]; + dst->b[2] += src.b[2]; + dst->b[3] += src.b[3]; + dst->b[4] += src.b[4]; + dst->b[5] += src.b[5]; + dst->b[6] += src.b[6]; + dst->b[7] += src.b[7]; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] += src.b[0]; - cpu_state.MM[cpu_reg].b[1] += src.b[1]; - cpu_state.MM[cpu_reg].b[2] += src.b[2]; - cpu_state.MM[cpu_reg].b[3] += src.b[3]; - cpu_state.MM[cpu_reg].b[4] += src.b[4]; - cpu_state.MM[cpu_reg].b[5] += src.b[5]; - cpu_state.MM[cpu_reg].b[6] += src.b[6]; - cpu_state.MM[cpu_reg].b[7] += src.b[7]; - } return 0; } @@ -78,111 +56,88 @@ opPADDB_a32(uint32_t fetchdat) static int opPADDW_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); - if (fpu_softfloat) { - dst.w[0] += src.w[0]; - dst.w[1] += src.w[1]; - dst.w[2] += src.w[2]; - dst.w[3] += src.w[3]; + dst->w[0] += src.w[0]; + dst->w[1] += src.w[1]; + dst->w[2] += src.w[2]; + dst->w[3] += src.w[3]; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - } + return 0; } static int opPADDW_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); - if (fpu_softfloat) { - dst.w[0] += src.w[0]; - dst.w[1] += src.w[1]; - dst.w[2] += src.w[2]; - dst.w[3] += src.w[3]; + dst->w[0] += src.w[0]; + dst->w[1] += src.w[1]; + dst->w[2] += src.w[2]; + dst->w[3] += src.w[3]; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] += src.w[0]; - cpu_state.MM[cpu_reg].w[1] += src.w[1]; - cpu_state.MM[cpu_reg].w[2] += src.w[2]; - cpu_state.MM[cpu_reg].w[3] += src.w[3]; - } return 0; } static int opPADDD_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); - if (fpu_softfloat) { - dst.l[0] += src.l[0]; - dst.l[1] += src.l[1]; + dst->l[0] += src.l[0]; + dst->l[1] += src.l[1]; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; - } return 0; } static int opPADDD_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); - if (fpu_softfloat) { - dst.l[0] += src.l[0]; - dst.l[1] += src.l[1]; + dst->l[0] += src.l[0]; + dst->l[1] += src.l[1]; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] += src.l[0]; - cpu_state.MM[cpu_reg].l[1] += src.l[1]; - } return 0; } @@ -190,1073 +145,879 @@ opPADDD_a32(uint32_t fetchdat) static int opPADDSB_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sb[0] = SSATB(dst.sb[0] + src.sb[0]); - dst.sb[1] = SSATB(dst.sb[1] + src.sb[1]); - dst.sb[2] = SSATB(dst.sb[2] + src.sb[2]); - dst.sb[3] = SSATB(dst.sb[3] + src.sb[3]); - dst.sb[4] = SSATB(dst.sb[4] + src.sb[4]); - dst.sb[5] = SSATB(dst.sb[5] + src.sb[5]); - dst.sb[6] = SSATB(dst.sb[6] + src.sb[6]); - dst.sb[7] = SSATB(dst.sb[7] + src.sb[7]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); } + dst->sb[0] = SSATB(dst->sb[0] + src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] + src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] + src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] + src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] + src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] + src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDSB_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sb[0] = SSATB(dst.sb[0] + src.sb[0]); - dst.sb[1] = SSATB(dst.sb[1] + src.sb[1]); - dst.sb[2] = SSATB(dst.sb[2] + src.sb[2]); - dst.sb[3] = SSATB(dst.sb[3] + src.sb[3]); - dst.sb[4] = SSATB(dst.sb[4] + src.sb[4]); - dst.sb[5] = SSATB(dst.sb[5] + src.sb[5]); - dst.sb[6] = SSATB(dst.sb[6] + src.sb[6]); - dst.sb[7] = SSATB(dst.sb[7] + src.sb[7]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] + src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] + src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] + src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] + src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] + src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] + src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] + src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] + src.sb[7]); } + dst->sb[0] = SSATB(dst->sb[0] + src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] + src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] + src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] + src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] + src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] + src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDUSB_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] = USATB(dst.b[0] + src.b[0]); - dst.b[1] = USATB(dst.b[1] + src.b[1]); - dst.b[2] = USATB(dst.b[2] + src.b[2]); - dst.b[3] = USATB(dst.b[3] + src.b[3]); - dst.b[4] = USATB(dst.b[4] + src.b[4]); - dst.b[5] = USATB(dst.b[5] + src.b[5]); - dst.b[6] = USATB(dst.b[6] + src.b[6]); - dst.b[7] = USATB(dst.b[7] + src.b[7]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); } + dst->b[0] = USATB(dst->b[0] + src.b[0]); + dst->b[1] = USATB(dst->b[1] + src.b[1]); + dst->b[2] = USATB(dst->b[2] + src.b[2]); + dst->b[3] = USATB(dst->b[3] + src.b[3]); + dst->b[4] = USATB(dst->b[4] + src.b[4]); + dst->b[5] = USATB(dst->b[5] + src.b[5]); + dst->b[6] = USATB(dst->b[6] + src.b[6]); + dst->b[7] = USATB(dst->b[7] + src.b[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDUSB_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] = USATB(dst.b[0] + src.b[0]); - dst.b[1] = USATB(dst.b[1] + src.b[1]); - dst.b[2] = USATB(dst.b[2] + src.b[2]); - dst.b[3] = USATB(dst.b[3] + src.b[3]); - dst.b[4] = USATB(dst.b[4] + src.b[4]); - dst.b[5] = USATB(dst.b[5] + src.b[5]); - dst.b[6] = USATB(dst.b[6] + src.b[6]); - dst.b[7] = USATB(dst.b[7] + src.b[7]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] + src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] + src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] + src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] + src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] + src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] + src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] + src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] + src.b[7]); } + dst->b[0] = USATB(dst->b[0] + src.b[0]); + dst->b[1] = USATB(dst->b[1] + src.b[1]); + dst->b[2] = USATB(dst->b[2] + src.b[2]); + dst->b[3] = USATB(dst->b[3] + src.b[3]); + dst->b[4] = USATB(dst->b[4] + src.b[4]); + dst->b[5] = USATB(dst->b[5] + src.b[5]); + dst->b[6] = USATB(dst->b[6] + src.b[6]); + dst->b[7] = USATB(dst->b[7] + src.b[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDSW_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sw[0] = SSATW(dst.sw[0] + src.sw[0]); - dst.sw[1] = SSATW(dst.sw[1] + src.sw[1]); - dst.sw[2] = SSATW(dst.sw[2] + src.sw[2]); - dst.sw[3] = SSATW(dst.sw[3] + src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); } + dst->sw[0] = SSATW(dst->sw[0] + src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] + src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDSW_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sw[0] = SSATW(dst.sw[0] + src.sw[0]); - dst.sw[1] = SSATW(dst.sw[1] + src.sw[1]); - dst.sw[2] = SSATW(dst.sw[2] + src.sw[2]); - dst.sw[3] = SSATW(dst.sw[3] + src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] + src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] + src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] + src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] + src.sw[3]); } + dst->sw[0] = SSATW(dst->sw[0] + src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] + src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDUSW_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] = USATW(dst.w[0] + src.w[0]); - dst.w[1] = USATW(dst.w[1] + src.w[1]); - dst.w[2] = USATW(dst.w[2] + src.w[2]); - dst.w[3] = USATW(dst.w[3] + src.w[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); } + dst->w[0] = USATW(dst->w[0] + src.w[0]); + dst->w[1] = USATW(dst->w[1] + src.w[1]); + dst->w[2] = USATW(dst->w[2] + src.w[2]); + dst->w[3] = USATW(dst->w[3] + src.w[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPADDUSW_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] = USATW(dst.w[0] + src.w[0]); - dst.w[1] = USATW(dst.w[1] + src.w[1]); - dst.w[2] = USATW(dst.w[2] + src.w[2]); - dst.w[3] = USATW(dst.w[3] + src.w[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] + src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] + src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] + src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] + src.w[3]); } + dst->w[0] = USATW(dst->w[0] + src.w[0]); + dst->w[1] = USATW(dst->w[1] + src.w[1]); + dst->w[2] = USATW(dst->w[2] + src.w[2]); + dst->w[3] = USATW(dst->w[3] + src.w[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPMADDWD_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - if (dst.l[0] == 0x80008000 && src.l[0] == 0x80008000) - dst.l[0] = 0x80000000; - else - dst.sl[0] = ((int32_t) dst.sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst.sw[1] * (int32_t) src.sw[1]); - - if (dst.l[1] == 0x80008000 && src.l[1] == 0x80008000) - dst.l[1] = 0x80000000; - else - dst.sl[1] = ((int32_t) dst.sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst.sw[3] * (int32_t) src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); - - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); } + if (dst->l[0] == 0x80008000 && src.l[0] == 0x80008000) + dst->l[0] = 0x80000000; + else + dst->sl[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst->sw[1] * (int32_t) src.sw[1]); + + if (dst->l[1] == 0x80008000 && src.l[1] == 0x80008000) + dst->l[1] = 0x80000000; + else + dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPMADDWD_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - if (dst.l[0] == 0x80008000 && src.l[0] == 0x80008000) - dst.l[0] = 0x80000000; - else - dst.sl[0] = ((int32_t) dst.sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst.sw[1] * (int32_t) src.sw[1]); - - if (dst.l[1] == 0x80008000 && src.l[1] == 0x80008000) - dst.l[1] = 0x80000000; - else - dst.sl[1] = ((int32_t) dst.sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst.sw[3] * (int32_t) src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - if (cpu_state.MM[cpu_reg].l[0] == 0x80008000 && src.l[0] == 0x80008000) - cpu_state.MM[cpu_reg].l[0] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]); - - if (cpu_state.MM[cpu_reg].l[1] == 0x80008000 && src.l[1] == 0x80008000) - cpu_state.MM[cpu_reg].l[1] = 0x80000000; - else - cpu_state.MM[cpu_reg].sl[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]); } + if (dst->l[0] == 0x80008000 && src.l[0] == 0x80008000) + dst->l[0] = 0x80000000; + else + dst->sl[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + ((int32_t) dst->sw[1] * (int32_t) src.sw[1]); + + if (dst->l[1] == 0x80008000 && src.l[1] == 0x80008000) + dst->l[1] = 0x80000000; + else + dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPMULLW_a16(uint32_t fetchdat) { - uint32_t p1, p2, p3, p4; - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - - MMX_GETSRC(); - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - p1 = (uint32_t)(dst.w[0]) * (uint32_t)(src.w[0]); - p2 = (uint32_t)(dst.w[1]) * (uint32_t)(src.w[1]); - p3 = (uint32_t)(dst.w[2]) * (uint32_t)(src.w[2]); - p4 = (uint32_t)(dst.w[3]) * (uint32_t)(src.w[3]); - - dst.w[0] = p1 & 0xffff; - dst.w[1] = p2 & 0xffff; - dst.w[2] = p3 & 0xffff; - dst.w[3] = p4 & 0xffff; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } } + + if (cpu_mod == 3) + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + CLOCK_CYCLES(1); + } + dst->w[0] *= src.w[0]; + dst->w[1] *= src.w[1]; + dst->w[2] *= src.w[2]; + dst->w[3] *= src.w[3]; + CLOCK_CYCLES(1); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPMULLW_a32(uint32_t fetchdat) { - uint32_t p1, p2, p3, p4; - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - - MMX_GETSRC(); - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - p1 = (uint32_t)(dst.w[0]) * (uint32_t)(src.w[0]); - p2 = (uint32_t)(dst.w[1]) * (uint32_t)(src.w[1]); - p3 = (uint32_t)(dst.w[2]) * (uint32_t)(src.w[2]); - p4 = (uint32_t)(dst.w[3]) * (uint32_t)(src.w[3]); - - dst.w[0] = p1 & 0xffff; - dst.w[1] = p2 & 0xffff; - dst.w[2] = p3 & 0xffff; - dst.w[3] = p4 & 0xffff; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] *= cpu_state.MM[cpu_rm].w[0]; - cpu_state.MM[cpu_reg].w[1] *= cpu_state.MM[cpu_rm].w[1]; - cpu_state.MM[cpu_reg].w[2] *= cpu_state.MM[cpu_rm].w[2]; - cpu_state.MM[cpu_reg].w[3] *= cpu_state.MM[cpu_rm].w[3]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] *= src.w[0]; - cpu_state.MM[cpu_reg].w[1] *= src.w[1]; - cpu_state.MM[cpu_reg].w[2] *= src.w[2]; - cpu_state.MM[cpu_reg].w[3] *= src.w[3]; - CLOCK_CYCLES(2); - } } + + if (cpu_mod == 3) + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + CLOCK_CYCLES(1); + } + dst->w[0] *= src.w[0]; + dst->w[1] *= src.w[1]; + dst->w[2] *= src.w[2]; + dst->w[3] *= src.w[3]; + CLOCK_CYCLES(1); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPMULHW_a16(uint32_t fetchdat) { - int32_t p1, p2, p3, p4; - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - - MMX_GETSRC(); - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - p1 = (int32_t)(dst.w[0]) * (int32_t)(src.sw[0]); - p2 = (int32_t)(dst.w[1]) * (int32_t)(src.sw[1]); - p3 = (int32_t)(dst.w[2]) * (int32_t)(src.sw[2]); - p4 = (int32_t)(dst.w[3]) * (int32_t)(src.sw[3]); - - dst.w[0] = (uint16_t)(p1 >> 16); - dst.w[1] = (uint16_t)(p2 >> 16); - dst.w[2] = (uint16_t)(p3 >> 16); - dst.w[3] = (uint16_t)(p4 >> 16); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } } + + if (cpu_mod == 3) + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + CLOCK_CYCLES(1); + } + dst->w[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) >> 16; + dst->w[1] = ((int32_t) dst->sw[1] * (int32_t) src.sw[1]) >> 16; + dst->w[2] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) >> 16; + dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(1); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPMULHW_a32(uint32_t fetchdat) { - int32_t p1, p2, p3, p4; - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - - MMX_GETSRC(); - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - p1 = (int32_t)(dst.w[0]) * (int32_t)(src.sw[0]); - p2 = (int32_t)(dst.w[1]) * (int32_t)(src.sw[1]); - p3 = (int32_t)(dst.w[2]) * (int32_t)(src.sw[2]); - p4 = (int32_t)(dst.w[3]) * (int32_t)(src.sw[3]); - - dst.w[0] = (uint16_t)(p1 >> 16); - dst.w[1] = (uint16_t)(p2 >> 16); - dst.w[2] = (uint16_t)(p3 >> 16); - dst.w[3] = (uint16_t)(p4 >> 16); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) >> 16; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) >> 16; - CLOCK_CYCLES(2); - } } + + if (cpu_mod == 3) + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + else { + SEG_CHECK_READ(cpu_state.ea_seg); + src.l[0] = readmeml(easeg, cpu_state.eaaddr); + src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); + if (cpu_state.abrt) + return 0; + CLOCK_CYCLES(1); + } + dst->w[0] = ((int32_t) dst->sw[0] * (int32_t) src.sw[0]) >> 16; + dst->w[1] = ((int32_t) dst->sw[1] * (int32_t) src.sw[1]) >> 16; + dst->w[2] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) >> 16; + dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; + CLOCK_CYCLES(1); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBB_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] -= src.b[0]; - dst.b[1] -= src.b[1]; - dst.b[2] -= src.b[2]; - dst.b[3] -= src.b[3]; - dst.b[4] -= src.b[4]; - dst.b[5] -= src.b[5]; - dst.b[6] -= src.b[6]; - dst.b[7] -= src.b[7]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; } + + dst->b[0] -= src.b[0]; + dst->b[1] -= src.b[1]; + dst->b[2] -= src.b[2]; + dst->b[3] -= src.b[3]; + dst->b[4] -= src.b[4]; + dst->b[5] -= src.b[5]; + dst->b[6] -= src.b[6]; + dst->b[7] -= src.b[7]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBB_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] -= src.b[0]; - dst.b[1] -= src.b[1]; - dst.b[2] -= src.b[2]; - dst.b[3] -= src.b[3]; - dst.b[4] -= src.b[4]; - dst.b[5] -= src.b[5]; - dst.b[6] -= src.b[6]; - dst.b[7] -= src.b[7]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] -= src.b[0]; - cpu_state.MM[cpu_reg].b[1] -= src.b[1]; - cpu_state.MM[cpu_reg].b[2] -= src.b[2]; - cpu_state.MM[cpu_reg].b[3] -= src.b[3]; - cpu_state.MM[cpu_reg].b[4] -= src.b[4]; - cpu_state.MM[cpu_reg].b[5] -= src.b[5]; - cpu_state.MM[cpu_reg].b[6] -= src.b[6]; - cpu_state.MM[cpu_reg].b[7] -= src.b[7]; } + + dst->b[0] -= src.b[0]; + dst->b[1] -= src.b[1]; + dst->b[2] -= src.b[2]; + dst->b[3] -= src.b[3]; + dst->b[4] -= src.b[4]; + dst->b[5] -= src.b[5]; + dst->b[6] -= src.b[6]; + dst->b[7] -= src.b[7]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBW_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] -= src.w[0]; - dst.w[1] -= src.w[1]; - dst.w[2] -= src.w[2]; - dst.w[3] -= src.w[3]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; } + + dst->w[0] -= src.w[0]; + dst->w[1] -= src.w[1]; + dst->w[2] -= src.w[2]; + dst->w[3] -= src.w[3]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBW_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] -= src.w[0]; - dst.w[1] -= src.w[1]; - dst.w[2] -= src.w[2]; - dst.w[3] -= src.w[3]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] -= src.w[0]; - cpu_state.MM[cpu_reg].w[1] -= src.w[1]; - cpu_state.MM[cpu_reg].w[2] -= src.w[2]; - cpu_state.MM[cpu_reg].w[3] -= src.w[3]; } + + dst->w[0] -= src.w[0]; + dst->w[1] -= src.w[1]; + dst->w[2] -= src.w[2]; + dst->w[3] -= src.w[3]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBD_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] -= src.l[0]; - dst.l[1] -= src.l[1]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; } + + dst->l[0] -= src.l[0]; + dst->l[1] -= src.l[1]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBD_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] -= src.l[0]; - dst.l[1] -= src.l[1]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] -= src.l[0]; - cpu_state.MM[cpu_reg].l[1] -= src.l[1]; } + + dst->l[0] -= src.l[0]; + dst->l[1] -= src.l[1]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBSB_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sb[0] = SSATB(dst.sb[0] - src.sb[0]); - dst.sb[1] = SSATB(dst.sb[1] - src.sb[1]); - dst.sb[2] = SSATB(dst.sb[2] - src.sb[2]); - dst.sb[3] = SSATB(dst.sb[3] - src.sb[3]); - dst.sb[4] = SSATB(dst.sb[4] - src.sb[4]); - dst.sb[5] = SSATB(dst.sb[5] - src.sb[5]); - dst.sb[6] = SSATB(dst.sb[6] - src.sb[6]); - dst.sb[7] = SSATB(dst.sb[7] - src.sb[7]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); } + + dst->sb[0] = SSATB(dst->sb[0] - src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] - src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] - src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] - src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] - src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] - src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBSB_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sb[0] = SSATB(dst.sb[0] - src.sb[0]); - dst.sb[1] = SSATB(dst.sb[1] - src.sb[1]); - dst.sb[2] = SSATB(dst.sb[2] - src.sb[2]); - dst.sb[3] = SSATB(dst.sb[3] - src.sb[3]); - dst.sb[4] = SSATB(dst.sb[4] - src.sb[4]); - dst.sb[5] = SSATB(dst.sb[5] - src.sb[5]); - dst.sb[6] = SSATB(dst.sb[6] - src.sb[6]); - dst.sb[7] = SSATB(dst.sb[7] - src.sb[7]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sb[0] = SSATB(cpu_state.MM[cpu_reg].sb[0] - src.sb[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(cpu_state.MM[cpu_reg].sb[1] - src.sb[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(cpu_state.MM[cpu_reg].sb[2] - src.sb[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(cpu_state.MM[cpu_reg].sb[3] - src.sb[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(cpu_state.MM[cpu_reg].sb[4] - src.sb[4]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(cpu_state.MM[cpu_reg].sb[5] - src.sb[5]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(cpu_state.MM[cpu_reg].sb[6] - src.sb[6]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(cpu_state.MM[cpu_reg].sb[7] - src.sb[7]); } + + dst->sb[0] = SSATB(dst->sb[0] - src.sb[0]); + dst->sb[1] = SSATB(dst->sb[1] - src.sb[1]); + dst->sb[2] = SSATB(dst->sb[2] - src.sb[2]); + dst->sb[3] = SSATB(dst->sb[3] - src.sb[3]); + dst->sb[4] = SSATB(dst->sb[4] - src.sb[4]); + dst->sb[5] = SSATB(dst->sb[5] - src.sb[5]); + dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); + dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBUSB_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }, result; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - result.q = 0; - - result.b[0] = USATB(dst.b[0] - src.b[0]); - result.b[1] = USATB(dst.b[1] - src.b[1]); - result.b[2] = USATB(dst.b[2] - src.b[2]); - result.b[3] = USATB(dst.b[3] - src.b[3]); - result.b[4] = USATB(dst.b[4] - src.b[4]); - result.b[5] = USATB(dst.b[5] - src.b[5]); - result.b[6] = USATB(dst.b[6] - src.b[6]); - result.b[7] = USATB(dst.b[7] - src.b[7]); - - fpu_state.st_space[cpu_reg].fraction = result.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); } + + dst->b[0] = USATB(dst->b[0] - src.b[0]); + dst->b[1] = USATB(dst->b[1] - src.b[1]); + dst->b[2] = USATB(dst->b[2] - src.b[2]); + dst->b[3] = USATB(dst->b[3] - src.b[3]); + dst->b[4] = USATB(dst->b[4] - src.b[4]); + dst->b[5] = USATB(dst->b[5] - src.b[5]); + dst->b[6] = USATB(dst->b[6] - src.b[6]); + dst->b[7] = USATB(dst->b[7] - src.b[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBUSB_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }, result; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - result.q = 0; - - result.b[0] = USATB(dst.b[0] - src.b[0]); - result.b[1] = USATB(dst.b[1] - src.b[1]); - result.b[2] = USATB(dst.b[2] - src.b[2]); - result.b[3] = USATB(dst.b[3] - src.b[3]); - result.b[4] = USATB(dst.b[4] - src.b[4]); - result.b[5] = USATB(dst.b[5] - src.b[5]); - result.b[6] = USATB(dst.b[6] - src.b[6]); - result.b[7] = USATB(dst.b[7] - src.b[7]); - - fpu_state.st_space[cpu_reg].fraction = result.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = USATB(cpu_state.MM[cpu_reg].b[0] - src.b[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(cpu_state.MM[cpu_reg].b[1] - src.b[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(cpu_state.MM[cpu_reg].b[2] - src.b[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(cpu_state.MM[cpu_reg].b[3] - src.b[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(cpu_state.MM[cpu_reg].b[4] - src.b[4]); - cpu_state.MM[cpu_reg].b[5] = USATB(cpu_state.MM[cpu_reg].b[5] - src.b[5]); - cpu_state.MM[cpu_reg].b[6] = USATB(cpu_state.MM[cpu_reg].b[6] - src.b[6]); - cpu_state.MM[cpu_reg].b[7] = USATB(cpu_state.MM[cpu_reg].b[7] - src.b[7]); } + + dst->b[0] = USATB(dst->b[0] - src.b[0]); + dst->b[1] = USATB(dst->b[1] - src.b[1]); + dst->b[2] = USATB(dst->b[2] - src.b[2]); + dst->b[3] = USATB(dst->b[3] - src.b[3]); + dst->b[4] = USATB(dst->b[4] - src.b[4]); + dst->b[5] = USATB(dst->b[5] - src.b[5]); + dst->b[6] = USATB(dst->b[6] - src.b[6]); + dst->b[7] = USATB(dst->b[7] - src.b[7]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBSW_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sw[0] = SSATW(dst.sw[0] - src.sw[0]); - dst.sw[1] = SSATW(dst.sw[1] - src.sw[1]); - dst.sw[2] = SSATW(dst.sw[2] - src.sw[2]); - dst.sw[3] = SSATW(dst.sw[3] - src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); } + + dst->sw[0] = SSATW(dst->sw[0] - src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] - src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBSW_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sw[0] = SSATW(dst.sw[0] - src.sw[0]); - dst.sw[1] = SSATW(dst.sw[1] - src.sw[1]); - dst.sw[2] = SSATW(dst.sw[2] - src.sw[2]); - dst.sw[3] = SSATW(dst.sw[3] - src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].sw[0] = SSATW(cpu_state.MM[cpu_reg].sw[0] - src.sw[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(cpu_state.MM[cpu_reg].sw[1] - src.sw[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(cpu_state.MM[cpu_reg].sw[2] - src.sw[2]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(cpu_state.MM[cpu_reg].sw[3] - src.sw[3]); } + + dst->sw[0] = SSATW(dst->sw[0] - src.sw[0]); + dst->sw[1] = SSATW(dst->sw[1] - src.sw[1]); + dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); + dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBUSW_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }, result; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - result.q = 0; - - result.w[0] = USATW(dst.w[0] - src.w[0]); - result.w[1] = USATW(dst.w[1] - src.w[1]); - result.w[2] = USATW(dst.w[2] - src.w[2]); - result.w[3] = USATW(dst.w[3] - src.w[3]); - - fpu_state.st_space[cpu_reg].fraction = result.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); } + + dst->w[0] = USATW(dst->w[0] - src.w[0]); + dst->w[1] = USATW(dst->w[1] - src.w[1]); + dst->w[2] = USATW(dst->w[2] - src.w[2]); + dst->w[3] = USATW(dst->w[3] - src.w[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSUBUSW_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }, result; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - result.q = 0; - - result.w[0] = USATW(dst.w[0] - src.w[0]); - result.w[1] = USATW(dst.w[1] - src.w[1]); - result.w[2] = USATW(dst.w[2] - src.w[2]); - result.w[3] = USATW(dst.w[3] - src.w[3]); - - fpu_state.st_space[cpu_reg].fraction = result.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = USATW(cpu_state.MM[cpu_reg].w[0] - src.w[0]); - cpu_state.MM[cpu_reg].w[1] = USATW(cpu_state.MM[cpu_reg].w[1] - src.w[1]); - cpu_state.MM[cpu_reg].w[2] = USATW(cpu_state.MM[cpu_reg].w[2] - src.w[2]); - cpu_state.MM[cpu_reg].w[3] = USATW(cpu_state.MM[cpu_reg].w[3] - src.w[3]); } + + dst->w[0] = USATW(dst->w[0] - src.w[0]); + dst->w[1] = USATW(dst->w[1] - src.w[1]); + dst->w[2] = USATW(dst->w[2] - src.w[2]); + dst->w[3] = USATW(dst->w[3] - src.w[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index cdee0cfb5..4f64119a3 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -1,393 +1,349 @@ static int opPCMPEQB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] = (dst.b[0] == src.b[0]) ? 0xff : 0; - dst.b[1] = (dst.b[1] == src.b[1]) ? 0xff : 0; - dst.b[2] = (dst.b[2] == src.b[2]) ? 0xff : 0; - dst.b[3] = (dst.b[3] == src.b[3]) ? 0xff : 0; - dst.b[4] = (dst.b[4] == src.b[4]) ? 0xff : 0; - dst.b[5] = (dst.b[5] == src.b[5]) ? 0xff : 0; - dst.b[6] = (dst.b[6] == src.b[6]) ? 0xff : 0; - dst.b[7] = (dst.b[7] == src.b[7]) ? 0xff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; } + + dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0; + dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0; + dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0; + dst->b[3] = (dst->b[3] == src.b[3]) ? 0xff : 0; + dst->b[4] = (dst->b[4] == src.b[4]) ? 0xff : 0; + dst->b[5] = (dst->b[5] == src.b[5]) ? 0xff : 0; + dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; + dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPEQB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] = (dst.b[0] == src.b[0]) ? 0xff : 0; - dst.b[1] = (dst.b[1] == src.b[1]) ? 0xff : 0; - dst.b[2] = (dst.b[2] == src.b[2]) ? 0xff : 0; - dst.b[3] = (dst.b[3] == src.b[3]) ? 0xff : 0; - dst.b[4] = (dst.b[4] == src.b[4]) ? 0xff : 0; - dst.b[5] = (dst.b[5] == src.b[5]) ? 0xff : 0; - dst.b[6] = (dst.b[6] == src.b[6]) ? 0xff : 0; - dst.b[7] = (dst.b[7] == src.b[7]) ? 0xff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] == src.b[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] == src.b[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] == src.b[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] == src.b[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] == src.b[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] == src.b[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] == src.b[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] == src.b[7]) ? 0xff : 0; } + + dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0; + dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0; + dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0; + dst->b[3] = (dst->b[3] == src.b[3]) ? 0xff : 0; + dst->b[4] = (dst->b[4] == src.b[4]) ? 0xff : 0; + dst->b[5] = (dst->b[5] == src.b[5]) ? 0xff : 0; + dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; + dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPGTB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] = (dst.sb[0] > src.sb[0]) ? 0xff : 0; - dst.b[1] = (dst.sb[1] > src.sb[1]) ? 0xff : 0; - dst.b[2] = (dst.sb[2] > src.sb[2]) ? 0xff : 0; - dst.b[3] = (dst.sb[3] > src.sb[3]) ? 0xff : 0; - dst.b[4] = (dst.sb[4] > src.sb[4]) ? 0xff : 0; - dst.b[5] = (dst.sb[5] > src.sb[5]) ? 0xff : 0; - dst.b[6] = (dst.sb[6] > src.sb[6]) ? 0xff : 0; - dst.b[7] = (dst.sb[7] > src.sb[7]) ? 0xff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; } + + dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0; + dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0; + dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0; + dst->b[3] = (dst->sb[3] > src.sb[3]) ? 0xff : 0; + dst->b[4] = (dst->sb[4] > src.sb[4]) ? 0xff : 0; + dst->b[5] = (dst->sb[5] > src.sb[5]) ? 0xff : 0; + dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; + dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPGTB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.b[0] = (dst.sb[0] > src.sb[0]) ? 0xff : 0; - dst.b[1] = (dst.sb[1] > src.sb[1]) ? 0xff : 0; - dst.b[2] = (dst.sb[2] > src.sb[2]) ? 0xff : 0; - dst.b[3] = (dst.sb[3] > src.sb[3]) ? 0xff : 0; - dst.b[4] = (dst.sb[4] > src.sb[4]) ? 0xff : 0; - dst.b[5] = (dst.sb[5] > src.sb[5]) ? 0xff : 0; - dst.b[6] = (dst.sb[6] > src.sb[6]) ? 0xff : 0; - dst.b[7] = (dst.sb[7] > src.sb[7]) ? 0xff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].sb[0] > src.sb[0]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].sb[1] > src.sb[1]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].sb[2] > src.sb[2]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].sb[3] > src.sb[3]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].sb[4] > src.sb[4]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].sb[5] > src.sb[5]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].sb[6] > src.sb[6]) ? 0xff : 0; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].sb[7] > src.sb[7]) ? 0xff : 0; } + + dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0; + dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0; + dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0; + dst->b[3] = (dst->sb[3] > src.sb[3]) ? 0xff : 0; + dst->b[4] = (dst->sb[4] > src.sb[4]) ? 0xff : 0; + dst->b[5] = (dst->sb[5] > src.sb[5]) ? 0xff : 0; + dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; + dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPEQW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] = (dst.w[0] == src.w[0]) ? 0xffff : 0; - dst.w[1] = (dst.w[1] == src.w[1]) ? 0xffff : 0; - dst.w[2] = (dst.w[2] == src.w[2]) ? 0xffff : 0; - dst.w[3] = (dst.w[3] == src.w[3]) ? 0xffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; } + + dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0; + dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0; + dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; + dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPEQW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] = (dst.w[0] == src.w[0]) ? 0xffff : 0; - dst.w[1] = (dst.w[1] == src.w[1]) ? 0xffff : 0; - dst.w[2] = (dst.w[2] == src.w[2]) ? 0xffff : 0; - dst.w[3] = (dst.w[3] == src.w[3]) ? 0xffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].w[0] == src.w[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].w[1] == src.w[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].w[2] == src.w[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].w[3] == src.w[3]) ? 0xffff : 0; } + + dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0; + dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0; + dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; + dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPGTW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] = (dst.sw[0] > src.sw[0]) ? 0xffff : 0; - dst.w[1] = (dst.sw[1] > src.sw[1]) ? 0xffff : 0; - dst.w[2] = (dst.sw[2] > src.sw[2]) ? 0xffff : 0; - dst.w[3] = (dst.sw[3] > src.sw[3]) ? 0xffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; } + + dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0; + dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0; + dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; + dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPGTW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.w[0] = (dst.sw[0] > src.sw[0]) ? 0xffff : 0; - dst.w[1] = (dst.sw[1] > src.sw[1]) ? 0xffff : 0; - dst.w[2] = (dst.sw[2] > src.sw[2]) ? 0xffff : 0; - dst.w[3] = (dst.sw[3] > src.sw[3]) ? 0xffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = (cpu_state.MM[cpu_reg].sw[0] > src.sw[0]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[1] = (cpu_state.MM[cpu_reg].sw[1] > src.sw[1]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[2] = (cpu_state.MM[cpu_reg].sw[2] > src.sw[2]) ? 0xffff : 0; - cpu_state.MM[cpu_reg].w[3] = (cpu_state.MM[cpu_reg].sw[3] > src.sw[3]) ? 0xffff : 0; } + + dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0; + dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0; + dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; + dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPEQD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] = (dst.l[0] == src.l[0]) ? 0xffffffff : 0; - dst.l[1] = (dst.l[1] == src.l[1]) ? 0xffffffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; } + + dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPEQD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] = (dst.l[0] == src.l[0]) ? 0xffffffff : 0; - dst.l[1] = (dst.l[1] == src.l[1]) ? 0xffffffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].l[0] == src.l[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].l[1] == src.l[1]) ? 0xffffffff : 0; } + + dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPGTD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] = (dst.sl[0] > src.sl[0]) ? 0xffffffff : 0; - dst.l[1] = (dst.sl[1] > src.sl[1]) ? 0xffffffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; } + + dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPCMPGTD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] = (dst.sl[0] > src.sl[0]) ? 0xffffffff : 0; - dst.l[1] = (dst.sl[1] > src.sl[1]) ? 0xffffffff : 0; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].sl[0] > src.sl[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].sl[1] > src.sl[1]) ? 0xffffffff : 0; } + + dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index 9a9a9ee01..67622a3df 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -1,50 +1,50 @@ static int opPAND_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q &= src.q; + dst->q &= src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q &= src.q; return 0; } static int opPAND_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q &= src.q; + dst->q &= src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q &= src.q; return 0; } @@ -52,50 +52,50 @@ opPAND_a32(uint32_t fetchdat) static int opPANDN_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q = ~dst.q & src.q; + dst->q = ~dst->q & src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; return 0; } static int opPANDN_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q = ~dst.q & src.q; + dst->q = ~dst->q & src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q = ~cpu_state.MM[cpu_reg].q & src.q; return 0; } @@ -103,50 +103,50 @@ opPANDN_a32(uint32_t fetchdat) static int opPOR_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q |= src.q; + dst->q |= src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q |= src.q; return 0; } static int opPOR_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q |= src.q; + dst->q |= src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q |= src.q; return 0; } @@ -154,50 +154,50 @@ opPOR_a32(uint32_t fetchdat) static int opPXOR_a16(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q ^= src.q; + dst->q ^= src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q ^= src.q; return 0; } static int opPXOR_a32(uint32_t fetchdat) { - MMX_REG src, dst = { 0 }; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } - dst.q ^= src.q; + dst->q ^= src.q; - fpu_state.st_space[cpu_reg].fraction = dst.q; + if (fpu_softfloat) fpu_state.st_space[cpu_reg].exp = 0xffff; - } else - cpu_state.MM[cpu_reg].q ^= src.q; return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index fad58898f..c631c6444 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -2,175 +2,153 @@ static int opMOVD_l_mm_a16(uint32_t fetchdat) { uint32_t dst; - MMX_REG op; + MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op.l[0] = cpu_state.regs[cpu_rm].l; - op.l[1] = 0; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op.l[0] = dst; - op.l[1] = 0; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(2); } + + op->l[0] = cpu_state.regs[cpu_rm].l; + op->l[1] = 0; + CLOCK_CYCLES(1); } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + op->l[0] = dst; + op->l[1] = 0; + CLOCK_CYCLES(2); } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opMOVD_l_mm_a32(uint32_t fetchdat) { uint32_t dst; - MMX_REG op; + MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op.l[0] = cpu_state.regs[cpu_rm].l; - op.l[1] = 0; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op.l[0] = dst; - op.l[1] = 0; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(2); } + + op->l[0] = cpu_state.regs[cpu_rm].l; + op->l[1] = 0; + CLOCK_CYCLES(1); } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[0] = cpu_state.regs[cpu_rm].l; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].l[0] = dst; - cpu_state.MM[cpu_reg].l[1] = 0; - CLOCK_CYCLES(2); + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + op->l[0] = dst; + op->l[1] = 0; + CLOCK_CYCLES(2); } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opMOVD_mm_l_a16(uint32_t fetchdat) { - MMX_REG op; + MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - cpu_state.regs[cpu_rm].l = op.l[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - writememl(easeg, cpu_state.eaaddr, op.l[0]); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - CLOCK_CYCLES(2); } + + cpu_state.regs[cpu_rm].l = op->l[0]; + CLOCK_CYCLES(1); } else { - if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, op->l[0]); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + CLOCK_CYCLES(2); } + return 0; } static int opMOVD_mm_l_a32(uint32_t fetchdat) { - MMX_REG op; + MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - cpu_state.regs[cpu_rm].l = op.l[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - op = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - writememl(easeg, cpu_state.eaaddr, op.l[0]); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - CLOCK_CYCLES(2); } + + cpu_state.regs[cpu_rm].l = op->l[0]; + CLOCK_CYCLES(1); } else { - if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); + writememl(easeg, cpu_state.eaaddr, op->l[0]); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + CLOCK_CYCLES(2); } + return 0; } @@ -179,45 +157,79 @@ opMOVD_mm_l_a32(uint32_t fetchdat) static int opMOVD_mm_l_a16_cx(uint32_t fetchdat) { + MMX_REG *op; + if (in_smm) return opSMINT(fetchdat); MMX_ENTER(); fetch_ea_16(fetchdat); + + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } + + cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + writememl(easeg, cpu_state.eaaddr, op->l[0]); if (cpu_state.abrt) return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } + CLOCK_CYCLES(2); } + return 0; } static int opMOVD_mm_l_a32_cx(uint32_t fetchdat) { + MMX_REG *op; + if (in_smm) return opSMINT(fetchdat); MMX_ENTER(); fetch_ea_32(fetchdat); + + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + if (cpu_mod == 3) { - cpu_state.regs[cpu_rm].l = cpu_state.MM[cpu_reg].l[0]; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } + + cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 3); - writememl(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].l[0]); + writememl(easeg, cpu_state.eaaddr, op->l[0]); if (cpu_state.abrt) return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } + CLOCK_CYCLES(2); } + return 0; } #endif @@ -226,162 +238,164 @@ static int opMOVQ_q_mm_a16(uint32_t fetchdat) { uint64_t dst; - MMX_REG src, op; + MMX_REG src; + MMX_REG *op; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; - op.q = src.q; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op.q = dst; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(2); } + + op->q = src.q; + CLOCK_CYCLES(1); } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + op->q = dst; + CLOCK_CYCLES(2); } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opMOVQ_q_mm_a32(uint32_t fetchdat) { uint64_t dst; - MMX_REG src, op; + MMX_REG src; + MMX_REG *op; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; - op.q = src.q; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - op.q = dst; - fpu_state.st_space[cpu_reg].fraction = op.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(2); } + + op->q = src.q; + CLOCK_CYCLES(1); } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].q = cpu_state.MM[cpu_rm].q; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - dst = readmemq(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - cpu_state.MM[cpu_reg].q = dst; - CLOCK_CYCLES(2); + SEG_CHECK_READ(cpu_state.ea_seg); + dst = readmemq(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + op->q = dst; + CLOCK_CYCLES(2); } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opMOVQ_mm_q_a16(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; + MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : cpu_state.MM[cpu_reg]; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : &(cpu_state.MM[cpu_rm]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - fpu_state.st_space[cpu_rm].fraction = fpu_state.st_space[cpu_reg].fraction; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, fpu_state.st_space[cpu_reg].fraction); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - CLOCK_CYCLES(2); } + + dst->q = src.q; + CLOCK_CYCLES(1); + + if (fpu_softfloat) + fpu_state.st_space[cpu_rm].exp = 0xffff; } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, src.q); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + CLOCK_CYCLES(2); } + return 0; } static int opMOVQ_mm_q_a32(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst; + MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - if (cpu_mod == 3) { + + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : cpu_state.MM[cpu_reg]; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : &(cpu_state.MM[cpu_rm]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - fpu_state.st_space[cpu_rm].fraction = fpu_state.st_space[cpu_reg].fraction; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, fpu_state.st_space[cpu_reg].fraction); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - CLOCK_CYCLES(2); } + + dst->q = src.q; + CLOCK_CYCLES(1); + + if (fpu_softfloat) + fpu_state.st_space[cpu_rm].exp = 0xffff; } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_rm].q = cpu_state.MM[cpu_reg].q; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_WRITE(cpu_state.ea_seg); - CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); - writememq(easeg, cpu_state.eaaddr, cpu_state.MM[cpu_reg].q); - if (cpu_state.abrt) - return 1; - CLOCK_CYCLES(2); + SEG_CHECK_WRITE(cpu_state.ea_seg); + CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); + writememq(easeg, cpu_state.eaaddr, src.q); + if (cpu_state.abrt) + return 1; + + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + + CLOCK_CYCLES(2); } + return 0; } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index 25bc85a9a..a768a0183 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -2,635 +2,563 @@ static int opPUNPCKLDQ_a16(uint32_t fetchdat) { uint32_t usrc; - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - if (cpu_mod == 3) { - src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.l[1] = src.l[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.l[1] = src.l[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(2); - } - } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - usrc = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].l[1] = usrc; - CLOCK_CYCLES(2); + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + dst->l[1] = src.l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + usrc = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } + dst->l[1] = usrc; + + CLOCK_CYCLES(2); } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKLDQ_a32(uint32_t fetchdat) { uint32_t usrc; - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - if (cpu_mod == 3) { - src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.l[1] = src.l[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - src.l[0] = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 1; - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.l[1] = src.l[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - CLOCK_CYCLES(2); - } - } else { - if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].l[1] = cpu_state.MM[cpu_rm].l[0]; - CLOCK_CYCLES(1); - } else { - SEG_CHECK_READ(cpu_state.ea_seg); - usrc = readmeml(easeg, cpu_state.eaaddr); - if (cpu_state.abrt) - return 0; - cpu_state.MM[cpu_reg].l[1] = usrc; - CLOCK_CYCLES(2); + src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (cpu_mod == 3) { + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } + dst->l[1] = src.l[0]; + CLOCK_CYCLES(1); + } else { + SEG_CHECK_READ(cpu_state.ea_seg); + usrc = readmeml(easeg, cpu_state.eaaddr); + if (cpu_state.abrt) + return 0; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } + dst->l[1] = usrc; + + CLOCK_CYCLES(2); } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKHDQ_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + MMX_GETSRC(); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] = dst.l[1]; - dst.l[1] = src.l[1]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; } + + dst->l[0] = dst->l[1]; + dst->l[1] = src.l[1]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKHDQ_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + MMX_GETSRC(); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.l[0] = dst.l[1]; - dst.l[1] = src.l[1]; - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].l[0] = cpu_state.MM[cpu_reg].l[1]; - cpu_state.MM[cpu_reg].l[1] = src.l[1]; } + + dst->l[0] = dst->l[1]; + dst->l[1] = src.l[1]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKLBW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.b[7] = src.b[3]; - dst.b[6] = dst.b[3]; - dst.b[5] = src.b[2]; - dst.b[4] = dst.b[2]; - dst.b[3] = src.b[1]; - dst.b[2] = dst.b[1]; - dst.b[1] = src.b[0]; - dst.b[0] = dst.b[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; } + + dst->b[7] = src.b[3]; + dst->b[6] = dst->b[3]; + dst->b[5] = src.b[2]; + dst->b[4] = dst->b[2]; + dst->b[3] = src.b[1]; + dst->b[2] = dst->b[1]; + dst->b[1] = src.b[0]; + dst->b[0] = dst->b[0]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKLBW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.b[7] = src.b[3]; - dst.b[6] = dst.b[3]; - dst.b[5] = src.b[2]; - dst.b[4] = dst.b[2]; - dst.b[3] = src.b[1]; - dst.b[2] = dst.b[1]; - dst.b[1] = src.b[0]; - dst.b[0] = dst.b[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[7] = src.b[3]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[3]; - cpu_state.MM[cpu_reg].b[5] = src.b[2]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[2]; - cpu_state.MM[cpu_reg].b[3] = src.b[1]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[1]; - cpu_state.MM[cpu_reg].b[1] = src.b[0]; - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[0]; } + + dst->b[7] = src.b[3]; + dst->b[6] = dst->b[3]; + dst->b[5] = src.b[2]; + dst->b[4] = dst->b[2]; + dst->b[3] = src.b[1]; + dst->b[2] = dst->b[1]; + dst->b[1] = src.b[0]; + dst->b[0] = dst->b[0]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKHBW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.b[0] = dst.b[4]; - dst.b[1] = src.b[4]; - dst.b[2] = dst.b[5]; - dst.b[3] = src.b[5]; - dst.b[4] = dst.b[6]; - dst.b[5] = src.b[6]; - dst.b[6] = dst.b[7]; - dst.b[7] = src.b[7]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; } + + dst->b[0] = dst->b[4]; + dst->b[1] = src.b[4]; + dst->b[2] = dst->b[5]; + dst->b[3] = src.b[5]; + dst->b[4] = dst->b[6]; + dst->b[5] = src.b[6]; + dst->b[6] = dst->b[7]; + dst->b[7] = src.b[7]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKHBW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.b[0] = dst.b[4]; - dst.b[1] = src.b[4]; - dst.b[2] = dst.b[5]; - dst.b[3] = src.b[5]; - dst.b[4] = dst.b[6]; - dst.b[5] = src.b[6]; - dst.b[6] = dst.b[7]; - dst.b[7] = src.b[7]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].b[0] = cpu_state.MM[cpu_reg].b[4]; - cpu_state.MM[cpu_reg].b[1] = src.b[4]; - cpu_state.MM[cpu_reg].b[2] = cpu_state.MM[cpu_reg].b[5]; - cpu_state.MM[cpu_reg].b[3] = src.b[5]; - cpu_state.MM[cpu_reg].b[4] = cpu_state.MM[cpu_reg].b[6]; - cpu_state.MM[cpu_reg].b[5] = src.b[6]; - cpu_state.MM[cpu_reg].b[6] = cpu_state.MM[cpu_reg].b[7]; - cpu_state.MM[cpu_reg].b[7] = src.b[7]; } + + dst->b[0] = dst->b[4]; + dst->b[1] = src.b[4]; + dst->b[2] = dst->b[5]; + dst->b[3] = src.b[5]; + dst->b[4] = dst->b[6]; + dst->b[5] = src.b[6]; + dst->b[6] = dst->b[7]; + dst->b[7] = src.b[7]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKLWD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.w[3] = src.w[1]; - dst.w[2] = dst.w[1]; - dst.w[1] = src.w[0]; - dst.w[0] = dst.w[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; } + + dst->w[3] = src.w[1]; + dst->w[2] = dst->w[1]; + dst->w[1] = src.w[0]; + dst->w[0] = dst->w[0]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKLWD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.w[3] = src.w[1]; - dst.w[2] = dst.w[1]; - dst.w[1] = src.w[0]; - dst.w[0] = dst.w[0]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[3] = src.w[1]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[1]; - cpu_state.MM[cpu_reg].w[1] = src.w[0]; - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[0]; } + + dst->w[3] = src.w[1]; + dst->w[2] = dst->w[1]; + dst->w[1] = src.w[0]; + dst->w[0] = dst->w[0]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKHWD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.w[0] = dst.w[2]; - dst.w[1] = src.w[2]; - dst.w[2] = dst.w[3]; - dst.w[3] = src.w[3]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; } + + dst->w[0] = dst->w[2]; + dst->w[1] = src.w[2]; + dst->w[2] = dst->w[3]; + dst->w[3] = src.w[3]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPUNPCKHWD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); MMX_GETSRC(); if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.w[0] = dst.w[2]; - dst.w[1] = src.w[2]; - dst.w[2] = dst.w[3]; - dst.w[3] = src.w[3]; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - cpu_state.MM[cpu_reg].w[0] = cpu_state.MM[cpu_reg].w[2]; - cpu_state.MM[cpu_reg].w[1] = src.w[2]; - cpu_state.MM[cpu_reg].w[2] = cpu_state.MM[cpu_reg].w[3]; - cpu_state.MM[cpu_reg].w[3] = src.w[3]; } + + dst->w[0] = dst->w[2]; + dst->w[1] = src.w[2]; + dst->w[2] = dst->w[3]; + dst->w[3] = src.w[3]; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPACKSSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + MMX_GETSRC(); if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.sb[0] = SSATB(dst.sw[0]); - dst.sb[1] = SSATB(dst.sw[1]); - dst.sb[2] = SSATB(dst.sw[2]); - dst.sb[3] = SSATB(dst.sw[3]); - dst.sb[4] = SSATB(src.sw[0]); - dst.sb[5] = SSATB(src.sw[1]); - dst.sb[6] = SSATB(src.sw[2]); - dst.sb[7] = SSATB(src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); } + + dst->sb[0] = SSATB(dst->sw[0]); + dst->sb[1] = SSATB(dst->sw[1]); + dst->sb[2] = SSATB(dst->sw[2]); + dst->sb[3] = SSATB(dst->sw[3]); + dst->sb[4] = SSATB(src.sw[0]); + dst->sb[5] = SSATB(src.sw[1]); + dst->sb[6] = SSATB(src.sw[2]); + dst->sb[7] = SSATB(src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPACKSSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + MMX_GETSRC(); if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.sb[0] = SSATB(dst.sw[0]); - dst.sb[1] = SSATB(dst.sw[1]); - dst.sb[2] = SSATB(dst.sw[2]); - dst.sb[3] = SSATB(dst.sw[3]); - dst.sb[4] = SSATB(src.sw[0]); - dst.sb[5] = SSATB(src.sw[1]); - dst.sb[6] = SSATB(src.sw[2]); - dst.sb[7] = SSATB(src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sb[0] = SSATB(dst.sw[0]); - cpu_state.MM[cpu_reg].sb[1] = SSATB(dst.sw[1]); - cpu_state.MM[cpu_reg].sb[2] = SSATB(dst.sw[2]); - cpu_state.MM[cpu_reg].sb[3] = SSATB(dst.sw[3]); - cpu_state.MM[cpu_reg].sb[4] = SSATB(src.sw[0]); - cpu_state.MM[cpu_reg].sb[5] = SSATB(src.sw[1]); - cpu_state.MM[cpu_reg].sb[6] = SSATB(src.sw[2]); - cpu_state.MM[cpu_reg].sb[7] = SSATB(src.sw[3]); } + + dst->sb[0] = SSATB(dst->sw[0]); + dst->sb[1] = SSATB(dst->sw[1]); + dst->sb[2] = SSATB(dst->sw[2]); + dst->sb[3] = SSATB(dst->sw[3]); + dst->sb[4] = SSATB(src.sw[0]); + dst->sb[5] = SSATB(src.sw[1]); + dst->sb[6] = SSATB(src.sw[2]); + dst->sb[7] = SSATB(src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPACKUSWB_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + MMX_GETSRC(); if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.b[0] = USATB(dst.sw[0]); - dst.b[1] = USATB(dst.sw[1]); - dst.b[2] = USATB(dst.sw[2]); - dst.b[3] = USATB(dst.sw[3]); - dst.b[4] = USATB(src.sw[0]); - dst.b[5] = USATB(src.sw[1]); - dst.b[6] = USATB(src.sw[2]); - dst.b[7] = USATB(src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); } + + dst->b[0] = USATB(dst->sw[0]); + dst->b[1] = USATB(dst->sw[1]); + dst->b[2] = USATB(dst->sw[2]); + dst->b[3] = USATB(dst->sw[3]); + dst->b[4] = USATB(src.sw[0]); + dst->b[5] = USATB(src.sw[1]); + dst->b[6] = USATB(src.sw[2]); + dst->b[7] = USATB(src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPACKUSWB_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + MMX_GETSRC(); if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - dst.b[0] = USATB(dst.sw[0]); - dst.b[1] = USATB(dst.sw[1]); - dst.b[2] = USATB(dst.sw[2]); - dst.b[3] = USATB(dst.sw[3]); - dst.b[4] = USATB(src.sw[0]); - dst.b[5] = USATB(src.sw[1]); - dst.b[6] = USATB(src.sw[2]); - dst.b[7] = USATB(src.sw[3]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].b[0] = USATB(dst.sw[0]); - cpu_state.MM[cpu_reg].b[1] = USATB(dst.sw[1]); - cpu_state.MM[cpu_reg].b[2] = USATB(dst.sw[2]); - cpu_state.MM[cpu_reg].b[3] = USATB(dst.sw[3]); - cpu_state.MM[cpu_reg].b[4] = USATB(src.sw[0]); - cpu_state.MM[cpu_reg].b[5] = USATB(src.sw[1]); - cpu_state.MM[cpu_reg].b[6] = USATB(src.sw[2]); - cpu_state.MM[cpu_reg].b[7] = USATB(src.sw[3]); } + + dst->b[0] = USATB(dst->sw[0]); + dst->b[1] = USATB(dst->sw[1]); + dst->b[2] = USATB(dst->sw[2]); + dst->b[3] = USATB(dst->sw[3]); + dst->b[4] = USATB(src.sw[0]); + dst->b[5] = USATB(src.sw[1]); + dst->b[6] = USATB(src.sw[2]); + dst->b[7] = USATB(src.sw[3]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPACKSSDW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst, dst2; MMX_ENTER(); fetch_ea_16(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst2 = *dst; + MMX_GETSRC(); if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sw[0] = SSATW(dst.sl[0]); - dst.sw[1] = SSATW(dst.sl[1]); - dst.sw[2] = SSATW(src.sl[0]); - dst.sw[3] = SSATW(src.sl[1]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); } + + dst->sw[0] = SSATW(dst2.sl[0]); + dst->sw[1] = SSATW(dst2.sl[1]); + dst->sw[2] = SSATW(src.sl[0]); + dst->sw[3] = SSATW(src.sl[1]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPACKSSDW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG src; + MMX_REG *dst, dst2; MMX_ENTER(); fetch_ea_32(fetchdat); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst2 = *dst; + MMX_GETSRC(); if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - - dst.sw[0] = SSATW(dst.sl[0]); - dst.sw[1] = SSATW(dst.sl[1]); - dst.sw[2] = SSATW(src.sl[0]); - dst.sw[3] = SSATW(src.sl[1]); - - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - dst = cpu_state.MM[cpu_reg]; - - cpu_state.MM[cpu_reg].sw[0] = SSATW(dst.sl[0]); - cpu_state.MM[cpu_reg].sw[1] = SSATW(dst.sl[1]); - cpu_state.MM[cpu_reg].sw[2] = SSATW(src.sl[0]); - cpu_state.MM[cpu_reg].sw[3] = SSATW(src.sl[1]); } + + dst->sw[0] = SSATW(dst2.sl[0]); + dst->sw[1] = SSATW(dst2.sl[1]); + dst->sw[2] = SSATW(src.sl[0]); + dst->sw[3] = SSATW(src.sl[1]); + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index a3ede0021..e0c9f89a5 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -1,13 +1,13 @@ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) { \ - shift = cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } else { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - shift = readmemb(easeg, cpu_state.eaaddr); \ - if (cpu_state.abrt) \ - return 0; \ - CLOCK_CYCLES(2); \ +#define MMX_GETSHIFT() \ + if (cpu_mod == 3) { \ + shift = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction).b[0] : cpu_state.MM[cpu_rm].b[0]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 0; \ + CLOCK_CYCLES(2); \ } static int @@ -16,80 +16,44 @@ opPSxxW_imm(uint32_t fetchdat) int reg = fetchdat & 7; int op = fetchdat & 0x38; int shift = (fetchdat >> 8) & 0xff; - MMX_REG dst; + MMX_REG *dst; cpu_state.pc += 2; MMX_ENTER(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[reg].fraction) : &(cpu_state.MM[reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[reg].fraction; fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } switch (op) { case 0x10: /*PSRLW*/ - if (fpu_softfloat) { - if (shift > 15) - dst.q = 0; - else { - dst.w[0] >>= shift; - dst.w[1] >>= shift; - dst.w[2] >>= shift; - dst.w[3] >>= shift; - } - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 15) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].w[0] >>= shift; - cpu_state.MM[reg].w[1] >>= shift; - cpu_state.MM[reg].w[2] >>= shift; - cpu_state.MM[reg].w[3] >>= shift; - } + if (shift > 15) + dst->q = 0; + else { + dst->w[0] >>= shift; + dst->w[1] >>= shift; + dst->w[2] >>= shift; + dst->w[3] >>= shift; } break; case 0x20: /*PSRAW*/ - if (fpu_softfloat) { - if (shift > 15) - shift = 15; - dst.sw[0] >>= shift; - dst.sw[1] >>= shift; - dst.sw[2] >>= shift; - dst.sw[3] >>= shift; - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 15) - shift = 15; - cpu_state.MM[reg].sw[0] >>= shift; - cpu_state.MM[reg].sw[1] >>= shift; - cpu_state.MM[reg].sw[2] >>= shift; - cpu_state.MM[reg].sw[3] >>= shift; - } + if (shift > 15) + shift = 15; + dst->sw[0] >>= shift; + dst->sw[1] >>= shift; + dst->sw[2] >>= shift; + dst->sw[3] >>= shift; break; case 0x30: /*PSLLW*/ - if (fpu_softfloat) { - if (shift > 15) - dst.q = 0; - else { - dst.w[0] <<= shift; - dst.w[1] <<= shift; - dst.w[2] <<= shift; - dst.w[3] <<= shift; - } - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 15) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].w[0] <<= shift; - cpu_state.MM[reg].w[1] <<= shift; - cpu_state.MM[reg].w[2] <<= shift; - cpu_state.MM[reg].w[3] <<= shift; - } + if (shift > 15) + dst->q = 0; + else { + dst->w[0] <<= shift; + dst->w[1] <<= shift; + dst->w[2] <<= shift; + dst->w[3] <<= shift; } break; default: @@ -98,6 +62,9 @@ opPSxxW_imm(uint32_t fetchdat) return 0; } + if (fpu_softfloat) + fpu_state.st_space[reg].exp = 0xffff; + CLOCK_CYCLES(1); return 0; } @@ -105,239 +72,199 @@ opPSxxW_imm(uint32_t fetchdat) static int opPSLLW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + MMX_GETSHIFT(); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 15) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.w[0] <<= shift; - dst.w[1] <<= shift; - dst.w[2] <<= shift; - dst.w[3] <<= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } } + + if (shift > 15) + dst->q = 0; + else { + dst->w[0] <<= shift; + dst->w[1] <<= shift; + dst->w[2] <<= shift; + dst->w[3] <<= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSLLW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + MMX_GETSHIFT(); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 15) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.w[0] <<= shift; - dst.w[1] <<= shift; - dst.w[2] <<= shift; - dst.w[3] <<= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] <<= shift; - cpu_state.MM[cpu_reg].w[1] <<= shift; - cpu_state.MM[cpu_reg].w[2] <<= shift; - cpu_state.MM[cpu_reg].w[3] <<= shift; - } } + + if (shift > 15) + dst->q = 0; + else { + dst->w[0] <<= shift; + dst->w[1] <<= shift; + dst->w[2] <<= shift; + dst->w[3] <<= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRLW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 15) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.w[0] >>= shift; - dst.w[1] >>= shift; - dst.w[2] >>= shift; - dst.w[3] >>= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } } + + MMX_GETSHIFT(); + + if (shift > 15) + dst->q = 0; + else { + dst->w[0] >>= shift; + dst->w[1] >>= shift; + dst->w[2] >>= shift; + dst->w[3] >>= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRLW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 15) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.w[0] >>= shift; - dst.w[1] >>= shift; - dst.w[2] >>= shift; - dst.w[3] >>= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 15) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].w[0] >>= shift; - cpu_state.MM[cpu_reg].w[1] >>= shift; - cpu_state.MM[cpu_reg].w[2] >>= shift; - cpu_state.MM[cpu_reg].w[3] >>= shift; - } } + + MMX_GETSHIFT(); + + if (shift > 15) + dst->q = 0; + else { + dst->w[0] >>= shift; + dst->w[1] >>= shift; + dst->w[2] >>= shift; + dst->w[3] >>= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRAW_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 15) { - src.q = 15; - } - shift = src.b[0]; - dst.sw[0] >>= shift; - dst.sw[1] >>= shift; - dst.sw[2] >>= shift; - dst.sw[3] >>= shift; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; } + + MMX_GETSHIFT(); + + if (shift > 15) + shift = 15; + + dst->sw[0] >>= shift; + dst->sw[1] >>= shift; + dst->sw[2] >>= shift; + dst->sw[3] >>= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRAW_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 15) { - src.q = 15; - } - shift = src.b[0]; - dst.sw[0] >>= shift; - dst.sw[1] >>= shift; - dst.sw[2] >>= shift; - dst.sw[3] >>= shift; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 15) - shift = 15; - - cpu_state.MM[cpu_reg].sw[0] >>= shift; - cpu_state.MM[cpu_reg].sw[1] >>= shift; - cpu_state.MM[cpu_reg].sw[2] >>= shift; - cpu_state.MM[cpu_reg].sw[3] >>= shift; } + + MMX_GETSHIFT(); + + if (shift > 15) + shift = 15; + + dst->sw[0] >>= shift; + dst->sw[1] >>= shift; + dst->sw[2] >>= shift; + dst->sw[3] >>= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } @@ -347,68 +274,39 @@ opPSxxD_imm(uint32_t fetchdat) int reg = fetchdat & 7; int op = fetchdat & 0x38; int shift = (fetchdat >> 8) & 0xff; - MMX_REG dst; + MMX_REG *dst; cpu_state.pc += 2; MMX_ENTER(); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[reg].fraction) : &(cpu_state.MM[reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[reg].fraction; fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } switch (op) { case 0x10: /*PSRLD*/ - if (fpu_softfloat) { - if (shift > 31) - dst.q = 0; - else { - dst.l[0] >>= shift; - dst.l[1] >>= shift; - } - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 31) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].l[0] >>= shift; - cpu_state.MM[reg].l[1] >>= shift; - } + if (shift > 31) + dst->q = 0; + else { + dst->l[0] >>= shift; + dst->l[1] >>= shift; } break; case 0x20: /*PSRAD*/ - if (fpu_softfloat) { - if (shift > 31) - shift = 31; - dst.sl[0] >>= shift; - dst.sl[1] >>= shift; - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 31) - shift = 31; - cpu_state.MM[reg].sl[0] >>= shift; - cpu_state.MM[reg].sl[1] >>= shift; - } + if (shift > 31) + shift = 31; + dst->sl[0] >>= shift; + dst->sl[1] >>= shift; break; case 0x30: /*PSLLD*/ - if (fpu_softfloat) { - if (shift > 31) - dst.q = 0; - else { - dst.l[0] <<= shift; - dst.l[1] <<= shift; - } - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 31) - cpu_state.MM[reg].q = 0; - else { - cpu_state.MM[reg].l[0] <<= shift; - cpu_state.MM[reg].l[1] <<= shift; - } + if (shift > 31) + dst->q = 0; + else { + dst->l[0] <<= shift; + dst->l[1] <<= shift; } break; default: @@ -417,6 +315,9 @@ opPSxxD_imm(uint32_t fetchdat) return 0; } + if (fpu_softfloat) + fpu_state.st_space[reg].exp = 0xffff; + CLOCK_CYCLES(1); return 0; } @@ -424,215 +325,187 @@ opPSxxD_imm(uint32_t fetchdat) static int opPSLLD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 31) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.l[0] <<= shift; - dst.l[1] <<= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } } + + MMX_GETSHIFT(); + + if (shift > 31) + dst->q = 0; + else { + dst->l[0] <<= shift; + dst->l[1] <<= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSLLD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 31) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.l[0] <<= shift; - dst.l[1] <<= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] <<= shift; - cpu_state.MM[cpu_reg].l[1] <<= shift; - } } + + MMX_GETSHIFT(); + + if (shift > 31) + dst->q = 0; + else { + dst->l[0] <<= shift; + dst->l[1] <<= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRLD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 31) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.l[0] >>= shift; - dst.l[1] >>= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } } + + MMX_GETSHIFT(); + + if (shift > 31) + dst->q = 0; + else { + dst->l[0] >>= shift; + dst->l[1] >>= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRLD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 31) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.l[0] >>= shift; - dst.l[1] >>= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 31) - cpu_state.MM[cpu_reg].q = 0; - else { - cpu_state.MM[cpu_reg].l[0] >>= shift; - cpu_state.MM[cpu_reg].l[1] >>= shift; - } } + + MMX_GETSHIFT(); + + if (shift > 31) + dst->q = 0; + else { + dst->l[0] >>= shift; + dst->l[1] >>= shift; + } + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRAD_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 31) { - src.q = 31; - } - shift = src.b[0]; - dst.sl[0] >>= shift; - dst.sl[1] >>= shift; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 31) - shift = 31; - - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; } + + MMX_GETSHIFT(); + + if (shift > 31) + shift = 31; + + dst->sl[0] >>= shift; + dst->sl[1] >>= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRAD_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 31) { - src.q = 31; - } - shift = src.b[0]; - dst.sl[0] >>= shift; - dst.sl[1] >>= shift; - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 31) - shift = 31; - - cpu_state.MM[cpu_reg].sl[0] >>= shift; - cpu_state.MM[cpu_reg].sl[1] >>= shift; } + + MMX_GETSHIFT(); + + if (shift > 31) + shift = 31; + + dst->sl[0] >>= shift; + dst->sl[1] >>= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } @@ -642,59 +515,37 @@ opPSxxQ_imm(uint32_t fetchdat) int reg = fetchdat & 7; int op = fetchdat & 0x38; int shift = (fetchdat >> 8) & 0xff; - MMX_REG dst; + MMX_REG *dst; cpu_state.pc += 2; + MMX_ENTER(); + + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[reg].fraction) : &(cpu_state.MM[reg]); + if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[reg].fraction; fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ } switch (op) { case 0x10: /*PSRLW*/ - if (fpu_softfloat) { - if (shift > 63) - dst.q = 0; - else - dst.q >>= shift; - - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q >>= shift; - } + if (shift > 63) + dst->q = 0; + else + dst->q >>= shift; break; case 0x20: /*PSRAW*/ if (shift > 63) shift = 63; - if (fpu_softfloat) { - dst.sq >>= shift; - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else - cpu_state.MM[reg].sq >>= shift; + dst->sq >>= shift; break; case 0x30: /*PSLLW*/ - if (fpu_softfloat) { - if (shift > 63) - dst.q = 0; - else - dst.q <<= shift; - - fpu_state.st_space[reg].fraction = dst.q; - fpu_state.st_space[reg].exp = 0xffff; - } else { - if (shift > 63) - cpu_state.MM[reg].q = 0; - else - cpu_state.MM[reg].q <<= shift; - } + if (shift > 63) + dst->q = 0; + else + dst->q <<= shift; break; default: cpu_state.pc = cpu_state.oldpc; @@ -702,6 +553,9 @@ opPSxxQ_imm(uint32_t fetchdat) return 0; } + if (fpu_softfloat) + fpu_state.st_space[reg].exp = 0xffff; + CLOCK_CYCLES(1); return 0; } @@ -709,133 +563,117 @@ opPSxxQ_imm(uint32_t fetchdat) static int opPSLLQ_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 63) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.q <<= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; } + + MMX_GETSHIFT(); + + if (shift > 63) + dst->q = 0; + else + dst->q <<= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSLLQ_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 63) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.q <<= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q <<= shift; } + + MMX_GETSHIFT(); + + if (shift > 63) + dst->q = 0; + else + dst->q <<= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRLQ_a16(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_16(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 63) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.q >>= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; } + + MMX_GETSHIFT(); + + if (shift > 63) + dst->q = 0; + else + dst->q >>= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } static int opPSRLQ_a32(uint32_t fetchdat) { - MMX_REG src, dst; + MMX_REG *dst; int shift; MMX_ENTER(); fetch_ea_32(fetchdat); - if (fpu_softfloat) { - dst = *(MMX_REG *)&fpu_state.st_space[cpu_reg].fraction; - MMX_GETSRC(); + dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + + if (fpu_softfloat) { fpu_state.tag = 0; fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - if (src.q > 63) { - dst.q = 0; - } else { - shift = src.b[0]; - dst.q >>= shift; - } - fpu_state.st_space[cpu_reg].fraction = dst.q; - fpu_state.st_space[cpu_reg].exp = 0xffff; - } else { - MMX_GETSHIFT(); - - if (shift > 63) - cpu_state.MM[cpu_reg].q = 0; - else - cpu_state.MM[cpu_reg].q >>= shift; } + + MMX_GETSHIFT(); + + if (shift > 63) + dst->q = 0; + else + dst->q >>= shift; + + if (fpu_softfloat) + fpu_state.st_space[cpu_reg].exp = 0xffff; + return 0; } From 8b4a2a6ecc590958b0134a0a13fe775e9bbaf3c4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:01:11 +0200 Subject: [PATCH 15/44] Part 2. --- src/cpu/x86_ops_mmx.h | 12 +- src/cpu/x86_ops_mmx_arith.h | 319 +++++++++--------------------------- src/cpu/x86_ops_mmx_cmp.h | 120 +++----------- src/cpu/x86_ops_mmx_logic.h | 80 ++------- src/cpu/x86_ops_mmx_mov.h | 146 +++-------------- src/cpu/x86_ops_mmx_pack.h | 196 +++++----------------- src/cpu/x86_ops_mmx_shift.h | 210 ++++++------------------ src/cpu/x87.h | 20 ++- 8 files changed, 246 insertions(+), 857 deletions(-) diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index 9942f653f..77df5d990 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -3,12 +3,16 @@ #define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) #define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) +#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r]) +#define MMX_GETREG(r) fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[r].fraction) : cpu_state.MM[r] + +#define MMX_SETEXP() \ + if (fpu_softfloat) \ + fpu_state.st_space[cpu_reg].exp = 0xffff + #define MMX_GETSRC() \ if (cpu_mod == 3) { \ - if (fpu_softfloat) \ - src = *(MMX_REG *)&fpu_state.st_space[cpu_rm].fraction; \ - else \ - src = cpu_state.MM[cpu_rm]; \ + src = MMX_GETREG(cpu_rm); \ CLOCK_CYCLES(1); \ } else { \ SEG_CHECK_READ(cpu_state.ea_seg); \ diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index 3ebe960f9..66ff79cd2 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -7,7 +7,7 @@ opPADDB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -20,8 +20,7 @@ opPADDB_a16(uint32_t fetchdat) dst->b[6] += src.b[6]; dst->b[7] += src.b[7]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -34,7 +33,7 @@ opPADDB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -47,8 +46,7 @@ opPADDB_a32(uint32_t fetchdat) dst->b[6] += src.b[6]; dst->b[7] += src.b[7]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -62,7 +60,7 @@ opPADDW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -71,8 +69,7 @@ opPADDW_a16(uint32_t fetchdat) dst->w[2] += src.w[2]; dst->w[3] += src.w[3]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -85,7 +82,7 @@ opPADDW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); @@ -94,8 +91,8 @@ opPADDW_a32(uint32_t fetchdat) dst->w[2] += src.w[2]; dst->w[3] += src.w[3]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); + return 0; } @@ -108,15 +105,14 @@ opPADDD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); dst->l[0] += src.l[0]; dst->l[1] += src.l[1]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -129,15 +125,14 @@ opPADDD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); dst->l[0] += src.l[0]; dst->l[1] += src.l[1]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -151,15 +146,10 @@ opPADDSB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sb[0] = SSATB(dst->sb[0] + src.sb[0]); dst->sb[1] = SSATB(dst->sb[1] + src.sb[1]); dst->sb[2] = SSATB(dst->sb[2] + src.sb[2]); @@ -169,8 +159,7 @@ opPADDSB_a16(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -183,15 +172,10 @@ opPADDSB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sb[0] = SSATB(dst->sb[0] + src.sb[0]); dst->sb[1] = SSATB(dst->sb[1] + src.sb[1]); dst->sb[2] = SSATB(dst->sb[2] + src.sb[2]); @@ -201,8 +185,7 @@ opPADDSB_a32(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -216,15 +199,10 @@ opPADDUSB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = USATB(dst->b[0] + src.b[0]); dst->b[1] = USATB(dst->b[1] + src.b[1]); dst->b[2] = USATB(dst->b[2] + src.b[2]); @@ -234,8 +212,7 @@ opPADDUSB_a16(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] + src.b[6]); dst->b[7] = USATB(dst->b[7] + src.b[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -248,15 +225,10 @@ opPADDUSB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = USATB(dst->b[0] + src.b[0]); dst->b[1] = USATB(dst->b[1] + src.b[1]); dst->b[2] = USATB(dst->b[2] + src.b[2]); @@ -266,8 +238,7 @@ opPADDUSB_a32(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] + src.b[6]); dst->b[7] = USATB(dst->b[7] + src.b[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -281,22 +252,16 @@ opPADDSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sw[0] = SSATW(dst->sw[0] + src.sw[0]); dst->sw[1] = SSATW(dst->sw[1] + src.sw[1]); dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -309,22 +274,16 @@ opPADDSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sw[0] = SSATW(dst->sw[0] + src.sw[0]); dst->sw[1] = SSATW(dst->sw[1] + src.sw[1]); dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -338,22 +297,16 @@ opPADDUSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = USATW(dst->w[0] + src.w[0]); dst->w[1] = USATW(dst->w[1] + src.w[1]); dst->w[2] = USATW(dst->w[2] + src.w[2]); dst->w[3] = USATW(dst->w[3] + src.w[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -366,22 +319,16 @@ opPADDUSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = USATW(dst->w[0] + src.w[0]); dst->w[1] = USATW(dst->w[1] + src.w[1]); dst->w[2] = USATW(dst->w[2] + src.w[2]); dst->w[3] = USATW(dst->w[3] + src.w[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -395,15 +342,10 @@ opPMADDWD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - if (dst->l[0] == 0x80008000 && src.l[0] == 0x80008000) dst->l[0] = 0x80000000; else @@ -414,8 +356,7 @@ opPMADDWD_a16(uint32_t fetchdat) else dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -428,15 +369,10 @@ opPMADDWD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - if (dst->l[0] == 0x80008000 && src.l[0] == 0x80008000) dst->l[0] = 0x80000000; else @@ -447,8 +383,7 @@ opPMADDWD_a32(uint32_t fetchdat) else dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -462,15 +397,10 @@ opPMULLW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + src = MMX_GETREG(cpu_rm); else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); @@ -485,8 +415,7 @@ opPMULLW_a16(uint32_t fetchdat) dst->w[3] *= src.w[3]; CLOCK_CYCLES(1); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -499,15 +428,10 @@ opPMULLW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + src = MMX_GETREG(cpu_rm); else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); @@ -522,8 +446,7 @@ opPMULLW_a32(uint32_t fetchdat) dst->w[3] *= src.w[3]; CLOCK_CYCLES(1); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -537,15 +460,10 @@ opPMULHW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + src = MMX_GETREG(cpu_rm); else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); @@ -560,8 +478,7 @@ opPMULHW_a16(uint32_t fetchdat) dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; CLOCK_CYCLES(1); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -574,15 +491,10 @@ opPMULHW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; + src = MMX_GETREG(cpu_rm); else { SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); @@ -597,8 +509,7 @@ opPMULHW_a32(uint32_t fetchdat) dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; CLOCK_CYCLES(1); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -612,15 +523,10 @@ opPSUBB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] -= src.b[0]; dst->b[1] -= src.b[1]; dst->b[2] -= src.b[2]; @@ -630,8 +536,7 @@ opPSUBB_a16(uint32_t fetchdat) dst->b[6] -= src.b[6]; dst->b[7] -= src.b[7]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -644,15 +549,10 @@ opPSUBB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] -= src.b[0]; dst->b[1] -= src.b[1]; dst->b[2] -= src.b[2]; @@ -662,8 +562,7 @@ opPSUBB_a32(uint32_t fetchdat) dst->b[6] -= src.b[6]; dst->b[7] -= src.b[7]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -677,22 +576,16 @@ opPSUBW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] -= src.w[0]; dst->w[1] -= src.w[1]; dst->w[2] -= src.w[2]; dst->w[3] -= src.w[3]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -705,22 +598,16 @@ opPSUBW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] -= src.w[0]; dst->w[1] -= src.w[1]; dst->w[2] -= src.w[2]; dst->w[3] -= src.w[3]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -734,20 +621,14 @@ opPSUBD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] -= src.l[0]; dst->l[1] -= src.l[1]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -760,20 +641,14 @@ opPSUBD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] -= src.l[0]; dst->l[1] -= src.l[1]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -787,15 +662,10 @@ opPSUBSB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sb[0] = SSATB(dst->sb[0] - src.sb[0]); dst->sb[1] = SSATB(dst->sb[1] - src.sb[1]); dst->sb[2] = SSATB(dst->sb[2] - src.sb[2]); @@ -805,8 +675,7 @@ opPSUBSB_a16(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -819,15 +688,10 @@ opPSUBSB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sb[0] = SSATB(dst->sb[0] - src.sb[0]); dst->sb[1] = SSATB(dst->sb[1] - src.sb[1]); dst->sb[2] = SSATB(dst->sb[2] - src.sb[2]); @@ -837,8 +701,7 @@ opPSUBSB_a32(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -852,15 +715,10 @@ opPSUBUSB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = USATB(dst->b[0] - src.b[0]); dst->b[1] = USATB(dst->b[1] - src.b[1]); dst->b[2] = USATB(dst->b[2] - src.b[2]); @@ -870,8 +728,7 @@ opPSUBUSB_a16(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] - src.b[6]); dst->b[7] = USATB(dst->b[7] - src.b[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -884,15 +741,10 @@ opPSUBUSB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = USATB(dst->b[0] - src.b[0]); dst->b[1] = USATB(dst->b[1] - src.b[1]); dst->b[2] = USATB(dst->b[2] - src.b[2]); @@ -902,8 +754,7 @@ opPSUBUSB_a32(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] - src.b[6]); dst->b[7] = USATB(dst->b[7] - src.b[7]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -917,22 +768,16 @@ opPSUBSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sw[0] = SSATW(dst->sw[0] - src.sw[0]); dst->sw[1] = SSATW(dst->sw[1] - src.sw[1]); dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -945,22 +790,16 @@ opPSUBSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sw[0] = SSATW(dst->sw[0] - src.sw[0]); dst->sw[1] = SSATW(dst->sw[1] - src.sw[1]); dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -974,22 +813,16 @@ opPSUBUSW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = USATW(dst->w[0] - src.w[0]); dst->w[1] = USATW(dst->w[1] - src.w[1]); dst->w[2] = USATW(dst->w[2] - src.w[2]); dst->w[3] = USATW(dst->w[3] - src.w[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -1002,22 +835,16 @@ opPSUBUSW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = USATW(dst->w[0] - src.w[0]); dst->w[1] = USATW(dst->w[1] - src.w[1]); dst->w[2] = USATW(dst->w[2] - src.w[2]); dst->w[3] = USATW(dst->w[3] - src.w[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index 4f64119a3..d98e56511 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -7,15 +7,10 @@ opPCMPEQB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0; dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0; dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0; @@ -25,8 +20,7 @@ opPCMPEQB_a16(uint32_t fetchdat) dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -39,15 +33,10 @@ opPCMPEQB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = (dst->b[0] == src.b[0]) ? 0xff : 0; dst->b[1] = (dst->b[1] == src.b[1]) ? 0xff : 0; dst->b[2] = (dst->b[2] == src.b[2]) ? 0xff : 0; @@ -57,8 +46,7 @@ opPCMPEQB_a32(uint32_t fetchdat) dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -72,15 +60,10 @@ opPCMPGTB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0; dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0; dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0; @@ -90,8 +73,7 @@ opPCMPGTB_a16(uint32_t fetchdat) dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -104,15 +86,10 @@ opPCMPGTB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = (dst->sb[0] > src.sb[0]) ? 0xff : 0; dst->b[1] = (dst->sb[1] > src.sb[1]) ? 0xff : 0; dst->b[2] = (dst->sb[2] > src.sb[2]) ? 0xff : 0; @@ -122,8 +99,7 @@ opPCMPGTB_a32(uint32_t fetchdat) dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -137,22 +113,16 @@ opPCMPEQW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0; dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0; dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -165,22 +135,16 @@ opPCMPEQW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = (dst->w[0] == src.w[0]) ? 0xffff : 0; dst->w[1] = (dst->w[1] == src.w[1]) ? 0xffff : 0; dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -194,22 +158,16 @@ opPCMPGTW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0; dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0; dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -222,22 +180,16 @@ opPCMPGTW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = (dst->sw[0] > src.sw[0]) ? 0xffff : 0; dst->w[1] = (dst->sw[1] > src.sw[1]) ? 0xffff : 0; dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -251,20 +203,14 @@ opPCMPEQD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -277,20 +223,14 @@ opPCMPEQD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -304,20 +244,14 @@ opPCMPGTD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -330,20 +264,14 @@ opPCMPGTD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index 67622a3df..d0079347a 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -7,19 +7,13 @@ opPAND_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q &= src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -32,19 +26,13 @@ opPAND_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q &= src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -58,19 +46,13 @@ opPANDN_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q = ~dst->q & src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -83,19 +65,13 @@ opPANDN_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q = ~dst->q & src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -109,19 +85,13 @@ opPOR_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q |= src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -134,19 +104,13 @@ opPOR_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q |= src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -160,19 +124,13 @@ opPXOR_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q ^= src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -185,19 +143,13 @@ opPXOR_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q ^= src.q; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index c631c6444..d65c82693 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -7,14 +7,9 @@ opMOVD_l_mm_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->l[0] = cpu_state.regs[cpu_rm].l; op->l[1] = 0; CLOCK_CYCLES(1); @@ -24,18 +19,12 @@ opMOVD_l_mm_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->l[0] = dst; op->l[1] = 0; CLOCK_CYCLES(2); } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -48,14 +37,9 @@ opMOVD_l_mm_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->l[0] = cpu_state.regs[cpu_rm].l; op->l[1] = 0; CLOCK_CYCLES(1); @@ -65,18 +49,12 @@ opMOVD_l_mm_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->l[0] = dst; op->l[1] = 0; CLOCK_CYCLES(2); } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -89,14 +67,9 @@ opMOVD_mm_l_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { @@ -106,11 +79,6 @@ opMOVD_mm_l_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - CLOCK_CYCLES(2); } @@ -124,14 +92,9 @@ opMOVD_mm_l_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { @@ -141,11 +104,6 @@ opMOVD_mm_l_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - CLOCK_CYCLES(2); } @@ -166,14 +124,9 @@ opMOVD_mm_l_a16_cx(uint32_t fetchdat) fetch_ea_16(fetchdat); - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { @@ -183,11 +136,6 @@ opMOVD_mm_l_a16_cx(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - CLOCK_CYCLES(2); } @@ -205,14 +153,9 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat) fetch_ea_32(fetchdat); - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - cpu_state.regs[cpu_rm].l = op->l[0]; CLOCK_CYCLES(1); } else { @@ -222,11 +165,6 @@ opMOVD_mm_l_a32_cx(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - CLOCK_CYCLES(2); } @@ -244,15 +182,10 @@ opMOVQ_q_mm_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + src = MMX_GETREG(cpu_rm); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->q = src.q; CLOCK_CYCLES(1); } else { @@ -261,17 +194,11 @@ opMOVQ_q_mm_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->q = dst; CLOCK_CYCLES(2); } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -285,15 +212,10 @@ opMOVQ_q_mm_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; - op = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + src = MMX_GETREG(cpu_rm); + op = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->q = src.q; CLOCK_CYCLES(1); } else { @@ -302,17 +224,11 @@ opMOVQ_q_mm_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - op->q = dst; CLOCK_CYCLES(2); } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -327,20 +243,14 @@ opMOVQ_mm_q_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : cpu_state.MM[cpu_reg]; - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : &(cpu_state.MM[cpu_rm]); + src = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_rm); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q = src.q; CLOCK_CYCLES(1); - if (fpu_softfloat) - fpu_state.st_space[cpu_rm].exp = 0xffff; + MMX_SETEXP(); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); @@ -348,11 +258,6 @@ opMOVQ_mm_q_a16(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - CLOCK_CYCLES(2); } @@ -368,20 +273,14 @@ opMOVQ_mm_q_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : cpu_state.MM[cpu_reg]; - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : &(cpu_state.MM[cpu_rm]); + src = MMX_GETREG(cpu_reg); + dst = MMX_GETREGP(cpu_rm); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->q = src.q; CLOCK_CYCLES(1); - if (fpu_softfloat) - fpu_state.st_space[cpu_rm].exp = 0xffff; + MMX_SETEXP(); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); @@ -389,11 +288,6 @@ opMOVQ_mm_q_a32(uint32_t fetchdat) if (cpu_state.abrt) return 1; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - CLOCK_CYCLES(2); } diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index a768a0183..a76ad1d0a 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -8,14 +8,10 @@ opPUNPCKLDQ_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + src = MMX_GETREG(cpu_rm); + dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } dst->l[1] = src.l[0]; CLOCK_CYCLES(1); } else { @@ -23,17 +19,12 @@ opPUNPCKLDQ_a16(uint32_t fetchdat) usrc = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } dst->l[1] = usrc; CLOCK_CYCLES(2); } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -47,14 +38,10 @@ opPUNPCKLDQ_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - src = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction) : cpu_state.MM[cpu_rm]; - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + src = MMX_GETREG(cpu_rm); + dst = MMX_GETREGP(cpu_reg); if (cpu_mod == 3) { - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } dst->l[1] = src.l[0]; CLOCK_CYCLES(1); } else { @@ -62,17 +49,12 @@ opPUNPCKLDQ_a32(uint32_t fetchdat) usrc = readmeml(easeg, cpu_state.eaaddr); if (cpu_state.abrt) return 0; - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } dst->l[1] = usrc; CLOCK_CYCLES(2); } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -86,20 +68,14 @@ opPUNPCKHDQ_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] = dst->l[1]; dst->l[1] = src.l[1]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -112,20 +88,14 @@ opPUNPCKHDQ_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->l[0] = dst->l[1]; dst->l[1] = src.l[1]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -139,15 +109,10 @@ opPUNPCKLBW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[7] = src.b[3]; dst->b[6] = dst->b[3]; dst->b[5] = src.b[2]; @@ -157,8 +122,7 @@ opPUNPCKLBW_a16(uint32_t fetchdat) dst->b[1] = src.b[0]; dst->b[0] = dst->b[0]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -171,15 +135,10 @@ opPUNPCKLBW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[7] = src.b[3]; dst->b[6] = dst->b[3]; dst->b[5] = src.b[2]; @@ -189,8 +148,7 @@ opPUNPCKLBW_a32(uint32_t fetchdat) dst->b[1] = src.b[0]; dst->b[0] = dst->b[0]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -204,15 +162,10 @@ opPUNPCKHBW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = dst->b[4]; dst->b[1] = src.b[4]; dst->b[2] = dst->b[5]; @@ -222,8 +175,7 @@ opPUNPCKHBW_a16(uint32_t fetchdat) dst->b[6] = dst->b[7]; dst->b[7] = src.b[7]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -236,15 +188,10 @@ opPUNPCKHBW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = dst->b[4]; dst->b[1] = src.b[4]; dst->b[2] = dst->b[5]; @@ -254,8 +201,7 @@ opPUNPCKHBW_a32(uint32_t fetchdat) dst->b[6] = dst->b[7]; dst->b[7] = src.b[7]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -269,22 +215,16 @@ opPUNPCKLWD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[3] = src.w[1]; dst->w[2] = dst->w[1]; dst->w[1] = src.w[0]; dst->w[0] = dst->w[0]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -297,22 +237,16 @@ opPUNPCKLWD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[3] = src.w[1]; dst->w[2] = dst->w[1]; dst->w[1] = src.w[0]; dst->w[0] = dst->w[0]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -326,22 +260,16 @@ opPUNPCKHWD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = dst->w[2]; dst->w[1] = src.w[2]; dst->w[2] = dst->w[3]; dst->w[3] = src.w[3]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -354,22 +282,16 @@ opPUNPCKHWD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->w[0] = dst->w[2]; dst->w[1] = src.w[2]; dst->w[2] = dst->w[3]; dst->w[3] = src.w[3]; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -383,15 +305,10 @@ opPACKSSWB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sb[0] = SSATB(dst->sw[0]); dst->sb[1] = SSATB(dst->sw[1]); dst->sb[2] = SSATB(dst->sw[2]); @@ -401,8 +318,7 @@ opPACKSSWB_a16(uint32_t fetchdat) dst->sb[6] = SSATB(src.sw[2]); dst->sb[7] = SSATB(src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -415,15 +331,10 @@ opPACKSSWB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sb[0] = SSATB(dst->sw[0]); dst->sb[1] = SSATB(dst->sw[1]); dst->sb[2] = SSATB(dst->sw[2]); @@ -433,8 +344,7 @@ opPACKSSWB_a32(uint32_t fetchdat) dst->sb[6] = SSATB(src.sw[2]); dst->sb[7] = SSATB(src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -448,15 +358,10 @@ opPACKUSWB_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = USATB(dst->sw[0]); dst->b[1] = USATB(dst->sw[1]); dst->b[2] = USATB(dst->sw[2]); @@ -466,8 +371,7 @@ opPACKUSWB_a16(uint32_t fetchdat) dst->b[6] = USATB(src.sw[2]); dst->b[7] = USATB(src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -480,15 +384,10 @@ opPACKUSWB_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->b[0] = USATB(dst->sw[0]); dst->b[1] = USATB(dst->sw[1]); dst->b[2] = USATB(dst->sw[2]); @@ -498,8 +397,7 @@ opPACKUSWB_a32(uint32_t fetchdat) dst->b[6] = USATB(src.sw[2]); dst->b[7] = USATB(src.sw[3]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -508,28 +406,23 @@ static int opPACKSSDW_a16(uint32_t fetchdat) { MMX_REG src; - MMX_REG *dst, dst2; + MMX_REG *dst; + MMX_REG dst2; MMX_ENTER(); fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); dst2 = *dst; MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sw[0] = SSATW(dst2.sl[0]); dst->sw[1] = SSATW(dst2.sl[1]); dst->sw[2] = SSATW(src.sl[0]); dst->sw[3] = SSATW(src.sl[1]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -537,28 +430,23 @@ static int opPACKSSDW_a32(uint32_t fetchdat) { MMX_REG src; - MMX_REG *dst, dst2; + MMX_REG *dst; + MMX_REG dst2; MMX_ENTER(); fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); dst2 = *dst; MMX_GETSRC(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - dst->sw[0] = SSATW(dst2.sl[0]); dst->sw[1] = SSATW(dst2.sl[1]); dst->sw[2] = SSATW(src.sl[0]); dst->sw[3] = SSATW(src.sl[1]); - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index e0c9f89a5..912919064 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -1,13 +1,13 @@ -#define MMX_GETSHIFT() \ - if (cpu_mod == 3) { \ - shift = fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[cpu_rm].fraction).b[0] : cpu_state.MM[cpu_rm].b[0]; \ - CLOCK_CYCLES(1); \ - } else { \ - SEG_CHECK_READ(cpu_state.ea_seg); \ - shift = readmemb(easeg, cpu_state.eaaddr); \ - if (cpu_state.abrt) \ - return 0; \ - CLOCK_CYCLES(2); \ +#define MMX_GETSHIFT() \ + if (cpu_mod == 3) { \ + shift = (MMX_GETREG(cpu_rm)).b[0]; \ + CLOCK_CYCLES(1); \ + } else { \ + SEG_CHECK_READ(cpu_state.ea_seg); \ + shift = readmemb(easeg, cpu_state.eaaddr); \ + if (cpu_state.abrt) \ + return 0; \ + CLOCK_CYCLES(2); \ } static int @@ -20,12 +20,7 @@ opPSxxW_imm(uint32_t fetchdat) cpu_state.pc += 2; MMX_ENTER(); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[reg].fraction) : &(cpu_state.MM[reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(reg); switch (op) { case 0x10: /*PSRLW*/ @@ -62,8 +57,7 @@ opPSxxW_imm(uint32_t fetchdat) return 0; } - if (fpu_softfloat) - fpu_state.st_space[reg].exp = 0xffff; + MMX_SETEXP(); CLOCK_CYCLES(1); return 0; @@ -79,15 +73,10 @@ opPSLLW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - if (shift > 15) dst->q = 0; else { @@ -97,8 +86,7 @@ opPSLLW_a16(uint32_t fetchdat) dst->w[3] <<= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -112,15 +100,10 @@ opPSLLW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } - if (shift > 15) dst->q = 0; else { @@ -130,8 +113,7 @@ opPSLLW_a32(uint32_t fetchdat) dst->w[3] <<= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -146,12 +128,7 @@ opPSRLW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -164,8 +141,7 @@ opPSRLW_a16(uint32_t fetchdat) dst->w[3] >>= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -179,12 +155,7 @@ opPSRLW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -197,8 +168,7 @@ opPSRLW_a32(uint32_t fetchdat) dst->w[3] >>= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -213,12 +183,7 @@ opPSRAW_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -230,8 +195,7 @@ opPSRAW_a16(uint32_t fetchdat) dst->sw[2] >>= shift; dst->sw[3] >>= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -245,12 +209,7 @@ opPSRAW_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -262,8 +221,7 @@ opPSRAW_a32(uint32_t fetchdat) dst->sw[2] >>= shift; dst->sw[3] >>= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -279,12 +237,7 @@ opPSxxD_imm(uint32_t fetchdat) cpu_state.pc += 2; MMX_ENTER(); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[reg].fraction) : &(cpu_state.MM[reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(reg); switch (op) { case 0x10: /*PSRLD*/ @@ -315,8 +268,7 @@ opPSxxD_imm(uint32_t fetchdat) return 0; } - if (fpu_softfloat) - fpu_state.st_space[reg].exp = 0xffff; + MMX_SETEXP(); CLOCK_CYCLES(1); return 0; @@ -332,12 +284,7 @@ opPSLLD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -348,8 +295,7 @@ opPSLLD_a16(uint32_t fetchdat) dst->l[1] <<= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -363,12 +309,7 @@ opPSLLD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -379,8 +320,7 @@ opPSLLD_a32(uint32_t fetchdat) dst->l[1] <<= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -395,12 +335,7 @@ opPSRLD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -411,8 +346,7 @@ opPSRLD_a16(uint32_t fetchdat) dst->l[1] >>= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -426,12 +360,7 @@ opPSRLD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -442,8 +371,7 @@ opPSRLD_a32(uint32_t fetchdat) dst->l[1] >>= shift; } - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -458,12 +386,7 @@ opPSRAD_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -473,8 +396,7 @@ opPSRAD_a16(uint32_t fetchdat) dst->sl[0] >>= shift; dst->sl[1] >>= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -488,12 +410,7 @@ opPSRAD_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -503,8 +420,7 @@ opPSRAD_a32(uint32_t fetchdat) dst->sl[0] >>= shift; dst->sl[1] >>= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -521,12 +437,7 @@ opPSxxQ_imm(uint32_t fetchdat) MMX_ENTER(); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[reg].fraction) : &(cpu_state.MM[reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(reg); switch (op) { case 0x10: /*PSRLW*/ @@ -553,8 +464,7 @@ opPSxxQ_imm(uint32_t fetchdat) return 0; } - if (fpu_softfloat) - fpu_state.st_space[reg].exp = 0xffff; + MMX_SETEXP(); CLOCK_CYCLES(1); return 0; @@ -570,12 +480,7 @@ opPSLLQ_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -584,8 +489,7 @@ opPSLLQ_a16(uint32_t fetchdat) else dst->q <<= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -599,12 +503,7 @@ opPSLLQ_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -613,8 +512,7 @@ opPSLLQ_a32(uint32_t fetchdat) else dst->q <<= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -629,12 +527,7 @@ opPSRLQ_a16(uint32_t fetchdat) fetch_ea_16(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -643,8 +536,7 @@ opPSRLQ_a16(uint32_t fetchdat) else dst->q >>= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } @@ -658,12 +550,7 @@ opPSRLQ_a32(uint32_t fetchdat) fetch_ea_32(fetchdat); - dst = fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[cpu_reg].fraction) : &(cpu_state.MM[cpu_reg]); - - if (fpu_softfloat) { - fpu_state.tag = 0; - fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ - } + dst = MMX_GETREGP(cpu_reg); MMX_GETSHIFT(); @@ -672,8 +559,7 @@ opPSRLQ_a32(uint32_t fetchdat) else dst->q >>= shift; - if (fpu_softfloat) - fpu_state.st_space[cpu_reg].exp = 0xffff; + MMX_SETEXP(); return 0; } diff --git a/src/cpu/x87.h b/src/cpu/x87.h index 8fab28ce8..66d51dbd9 100644 --- a/src/cpu/x87.h +++ b/src/cpu/x87.h @@ -10,9 +10,14 @@ static __inline void x87_set_mmx(void) { uint64_t *p; - cpu_state.TOP = 0; - p = (uint64_t *) cpu_state.tag; - *p = 0x0101010101010101ull; + if (fpu_softfloat) { + fpu_state.tag = 0; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } else { + cpu_state.TOP = 0; + p = (uint64_t *) cpu_state.tag; + *p = 0x0101010101010101ull; + } cpu_state.ismmx = 1; } @@ -20,8 +25,13 @@ static __inline void x87_emms(void) { uint64_t *p; - p = (uint64_t *) cpu_state.tag; - *p = 0; + if (fpu_softfloat) { + fpu_state.tag = 0xffff; + fpu_state.tos = 0; /* reset FPU Top-Of-Stack */ + } else { + p = (uint64_t *) cpu_state.tag; + *p = 0; + } cpu_state.ismmx = 0; } From dd38a5a15f886abac8670ff0552a7ae5537b31a4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:22:04 +0200 Subject: [PATCH 16/44] Part 3. --- src/cpu/x86_ops_3dnow.h | 216 +++++++++++++++++++++++++++------------- 1 file changed, 145 insertions(+), 71 deletions(-) diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index eb7a35ace..3b647b69c 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -36,17 +36,20 @@ static int opPAVGUSB(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].b[0] = (cpu_state.MM[cpu_reg].b[0] + src.b[0] + 1) >> 1; - cpu_state.MM[cpu_reg].b[1] = (cpu_state.MM[cpu_reg].b[1] + src.b[1] + 1) >> 1; - cpu_state.MM[cpu_reg].b[2] = (cpu_state.MM[cpu_reg].b[2] + src.b[2] + 1) >> 1; - cpu_state.MM[cpu_reg].b[3] = (cpu_state.MM[cpu_reg].b[3] + src.b[3] + 1) >> 1; - cpu_state.MM[cpu_reg].b[4] = (cpu_state.MM[cpu_reg].b[4] + src.b[4] + 1) >> 1; - cpu_state.MM[cpu_reg].b[5] = (cpu_state.MM[cpu_reg].b[5] + src.b[5] + 1) >> 1; - cpu_state.MM[cpu_reg].b[6] = (cpu_state.MM[cpu_reg].b[6] + src.b[6] + 1) >> 1; - cpu_state.MM[cpu_reg].b[7] = (cpu_state.MM[cpu_reg].b[7] + src.b[7] + 1) >> 1; + dst->b[0] = (dst->b[0] + src.b[0] + 1) >> 1; + dst->b[1] = (dst->b[1] + src.b[1] + 1) >> 1; + dst->b[2] = (dst->b[2] + src.b[2] + 1) >> 1; + dst->b[3] = (dst->b[3] + src.b[3] + 1) >> 1; + dst->b[4] = (dst->b[4] + src.b[4] + 1) >> 1; + dst->b[5] = (dst->b[5] + src.b[5] + 1) >> 1; + dst->b[6] = (dst->b[6] + src.b[6] + 1) >> 1; + dst->b[7] = (dst->b[7] + src.b[7] + 1) >> 1; + + MMX_SETEXP(); return 0; } @@ -54,11 +57,14 @@ static int opPF2ID(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].sl[0] = (int32_t) src.f[0]; - cpu_state.MM[cpu_reg].sl[1] = (int32_t) src.f[1]; + dst->sl[0] = (int32_t) src.f[0]; + dst->sl[1] = (int32_t) src.f[1]; + + MMX_SETEXP(); return 0; } @@ -66,11 +72,14 @@ static int opPF2IW(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].sw[0] = (int32_t) src.f[0]; - cpu_state.MM[cpu_reg].sw[1] = (int32_t) src.f[1]; + dst->sw[0] = (int32_t) src.f[0]; + dst->sw[1] = (int32_t) src.f[1]; + + MMX_SETEXP(); return 0; } @@ -78,13 +87,16 @@ static int opPFACC(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); float tempf; MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] + cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = dst->f[0] + dst->f[1]; + dst->f[1] = src.f[0] + src.f[1]; + dst->f[0] = tempf; + + MMX_SETEXP(); return 0; } @@ -92,13 +104,16 @@ static int opPFNACC(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); float tempf; MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] - src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = dst->f[0] - dst->f[1]; + dst->f[1] = src.f[0] - src.f[1]; + dst->f[0] = tempf; + + MMX_SETEXP(); return 0; } @@ -106,13 +121,16 @@ static int opPFPNACC(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); float tempf; MMX_GETSRC(); - tempf = cpu_state.MM[cpu_reg].f[0] - cpu_state.MM[cpu_reg].f[1]; - cpu_state.MM[cpu_reg].f[1] = src.f[0] + src.f[1]; - cpu_state.MM[cpu_reg].f[0] = tempf; + tempf = dst->f[0] - dst->f[1]; + dst->f[1] = src.f[0] + src.f[1]; + dst->f[0] = tempf; + + MMX_SETEXP(); return 0; } @@ -120,15 +138,18 @@ static int opPSWAPD(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); float tempf, tempf2; MMX_GETSRC(); /* We have to do this in case source and destination overlap. */ - tempf = src.f[0]; - tempf2 = src.f[1]; - cpu_state.MM[cpu_reg].f[1] = tempf; - cpu_state.MM[cpu_reg].f[0] = tempf2; + tempf = src.f[0]; + tempf2 = src.f[1]; + dst->f[1] = tempf; + dst->f[0] = tempf2; + + MMX_SETEXP(); return 0; } @@ -136,11 +157,14 @@ static int opPFADD(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] += src.f[0]; - cpu_state.MM[cpu_reg].f[1] += src.f[1]; + dst->f[0] += src.f[0]; + dst->f[1] += src.f[1]; + + MMX_SETEXP(); return 0; } @@ -148,11 +172,14 @@ static int opPFCMPEQ(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] == src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] == src.f[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->f[0] == src.f[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->f[1] == src.f[1]) ? 0xffffffff : 0; + + MMX_SETEXP(); return 0; } @@ -160,11 +187,14 @@ static int opPFCMPGE(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] >= src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] >= src.f[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->f[0] >= src.f[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->f[1] >= src.f[1]) ? 0xffffffff : 0; + + MMX_SETEXP(); return 0; } @@ -172,11 +202,14 @@ static int opPFCMPGT(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].l[0] = (cpu_state.MM[cpu_reg].f[0] > src.f[0]) ? 0xffffffff : 0; - cpu_state.MM[cpu_reg].l[1] = (cpu_state.MM[cpu_reg].f[1] > src.f[1]) ? 0xffffffff : 0; + dst->l[0] = (dst->f[0] > src.f[0]) ? 0xffffffff : 0; + dst->l[1] = (dst->f[1] > src.f[1]) ? 0xffffffff : 0; + + MMX_SETEXP(); return 0; } @@ -184,13 +217,16 @@ static int opPFMAX(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (src.f[0] > cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] > cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + if (src.f[0] > dst->f[0]) + dst->f[0] = src.f[0]; + if (src.f[1] > dst->f[1]) + dst->f[1] = src.f[1]; + + MMX_SETEXP(); return 0; } @@ -198,13 +234,16 @@ static int opPFMIN(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - if (src.f[0] < cpu_state.MM[cpu_reg].f[0]) - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - if (src.f[1] < cpu_state.MM[cpu_reg].f[1]) - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + if (src.f[0] < dst->f[0]) + dst->f[0] = src.f[0]; + if (src.f[1] < dst->f[1]) + dst->f[1] = src.f[1]; + + MMX_SETEXP(); return 0; } @@ -212,24 +251,29 @@ static int opPFMUL(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] *= src.f[0]; - cpu_state.MM[cpu_reg].f[1] *= src.f[1]; + dst->f[0] *= src.f[0]; + dst->f[1] *= src.f[1]; + + MMX_SETEXP(); return 0; } static int opPFRCP(uint32_t fetchdat) { + MMX_REG *dst = MMX_GETREGP(cpu_reg); + union { uint32_t i; float f; } src; if (cpu_mod == 3) { - src.f = cpu_state.MM[cpu_rm].f[0]; + src.f = (MMX_GETREG(cpu_rm)).f[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_READ(cpu_state.ea_seg); @@ -239,8 +283,10 @@ opPFRCP(uint32_t fetchdat) CLOCK_CYCLES(2); } - cpu_state.MM[cpu_reg].f[0] = 1.0 / src.f; - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + dst->f[0] = 1.0 / src.f; + dst->f[1] = dst->f[0]; + + MMX_SETEXP(); return 0; } @@ -249,11 +295,14 @@ static int opPFRCPIT1(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + dst->f[0] = src.f[0]; + dst->f[1] = src.f[1]; + + MMX_SETEXP(); return 0; } @@ -261,24 +310,29 @@ static int opPFRCPIT2(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1]; + dst->f[0] = src.f[0]; + dst->f[1] = src.f[1]; + + MMX_SETEXP(); return 0; } static int opPFRSQRT(uint32_t fetchdat) { + MMX_REG *dst = MMX_GETREGP(cpu_reg); + union { uint32_t i; float f; } src; if (cpu_mod == 3) { - src.f = cpu_state.MM[cpu_rm].f[0]; + src.f = (MMX_GETREG(cpu_rm)).f[0]; CLOCK_CYCLES(1); } else { SEG_CHECK_READ(cpu_state.ea_seg); @@ -288,8 +342,10 @@ opPFRSQRT(uint32_t fetchdat) CLOCK_CYCLES(2); } - cpu_state.MM[cpu_reg].f[0] = 1.0 / sqrt(src.f); - cpu_state.MM[cpu_reg].f[1] = cpu_state.MM[cpu_reg].f[0]; + dst->f[0] = 1.0 / sqrt(src.f); + dst->f[1] = dst->f[0]; + + MMX_SETEXP(); return 0; } @@ -308,11 +364,14 @@ static int opPFSUB(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] -= src.f[0]; - cpu_state.MM[cpu_reg].f[1] -= src.f[1]; + dst->f[0] -= src.f[0]; + dst->f[1] -= src.f[1]; + + MMX_SETEXP(); return 0; } @@ -320,11 +379,14 @@ static int opPFSUBR(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = src.f[0] - cpu_state.MM[cpu_reg].f[0]; - cpu_state.MM[cpu_reg].f[1] = src.f[1] - cpu_state.MM[cpu_reg].f[1]; + dst->f[0] = src.f[0] - dst->f[0]; + dst->f[1] = src.f[1] - dst->f[1]; + + MMX_SETEXP(); return 0; } @@ -332,11 +394,14 @@ static int opPI2FD(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = (float) src.sl[0]; - cpu_state.MM[cpu_reg].f[1] = (float) src.sl[1]; + dst->f[0] = (float) src.sl[0]; + dst->f[1] = (float) src.sl[1]; + + MMX_SETEXP(); return 0; } @@ -344,37 +409,46 @@ static int opPI2FW(uint32_t fetchdat) { MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); MMX_GETSRC(); - cpu_state.MM[cpu_reg].f[0] = (float) src.sw[0]; - cpu_state.MM[cpu_reg].f[1] = (float) src.sw[1]; + dst->f[0] = (float) src.sw[0]; + dst->f[1] = (float) src.sw[1]; + + MMX_SETEXP(); return 0; } static int opPMULHRW(uint32_t fetchdat) { + MMX_REG src; + MMX_REG *dst = MMX_GETREGP(cpu_reg); + if (cpu_mod == 3) { - cpu_state.MM[cpu_reg].w[0] = (((int32_t) cpu_state.MM[cpu_reg].sw[0] * (int32_t) cpu_state.MM[cpu_rm].sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = (((int32_t) cpu_state.MM[cpu_reg].sw[1] * (int32_t) cpu_state.MM[cpu_rm].sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = (((int32_t) cpu_state.MM[cpu_reg].sw[2] * (int32_t) cpu_state.MM[cpu_rm].sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = (((int32_t) cpu_state.MM[cpu_reg].sw[3] * (int32_t) cpu_state.MM[cpu_rm].sw[3]) + 0x8000) >> 16; + src = MMX_GETREG(cpu_rm); + + dst->w[0] = (((int32_t) dst->sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + dst->w[1] = (((int32_t) dst->sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + dst->w[2] = (((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + dst->w[3] = (((int32_t) dst->sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; CLOCK_CYCLES(1); } else { - MMX_REG src; - SEG_CHECK_READ(cpu_state.ea_seg); src.l[0] = readmeml(easeg, cpu_state.eaaddr); src.l[1] = readmeml(easeg, cpu_state.eaaddr + 4); if (cpu_state.abrt) return 0; - cpu_state.MM[cpu_reg].w[0] = ((int32_t) (cpu_state.MM[cpu_reg].sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[1] = ((int32_t) (cpu_state.MM[cpu_reg].sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[2] = ((int32_t) (cpu_state.MM[cpu_reg].sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; - cpu_state.MM[cpu_reg].w[3] = ((int32_t) (cpu_state.MM[cpu_reg].sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; + dst->w[0] = ((int32_t) (dst->sw[0] * (int32_t) src.sw[0]) + 0x8000) >> 16; + dst->w[1] = ((int32_t) (dst->sw[1] * (int32_t) src.sw[1]) + 0x8000) >> 16; + dst->w[2] = ((int32_t) (dst->sw[2] * (int32_t) src.sw[2]) + 0x8000) >> 16; + dst->w[3] = ((int32_t) (dst->sw[3] * (int32_t) src.sw[3]) + 0x8000) >> 16; CLOCK_CYCLES(2); } + + MMX_SETEXP(); + return 0; } From 002540e76382f64bc62e0f562243e953b531b86a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Jul 2023 22:24:29 -0300 Subject: [PATCH 17/44] serial: Give up on passthrough if no ports are enabled, fixes #3254 --- src/device/serial_passthrough.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/device/serial_passthrough.c b/src/device/serial_passthrough.c index a8c531f07..b703cd67c 100644 --- a/src/device/serial_passthrough.c +++ b/src/device/serial_passthrough.c @@ -119,6 +119,8 @@ static void serial_passthrough_speed_changed(void *priv) { serial_passthrough_t *dev = (serial_passthrough_t *) priv; + if (!dev) + return; timer_stop(&dev->host_to_serial_timer); /* FIXME: do something to dev->baudrate */ @@ -132,9 +134,11 @@ static void serial_passthrough_dev_close(void *priv) { serial_passthrough_t *dev = (serial_passthrough_t *) priv; + if (!dev) + return; /* Detach passthrough device from COM port */ - if (dev && dev->serial && dev->serial->sd) + if (dev->serial && dev->serial->sd) memset(dev->serial->sd, 0, sizeof(serial_device_t)); plat_serpt_close(dev); @@ -184,6 +188,10 @@ serial_passthrough_dev_init(const device_t *info) /* Attach passthrough device to a COM port */ dev->serial = serial_attach_ex(dev->port, serial_passthrough_rcr_cb, serial_passthrough_write, serial_passthrough_transmit_period, serial_passthrough_lcr_callback, dev); + if (!dev->serial) { + free(dev); + return NULL; + } strncpy(dev->host_serial_path, device_get_config_string("host_serial_path"), 1023); #ifdef _WIN32 From e47e1b62c8cda39d35481ecd196fc5b241ffdfb8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:28:37 +0200 Subject: [PATCH 18/44] Part 4. --- src/cpu/x86_ops_3dnow.h | 46 ++++++++++++------------- src/cpu/x86_ops_mmx.h | 4 +-- src/cpu/x86_ops_mmx_arith.h | 68 ++++++++++++++++++------------------- src/cpu/x86_ops_mmx_cmp.h | 24 ++++++------- src/cpu/x86_ops_mmx_logic.h | 16 ++++----- src/cpu/x86_ops_mmx_mov.h | 12 +++---- src/cpu/x86_ops_mmx_pack.h | 36 ++++++++++---------- src/cpu/x86_ops_mmx_shift.h | 38 ++++++++++----------- 8 files changed, 122 insertions(+), 122 deletions(-) diff --git a/src/cpu/x86_ops_3dnow.h b/src/cpu/x86_ops_3dnow.h index 3b647b69c..ff657d708 100644 --- a/src/cpu/x86_ops_3dnow.h +++ b/src/cpu/x86_ops_3dnow.h @@ -49,7 +49,7 @@ opPAVGUSB(uint32_t fetchdat) dst->b[6] = (dst->b[6] + src.b[6] + 1) >> 1; dst->b[7] = (dst->b[7] + src.b[7] + 1) >> 1; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -64,7 +64,7 @@ opPF2ID(uint32_t fetchdat) dst->sl[0] = (int32_t) src.f[0]; dst->sl[1] = (int32_t) src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -79,7 +79,7 @@ opPF2IW(uint32_t fetchdat) dst->sw[0] = (int32_t) src.f[0]; dst->sw[1] = (int32_t) src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -96,7 +96,7 @@ opPFACC(uint32_t fetchdat) dst->f[1] = src.f[0] + src.f[1]; dst->f[0] = tempf; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -113,7 +113,7 @@ opPFNACC(uint32_t fetchdat) dst->f[1] = src.f[0] - src.f[1]; dst->f[0] = tempf; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -130,7 +130,7 @@ opPFPNACC(uint32_t fetchdat) dst->f[1] = src.f[0] + src.f[1]; dst->f[0] = tempf; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -149,7 +149,7 @@ opPSWAPD(uint32_t fetchdat) dst->f[1] = tempf; dst->f[0] = tempf2; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -164,7 +164,7 @@ opPFADD(uint32_t fetchdat) dst->f[0] += src.f[0]; dst->f[1] += src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -179,7 +179,7 @@ opPFCMPEQ(uint32_t fetchdat) dst->l[0] = (dst->f[0] == src.f[0]) ? 0xffffffff : 0; dst->l[1] = (dst->f[1] == src.f[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -194,7 +194,7 @@ opPFCMPGE(uint32_t fetchdat) dst->l[0] = (dst->f[0] >= src.f[0]) ? 0xffffffff : 0; dst->l[1] = (dst->f[1] >= src.f[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -209,7 +209,7 @@ opPFCMPGT(uint32_t fetchdat) dst->l[0] = (dst->f[0] > src.f[0]) ? 0xffffffff : 0; dst->l[1] = (dst->f[1] > src.f[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -226,7 +226,7 @@ opPFMAX(uint32_t fetchdat) if (src.f[1] > dst->f[1]) dst->f[1] = src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -243,7 +243,7 @@ opPFMIN(uint32_t fetchdat) if (src.f[1] < dst->f[1]) dst->f[1] = src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -258,7 +258,7 @@ opPFMUL(uint32_t fetchdat) dst->f[0] *= src.f[0]; dst->f[1] *= src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -286,7 +286,7 @@ opPFRCP(uint32_t fetchdat) dst->f[0] = 1.0 / src.f; dst->f[1] = dst->f[0]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -302,7 +302,7 @@ opPFRCPIT1(uint32_t fetchdat) dst->f[0] = src.f[0]; dst->f[1] = src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -317,7 +317,7 @@ opPFRCPIT2(uint32_t fetchdat) dst->f[0] = src.f[0]; dst->f[1] = src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -345,7 +345,7 @@ opPFRSQRT(uint32_t fetchdat) dst->f[0] = 1.0 / sqrt(src.f); dst->f[1] = dst->f[0]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -371,7 +371,7 @@ opPFSUB(uint32_t fetchdat) dst->f[0] -= src.f[0]; dst->f[1] -= src.f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -386,7 +386,7 @@ opPFSUBR(uint32_t fetchdat) dst->f[0] = src.f[0] - dst->f[0]; dst->f[1] = src.f[1] - dst->f[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -401,7 +401,7 @@ opPI2FD(uint32_t fetchdat) dst->f[0] = (float) src.sl[0]; dst->f[1] = (float) src.sl[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -416,7 +416,7 @@ opPI2FW(uint32_t fetchdat) dst->f[0] = (float) src.sw[0]; dst->f[1] = (float) src.sw[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -447,7 +447,7 @@ opPMULHRW(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index 77df5d990..9706b206c 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -6,9 +6,9 @@ #define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r]) #define MMX_GETREG(r) fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[r].fraction) : cpu_state.MM[r] -#define MMX_SETEXP() \ +#define MMX_SETEXP(r) \ if (fpu_softfloat) \ - fpu_state.st_space[cpu_reg].exp = 0xffff + fpu_state.st_space[r].exp = 0xffff #define MMX_GETSRC() \ if (cpu_mod == 3) { \ diff --git a/src/cpu/x86_ops_mmx_arith.h b/src/cpu/x86_ops_mmx_arith.h index 66ff79cd2..642e99c8a 100644 --- a/src/cpu/x86_ops_mmx_arith.h +++ b/src/cpu/x86_ops_mmx_arith.h @@ -20,7 +20,7 @@ opPADDB_a16(uint32_t fetchdat) dst->b[6] += src.b[6]; dst->b[7] += src.b[7]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -46,7 +46,7 @@ opPADDB_a32(uint32_t fetchdat) dst->b[6] += src.b[6]; dst->b[7] += src.b[7]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -69,7 +69,7 @@ opPADDW_a16(uint32_t fetchdat) dst->w[2] += src.w[2]; dst->w[3] += src.w[3]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -91,7 +91,7 @@ opPADDW_a32(uint32_t fetchdat) dst->w[2] += src.w[2]; dst->w[3] += src.w[3]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -112,7 +112,7 @@ opPADDD_a16(uint32_t fetchdat) dst->l[0] += src.l[0]; dst->l[1] += src.l[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -132,7 +132,7 @@ opPADDD_a32(uint32_t fetchdat) dst->l[0] += src.l[0]; dst->l[1] += src.l[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -159,7 +159,7 @@ opPADDSB_a16(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -185,7 +185,7 @@ opPADDSB_a32(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] + src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] + src.sb[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -212,7 +212,7 @@ opPADDUSB_a16(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] + src.b[6]); dst->b[7] = USATB(dst->b[7] + src.b[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -238,7 +238,7 @@ opPADDUSB_a32(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] + src.b[6]); dst->b[7] = USATB(dst->b[7] + src.b[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -261,7 +261,7 @@ opPADDSW_a16(uint32_t fetchdat) dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -283,7 +283,7 @@ opPADDSW_a32(uint32_t fetchdat) dst->sw[2] = SSATW(dst->sw[2] + src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] + src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -306,7 +306,7 @@ opPADDUSW_a16(uint32_t fetchdat) dst->w[2] = USATW(dst->w[2] + src.w[2]); dst->w[3] = USATW(dst->w[3] + src.w[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -328,7 +328,7 @@ opPADDUSW_a32(uint32_t fetchdat) dst->w[2] = USATW(dst->w[2] + src.w[2]); dst->w[3] = USATW(dst->w[3] + src.w[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -356,7 +356,7 @@ opPMADDWD_a16(uint32_t fetchdat) else dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -383,7 +383,7 @@ opPMADDWD_a32(uint32_t fetchdat) else dst->sl[1] = ((int32_t) dst->sw[2] * (int32_t) src.sw[2]) + ((int32_t) dst->sw[3] * (int32_t) src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -415,7 +415,7 @@ opPMULLW_a16(uint32_t fetchdat) dst->w[3] *= src.w[3]; CLOCK_CYCLES(1); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -446,7 +446,7 @@ opPMULLW_a32(uint32_t fetchdat) dst->w[3] *= src.w[3]; CLOCK_CYCLES(1); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -478,7 +478,7 @@ opPMULHW_a16(uint32_t fetchdat) dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; CLOCK_CYCLES(1); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -509,7 +509,7 @@ opPMULHW_a32(uint32_t fetchdat) dst->w[3] = ((int32_t) dst->sw[3] * (int32_t) src.sw[3]) >> 16; CLOCK_CYCLES(1); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -536,7 +536,7 @@ opPSUBB_a16(uint32_t fetchdat) dst->b[6] -= src.b[6]; dst->b[7] -= src.b[7]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -562,7 +562,7 @@ opPSUBB_a32(uint32_t fetchdat) dst->b[6] -= src.b[6]; dst->b[7] -= src.b[7]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -585,7 +585,7 @@ opPSUBW_a16(uint32_t fetchdat) dst->w[2] -= src.w[2]; dst->w[3] -= src.w[3]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -607,7 +607,7 @@ opPSUBW_a32(uint32_t fetchdat) dst->w[2] -= src.w[2]; dst->w[3] -= src.w[3]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -628,7 +628,7 @@ opPSUBD_a16(uint32_t fetchdat) dst->l[0] -= src.l[0]; dst->l[1] -= src.l[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -648,7 +648,7 @@ opPSUBD_a32(uint32_t fetchdat) dst->l[0] -= src.l[0]; dst->l[1] -= src.l[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -675,7 +675,7 @@ opPSUBSB_a16(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -701,7 +701,7 @@ opPSUBSB_a32(uint32_t fetchdat) dst->sb[6] = SSATB(dst->sb[6] - src.sb[6]); dst->sb[7] = SSATB(dst->sb[7] - src.sb[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -728,7 +728,7 @@ opPSUBUSB_a16(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] - src.b[6]); dst->b[7] = USATB(dst->b[7] - src.b[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -754,7 +754,7 @@ opPSUBUSB_a32(uint32_t fetchdat) dst->b[6] = USATB(dst->b[6] - src.b[6]); dst->b[7] = USATB(dst->b[7] - src.b[7]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -777,7 +777,7 @@ opPSUBSW_a16(uint32_t fetchdat) dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -799,7 +799,7 @@ opPSUBSW_a32(uint32_t fetchdat) dst->sw[2] = SSATW(dst->sw[2] - src.sw[2]); dst->sw[3] = SSATW(dst->sw[3] - src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -822,7 +822,7 @@ opPSUBUSW_a16(uint32_t fetchdat) dst->w[2] = USATW(dst->w[2] - src.w[2]); dst->w[3] = USATW(dst->w[3] - src.w[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -844,7 +844,7 @@ opPSUBUSW_a32(uint32_t fetchdat) dst->w[2] = USATW(dst->w[2] - src.w[2]); dst->w[3] = USATW(dst->w[3] - src.w[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_cmp.h b/src/cpu/x86_ops_mmx_cmp.h index d98e56511..b3081b8e8 100644 --- a/src/cpu/x86_ops_mmx_cmp.h +++ b/src/cpu/x86_ops_mmx_cmp.h @@ -20,7 +20,7 @@ opPCMPEQB_a16(uint32_t fetchdat) dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -46,7 +46,7 @@ opPCMPEQB_a32(uint32_t fetchdat) dst->b[6] = (dst->b[6] == src.b[6]) ? 0xff : 0; dst->b[7] = (dst->b[7] == src.b[7]) ? 0xff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -73,7 +73,7 @@ opPCMPGTB_a16(uint32_t fetchdat) dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -99,7 +99,7 @@ opPCMPGTB_a32(uint32_t fetchdat) dst->b[6] = (dst->sb[6] > src.sb[6]) ? 0xff : 0; dst->b[7] = (dst->sb[7] > src.sb[7]) ? 0xff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -122,7 +122,7 @@ opPCMPEQW_a16(uint32_t fetchdat) dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -144,7 +144,7 @@ opPCMPEQW_a32(uint32_t fetchdat) dst->w[2] = (dst->w[2] == src.w[2]) ? 0xffff : 0; dst->w[3] = (dst->w[3] == src.w[3]) ? 0xffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -167,7 +167,7 @@ opPCMPGTW_a16(uint32_t fetchdat) dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -189,7 +189,7 @@ opPCMPGTW_a32(uint32_t fetchdat) dst->w[2] = (dst->sw[2] > src.sw[2]) ? 0xffff : 0; dst->w[3] = (dst->sw[3] > src.sw[3]) ? 0xffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -210,7 +210,7 @@ opPCMPEQD_a16(uint32_t fetchdat) dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -230,7 +230,7 @@ opPCMPEQD_a32(uint32_t fetchdat) dst->l[0] = (dst->l[0] == src.l[0]) ? 0xffffffff : 0; dst->l[1] = (dst->l[1] == src.l[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -251,7 +251,7 @@ opPCMPGTD_a16(uint32_t fetchdat) dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -271,7 +271,7 @@ opPCMPGTD_a32(uint32_t fetchdat) dst->l[0] = (dst->sl[0] > src.sl[0]) ? 0xffffffff : 0; dst->l[1] = (dst->sl[1] > src.sl[1]) ? 0xffffffff : 0; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_logic.h b/src/cpu/x86_ops_mmx_logic.h index d0079347a..26d7c1693 100644 --- a/src/cpu/x86_ops_mmx_logic.h +++ b/src/cpu/x86_ops_mmx_logic.h @@ -13,7 +13,7 @@ opPAND_a16(uint32_t fetchdat) dst->q &= src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -32,7 +32,7 @@ opPAND_a32(uint32_t fetchdat) dst->q &= src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -52,7 +52,7 @@ opPANDN_a16(uint32_t fetchdat) dst->q = ~dst->q & src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -71,7 +71,7 @@ opPANDN_a32(uint32_t fetchdat) dst->q = ~dst->q & src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -91,7 +91,7 @@ opPOR_a16(uint32_t fetchdat) dst->q |= src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -110,7 +110,7 @@ opPOR_a32(uint32_t fetchdat) dst->q |= src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -130,7 +130,7 @@ opPXOR_a16(uint32_t fetchdat) dst->q ^= src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -149,7 +149,7 @@ opPXOR_a32(uint32_t fetchdat) dst->q ^= src.q; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_mov.h b/src/cpu/x86_ops_mmx_mov.h index d65c82693..65bbb0c01 100644 --- a/src/cpu/x86_ops_mmx_mov.h +++ b/src/cpu/x86_ops_mmx_mov.h @@ -24,7 +24,7 @@ opMOVD_l_mm_a16(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -54,7 +54,7 @@ opMOVD_l_mm_a32(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -198,7 +198,7 @@ opMOVQ_q_mm_a16(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -228,7 +228,7 @@ opMOVQ_q_mm_a32(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -250,7 +250,7 @@ opMOVQ_mm_q_a16(uint32_t fetchdat) dst->q = src.q; CLOCK_CYCLES(1); - MMX_SETEXP(); + MMX_SETEXP(cpu_rm); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); @@ -280,7 +280,7 @@ opMOVQ_mm_q_a32(uint32_t fetchdat) dst->q = src.q; CLOCK_CYCLES(1); - MMX_SETEXP(); + MMX_SETEXP(cpu_rm); } else { SEG_CHECK_WRITE(cpu_state.ea_seg); CHECK_WRITE_COMMON(cpu_state.ea_seg, cpu_state.eaaddr, cpu_state.eaaddr + 7); diff --git a/src/cpu/x86_ops_mmx_pack.h b/src/cpu/x86_ops_mmx_pack.h index a76ad1d0a..90590638b 100644 --- a/src/cpu/x86_ops_mmx_pack.h +++ b/src/cpu/x86_ops_mmx_pack.h @@ -24,7 +24,7 @@ opPUNPCKLDQ_a16(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -54,7 +54,7 @@ opPUNPCKLDQ_a32(uint32_t fetchdat) CLOCK_CYCLES(2); } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -75,7 +75,7 @@ opPUNPCKHDQ_a16(uint32_t fetchdat) dst->l[0] = dst->l[1]; dst->l[1] = src.l[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -95,7 +95,7 @@ opPUNPCKHDQ_a32(uint32_t fetchdat) dst->l[0] = dst->l[1]; dst->l[1] = src.l[1]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -122,7 +122,7 @@ opPUNPCKLBW_a16(uint32_t fetchdat) dst->b[1] = src.b[0]; dst->b[0] = dst->b[0]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -148,7 +148,7 @@ opPUNPCKLBW_a32(uint32_t fetchdat) dst->b[1] = src.b[0]; dst->b[0] = dst->b[0]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -175,7 +175,7 @@ opPUNPCKHBW_a16(uint32_t fetchdat) dst->b[6] = dst->b[7]; dst->b[7] = src.b[7]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -201,7 +201,7 @@ opPUNPCKHBW_a32(uint32_t fetchdat) dst->b[6] = dst->b[7]; dst->b[7] = src.b[7]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -224,7 +224,7 @@ opPUNPCKLWD_a16(uint32_t fetchdat) dst->w[1] = src.w[0]; dst->w[0] = dst->w[0]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -246,7 +246,7 @@ opPUNPCKLWD_a32(uint32_t fetchdat) dst->w[1] = src.w[0]; dst->w[0] = dst->w[0]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -269,7 +269,7 @@ opPUNPCKHWD_a16(uint32_t fetchdat) dst->w[2] = dst->w[3]; dst->w[3] = src.w[3]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -291,7 +291,7 @@ opPUNPCKHWD_a32(uint32_t fetchdat) dst->w[2] = dst->w[3]; dst->w[3] = src.w[3]; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -318,7 +318,7 @@ opPACKSSWB_a16(uint32_t fetchdat) dst->sb[6] = SSATB(src.sw[2]); dst->sb[7] = SSATB(src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -344,7 +344,7 @@ opPACKSSWB_a32(uint32_t fetchdat) dst->sb[6] = SSATB(src.sw[2]); dst->sb[7] = SSATB(src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -371,7 +371,7 @@ opPACKUSWB_a16(uint32_t fetchdat) dst->b[6] = USATB(src.sw[2]); dst->b[7] = USATB(src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -397,7 +397,7 @@ opPACKUSWB_a32(uint32_t fetchdat) dst->b[6] = USATB(src.sw[2]); dst->b[7] = USATB(src.sw[3]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -422,7 +422,7 @@ opPACKSSDW_a16(uint32_t fetchdat) dst->sw[2] = SSATW(src.sl[0]); dst->sw[3] = SSATW(src.sl[1]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -446,7 +446,7 @@ opPACKSSDW_a32(uint32_t fetchdat) dst->sw[2] = SSATW(src.sl[0]); dst->sw[3] = SSATW(src.sl[1]); - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } diff --git a/src/cpu/x86_ops_mmx_shift.h b/src/cpu/x86_ops_mmx_shift.h index 912919064..c0c80e87e 100644 --- a/src/cpu/x86_ops_mmx_shift.h +++ b/src/cpu/x86_ops_mmx_shift.h @@ -57,7 +57,7 @@ opPSxxW_imm(uint32_t fetchdat) return 0; } - MMX_SETEXP(); + MMX_SETEXP(reg); CLOCK_CYCLES(1); return 0; @@ -86,7 +86,7 @@ opPSLLW_a16(uint32_t fetchdat) dst->w[3] <<= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -113,7 +113,7 @@ opPSLLW_a32(uint32_t fetchdat) dst->w[3] <<= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -141,7 +141,7 @@ opPSRLW_a16(uint32_t fetchdat) dst->w[3] >>= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -168,7 +168,7 @@ opPSRLW_a32(uint32_t fetchdat) dst->w[3] >>= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -195,7 +195,7 @@ opPSRAW_a16(uint32_t fetchdat) dst->sw[2] >>= shift; dst->sw[3] >>= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -221,7 +221,7 @@ opPSRAW_a32(uint32_t fetchdat) dst->sw[2] >>= shift; dst->sw[3] >>= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -268,7 +268,7 @@ opPSxxD_imm(uint32_t fetchdat) return 0; } - MMX_SETEXP(); + MMX_SETEXP(reg); CLOCK_CYCLES(1); return 0; @@ -295,7 +295,7 @@ opPSLLD_a16(uint32_t fetchdat) dst->l[1] <<= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -320,7 +320,7 @@ opPSLLD_a32(uint32_t fetchdat) dst->l[1] <<= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -346,7 +346,7 @@ opPSRLD_a16(uint32_t fetchdat) dst->l[1] >>= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -371,7 +371,7 @@ opPSRLD_a32(uint32_t fetchdat) dst->l[1] >>= shift; } - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -396,7 +396,7 @@ opPSRAD_a16(uint32_t fetchdat) dst->sl[0] >>= shift; dst->sl[1] >>= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -420,7 +420,7 @@ opPSRAD_a32(uint32_t fetchdat) dst->sl[0] >>= shift; dst->sl[1] >>= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -464,7 +464,7 @@ opPSxxQ_imm(uint32_t fetchdat) return 0; } - MMX_SETEXP(); + MMX_SETEXP(reg); CLOCK_CYCLES(1); return 0; @@ -489,7 +489,7 @@ opPSLLQ_a16(uint32_t fetchdat) else dst->q <<= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -512,7 +512,7 @@ opPSLLQ_a32(uint32_t fetchdat) else dst->q <<= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -536,7 +536,7 @@ opPSRLQ_a16(uint32_t fetchdat) else dst->q >>= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } @@ -559,7 +559,7 @@ opPSRLQ_a32(uint32_t fetchdat) else dst->q >>= shift; - MMX_SETEXP(); + MMX_SETEXP(cpu_reg); return 0; } From 937b7740f2ca4acdec5251816cdeaf5750f32ec5 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Jul 2023 22:33:15 -0300 Subject: [PATCH 19/44] printer: Enable 10.x and unversioned ghostscript libraries to be used on Linux, fixes #2996 --- src/printer/prt_ps.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/printer/prt_ps.c b/src/printer/prt_ps.c index 9786b9063..caa166a10 100644 --- a/src/printer/prt_ps.c +++ b/src/printer/prt_ps.c @@ -51,7 +51,9 @@ #elif defined __APPLE__ # define PATH_GHOSTSCRIPT_DLL "libgs.dylib" #else -# define PATH_GHOSTSCRIPT_DLL "libgs.so.9" +# define PATH_GHOSTSCRIPT_DLL "libgs.so.9" +# define PATH_GHOSTSCRIPT_DLL_ALT1 "libgs.so.10" +# define PATH_GHOSTSCRIPT_DLL_ALT2 "libgs.so" #endif #define POSTSCRIPT_BUFFER_LENGTH 65536 @@ -341,12 +343,21 @@ ps_init(void *lpt) /* Try loading the DLL. */ ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL, ghostscript_imports); - if (ghostscript_handle == NULL) +#ifdef PATH_GHOSTSCRIPT_DLL_ALT1 + if (ghostscript_handle == NULL) { + ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT1, ghostscript_imports); +# ifdef PATH_GHOSTSCRIPT_DLL_ALT2 + if (ghostscript_handle == NULL) + ghostscript_handle = dynld_module(PATH_GHOSTSCRIPT_DLL_ALT2, ghostscript_imports); +# endif + } +#endif + if (ghostscript_handle == NULL) { ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2115, (wchar_t *) IDS_2133); - else { - if (gsapi_revision(&rev, sizeof(rev)) == 0) + } else { + if (gsapi_revision(&rev, sizeof(rev)) == 0) { pclog("Loaded %s, rev %ld (%ld)\n", rev.product, rev.revision, rev.revisiondate); - else { + } else { dynld_close(ghostscript_handle); ghostscript_handle = NULL; } From 1d59351c03a1f0d8cc3f53f5c771232bf406db65 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:43:54 +0200 Subject: [PATCH 20/44] Some MMX optimizations. --- src/cpu/CMakeLists.txt | 2 +- src/cpu/cpu.c | 1 + src/cpu/cpu.h | 5 +++++ src/cpu/x86_ops_mmx.h | 7 +++---- src/win/Makefile.mingw | 2 +- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/cpu/CMakeLists.txt b/src/cpu/CMakeLists.txt index d1011504e..e4d8e71b2 100644 --- a/src/cpu/CMakeLists.txt +++ b/src/cpu/CMakeLists.txt @@ -14,7 +14,7 @@ # add_library(cpu OBJECT cpu.c cpu_table.c fpu.c x86.c 808x.c 386.c 386_common.c - 386_dynarec.c x86seg.c x87.c x87_timings.c 8080.c) + 386_dynarec.c x86_ops_mmx.c x86seg.c x87.c x87_timings.c 8080.c) if(AMD_K5) target_compile_definitions(cpu PRIVATE USE_AMD_K5) diff --git a/src/cpu/cpu.c b/src/cpu/cpu.c index 257d23845..d633b9bb2 100644 --- a/src/cpu/cpu.c +++ b/src/cpu/cpu.c @@ -1646,6 +1646,7 @@ cpu_set(void) cpu_exec = exec386; else cpu_exec = execx86; + mmx_init(); gdbstub_cpu_init(); } diff --git a/src/cpu/cpu.h b/src/cpu/cpu.h index 692600005..3d6d0622a 100644 --- a/src/cpu/cpu.h +++ b/src/cpu/cpu.h @@ -850,4 +850,9 @@ extern void cpu_fast_off_reset(void); extern void smi_raise(void); extern void nmi_raise(void); +extern MMX_REG *MMP[8]; +extern uint16_t *MMEP[8]; + +extern void mmx_init(void); + #endif /*EMU_CPU_H*/ diff --git a/src/cpu/x86_ops_mmx.h b/src/cpu/x86_ops_mmx.h index 9706b206c..47751d059 100644 --- a/src/cpu/x86_ops_mmx.h +++ b/src/cpu/x86_ops_mmx.h @@ -3,12 +3,11 @@ #define USATB(val) (((val) < 0) ? 0 : (((val) > 255) ? 255 : (val))) #define USATW(val) (((val) < 0) ? 0 : (((val) > 65535) ? 65535 : (val))) -#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r]) -#define MMX_GETREG(r) fpu_softfloat ? (*(MMX_REG *) &fpu_state.st_space[r].fraction) : cpu_state.MM[r] +#define MMX_GETREGP(r) MMP[r] +#define MMX_GETREG(r) *(MMP[r]) #define MMX_SETEXP(r) \ - if (fpu_softfloat) \ - fpu_state.st_space[r].exp = 0xffff + *(MMEP[r]) = 0xffff #define MMX_GETSRC() \ if (cpu_mod == 3) { \ diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index c5f6c61ce..55306e8d8 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -553,7 +553,7 @@ CPUOBJ := $(DYNARECOBJ) \ $(CGTOBJ) \ cpu.o cpu_table.o fpu.o x86.o \ 8080.o 808x.o 386.o 386_common.o 386_dynarec.o 386_dynarec_ops.o \ - x86seg.o x87.o x87_timings.o \ + x86_ops_mmx.o x86seg.o x87.o x87_timings.o \ f2xm1.o fpatan.o fprem.o fsincos.o fyl2x.o softfloat_poly.o softfloat.o softfloat16.o \ softfloat-muladd.o softfloat-round-pack.o softfloat-specialize.o softfloatx80.o From 3555dacec391baa636cef1c9e91172da9d555b8c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:45:14 +0200 Subject: [PATCH 21/44] Disable MMX and 3DNow! recompilation when SoftFloat is in use. --- src/codegen/codegen_ops.c | 48 +++++++++++++++++++++++++++++++++++ src/codegen/codegen_ops.h | 1 + src/codegen/codegen_x86-64.c | 2 +- src/codegen/codegen_x86.c | 2 +- src/codegen_new/codegen.c | 6 ++--- src/codegen_new/codegen_ops.c | 48 +++++++++++++++++++++++++++++++++++ src/codegen_new/codegen_ops.h | 1 + 7 files changed, 103 insertions(+), 5 deletions(-) diff --git a/src/codegen/codegen_ops.c b/src/codegen/codegen_ops.c index 46a49f118..894ebb100 100644 --- a/src/codegen/codegen_ops.c +++ b/src/codegen/codegen_ops.c @@ -128,6 +128,54 @@ RecompOpFn recomp_opcodes_0f[512] = { // clang-format on }; +RecompOpFn recomp_opcodes_0f_no_mmx[512] = { + // clang-format off + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_w, ropJNO_w, ropJB_w, ropJNB_w, ropJE_w, ropJNE_w, ropJBE_w, ropJNBE_w, ropJS_w, ropJNS_w, ropJP_w, ropJNP_w, ropJL_w, ropJNL_w, ropJLE_w, ropJNLE_w, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_w_b, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_w_b, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_l, ropJNO_l, ropJB_l, ropJNB_l, ropJE_l, ropJNE_l, ropJBE_l, ropJNBE_l, ropJS_l, ropJNS_l, ropJP_l, ropJNP_l, ropJL_l, ropJNL_l, ropJLE_l, ropJNLE_l, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, NULL, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, NULL, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS, NULL, ropLFS, ropLGS, ropMOVZX_l_b, ropMOVZX_l_w, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_l_b, ropMOVSX_l_w, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on +}; + RecompOpFn recomp_opcodes_d8[512] = { // clang-format off /*16-bit data*/ diff --git a/src/codegen/codegen_ops.h b/src/codegen/codegen_ops.h index f92ba4f6d..5c19fb666 100644 --- a/src/codegen/codegen_ops.h +++ b/src/codegen/codegen_ops.h @@ -7,6 +7,7 @@ typedef uint32_t (*RecompOpFn)(uint8_t opcode, uint32_t fetchdat, uint32_t op_32 extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; +extern RecompOpFn recomp_opcodes_0f_no_mmx[512]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; extern RecompOpFn recomp_opcodes_da[512]; diff --git a/src/codegen/codegen_x86-64.c b/src/codegen/codegen_x86-64.c index c02e8a7c2..3934b4ac5 100644 --- a/src/codegen/codegen_x86-64.c +++ b/src/codegen/codegen_x86-64.c @@ -845,7 +845,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p switch (opcode) { case 0x0f: op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; + recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f; over = 1; break; diff --git a/src/codegen/codegen_x86.c b/src/codegen/codegen_x86.c index c4b32c8a2..712fbe087 100644 --- a/src/codegen/codegen_x86.c +++ b/src/codegen/codegen_x86.c @@ -1884,7 +1884,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p switch (opcode) { case 0x0f: op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; + recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f; over = 1; break; diff --git a/src/codegen_new/codegen.c b/src/codegen_new/codegen.c index d49fcecbf..b0250fb7d 100644 --- a/src/codegen_new/codegen.c +++ b/src/codegen_new/codegen.c @@ -399,7 +399,7 @@ codegen_generate_call(uint8_t opcode, OpFn op, uint32_t fetchdat, uint32_t new_p last_prefix = 0x0f; #endif op_table = x86_dynarec_opcodes_0f; - recomp_op_table = recomp_opcodes_0f; + recomp_op_table = fpu_softfloat ? recomp_opcodes_0f_no_mmx : recomp_opcodes_0f; over = 1; break; @@ -634,11 +634,11 @@ generate_call: } opcode_3dnow = fastreadb(cs + opcode_pc); - if (recomp_opcodes_3DNOW[opcode_3dnow]) { + if (!fpu_softfloat && recomp_opcodes_3DNOW[opcode_3dnow]) { next_pc = opcode_pc + 1; op_table = (OpFn *) x86_dynarec_opcodes_3DNOW; - recomp_op_table = recomp_opcodes_3DNOW; + recomp_op_table = fpu_softfloat ? NULL : recomp_opcodes_3DNOW; opcode = opcode_3dnow; recomp_opcode_mask = 0xff; opcode_mask = 0xff; diff --git a/src/codegen_new/codegen_ops.c b/src/codegen_new/codegen_ops.c index 698a7899b..ae93aa80f 100644 --- a/src/codegen_new/codegen_ops.c +++ b/src/codegen_new/codegen_ops.c @@ -144,6 +144,54 @@ RecompOpFn recomp_opcodes_0f[512] = { // clang-format on }; +RecompOpFn recomp_opcodes_0f_no_mmx[512] = { + // clang-format off + /*16-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_16, ropJNO_16, ropJB_16, ropJNB_16, ropJE_16, ropJNE_16, ropJBE_16, ropJNBE_16, ropJS_16, ropJNS_16, ropJP_16, ropJNP_16, ropJL_16, ropJNL_16, ropJLE_16, ropJNLE_16, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_16, ropPOP_FS_16, NULL, NULL, ropSHLD_16_imm, NULL, NULL, NULL, ropPUSH_GS_16, ropPOP_GS_16, NULL, NULL, ropSHRD_16_imm, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS_16, NULL, ropLFS_16, ropLGS_16, ropMOVZX_16_8, NULL, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_16_8, NULL, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + + /*32-bit data*/ +/* 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f*/ +/*00*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*10*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*20*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*30*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*40*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*50*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*60*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*70*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + +/*80*/ ropJO_32, ropJNO_32, ropJB_32, ropJNB_32, ropJE_32, ropJNE_32, ropJBE_32, ropJNBE_32, ropJS_32, ropJNS_32, ropJP_32, ropJNP_32, ropJL_32, ropJNL_32, ropJLE_32, ropJNLE_32, +/*90*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*a0*/ ropPUSH_FS_32, ropPOP_FS_32, NULL, NULL, ropSHLD_32_imm, NULL, NULL, NULL, ropPUSH_GS_32, ropPOP_GS_32, NULL, NULL, ropSHRD_32_imm, NULL, NULL, NULL, +/*b0*/ NULL, NULL, ropLSS_32, NULL, ropLFS_32, ropLGS_32, ropMOVZX_32_8, ropMOVZX_32_16, NULL, NULL, NULL, NULL, NULL, NULL, ropMOVSX_32_8, ropMOVSX_32_16, + +/*c0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*d0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*e0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, +/*f0*/ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + // clang-format on +}; + RecompOpFn recomp_opcodes_3DNOW[256] = { // clang-format off #if defined __ARM_EABI__ || defined _ARM_ || defined _M_ARM || defined __aarch64__ || defined _M_ARM64 diff --git a/src/codegen_new/codegen_ops.h b/src/codegen_new/codegen_ops.h index 9cef07e15..352d95f13 100644 --- a/src/codegen_new/codegen_ops.h +++ b/src/codegen_new/codegen_ops.h @@ -9,6 +9,7 @@ typedef uint32_t (*RecompOpFn)(codeblock_t *block, struct ir_data_t *ir, uint8_t extern RecompOpFn recomp_opcodes[512]; extern RecompOpFn recomp_opcodes_0f[512]; +extern RecompOpFn recomp_opcodes_0f_no_mmx[512]; extern RecompOpFn recomp_opcodes_3DNOW[256]; extern RecompOpFn recomp_opcodes_d8[512]; extern RecompOpFn recomp_opcodes_d9[512]; From 38fb084124c874babd7207c1fa85f16fe67f1b7c Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:46:54 +0200 Subject: [PATCH 22/44] Fixed a bug in the Mach8/32 code. --- src/video/vid_ati_mach8.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index c8996e0eb..035f1cef0 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -1864,9 +1864,9 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 if (mach->accel.dest_y_end >= 0x600) mach->accel.dy_end |= ~0x5ff; - if (mach->accel.dy_end > mach->accel.dy_end) { + if (mach->accel.dy_end > mach->accel.dy_start) { mach->accel.stepy = 1; - } else if (mach->accel.dy_end < mach->accel.dy_end) { + } else if (mach->accel.dy_end < mach->accel.dy_start) { mach->accel.stepy = -1; } else { mach->accel.stepy = 0; From 4de80ab93e8d4a2cb1ca0e0406d2fd65bf06b108 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:47:31 +0200 Subject: [PATCH 23/44] Fixed some indentation mess in the Mach64 code. --- src/video/vid_ati_mach64.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index fee3e94f8..8c32929ce 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -1857,11 +1857,10 @@ mach64_blit(uint32_t cpu_dat, int count, mach64_t *mach64) if (!cmp_clr) MIX - if (!(mach64->dst_cntl & DST_Y_MAJOR)) { - if (!x) - dest_dat &= ~1; - } - else { + if (!(mach64->dst_cntl & DST_Y_MAJOR)) { + if (!x) + dest_dat &= ~1; + } else { if (x == (mach64->accel.x_count - 1)) dest_dat &= ~1; } From 2b5d1e19c15523b3bca58ae57be3ea6e508077d6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:48:04 +0200 Subject: [PATCH 24/44] And some unused variables in the Mach32 PCI code. --- src/video/vid_ati_mach8.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 035f1cef0..52846c21a 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -5178,7 +5178,6 @@ static uint8_t mach32_pci_read(int func, int addr, void *p) { mach_t *mach = (mach_t *) p; - svga_t *svga = &mach->svga; uint8_t ret = 0x00; switch (addr) { @@ -5252,7 +5251,6 @@ static void mach32_pci_write(int func, int addr, uint8_t val, void *p) { mach_t *mach = (mach_t *) p; - svga_t *svga = &mach->svga; switch (addr) { case PCI_REG_COMMAND: From 1d62a8dc9a3f3188b63cbe3ffdd697edef5d608f Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:49:05 +0200 Subject: [PATCH 25/44] And another warning in the Mach8/32 code. --- src/video/vid_ati_mach8.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 52846c21a..9b96dbd97 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -373,12 +373,12 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 svga_t *svga = &mach->svga; int compare_mode; int poly_src = 0; - uint16_t rd_mask = dev->accel.rd_mask; - uint16_t wrt_mask = dev->accel.wrt_mask; - uint16_t dest_cmp_clr = dev->accel.color_cmp; + unt16_t rd_mask = dev->accel.rd_mask; + uint16_t wrt_mask = dev->accel.wrt_mask; + uint16_t dest_cmp_clr = dev->accel.color_cmp; int frgd_sel, bkgd_sel, mono_src; int compare = 0; - uint16_t src_dat = 0, dest_dat; + uint16_t src_dat = 0, dest_dat = 0; uint16_t old_dest_dat; uint16_t *vram_w = (uint16_t *) svga->vram; uint16_t mix = 0; From 7e9045e6b156b641f7d6f7aaaef7aa7332ea194e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:50:00 +0200 Subject: [PATCH 26/44] And a warning in the XGA code. --- src/video/vid_xga.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 7933e74a8..e4f91bb00 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -2822,7 +2822,7 @@ xga_pos_in(uint16_t addr, void *priv) { svga_t *svga = (svga_t *) priv; xga_t *xga = &svga->xga; - uint8_t ret; + uint8_t ret = 0xff; if (xga_has_vga) { switch (addr) { From e7d150b2c6a0537342828dd3bca778f4a3a027da Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:50:49 +0200 Subject: [PATCH 27/44] And a newly-introduced compile-breaking bug in the Mach8/32 code. --- src/video/vid_ati_mach8.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_ati_mach8.c b/src/video/vid_ati_mach8.c index 9b96dbd97..9c0cbb616 100644 --- a/src/video/vid_ati_mach8.c +++ b/src/video/vid_ati_mach8.c @@ -373,7 +373,7 @@ mach_accel_start(int cmd_type, int cpu_input, int count, uint32_t mix_dat, uint3 svga_t *svga = &mach->svga; int compare_mode; int poly_src = 0; - unt16_t rd_mask = dev->accel.rd_mask; + uint16_t rd_mask = dev->accel.rd_mask; uint16_t wrt_mask = dev->accel.wrt_mask; uint16_t dest_cmp_clr = dev->accel.color_cmp; int frgd_sel, bkgd_sel, mono_src; From 4cde2f2f10038643a1ba737df4cf09a604a9a56e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 03:52:02 +0200 Subject: [PATCH 28/44] And a warning in the AT Compaq's video poll function. --- src/machine/m_at_compaq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/machine/m_at_compaq.c b/src/machine/m_at_compaq.c index 0b96495be..3676a9d92 100644 --- a/src/machine/m_at_compaq.c +++ b/src/machine/m_at_compaq.c @@ -262,7 +262,6 @@ compaq_plasma_poll(void *p) uint8_t sc; uint16_t ma = (self->cga.crtc[13] | (self->cga.crtc[12] << 8)) & 0x7fff; uint16_t ca = (self->cga.crtc[15] | (self->cga.crtc[14] << 8)) & 0x7fff; - uint16_t dat; uint16_t addr; int drawcursor; int x, c; From 7a0100e35a775c0092dfb87c077ccb15692c126d Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sat, 15 Jul 2023 22:54:33 -0300 Subject: [PATCH 29/44] printer: Switch to static freetype on Windows, finally fixes #2221 --- .ci/build.sh | 8 -- .ci/static2dll.sh | 160 ------------------------------------- src/printer/CMakeLists.txt | 9 ++- src/printer/prt_escp.c | 69 +++------------- 4 files changed, 18 insertions(+), 228 deletions(-) delete mode 100755 .ci/static2dll.sh diff --git a/.ci/build.sh b/.ci/build.sh index f4f28dea6..cf420d4dd 100755 --- a/.ci/build.sh +++ b/.ci/build.sh @@ -288,7 +288,6 @@ then echo [-] Using MSYSTEM [$MSYSTEM] # Install dependencies only if we're in a new build and/or architecture. - freetype_dll="$cache_dir/freetype.$MSYSTEM.dll" if check_buildtag "$MSYSTEM" then # Update databases and keyring only if we're in a new build. @@ -333,9 +332,6 @@ then # Clean pacman cache when running under Jenkins to save disk space. [ "$CI" = "true" ] && rm -rf /var/cache/pacman/pkg - # Generate a new freetype DLL for this architecture. - rm -f "$freetype_dll" - # Save build tag to skip this later. Doing it here (once everything is # in place) is important to avoid potential issues with retried builds. save_buildtag "$MSYSTEM" @@ -796,10 +792,6 @@ then sevenzip="$pf/7-Zip/7z.exe" [ "$arch" = "32" -a -d "/c/Program Files (x86)" ] && pf="/c/Program Files (x86)" - # Archive freetype from cache or generate it from local MSYS installation. - [ ! -e "$freetype_dll" ] && .ci/static2dll.sh -p freetype2 /$MSYSTEM/lib/libfreetype.a "$freetype_dll" - cp -p "$freetype_dll" archive_tmp/freetype.dll - # Archive Ghostscript DLL from local official distribution installation. for gs in "$pf"/gs/gs*.*.* do diff --git a/.ci/static2dll.sh b/.ci/static2dll.sh deleted file mode 100755 index 030898752..000000000 --- a/.ci/static2dll.sh +++ /dev/null @@ -1,160 +0,0 @@ -#!/bin/sh -# -# 86Box A hypervisor and IBM PC system emulator that specializes in -# running old operating systems and software designed for IBM -# PC systems and compatibles from 1981 through fairly recent -# system designs based on the PCI bus. -# -# This file is part of the 86Box distribution. -# -# Script for converting MinGW static libraries into a DLL. -# -# -# Authors: RichardG, -# -# Copyright 2021 RichardG. -# - -def_file="static2dll.def" -seen_file="static2dll.seen" -libs_file="static2dll.libs" - -find_lib() { - # Try to find a static library's file. - local msystem_lib="/$(echo $MSYSTEM | tr '[:upper:]' '[:lower:]')/lib/lib" - if [ -e "$msystem_lib$1.a" ] - then - echo "$msystem_lib$1.a" - elif [ -e "$msystem_lib$1.dll.a" ] - then - echo "$msystem_lib$1.dll.a" - else - # Return dynamic reference to the library. - echo "-l$1" - return 1 - fi -} - -add_lib() { - # Always make sure this lib is listed after the last lib that depends on it. - old_libs=$(cat "$libs_file") - rm -f "$libs_file" - for lib in $old_libs - do - [ "$lib" != "$*" ] && echo "$lib" >> "$libs_file" - done - echo "$*" >> "$libs_file" - - # Add libstdc++ in the end if required. - if echo "$*" | grep -q "/" - then - grep -Eq -- "__cxa_|__gxx_" "$1" 2> /dev/null && add_lib -static -lstdc++ - fi - - # Add libiconv for libintl. - if echo "$*" | grep -q "libintl" - then - add_lib $(find_lib iconv) - fi - - # Add libuuid for glib. - if echo "$*" | grep -q "libglib" - then - add_lib $(find_lib uuid) - fi -} - -run_pkgconfig() { - local cache_file="static2dll.$1.cache" - if [ -e "$cache_file" ] - then - cat "$cache_file" - else - pkg-config --static --libs "$1" 2> /dev/null | tee "$cache_file" - fi -} - -parse_pkgconfig() { - # Parse arguments. - local layers=$1 - shift - local input_lib_name=$1 - shift - - # Don't process the same file again. - grep -q '^'$input_lib_name'$' "$seen_file" && return - echo $input_lib_name >> "$seen_file" - - echo "$layers" parse_pkgconfig $input_lib_name - - # Parse pkg-config arguments. - for arg in $* - do - local arg_base="$(echo $arg | cut -c1-2)" - if [ "x$arg_base" = "x-l" ] - then - # Don't process the same lib again. - local lib_name="$(echo $arg | cut -c3-)" - [ "x$lib_name" == "x$input_lib_name" ] && continue - - # Add lib path. - add_lib "$(find_lib $lib_name)" - - # Get this lib's dependencies through pkg-config. - local pkgconfig="$(run_pkgconfig "$lib_name")" - [ $? -eq 0 ] && parse_pkgconfig "$layers"'>' "$lib_name" $pkgconfig || echo $lib_name >> "$seen_file" - elif [ "x$(echo $arg_base | cut -c1)" = "x-" ] - then - # Ignore other arguments. - continue - else - # Add lib path. - add_lib "$arg" - fi - done -} - -# Parse arguments. -case $1 in - -p) # -p pkg_config_name static_lib_path out_dll - shift - base_pkgconfig=$(run_pkgconfig "$1") - base_path="$2" - base_name="$1" - ;; - - *) # pc_path static_lib_path out_dll - base_pkgconfig="$(grep ^Libs.private: $1 | cut -d: -f2-)" - base_path="$2" - base_name="$2" - ;; -esac - -# Check arguments. -if [ -z "$base_pkgconfig" -o -z "$base_path" -o -z "$base_name" ] -then - echo Usage: - echo static2dll.sh -p {pkgconfig_package_name} {static_lib_path} {out_dll_name} - echo static2dll.sh {pc_file_path} {static_lib_path} {out_dll_name} - exit 1 -fi - -# Produce .def file. -echo LIBRARY $(basename "$3") > "$def_file" -echo EXPORTS >> "$def_file" -nm "$base_path" | grep " [TC] " | sed "/ _/s// /" | awk '{ print $3 }' >> "$def_file" - -# Parse dependencies recursively. -rm -f "$seen_file" "$libs_file" "$libs_file.tmp" -touch "$seen_file" "$libs_file" -parse_pkgconfig '>' $base_name $base_pkgconfig - -# Produce final DLL. -dllwrap --def "$def_file" -o "$3" -Wl,--allow-multiple-definition "$base_path" $(cat "$libs_file") -status=$? -[ $status -eq 0 ] && rm -f "$def_file" "$seen_file" "$libs_file" "static2dll.*.cache" - -# Update final DLL timestamp. -touch -r "$base_path" "$3" - -exit $status diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index c774258e2..4f4158476 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -20,4 +20,11 @@ if(APPLE) if (NOT GHOSTSCRIPT_LIB) message(WARNING "Could not find ghostscript. The library will not be bundled and any related features will not work.") endif() -endif () \ No newline at end of file +endif() + +find_package(PkgConfig REQUIRED) +pkg_check_modules(FREETYPE REQUIRED IMPORTED_TARGET freetype2) +target_link_libraries(86Box PkgConfig::FREETYPE) +if(STATIC_BUILD) + target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES}) +endif() diff --git a/src/printer/prt_escp.c b/src/printer/prt_escp.c index 5fc3646bc..b4099bc63 100644 --- a/src/printer/prt_escp.c +++ b/src/printer/prt_escp.c @@ -65,7 +65,6 @@ #include <86box/pit.h> #include <86box/path.h> #include <86box/plat.h> -#include <86box/plat_dynld.h> #include <86box/ui.h> #include <86box/lpt.h> #include <86box/video.h> @@ -85,45 +84,8 @@ #define PAGE_CPI 10.0 /* standard 10 cpi */ #define PAGE_LPI 6.0 /* standard 6 lpi */ -#ifdef _WIN32 -# define PATH_FREETYPE_DLL "freetype.dll" -#elif defined __APPLE__ -# define PATH_FREETYPE_DLL "libfreetype.6.dylib" -#else -# define PATH_FREETYPE_DLL "libfreetype.so.6" -#endif - /* FreeType library handles - global so they can be shared. */ -FT_Library ft_lib = NULL; -void *ft_handle = NULL; - -static int (*ft_Init_FreeType)(FT_Library *alibrary); -static int (*ft_Done_Face)(FT_Face face); -static int (*ft_New_Face)(FT_Library library, const char *filepathname, - FT_Long face_index, FT_Face *aface); -static int (*ft_Set_Char_Size)(FT_Face face, FT_F26Dot6 char_width, - FT_F26Dot6 char_height, - FT_UInt horz_resolution, - FT_UInt vert_resolution); -static int (*ft_Set_Transform)(FT_Face face, FT_Matrix *matrix, - FT_Vector *delta); -static int (*ft_Get_Char_Index)(FT_Face face, FT_ULong charcode); -static int (*ft_Load_Glyph)(FT_Face face, FT_UInt glyph_index, - FT_Int32 load_flags); -static int (*ft_Render_Glyph)(FT_GlyphSlot slot, - FT_Render_Mode render_mode); - -static dllimp_t ft_imports[] = { - {"FT_Init_FreeType", &ft_Init_FreeType }, - { "FT_New_Face", &ft_New_Face }, - { "FT_Done_Face", &ft_Done_Face }, - { "FT_Set_Char_Size", &ft_Set_Char_Size }, - { "FT_Set_Transform", &ft_Set_Transform }, - { "FT_Get_Char_Index", &ft_Get_Char_Index}, - { "FT_Load_Glyph", &ft_Load_Glyph }, - { "FT_Render_Glyph", &ft_Render_Glyph }, - { NULL, NULL } -}; +FT_Library ft_lib = NULL; /* The fonts. */ #define FONT_DEFAULT 0 @@ -544,7 +506,7 @@ update_font(escp_t *dev) /* Release current font if we have one. */ if (dev->fontface) - ft_Done_Face(dev->fontface); + FT_Done_Face(dev->fontface); if (dev->print_quality == QUALITY_DRAFT) fn = FONT_FILE_DOTMATRIX; @@ -580,7 +542,7 @@ update_font(escp_t *dev) escp_log("Temp file=%s\n", path); /* Load the new font. */ - if (ft_New_Face(ft_lib, path, 0, &dev->fontface)) { + if (FT_New_Face(ft_lib, path, 0, &dev->fontface)) { escp_log("ESC/P: unable to load font '%s'\n", path); dev->fontface = NULL; } @@ -626,7 +588,7 @@ update_font(escp_t *dev) dev->actual_cpi /= 2.0 / 3.0; } - ft_Set_Char_Size(dev->fontface, + FT_Set_Char_Size(dev->fontface, (uint16_t) (hpoints * 64), (uint16_t) (vpoints * 64), dev->dpi, dev->dpi); @@ -636,7 +598,7 @@ update_font(escp_t *dev) matrix.xy = (FT_Fixed) (0.20 * 0x10000L); matrix.yx = 0; matrix.yy = 0x10000L; - ft_Set_Transform(dev->fontface, &matrix, 0); + FT_Set_Transform(dev->fontface, &matrix, 0); } } @@ -1611,9 +1573,9 @@ handle_char(escp_t *dev, uint8_t ch) /* ok, so we need to print the character now */ if (ft_lib) { - char_index = ft_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]); - ft_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT); - ft_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); + char_index = FT_Get_Char_Index(dev->fontface, dev->curr_cpmap[ch]); + FT_Load_Glyph(dev->fontface, char_index, FT_LOAD_DEFAULT); + FT_Render_Glyph(dev->fontface->glyph, FT_RENDER_MODE_NORMAL); } pen_x = PIXX + dev->fontface->glyph->bitmap_left; @@ -1986,23 +1948,12 @@ read_status(void *priv) static void * escp_init(void *lpt) { - const char *fn = PATH_FREETYPE_DLL; - escp_t *dev; - - /* Dynamically load FreeType. */ - if (ft_handle == NULL) { - ft_handle = dynld_module(fn, ft_imports); - if (ft_handle == NULL) { - ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); - return (NULL); - } - } + escp_t *dev; /* Initialize FreeType. */ if (ft_lib == NULL) { - if (ft_Init_FreeType(&ft_lib)) { + if (FT_Init_FreeType(&ft_lib)) { ui_msgbox_header(MBX_ERROR, (wchar_t *) IDS_2111, (wchar_t *) IDS_2132); - dynld_close(ft_lib); ft_lib = NULL; return (NULL); } From d066893330966929b8a05ed3abddb1ee81d26132 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 04:09:45 +0200 Subject: [PATCH 30/44] A forgotten file. --- src/cpu/x86_ops_mmx.c | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/cpu/x86_ops_mmx.c diff --git a/src/cpu/x86_ops_mmx.c b/src/cpu/x86_ops_mmx.c new file mode 100644 index 000000000..1afc4fba2 --- /dev/null +++ b/src/cpu/x86_ops_mmx.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include +#include +#include +#ifndef INFINITY +# define INFINITY (__builtin_inff()) +#endif +#define HAVE_STDARG_H +#include <86box/86box.h> +#include "cpu.h" +#include <86box/timer.h> +#include "x86.h" +#include "x87.h" +#include <86box/nmi.h> +#include <86box/mem.h> +#include <86box/smram.h> +#include <86box/pic.h> +#include <86box/pit.h> +#include <86box/fdd.h> +#include <86box/fdc.h> +#include <86box/keyboard.h> +#include <86box/timer.h> +#include "386_common.h" +#include "x86_flags.h" +#include "x86seg.h" + +MMX_REG *MMP[8]; +uint16_t *MMEP[8]; + +static uint16_t MME[8]; + +#define MMX_GETREGP(r) fpu_softfloat ? ((MMX_REG *) &fpu_state.st_space[r].fraction) : &(cpu_state.MM[r]) +void +mmx_init(void) +{ + memset(MME, 0xff, sizeof(MME)); + + for (uint8_t i = 0; i < 8; i++) { + if (fpu_softfloat) { + MMP[i] = (MMX_REG *) &fpu_state.st_space[i].fraction; + MMEP[i] = (uint16_t *) &fpu_state.st_space[i].exp; + } else { + MMP[i] = &(cpu_state.MM[i]); + MMEP[i] = &(MME[i]); + } + } +} From 71119aef224408047b96ccbb9635956028c15377 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 04:21:21 +0200 Subject: [PATCH 31/44] Makefile.mingw now has all the required dependencies for static libfreetype. --- src/win/Makefile.mingw | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/win/Makefile.mingw b/src/win/Makefile.mingw index 55306e8d8..806f2b45b 100644 --- a/src/win/Makefile.mingw +++ b/src/win/Makefile.mingw @@ -789,15 +789,24 @@ else MWIN := -mwindows endif -LIBS := -lfluidsynth -lslirp -lgomp -lsndfile -lflac -lmp3lame -lmpg123 -lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline -ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv +LIBS := -lfreetype -lfluidsynth -lslirp -lbz2 -lharfbuzz -lgraphite2 -lbrotlidec \ + -lbrotlicommon -lusp10 -lrpcrt4 -lgomp -lsndfile -lflac -lmp3lame -lmpg123 \ + -lopus -lvorbis -lvorbisenc -logg -ldsound -lshlwapi -lksuser -lreadline \ + -ltermcap -lportaudio -lgmodule-2.0 -lglib-2.0 -lintl -liconv ifeq ($(OPENAL), y) - LIBS += $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS += $(MWIN) -lopenal -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ + -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ + -luuid -lws2_32 else ifeq ($(FAUDIO), y) - LIBS += $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS += $(MWIN) -lfaudio -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 \ + -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion \ + -luuid -lws2_32 else - LIBS += $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid -lws2_32 + LIBS += $(MWIN) -lcomctl32 -lSDL2 -limagehlp -ldinput8 -ldxguid -ldxerr8 -luser32 \ + -lgdi32 -lwinmm -limm32 -lole32 -loleaut32 -lshell32 -lversion -luuid \ + -lws2_32 endif endif From d3086d6c5eb12446f549ee9f406c76c77eb4b8b0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sun, 16 Jul 2023 04:29:13 +0200 Subject: [PATCH 32/44] Fixed a mistake in src/cpu/808x/CMakeLists.txt. --- src/cpu/808x/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpu/808x/CMakeLists.txt b/src/cpu/808x/CMakeLists.txt index 72aced128..d29bdf4e0 100644 --- a/src/cpu/808x/CMakeLists.txt +++ b/src/cpu/808x/CMakeLists.txt @@ -13,4 +13,4 @@ # Copyright 2020-2021 David Hrdlička. # -add_library(808x.c OBJECT queue.c) +add_library(808x OBJECT queue.c) From 5ba2ad529d5dc12aaa1236c9947396e28af7158a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Sun, 16 Jul 2023 00:01:59 -0300 Subject: [PATCH 33/44] printer: Fix Windows build --- src/printer/CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/printer/CMakeLists.txt b/src/printer/CMakeLists.txt index 4f4158476..dea0c7fbe 100644 --- a/src/printer/CMakeLists.txt +++ b/src/printer/CMakeLists.txt @@ -26,5 +26,9 @@ find_package(PkgConfig REQUIRED) pkg_check_modules(FREETYPE REQUIRED IMPORTED_TARGET freetype2) target_link_libraries(86Box PkgConfig::FREETYPE) if(STATIC_BUILD) + if(QT) + # Qt provides its own version of harfbuzz which leads to duplicated symbols. + target_link_options(86Box PRIVATE "LINKER:--allow-multiple-definition") + endif() target_link_libraries(86Box -static ${FREETYPE_STATIC_LIBRARIES}) endif() From 7d41b46c5e600773cb5785a0af74224b42556a35 Mon Sep 17 00:00:00 2001 From: richardg867 Date: Tue, 18 Jul 2023 11:58:09 -0300 Subject: [PATCH 34/44] machine: Declare onboard slots on ASUS P2B-LS, fixes Adaptec SCSI hang on some BIOS versions --- src/machine/m_at_slot1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/machine/m_at_slot1.c b/src/machine/m_at_slot1.c index 3cedb669a..f13fe72cd 100644 --- a/src/machine/m_at_slot1.c +++ b/src/machine/m_at_slot1.c @@ -200,8 +200,8 @@ machine_at_p2bls_init(const machine_t *model) pci_init(PCI_CONFIG_TYPE_1); pci_register_slot(0x00, PCI_CARD_NORTHBRIDGE, 0, 0, 0, 0); pci_register_slot(0x04, PCI_CARD_SOUTHBRIDGE, 1, 2, 3, 4); - pci_register_slot(0x06, PCI_CARD_NORMAL, 4, 1, 2, 3); /* SCSI */ - pci_register_slot(0x07, PCI_CARD_NORMAL, 3, 4, 1, 2); /* LAN */ + pci_register_slot(0x06, PCI_CARD_SCSI, 4, 1, 2, 3); + pci_register_slot(0x07, PCI_CARD_NETWORK, 3, 4, 1, 2); pci_register_slot(0x0B, PCI_CARD_NORMAL, 2, 3, 4, 1); pci_register_slot(0x0C, PCI_CARD_NORMAL, 1, 2, 3, 4); pci_register_slot(0x09, PCI_CARD_NORMAL, 4, 1, 2, 3); From 7ee94927639dfe46a61cca96965c3b1e1e2af327 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 20 Jul 2023 20:28:19 -0300 Subject: [PATCH 35/44] AudioPCI: Fix nonsensical read masking on interrupt status register --- src/sound/snd_audiopci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 6b9d8d792..533cd5430 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -621,11 +621,11 @@ es1371_inb(uint16_t port, void *p) audiopci_log("[R] STATUS 8-15 = %02X\n", ret); break; case 0x06: - ret = (dev->int_status >> 16) & 0x0f; + ret = (dev->int_status >> 16) & 0xff; audiopci_log("[R] STATUS 16-23 = %02X\n", ret); break; case 0x07: - ret = ((dev->int_status >> 24) & 0x03) | 0xfc; + ret = (dev->int_status >> 24) & 0xff; audiopci_log("[R] STATUS 24-31 = %02X\n", ret); break; From c5b50fabf04d5290cbb311fa4dd0d94800a06e11 Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Thu, 20 Jul 2023 21:59:26 -0300 Subject: [PATCH 36/44] AudioPCI: Fix GPIO quirk for returning back to ES1371 revision ID --- src/sound/snd_audiopci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index 533cd5430..b46a40dda 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -311,7 +311,13 @@ es1371_reset(void *p) /* Interrupt/Chip Select Control Register, Address 00H Addressable as longword only */ - dev->int_status = 0x7ffffec0; + /* Bit 13 is supposed to be always 1 on ES1371, and one of the GPIO interrupt + flags on ES1373. The 5.12.01 WDM driver only initializes its GPIO interrupt + handler on chip revisions which support this feature (1371 >= 0x04 and 5880 + all), but calls it anyway during interrupt servicing regardless of revision, + crashing on ES1371 as soon as an interrupt arrives while that bit is set. + Pending hardware research because actual early ES1371 cards are rare. */ + dev->int_status = 0x7fffdec0; /* UART Status Register, Address 09H Addressable as byte only */ @@ -1551,7 +1557,7 @@ es1371_pci_read(int func, int addr, void *p) return 0x00; case 0x08: - return 0x08; /* Revision ID - 0x02 (datasheet, VMware) has issues with the 2001 Creative WDM driver */ + return 0x02; /* Revision ID - 0x02 is supposed to be early Ensoniq-branded ES1371 but unconfirmed */ case 0x09: return 0x00; /* Multimedia audio device */ case 0x0a: From 08da777e844e61e012096e72dfa158a7fd36935c Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 21 Jul 2023 13:23:59 +0200 Subject: [PATCH 37/44] The WSS get buffer function now correctly ignores OPL if OPL is disabled. --- src/sound/snd_wss.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index a3a748374..d82e5e6f9 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -79,15 +79,20 @@ static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; + int32_t *opl_buf + + if (wss->opl_enabled) + opl_buf = wss->opl.update(wss->opl.priv); - int32_t *opl_buf = wss->opl.update(wss->opl.priv); ad1848_update(&wss->ad1848); for (int c = 0; c < len * 2; c++) { - buffer[c] += opl_buf[c]; + if (wss->opl_enabled) + buffer[c] += opl_buf[c]; buffer[c] += wss->ad1848.buffer[c] / 2; } - wss->opl.reset_buffer(wss->opl.priv); + if (wss->opl_enabled) + wss->opl.reset_buffer(wss->opl.priv); wss->ad1848.pos = 0; } From 223ec091686ba4c16a2c6ea8a9e4ca288187fff9 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 21 Jul 2023 14:56:35 +0200 Subject: [PATCH 38/44] Added a forgotten semicolon. --- src/sound/snd_wss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index d82e5e6f9..576a4f182 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -79,7 +79,7 @@ static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; - int32_t *opl_buf + int32_t *opl_buf; if (wss->opl_enabled) opl_buf = wss->opl.update(wss->opl.priv); From 54c52fb55cf030a06fa5f5851e64b76669d72048 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 21 Jul 2023 13:46:08 -0400 Subject: [PATCH 39/44] Fix several instances of uninitialized variables. --- src/cpu/386_ops.h | 5 +++-- src/cpu/x86_ops_misc.h | 27 ++++++++++++++++++--------- src/floppy/fdd_img.c | 4 ++-- src/scsi/scsi_buslogic.c | 12 ++++++------ src/sio/sio_82091aa.c | 2 +- src/sound/snd_ad1848.c | 4 ++-- src/sound/snd_sb.c | 2 +- src/video/vid_ati_mach64.c | 2 +- src/video/vid_et4000w32.c | 2 +- src/video/vid_xga.c | 2 +- 10 files changed, 36 insertions(+), 26 deletions(-) diff --git a/src/cpu/386_ops.h b/src/cpu/386_ops.h index e345ee8d8..91449efeb 100644 --- a/src/cpu/386_ops.h +++ b/src/cpu/386_ops.h @@ -223,10 +223,11 @@ extern void x386_dynarec_log(const char *fmt, ...); static int opVPCEXT(uint32_t fetchdat) { - uint8_t b1, b2; + uint8_t b1; + uint8_t b2; uint16_t cent; time_t now; - struct tm *tm; + struct tm *tm = NULL; if (!is_vpc) /* only emulate this on Virtual PC machines */ return ILLEGAL(fetchdat); diff --git a/src/cpu/x86_ops_misc.h b/src/cpu/x86_ops_misc.h index 940e2ea8e..60ed873e4 100644 --- a/src/cpu/x86_ops_misc.h +++ b/src/cpu/x86_ops_misc.h @@ -51,8 +51,10 @@ opSETALC(uint32_t fetchdat) static int opF6_a16(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; + int tempws = 0; + int tempws2 = 0; + uint16_t tempw = 0; + uint16_t src16; uint8_t src, dst; int8_t temps; @@ -167,8 +169,10 @@ opF6_a16(uint32_t fetchdat) static int opF6_a32(uint32_t fetchdat) { - int tempws, tempws2 = 0; - uint16_t tempw, src16; + int tempws = 0; + int tempws2 = 0; + uint16_t tempw = 0; + uint16_t src16; uint8_t src, dst; int8_t temps; @@ -282,10 +286,13 @@ opF6_a32(uint32_t fetchdat) static int opF7_w_a16(uint32_t fetchdat) { - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 0; + uint32_t templ; + uint32_t templ2 = 0; + int tempws; + int tempws2 = 0; int16_t temps16; - uint16_t src, dst; + uint16_t src; + uint16_t dst; fetch_ea_16(fetchdat); if (cpu_mod != 3) @@ -392,8 +399,10 @@ opF7_w_a16(uint32_t fetchdat) static int opF7_w_a32(uint32_t fetchdat) { - uint32_t templ, templ2 = 0; - int tempws, tempws2 = 1; + uint32_t templ; + uint32_t templ2 = 0; + int tempws; + int tempws2 = 1; int16_t temps16; uint16_t src, dst; diff --git a/src/floppy/fdd_img.c b/src/floppy/fdd_img.c index 589f04292..9d5232cdf 100644 --- a/src/floppy/fdd_img.c +++ b/src/floppy/fdd_img.c @@ -668,8 +668,8 @@ img_load(int drive, char *fn) uint16_t track_bytes = 0; uint8_t *literal; img_t *dev; - int temp_rate; - int guess = 0; + int temp_rate = 0; + int guess = 0; int size; ext = path_get_extension(fn); diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index efc2a62ae..5616042ec 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -1513,14 +1513,14 @@ buslogic_init(const device_t *info) { x54x_t *dev; char *bios_rom_name; - uint16_t bios_rom_size; - uint16_t bios_rom_mask; + uint16_t bios_rom_size = 0; + uint16_t bios_rom_mask = 0; uint8_t has_autoscsi_rom; - char *autoscsi_rom_name; - uint16_t autoscsi_rom_size; + char *autoscsi_rom_name = NULL; + uint16_t autoscsi_rom_size = 0; uint8_t has_scam_rom; - char *scam_rom_name; - uint16_t scam_rom_size; + char *scam_rom_name = NULL; + uint16_t scam_rom_size = 0; FILE *f; buslogic_data_t *bl; uint32_t bios_rom_addr; diff --git a/src/sio/sio_82091aa.c b/src/sio/sio_82091aa.c index 800bf1b1a..346d2d435 100644 --- a/src/sio/sio_82091aa.c +++ b/src/sio/sio_82091aa.c @@ -142,7 +142,7 @@ i82091aa_write(uint16_t port, uint8_t val, void *priv) { i82091aa_t *dev = (i82091aa_t *) priv; uint8_t index; - uint8_t valxor; + uint8_t valxor = 0; uint8_t uart = (dev->cur_reg >> 4) - 0x03; uint8_t *reg = &(dev->regs[dev->cur_reg]); diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index 284836704..a1114c4be 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -65,8 +65,8 @@ ad1848_updatevolmask(ad1848_t *ad1848) static void ad1848_updatefreq(ad1848_t *ad1848) { - double freq; - uint8_t set = 0; + double freq = 0; + uint8_t set = 0; if (ad1848->type >= AD1848_TYPE_CS4235) { if (ad1848->xregs[11] & 0x20) { diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 84f31f500..9c25be7a1 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -348,7 +348,7 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *p) sb_t *sb = (sb_t *) p; sb_ct1745_mixer_t *mixer = &sb->mixer_sb16; int dsp_rec_pos = sb->dsp.record_pos_write; - int c_emu8k; + int c_emu8k = 0; int c_record; int32_t in_l; int32_t in_r; diff --git a/src/video/vid_ati_mach64.c b/src/video/vid_ati_mach64.c index 8c32929ce..39371e882 100644 --- a/src/video/vid_ati_mach64.c +++ b/src/video/vid_ati_mach64.c @@ -3223,7 +3223,7 @@ uint8_t mach64_ext_inb(uint16_t port, void *p) { mach64_t *mach64 = (mach64_t *) p; - uint8_t ret; + uint8_t ret = 0xff; switch (port) { case 0x02ec: diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 4016067ab..ee5a2117b 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -2084,7 +2084,7 @@ et4000w32_blit(int count, int cpu_input, uint32_t src_dat, uint32_t mix_dat, et4 uint8_t source; uint8_t dest; uint8_t rop; - uint8_t out; + uint8_t out = 0; int mixmap; if (!(et4000->acl.status & ACL_XYST) && !et4000->acl.mmu_start) { diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index e4f91bb00..db1ae0afb 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -504,7 +504,7 @@ xga_ext_inb(uint16_t addr, void *p) { svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; - uint8_t ret; + uint8_t ret = 0xff; uint8_t index; switch (addr & 0x0f) { From e90c17c4c992778e6ab9c7d8e13a0eeab4e0d8be Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 21 Jul 2023 20:15:30 +0200 Subject: [PATCH 40/44] Corrected the ALi M148x IRQ mappings. --- src/chipset/ali1489.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/ali1489.c b/src/chipset/ali1489.c index c4488ffd6..7d911e620 100644 --- a/src/chipset/ali1489.c +++ b/src/chipset/ali1489.c @@ -213,7 +213,7 @@ ali1489_write(uint16_t addr, uint8_t val, void *priv) ali1489_t *dev = (ali1489_t *) priv; uint8_t old; uint8_t irq; - const uint8_t irq_array[16] = { 0, 3, 4, 7, 0, 0, 0, 0, 9, 10, 5, 6, 11, 12, 14, 15 }; + const uint8_t irq_array[16] = { 0, 9, 3, 10, 4, 5, 7, 6, 0, 11, 0, 12, 0, 14, 0, 15 }; switch (addr) { case 0x22: From 80bc465bf373fa4490a0cb54bee104ffe98f405c Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 21 Jul 2023 16:02:01 -0300 Subject: [PATCH 41/44] WSS: Fix warning --- src/sound/snd_wss.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound/snd_wss.c b/src/sound/snd_wss.c index 576a4f182..274a0579e 100644 --- a/src/sound/snd_wss.c +++ b/src/sound/snd_wss.c @@ -79,14 +79,14 @@ static void wss_get_buffer(int32_t *buffer, int len, void *priv) { wss_t *wss = (wss_t *) priv; - int32_t *opl_buf; + int32_t *opl_buf = NULL; if (wss->opl_enabled) opl_buf = wss->opl.update(wss->opl.priv); ad1848_update(&wss->ad1848); for (int c = 0; c < len * 2; c++) { - if (wss->opl_enabled) + if (opl_buf) buffer[c] += opl_buf[c]; buffer[c] += wss->ad1848.buffer[c] / 2; } From 6732c44c8938c2151aff832a1ba4e6e5d783e7bf Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 21 Jul 2023 17:32:22 -0400 Subject: [PATCH 42/44] Fix reported issue --- src/sound/snd_ad1848.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sound/snd_ad1848.c b/src/sound/snd_ad1848.c index a1114c4be..0feb3ab74 100644 --- a/src/sound/snd_ad1848.c +++ b/src/sound/snd_ad1848.c @@ -65,7 +65,7 @@ ad1848_updatevolmask(ad1848_t *ad1848) static void ad1848_updatefreq(ad1848_t *ad1848) { - double freq = 0; + double freq = 0.0; uint8_t set = 0; if (ad1848->type >= AD1848_TYPE_CS4235) { From 78c33471b5ab70a94469ab844001f787e3d5890a Mon Sep 17 00:00:00 2001 From: RichardG867 Date: Fri, 21 Jul 2023 21:40:29 -0300 Subject: [PATCH 43/44] AudioPCI: Remove 4-channel codec from selection (only available as CT5880) --- src/sound/snd_audiopci.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/sound/snd_audiopci.c b/src/sound/snd_audiopci.c index b46a40dda..53de22ce7 100644 --- a/src/sound/snd_audiopci.c +++ b/src/sound/snd_audiopci.c @@ -2075,10 +2075,6 @@ static const device_config_t es1371_config[] = { .description = "Crystal CS4297A", .value = AC97_CODEC_CS4297A }, - { - .description = "SigmaTel STAC9708", - .value = AC97_CODEC_STAC9708 - }, { .description = "SigmaTel STAC9721", .value = AC97_CODEC_STAC9721 From f4423bcf175dc0a6ac00122f6596e3e740a771c8 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 22 Jul 2023 04:58:47 +0200 Subject: [PATCH 44/44] Fixed a warning in video/vid_8514a.c. --- src/video/vid_8514a.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/video/vid_8514a.c b/src/video/vid_8514a.c index 115105d7a..ebf2d0b3f 100644 --- a/src/video/vid_8514a.c +++ b/src/video/vid_8514a.c @@ -3514,7 +3514,7 @@ bitblt: } } else { if ((svga->bpp == 24) && dev->local && (dev->accel.cmd == 0xc2b5)) { - int64_t x, cx, dx; + int64_t cx, dx; cx = (int64_t)dev->accel.cx; dx = (int64_t)dev->accel.dx;