From 7bf6fc384401fb6d636f2866404dafd3dabea063 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Sun, 31 Oct 2021 19:06:16 +0100 Subject: [PATCH] Video changes (ET4000W32/i): Bit 1 is of 0x3DA (read only) is apparently required to make the OS/2 Tseng ET4000W32/i drivers work fine, fixes hangs upon reaching the GUI with said drivers. Avoid division by zero in the blitter of the ET4000W32/i under OS/2. Video changes (PVGA): Fixes mode changes of the PVGA1a, including the built-in video card of the Amstrad 2086/3086. --- src/video/vid_et4000w32.c | 56 ++++++++++++++++++++++++++------------- src/video/vid_paradise.c | 7 +++-- 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/video/vid_et4000w32.c b/src/video/vid_et4000w32.c index 233783439..65dced875 100644 --- a/src/video/vid_et4000w32.c +++ b/src/video/vid_et4000w32.c @@ -169,7 +169,7 @@ et4000w32p_out(uint16_t addr, uint8_t val, void *p) uint32_t add2addr = 0; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { case 0x3c2: @@ -311,7 +311,7 @@ et4000w32p_in(uint16_t addr, void *p) svga_t *svga = &et4000->svga; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) - addr ^= 0x60; + addr ^= 0x60; switch (addr) { case 0x3c5: @@ -335,13 +335,25 @@ et4000w32p_in(uint16_t addr, void *p) case 0x3d5: return svga->crtc[svga->crtcreg]; + case 0x3da: + svga->attrff = 0; + + /*Bit 1 of the Input Status Register is required by OS/2 ET4000W32/I drivers to be set otherwise + the guest will loop infinitely upon reaching the GUI*/ + if (svga->cgastat & 0x01) + svga->cgastat &= ~0x32; + else + svga->cgastat ^= 0x32; + return svga->cgastat; + case 0x210a: case 0x211a: case 0x212a: case 0x213a: case 0x214a: case 0x215a: case 0x216a: case 0x217a: return et4000->index; - case 0x210B: case 0x211B: case 0x212B: case 0x213B: - case 0x214B: case 0x215B: case 0x216B: case 0x217B: - if (et4000->index == 0xec) + case 0x210B: case 0x211B: case 0x212B: case 0x213B: + case 0x214B: case 0x215B: case 0x216B: case 0x217B: + if (et4000->index == 0xec) { return (et4000->regs[0xec] & 0xf) | (et4000->rev << 4); + } if (et4000->index == 0xee) { if (svga->bpp == 8) { if ((svga->gdcreg[5] & 0x60) >= 0x40) @@ -761,7 +773,7 @@ et4000w32p_mmu_read(uint32_t addr, void *p) svga_t *svga = &et4000->svga; int bank; uint8_t temp; - + switch (addr & 0x6000) { case 0x0000: /* MMU 0 */ case 0x2000: /* MMU 1 */ @@ -783,7 +795,7 @@ et4000w32p_mmu_read(uint32_t addr, void *p) if ((addr&0x1fff) + et4000->mmu.base[bank] >= svga->vram_max) return 0xff; - + return svga->vram[(addr&0x1fff) + et4000->mmu.base[bank]]; case 0x6000: @@ -889,7 +901,10 @@ et4000w32_blit_start(et4000w32p_t *et4000) } et4000->acl.pattern_back = et4000->acl.pattern_addr; if (!(et4000->acl.internal.pattern_wrap & 0x40)) { - et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + if ((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) == 0x00) + et4000->acl.pattern_y = (et4000->acl.pattern_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); + else + et4000->acl.pattern_y = (et4000->acl.pattern_addr / (et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7] - 1); et4000->acl.pattern_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.pattern_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.pattern_wrap >> 4) & 7]) - 1); } et4000->acl.pattern_x_back = et4000->acl.pattern_x; @@ -902,7 +917,10 @@ et4000w32_blit_start(et4000w32p_t *et4000) et4000->acl.source_back = et4000->acl.source_addr; if (!(et4000->acl.internal.source_wrap & 0x40)) { - et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + if ((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) == 0x00) + et4000->acl.source_y = (et4000->acl.source_addr / (0x7f + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); + else + et4000->acl.source_y = (et4000->acl.source_addr / (et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1)) & (et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7] - 1); et4000->acl.source_back &= ~(((et4000w32_wrap_x[et4000->acl.internal.source_wrap & 7] + 1) * et4000w32_wrap_y[(et4000->acl.internal.source_wrap >> 4) & 7]) - 1); } et4000->acl.source_x_back = et4000->acl.source_x; @@ -1655,7 +1673,7 @@ static const device_config_t et4000w32p_config[] = const device_t et4000w32_device = { - "Tseng Labs ET4000/w32", + "Tseng Labs ET4000/w32 ISA", DEVICE_ISA | DEVICE_AT, ET4000W32, et4000w32p_init, et4000w32p_close, NULL, { et4000w32_available }, @@ -1666,7 +1684,7 @@ const device_t et4000w32_device = const device_t et4000w32_onboard_device = { - "Tseng Labs ET4000/w32 (On-board)", + "Tseng Labs ET4000/w32 (ISA) (On-Board)", DEVICE_ISA | DEVICE_AT, ET4000W32, et4000w32p_init, et4000w32p_close, NULL, { et4000w32_available }, @@ -1677,7 +1695,7 @@ const device_t et4000w32_onboard_device = const device_t et4000w32i_isa_device = { - "Tseng Labs ET4000/w32i ISA", + "Tseng Labs ET4000/w32i Rev. B ISA", DEVICE_ISA | DEVICE_AT, ET4000W32I, et4000w32p_init, et4000w32p_close, NULL, { et4000w32i_isa_available }, @@ -1688,7 +1706,7 @@ const device_t et4000w32i_isa_device = const device_t et4000w32i_vlb_device = { - "Tseng Labs ET4000/w32i VLB", + "Tseng Labs ET4000/w32i Rev. B VLB", DEVICE_VLB, ET4000W32I, et4000w32p_init, et4000w32p_close, NULL, { et4000w32i_vlb_available }, @@ -1721,7 +1739,7 @@ const device_t et4000w32p_revc_pci_device = const device_t et4000w32p_noncardex_vlb_device = { - "Tseng Labs ET4000/w32p VLB", + "Tseng Labs ET4000/w32p Rev. D VLB", DEVICE_VLB, ET4000W32P, et4000w32p_init, et4000w32p_close, NULL, { et4000w32p_noncardex_available }, @@ -1732,7 +1750,7 @@ const device_t et4000w32p_noncardex_vlb_device = const device_t et4000w32p_noncardex_pci_device = { - "Tseng Labs ET4000/w32p PCI", + "Tseng Labs ET4000/w32p Rev. D PCI", DEVICE_PCI, ET4000W32P, et4000w32p_init, et4000w32p_close, NULL, { et4000w32p_noncardex_available }, @@ -1743,7 +1761,7 @@ const device_t et4000w32p_noncardex_pci_device = const device_t et4000w32p_cardex_vlb_device = { - "Tseng Labs ET4000/w32p VLB (Cardex)", + "Tseng Labs ET4000/w32p Rev. D VLB (Cardex)", DEVICE_VLB, ET4000W32P_CARDEX, et4000w32p_init, et4000w32p_close, NULL, { et4000w32p_cardex_available }, @@ -1754,7 +1772,7 @@ const device_t et4000w32p_cardex_vlb_device = const device_t et4000w32p_cardex_pci_device = { - "Tseng Labs ET4000/w32p PCI (Cardex)", + "Tseng Labs ET4000/w32p Rev. D PCI (Cardex)", DEVICE_PCI, ET4000W32P_CARDEX, et4000w32p_init, et4000w32p_close, NULL, { et4000w32p_cardex_available }, @@ -1765,7 +1783,7 @@ const device_t et4000w32p_cardex_pci_device = const device_t et4000w32p_vlb_device = { - "Tseng Labs ET4000/w32p VLB (Diamond)", + "Tseng Labs ET4000/w32p Rev. D VLB (Diamond Stealth32)", DEVICE_VLB, ET4000W32P_DIAMOND, et4000w32p_init, et4000w32p_close, NULL, { et4000w32p_available }, @@ -1776,7 +1794,7 @@ const device_t et4000w32p_vlb_device = const device_t et4000w32p_pci_device = { - "Tseng Labs ET4000/w32p PCI (Diamond)", + "Tseng Labs ET4000/w32p Rev. D PCI (Diamond Stealth32)", DEVICE_PCI, ET4000W32P_DIAMOND, et4000w32p_init, et4000w32p_close, NULL, { et4000w32p_available }, diff --git a/src/video/vid_paradise.c b/src/video/vid_paradise.c index 5fd0aada0..107a1773f 100644 --- a/src/video/vid_paradise.c +++ b/src/video/vid_paradise.c @@ -231,7 +231,7 @@ uint8_t paradise_in(uint16_t addr, void *p) case 0x3cf: if (svga->gdcaddr >= 9 && svga->gdcaddr <= 0x0e) { - if ((paradise->pr5 & 7) != 5) + if (paradise->pr5 & 0x10) return 0xff; } switch (svga->gdcaddr) { @@ -354,8 +354,11 @@ void paradise_recalctimings(svga_t *svga) } if (paradise->type < WD90C30) { - if (svga->bpp >= 8 && !svga->lowres) + if (svga->bpp >= 8 && !svga->lowres) { + if ((svga->crtc[0x17] == 0xc2) && (svga->crtc[0x14] & 0x40)) + paradise->check = 1; svga->render = svga_render_8bpp_highres; + } } else { if (svga->bpp >= 8 && !svga->lowres) { if (svga->bpp == 16) {