]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Mediator TX1200 secondary PCI window implemented.
authorToni Wilen <twilen@winuae.net>
Fri, 2 Aug 2024 18:06:44 +0000 (21:06 +0300)
committerToni Wilen <twilen@winuae.net>
Fri, 2 Aug 2024 18:06:44 +0000 (21:06 +0300)
gfxboard.cpp
include/pci_hw.h
pci.cpp

index f712ee27a7d2c97b8b68db1093ab9610508b9ed7..deca96973fd5f6434eaa1c7478dd10187707a201 100644 (file)
@@ -3918,27 +3918,29 @@ static void pci_change_config(struct pci_board_state *pci)
        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) {
+                       struct pci_bridge *pcib = pci->bridge;
                        // 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 (rc && (rc->device_settings & 1) && pci_validate_address(pci->bar[1] + pcib->memory_start_offset[pcib->windowindex], 0x02000000, false)) {
                                if (!gb->original_pci_bank) {
-                                       gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset);
+                                       gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pcib->memory_start_offset[pcib->windowindex]);
                                }
-                               reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true);
+                               reinit_vram(gb, pci->bar[1] + pcib->memory_start_offset[pcib->windowindex], 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);
+                               reinit_vram(gb, pci->bar[1] + pcib->memory_start_offset[pcib->windowindex], false);
                        }
                }
        } else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) {
                if (pci->memory_map_active) {
+                       struct pci_bridge *pcib = pci->bridge;
                        // 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);
+                       if (pci_validate_address(pci->bar[1] + pcib->memory_start_offset[0], gb->rbc->rtgmem_size, false)) {
+                               reinit_vram(gb, pci->bar[1] + pcib->memory_start_offset[pcib->windowindex], true);
+                               gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pcib->memory_start_offset[pcib->windowindex]);
                        } else {
-                               reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false);
+                               reinit_vram(gb, pci->bar[1] + pcib->memory_start_offset[pcib->windowindex], false);
                        }
                }
        } else if (gb->rbc->rtgmem_type == GFXBOARD_ID_S3VIRGE_PCI ||
@@ -3946,7 +3948,8 @@ static void pci_change_config(struct pci_board_state *pci)
                gb->rbc->rtgmem_type == GFXBOARD_ID_PERMEDIA2_PCI ||
                gb->rbc->rtgmem_type == GFXBOARD_ID_GD5446_PCI) {
                if (pci->memory_map_active) {
-                       reinit_vram(gb, pci->bar[0] + pci->bridge->memory_start_offset, false);
+                       struct pci_bridge *pcib = pci->bridge;
+                       reinit_vram(gb, pci->bar[0] + pcib->memory_start_offset[pcib->windowindex], false);
                }
        }
 }
index dbe179a337ca1d9df002b8c9d9edd8b5e8bc37b5..7d06f147652981c48ffd021ece8659c5daee8bd0 100644 (file)
@@ -87,7 +87,7 @@ struct pci_bridge
        int type;
        int endian_swap_config;
        uae_u32 io_offset;
-       uae_u32 memory_start_offset;
+       uae_u32 memory_start_offset[2];
        int endian_swap_io;
        uae_u32 memory_window_offset;
        int endian_swap_memory;
@@ -118,9 +118,11 @@ struct pci_bridge
        uae_u8 acmemory[128];
        uae_u8 acmemory_2[128];
        struct romconfig *rc;
-       uae_u16 window;
+       uae_u16 window[2];
        int log_slot_cnt;
        int phys_slot_cnt;
+       bool multiwindow;
+       int windowindex;
 };
 
 extern void pci_irq_callback(struct pci_board_state *pcibs, bool irq);
diff --git a/pci.cpp b/pci.cpp
index 1d689faf2fe9fce4349d52405bf395d36234c37b..e64db60d971ec011d83133507570f26761de990a 100644 (file)
--- a/pci.cpp
+++ b/pci.cpp
@@ -291,10 +291,15 @@ static struct pci_bridge *get_pci_bridge(uaecptr addr)
        }
        struct pci_bridge *pcib = bridges[last_bridge_index];
        if (pcib) {
-               if (addr >= pcib->baseaddress && addr < pcib->baseaddress_end)
+               if (addr >= pcib->baseaddress && addr < pcib->baseaddress_end) {
+                       if (pcib->multiwindow) {
+                               pcib->windowindex = addr >= pcib->baseaddress + 0x00400000 ? 1 : 0;
+                       }
                        return pcib;
-               if (pcib->configured_2 && addr >= pcib->baseaddress_2 && addr < pcib->baseaddress_end_2)
+               }
+               if (pcib->configured_2 && addr >= pcib->baseaddress_2 && addr < pcib->baseaddress_end_2) {
                        return pcib;
+               }
        }
        for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
                struct pci_bridge *pcib = bridges[i];
@@ -302,6 +307,9 @@ static struct pci_bridge *get_pci_bridge(uaecptr addr)
                        if ((addr >= pcib->baseaddress && addr < pcib->baseaddress_end) ||
                                (pcib->configured_2 && addr >= pcib->baseaddress_2 && addr < pcib->baseaddress_end_2)) {
                                last_bridge_index = i;
+                               if (pcib->multiwindow) {
+                                       pcib->windowindex = addr >= pcib->baseaddress + 0x00400000 ? 1 : 0;
+                               }
                                return pcib;
                        }
                }
@@ -357,7 +365,7 @@ static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaec
        if (io) {
                addr2 -= pcib->io_offset;
        } else {
-               addr2 -= pcib->memory_start_offset;
+               addr2 -= pcib->memory_start_offset[pcib->windowindex];
        }
        struct pci_board_state *pcibs2 = &pcib->boards[stored_board];
        if (pcibs2 && stored_bar < MAX_PCI_BARS) {
@@ -431,7 +439,7 @@ static const pci_addrbank *get_pci_mem(uaecptr *addrp, struct pci_board_state **
        *pcibsp = pcibs;
        pcibs->selected_bar = bar;
        *endianswap = pcib->endian_swap_memory;
-       addr -= pcibs->bridge->memory_start_offset;
+       addr -= pcibs->bridge->memory_start_offset[pcib->windowindex];
        *addrp = addr;
        return &pcibs->board->bars[bar];
 }
@@ -1138,7 +1146,7 @@ static void REGPARAM2 pci_bridge_wput(uaecptr addr, uae_u32 b)
                                        }
                                        pcib->baseaddress_offset = pcib->baseaddress;
                                        pcib->io_offset = expamem_board_pointer;
-                                       pcib->memory_start_offset = expamem_board_pointer;
+                                       pcib->memory_start_offset[0] = expamem_board_pointer;
                                } else if (pcib->type == PCI_BRIDGE_PROMETHEUS_FS) {
                                        if (validate_banks_z3(&pci_io_bank, (expamem_board_pointer) >> 16, expamem_board_size >> 16)) {
                                                map_banks_z3(&pci_io_bank, (expamem_board_pointer + 0x1fe00000) >> 16, 0x100000 >> 16);
@@ -1147,7 +1155,7 @@ static void REGPARAM2 pci_bridge_wput(uaecptr addr, uae_u32 b)
                                        }
                                        pcib->baseaddress_offset = pcib->baseaddress;
                                        pcib->io_offset = expamem_board_pointer;
-                                       pcib->memory_start_offset = expamem_board_pointer;
+                                       pcib->memory_start_offset[0] = expamem_board_pointer;
                                } else if (pcib->type == PCI_BRIDGE_MEDIATOR) {
                                        map_banks_z3(&pci_mem_bank, expamem_board_pointer >> 16, expamem_board_size >> 16);
                                        pcib->baseaddress_offset = 0;
@@ -1211,26 +1219,32 @@ static void REGPARAM2 pci_bridge_bput(uaecptr addr, uae_u32 b)
 
 static void mediator_set_window_offset(struct pci_bridge *pcib, uae_u16 v)
 {
-       uae_u32 offset;
        v = do_byteswap_16(v);
        if (pcib->bank_2_zorro == 3) {
                // 4000
-               uae_u8 mask = pcib->board_size == 256 * 1024 * 1024 ? 0xf0 : 0xe0;
-               pcib->window = v & mask;
-               pcib->memory_start_offset = pcib->window << 18;
-               offset = pcib->memory_start_offset;
+               pcib->window[0] = v & 0xf0;
+               pcib->memory_start_offset[0] = pcib->window[0] << 18;
        } else {
                // 1200
-               uae_u16 mask = pcib->board_size == 4 * 1024 * 1024 ? 0xffc0 : 0xff80;
-               pcib->window = v & mask;
-               pcib->memory_start_offset = pcib->window << 16;
-               offset = pcib->memory_start_offset;
-               pcib->memory_start_offset -= pcib->baseaddress;
-               pcib->memory_start_offset = 0 - pcib->memory_start_offset;
-       }
-#if 0
-       write_log(_T"Mediator window: %08x %04x PC=%08x\n"), offset, v, M68K_GETPC);
-#endif
+               if (pcib->multiwindow) {
+                       // TX has 2x4M banks
+                       if (v & 0x0010) {
+                               pcib->window[1] = v & 0xffc0;
+                               pcib->memory_start_offset[1] = pcib->window[1] << 16;
+                               pcib->memory_start_offset[1] -= 0x00400000;
+                               pcib->memory_start_offset[1] -= pcib->baseaddress;
+                               pcib->memory_start_offset[1] = 0 - pcib->memory_start_offset[1];
+                       }
+               } else {
+                       v &= ~0x0010;
+               }
+               if (!(v& 0x0010)) {
+                       pcib->window[0] = v & 0xffc0;
+                       pcib->memory_start_offset[0] = pcib->window[0] << 16;
+                       pcib->memory_start_offset[0] -= pcib->baseaddress;
+                       pcib->memory_start_offset[0] = 0 - pcib->memory_start_offset[0];
+               }
+       }
 }
 
 static uae_u32 REGPARAM2 pci_bridge_bget_2(uaecptr addr)
@@ -1248,7 +1262,7 @@ static uae_u32 REGPARAM2 pci_bridge_bget_2(uaecptr addr)
                if (pcib->bank_2_zorro == 3) {
                        int offset = addr & 0x7fffff;
                        if (offset == 0) {
-                               v = (uae_u8)pcib->window;
+                               v = (uae_u8)pcib->window[0];
                                v |= 8; // id
                        }
                        if (offset == 4) {
@@ -1283,7 +1297,7 @@ static uae_u32 REGPARAM2 pci_bridge_wget_2(uaecptr addr)
                        int offset = addr & 0x1f;
                        v = 0;
                        if (offset == 2) {
-                               v = 0x2000 | do_byteswap_16(pcib->window); // id + window
+                               v = 0x2000 | do_byteswap_16(pcib->window[0]); // id + window
                        } else if (offset == 10) {
                                v = pcib->irq | (pcib->intena << 4);
                        }
@@ -2168,8 +2182,13 @@ static void mediator_pci_init_1200(struct pci_bridge *pcib)
        pcib->bank_zorro = 2;
        pcib->bank_2_zorro = 2;
        pcib->pcipcidma = true;
-       if (pcib->rc->device_settings & 1)
+       if (pcib->rc->device_settings & 1) {
                pcib->amigapicdma = true;
+       }
+       // 1200TX 8M?
+       if (pcib->rc->subtype == 2 && (pcib->rc->device_settings & 2)) {
+               pcib->multiwindow = true;
+       }
        mediator_set_window_offset(pcib, 0);
 }