From 6d5de8bfbb165238768bec2d4c74baa109269d55 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sat, 2 Jan 2021 16:49:55 +0200 Subject: [PATCH] PCI graphics/sound card updates --- expansion.cpp | 29 +++ gfxboard.cpp | 419 +++++++++++++++++++++++++++++------- include/gfxboard.h | 4 +- include/pci_hw.h | 2 +- include/rommgr.h | 2 + pcem/pcemglue.cpp | 11 +- pcem/vid_cl5429.cpp | 18 -- pcem/vid_s3.cpp | 2 +- pcem/vid_s3_virge.cpp | 40 +++- pcem/vid_svga.cpp | 4 +- pcem/vid_voodoo_banshee.cpp | 71 ++++-- pcem/vid_voodoo_banshee.h | 1 + pci.cpp | 26 ++- qemuvga/es1370.cpp | 7 +- sndboard.cpp | 3 + 15 files changed, 502 insertions(+), 137 deletions(-) diff --git a/expansion.cpp b/expansion.cpp index 3ed9ce27..80861e80 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -4129,6 +4129,15 @@ static const struct expansionsubromtype a2090_sub[] = { }; #endif +static const struct expansionboardsettings voodoo_settings[] = { + { + _T("Direct VRAM access in little endian modes"), _T("directvram") + }, + { + NULL + } +}; + static const struct expansionsubromtype a2091_sub[] = { { _T("DMAC-01"), _T("dmac01"), 0, @@ -5824,8 +5833,28 @@ const struct expansionromtype expansionroms[] = { _T("vooodoo3_3k"), _T("Voodoo 3 3000"), _T("3dfx"), NULL, NULL, NULL, NULL, ROMTYPE_VOODOO3 | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, false, NULL, 0, + false, EXPANSIONTYPE_RTG, + 0, 0, 0, false, NULL, + false, 0, voodoo_settings + }, +#if 0 + { + _T("vooodoo5_5k"), _T("Voodoo 5 5500"), _T("3dfx"), + NULL, NULL, NULL, NULL, ROMTYPE_VOODOO5 | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, false, + NULL, 0, + false, EXPANSIONTYPE_RTG, + 0, 0, 0, false, NULL, + false, 0, voodoo_settings + }, +#endif +#if 0 + { + _T("s3virge"), _T("Virge"), _T("S3"), + NULL, NULL, NULL, NULL, ROMTYPE_S3VIRGE | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, false, + NULL, 0, false, EXPANSIONTYPE_RTG }, +#endif { _T("x86vga"), _T("x86 VGA"), NULL, NULL, NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true, diff --git a/gfxboard.cpp b/gfxboard.cpp index a87297a4..a4d0fef8 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -133,91 +133,91 @@ static const struct gfxboard boards[] = { { GFXBOARD_ID_A2410, - _T("A2410"), _T("Commodore"), _T("A2410"), + _T("A2410 [Zorro II]"), _T("Commodore"), _T("A2410"), 1030, 0, 0, 0x00000000, 0x00200000, 0x00200000, 0x10000, 0, 0, 2, false, 0, 0xc1, &a2410_func }, { GFXBOARD_ID_SPECTRUM_Z2, - _T("Spectrum 28/24 Zorro II"), _T("Great Valley Products"), _T("Spectrum28/24_Z2"), + _T("Spectrum 28/24 [Zorro II]"), _T("Great Valley Products"), _T("Spectrum28/24_Z2"), BOARD_MANUFACTURER_SPECTRUM, BOARD_MODEL_MEMORY_SPECTRUM, BOARD_MODEL_REGISTERS_SPECTRUM, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 6, true, 0, 0, NULL, &gd5428_swapped_device }, { GFXBOARD_ID_SPECTRUM_Z3, - _T("Spectrum 28/24 Zorro III"), _T("Great Valley Products"), _T("Spectrum28/24_Z3"), + _T("Spectrum 28/24 [Zorro III]"), _T("Great Valley Products"), _T("Spectrum28/24_Z3"), BOARD_MANUFACTURER_SPECTRUM, BOARD_MODEL_MEMORY_SPECTRUM, BOARD_MODEL_REGISTERS_SPECTRUM, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 3, 6, true, 0, 0, NULL, &gd5428_swapped_device }, { GFXBOARD_ID_PICCOLO_Z2, - _T("Piccolo Zorro II"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z2"), + _T("Piccolo [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z2"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 6, true, 0, 0, NULL, &gd5426_swapped_device }, { GFXBOARD_ID_PICCOLO_Z3, - _T("Piccolo Zorro III"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z3"), + _T("Piccolo [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("Piccolo_Z3"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, 0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 3, 6, true, 0, 0, NULL, &gd5426_swapped_device }, { GFXBOARD_ID_SD64_Z2, - _T("Piccolo SD64 Zorro II"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z2"), + _T("Piccolo SD64 [Zorro II]"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z2"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, 0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 2, 6, true, 0, 0, NULL, &gd5434_vlb_swapped_device }, { GFXBOARD_ID_SD64_Z3, - _T("Piccolo SD64 Zorro III"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z3"), + _T("Piccolo SD64 [Zorro III]"), _T("Ingenieurbüro Helfrich"), _T("PiccoloSD64_Z3"), BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, 0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 3, 6, true, 0, 0, NULL, &gd5434_vlb_swapped_device }, { GFXBOARD_ID_CV64_Z3, - _T("CyberVision 64 Zorro III"), _T("Phase 5"), _T("CV64_Z3"), + _T("CyberVision 64 [Zorro III]"), _T("Phase 5"), _T("CV64_Z3"), 8512, 34, 0, 0x00000000, 0x00200000, 0x00400000, 0x20000000, 0, 3, 2, false, 0, 0, NULL, &s3_cybervision_trio64_device, 0x40 }, { GFXBOARD_ID_CV643D_Z2, - _T("CyberVision 64/3D Zorro II"), _T("Phase 5"), _T("CV643D_Z2"), + _T("CyberVision 64/3D [Zorro II]"), _T("Phase 5"), _T("CV643D_Z2"), 8512, 67, 0, 0x00000000, 0x00400000, 0x00400000, 0x00400000, 0, 2, 2, false, 0, 0, NULL, &s3_virge_device, 0xc0 }, { GFXBOARD_ID_CV643D_Z3, - _T("CyberVision 64/3D Zorro III"), _T("Phase 5"), _T("CV643D_Z3"), + _T("CyberVision 64/3D [Zorro III]"), _T("Phase 5"), _T("CV643D_Z3"), 8512, 67, 0, 0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 3, 2, false, 0, 0, NULL, &s3_virge_device, 0x40 }, { GFXBOARD_ID_PICASSO2, - _T("Picasso II"), _T("Village Tronic"), _T("PicassoII"), + _T("Picasso II [Zorro II]"), _T("Village Tronic"), _T("PicassoII"), BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII, 0x00020000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 0, false, 0, 0, NULL, &gd5426_device }, { GFXBOARD_ID_PICASSO2PLUS, - _T("Picasso II+"), _T("Village Tronic"), _T("PicassoII+"), + _T("Picasso II+ [Zorro II]"), _T("Village Tronic"), _T("PicassoII+"), BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII, 0x00100000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 2, false, 0, 0, NULL, &gd5428_device }, { GFXBOARD_ID_PICASSO4_Z2, - _T("Picasso IV Zorro II"), _T("Village Tronic"), _T("PicassoIV_Z2"), + _T("Picasso IV [Zorro II]"), _T("Village Tronic"), _T("PicassoIV_Z2"), BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, BOARD_MODEL_REGISTERS_PICASSOIV, 0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5446, 2, 2, false, ROMTYPE_PICASSOIV, @@ -225,7 +225,7 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_PICASSO4_Z3, - _T("Picasso IV Zorro III"), _T("Village Tronic"), _T("PicassoIV_Z3"), + _T("Picasso IV [Zorro III]"), _T("Village Tronic"), _T("PicassoIV_Z3"), BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, 0, 0x00000000, 0x00400000, 0x00400000, 0x02000000, CIRRUS_ID_CLGD5446, 3, 2, false, ROMTYPE_PICASSOIV, @@ -233,7 +233,7 @@ static const struct gfxboard boards[] = }, { GFXBOARD_ID_HARLEQUIN, - _T("Harlequin"), _T("ACS"), _T("Harlequin_PAL"), + _T("Harlequin [Zorro II]"), _T("ACS"), _T("Harlequin_PAL"), 2118, 100, 0, 0x00000000, 0x00200000, 0x00200000, 0x10000, 0, 0, 2, false, ROMTYPE_HARLEQUIN, 0xc2, &harlequin_func @@ -247,16 +247,35 @@ static const struct gfxboard boards[] = }, #endif { - GFXBOARD_ID_VOODOO3, - _T("Voodoo 3 3000"), _T("3dfx"), _T("V3_3000"), + GFXBOARD_ID_VOODOO3_PCI, + _T("Voodoo 3 3000 [PCI]"), _T("3dfx"), _T("V3_3000"), 0, 0, 0, 0x00000000, 0x01000000, 0x01000000, 0x01000000, 0, 0, -1, false, ROMTYPE_VOODOO3, - 0, NULL, &voodoo_3_3000_device,0, true + 0, NULL, &voodoo_3_3000_device, 0, true }, +#if 0 + { + GFXBOARD_ID_VOODOO5_PCI, + _T("Voodoo 5 5500 [PCI] (Basic 2D only, Fast direct VRAM access)"), _T("3dfx"), _T("V5_5500"), + 0, 0, 0, + 0x00000000, 0x04000000, 0x04000000, 0x04000000, 0, 0, -1, false, + ROMTYPE_VOODOO5, + 0, NULL, &voodoo_5_5500_device, 0, true + }, +#endif +#if 0 + { + GFXBOARD_ID_S3VIRGE_PCI, + _T("Virge [PCI]"), _T("S3"), _T("S3VIRGE_PCI"), + 0, 0, 0, + 0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 0, -1, false, + 0, 0, NULL, &s3_virge_device, 0, true + }, +#endif { GFXBOARD_ID_VGA, - _T("x86 bridgeboard VGA"), _T("x86"), _T("VGA"), + _T("x86 bridgeboard VGA [ISA]"), _T("x86"), _T("VGA"), 0, 0, 0, 0x00000000, 0x00100000, 0x00200000, 0x00000000, CIRRUS_ID_CLGD5426, 0, 0, false, ROMTYPE_x86_VGA @@ -272,11 +291,11 @@ struct rtggfxboard int rtg_index; int monitor_id; struct rtgboardconfig *rbc; - TCHAR memorybankname[40]; - TCHAR memorybanknamenojit[40]; - TCHAR wbsmemorybankname[40]; - TCHAR lbsmemorybankname[40]; - TCHAR regbankname[40]; + TCHAR memorybankname[100]; + TCHAR memorybanknamenojit[100]; + TCHAR wbsmemorybankname[100]; + TCHAR lbsmemorybankname[100]; + TCHAR regbankname[100]; int configured_mem, configured_regs; const struct gfxboard *board; @@ -349,7 +368,7 @@ struct rtggfxboard addrbank gfxboard_bank_special_pcem; addrbank gfxboard_bank_bios; - addrbank *old_pci_bank; + addrbank *original_pci_bank; addrbank *gfxmem_bank; uae_u8 *vram_back; @@ -373,6 +392,7 @@ struct rtggfxboard uae_u32 bios_mask; int lfbbyteswapmode; struct pci_board_state *pcibs; + bool pcem_direct; void *userdata; }; @@ -478,7 +498,7 @@ static const addrbank tmpl_gfxboard_bank_vram_pcem = { static const addrbank tmpl_gfxboard_bank_vram_normal_pcem = { gfxboard_lget_vram_normal_pcem, gfxboard_wget_vram_normal_pcem, gfxboard_bget_vram_normal_pcem, gfxboard_lput_vram_normal_pcem, gfxboard_wput_vram_normal_pcem, gfxboard_bput_vram_normal_pcem, - gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (DIRECT)"), + gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (NOSWAP)"), gfxboard_lget_vram_normal_pcem, gfxboard_wget_vram_normal_pcem, ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE }; @@ -597,7 +617,6 @@ static const addrbank tmpl_gfxboard_bank_bios = { ABFLAG_ROM | ABFLAG_SAFE, S_READ, S_WRITE }; - static void ew(struct rtggfxboard *gb, int addr, uae_u32 value) { addr &= 0xffff; @@ -653,19 +672,19 @@ extern void voodoo_callback(void *p); // PCEM static void pcem_flush(struct rtggfxboard* gb, int index) { -#if 0 - uae_u8 **buf; - uae_u8 *start; - int cnt = picasso_getwritewatch(index, gb->vram_start_offset, &buf, &start); - if (cnt < 0) { - gb->pcemdev->force_redraw(gb->pcemobject); - } else { - for (int i = 0; i < cnt; i++) { - int offset = buf[i] - start; - pcem_linear_mark(offset); + if (gb->pcem_direct) { + uae_u8 **buf; + uae_u8 *start; + int cnt = picasso_getwritewatch(index, gb->vram_start_offset, &buf, &start); + if (cnt < 0) { + gb->pcemdev->force_redraw(gb->pcemobject); + } else { + for (int i = 0; i < cnt; i++) { + int offset = buf[i] - start; + pcem_linear_mark(offset); + } } } -#endif } void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) @@ -688,22 +707,38 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h) } } } - //picasso_getwritewatch(i, 0, NULL, NULL); + if (gb->pcem_direct) { + picasso_getwritewatch(i, 0, NULL, NULL); + } } } } static int gfxboard_pcem_poll(struct rtggfxboard *gb) { + static int toggle; if (!gb->vram) return 0; - return svga_poll(gb->pcemobject2); + // 1, 3, 1, 3,.. because some software needs to see hsync period. + int v = svga_poll(gb->pcemobject2); + if (toggle) { + if (!v) { + v |= svga_poll(gb->pcemobject2); + if (!v) { + v |= svga_poll(gb->pcemobject2); + } + } + toggle = 0; + } else { + toggle = 1; + } + return v; } static void gfxboard_rethink(void) { for (int i = 0; i < MAX_RTG_BOARDS; i++) { - struct rtggfxboard* gb = &rtggfxboards[i]; + struct rtggfxboard *gb = &rtggfxboards[i]; if (gb->pcemdev && gb->pcemobject && gb->gfxboard_intreq && gb->gfxboard_intena) { int irq = 0; if (gb->board->irq > 0) { @@ -733,7 +768,9 @@ static void gfxboard_hsync_handler(void) if (gb->pcemdev && gb->pcemobject && !gb->pcem_vblank) { static int pollcnt; int total = svga_get_vtotal(); - int pollsize = (p96syncrate << 8) / (total ? total : 1); + if (total <= 0) + total = p96syncrate; + int pollsize = (total << 8) / p96syncrate; pollcnt += pollsize; while (pollcnt >= 256) { if (gfxboard_pcem_poll(gb)) { @@ -768,9 +805,11 @@ static void reinit_vram(struct rtggfxboard *gb, uaecptr vram, bool direct) gb->vramend += gb->vram_start_offset; if (gb->pcemdev) { void svga_setvram(void *p, uint8_t *vram); - void voodoo_update_vram(void *p); svga_setvram(gb->pcemobject2, gb->vram); - voodoo_update_vram(gb->pcemobject); + if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) { + void voodoo_update_vram(void *p); + voodoo_update_vram(gb->pcemobject); + } } } @@ -3469,39 +3508,64 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v) } } -static void pci_change_config(struct pci_board_state *pci) +void gfxboard_voodoo_lfb_endianswap(int m) { - struct rtggfxboard *gb = (struct rtggfxboard*)pci->userdata; - if (pci->memory_map_active) { - // direct access, bypass PCI emulation redirection for performance reasons - if (pci_validate_address(pci->bar[1] + pci->bridge->memory_start_offset, 0x02000000, false)) { - reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true); - gb->old_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset); - //map_banks(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0); - //map_banks(&gb->gfxboard_bank_memory, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0); - //memory_map_dump(); - } else { - reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false); + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtggfxboard *gb = &rtggfxboards[i]; + if (gb->active && gb->board->pci) { + if (gb->lfbbyteswapmode != m) { + gb->lfbbyteswapmode = m; + if (gb->original_pci_bank) { + if (!m) { + gb->pcem_direct = true; + write_log(_T("Voodoo direct VRAM mode\n")); + map_banks(gb->gfxmem_bank, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0); + map_banks(gb->gfxmem_bank, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0); + } else { + gb->pcem_direct = false; + write_log(_T("Voodoo indirect VRAM mode (%d)\n"), m); + map_banks(gb->original_pci_bank, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0); + map_banks(gb->original_pci_bank, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0); + } + } + } + return; } } } -void gfxboard_voodoo_lfb_endianswap(int m) +static void pci_change_config(struct pci_board_state *pci) { - for (int i = 0; i < MAX_RTG_BOARDS; i++) { - struct rtggfxboard *gb = &rtggfxboards[i]; - if (gb->active && gb->board->romtype == ROMTYPE_VOODOO3) { - gb->lfbbyteswapmode = m; - if (gb->old_pci_bank && 0) { - if (0) { - map_banks(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0); - map_banks(&gb->gfxboard_bank_memory, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0); - } else { - map_banks(gb->old_pci_bank, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0); - map_banks(gb->old_pci_bank, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0); + struct rtggfxboard *gb = (struct rtggfxboard *)pci->userdata; + struct romconfig *rc = get_device_romconfig(&currprefs, gb->board->romtype, 0); + if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI) { + if (pci->memory_map_active) { + // direct access, bypass PCI emulation redirection for performance reasons + if (rc && (rc->device_settings & 1) && pci_validate_address(pci->bar[1] + pci->bridge->memory_start_offset, 0x02000000, false)) { + if (!gb->original_pci_bank) { + gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset); } + reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true); + int m = gb->lfbbyteswapmode; + gb->lfbbyteswapmode = -1; + gfxboard_voodoo_lfb_endianswap(m); + } else { + reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false); } - return; + } + } else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) { + if (pci->memory_map_active) { + // direct access, bypass PCI emulation redirection for performance reasons + if (pci_validate_address(pci->bar[1] + pci->bridge->memory_start_offset, gb->rbc->rtgmem_size, false)) { + reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true); + gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset); + } else { + reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false); + } + } + } else if (gb->rbc->rtgmem_type == GFXBOARD_ID_S3VIRGE_PCI) { + if (pci->memory_map_active) { + reinit_vram(gb, pci->bar[0] + pci->bridge->memory_start_offset, false); } } } @@ -3688,6 +3752,13 @@ static void REGPARAM2 voodoo3_mb1_bput(struct pci_board_state *pcibs, uaecptr ad int m = gb->lfbbyteswapmode; addr -= pcibs->bar[1]; addr &= 0x00ffffff; + switch (m) + { + case 1: + case 3: + addr ^= 3; + break; + } pcem_linear_write_b(addr, b, pcem_mapping_linear_priv); //do_put_mem_byte((uae_u8*)(addr + gb->vram), b); } @@ -3697,6 +3768,13 @@ static uae_u32 REGPARAM2 voodoo3_mb1_bget(struct pci_board_state *pcibs, uaecptr int m = gb->lfbbyteswapmode; addr -= pcibs->bar[1]; addr &= 0x00ffffff; + switch (m) + { + case 1: + case 3: + addr ^= 3; + break; + } uae_u32 v = pcem_linear_read_b(addr, pcem_mapping_linear_priv); //uae_u32 v = do_get_mem_byte((uae_u8*)(addr + gb->vram)); return v; @@ -3706,6 +3784,8 @@ static uae_u32 REGPARAM2 voodoo3_mb1_bget(struct pci_board_state *pcibs, uaecptr static uae_u32 REGPARAM2 voodoo3_bios_bget(struct pci_board_state *pcibs, uaecptr addr) { struct rtggfxboard* gb = getgfxboard(addr); + if (!gb->bios) + return 0; addr &= gb->bios_mask; return gb->bios[addr]; } @@ -3737,11 +3817,190 @@ static const struct pci_board voodoo3_pci_board = { NULL }, { NULL }, { voodoo3_bios_lget, voodoo3_bios_wget, voodoo3_bios_bget, NULL, NULL, NULL }, + { NULL } }, true, get_pci_pcem, put_pci_pcem, pci_change_config }; +void gfxboard_s3virge_lfb_endianswap(int m) +{ + for (int i = 0; i < MAX_RTG_BOARDS; i++) { + struct rtggfxboard *gb = &rtggfxboards[i]; + if (gb->active && gb->board->pci) { + gb->lfbbyteswapmode = m; + } + } +} + +static int s3virgeaddr(struct pci_board_state *pcibs, uaecptr *addrp) +{ + uaecptr addr = *addrp; + int swap = 0; + if (addr >= pcibs->bar[0] + 0x02000000 && addr < pcibs->bar[0] + 0x03000000) { + // LFB BE + addr = ((addr - pcibs->bar[0]) & 0x3fffff) + pcibs->bar[0]; + swap = -1; + } else if (addr >= pcibs->bar[0] + 0x03000000 && addr < pcibs->bar[0] + 0x04000000) { + // MMIO BE + addr = ((addr - pcibs->bar[0]) & 0xffff) + pcibs->bar[0] + 0x01000000; + swap = 1; + } else if (addr >= pcibs->bar[0] + 0x00000000 && addr < pcibs->bar[0] + 0x01000000) { + // LFB LE + addr = ((addr - pcibs->bar[0]) & 0x3fffff) + pcibs->bar[0]; + } else if (addr >= pcibs->bar[0] + 0x01000000 && addr < pcibs->bar[0] + 0x02000000) { + // MMIO LE + addr = ((addr - pcibs->bar[0]) & 0xffff) + pcibs->bar[0] + 0x01000000; + } + *addrp = addr; + return swap; +} + +static void REGPARAM2 s3virge_mb0_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b) +{ + int swap = s3virgeaddr(pcibs, &addr); + if (swap > 0) { + b = do_byteswap_32(b); + } else if (swap < 0) { + struct rtggfxboard *gb = getgfxboard(addr); + int m = gb->lfbbyteswapmode; + switch (m) + { + case 0: + default: + break; + case 1: + b = do_byteswap_32(b); + b = (b >> 16) | (b << 16); + break; + } + } + put_mem_pcem(addr, b, 2); +} +static void REGPARAM2 s3virge_mb0_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b) +{ + int swap = s3virgeaddr(pcibs, &addr); + if (swap > 0) { + b = do_byteswap_16(b); + } else if (swap < 0) { + struct rtggfxboard *gb = getgfxboard(addr); + int m = gb->lfbbyteswapmode; + switch (m) + { + case 0: + default: + break; + case 1: + b = do_byteswap_16(b); + break; + } + } + put_mem_pcem(addr, b, 1); +} +static void REGPARAM2 s3virge_mb0_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b) +{ + int swap = s3virgeaddr(pcibs, &addr); + put_mem_pcem(addr, b, 0); +} +static uae_u32 REGPARAM2 s3virge_mb0_lget(struct pci_board_state *pcibs, uaecptr addr) +{ + int swap = s3virgeaddr(pcibs, &addr); + uae_u32 v = get_mem_pcem(addr, 2); + if (swap > 0) { + v = do_byteswap_32(v); + } else if (swap < 0) { + struct rtggfxboard *gb = getgfxboard(addr); + int m = gb->lfbbyteswapmode; + switch (m) + { + case 0: + default: + break; + case 1: + v = (v >> 16) | (v << 16); + v = do_byteswap_32(v); + break; + } + } + return v; +} +static uae_u32 REGPARAM2 s3virge_mb0_wget(struct pci_board_state *pcibs, uaecptr addr) +{ + int swap = s3virgeaddr(pcibs, &addr); + uae_u32 v = get_mem_pcem(addr, 1); + if (swap > 0) { + v = do_byteswap_16(v); + } else if (swap < 0) { + struct rtggfxboard *gb = getgfxboard(addr); + int m = gb->lfbbyteswapmode; + switch (m) + { + case 0: + default: + break; + case 1: + v = do_byteswap_16(v); + break; + } + } return v; +} +static uae_u32 REGPARAM2 s3virge_mb0_bget(struct pci_board_state *pcibs, uaecptr addr) +{ + int swap = s3virgeaddr(pcibs, &addr); + uae_u32 v = get_mem_pcem(addr, 0); + return v; +} + +static void REGPARAM2 s3virge_io_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b) +{ + put_io_pcem(addr, b, 2); +} +static void REGPARAM2 s3virge_io_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b) +{ + put_io_pcem(addr, b, 1); +} +static void REGPARAM2 s3virge_io_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b) +{ + //write_log(_T("s3virge_io_bput(%08x,%02x) PC=%08x\n"), addr, b & 0xff, M68K_GETPC); + put_io_pcem(addr, b, 0); +} +static uae_u32 REGPARAM2 s3virge_io_lget(struct pci_board_state *pcibs, uaecptr addr) +{ + return get_io_pcem(addr, 2); +} +static uae_u32 REGPARAM2 s3virge_io_wget(struct pci_board_state *pcibs, uaecptr addr) +{ + return get_io_pcem(addr, 1); +} +static uae_u32 REGPARAM2 s3virge_io_bget(struct pci_board_state *pcibs, uaecptr addr) +{ + uae_u32 v = get_io_pcem(addr, 0); + //write_log(_T("s3virge_io_bget(%08x,%02x) PC=%08x\n"), addr, v & 0xff, M68K_GETPC); + return v; +} + +static const struct pci_config s3virge_pci_config = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0 } +}; + +static const struct pci_board s3virge_pci_board = +{ + _T("S3VIRGE"), + &s3virge_pci_config, NULL, NULL, NULL, NULL, + { + { s3virge_mb0_lget, s3virge_mb0_wget, s3virge_mb0_bget, s3virge_mb0_lput, s3virge_mb0_wput, s3virge_mb0_bput }, + { NULL }, + { NULL }, + { NULL }, + { NULL }, + { NULL }, + { voodoo3_bios_lget, voodoo3_bios_wget, voodoo3_bios_bget, NULL, NULL, NULL }, + { s3virge_io_lget, s3virge_io_wget, s3virge_io_bget, s3virge_io_lput, s3virge_io_wput, s3virge_io_bput } + }, + true, + get_pci_pcem, put_pci_pcem, pci_change_config +}; int gfxboard_get_index_from_id(int id) @@ -3768,9 +4027,9 @@ int gfxboard_get_id_from_index(int index) const TCHAR *gfxboard_get_name(int type) { if (type == GFXBOARD_UAE_Z2) - return _T("UAE Zorro II"); + return _T("UAE [Zorro II]"); if (type == GFXBOARD_UAE_Z3) - return _T("UAE Zorro III"); + return _T("UAE [Zorro III]"); const struct gfxboard *b = find_board(type); if (!b) return NULL; @@ -4065,7 +4324,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) { static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 }; aci->parent_romtype = parent; - } else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3) { + } else if (gb->board->pci) { static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 }; aci->parent_romtype = parent; } else { @@ -4130,20 +4389,23 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) gb->active = true; - if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3) { + if (gb->board->pci) { TCHAR path[MAX_DPATH]; fetch_rompath(path, sizeof path / sizeof(TCHAR)); - _tcscat(path, _T("voodoo3.rom")); + if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) + _tcscat(path, _T("voodoo3.rom")); + else + _tcscat(path, _T("s3virge.rom")); struct zfile *zf = read_rom_name(path); if (zf) { gb->bios = xcalloc(uae_u8, 65536); gb->bios_mask = 65535; int size = zfile_fread(gb->bios, 1, 65536, zf); zfile_fclose(zf); - write_log(_T("Voodoo 3 BIOS load, %d bytes\n"), size); + write_log(_T("PCI RTG board BIOS load, %d bytes\n"), size); } else { - error_log(_T("Voodoo 3 BIOS ROM (\\voodoo3.rom) failed to load!\n")); + error_log(_T("PCI RTG board BIOS ROM (%s) failed to load!\n"), path); } gb->gfxboard_bank_memory.bget = gfxboard_bget_mem; gb->gfxboard_bank_memory.bput = gfxboard_bput_mem; @@ -4154,7 +4416,10 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) gb->configured_regs = 1; struct pci_bridge *b = pci_bridge_get(); if (b) { - gb->pcibs = pci_board_add(b, &voodoo3_pci_board, -1, 0, aci, gb); + if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) + gb->pcibs = pci_board_add(b, &voodoo3_pci_board, -1, 0, aci, gb); + else + gb->pcibs = pci_board_add(b, &s3virge_pci_board, -1, 0, aci, gb); } gb->gfxboard_intena = 1; return true; diff --git a/include/gfxboard.h b/include/gfxboard.h index e27b842e..e86d1bac 100644 --- a/include/gfxboard.h +++ b/include/gfxboard.h @@ -76,7 +76,9 @@ int pcem_getvramsize(void); #define GFXBOARD_ID_CV643D_Z2 15 #define GFXBOARD_ID_CV643D_Z3 16 #define GFXBOARD_ID_CV64_Z3 17 -#define GFXBOARD_ID_VOODOO3 18 +#define GFXBOARD_ID_VOODOO3_PCI 18 +#define GFXBOARD_ID_S3VIRGE_PCI 19 +#define GFXBOARD_ID_VOODOO5_PCI 20 struct gfxboard_mode diff --git a/include/pci_hw.h b/include/pci_hw.h index 2cbcdfc1..01f55b29 100644 --- a/include/pci_hw.h +++ b/include/pci_hw.h @@ -50,7 +50,7 @@ struct pci_board pci_dev_free free; pci_dev_reset reset; pci_dev_hsync hsync; - pci_addrbank bars[MAX_PCI_BARS]; + pci_addrbank bars[MAX_PCI_BARS + 1]; bool dont_mask_io; pci_get_config_func pci_get_config; pci_put_config_func pci_put_config; diff --git a/include/rommgr.h b/include/rommgr.h index 4e7a3ac2..71e0b63f 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -198,6 +198,8 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size); #define ROMTYPE_SYNTHESIS 0x00100086 #define ROMTYPE_MASTFB 0x00100087 #define ROMTYPE_VOODOO3 0x00100088 +#define ROMTYPE_S3VIRGE 0x00100089 +#define ROMTYPE_VOODOO5 0x0010008a #define ROMTYPE_NOT 0x00800000 #define ROMTYPE_QUAD 0x01000000 diff --git a/pcem/pcemglue.cpp b/pcem/pcemglue.cpp index d01a1a06..6cbd621d 100644 --- a/pcem/pcemglue.cpp +++ b/pcem/pcemglue.cpp @@ -87,7 +87,7 @@ void pclog(char const *format, ...) va_start(parms, format); char buf[256]; vsprintf(buf, format, parms); - write_log("PCEMLOG: %s", buf); + write_log("%s", buf); va_end(parms); } @@ -428,7 +428,7 @@ void (*pcem_linear_write_l)(uint32_t addr, uint32_t val, void *priv); #define MAX_PCEMMAPPINGS 10 static mem_mapping_t *pcemmappings[MAX_PCEMMAPPINGS]; #define PCEMMAPBLOCKSIZE 0x10000 -#define MAX_PCEMMAPBLOCKS (0x10000000 / PCEMMAPBLOCKSIZE) +#define MAX_PCEMMAPBLOCKS (0x80000000 / PCEMMAPBLOCKSIZE) mem_mapping_t *pcemmap[MAX_PCEMMAPBLOCKS]; static uint8_t dummy_bread(uint32_t addr, void *p) @@ -779,7 +779,7 @@ void thread_destroy_mutex(mutex_t* _mutex) static mem_mapping_t *getmm(uaecptr *addrp) { uaecptr addr = *addrp; - addr &= 0x0fffffff; + addr &= 0x7fffffff; int index = addr / PCEMMAPBLOCKSIZE; mem_mapping_t *m = pcemmap[index]; if (!m) { @@ -790,6 +790,9 @@ static mem_mapping_t *getmm(uaecptr *addrp) void put_mem_pcem(uaecptr addr, uae_u32 v, int size) { +#if 0 + write_log("%08x %08x %d\n", addr, v, size); +#endif mem_mapping_t *m = getmm(&addr); if (m) { if (size == 0) { @@ -856,7 +859,7 @@ static void mapping_recalc(mem_mapping_t *mapping) for (uae_u32 i = 0; i < mapping->size; i += PCEMMAPBLOCKSIZE) { uae_u32 addr = i + mapping->base; - addr &= 0x0fffffff; + addr &= 0x7fffffff; int offset = addr / PCEMMAPBLOCKSIZE; if (offset >= 0 && offset < MAX_PCEMMAPBLOCKS) { if (mapping->enable) { diff --git a/pcem/vid_cl5429.cpp b/pcem/vid_cl5429.cpp index 17986862..5a76f74e 100644 --- a/pcem/vid_cl5429.cpp +++ b/pcem/vid_cl5429.cpp @@ -2188,7 +2188,6 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) svga->vram[(gd5429->blt.dst_addr + 1) & svga->vram_mask] = dststore[1]; svga->vram[(gd5429->blt.dst_addr + 2) & svga->vram_mask] = dststore[2]; svga->changedvram[((gd5429->blt.dst_addr + 0) & svga->vram_mask) >> 12] = changeframecount; - svga->changedvram[((gd5429->blt.dst_addr + 1) & svga->vram_mask) >> 12] = changeframecount; svga->changedvram[((gd5429->blt.dst_addr + 2) & svga->vram_mask) >> 12] = changeframecount; } } else if (bpp == 4) { @@ -2199,8 +2198,6 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) svga->vram[(gd5429->blt.dst_addr + 2) & svga->vram_mask] = dststore[2]; svga->vram[(gd5429->blt.dst_addr + 3) & svga->vram_mask] = dststore[3]; svga->changedvram[((gd5429->blt.dst_addr + 0) & svga->vram_mask) >> 12] = changeframecount; - svga->changedvram[((gd5429->blt.dst_addr + 1) & svga->vram_mask) >> 12] = changeframecount; - svga->changedvram[((gd5429->blt.dst_addr + 2) & svga->vram_mask) >> 12] = changeframecount; svga->changedvram[((gd5429->blt.dst_addr + 3) & svga->vram_mask) >> 12] = changeframecount; } } @@ -2208,21 +2205,6 @@ void gd5429_start_blit(uint32_t cpu_dat, int count, void *p) bplcnt = 0; maskstore = 0; } -#if 0 - if (0 && gd5429->type <= CL_TYPE_GD5428) - { - if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && - (!(gd5429->blt.mode & 0x08) || (dst & ~gd5429->blt.trans_mask) != (gd5429->blt.trans_col & ~gd5429->blt.trans_mask))) - svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; - } - else - { - if ((gd5429->blt.width_backup - gd5429->blt.width) >= blt_mask && - !((gd5429->blt.mode & 0x08) && !mask)) - svga->vram[gd5429->blt.dst_addr & svga->vram_mask] = dst; - } - gd5429->blt.dst_addr += ((gd5429->blt.mode & 0x01) ? -1 : 1); -#endif gd5429->blt.x_count++; if (gd5429->blt.x_count == x_max) diff --git a/pcem/vid_s3.cpp b/pcem/vid_s3.cpp index 088b055b..7b7054c5 100644 --- a/pcem/vid_s3.cpp +++ b/pcem/vid_s3.cpp @@ -194,7 +194,7 @@ static void s3_update_irqs(s3_t *s3) else pci_clear_irq(s3->card, PCI_INTA); - if ((s3->subsys_stat & INT_VSY) && !(s3->subsys_stat & INT_VSY) && !enabled) { + if ((s3->subsys_stat & INT_VSY) && !(s3->subsys_cntl & INT_VSY) && !enabled) { s3->subsys_stat &= ~INT_VSY; } } diff --git a/pcem/vid_s3_virge.cpp b/pcem/vid_s3_virge.cpp index 99c32666..fdf628bf 100644 --- a/pcem/vid_s3_virge.cpp +++ b/pcem/vid_s3_virge.cpp @@ -237,6 +237,7 @@ typedef struct virge_t int virge_busy; uint8_t subsys_stat, subsys_cntl; + uint32_t advfunc; int vblank_irq; } virge_t; @@ -473,6 +474,16 @@ static void s3_virge_out(uint16_t addr, uint8_t val, void *p) break; case 0x53: + extern void gfxboard_s3virge_lfb_endianswap(int); + gfxboard_s3virge_lfb_endianswap((val >> 1) & 3); + s3_virge_updatemapping(virge); + break; + + case 0x54: + break; + case 0x61: + break; + case 0x58: case 0x59: case 0x5a: s3_virge_updatemapping(virge); break; @@ -746,7 +757,7 @@ static void s3_virge_updatemapping(virge_t *virge) virge->linear_base = (svga->crtc[0x5a] << 16) | (svga->crtc[0x59] << 24); pclog("Linear framebuffer %02X ", svga->crtc[0x58] & 0x10); - if (svga->crtc[0x58] & 0x10) /*Linear framebuffer*/ + if ((svga->crtc[0x58] | virge->advfunc) & 0x10) /*Linear framebuffer*/ { switch (svga->crtc[0x58] & 3) { @@ -1047,18 +1058,20 @@ static void fifo_thread(void *param) if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) { if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 16, ((val >> 8) | (val << 8)) << 16); - else - s3_virge_bitblt(virge, 16, val); + ((val >> 8) | (val << 8)) << 16; +// if ((virge->svga.crtc[0x54] & 3) == 1) +// ((val >> 8) | (val << 8)) << 16; + s3_virge_bitblt(virge, 16, val); } break; case FIFO_WRITE_DWORD: if (((fifo->addr_type & FIFO_ADDR) & 0xfffc) < 0x8000) - { + { if (virge->s3d.cmd_set & CMD_SET_MS) - s3_virge_bitblt(virge, 32, ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); - else - s3_virge_bitblt(virge, 32, val); + val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); +// if ((virge->svga.crtc[0x54] & 3) == 2) +// val = ((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24); + s3_virge_bitblt(virge, 32, val); } else { @@ -1433,7 +1446,7 @@ static void s3_virge_mmio_write_w(uint32_t addr, uint16_t val, void *p) { virge_t *virge = (virge_t *)p; reg_writes++; -// pclog("New MMIO writew %08X %04X %04x(%08x):%08x\n", addr, val, CS, cs, pc); + //pclog("New MMIO writew %08X %04X %04x(%08x):%08x\n", addr, val, CS, cs, 0); if ((addr & 0xfffc) < 0x8000) { s3_virge_queue(virge, addr, val, FIFO_WRITE_WORD); @@ -1449,8 +1462,8 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge_t *virge = (virge_t *)p; svga_t *svga = &virge->svga; reg_writes++; -// if ((addr & 0xfffc) >= 0xb400 && (addr & 0xfffc) < 0xb800) -// pclog("New MMIO writel %08X %08X %04x(%08x):%08x\n", addr, val, CS, cs, pc); +// if ((addr & 0xfffc) >= 0xb400 && (addr & 0xfffc) < 0xb800) +// pclog("New MMIO writel %08X %08X %04x(%08x):%08x\n", addr, val, CS, cs, 0); if ((addr & 0xfffc) < 0x8000) { @@ -1585,6 +1598,11 @@ static void s3_virge_mmio_write_l(uint32_t addr, uint32_t val, void *p) virge->subsys_cntl = (val >> 8); s3_virge_update_irqs(virge); break; + + case 0x850c: + virge->advfunc = val; + s3_virge_updatemapping(virge); + break; case 0xa000: case 0xa004: case 0xa008: case 0xa00c: case 0xa010: case 0xa014: case 0xa018: case 0xa01c: diff --git a/pcem/vid_svga.cpp b/pcem/vid_svga.cpp index 62523a0d..01a4aaa1 100644 --- a/pcem/vid_svga.cpp +++ b/pcem/vid_svga.cpp @@ -693,8 +693,6 @@ int svga_poll(void *p) wx = x; wy = svga->lastline - svga->firstline; - if (svga->interlace) - wy /= 2; if (!svga->override) svga_doblit(svga->firstline_draw, svga->lastline_draw + 1, wx, wy, svga); @@ -1406,7 +1404,7 @@ void svga_doblit(int y1, int y2, int wx, int wy, svga_t *svga) // pclog("svga_doblit %i %i\n", wx, svga->hdisp); if (y1 > y2) { - video_blit_memtoscreen(32, 0, 0, 0, xsize, ysize); + video_blit_memtoscreen(32, 0, 0, 0, xsize << svga->horizontal_linedbl, ysize); return; } diff --git a/pcem/vid_voodoo_banshee.cpp b/pcem/vid_voodoo_banshee.cpp index d332f066..9c77608a 100644 --- a/pcem/vid_voodoo_banshee.cpp +++ b/pcem/vid_voodoo_banshee.cpp @@ -32,7 +32,8 @@ enum { TYPE_BANSHEE = 0, TYPE_V3_2000, - TYPE_V3_3000 + TYPE_V3_3000, + TYPE_V5_5500 }; typedef struct banshee_t @@ -481,10 +482,6 @@ static void banshee_recalctimings(svga_t *svga) if (banshee->vidProcCfg & VIDPROCCFG_INTERLACE) { svga->interlace = 1; - svga->vtotal *= 2; - svga->dispend *= 2; - svga->vblankstart *= 2; - svga->vsyncstart *= 2; } svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE; @@ -590,7 +587,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p) case Init_lfbMemoryConfig: banshee->lfbMemoryConfig = val; -// pclog("lfbMemoryConfig=%08x\n", val); + pclog("lfbMemoryConfig=%08x\n", val); voodoo->tile_base = (val & 0x1fff) << 12; voodoo->tile_stride = 1024 << ((val >> 13) & 7); voodoo->tile_stride_shift = 10 + ((val >> 13) & 7); @@ -986,6 +983,21 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p) return ret; } +// miscInit0 register swizzle +static uint32_t registerswizzle(uint32_t data, uint32_t addr, int addrtype, banshee_t *banshee) +{ + // swizzling enabled if miscInit0 swizzle bit(s) set and: + // 2D register address space and address bit 19 set + // 3D register address space and address bit 20 set + if ((!addrtype && (addr & 0x00080000)) || (addrtype && (addr & 0x00100000))) { + if (banshee->miscInit0 & 4) + data = (data >> 24) | ((data >> 8) & 0xff00) | ((data << 8) & 0xff0000) | (data << 24); + if (banshee->miscInit0 & 8) + data = (data >> 16) | (data << 16); + } + return data; +} + static uint32_t banshee_reg_readl(uint32_t addr, void *p); @@ -1103,6 +1115,7 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p) default: pclog("banshee_reg_readl: addr=%08x\n", addr); } + ret = registerswizzle(ret, addr, 0, banshee); break; case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/ @@ -1183,6 +1196,7 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p) pclog("banshee_reg_readl: 3D addr=%08x\n", addr); break; } + ret = registerswizzle(ret, addr, 1, banshee); break; } @@ -1295,6 +1309,7 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) break; case 0x0100000: /*2D registers*/ + val = registerswizzle(val, addr, 0, banshee); if ((addr & 0x3fc) == SST_intrCtrl) { banshee->intrCtrl = val & 0x0030003f; } else { @@ -1303,7 +1318,8 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p) break; case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/ - switch (addr & 0x3fc) + val = registerswizzle(val, addr, 1, banshee); + switch (addr & 0x3fc) { case SST_intrCtrl: banshee->intrCtrl = val & 0x0030003f; @@ -1497,10 +1513,12 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) voodoo_t *voodoo = banshee->voodoo; svga_t *svga = &banshee->svga; +#if 0 cycles -= voodoo->write_time; cycles_lost += voodoo->write_time; +#endif -// pclog("write_linear: addr=%08x val=%02x\n", addr, val); + // pclog("write_linear: addr=%08x val=%02x\n", addr, val); addr &= svga->decode_mask; if (addr >= voodoo->tile_base) { @@ -1516,11 +1534,12 @@ static void banshee_write_linear(uint32_t addr, uint8_t val, void *p) if (addr >= svga->vram_max) return; +#if 0 egawrites++; cycles -= video_timing_write_b; cycles_lost += video_timing_write_b; - +#endif svga->changedvram[addr >> 12] = changeframecount; svga->vram[addr & svga->vram_mask] = val; } @@ -2402,7 +2421,7 @@ static uint8_t banshee_pci_read(int func, int addr, void *p) case 0x00: ret = 0x1a; break; /*3DFX*/ case 0x01: ret = 0x12; break; - case 0x02: ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : 0x05; break; + case 0x02: ret = (banshee->type == TYPE_BANSHEE) ? 0x03 : (banshee->type == TYPE_V5_5500 ? 0x09 : 0x05); break; case 0x03: ret = 0x00; break; case 0x04: ret = banshee->pci_regs[0x04] & 0x27; break; @@ -2459,6 +2478,7 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) { banshee_t *banshee = (banshee_t *)p; // svga_t *svga = &banshee->svga; + uint32_t basemask = banshee->type == TYPE_V5_5500 ? 0xfc : 0xfe; if (func) return; @@ -2497,12 +2517,12 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p) return; case 0x13: - banshee->memBaseAddr0 = (val & 0xfe) << 24; + banshee->memBaseAddr0 = (val & basemask) << 24; banshee_updatemapping(banshee); return; case 0x17: - banshee->memBaseAddr1 = (val & 0xfe) << 24; + banshee->memBaseAddr1 = (val & basemask) << 24; banshee_updatemapping(banshee); return; @@ -2796,6 +2816,14 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t banshee->pci_regs[0x2e] = 0x3a; banshee->pci_regs[0x2f] = 0x00; break; + + case TYPE_V5_5500: + banshee->pci_regs[0x2c] = 0x1a; + banshee->pci_regs[0x2d] = 0x12; + banshee->pci_regs[0x2e] = 0x09; + banshee->pci_regs[0x2f] = 0x00; + break; + } banshee->svga.vblank_start = banshee_vblank_start; @@ -2817,7 +2845,11 @@ static void *v3_2000_init() } static void *v3_3000_init() { - return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3); + return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V3_3000, VOODOO_3); +} +static void *v5_5500_init() +{ + return banshee_init_common("voodoo3_3000/3k12sd.rom", 0, TYPE_V5_5500, VOODOO_3); } static int banshee_available() @@ -3002,3 +3034,16 @@ device_t voodoo_3_3000_device = banshee_add_status_info, banshee_sdram_config }; + +device_t voodoo_5_5500_device = +{ + "Voodoo 5 5500 PCI", + DEVICE_PCI, + v5_5500_init, + banshee_close, + v3_3000_available, + banshee_speed_changed, + banshee_force_redraw, + banshee_add_status_info, + banshee_sdram_config +}; diff --git a/pcem/vid_voodoo_banshee.h b/pcem/vid_voodoo_banshee.h index ddd7e3fd..20c8808e 100644 --- a/pcem/vid_voodoo_banshee.h +++ b/pcem/vid_voodoo_banshee.h @@ -2,5 +2,6 @@ extern device_t voodoo_banshee_device; extern device_t creative_voodoo_banshee_device; extern device_t voodoo_3_2000_device; extern device_t voodoo_3_3000_device; +extern device_t voodoo_5_5500_device; void banshee_set_overlay_addr(void *p, uint32_t addr); diff --git a/pci.cpp b/pci.cpp index 61697be1..86e5f4f5 100644 --- a/pci.cpp +++ b/pci.cpp @@ -182,11 +182,14 @@ static void pci_hsync(void) static void pci_rethink(void) { + static int bridgenum; + for (int i = 0; i < PCI_BRIDGE_MAX; i++) { - struct pci_bridge *pcib = bridges[i]; + struct pci_bridge *pcib = bridges[(i + bridgenum) % PCI_BRIDGE_MAX]; if (!pcib) continue; pcib->irq = 0; + bridgenum = i; for (int j = 0; j < MAX_PCI_BOARDS; j++) { struct pci_board_state *pcibs = &pcib->boards[j]; if (pcibs->board) { @@ -197,12 +200,14 @@ static void pci_rethink(void) uae_u8 irq = 1 << pin; pcib->irq |= irq; if (irq & pcib->intena) { + //write_log(_T("%02x %02x %s\n"), pin, pcib->irq, pcibs->board->label); safe_interrupt_set(IRQ_SOURCE_PCI, i, (pcib->intreq_mask & 0x2000) != 0); } } } } } + break; } } @@ -331,7 +336,7 @@ static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaec addr2 -= pcib->memory_start_offset; } struct pci_board_state *pcibs2 = &pcib->boards[stored_board]; - if (pcibs2) { + if (pcibs2 && stored_bar < MAX_PCI_BARS) { if (pcibs2->bar_enabled[stored_bar] && addr2 >= pcibs2->bar_start[stored_bar] && addr2 <= pcibs2->bar_end[stored_bar]) { *bar = stored_bar; return pcibs2; @@ -348,6 +353,17 @@ static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaec } } } + if (io && addr2 < 0x400) { + for (int i = 0; i < MAX_PCI_BOARDS; i++) { + struct pci_board_state *pcibs = &pcib->boards[i]; + if (pcibs->board->bars[MAX_PCI_BARS].bget) { + stored_board = i; + stored_bar = MAX_PCI_BARS; + *bar = stored_bar; + return pcibs; + } + } + } return NULL; } @@ -365,11 +381,11 @@ static const pci_addrbank *get_pci_io(uaecptr *addrp, struct pci_board_state **p pcibs->selected_bar = bar; *endianswap = pcib->endian_swap_io; addr -= pcib->io_offset; - if (!pcibs->board->dont_mask_io) { + if (!pcibs->board->dont_mask_io && bar < MAX_PCI_BARS) { addr &= (pcibs->bar_size[bar] & ~1) - 1; } #if PCI_DEBUG_IO - write_log(_T("get_pci_io %08x=%08x %c:%d PC=%08x "), *addrp, addr, size < 0 ? 'W' : 'R', size < 0 ? -size : size, M68K_GETPC); + write_log(_T("get_pci_io %08x=%08x %c:%d PC=%08x\n"), *addrp, addr, size < 0 ? 'W' : 'R', size < 0 ? -size : size, M68K_GETPC); #endif *addrp = addr; return &pcibs->board->bars[bar]; @@ -569,7 +585,7 @@ static void update_pci_config(uaecptr addr, int size) static uaecptr beswap(int endianswap, uaecptr addr) { if (endianswap > 0) - return addr ^ 3;; + return addr ^ 3; return addr; } diff --git a/qemuvga/es1370.cpp b/qemuvga/es1370.cpp index fc5b3d60..163379e9 100644 --- a/qemuvga/es1370.cpp +++ b/qemuvga/es1370.cpp @@ -1207,7 +1207,8 @@ const struct pci_board es1370_pci_board = { NULL }, { NULL }, { NULL }, - { NULL }, - { NULL }, - } + { NULL }, + { NULL }, + { NULL } + } }; diff --git a/sndboard.cpp b/sndboard.cpp index 673ccdc6..c3f06f2c 100644 --- a/sndboard.cpp +++ b/sndboard.cpp @@ -2708,6 +2708,7 @@ const struct pci_board fm801_pci_board = { NULL }, { NULL }, { NULL }, + { NULL } } }; @@ -2723,6 +2724,7 @@ const struct pci_board fm801_pci_board_func1 = { NULL }, { NULL }, { NULL }, + { NULL } } }; @@ -2816,6 +2818,7 @@ const struct pci_board solo1_pci_board = { solo1_lget, solo1_wget, solo1_bget, solo1_lput, solo1_wput, solo1_bput }, { NULL }, { NULL }, + { NULL } } }; -- 2.47.3