]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Prometheus FireStorm PCI bridgeboard emulation
authorToni Wilen <twilen@winuae.net>
Fri, 15 Mar 2024 15:46:24 +0000 (17:46 +0200)
committerToni Wilen <twilen@winuae.net>
Fri, 15 Mar 2024 15:46:24 +0000 (17:46 +0200)
cfgfile.cpp
expansion.cpp
gfxboard.cpp
include/pci.h
include/pci_hw.h
include/rommgr.h
pci.cpp

index 58b3a5ab358f5dbc8b64bc15dd322dc542463f83..315c647115ec5fec71b8e1eab2975bfcd1695e8e 100644 (file)
@@ -6654,7 +6654,7 @@ void cfgfile_compatibility_romtype(struct uae_prefs *p)
                ROMTYPE_HYDRA, ROMTYPE_LANROVER,
                0 };
        static const int restricted_x86[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
-       static const int restricted_pci[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
+       static const int restricted_pci[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, ROMTYPE_PROMETHEUSFS, 0 };
        romtype_restricted(p, restricted_net);
        romtype_restricted(p, restricted_x86);
        romtype_restricted(p, restricted_pci);
index 0cda586eecb71ea8ec41897cc2bb471ed45fe86f..e311aeeee7665efb86c520a281fcc6bdd9615097 100644 (file)
@@ -5340,6 +5340,14 @@ const struct expansionromtype expansionroms[] = {
                0, 0, 0, false, NULL,
                false, 0, bridge_settings
        },
+       {
+               _T("prometheusfirestorm"), _T("Prometheus FireStorm"), _T("E3B"),
+               NULL, prometheusfs_init, NULL, NULL, ROMTYPE_PROMETHEUSFS | ROMTYPE_NOT, 0, 0, BOARD_AUTOCONFIG_Z3, false,
+               NULL, 0,
+               false, EXPANSIONTYPE_PCI_BRIDGE,
+               0, 0, 0, false, NULL,
+               false, 0, bridge_settings
+       },
 
        /* SCSI/IDE expansion */
 
index 86c19d940511f768a4fe3193b5fe8447c36dac10..d536c2c87d233c870809e8e3f4ea71ee99aeddfe 100644 (file)
@@ -4563,7 +4563,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
                        static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
                        aci->parent_romtype = parent;
                } else if (gb->board->bustype == GFXBOARD_BUSTYPE_PCI) {
-                       static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
+                       static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, ROMTYPE_PROMETHEUSFS, 0 };
                        aci->parent_romtype = parent;
                } else {
                        memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
index 766fe63e0e298bf7e031596171055e8c26f90b94..b5863be05e848d1934392844ce4664123ceb91f4 100644 (file)
@@ -5,6 +5,7 @@ extern void pci_dump(int);
 
 extern bool dkb_wildfire_pci_init(struct autoconfig_info *aci);
 extern bool prometheus_init(struct autoconfig_info *aci);
+extern bool prometheusfs_init(struct autoconfig_info *aci);
 extern bool grex_init(struct autoconfig_info *aci);
 extern bool mediator_init(struct autoconfig_info *aci);
 extern bool mediator_init2(struct autoconfig_info *aci);
index 4afbc767d0907a8bcd21ca30fb4a3eb782bb6f68..dbe179a337ca1d9df002b8c9d9edd8b5e8bc37b5 100644 (file)
@@ -24,7 +24,7 @@ typedef struct
        pci_put_func lput, wput, bput;
 } pci_addrbank;
 
-typedef int(*pci_slot_index)(uaecptr);
+typedef int(*pci_slot_index)(uaecptr, bool, uae_u32*);
 
 struct pci_config
 {
@@ -95,6 +95,7 @@ struct pci_bridge
        bool amigapicdma;
        uae_u8 intena;
        uae_u8 irq;
+       uae_u8 reset;
        uae_u16 intreq_mask;
        pci_slot_index get_index;
        struct pci_board_state boards[MAX_PCI_BOARDS];
index d3448ede987a19208df6b977253fbc4be33629a3..c72120875578f5fefefe30989cc477513fa48f05 100644 (file)
@@ -210,6 +210,7 @@ extern int decode_cloanto_rom_do(uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_GVPA1208       0x0010008e
 #define ROMTYPE_DSP3210                0x0010008f
 #define ROMTYPE_ALTAIS         0x00100090
+#define ROMTYPE_PROMETHEUSFS 0x00100091
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
diff --git a/pci.cpp b/pci.cpp
index 6b99381c9e81e7d497e6a40130b7fc3bbe5e5d52..95903f0995c06a3ed4dcd28057696fb93889bb41 100644 (file)
--- a/pci.cpp
+++ b/pci.cpp
@@ -39,7 +39,8 @@
 #define PCI_BRIDGE_GREX (PCI_BRIDGE_WILDFIRE + 1)
 #define PCI_BRIDGE_XVISION (PCI_BRIDGE_GREX + 1)
 #define PCI_BRIDGE_PROMETHEUS (PCI_BRIDGE_XVISION + 1)
-#define PCI_BRIDGE_MEDIATOR (PCI_BRIDGE_PROMETHEUS + MAX_DUPLICATE_EXPANSION_BOARDS)
+#define PCI_BRIDGE_PROMETHEUS_FS (PCI_BRIDGE_PROMETHEUS + 1)
+#define PCI_BRIDGE_MEDIATOR (PCI_BRIDGE_PROMETHEUS_FS + MAX_DUPLICATE_EXPANSION_BOARDS)
 #define PCI_BRIDGE_MAX (PCI_BRIDGE_MEDIATOR + MAX_DUPLICATE_EXPANSION_BOARDS + 1)
 
 static struct pci_bridge *bridges[PCI_BRIDGE_MAX + 1];
@@ -324,12 +325,12 @@ static struct pci_bridge *get_pci_bridge_2(uaecptr addr)
        return NULL;
 }
 
-static struct pci_board_state *get_pci_board_state_config(struct pci_bridge *pcib, uaecptr addr)
+static struct pci_board_state *get_pci_board_state_config(struct pci_bridge *pcib, uaecptr addr, bool w, uae_u32 *vp)
 {
        if (!pcib)
                return NULL;
        // get slot
-       int idx = pcib->get_index(addr);
+       int idx = pcib->get_index(addr, w, vp);
        if (idx < 0)
                return NULL;
        int slot = idx & 0xff;
@@ -433,9 +434,8 @@ static uae_u8 *get_pci_config(uaecptr addr, int size, uae_u32 v, int *endianswap
 {
 #if PCI_DEBUG_CONFIG
        if (size < 0) {
-               size = -size;
                write_log(_T("PCI Config Space %s READ %08x PC=%08x\n"),
-                       size == 4 ? _T("LONG") : (size == 2 ? _T("WORD") : _T("BYTE")), addr, M68K_GETPC);
+                       size == -4 ? _T("LONG") : (size == -2 ? _T("WORD") : _T("BYTE")), addr, M68K_GETPC);
        } else {
                write_log(_T("PCI Config Space %s WRITE %08x = %08x PC=%08x\n"),
                                         size == 4 ? _T("LONG") : (size == 2 ? _T("WORD") : _T("BYTE")), addr, v, M68K_GETPC);
@@ -444,9 +444,18 @@ static uae_u8 *get_pci_config(uaecptr addr, int size, uae_u32 v, int *endianswap
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
                return NULL;
-       struct pci_board_state *pcibs = get_pci_board_state_config(pcib, addr);
-       if (!pcibs)
+       struct pci_board_state *pcibs = get_pci_board_state_config(pcib, addr, size > 0, &v);
+       if (!pcibs) {
+               if (size < 0) {
+                       static uae_u8 ret[256+3];
+                       ret[3] = v >> 24;
+                       ret[2] = v >> 16;
+                       ret[1] = v >> 8;
+                       ret[0] = v >> 0;
+                       return ret;
+               }
                return NULL;
+       }
        *endianswap = pcib->endian_swap_config;
 #if PCI_DEBUG_CONFIG
        write_log(_T("- Board %d/%d (%s)\n"), pcibs->slot, pcibs->func, pcibs->board->label);
@@ -520,7 +529,7 @@ static void update_pci_config(uaecptr addr, int size)
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
                return;
-       struct pci_board_state *pcibs = get_pci_board_state_config(pcib, addr);
+       struct pci_board_state *pcibs = get_pci_board_state_config(pcib, addr, false, 0);
        if (!pcibs)
                return;
        uae_u8 *d = pcibs->config_data;
@@ -647,7 +656,7 @@ static uae_u32 REGPARAM2 pci_config_lget(uaecptr addr)
 {
        uae_u32 v = 0xffffffff;
        int endianswap;
-       uae_u8 *config = get_pci_config(addr, -4, 0, &endianswap);
+       uae_u8 *config = get_pci_config(addr, -4, v, &endianswap);
        if (config) {
                uae_u32 offset = addr & 0xff;
                if (!endianswap) {
@@ -671,7 +680,7 @@ static uae_u32 REGPARAM2 pci_config_wget(uaecptr addr)
 {
        uae_u32 v = 0xffff;
        int endianswap;
-       uae_u8 *config = get_pci_config(addr, -2, 0, &endianswap);
+       uae_u8 *config = get_pci_config(addr, -2, v, &endianswap);
        if (config) {
                uae_u32 offset = addr & 0xff;
                if (!endianswap) {
@@ -1118,6 +1127,15 @@ 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;
+                               } 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);
+                                               map_banks_z3(&pci_mem_bank, (expamem_board_pointer + 0x00000000) >> 16, (508 * 1024 * 1024) >> 16);
+                                               map_banks_z3(&pci_config_bank, (expamem_board_pointer + 0x1fc00000) >> 16, 0x100000 >> 16);
+                                       }
+                                       pcib->baseaddress_offset = pcib->baseaddress;
+                                       pcib->io_offset = expamem_board_pointer;
+                                       pcib->memory_start_offset = 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;
@@ -1580,7 +1598,7 @@ void pci_dump(int log)
                        _stprintf(txt, _T("%08X - %08X: Configuration space\n"), start, end - 1);
                        pci_dump_out(txt, log);
                        while (start < end) {
-                               struct pci_board_state *pcibs = get_pci_board_state_config(pcib, start);
+                               struct pci_board_state *pcibs = get_pci_board_state_config(pcib, start, false, 0);
                                if (pcibs && pcibs != oldpcibs) {
                                        const struct pci_board *pci = pcibs->board;
                                        if (pcibs->board) {
@@ -1589,7 +1607,7 @@ void pci_dump(int log)
                                                        start, pcibs->slot, pcibs->func, cfg->vendor, cfg->device, pci->label,
                                                        pcibs->io_map_active, pcibs->memory_map_active);
                                        } else {
-                                               int idx = pcib->get_index(start);
+                                               int idx = pcib->get_index(start, false, NULL);
                                                _stprintf(txt, _T("        - Slot %d: <none>\n"), idx & 0xff);
                                        }
                                        pci_dump_out(txt, log);
@@ -1702,7 +1720,7 @@ static uae_u32 REGPARAM2 wildfire_lget(struct pci_board_state *pcibs, uaecptr ad
        return v;
 }
 
-static int dkb_wildfire_get_index(uaecptr addr)
+static int dkb_wildfire_get_index(uaecptr addr, bool w, uae_u32 *vp)
 {
        int idx = 0;
        int slot = -1;
@@ -1835,8 +1853,9 @@ bool dkb_wildfire_pci_init(struct autoconfig_info *aci)
 }
 
 // Prometheus: 44359/1
-
 static const uae_u8 prometheus_autoconfig[16] = { 0x85, 0x01, 0x30, 0x00, 0xad, 0x47, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
+// Prometheus FireStorm: 3643/200
+static const uae_u8 prometheusfs_autoconfig[16] = { 0x85, 0xc8, 0x30, 0x00, 0x0e, 0x3b, 0x00, 0x00, 0x00, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
 
 static void ew(uae_u8 *acmemory, int addr, uae_u8 value)
 {
@@ -1849,7 +1868,7 @@ static void ew(uae_u8 *acmemory, int addr, uae_u8 value)
        }
 }
 
-static int prometheus_get_index(uaecptr addr)
+static int prometheus_get_index(uaecptr addr, bool w, uae_u32 *vp)
 {
        struct pci_bridge *pcib = get_pci_bridge(addr);
 
@@ -1863,6 +1882,43 @@ static int prometheus_get_index(uaecptr addr)
        return slot;
 }
 
+static int prometheusfs_get_index(uaecptr addr, bool w, uae_u32 *vp)
+{
+       struct pci_bridge *pcib = get_pci_bridge(addr);
+
+       addr -= pcib->baseaddress;
+       if ((addr & 0xfff00000) != 0x1fc00000) {
+               return -1;
+       }
+       if (addr & 0x8000) {
+               if (vp) {
+                       if (w) {
+                               uae_u32 v = *vp;
+                               pcib->intena = (v & (1 << 30)) ? 0xff : 0x00;
+                               pcib->reset = (v & (1 << 31)) != 0;
+                               return -1;
+                       }
+                       *vp = (pcib->irq ? (1 << 29) : 0) | (pcib->intena ? (1 << 30) : 0) | (pcib->reset ? (1 << 31) : 0);
+               }
+               return -1;
+       }
+       int slot = -1;
+       if ((addr & 0xf0000) == 0x10000) {
+               slot = 0;
+       } else if ((addr & 0xf0000) == 0x20000) {
+               slot = 1;
+       } else if ((addr & 0xf0000) == 0x40000) {
+               slot = 2;
+       } else if ((addr & 0xf0000) == 0x80000) {
+               slot = 3;
+       }
+       if (slot < 0) {
+               return -1;
+       }
+       slot |= ((addr >> 8) & 7) << 8;
+       return slot;
+}
+
 static bool prometheus_pci_init(struct autoconfig_info *aci)
 {
        device_add_reset(pci_reset);
@@ -1900,9 +1956,46 @@ static bool prometheus_pci_init(struct autoconfig_info *aci)
        return true;
 }
 
+static bool prometheusfs_pci_init(struct autoconfig_info *aci)
+{
+       device_add_reset(pci_reset);
+       if (!aci->doinit) {
+               for (int i = 0; i < sizeof prometheusfs_autoconfig; i++) {
+                       ew(aci->autoconfig_raw, i * 4, prometheusfs_autoconfig[i]);
+               }
+               return true;
+       }
+       struct romconfig *rc = aci->rc;
+       struct pci_bridge *pcib = pci_bridge_alloc_zorro(PCI_BRIDGE_PROMETHEUS_FS, rc);
+       if (!pcib)
+               return false;
+       pcib->label = _T("Prometheus FireStorm");
+       pcib->endian_swap_config = 1;
+       pcib->endian_swap_io = -1;
+       pcib->endian_swap_memory = -1;
+       pcib->intena = 0;
+       pcib->intreq_mask = 0x0008;
+       pcib->get_index = prometheusfs_get_index;
+       pcib->bank = &pci_bridge_bank;
+       pcib->bank_zorro = 3;
+       pcib->pcipcidma = true;
+       if (rc->device_settings & 1)
+               pcib->amigapicdma = true;
+
+       add_pci_devices(pcib, aci);
+
+       memset(pcib->acmemory, 0xff, sizeof pcib->acmemory);
+       for (int i = 0; i < sizeof prometheusfs_autoconfig; i++) {
+               ew(pcib->acmemory, i * 4, prometheusfs_autoconfig[i]);
+       }
+       aci->addrbank = pcib->bank;
+       pci_init();
+       return true;
+}
+
 // G-REX
 
-static int grex_get_index(uaecptr addr)
+static int grex_get_index(uaecptr addr, bool w, uae_u32 *vp)
 {
        int slot = -1;
        struct pci_bridge *pcib = get_pci_bridge(addr);
@@ -2003,7 +2096,7 @@ static struct mediator_autoconfig mediator_ac[] =
 };
 
 
-static int mediator_get_index_1200(uaecptr addr)
+static int mediator_get_index_1200(uaecptr addr, bool w, uae_u32 *vp)
 {
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
@@ -2019,7 +2112,7 @@ static int mediator_get_index_1200(uaecptr addr)
        return slot;
 }
 
-static int mediator_get_index_4000(uaecptr addr)
+static int mediator_get_index_4000(uaecptr addr, bool w, uae_u32 *vp)
 {
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
@@ -2275,6 +2368,11 @@ bool prometheus_init(struct autoconfig_info *aci)
        return prometheus_pci_init(aci);
 }
 
+bool prometheusfs_init(struct autoconfig_info *aci)
+{
+       return prometheusfs_pci_init(aci);
+}
+
 bool grex_init(struct autoconfig_info *aci)
 {
        return grex_pci_init(aci);
@@ -2282,7 +2380,7 @@ bool grex_init(struct autoconfig_info *aci)
 
 bool pci_expansion_init(struct autoconfig_info *aci)
 {
-       static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
+       static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, ROMTYPE_PROMETHEUSFS, 0 };
        aci->parent_romtype = parent;
        aci->zorro = 0;
        return true;