From 9737a2c8004470d918ac2541b7ec3f5e521489f4 Mon Sep 17 00:00:00 2001 From: OBattler Date: Tue, 31 Oct 2023 21:47:45 +0100 Subject: [PATCH 01/19] Added sanity checks to all RAM accesses in the GUS code, fixes #3790. --- src/sound/snd_gus.c | 106 ++++++++++++++++++++++++++++---------------- 1 file changed, 69 insertions(+), 37 deletions(-) diff --git a/src/sound/snd_gus.c b/src/sound/snd_gus.c index a68435815..d0af5c564 100644 --- a/src/sound/snd_gus.c +++ b/src/sound/snd_gus.c @@ -427,7 +427,8 @@ writegus(uint16_t addr, uint8_t val, void *priv) if (gus->voices < 14) gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / 44100.0)); else - gus->samp_latch = (uint64_t) (TIMER_USEC * (1000000.0 / gusfreqs[gus->voices - 14])); + gus->samp_latch = (uint64_t) (TIMER_USEC * + (1000000.0 / gusfreqs[gus->voices - 14])); break; case 0x41: /*DMA*/ @@ -437,15 +438,28 @@ writegus(uint16_t addr, uint8_t val, void *priv) while (c < 65536) { int dma_result; if (val & 0x04) { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); - d = gus->ram[gus_addr] | (gus->ram[gus_addr + 1] << 8); + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | + ((gus->dmaaddr & 0x1ffff) << 1); + + if (gus_addr < gus->gus_end_ram) + d = gus->ram[gus_addr]; + else + d = 0x00; + + if ((gus_addr + 1) < gus->gus_end_ram) + d |= (gus->ram[gus_addr + 1] << 8); + if (val & 0x80) d ^= 0x8080; dma_result = dma_channel_write(gus->dma, d); if (dma_result == DMA_NODATA) break; } else { - d = gus->ram[gus->dmaaddr]; + if (gus->dmaaddr < gus->gus_end_ram) + d = gus->ram[gus->dmaaddr]; + else + d = 0x00; + if (val & 0x80) d ^= 0x80; dma_result = dma_channel_write(gus->dma, d); @@ -453,7 +467,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) break; } gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; + gus->dmaaddr &= 0xfffff; c++; if (dma_result & DMA_OVER) break; @@ -467,18 +481,25 @@ writegus(uint16_t addr, uint8_t val, void *priv) if (d == DMA_NODATA) break; if (val & 0x04) { - uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | ((gus->dmaaddr & 0x1ffff) << 1); + uint32_t gus_addr = (gus->dmaaddr & 0xc0000) | + ((gus->dmaaddr & 0x1ffff) << 1); if (val & 0x80) d ^= 0x8080; - gus->ram[gus_addr] = d & 0xff; - gus->ram[gus_addr + 1] = (d >> 8) & 0xff; + + if (gus_addr < gus->gus_end_ram) + gus->ram[gus_addr] = d & 0xff; + + if ((gus_addr + 1) < gus->gus_end_ram) + gus->ram[gus_addr + 1] = (d >> 8) & 0xff; } else { if (val & 0x80) d ^= 0x80; - gus->ram[gus->dmaaddr] = d; + + if (gus->dmaaddr < gus->gus_end_ram) + gus->ram[gus->dmaaddr] = d; } gus->dmaaddr++; - gus->dmaaddr &= 0xFFFFF; + gus->dmaaddr &= 0xfffff; c++; if (d & DMA_OVER) break; @@ -494,28 +515,20 @@ writegus(uint16_t addr, uint8_t val, void *priv) break; case 0x43: /*Address low*/ - gus->addr = (gus->addr & 0xF00FF) | (val << 8); + gus->addr = (gus->addr & 0xf00ff) | (val << 8); break; case 0x44: /*Address high*/ - gus->addr = (gus->addr & 0xFFFF) | ((val << 16) & 0xF0000); + gus->addr = (gus->addr & 0x0ffff) | ((val << 16) & 0xf0000); break; case 0x45: /*Timer control*/ if (!(val & 4)) gus->irqstatus &= ~4; if (!(val & 8)) gus->irqstatus &= ~8; - if (!(val & 0x20)) { + if (!(val & 0x20)) gus->ad_status &= ~0x18; -#ifdef OLD_NMI_BEHAVIOR - nmi = 0; -#endif - } - if (!(val & 0x02)) { + if (!(val & 0x02)) gus->ad_status &= ~0x01; -#ifdef OLD_NMI_BEHAVIOR - nmi = 0; -#endif - } gus->tctrl = val; gus->sb_ctrl = val; gus_update_int_status(gus); @@ -540,7 +553,7 @@ writegus(uint16_t addr, uint8_t val, void *priv) case 0x307: /*DRAM access*/ if (gus->addr < gus->gus_end_ram) gus->ram[gus->addr] = val; - gus->addr &= 0xFFFFF; + gus->addr &= 0xfffff; break; case 0x208: case 0x388: @@ -874,8 +887,7 @@ readgus(uint16_t addr, void *priv) break; case 0x307: /*DRAM access*/ - val = gus->ram[gus->addr]; - gus->addr &= 0xFFFFF; + gus->addr &= 0xfffff; if (gus->addr < gus->gus_end_ram) val = gus->ram[gus->addr]; else @@ -1034,21 +1046,41 @@ gus_poll_wave(void *priv) if (gus->ctrl[d] & 4) { addr = gus->cur[d] >> 9; addr = (addr & 0xC0000) | ((addr << 1) & 0x3FFFE); - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80) * (511 - (gus->cur[d] & 511)); - vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xFFFFF] ^ 0x80) - 0x80) * (gus->cur[d] & 511); + if (!(gus->freq[d] >> 10)) { + /* Interpolate */ + if (((addr + 1) & 0xfffff) < gus->gus_end_ram) + vl = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80) * + (511 - (gus->cur[d] & 511)); + else + vl = 0; + + if (((addr + 3) & 0xfffff) < gus->gus_end_ram) + vl += (int16_t) (int8_t) ((gus->ram[(addr + 3) & 0xfffff] ^ 0x80) - 0x80) * + (gus->cur[d] & 511); + v = vl >> 9; - } else - v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xFFFFF] ^ 0x80) - 0x80); + } else if (((addr + 1) & 0xfffff) < gus->gus_end_ram) + v = (int16_t) (int8_t) ((gus->ram[(addr + 1) & 0xfffff] ^ 0x80) - 0x80); + else + v = 0x0000; } else { - if (!(gus->freq[d] >> 10)) /*Interpolate*/ - { - vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80)) * (511 - (gus->cur[d] & 511)); - vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xFFFFF] ^ 0x80) - 0x80)) * (gus->cur[d] & 511); + if (!(gus->freq[d] >> 10)) { + /* Interpolate */ + if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram) + vl = ((int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80)) * + (511 - (gus->cur[d] & 511)); + else + vl = 0; + + if ((((gus->cur[d] >> 9) + 1) & 0xfffff) < gus->gus_end_ram) + vl += ((int8_t) ((gus->ram[((gus->cur[d] >> 9) + 1) & 0xfffff] ^ 0x80) - 0x80)) * + (gus->cur[d] & 511); + v = vl >> 9; - } else - v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xFFFFF] ^ 0x80) - 0x80); + } else if (((gus->cur[d] >> 9) & 0xfffff) < gus->gus_end_ram) + v = (int16_t) (int8_t) ((gus->ram[(gus->cur[d] >> 9) & 0xfffff] ^ 0x80) - 0x80); + else + v = 0x0000; } if ((gus->rcur[d] >> 14) > 4095) From 53512a251055b7f907a1843a6a5742a432455b48 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Wed, 1 Nov 2023 21:59:49 +0100 Subject: [PATCH 02/19] More S3 blitting fixes: Toggling the RSF bit is now applied to reads too. Fixes wrong colors on Solaris using true color mode and possibly other stuff too. --- src/video/vid_s3.c | 513 ++++++++++++++++++++++++++++----------------- 1 file changed, 316 insertions(+), 197 deletions(-) diff --git a/src/video/vid_s3.c b/src/video/vid_s3.c index 9e626ccb2..f35f729da 100644 --- a/src/video/vid_s3.c +++ b/src/video/vid_s3.c @@ -852,7 +852,6 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) s3->accel.cmd = (s3->accel.cmd & 0xff) | (val << 8); s3->accel.ssv_state = 0; s3_accel_start(-1, 0, 0xffffffff, 0, s3); - s3->accel.multifunc[0xe] &= ~0x10; /*hack*/ break; case 0x994a: @@ -887,202 +886,167 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) case 0xa148: case 0xa2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; break; case 0xa149: case 0xa2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xa14a: case 0xa2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffffff00) | val; + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xff00ffff) | (val << 16); break; case 0xa14b: case 0xa2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0xff000000) | (val << 24); - else - s3->accel.bkgd_color = (s3->accel.bkgd_color & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0xffff00ff) | (val << 8); + else + s3->accel.bkgd_color = (s3->accel.bkgd_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xa548: case 0xa6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; break; case 0xa549: case 0xa6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xa54a: case 0xa6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x00ff0000) | (val << 16); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffffff00) | val; + else + s3->accel.frgd_color = (s3->accel.frgd_color & 0xff00ffff) | (val << 16); break; case 0xa54b: case 0xa6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.frgd_color = (s3->accel.frgd_color & ~0xff000000) | (val << 24); - else - s3->accel.frgd_color = (s3->accel.frgd_color & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.frgd_color = (s3->accel.frgd_color & 0xffff00ff) | (val << 8); + else + s3->accel.frgd_color = (s3->accel.frgd_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xa948: case 0xaae8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; break; case 0xa949: case 0xaae9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xa94a: case 0xaaea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffffff00) | val; + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xff00ffff) | (val << 16); break; case 0xa94b: case 0xaaeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0xff000000) | (val << 24); - else - s3->accel.wrt_mask = (s3->accel.wrt_mask & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0xffff00ff) | (val << 8); + else + s3->accel.wrt_mask = (s3->accel.wrt_mask & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xad48: case 0xaee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; break; case 0xad49: case 0xaee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xad4a: case 0xaeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x00ff0000) | (val << 16); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffffff00) | val; + else + s3->accel.rd_mask = (s3->accel.rd_mask & 0xff00ffff) | (val << 16); break; case 0xad4b: case 0xaeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.rd_mask = (s3->accel.rd_mask & ~0xff000000) | (val << 24); - else - s3->accel.rd_mask = (s3->accel.rd_mask & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.rd_mask = (s3->accel.rd_mask & 0xffff00ff) | (val << 8); + else + s3->accel.rd_mask = (s3->accel.rd_mask & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xb148: case 0xb2e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; break; case 0xb149: case 0xb2e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xb14a: case 0xb2ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x00ff0000) | (val << 16); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffffff00) | val; + else + s3->accel.color_cmp = (s3->accel.color_cmp & 0xff00ffff) | (val << 16); break; case 0xb14b: case 0xb2eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.color_cmp = (s3->accel.color_cmp & ~0xff000000) | (val << 24); - else - s3->accel.color_cmp = (s3->accel.color_cmp & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.color_cmp = (s3->accel.color_cmp & 0xffff00ff) | (val << 8); + else + s3->accel.color_cmp = (s3->accel.color_cmp & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xb548: @@ -1115,42 +1079,35 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xe548: case 0xe6e8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; break; case 0xe549: case 0xe6e9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xe54a: case 0xe6ea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x00ff0000) | (val << 16); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffffff00) | val; + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xff00ffff) | (val << 16); break; case 0xe54b: case 0xe6eb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0xff000000) | (val << 24); - else - s3->accel.pat_bg_color = (s3->accel.pat_bg_color & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0xffff00ff) | (val << 8); + else + s3->accel.pat_bg_color = (s3->accel.pat_bg_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xe948: case 0xeae8: @@ -1170,42 +1127,35 @@ s3_accel_out_fifo(s3_t *s3, uint16_t port, uint8_t val) break; case 0xed48: case 0xeee8: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; break; case 0xed49: case 0xeee9: - if (s3->bpp == 3 && s3->accel.multifunc[0xe] & 0x10 && !(s3->accel.multifunc[0xe] & 0x200)) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; break; case 0xed4a: case 0xeeea: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x00ff0000) | (val << 16); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x000000ff) | val; - } + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffffff00) | val; + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xff00ffff) | (val << 16); break; case 0xed4b: case 0xeeeb: - if (s3->accel.multifunc[0xe] & 0x200) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else if (s3->bpp == 3) { - if (s3->accel.multifunc[0xe] & 0x10) - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0xff000000) | (val << 24); - else - s3->accel.pat_fg_color = (s3->accel.pat_fg_color & ~0x0000ff00) | (val << 8); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0xffff00ff) | (val << 8); + else + s3->accel.pat_fg_color = (s3->accel.pat_fg_color & 0x00ffffff) | (val << 24); + if (!(s3->accel.multifunc[0xe] & 0x200)) s3->accel.multifunc[0xe] ^= 0x10; - } break; case 0xe148: @@ -3733,6 +3683,7 @@ s3_accel_in(uint16_t port, void *priv) s3_t *s3 = (s3_t *) priv; svga_t *svga = &s3->svga; int temp; + uint8_t temp2; if (!s3->enable_8514) return 0xff; @@ -3895,7 +3846,12 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 16; + else + temp2 = s3->accel.bkgd_color & 0xff; + + return temp2; } break; case 0xa149: @@ -3903,26 +3859,49 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 24; + else + temp2 = s3->accel.bkgd_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xa14a: case 0xa2ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color & 0xff; + else + temp2 = s3->accel.bkgd_color >> 16; + + return temp2; case 0xa14b: case 0xa2eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.bkgd_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.bkgd_color >> 8; + else + temp2 = s3->accel.bkgd_color >> 24; + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xa548: case 0xa6e8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 16; + else + temp2 = s3->accel.frgd_color & 0xff; + + return temp2; } break; case 0xa549: @@ -3930,26 +3909,50 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 24; + else + temp2 = s3->accel.frgd_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xa54a: case 0xa6ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color & 0xff; + else + temp2 = s3->accel.frgd_color >> 16; + + return temp2; case 0xa54b: case 0xa6eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.frgd_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.frgd_color >> 8; + else + temp2 = s3->accel.frgd_color >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xa948: case 0xaae8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 16; + else + temp2 = s3->accel.wrt_mask & 0xff; + + return temp2; } break; case 0xa949: @@ -3957,50 +3960,101 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 24; + else + temp2 = s3->accel.wrt_mask >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xa94a: case 0xaaea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask & 0xff; + else + temp2 = s3->accel.wrt_mask >> 16; + + return temp2; case 0xa94b: case 0xaaeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.wrt_mask >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.wrt_mask >> 8; + else + temp2 = s3->accel.wrt_mask >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xad48: case 0xaee8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.rd_mask & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 16; + else + temp2 = s3->accel.rd_mask & 0xff; + + return temp2; } break; case 0xad49: case 0xaee9: - if (s3_enable_fifo(s3)) - s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 8; + if (s3->chip >= S3_86C928) { + if (s3_enable_fifo(s3)) + s3_wait_fifo_idle(s3); + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 24; + else + temp2 = s3->accel.rd_mask >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; + } + break; case 0xad4a: case 0xaeea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask & 0xff; + else + temp2 = s3->accel.rd_mask >> 16; + + return temp2; case 0xad4b: case 0xaeeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.rd_mask >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.rd_mask >> 8; + else + temp2 = s3->accel.rd_mask >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xb148: case 0xb2e8: if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 16; + else + temp2 = s3->accel.color_cmp & 0xff; + + return temp2; } break; case 0xb149: @@ -4008,19 +4062,38 @@ s3_accel_in(uint16_t port, void *priv) if (s3->chip >= S3_86C928) { if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 24; + else + temp2 = s3->accel.color_cmp >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; } break; case 0xb14a: case 0xb2ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp & 0xff; + else + temp2 = s3->accel.color_cmp >> 16; + + return temp2; case 0xb14b: case 0xb2eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.color_cmp >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.color_cmp >> 8; + else + temp2 = s3->accel.color_cmp >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xb548: case 0xb6e8: @@ -4130,25 +4203,49 @@ s3_accel_in(uint16_t port, void *priv) case 0xe6e8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 16; + else + temp2 = s3->accel.pat_bg_color & 0xff; + + return temp2; case 0xe549: case 0xe6e9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 24; + else + temp2 = s3->accel.pat_bg_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe54a: case 0xe6ea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color & 0xff; + else + temp2 = s3->accel.pat_bg_color >> 16; + + return temp2; case 0xe54b: case 0xe6eb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_bg_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_bg_color >> 8; + else + temp2 = s3->accel.pat_bg_color >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe948: case 0xeae8: @@ -4178,25 +4275,49 @@ s3_accel_in(uint16_t port, void *priv) case 0xeee8: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color & 0xff; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 16; + else + temp2 = s3->accel.pat_fg_color & 0xff; + + return temp2; case 0xed49: case 0xeee9: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 8; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 24; + else + temp2 = s3->accel.pat_fg_color >> 8; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xed4a: case 0xeeea: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 16; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color & 0xff; + else + temp2 = s3->accel.pat_fg_color >> 16; + + return temp2; case 0xed4b: case 0xeeeb: if (s3_enable_fifo(s3)) s3_wait_fifo_idle(s3); - return s3->accel.pat_fg_color >> 24; + if ((s3->bpp == 3) && (s3->accel.multifunc[0xe] & 0x10) && !(s3->accel.multifunc[0xe] & 0x200)) + temp2 = s3->accel.pat_fg_color >> 8; + else + temp2 = s3->accel.pat_fg_color >> 24; + + if (!(s3->accel.multifunc[0xe] & 0x200)) + s3->accel.multifunc[0xe] ^= 0x10; + return temp2; case 0xe148: case 0xe2e8: @@ -6182,21 +6303,20 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ uint32_t srcbase; uint32_t dstbase; - if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) { + if ((s3->chip >= S3_TRIO64 || s3->chip == S3_VISION968 || s3->chip == S3_VISION868) && (s3->accel.cmd & (1 << 11))) cmd |= 8; - } // SRC-BASE/DST-BASE - if ((s3->accel.multifunc[0xd] >> 4) & 7) { + if ((s3->accel.multifunc[0xd] >> 4) & 7) srcbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 4) & 3); - } else { + else srcbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 2) & 3); - } - if ((s3->accel.multifunc[0xd] >> 0) & 7) { + + if ((s3->accel.multifunc[0xd] >> 0) & 7) dstbase = 0x100000 * ((s3->accel.multifunc[0xd] >> 0) & 3); - } else { + else dstbase = 0x100000 * ((s3->accel.multifunc[0xe] >> 0) & 3); - } + if (s3->bpp == 1) { srcbase >>= 1; dstbase >>= 1; @@ -6205,9 +6325,8 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ dstbase >>= 2; } - if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) { + if ((s3->accel.cmd & 0x100) && (s3_cpu_src(s3) || (s3_cpu_dest(s3))) && (!cpu_input || (s3_enable_fifo(s3) == 0))) s3->force_busy = 1; - } if (!cpu_input) s3->accel.dat_count = 0; @@ -6225,7 +6344,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ } if ((s3->bpp == 1) || s3->color_16bit) count >>= 1; - if (s3->bpp == 3) + else if (s3->bpp == 3) count >>= 2; } @@ -6236,7 +6355,7 @@ s3_accel_start(int count, int cpu_input, uint32_t mix_dat, uint32_t cpu_dat, s3_ if ((s3->bpp == 0) && !s3->color_16bit) compare &= 0xff; - if ((s3->bpp == 1) || s3->color_16bit) + else if ((s3->bpp == 1) || s3->color_16bit) compare &= 0xffff; switch (s3->accel.cmd & 0x600) { From 2b14fc7baa093241428e5fefe43ec3a69bfec8a0 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Nov 2023 04:26:17 +0100 Subject: [PATCH 03/19] Removed the ability toggle between 16-bit and 8-bit DMA modes - evidently I was wrong about the existence of that ability and the purpose of those bits on the register FFh, fixes 16-bit audio in some instances on Windows 9x. --- src/sound/snd_sb.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sound/snd_sb.c b/src/sound/snd_sb.c index 5f9fb7f27..bfd1ca401 100644 --- a/src/sound/snd_sb.c +++ b/src/sound/snd_sb.c @@ -954,7 +954,9 @@ sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *priv) Seen values: 20, 05, 04, 03 */ sb_dsp_setdma16_enabled(&sb->dsp, !(val & 0x20)); +#ifdef TOGGLABLE_TRANSLATION sb_dsp_setdma16_translate(&sb->dsp, val & 0x02); +#endif } break; From c9b092be3ee3f3766b380c8664675f08cd753de2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Thu, 2 Nov 2023 05:53:05 +0100 Subject: [PATCH 04/19] Fixed accidentally swapped conditions in mem/spd.c, fixes RAM detection on 686 boards. --- src/mem/spd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mem/spd.c b/src/mem/spd.c index b2d0f7f16..a3bcba46d 100644 --- a/src/mem/spd.c +++ b/src/mem/spd.c @@ -388,9 +388,9 @@ spd_write_drbs(uint8_t *regs, uint8_t reg_min, uint8_t reg_max, uint8_t drb_unit /* Determine the DRB register to write. */ if (two_step) - drb = reg_min + row; - else drb = reg_min + (row << 1); + else + drb = reg_min + row; if (apollo && ((drb & 0xf) < 0xa)) drb = apollo + (drb & 0xf); From 18bd861c556697fdd49cdb17267a08ba0e7497f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B2=99=E6=B2=99=E5=AE=AE=E7=B4=97=E5=A4=9C?= <117635969+kzmidze@users.noreply.github.com> Date: Thu, 2 Nov 2023 14:06:32 +0800 Subject: [PATCH 05/19] Update languages --- src/qt/languages/zh-CN.po | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/qt/languages/zh-CN.po b/src/qt/languages/zh-CN.po index fe099265b..3d045b74e 100644 --- a/src/qt/languages/zh-CN.po +++ b/src/qt/languages/zh-CN.po @@ -653,7 +653,7 @@ msgid "ZIP images" msgstr "ZIP 映像" msgid "86Box could not find any usable ROM images.\n\nPlease download a ROM set and extract it into the \"roms\" directory." -msgstr "86Box 找不到任何可用的 ROM 映像。\n\n请下载ROM 包并将其解压到 \"roms\" 文件夹中。" +msgstr "86Box 找不到任何可用的 ROM 映像。\n\n请下载 ROM 包并将其解压到 \"roms\" 文件夹中。" msgid "(empty)" msgstr "(空)" From 4b9b664571358cde4ac713e03cc91fa90a10ecf2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Nov 2023 05:52:26 +0100 Subject: [PATCH 06/19] ACPI now correctly only does the power on resume event on power on, not software-initiated hard resets, fixes #3794. --- src/acpi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/acpi.c b/src/acpi.c index 544145553..0fe25d79f 100644 --- a/src/acpi.c +++ b/src/acpi.c @@ -1653,9 +1653,6 @@ acpi_reset(void *priv) dev->regs.gpi_val |= 0x00000004; } - /* Power on always generates a resume event. */ - dev->regs.pmsts |= 0x8100; - acpi_rtc_status = 0; acpi_update_irq(dev); @@ -1762,6 +1759,9 @@ acpi_init(const device_t *info) acpi_reset(dev); + /* Power on always generates a resume event. */ + dev->regs.pmsts |= 0x8100; + acpi_enabled = 1; return dev; } From 2a5a8f74317c1100ef20b542ceea8fd384126ab6 Mon Sep 17 00:00:00 2001 From: OBattler Date: Fri, 3 Nov 2023 05:54:30 +0100 Subject: [PATCH 07/19] Assorted IDE fixes and the PCI IDE bus master now also resets ATAPI hard disks. --- src/chipset/intel_piix.c | 2 -- src/disk/hdc_ide.c | 54 +++++++++++++++++------------------ src/disk/hdc_ide_sff8038i.c | 33 +++++++++------------ src/include/86box/hdc_ide.h | 6 ++-- src/include/86box/scsi_disk.h | 2 ++ src/scsi/scsi_disk.c | 3 +- 6 files changed, 48 insertions(+), 52 deletions(-) diff --git a/src/chipset/intel_piix.c b/src/chipset/intel_piix.c index e5b90d861..2094eefcf 100644 --- a/src/chipset/intel_piix.c +++ b/src/chipset/intel_piix.c @@ -1172,8 +1172,6 @@ piix_read(int func, int addr, void *priv) if ((func <= dev->max_func) || ((func == 1) && (dev->max_func == 0))) { fregs = (uint8_t *) dev->regs[func]; ret = fregs[addr]; - if ((func == 2) && (addr == 0xff)) - ret |= 0xef; piix_log("PIIX function %i read: %02X from %02X\n", func, ret, addr); } diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 2dffeeec3..049ebd259 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -336,7 +336,7 @@ ide_atapi_get_period(uint8_t channel) } static void -ide_irq_update(ide_board_t *dev) +ide_irq_update(ide_board_t *dev, int log) { ide_t *ide; uint8_t set; @@ -344,7 +344,10 @@ ide_irq_update(ide_board_t *dev) if (dev == NULL) return; - ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq); +#ifdef ENABLE_IDE_LOG + if (log) + ide_log("IDE %i: IRQ update (%i)\n", dev->cur_dev >> 1, dev->irq); +#endif ide = ide_drives[dev->cur_dev]; set = !(ide_boards[ide->board]->devctl & 2) && ide->irqstat; @@ -356,32 +359,22 @@ ide_irq_update(ide_board_t *dev) } void -ide_irq_raise(ide_t *ide) +ide_irq(ide_t *ide, int set, int log) { if (!ide_boards[ide->board]) return; - ide_log("IDE %i: IRQ raise\n", ide->channel); +#ifdef IDE_MORE_SPECIFIC_LOGS + ide_log("IDE %i: IRQ %s\n", set ? "raise" : "lower"); +#endif - ide->irqstat = 1; - ide->service = 1; + ide->irqstat = set; + + if (set) + ide->service = 1; if (ide->selected) - ide_irq_update(ide_boards[ide->board]); -} - -void -ide_irq_lower(ide_t *ide) -{ - if (!ide_boards[ide->board]) - return; - - ide_log("IDE %i: IRQ lower\n", ide->channel); - - ide->irqstat = 0; - - if (ide->selected) - ide_irq_update(ide_boards[ide->board]); + ide_irq_update(ide_boards[ide->board], log); } /** @@ -1214,7 +1207,9 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) ch = dev->cur_dev; ide = ide_drives[ch]; +#ifdef IDE_MORE_SPECIFIC_LOGS ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv); +#endif addr &= 0x7; @@ -1246,7 +1241,9 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) ch = dev->cur_dev; ide = ide_drives[ch]; +#ifdef IDE_MORE_SPECIFIC_LOGS ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv); +#endif addr &= 0x7; @@ -1361,7 +1358,7 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) old = dev->devctl; dev->devctl = val; if (!(val & 0x02) && (old & 0x02)) - ide_irq_update(ide_boards[ide->board]); + ide_irq_update(ide_boards[ide->board], 1); } static void @@ -1429,7 +1426,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) #ifdef WRITE_PARAM_TO_BOTH_DEVICES ide_other->tf->cylprecomp = val; #endif - return; + break; case 0x2: /* Sector count */ ide->tf->secount = val; @@ -1439,6 +1436,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) case 0x3: /* Sector */ ide->sector = val; ide->lba_addr = (ide->lba_addr & 0xfffff00) | val; + ide_other->sector = val; ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val; break; @@ -1482,7 +1480,7 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_set_board_callback(ide->board, 0.0); reset = 1; } else - ide_irq_update(ide_boards[ide->board]); + ide_irq_update(ide_boards[ide->board], 1); } if (!reset) { @@ -1911,7 +1909,7 @@ ide_readb(uint16_t addr, void *priv) /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is DF (drive fault). */ case 0x7: /* Status */ - ide_irq_lower(ide); + ide_irq(ide, 0, 0); ret = ide_status(ide, ide_drives[ch ^ 1], ch); break; @@ -1969,7 +1967,9 @@ ide_readw(uint16_t addr, void *priv) break; } +#ifdef IDE_MORE_SPECIFIC_LOGS ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret); +#endif return ret; } @@ -2002,7 +2002,9 @@ ide_readl(uint16_t addr, void *priv) break; } +#ifdef IDE_MORE_SPECIFIC_LOGS ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret); +#endif return ret; } @@ -2012,9 +2014,7 @@ ide_board_callback(void *priv) ide_board_t *dev = (ide_board_t *) priv; ide_t *ide; -#ifdef ENABLE_IDE_LOG ide_log("ide_board_callback(%i)\n", dev->cur_dev >> 1); -#endif for (uint8_t i = 0; i < 2; i++) { ide = dev->ide[i]; diff --git a/src/disk/hdc_ide_sff8038i.c b/src/disk/hdc_ide_sff8038i.c index 40cca95a9..3f43f80e6 100644 --- a/src/disk/hdc_ide_sff8038i.c +++ b/src/disk/hdc_ide_sff8038i.c @@ -27,7 +27,9 @@ #define HAVE_STDARG_H #include <86box/86box.h> #include <86box/cdrom.h> +#include <86box/hdd.h> #include <86box/scsi_device.h> +#include <86box/scsi_disk.h> #include <86box/scsi_cdrom.h> #include <86box/dma.h> #include <86box/io.h> @@ -389,7 +391,6 @@ sff_bus_master_set_irq(uint8_t status, void *priv) { sff8038i_t *dev = (sff8038i_t *) priv; uint8_t irq = !!(status & 0x04); - int irq_shift = 0; if (!(dev->status & 0x04) || (status & 0x04)) dev->status = (dev->status & ~0x04) | status; @@ -410,16 +411,12 @@ sff_bus_master_set_irq(uint8_t status, void *priv) else pci_clear_irq(dev->slot, dev->irq_pin, &dev->irq_state); break; - case IRQ_MODE_MIRQ_0: - case IRQ_MODE_MIRQ_1: - /* MIRQ 0 or 1. */ - case IRQ_MODE_MIRQ_2: - case IRQ_MODE_MIRQ_3: - /* MIRQ 2 or 3. */ + case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3: + /* MIRQ 0, 1, 2, or 3. */ if (irq) - pci_set_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state); + pci_set_mirq(dev->irq_mode & 3, 0, &dev->irq_state); else - pci_clear_mirq((dev->irq_mode & 3) + irq_shift, 0, &dev->irq_state); + pci_clear_mirq(dev->irq_mode & 3, 0, &dev->irq_state); break; /* TODO: Redo this as a MIRQ. */ case IRQ_MODE_PCI_IRQ_LINE: @@ -477,6 +474,10 @@ sff_reset(void *priv) sff_log("SFF8038i: Reset\n"); #endif + for (uint8_t i = 0; i < HDD_NUM; i++) { + if ((hdd[i].bus == HDD_BUS_ATAPI) && (hdd[i].ide_channel < 4) && hdd[i].priv) + scsi_disk_reset((scsi_common_t *) hdd[i].priv); + } for (uint8_t i = 0; i < CDROM_NUM; i++) { if ((cdrom[i].bus_type == CDROM_BUS_ATAPI) && (cdrom[i].ide_channel < 4) && cdrom[i].priv) scsi_cdrom_reset((scsi_common_t *) cdrom[i].priv); @@ -522,21 +523,15 @@ sff_set_irq_mode(sff8038i_t *dev, int irq_mode) default: case IRQ_MODE_LEGACY: /* Legacy IRQ mode. */ - sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, 14 + channel); + sff_log("[%08X] Setting IRQ mode to legacy IRQ %i\n", dev, dev->irq_line); break; case IRQ_MODE_PCI_IRQ_PIN: /* Native PCI IRQ mode with interrupt pin. */ sff_log("[%08X] Setting IRQ mode to native PCI INT%c\n", dev, 0x40 + dev->irq_pin); break; - case IRQ_MODE_MIRQ_0: - case IRQ_MODE_MIRQ_1: - /* MIRQ 0 or 1. */ - sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, irq_mode & 1); - break; - case IRQ_MODE_MIRQ_2: - case IRQ_MODE_MIRQ_3: - /* MIRQ 0 or 1. */ - sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, (irq_mode & 1) + 1); + case IRQ_MODE_MIRQ_0 ... IRQ_MODE_MIRQ_3: + /* MIRQ 0, 1, 2, or 3. */ + sff_log("[%08X] Setting IRQ mode to PCI MIRQ%i\n", dev, dev->irq_mode & 3); break; case IRQ_MODE_PCI_IRQ_LINE: /* Native PCI IRQ mode with specified interrupt line. */ diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index b1bff13b3..71ed9e448 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -179,8 +179,7 @@ extern int ide_qua_enabled; #ifdef SCSI_DEVICE_H extern ide_t *ide_get_drive(int ch); -extern void ide_irq_raise(ide_t *ide); -extern void ide_irq_lower(ide_t *ide); +extern void ide_irq(ide_t *ide, int set, int log); extern void ide_allocate_buffer(ide_t *dev); extern void ide_atapi_attach(ide_t *dev); #endif @@ -224,6 +223,9 @@ extern uint8_t ide_read_ali_75(void); extern uint8_t ide_read_ali_76(void); /* Legacy #define's. */ +#define ide_irq_raise(ide) ide_irq(ide, 1, 1) +#define ide_irq_lower(ide) ide_irq(ide, 0, 1) + #define ide_set_base(board, port) ide_set_base_addr(board, 0, port) #define ide_set_side(board, port) ide_set_base_addr(board, 1, port) diff --git a/src/include/86box/scsi_disk.h b/src/include/86box/scsi_disk.h index a62bc9e20..eb4dc69a4 100644 --- a/src/include/86box/scsi_disk.h +++ b/src/include/86box/scsi_disk.h @@ -68,6 +68,8 @@ typedef struct scsi_disk_t { extern scsi_disk_t *scsi_disk[HDD_NUM]; +extern void scsi_disk_reset(scsi_common_t *sc); + extern void scsi_disk_hard_reset(void); extern void scsi_disk_close(void); diff --git a/src/scsi/scsi_disk.c b/src/scsi/scsi_disk.c index ee0c3fc00..93d29a672 100644 --- a/src/scsi/scsi_disk.c +++ b/src/scsi/scsi_disk.c @@ -128,7 +128,6 @@ static void scsi_disk_command_complete(scsi_disk_t *dev); static void scsi_disk_mode_sense_load(scsi_disk_t *dev); static void scsi_disk_init(scsi_disk_t *dev); -static void scsi_disk_reset(scsi_common_t *sc); #ifdef ENABLE_SCSI_DISK_LOG int scsi_disk_do_log = ENABLE_SCSI_DISK_LOG; @@ -787,7 +786,7 @@ scsi_disk_rezero(scsi_disk_t *dev) scsi_disk_seek(dev, 0); } -static void +void scsi_disk_reset(scsi_common_t *sc) { scsi_disk_t *dev = (scsi_disk_t *) sc; From 859e74b30124c8c9d2e5c4ee9852d866a635145f Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 21 Oct 2023 17:24:36 -0400 Subject: [PATCH 08/19] Named-initializers for FPU's --- src/cpu/cpu_table.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 194089f72..b5c223231 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -33,39 +33,39 @@ #include <86box/machine.h> FPU fpus_none[] = { - {"None", "none", FPU_NONE}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_8088[] = { - {"None", "none", FPU_NONE}, - { "8087", "8087", FPU_8087}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "8087", .internal_name = "8087", .type = FPU_8087 }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_80186[] = { - {"None", "none", FPU_NONE }, - { "8087", "8087", FPU_8087 }, - { "80187", "80187", FPU_80187}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "8087", .internal_name = "8087", .type = FPU_8087 }, + { .name = "80187", .internal_name = "80187", .type = FPU_80187 }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_80286[] = { - {"None", "none", FPU_NONE }, - { "287", "287", FPU_287 }, - { "287XL", "287xl", FPU_287XL}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "287", .internal_name = "287", .type = FPU_287 }, + { .name = "287XL", .internal_name = "287xl", .type = FPU_287XL }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_80386[] = { - {"None", "none", FPU_NONE}, - { "387", "387", FPU_387 }, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "387", .internal_name = "387", .type = FPU_387 }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_486sx[] = { - {"None", "none", FPU_NONE }, - { "487SX", "487sx", FPU_487SX}, - { NULL, NULL, 0 } + { .name = "None", .internal_name = "none", .type = FPU_NONE }, + { .name = "487SX", .internal_name = "487sx", .type = FPU_487SX }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; FPU fpus_internal[] = { - {"Internal", "internal", FPU_INTERNAL}, - { NULL, NULL, 0 } + { .name = "Internal", .internal_name = "internal", .type = FPU_INTERNAL }, + { .name = NULL, .internal_name = NULL, .type = 0 } }; const cpu_family_t cpu_families[] = { From f6e6e2cda99c7a6545fb836bc9cd55c2a58b6058 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 21 Oct 2023 18:50:25 -0400 Subject: [PATCH 09/19] Named-initializers for 8088 CPU's --- src/cpu/cpu_table.c | 186 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 174 insertions(+), 12 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index b5c223231..f12bb254a 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -76,14 +76,128 @@ const cpu_family_t cpu_families[] = { .name = "8088", .internal_name = "8088", .cpus = (const CPU[]) { - {"4.77", CPU_8088, fpus_8088, 4772728, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_8088, fpus_8088, 7159092, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8", CPU_8088, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, -// {"9.54", CPU_8088, fpus_8088, 9545456, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"10", CPU_8088, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_8088, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_8088, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", 0} + { + .name = "4.77", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, +#if 0 + { + .name = "9.54", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, +#endif + { + .name = "10", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8088_EUROPC, @@ -91,10 +205,58 @@ const cpu_family_t cpu_families[] = { .name = "8088", .internal_name = "8088_europc", .cpus = (const CPU[]) { - {"4.77", CPU_8088, fpus_8088, 4772728, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"7.16", CPU_8088, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"9.54", CPU_8088, fpus_8088, 9545456, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"", 0} + { + .name = "4.77", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_8088, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8086, From bc4f006e5904f36b08e3a0a222f3d9ea11388177 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 21 Oct 2023 19:42:14 -0400 Subject: [PATCH 10/19] Named-initializers for 8086 CPU's --- src/cpu/cpu_table.c | 110 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 7 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index f12bb254a..e52697ab7 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -264,13 +264,109 @@ const cpu_family_t cpu_families[] = { .name = "8086", .internal_name = "8086", .cpus = (const CPU[]) { - {"7.16", CPU_8086, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8", CPU_8086, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"9.54", CPU_8086, fpus_8088, 9545456, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"10", CPU_8086, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_8086, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_8086, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", 0} + { + .name = "7.16", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_8086, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_188, From eb3d3804aad790c299d65d857328ba2d87050886 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Sat, 21 Oct 2023 20:03:05 -0400 Subject: [PATCH 11/19] Named-initializers for 80188 CPU's --- src/cpu/cpu_table.c | 164 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 154 insertions(+), 10 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index e52697ab7..2128f22eb 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -374,16 +374,160 @@ const cpu_family_t cpu_families[] = { .name = "80188", .internal_name = "80188", .cpus = (const CPU[]) { - {"6", CPU_188, fpus_8088, 6000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_188, fpus_8088, 7159092, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8", CPU_188, fpus_8088, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"9.54", CPU_188, fpus_8088, 9545456, 1, 5000, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"10", CPU_188, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_188, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_188, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"20", CPU_188, fpus_8088, 20000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 3}, - {"25", CPU_188, fpus_8088, 25000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 3}, - {"", 0} + { + .name = "6", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 6000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 9545456, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_188, + .fpus = fpus_8088, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8088, From cf6af5128b9b103d2a7f1a406b0d566c842dad81 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Mon, 23 Oct 2023 15:27:23 -0400 Subject: [PATCH 12/19] Named-initializers for NEC V20 CPU's --- src/cpu/cpu_table.c | 92 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 2128f22eb..6556b9380 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -535,12 +535,92 @@ const cpu_family_t cpu_families[] = { .name = "V20", .internal_name = "necv20", .cpus = (const CPU[]) { - {"4.77", CPU_V20, fpus_8088, 4772728, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_V20, fpus_8088, 7159092, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"10", CPU_V20, fpus_8088, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_V20, fpus_8088, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_V20, fpus_8088, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", 0} + { + .name = "4.77", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 4772728, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 7159092, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_V20, + .fpus = fpus_8088, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_186, From ba44d3cbac01162ab1ef11c2dbdb7ca73258f508 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 3 Nov 2023 21:32:57 -0400 Subject: [PATCH 13/19] Named-initializers for 80186 CPU's --- src/cpu/cpu_table.c | 164 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 154 insertions(+), 10 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 6556b9380..52d8edf5a 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -628,16 +628,160 @@ const cpu_family_t cpu_families[] = { .name = "80186", .internal_name = "80186", .cpus = (const CPU[]) { - {"6", CPU_186, fpus_80186, 6000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"7.16", CPU_186, fpus_80186, 7159092, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"8", CPU_186, fpus_80186, 8000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"9.54", CPU_186, fpus_80186, 9545456, 1, 0, 0, 0, 0, CPU_ALTERNATE_XTAL, 0,0,0,0, 1}, - {"10", CPU_186, fpus_80186, 10000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_186, fpus_80186, 12000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_186, fpus_80186, 16000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 2}, - {"20", CPU_186, fpus_80186, 20000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 3}, - {"25", CPU_186, fpus_80186, 25000000, 1, 0, 0, 0, 0, 0, 0,0,0,0, 3}, - {"", 0} + { + .name = "6", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 6000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "7.16", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 7159092, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 8000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "9.54", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 9545456, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = CPU_ALTERNATE_XTAL, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 10000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 12000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 16000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 20000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_186, + .fpus = fpus_80186, + .rspeed = 25000000, + .multi = 1, + .voltage = 0, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_8086, From 2c7175bb664400deac23b61177452533d464aa2d Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 3 Nov 2023 21:57:19 -0400 Subject: [PATCH 14/19] Named-initializers for NEC V30 CPU's --- src/cpu/cpu_table.c | 92 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 86 insertions(+), 6 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index 52d8edf5a..be9656b43 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -789,12 +789,92 @@ const cpu_family_t cpu_families[] = { .name = "V30", .internal_name = "necv30", .cpus = (const CPU[]) { - {"5", CPU_V30, fpus_80186, 5000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"8", CPU_V30, fpus_80186, 8000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"10", CPU_V30, fpus_80186, 10000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"12", CPU_V30, fpus_80186, 12000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 1}, - {"16", CPU_V30, fpus_80186, 16000000, 1, 5000, 0, 0, 0, 0, 0,0,0,0, 2}, - {"", 0} + { + .name = "5", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 5000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 12000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 1 + }, + { + .name = "16", + .cpu_type = CPU_V30, + .fpus = fpus_80186, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 0, + .mem_write_cycles = 0, + .cache_read_cycles = 0, + .cache_write_cycles = 0, + .atclk_div = 2 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_286, From 410e6a834739ea340c7b51d47750479979071c25 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 3 Nov 2023 22:20:14 -0400 Subject: [PATCH 15/19] Named-initializers for 80286 CPU's --- src/cpu/cpu_table.c | 128 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 120 insertions(+), 8 deletions(-) diff --git a/src/cpu/cpu_table.c b/src/cpu/cpu_table.c index be9656b43..0b37ce2d6 100644 --- a/src/cpu/cpu_table.c +++ b/src/cpu/cpu_table.c @@ -882,14 +882,126 @@ const cpu_family_t cpu_families[] = { .name = "80286", .internal_name = "286", .cpus = (const CPU[]) { - {"6", CPU_286, fpus_80286, 6000000, 1, 5000, 0, 0, 0, 0, 2,2,2,2, 1}, - {"8", CPU_286, fpus_80286, 8000000, 1, 5000, 0, 0, 0, 0, 2,2,2,2, 1}, - {"10", CPU_286, fpus_80286, 10000000, 1, 5000, 0, 0, 0, 0, 2,2,2,2, 1}, - {"12", CPU_286, fpus_80286, 12500000, 1, 5000, 0, 0, 0, 0, 3,3,3,3, 2}, - {"16", CPU_286, fpus_80286, 16000000, 1, 5000, 0, 0, 0, 0, 3,3,3,3, 2}, - {"20", CPU_286, fpus_80286, 20000000, 1, 5000, 0, 0, 0, 0, 4,4,4,4, 3}, - {"25", CPU_286, fpus_80286, 25000000, 1, 5000, 0, 0, 0, 0, 4,4,4,4, 3}, - {"", 0} + { + .name = "6", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 6000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "8", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 8000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "10", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 10000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 2, + .mem_write_cycles = 2, + .cache_read_cycles = 2, + .cache_write_cycles = 2, + .atclk_div = 1 + }, + { + .name = "12", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 12500000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "16", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 16000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 3, + .mem_write_cycles = 3, + .cache_read_cycles = 3, + .cache_write_cycles = 3, + .atclk_div = 2 + }, + { + .name = "20", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 20000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 4, + .cache_write_cycles = 4, + .atclk_div = 3 + }, + { + .name = "25", + .cpu_type = CPU_286, + .fpus = fpus_80286, + .rspeed = 25000000, + .multi = 1, + .voltage = 5000, + .edx_reset = 0, + .cpuid_model = 0, + .cyrix_id = 0, + .cpu_flags = 0, + .mem_read_cycles = 4, + .mem_write_cycles = 4, + .cache_read_cycles = 4, + .cache_write_cycles = 4, + .atclk_div = 3 + }, + { .name = "", 0 } } }, { .package = CPU_PKG_386SX, From 507aa202d47210cf5503d6c3a2393517541f8df8 Mon Sep 17 00:00:00 2001 From: Jasmine Iwanek Date: Fri, 3 Nov 2023 22:25:50 -0400 Subject: [PATCH 16/19] Fix compile error in opti499.c --- src/chipset/opti499.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/chipset/opti499.c b/src/chipset/opti499.c index acac4d87b..f8b878559 100644 --- a/src/chipset/opti499.c +++ b/src/chipset/opti499.c @@ -33,7 +33,7 @@ #include <86box/chipset.h> typedef struct opti499_t { - uint8_t idx, + uint8_t idx; uint8_t regs[256]; uint8_t scratch[2]; } opti499_t; From 058391e1485346f70d982d8e6cb585162aa8d47e Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 Nov 2023 03:28:42 +0100 Subject: [PATCH 17/19] More IDE clean-ups and properly implemented task file ownership, fixes OS/2 Warp 3.0 booting from IDE hard disks. --- src/disk/hdc_ide.c | 590 ++++++++++++++++++++---------------- src/include/86box/hdc_ide.h | 35 +-- 2 files changed, 346 insertions(+), 279 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 049ebd259..126a9d583 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -82,23 +82,23 @@ #define WIN_SEEK 0x70 #define WIN_DRIVE_DIAGNOSTICS 0x90 /* Execute Drive Diagnostics */ #define WIN_SPECIFY 0x91 /* Initialize Drive Parameters */ -#define WIN_PACKETCMD 0xA0 /* Send a packet command. */ -#define WIN_PIDENTIFY 0xA1 /* Identify ATAPI device */ -#define WIN_READ_MULTIPLE 0xC4 -#define WIN_WRITE_MULTIPLE 0xC5 -#define WIN_SET_MULTIPLE_MODE 0xC6 -#define WIN_READ_DMA 0xC8 -#define WIN_READ_DMA_ALT 0xC9 -#define WIN_WRITE_DMA 0xCA -#define WIN_WRITE_DMA_ALT 0xCB -#define WIN_STANDBYNOW1 0xE0 -#define WIN_IDLENOW1 0xE1 -#define WIN_SETIDLE1 0xE3 -#define WIN_CHECKPOWERMODE1 0xE5 -#define WIN_SLEEP1 0xE6 -#define WIN_IDENTIFY 0xEC /* Ask drive to identify itself */ -#define WIN_SET_FEATURES 0xEF -#define WIN_READ_NATIVE_MAX 0xF8 +#define WIN_PACKETCMD 0xa0 /* Send a packet command. */ +#define WIN_PIDENTIFY 0xa1 /* Identify ATAPI device */ +#define WIN_READ_MULTIPLE 0xc4 +#define WIN_WRITE_MULTIPLE 0xc5 +#define WIN_SET_MULTIPLE_MODE 0xc6 +#define WIN_READ_DMA 0xc8 +#define WIN_READ_DMA_ALT 0xc9 +#define WIN_WRITE_DMA 0xcA +#define WIN_WRITE_DMA_ALT 0xcB +#define WIN_STANDBYNOW1 0xe0 +#define WIN_IDLENOW1 0xe1 +#define WIN_SETIDLE1 0xe3 +#define WIN_CHECKPOWERMODE1 0xe5 +#define WIN_SLEEP1 0xe6 +#define WIN_IDENTIFY 0xeC /* Ask drive to identify itself */ +#define WIN_SET_FEATURES 0xeF +#define WIN_READ_NATIVE_MAX 0xf8 #define FEATURE_SET_TRANSFER_MODE 0x03 #define FEATURE_ENABLE_IRQ_OVERLAPPED 0x5d @@ -138,50 +138,90 @@ typedef struct ide_board_t { ide_board_t *ide_boards[IDE_BUS_MAX]; static uint8_t ide_ter_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */ + /* BOX0001, serial 0, dummy checksum (filled in by isapnp_add_card) */ + 0x09, 0xf8, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, + /* PnP version 1.0, vendor version 1.0 */ + 0x0a, 0x10, 0x10, + /* ANSI identifier */ + 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', + 'l', 'l', 'e', 'r', - 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x08, /* IRQ 11 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ - 0x38, /* end dependent functions */ + /* Logical device BOX0001 */ + 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, + /* Compatible device PNP0600 */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, + /* Start dependent functions, preferred */ + 0x31, 0x00, + /* IRQ 11 */ + 0x22, 0x00, 0x08, + /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, + /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x1E8, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0xe8, 0x01, 0xe8, 0x01, 0x01, 0x08, + /* I/O 0x3EE, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0xee, 0x03, 0xee, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, + /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, + /* End dependent functions */ + 0x38, - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + /* End tag, dummy checksum (filled in by isapnp_add_card) */ + 0x79, 0x00 }; static uint8_t ide_qua_pnp_rom[] = { - 0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */ - 0x0a, 0x10, 0x10, /* PnP version 1.0, vendor version 1.0 */ - 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', 'l', 'l', 'e', 'r', /* ANSI identifier */ + /* BOX0001, serial 1, dummy checksum (filled in by isapnp_add_card) */ + 0x09, 0xf8, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, + /* PnP version 1.0, vendor version 1.0 */ + 0x0a, 0x10, 0x10, + /* ANSI identifier */ + 0x82, 0x0e, 0x00, 'I', 'D', 'E', ' ', 'C', 'o', 'n', 't', 'r', 'o', + 'l', 'l', 'e', 'r', - 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, /* logical device BOX0001 */ - 0x1c, 0x41, 0xd0, 0x06, 0x00, /* compatible device PNP0600 */ - 0x31, 0x00, /* start dependent functions, preferred */ - 0x22, 0x00, 0x04, /* IRQ 10 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ - 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ - 0x30, /* start dependent functions, acceptable */ - 0x22, 0xb8, 0x1e, /* IRQ 3/4/5/7/9/10/11/12 */ - 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ - 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ - 0x38, /* end dependent functions */ + /* Logical device BOX0001 */ + 0x15, 0x09, 0xf8, 0x00, 0x01, 0x00, + /* Compatible device PNP0600 */ + 0x1c, 0x41, 0xd0, 0x06, 0x00, + /* Start dependent functions, preferred */ + 0x31, 0x00, + /* IRQ 10 */ + 0x22, 0x00, 0x04, + /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, + /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x168, decodes 16-bit, 1-byte alignment, 8 addresses */ + 0x47, 0x01, 0x68, 0x01, 0x68, 0x01, 0x01, 0x08, + /* I/O 0x36E, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x6e, 0x03, 0x6e, 0x03, 0x01, 0x01, + /* Start dependent functions, acceptable */ + 0x30, + /* IRQ 3/4/5/7/9/10/11/12 */ + 0x22, 0xb8, 0x1e, + /* I/O 0x100-0xFFF8, decodes 16-bit, 8-byte alignment, 8 addresses */ + 0x47, 0x01, 0x00, 0x01, 0xf8, 0xff, 0x08, 0x08, + /* I/O 0x100-0xFFFF, decodes 16-bit, 1-byte alignment, 1 address */ + 0x47, 0x01, 0x00, 0x01, 0xff, 0xff, 0x01, 0x01, + /* End dependent functions */ + 0x38, - 0x79, 0x00 /* end tag, dummy checksum (filled in by isapnp_add_card) */ + /* End tag, dummy checksum (filled in by isapnp_add_card) */ + 0x79, 0x00 }; ide_t *ide_drives[IDE_NUM]; @@ -364,8 +404,8 @@ ide_irq(ide_t *ide, int set, int log) if (!ide_boards[ide->board]) return; -#ifdef IDE_MORE_SPECIFIC_LOGS - ide_log("IDE %i: IRQ %s\n", set ? "raise" : "lower"); +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("IDE %i: IRQ %s\n", ide->channel, set ? "raise" : "lower"); #endif ide->irqstat = set; @@ -583,7 +623,7 @@ ide_identify(ide_t *ide) if (ide->type == IDE_ATAPI) ide->identify(ide, !IDE_ATAPI_IS_EARLY && !ide_boards[ide->board]->force_ata3 && (bm != NULL)); - else if (ide->type != IDE_NONE) + else if (ide->type == IDE_HDD) ide_hd_identify(ide); else { fatal("IDE IDENTIFY or IDENTIFY PACKET DEVICE on non-attached IDE device\n"); @@ -675,15 +715,15 @@ ide_get_sector(ide_t *ide) uint32_t heads; uint32_t sectors; - if (ide->lba) + if (ide->tf->lba) return (off64_t) ide->lba_addr; else { heads = ide->cfg_hpc; sectors = ide->cfg_spt; - uint8_t sector = ide->sector ? (ide->sector - 1) : 0; + uint8_t sector = ide->tf->sector ? (ide->tf->sector - 1) : 0; - return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->head) * sectors) + + return ((((off64_t) ide->tf->cylinder * heads) + (off64_t) ide->tf->head) * sectors) + (off64_t) sector; } } @@ -694,15 +734,15 @@ ide_get_sector(ide_t *ide) static void ide_next_sector(ide_t *ide) { - if (ide->lba) + if (ide->tf->lba) ide->lba_addr++; else { - ide->sector++; - if ((ide->sector == 0) || (ide->sector == (ide->cfg_spt + 1))) { - ide->sector = 1; - ide->head++; - if ((ide->head == 0) || (ide->head == ide->cfg_hpc)) { - ide->head = 0; + ide->tf->sector++; + if ((ide->tf->sector == 0) || (ide->tf->sector == (ide->cfg_spt + 1))) { + ide->tf->sector = 1; + ide->tf->head++; + if ((ide->tf->head == 0) || (ide->head == ide->cfg_hpc)) { + ide->tf->head = 0; ide->tf->cylinder++; } } @@ -729,13 +769,12 @@ loadhd(ide_t *ide, int d, UNUSED(const char *fn)) void ide_set_signature(ide_t *ide) { - uint16_t ide_signatures[3] = { /* 0xffff */ 0x7f7f, 0x0000, 0xeb14 }; + uint16_t ide_signatures[4] = { 0x7f7f, 0x0000, 0xeb14, 0x7f7f }; - ide->sector = 1; - ide->head = 0; - - ide->tf->secount = 1; - ide->tf->cylinder = ide_signatures[ide->type]; + ide->tf->sector = 1; + ide->tf->head = 0; + ide->tf->secount = 1; + ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW]; if (ide->type == IDE_HDD) ide->drive = 0; @@ -839,16 +878,16 @@ ide_set_sector(ide_t *ide, int64_t sector_num) { unsigned int cyl; unsigned int r; - if (ide->lba) { - ide->head = (sector_num >> 24) & 0xff; + if (ide->tf->lba) { + ide->tf->head = (sector_num >> 24) & 0xff; ide->tf->cylinder = (sector_num >> 8) & 0xffff; - ide->sector = sector_num & 0xff; + ide->tf->sector = sector_num & 0xff; } else { cyl = sector_num / (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); r = sector_num % (hdd[ide->hdd_num].hpc * hdd[ide->hdd_num].spt); ide->tf->cylinder = cyl & 0xffff; - ide->head = ((r / hdd[ide->hdd_num].spt) & 0x0f) & 0xff; - ide->sector = ((r % hdd[ide->hdd_num].spt) + 1) & 0xff; + ide->tf->head = ((r / hdd[ide->hdd_num].spt) & 0x0f) & 0xff; + ide->tf->sector = ((r % hdd[ide->hdd_num].spt) + 1) & 0xff; } } @@ -954,14 +993,20 @@ ide_atapi_callback(ide_t *ide) "Complete" }; char *phase; - if (ide->sc->packet_status <= PHASE_COMPLETE) - phase = phases[ide->sc->packet_status]; - else if (ide->sc->packet_status == PHASE_ERROR) - phase = "Error"; - else if (ide->sc->packet_status == PHASE_NONE) - phase = "None"; - else - phase = "Unknown"; + switch (ide->sc->packet_status) { + default: + phase = "Unknown"; + break; + case PHASE_IDLE ... PHASE_COMPLETE: + phase = phases[ide->sc->packet_status]; + break; + case PHASE_ERROR: + phase = "Error"; + break; + case PHASE_NONE: + phase = "None"; + break; + } ide_log("Phase: %02X (%s)\n", ide->sc->packet_status, phase); #endif @@ -1162,36 +1207,38 @@ ide_write_data(ide_t *ide, uint16_t val, int length) uint8_t *idebufferb = (uint8_t *) ide->buffer; uint16_t *idebufferw = ide->buffer; - if (ide->command == WIN_PACKETCMD) { - if (ide->type == IDE_ATAPI) - ide_atapi_packet_write(ide, val, length); - else - ide->tf->pos = 0; - } else { - if (length == 2) { - idebufferw[ide->tf->pos >> 1] = val & 0xffff; - ide->tf->pos += 2; + if ((ide->type != IDE_NONE) && !(ide->type & IDE_SHADOW) && ide->buffer) { + if (ide->command == WIN_PACKETCMD) { + if (ide->type == IDE_ATAPI) + ide_atapi_packet_write(ide, val, length); + else + ide->tf->pos = 0; } else { - idebufferb[ide->tf->pos] = val & 0xff; - ide->tf->pos++; - } + if (length == 2) { + idebufferw[ide->tf->pos >> 1] = val & 0xffff; + ide->tf->pos += 2; + } else { + idebufferb[ide->tf->pos] = val & 0xff; + ide->tf->pos++; + } - if (ide->tf->pos >= 512) { - ide->tf->pos = 0; - ide->tf->atastat = BSY_STAT; - double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - double wait_time = seek_time + xfer_time; - if (ide->command == WIN_WRITE_MULTIPLE) { - if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { - ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); - ide->pending_delay = 0; - } else { - ide->pending_delay += wait_time; - ide_callback(ide); - } - } else - ide_set_callback(ide, wait_time); + if (ide->tf->pos >= 512) { + ide->tf->pos = 0; + ide->tf->atastat = BSY_STAT; + double seek_time = hdd_timing_write(&hdd[ide->hdd_num], ide_get_sector(ide), 1); + double xfer_time = ide_get_xfer_time(ide, 512); + double wait_time = seek_time + xfer_time; + if (ide->command == WIN_WRITE_MULTIPLE) { + if ((ide->blockcount + 1) >= ide->blocksize || ide->tf->secount == 1) { + ide_set_callback(ide, seek_time + xfer_time + ide->pending_delay); + ide->pending_delay = 0; + } else { + ide->pending_delay += wait_time; + ide_callback(ide); + } + } else + ide_set_callback(ide, wait_time); + } } } } @@ -1207,7 +1254,7 @@ ide_writew(uint16_t addr, uint16_t val, void *priv) ch = dev->cur_dev; ide = ide_drives[ch]; -#ifdef IDE_MORE_SPECIFIC_LOGS +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) ide_log("ide_writew(%04X, %04X, %08X)\n", addr, val, priv); #endif @@ -1241,7 +1288,7 @@ ide_writel(uint16_t addr, uint32_t val, void *priv) ch = dev->cur_dev; ide = ide_drives[ch]; -#ifdef IDE_MORE_SPECIFIC_LOGS +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) ide_log("ide_writel(%04X, %08X, %08X)\n", addr, val, priv); #endif @@ -1289,6 +1336,10 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) uint8_t old; ch = dev->cur_dev; + /* ATA/ATAPI specification: On a slave with non-present master, pretend the + master is selected. */ + if (ide_drives[ch]->type & IDE_SHADOW) + ch ^= 1; ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; @@ -1364,16 +1415,16 @@ ide_write_devctl(UNUSED(uint16_t addr), uint8_t val, void *priv) static void ide_reset_registers(ide_t *ide) { - uint16_t ide_signatures[3] = { /* 0xffff */ 0x7f7f, 0x0000, 0xeb14 }; + uint16_t ide_signatures[4] = { 0x7f7f, 0x0000, 0xeb14, 0x7f7f }; ide->tf->atastat = DRDY_STAT | DSC_STAT; ide->tf->error = 1; ide->tf->secount = 1; - ide->tf->cylinder = ide_signatures[ide->type]; + ide->tf->cylinder = ide_signatures[ide->type & ~IDE_SHADOW]; + ide->tf->sector = 1; + ide->tf->head = 0; - ide->sector = 1; - ide->head = 0; - ide->reset = 0; + ide->reset = 0; if (ide->type == IDE_ATAPI) ide->sc->callback = 0.0; @@ -1388,7 +1439,6 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide_t *ide; ide_t *ide_other; int ch; - int absent = 0; int bad = 0; int reset = 0; @@ -1396,65 +1446,74 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) ide = ide_drives[ch]; ide_other = ide_drives[ch ^ 1]; - /* Absent and is master or both are absent. */ - if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) - absent = 1; - /* Absent and is slave and master is present. */ - else if ((ide->type == IDE_NONE) && (ch & 1)) - absent = 2; - ide_log("ide_writeb(%04X, %02X, %08X)\n", addr, val, priv); addr &= 0x7; - if ((absent != 1) || ((addr != 0x0) && (addr != 0x7))) switch (addr) { + if ((ide->type != IDE_NONE) || ((addr != 0x0) && (addr != 0x7))) switch (addr) { case 0x0: /* Data */ - if (absent == 0) - ide_write_data(ide, val | (val << 8), 2); + ide_write_data(ide, val | (val << 8), 2); break; /* Note to self: for ATAPI, bit 0 of this is DMA if set, PIO if clear. */ case 0x1: /* Features */ - ide->tf->cylprecomp = val; - if (ide->type == IDE_ATAPI) - ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->cylprecomp = val; + if (ide->type == IDE_ATAPI) + ide_log("ATAPI transfer mode: %s\n", (val & 1) ? "DMA" : "PIO"); + } -/* The ATA-3 specification says this register is the parameter for the - command and is unclear as to whether or not it's written to both - devices at once. Writing it to both devices at once breaks CD boot - on the AMI Apollo. */ -#ifdef WRITE_PARAM_TO_BOTH_DEVICES - ide_other->tf->cylprecomp = val; -#endif + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) + ide_other->tf->cylprecomp = val; break; case 0x2: /* Sector count */ - ide->tf->secount = val; - ide_other->tf->secount = val; + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) + ide->tf->secount = val; + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) + ide_other->tf->secount = val; break; case 0x3: /* Sector */ - ide->sector = val; - ide->lba_addr = (ide->lba_addr & 0xfffff00) | val; + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->sector = val; + ide->lba_addr = (ide->lba_addr & 0xfffff00) | val; + } - ide_other->sector = val; - ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val; + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide_other->tf->sector = val; + ide_other->lba_addr = (ide_other->lba_addr & 0xfffff00) | val; + } break; case 0x4: /* Cylinder low */ - ide->tf->cylinder = (ide->tf->cylinder & 0xff00) | val; - ide->lba_addr = (ide->lba_addr & 0xfff00ff) | (val << 8); + if (ide->type & IDE_SHADOW) + break; - ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff00) | val; - ide_other->lba_addr = (ide_other->lba_addr & 0xfff00ff) | (val << 8); + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->cylinder = (ide->tf->cylinder & 0xff00) | val; + ide->lba_addr = (ide->lba_addr & 0xfff00ff) | (val << 8); + } + + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff00) | val; + ide_other->lba_addr = (ide_other->lba_addr & 0xfff00ff) | (val << 8); + } break; case 0x5: /* Cylinder high */ - ide->tf->cylinder = (ide->tf->cylinder & 0xff) | (val << 8); - ide->lba_addr = (ide->lba_addr & 0xf00ffff) | (val << 16); + if (ide->type & IDE_SHADOW) + break; - ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff) | (val << 8); - ide_other->lba_addr = (ide_other->lba_addr & 0xf00ffff) | (val << 16); + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->cylinder = (ide->tf->cylinder & 0xff) | (val << 8); + ide->lba_addr = (ide->lba_addr & 0xf00ffff) | (val << 16); + } + + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide_other->tf->cylinder = (ide_other->tf->cylinder & 0xff) | (val << 8); + ide_other->lba_addr = (ide_other->lba_addr & 0xf00ffff) | (val << 16); + } break; case 0x6: /* Drive/Head */ @@ -1484,16 +1543,27 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) } if (!reset) { - ide->head = ide_other->head = val & 0xF; - ide->lba = ide_other->lba = val & 0x40; + if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide->tf->head = val & 0xf; + ide->tf->lba = val & 0x40; - ide->lba_addr = (ide->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); - ide_other->lba_addr = (ide_other->lba_addr & 0x0FFFFFF) | ((val & 0xF) << 24); + ide->lba_addr = (ide->lba_addr & 0x0ffffff) | (ide->tf->head << 24); + } + + if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { + ide_other->tf->head = val & 0xf; + ide_other->tf->lba = val & 0x40; + + ide_other->lba_addr = (ide_other->lba_addr & 0x0ffffff) | (ide->tf->head << 24); + } } break; case 0x7: /* Command register */ - if (absent != 0) + if (ide->tf->atastat & (BSY_STAT | DRQ_STAT)) + break; + + if ((ide->type == IDE_NONE) || ((ide->type & IDE_SHADOW) && (val != WIN_DRIVE_DIAGNOSTICS))) break; ide_irq_lower(ide); @@ -1719,70 +1789,70 @@ ide_read_data(ide_t *ide, int length) { const uint8_t *idebufferb = (uint8_t *) ide->buffer; const uint16_t *idebufferw = ide->buffer; - int ch = ide->channel; uint16_t ret = 0; + double seek_us; + double xfer_us; - /* Absent and is master or both are absent. */ - if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) { +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("ide_read_data(): ch = %i, board = %i, type = %i\n", ch, + ide->board, ide->type); +#endif + + if ((ide->type == IDE_NONE) || (ide->type & IDE_SHADOW) || !ide->buffer) { if (length == 2) ret = 0xff7f; else ret = 0x7f; - /* Absent and is slave and master is present. */ - } else if ((ide->type != IDE_NONE) || !(ch & 1)) { - if (!ide->buffer) { - if (length == 2) - ret = 0xffff; - else - ret = 0xff; - } else if (ide->command == WIN_PACKETCMD) { - if (ide->type == IDE_ATAPI) - ret = ide_atapi_packet_read(ide, length); - else { - ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos); - ide->tf->pos = 0; - } + } else if (ide->command == WIN_PACKETCMD) { + if (ide->type == IDE_ATAPI) + ret = ide_atapi_packet_read(ide, length); + else { + ide_log("Drive not ATAPI (position: %i)\n", ide->tf->pos); + ide->tf->pos = 0; + } + } else { + if (length == 2) { + ret = idebufferw[ide->tf->pos >> 1]; + ide->tf->pos += 2; } else { - if (length == 2) { - ret = idebufferw[ide->tf->pos >> 1]; - ide->tf->pos += 2; - } else { - ret = idebufferb[ide->tf->pos]; - ide->tf->pos++; - } + ret = idebufferb[ide->tf->pos]; + ide->tf->pos++; + } - if (ide->tf->pos >= 512) { - ide->tf->pos = 0; - ide->tf->atastat = DRDY_STAT | DSC_STAT; - if (ide->type == IDE_ATAPI) - ide->sc->packet_status = PHASE_IDLE; + if (ide->tf->pos >= 512) { + ide->tf->pos = 0; + ide->tf->atastat = DRDY_STAT | DSC_STAT; + if (ide->type == IDE_ATAPI) + ide->sc->packet_status = PHASE_IDLE; - if ((ide->command == WIN_READ) || (ide->command == WIN_READ_NORETRY) || - (ide->command == WIN_READ_MULTIPLE)) { - ide->tf->secount--; + if ((ide->command == WIN_READ) || + (ide->command == WIN_READ_NORETRY) || + (ide->command == WIN_READ_MULTIPLE)) { + ide->tf->secount--; - if (ide->tf->secount) { - ide_next_sector(ide); - ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT; - if (ide->command == WIN_READ_MULTIPLE) { - if (!ide->blockcount) { - uint32_t sec_count = ide->tf->secount ? ide->tf->secount : 256; - if (sec_count > ide->blocksize) - sec_count = ide->blocksize; - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], - ide_get_sector(ide), sec_count); - double xfer_time = ide_get_xfer_time(ide, 512 * sec_count); - ide_set_callback(ide, seek_time + xfer_time); - } else - ide_callback(ide); - } else { - double seek_time = hdd_timing_read(&hdd[ide->hdd_num], ide_get_sector(ide), 1); - double xfer_time = ide_get_xfer_time(ide, 512); - ide_set_callback(ide, seek_time + xfer_time); - } - } else - ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); - } + if (ide->tf->secount) { + ide_next_sector(ide); + ide->tf->atastat = BSY_STAT | READY_STAT | DSC_STAT; + if (ide->command == WIN_READ_MULTIPLE) { + if (!ide->blockcount) { + uint32_t cnt = ide->tf->secount ? + ide->tf->secount : 256; + if (cnt > ide->blocksize) + cnt = ide->blocksize; + seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), cnt); + xfer_us = ide_get_xfer_time(ide, 512 * cnt); + ide_set_callback(ide, seek_us + xfer_us); + } else + ide_callback(ide); + } else { + seek_us = hdd_timing_read(&hdd[ide->hdd_num], + ide_get_sector(ide), 1); + xfer_us = ide_get_xfer_time(ide, 512); + ide_set_callback(ide, seek_us + xfer_us); + } + } else + ui_sb_update_icon(SB_HDD | hdd[ide->hdd_num].bus, 0); } } } @@ -1796,11 +1866,11 @@ ide_status(ide_t *ide, ide_t *ide_other, int ch) uint8_t ret; /* Absent and is master or both are absent. */ - if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) { + if (ide->type == IDE_NONE) { /* Bit 7 pulled down, all other bits pulled up, per the spec. */ ret = 0x7f; /* Absent and is slave and master is present. */ - } else if ((ide->type == IDE_NONE) && (ch & 1)) { + } else if (ide->type & IDE_SHADOW) { /* On real hardware, a slave with a present master always returns a status of 0x00. Confirmed by the ATA-3 and ATA-4 specifications. */ @@ -1819,21 +1889,11 @@ ide_readb(uint16_t addr, void *priv) { const ide_board_t *dev = (ide_board_t *) priv; int ch; - int absent = 0; ide_t *ide; - ide_t *ide_other; uint8_t ret = 0xff; ch = dev->cur_dev; ide = ide_drives[ch]; - ide_other = ide_drives[ch ^ 1]; - - /* Absent and is master or both are absent. */ - if ((ide->type == IDE_NONE) && ((ide_drives[ch ^ 1]->type == IDE_NONE) || !(ch & 1))) - absent = 1; - /* Absent and is slave and master is present. */ - else if ((ide->type == IDE_NONE) && (ch & 1)) - absent = 2; switch (addr & 0x7) { case 0x0: /* Data */ @@ -1844,7 +1904,7 @@ ide_readb(uint16_t addr, void *priv) Bit 2 = ABRT (aborted command), Bit 1 = EOM (end of media), and Bit 0 = ILI (illegal length indication). */ case 0x1: /* Error */ - if (absent == 1) + if (ide->type == IDE_NONE) ret = 0x7f; else ret = ide->tf->error; @@ -1864,46 +1924,46 @@ ide_readb(uint16_t addr, void *priv) 0 1 0 Data from host 1 0 1 Status. */ case 0x2: /* Sector count */ - if (absent == 1) + if (ide->type == IDE_NONE) ret = 0x7f; - else if (absent == 2) - ret = ide_other->tf->secount; else ret = ide->tf->secount; break; case 0x3: /* Sector */ - if (absent == 1) + if (ide->type == IDE_NONE) ret = 0x7f; - else if (absent == 2) - ret = (uint8_t) ide_other->sector; else - ret = (uint8_t) ide->sector; + ret = (uint8_t) ide->tf->sector; break; case 0x4: /* Cylinder low */ - if (absent == 1) + if (ide->type == IDE_NONE) ret = 0x7f; - else if (absent == 2) - ret = ide_other->tf->cylinder & 0xff; else ret = ide->tf->cylinder & 0xff; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + ide_log("Cylinder low @ board %i, channel %i: ide->type = %i, " + "ret = %02X\n", ide->board, ide->channel, ide->type, ret); +#endif break; case 0x5: /* Cylinder high */ - if (absent == 1) + if (ide->type == IDE_NONE) ret = 0x7f; - else if (absent == 2) - ret = ide_other->tf->cylinder >> 8; else ret = ide->tf->cylinder >> 8; +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) + pclog("Cylinder high @ board %i, channel %i: ide->type = %i, " + "ret = %02X\n", ide->board, ide->channel, ide->type, ret); +#endif break; case 0x6: /* Drive/Head */ - if (absent == 1) + if (ide->type == IDE_NONE) ret = 0x7f; else - ret = (uint8_t) (ide->head | ((ch & 1) ? 0x10 : 0) | (ide->lba ? 0x40 : 0) | 0xa0); + ret = ide->tf->drvsel | ((ch & 1) ? 0xb0 : 0xa0); break; /* For ATAPI: Bit 5 is DMA ready, but without overlapped or interlaved DMA, it is @@ -1967,7 +2027,7 @@ ide_readw(uint16_t addr, void *priv) break; } -#ifdef IDE_MORE_SPECIFIC_LOGS +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) ide_log("ide_readw(%04X, %08X) = %04X\n", addr, priv, ret); #endif return ret; @@ -2002,7 +2062,7 @@ ide_readl(uint16_t addr, void *priv) break; } -#ifdef IDE_MORE_SPECIFIC_LOGS +#if defined(ENABLE_IDE_LOG) && (ENABLE_IDE_LOG == 2) ide_log("ide_readl(%04X, %08X) = %04X\n", addr, priv, ret); #endif return ret; @@ -2060,13 +2120,13 @@ ide_callback(void *priv) ide_log("ide_callback(%i): %02X\n", ide->channel, ide->command); switch (ide->command) { - case WIN_SEEK ... 0x7F: - chk_chs = !ide->lba; + case WIN_SEEK ... 0x7f: + chk_chs = !ide->tf->lba; if (ide->type == IDE_ATAPI) atapi_error_no_ready(ide); else { - if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->head >= ide->hpc) || - !ide->sector || (ide->sector > ide->spt))) + if (chk_chs && ((ide->tf->cylinder >= ide->tracks) || (ide->tf->head >= ide->hpc) || + !ide->tf->sector || (ide->tf->sector > ide->spt))) err = IDNF_ERR; else { ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2075,7 +2135,7 @@ ide_callback(void *priv) } break; - case WIN_RECAL ... 0x1F: + case WIN_RECAL ... 0x1f: if (ide->type == IDE_ATAPI) atapi_error_no_ready(ide); else { @@ -2091,7 +2151,7 @@ ide_callback(void *priv) ide->tf->error = 1; /*Device passed*/ ide->tf->secount = 1; - ide->sector = 1; + ide->tf->sector = 1; ide_set_signature(ide); @@ -2129,7 +2189,7 @@ ide_callback(void *priv) if (ide->type == IDE_ATAPI) { ide_set_signature(ide); err = ABRT_ERR; - } else if (!ide->lba && (ide->cfg_spt == 0)) + } else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { if (ide->do_initial_read) { @@ -2157,7 +2217,7 @@ ide_callback(void *priv) if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || (bm == NULL)) { ide_log("IDE %i: DMA read aborted (bad device or board)\n", ide->channel); err = ABRT_ERR; - } else if (!ide->lba && (ide->cfg_spt == 0)) { + } else if (!ide->tf->lba && (ide->cfg_spt == 0)) { ide_log("IDE %i: DMA read aborted (SPECIFY failed)\n", ide->channel); err = IDNF_ERR; } else { @@ -2207,7 +2267,7 @@ ide_callback(void *priv) mand error. */ if ((ide->type == IDE_ATAPI) || !ide->blocksize) err = ABRT_ERR; - else if (!ide->lba && (ide->cfg_spt == 0)) + else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { if (ide->do_initial_read) { @@ -2235,7 +2295,7 @@ ide_callback(void *priv) case WIN_WRITE_NORETRY: if (ide->type == IDE_ATAPI) err = ABRT_ERR; - else if (!ide->lba && (ide->cfg_spt == 0)) + else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); @@ -2258,7 +2318,7 @@ ide_callback(void *priv) if ((ide->type == IDE_ATAPI) || ide_boards[ide->board]->force_ata3 || (bm == NULL)) { ide_log("IDE %i: DMA write aborted (bad device type or board)\n", ide->channel); err = ABRT_ERR; - } else if (!ide->lba && (ide->cfg_spt == 0)) { + } else if (!ide->tf->lba && (ide->cfg_spt == 0)) { ide_log("IDE %i: DMA write aborted (SPECIFY failed)\n", ide->channel); err = IDNF_ERR; } else { @@ -2307,7 +2367,7 @@ ide_callback(void *priv) mand error. */ if ((ide->type == IDE_ATAPI) || !ide->blocksize) err = ABRT_ERR; - else if (!ide->lba && (ide->cfg_spt == 0)) + else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { hdd_image_write(ide->hdd_num, ide_get_sector(ide), 1, (uint8_t *) ide->buffer); @@ -2332,7 +2392,7 @@ ide_callback(void *priv) case WIN_VERIFY_ONCE: if (ide->type == IDE_ATAPI) err = ABRT_ERR; - else if (!ide->lba && (ide->cfg_spt == 0)) + else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { ide->tf->pos = 0; @@ -2345,7 +2405,7 @@ ide_callback(void *priv) case WIN_FORMAT: if (ide->type == IDE_ATAPI) err = ABRT_ERR; - else if (!ide->lba && (ide->cfg_spt == 0)) + else if (!ide->tf->lba && (ide->cfg_spt == 0)) err = IDNF_ERR; else { hdd_image_zero(ide->hdd_num, ide_get_sector(ide), ide->tf->secount); @@ -2364,7 +2424,7 @@ ide_callback(void *priv) if (ide->cfg_spt == 0) { /* Only accept after RESET or DIAG. */ ide->cfg_spt = ide->tf->secount; - ide->cfg_hpc = ide->head + 1; + ide->cfg_hpc = ide->tf->head + 1; } ide->command = 0x00; ide->tf->atastat = DRDY_STAT | DSC_STAT; @@ -2863,8 +2923,14 @@ ide_drive_reset(int d) { ide_log("Resetting IDE drive %i...\n", d); + if ((d & 1) && (ide_drives[d]->type == IDE_NONE) && (ide_drives[d ^ 1]->type != IDE_NONE)) { + ide_drives[d]->type = ide_drives[d ^ 1]->type | IDE_SHADOW; + free(ide_drives[d]->tf); + ide_drives[d]->tf = ide_drives[d ^ 1]->tf; + } else + ide_drives[d]->tf->atastat = DRDY_STAT | DSC_STAT; + ide_drives[d]->channel = d; - ide_drives[d]->tf->atastat = DRDY_STAT | DSC_STAT; ide_drives[d]->service = 0; ide_drives[d]->board = d >> 1; ide_drives[d]->selected = !(d & 1); diff --git a/src/include/86box/hdc_ide.h b/src/include/86box/hdc_ide.h index 71ed9e448..291dec303 100644 --- a/src/include/86box/hdc_ide.h +++ b/src/include/86box/hdc_ide.h @@ -36,9 +36,13 @@ #define HDC_QUATERNARY_IRQ 10 enum { - IDE_NONE = 0, - IDE_HDD, - IDE_ATAPI + IDE_NONE = 0, /* Absent master or both. */ + IDE_HDD, /* Hard disk. */ + IDE_ATAPI, /* ATAPI device. */ + IDE_RESERVED, /* Reserved, do not use. */ + IDE_SHADOW, /* Shadow flag, do not assign on is own. */ + IDE_HDD_SHADOW, /* Shadow of a hard disk. */ + IDE_ATAPI_SHADOW /* Shadow of an ATAPI device. */ }; typedef struct ide_tf_s { @@ -59,28 +63,26 @@ typedef struct ide_tf_s { uint8_t status; }; uint8_t error; - uint16_t pad; + uint8_t sector; + union { + uint8_t drvsel; + struct { + uint8_t head :4; + uint8_t pad :2; + uint8_t lba :1; + uint8_t pad0 :1; + }; + }; uint32_t pos; } ide_tf_t; #ifdef _TIMER_H_ typedef struct ide_s { -#ifdef ANCIENT_CODE - /* Task file. */ - uint8_t cylprecomp; - uint8_t secount; - uint16_t cylinder; - uint8_t atastat; - uint8_t error; - uint16_t pad; - uint32_t pos; -#endif - /* The rest. */ uint8_t selected; uint8_t command; uint8_t head; - uint8_t sector; + uint8_t pad; int type; int board; int irqstat; @@ -90,7 +92,6 @@ typedef struct ide_s { int hdd_num; int channel; int sector_pos; - int lba; int reset; int mdma_mode; int do_initial_read; From bb515c3c05eb11e107150c01e711901bda240732 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 Nov 2023 04:12:09 +0100 Subject: [PATCH 18/19] Fixed the accidentally broken LBA mode on IDE hard disks. --- src/disk/hdc_ide.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/disk/hdc_ide.c b/src/disk/hdc_ide.c index 126a9d583..14ceb6504 100644 --- a/src/disk/hdc_ide.c +++ b/src/disk/hdc_ide.c @@ -1544,17 +1544,15 @@ ide_writeb(uint16_t addr, uint8_t val, void *priv) if (!reset) { if (!(ide->tf->atastat & (BSY_STAT | DRQ_STAT))) { - ide->tf->head = val & 0xf; - ide->tf->lba = val & 0x40; - - ide->lba_addr = (ide->lba_addr & 0x0ffffff) | (ide->tf->head << 24); + ide->tf->drvsel = val & 0xef; + ide->lba_addr = (ide->lba_addr & 0x0ffffff) | + (ide->tf->head << 24); } if (!(ide_other->tf->atastat & (BSY_STAT | DRQ_STAT))) { - ide_other->tf->head = val & 0xf; - ide_other->tf->lba = val & 0x40; - - ide_other->lba_addr = (ide_other->lba_addr & 0x0ffffff) | (ide->tf->head << 24); + ide_other->tf->drvsel = val & 0xef; + ide_other->lba_addr = (ide_other->lba_addr & 0x0ffffff) | + (ide->tf->head << 24); } } break; From 06c7567495d6ba1b6af4343fd3051ed8c4a4cba2 Mon Sep 17 00:00:00 2001 From: OBattler Date: Sat, 4 Nov 2023 06:41:57 +0100 Subject: [PATCH 19/19] Mouse capture is no longer possible when the emulator is paused, fixes #3799. --- src/qt/qt_rendererstack.cpp | 5 ++++- src/qt/qt_sdl.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/qt/qt_rendererstack.cpp b/src/qt/qt_rendererstack.cpp index 469dc04de..1b1ed45c3 100644 --- a/src/qt/qt_rendererstack.cpp +++ b/src/qt/qt_rendererstack.cpp @@ -144,7 +144,10 @@ int ignoreNextMouseEvent = 1; void RendererStack::mouseReleaseEvent(QMouseEvent *event) { - if (this->geometry().contains(event->pos()) && (event->button() == Qt::LeftButton) && !mouse_capture && (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && (mouse_input_mode == 0)) { + if (!dopause && this->geometry().contains(event->pos()) && + (event->button() == Qt::LeftButton) && !mouse_capture && + (isMouseDown & 1) && (kbd_req_capture || (mouse_get_buttons() != 0)) && + (mouse_input_mode == 0)) { plat_mouse_capture(1); this->setCursor(Qt::BlankCursor); if (!ignoreNextMouseEvent) diff --git a/src/qt/qt_sdl.c b/src/qt/qt_sdl.c index 166ea88fa..15af4d7b6 100644 --- a/src/qt/qt_sdl.c +++ b/src/qt/qt_sdl.c @@ -627,7 +627,7 @@ sdl_main() case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: { - if ((event.button.button == SDL_BUTTON_LEFT) + if (!dopause && (event.button.button == SDL_BUTTON_LEFT) && !(mouse_capture || video_fullscreen) && event.button.state == SDL_RELEASED && mouse_inside) {