]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
PCI graphics/sound card updates
authorToni Wilen <twilen@winuae.net>
Sat, 2 Jan 2021 14:49:55 +0000 (16:49 +0200)
committerToni Wilen <twilen@winuae.net>
Sat, 2 Jan 2021 14:49:55 +0000 (16:49 +0200)
15 files changed:
expansion.cpp
gfxboard.cpp
include/gfxboard.h
include/pci_hw.h
include/rommgr.h
pcem/pcemglue.cpp
pcem/vid_cl5429.cpp
pcem/vid_s3.cpp
pcem/vid_s3_virge.cpp
pcem/vid_svga.cpp
pcem/vid_voodoo_banshee.cpp
pcem/vid_voodoo_banshee.h
pci.cpp
qemuvga/es1370.cpp
sndboard.cpp

index 3ed9ce27b3140d13d77cde121d24a1cdbb6b0a4e..80861e809d684ccd13fc82106e3bfee7da27394f 100644 (file)
@@ -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,
index a87297a4e59602e9782ebe9a578df5e19ba02d40..a4d0fef82cdf90e0240b19948203e76ea01e7099 100644 (file)
@@ -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 rtggfxboardgb = &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 (<rom path>\\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;
index e27b842ecf8e4c57c9efdf6df491cc27e9651e06..e86d1bac91ee366b57d8acc6752dbe88f8d6f013 100644 (file)
@@ -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
index 2cbcdfc15799ea6b0662bc10545584f146782c45..01f55b298cdab5f3510b0254f0edc9399174400f 100644 (file)
@@ -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;
index 4e7a3ac285578dcf666f94c6eb18d583faf46222..71e0b63fe52b3c673115bf942b8630a1f20abc9b 100644 (file)
@@ -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
index d01a1a0608ba6e502fcb80eba18cb3bb7c11f89d..6cbd621d83865651a051814c141e7e0818ab7eea 100644 (file)
@@ -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) {
index 17986862e549bf47d91218c30ed70d8c137a964f..5a76f74e9d2f81f4d677302a28153c394522efa3 100644 (file)
@@ -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)
index 088b055baa78760d92781a7c468966f69693a4f0..7b7054c5744b33d5c1a3dfb160d71147677c15ee 100644 (file)
@@ -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;
         }
 }
index 99c3266693e914b3785eb1b1ca8bfa7f4fe5c445..fdf628bf5aa3694f5bd5e1cd8b0f7040cfcf9b7e 100644 (file)
@@ -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:
index 62523a0d5182f3e13abe442e8705d99bbc1748c3..01a4aaa1255a503d111e9dd50ee15219bf5825d1 100644 (file)
@@ -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;   
         }     
 
index d332f06679031b338127bd45cf7d1385deac51d4..9c77608a09760bec4ba35af412acb1713df30c55 100644 (file)
@@ -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
+};
index ddd7e3fda031599e7a5d9309631b77d270fa671f..20c8808e185f1743e3c3a7bbc44b47e553461af6 100644 (file)
@@ -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 61697be1c8afdb95e1f4f343ce03333e401cfab3..86e5f4f53b7757e91c547a0bf7f41c7a40ffe273 100644 (file)
--- 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;
 }
 
index fc5b3d6093f782520d1218e7437852e4acbd39c0..163379e9ae162b8ae0341e78c14b09aedb70368d 100644 (file)
@@ -1207,7 +1207,8 @@ const struct pci_board es1370_pci_board =
                { NULL },
                { NULL },
                { NULL },
-               { NULL },
-               { NULL },
-       }
+        { NULL },
+        { NULL },
+        { NULL }
+    }
 };
index 673ccdc67ad6311907b3fea83f93224999579a75..c3f06f2c9a03de69ee07a832801432034a4a6f56 100644 (file)
@@ -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 }
        }
 };