]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Voodoo 3 emulation from PCem.
authorToni Wilen <twilen@winuae.net>
Mon, 21 Dec 2020 19:23:51 +0000 (21:23 +0200)
committerToni Wilen <twilen@winuae.net>
Mon, 21 Dec 2020 19:23:51 +0000 (21:23 +0200)
28 files changed:
expansion.cpp
gfxboard.cpp
include/gfxboard.h
include/pci.h
include/pci_hw.h
include/rommgr.h
od-win32/picasso96_win.cpp
od-win32/picasso96_win.h
od-win32/winuae_msvc15/winuae_msvc.vcxproj
od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters
pcem/pcemglue.cpp
pcem/pcemglue.h
pcem/timer.h
pcem/vid_ddc.h [new file with mode: 0644]
pcem/vid_svga.h
pcem/vid_svga_render.cpp
pcem/vid_svga_render.h
pcem/vid_voodoo.cpp
pcem/vid_voodoo_banshee.cpp
pcem/vid_voodoo_banshee_blitter.cpp
pcem/vid_voodoo_codegen_x86-64.h
pcem/vid_voodoo_codegen_x86.h
pcem/vid_voodoo_display.cpp
pcem/vid_voodoo_fifo.cpp
pcem/vid_voodoo_render.cpp
pcem/vid_voodoo_render.h
pci.cpp
x86.cpp

index ee157c26573dd89621a3f2f6cb4611e430afcb68..b9b52fbc37d14351dfbf1213e0d330432ba5cef7 100644 (file)
@@ -5819,6 +5819,12 @@ const struct expansionromtype expansionroms[] = {
                NULL, 0,
                false, EXPANSIONTYPE_RTG
        },
+       {
+               _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
+       },
        {
                _T("x86vga"), _T("x86 VGA"), NULL,
                NULL, NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,
index 111588cfb41f6999358e43ad1ac468af01f92556..a87297a4e59602e9782ebe9a578df5e19ba02d40 100644 (file)
@@ -49,10 +49,19 @@ static bool memlogw = true;
 #include "pcem/vid_s3_virge.h"
 #include "pcem/vid_cl5429.h"
 #include "pcem/vid_s3.h"
-
+#include "pcem/vid_voodoo_banshee.h"
+#include "pci.h"
+#include "pci_hw.h"
+#include "pcem/pcemglue.h"
 #include "qemuvga/qemuuaeglue.h"
 #include "qemuvga/vga.h"
 
+extern void put_io_pcem(uaecptr, uae_u32, int);
+extern uae_u32 get_io_pcem(uaecptr, int);
+extern void put_mem_pcem(uaecptr, uae_u32, int);
+extern uae_u32 get_mem_pcem(uaecptr, int);
+
+
 #define MONITOR_SWITCH_DELAY 25
 
 #define GFXBOARD_AUTOCONFIG_SIZE 131072
@@ -112,6 +121,7 @@ struct gfxboard
        struct gfxboard_func *func;
        device_t *pcemdev;
        uae_u8 er_flags;
+       bool pci;
 };
 
 #define ISP4() (gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z2 || gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z3)
@@ -236,6 +246,14 @@ static const struct gfxboard boards[] =
                0, 0xc1, &a2410_func
        },
 #endif
+       {
+               GFXBOARD_ID_VOODOO3,
+               _T("Voodoo 3 3000"), _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
+       },
        {
                GFXBOARD_ID_VGA,
                _T("x86 bridgeboard VGA"), _T("x86"), _T("VGA"),
@@ -329,6 +347,9 @@ struct rtggfxboard
        addrbank gfxboard_bank_mmio_wbs_pcem;
        addrbank gfxboard_bank_mmio_lbs_pcem;
        addrbank gfxboard_bank_special_pcem;
+       addrbank gfxboard_bank_bios;
+
+       addrbank *old_pci_bank;
 
        addrbank *gfxmem_bank;
        uae_u8 *vram_back;
@@ -348,6 +369,10 @@ struct rtggfxboard
        int pcem_io_mask;
        int pcem_vblank;
        bool p4_revb;
+       uae_u8 *bios;
+       uae_u32 bios_mask;
+       int lfbbyteswapmode;
+       struct pci_board_state *pcibs;
 
        void *userdata;
 };
@@ -384,6 +409,7 @@ DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mmio_pcem);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mmio_wbs_pcem);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mmio_lbs_pcem);
 DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, special_pcem);
+DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, bios);
 
 static const addrbank tmpl_gfxboard_bank_memory = {
        gfxboard_lget_mem, gfxboard_wget_mem, gfxboard_bget_mem,
@@ -488,7 +514,6 @@ static const addrbank tmpl_gfxboard_bank_vram_p4z2_pcem = {
        ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
 };
 
-
 static const addrbank tmpl_gfxboard_bank_io_pcem = {
        gfxboard_lget_io_pcem, gfxboard_wget_io_pcem, gfxboard_bget_io_pcem,
        gfxboard_lput_io_pcem, gfxboard_wput_io_pcem, gfxboard_bput_io_pcem,
@@ -554,6 +579,24 @@ static const addrbank tmpl_gfxboard_bank_special_pcem = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
+static void REGPARAM2 dummy_lput(uaecptr addr, uae_u32 l)
+{
+}
+static void REGPARAM2 dummy_wput(uaecptr addr, uae_u32 l)
+{
+}
+static void REGPARAM2 dummy_bput(uaecptr addr, uae_u32 l)
+{
+}
+
+static const addrbank tmpl_gfxboard_bank_bios = {
+       gfxboard_lget_bios, gfxboard_wget_bios, gfxboard_bget_bios,
+       dummy_lput, dummy_wput, dummy_bput,
+       default_xlate, default_check, NULL, NULL, _T("SVGA BIOS"),
+       dummy_lgeti, dummy_wgeti,
+       ABFLAG_ROM | ABFLAG_SAFE, S_READ, S_WRITE
+};
+
 
 static void ew(struct rtggfxboard *gb, int addr, uae_u32 value)
 {
@@ -605,13 +648,32 @@ void gfxboard_free_vram(int index)
 extern uae_u8 *getpcembuffer32(int, int, int);
 extern int svga_get_vtotal(void);
 extern int svga_poll(void *p);
+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);
+               }
+       }
+#endif
+}
+
 void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
 {
        for (int i = 0; i < MAX_RTG_BOARDS; i++) {
                struct rtggfxboard *gb = &rtggfxboards[i];
                if (gb->pcemdev && gb->pcemobject) {
+                       pcem_flush(gb, i);
                        if (rtg_visible[gb->monitor_id] >= 0 && gb->monswitch_delay == 0 && gb->monswitch_current == gb->monswitch_new) {
                                if (gb->gfxboard_surface == NULL) {
                                        gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false);
@@ -626,12 +688,15 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
                                        }
                                }
                        }
+                       //picasso_getwritewatch(i, 0, NULL, NULL);
                }
        }
 }
 
 static int gfxboard_pcem_poll(struct rtggfxboard *gb)
 {
+       if (!gb->vram)
+               return 0;
        return svga_poll(gb->pcemobject2);
 }
 
@@ -641,12 +706,14 @@ static void gfxboard_rethink(void)
                struct rtggfxboard* gb = &rtggfxboards[i];
                if (gb->pcemdev && gb->pcemobject && gb->gfxboard_intreq && gb->gfxboard_intena) {
                        int irq = 0;
-                       if (gb->board->irq == 2 && gb->gfxboard_intena != 6)
-                               irq = 2;
-                       else
-                               irq = 6;
-                       if (irq) {
-                               safe_interrupt_set(IRQ_SOURCE_GFX, gb->monitor_id, irq == 6);
+                       if (gb->board->irq > 0) {
+                               if (gb->board->irq == 2 && gb->gfxboard_intena != 6)
+                                       irq = 2;
+                               else
+                                       irq = 6;
+                               if (irq > 0) {
+                                       safe_interrupt_set(IRQ_SOURCE_GFX, gb->monitor_id, irq == 6);
+                               }
                        }
                }
        }
@@ -678,6 +745,33 @@ static void gfxboard_hsync_handler(void)
                        }
                }
        }
+       pcemglue_hsync();
+}
+
+static void reinit_vram(struct rtggfxboard *gb, uaecptr vram, bool direct)
+{
+       if (vram == gb->gfxmem_bank->start)
+               return;
+       gb->vram = NULL;
+       mapped_free(gb->gfxmem_bank);
+       gb->gfxmem_bank->flags &= ~ABFLAG_ALLOCINDIRECT;
+       if (!direct) {
+               gb->gfxmem_bank->flags |= ABFLAG_ALLOCINDIRECT;
+       }
+       gb->gfxmem_bank->label = _T("*");
+       gb->gfxmem_bank->start = vram;
+       mapped_malloc(gb->gfxmem_bank);
+       gb->vram = gb->gfxmem_bank->baseaddr;
+       gb->vramend = gb->gfxmem_bank->baseaddr + gb->gfxmem_bank->reserved_size;
+       gb->vramrealstart = gb->vram;
+       gb->vram += gb->vram_start_offset;
+       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);
+       }
 }
 
 static void init_board (struct rtggfxboard *gb)
@@ -713,6 +807,10 @@ static void init_board (struct rtggfxboard *gb)
        if (gb->board->manufacturer) {
                gb->gfxmem_bank->label = _T("*");
                mapped_malloc(gb->gfxmem_bank);
+       } else if (gb->board->pci) {
+               // We don't know VRAM address until PCI bridge and
+               // PCI display card's BARs have been initialized
+               ;
        } else {
                gb->gfxmem_bank->label = _T("*");
                gb->vram_back = xmalloc(uae_u8, vramsize);
@@ -731,8 +829,10 @@ static void init_board (struct rtggfxboard *gb)
        //gb->gfxmem_bank->baseaddr = gb->vram;
        // restore original value because this is checked against
        // configured size in expansion.cpp
-       gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
-       gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
+       if (!gb->board->pci) {
+               gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
+               gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
+       }
        gb->vga.vga.vram_size_mb = rbc->rtgmem_size >> 20;
        gb->vgaioregion.opaque = &gb->vgaioregionptr;
        gb->vgaioregion.data = gb;
@@ -752,7 +852,9 @@ static void init_board (struct rtggfxboard *gb)
        gb->fakesurface.data = gb;
        vga_common_init(&gb->vga.vga);
        gb->vga.vga.con = (void*)gb;
-       cirrus_init_common(&gb->vga, chiptype, 0,  NULL, NULL, gb->board->manufacturer == 0, gb->board->romtype == ROMTYPE_x86_VGA);
+       if (chiptype) {
+               cirrus_init_common(&gb->vga, chiptype, 0, NULL, NULL, gb->board->manufacturer == 0, gb->board->romtype == ROMTYPE_x86_VGA);
+       }
        gb->pcemdev = gb->board->pcemdev;
        gb->pcem_pci_configured = false;
        if (gb->pcemdev) {
@@ -984,9 +1086,6 @@ static void vga_update_size_ext(struct rtggfxboard *gb)
 static void gfxboard_set_fullrefresh(struct rtggfxboard *gb, int cnt)
 {
        gb->fullrefresh = cnt;
-       if (gb->pcemdev && gb->pcemobject) {
-               gb->pcemdev->force_redraw(gb->pcemobject);
-       }
 }
 
 static bool gfxboard_setmode_ext(struct rtggfxboard *gb)
@@ -1266,16 +1365,30 @@ void gfxboard_refresh(int monid)
        }
 }
 
+static void set_monswitch(struct rtggfxboard *gb, bool newval)
+{
+       if (gb->monswitch_new == newval)
+               return;
+       gb->monswitch_new = newval;
+       gb->monswitch_delay = MONITOR_SWITCH_DELAY;
+}
+
 void gfxboard_intreq(void *p, int act, bool safe)
 {
        struct rtggfxboard *gb = (struct rtggfxboard*)p;
        if (act) {
                if (gb->board->irq && gb->gfxboard_intena) {
-                       int irq = 0;
-                       gb->gfxboard_intreq = 1;
+                       if (gb->board->irq > 0) {
+                               gb->gfxboard_intreq = 1;
+                       } else {
+                               gb->pcibs->irq_callback(gb->pcibs, true);
+                       }
                }
        } else {
                gb->gfxboard_intreq = 0;
+               if (gb->board->irq < 0) {
+                       gb->pcibs->irq_callback(gb->pcibs, false);
+               }
        }
        gfxboard_rethink();
 }
@@ -1323,7 +1436,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
                                        fcount++;
                                        if ((fcount % 50) == 0) {
                                                if (gb->pcemobject && gb->pcemdev->add_status_info) {
-                                                       char txt[256];
+                                                       char txt[1024];
                                                        txt[0] = 0;
                                                        gb->pcemdev->add_status_info(txt, sizeof(txt), gb->pcemobject);
                                                        TCHAR *s = au(txt);
@@ -1332,6 +1445,10 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
                                                }
                                        }
                                }
+                               if (gb->board->pci && gb->vram) {
+                                       bool svga_on(void* p);
+                                       set_monswitch(gb, svga_on(gb->pcemobject));
+                               }
                        }
 
                        if (gb->monswitch_keep_trying) {
@@ -1425,13 +1542,23 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
                        continue;
 
                if (!gb->monswitch_delay && gb->monswitch_current && ad->picasso_on && ad->picasso_requested_on && !gb->resolutionchange) {
-                       picasso_getwritewatch(i, gb->vram_start_offset);
                        if (!gb->pcemdev) {
+                               if (picasso_getwritewatch(i, gb->vram_start_offset, NULL, NULL) < 0) {
+                                       gb->fullrefresh = 1;
+                               }
                                if (gb->fullrefresh)
                                        gb->vga.vga.graphic_mode = -1;
                                gb->vga_refresh_active = true;
                                gb->vga.vga.hw_ops->gfx_update(&gb->vga);
                                gb->vga_refresh_active = false;
+                       } else {
+                               if (gb->pcemobject) {
+                                       if (gb->fullrefresh) {
+                                               gb->pcemdev->force_redraw(gb->pcemobject);
+                                       } else {
+                                               pcem_flush(gb, i);
+                                       }
+                               }
                        }
                }
 
@@ -1605,14 +1732,6 @@ static void reset_pci (struct rtggfxboard *gb)
        gb->p4i2c = 0xff;
 }
 
-static void set_monswitch(struct rtggfxboard *gb, bool newval)
-{
-       if (gb->monswitch_new == newval)
-               return;
-       gb->monswitch_new = newval;
-       gb->monswitch_delay = MONITOR_SWITCH_DELAY;
-}
-
 static void picassoiv_checkswitch (struct rtggfxboard *gb)
 {
        if (ISP4()) {
@@ -2939,6 +3058,8 @@ static void gfxboard_free_board(struct rtggfxboard *gb)
        gb->vramrealstart = NULL;
        xfree(gb->fakesurface_surface);
        gb->fakesurface_surface = NULL;
+       xfree(gb->bios);
+       gb->bios = NULL;
        gb->configured_mem = 0;
        gb->configured_regs = 0;
        gb->monswitch_new = false;
@@ -3348,6 +3469,281 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v)
        }
 }
 
+static void pci_change_config(struct pci_board_state *pci)
+{
+       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);
+               }
+       }
+}
+
+void gfxboard_voodoo_lfb_endianswap(int m)
+{
+       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);
+                               }
+                       }
+                       return;
+               }
+       }
+}
+
+static void REGPARAM2 voodoo3_io_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       put_io_pcem(addr, b, 2);
+}
+static void REGPARAM2 voodoo3_io_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       put_io_pcem(addr, b, 1);
+}
+static void REGPARAM2 voodoo3_io_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       put_io_pcem(addr, b, 0);
+}
+static uae_u32 REGPARAM2 voodoo3_io_lget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return get_io_pcem(addr, 2);
+}
+static uae_u32 REGPARAM2 voodoo3_io_wget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return get_io_pcem(addr, 1);
+}
+static uae_u32 REGPARAM2 voodoo3_io_bget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return get_io_pcem(addr, 0);
+}
+
+static void REGPARAM2 voodoo3_mb0_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       put_mem_pcem(addr, b, 2);
+}
+static void REGPARAM2 voodoo3_mb0_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       put_mem_pcem(addr, b, 1);
+}
+static void REGPARAM2 voodoo3_mb0_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       put_mem_pcem(addr, b, 0);
+}
+static uae_u32 REGPARAM2 voodoo3_mb0_lget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return get_mem_pcem(addr, 2);
+}
+static uae_u32 REGPARAM2 voodoo3_mb0_wget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return get_mem_pcem(addr, 1);
+}
+static uae_u32 REGPARAM2 voodoo3_mb0_bget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return get_mem_pcem(addr, 0);
+}
+
+static void REGPARAM2 voodoo3_mb1_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
+       int m = gb->lfbbyteswapmode;
+       addr -= pcibs->bar[1];
+       addr &= 0x00ffffff;
+       switch (m)
+       {
+       case 0:
+               //((uae_u32*)(addr + gb->vram))[0] = b;
+               pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
+               break;
+       case 1:
+               //do_put_mem_long((uae_u32*)(addr + gb->vram), b);
+               b = do_byteswap_32(b);
+               pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
+               break;
+       case 2:
+               //((uae_u32*)(addr + gb->vram))[0] = b;
+               b = do_byteswap_32(b);
+               pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
+               break;
+       case 3:
+               b = (b >> 16) | (b << 16);
+               b = do_byteswap_32(b);
+               pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
+               //do_put_mem_long((uae_u32*)(addr + gb->vram), b);
+               break;
+       }
+}
+static uae_u32 REGPARAM2 voodoo3_mb1_lget(struct pci_board_state* pcibs, uaecptr addr)
+{
+       struct rtggfxboard* gb = (struct rtggfxboard*)pcibs->userdata;
+       int m = gb->lfbbyteswapmode;
+       uae_u32 v = 0;
+       addr -= pcibs->bar[1];
+       addr &= 0x00ffffff;
+       switch (m)
+       {
+       case 0:
+               //v = ((uae_u32*)(addr + gb->vram))[0];
+               v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
+               break;
+       case 1:
+               //v = do_get_mem_long((uae_u32*)(addr + gb->vram));
+               v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
+               v = do_byteswap_32(v);
+               break;
+       case 2:
+               //v = ((uae_u32*)(addr + gb->vram))[0];
+               v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
+               v = do_byteswap_32(v);
+               break;
+       case 3:
+               //v = do_get_mem_long((uae_u32*)(addr + gb->vram));
+               v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
+               v = do_byteswap_32(v);
+               v = (v >> 16) | (v << 16);
+               break;
+       }
+       return v;
+}
+
+static void REGPARAM2 voodoo3_mb1_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
+       int m = gb->lfbbyteswapmode;
+       addr -= pcibs->bar[1];
+       addr &= 0x00ffffff;
+       switch (m)
+       {
+       case 0:
+               //*((uae_u16*)(addr + gb->vram)) = b;
+               pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
+               break;
+       case 1:
+               addr ^= 2;
+               b = do_byteswap_16(b);
+               //do_put_mem_word((uae_u16*)(addr + gb->vram), b);
+               pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
+               break;
+       case 2:
+               //do_put_mem_word((uae_u16*)(addr + gb->vram), b);
+               b = do_byteswap_16(b);
+               pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
+               break;
+       case 3:
+               //do_put_mem_word((uae_u16*)(addr + gb->vram), b);
+               b = do_byteswap_16(b);
+               pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
+               break;
+       }
+}
+static uae_u32 REGPARAM2 voodoo3_mb1_wget(struct pci_board_state* pcibs, uaecptr addr)
+{
+       struct rtggfxboard* gb = (struct rtggfxboard*)pcibs->userdata;
+       int m = gb->lfbbyteswapmode;
+       uae_u32 v = 0;
+       addr -= pcibs->bar[1];
+       addr &= 0x00ffffff;
+       switch (m)
+       {
+       case 0:
+               //v = *((uae_u16*)(addr + gb->vram));
+               v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
+               break;
+       case 1:
+               addr ^= 2;
+               //v = *((uae_u16*)(addr + gb->vram));
+               v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
+               v = do_byteswap_16(v);
+               break;
+       case 2:
+               //v = do_get_mem_word((uae_u16*)(addr + gb->vram));
+               v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
+               v = do_byteswap_16(v);
+               break;
+       case 3:
+               //v = do_get_mem_word((uae_u16*)(addr + gb->vram));
+               v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
+               v = do_byteswap_16(v);
+               break;
+       }
+       return v;
+}
+
+static void REGPARAM2 voodoo3_mb1_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
+{
+       struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
+       int m = gb->lfbbyteswapmode;
+       addr -= pcibs->bar[1];
+       addr &= 0x00ffffff;
+       pcem_linear_write_b(addr, b, pcem_mapping_linear_priv);
+       //do_put_mem_byte((uae_u8*)(addr + gb->vram), b);
+}
+static uae_u32 REGPARAM2 voodoo3_mb1_bget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
+       int m = gb->lfbbyteswapmode;
+       addr -= pcibs->bar[1];
+       addr &= 0x00ffffff;
+       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;
+}
+
+
+static uae_u32 REGPARAM2 voodoo3_bios_bget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       struct rtggfxboard* gb = getgfxboard(addr);
+       addr &= gb->bios_mask;
+       return gb->bios[addr];
+}
+static uae_u32 REGPARAM2 voodoo3_bios_wget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return (voodoo3_bios_bget(pcibs, addr) << 0) | (voodoo3_bios_bget(pcibs, addr + 1) << 8);
+}
+static uae_u32 REGPARAM2 voodoo3_bios_lget(struct pci_board_state *pcibs, uaecptr addr)
+{
+       return (voodoo3_bios_wget(pcibs, addr + 0) << 24) | (voodoo3_bios_wget(pcibs, addr + 1) << 16) | (voodoo3_bios_wget(pcibs, addr + 2) << 8) | (voodoo3_bios_wget(pcibs, addr + 3) << 0);
+}
+
+uae_u8 get_pci_pcem(uaecptr addr);
+void put_pci_pcem(uaecptr addr, uae_u8 v);
+static const struct pci_config voodoo3_pci_config =
+{
+       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 1, 0, 0, 0, 0 }
+};
+
+static const struct pci_board voodoo3_pci_board =
+{
+       _T("VOODOO3"),
+       &voodoo3_pci_config, NULL, NULL, NULL, NULL,
+       {
+               { voodoo3_mb0_lget, voodoo3_mb0_wget, voodoo3_mb0_bget, voodoo3_mb0_lput, voodoo3_mb0_wput, voodoo3_mb0_bput },
+               { voodoo3_mb1_lget, voodoo3_mb1_wget, voodoo3_mb1_bget, voodoo3_mb1_lput, voodoo3_mb1_wput, voodoo3_mb1_bput },
+               { voodoo3_io_lget, voodoo3_io_wget, voodoo3_io_bget, voodoo3_io_lput, voodoo3_io_wput, voodoo3_io_bput },
+               { NULL },
+               { NULL },
+               { NULL },
+               { voodoo3_bios_lget, voodoo3_bios_wget, voodoo3_bios_bget, NULL, NULL, NULL },
+       },
+       true,
+       get_pci_pcem, put_pci_pcem, pci_change_config
+};
+
+
+
 int gfxboard_get_index_from_id(int id)
 {
        if (id == GFXBOARD_UAE_Z2)
@@ -3661,11 +4057,17 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
                        gb->monswitch_keep_trying = true;
                }
        }
+       if (gb->board->pci) {
+               aci->zorro = -1;
+       }
        aci->parent = aci;
        if (!aci->doinit) {
                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) {
+                       static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
+                       aci->parent_romtype = parent;
                } else {
                        memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
                }
@@ -3714,6 +4116,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
        memcpy(&gb->gfxboard_bank_mmio_wbs_pcem, &tmpl_gfxboard_bank_mmio_wbs_pcem, sizeof addrbank);
        memcpy(&gb->gfxboard_bank_mmio_lbs_pcem, &tmpl_gfxboard_bank_mmio_lbs_pcem, sizeof addrbank);
        memcpy(&gb->gfxboard_bank_special_pcem, &tmpl_gfxboard_bank_special_pcem, sizeof addrbank);
+       memcpy(&gb->gfxboard_bank_bios, &tmpl_gfxboard_bank_bios, sizeof addrbank);
 
        gb->gfxboard_bank_memory.name = gb->memorybankname;
        gb->gfxboard_bank_memory_nojit.name = gb->memorybanknamenojit;
@@ -3727,6 +4130,36 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
 
        gb->active = true;
 
+       if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3) {
+
+               TCHAR path[MAX_DPATH];
+               fetch_rompath(path, sizeof path / sizeof(TCHAR));
+               _tcscat(path, _T("voodoo3.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);
+               } else {
+                       error_log(_T("Voodoo 3 BIOS ROM (<rom path>\\voodoo3.rom) failed to load!\n"));
+               }
+               gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
+               gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
+               gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
+               init_board(gb);
+               copyvrambank(&gb->gfxboard_bank_memory, gb->gfxmem_bank, false);
+               gb->configured_mem = 1;
+               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);
+               }
+               gb->gfxboard_intena = 1;
+               return true;
+       }
+
        if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
                init_board(gb);
                gb->configured_mem = 1;
@@ -3809,22 +4242,23 @@ bool gfxboard_init_registers (struct autoconfig_info *aci)
        return true;
 }
 
+static uae_u32 REGPARAM2 gfxboard_bget_bios(uaecptr addr)
+{
+       struct rtggfxboard *gb = getgfxboard(addr);
+       addr &= gb->bios_mask;
+       return gb->bios[addr];
+}
+static uae_u32 REGPARAM2 gfxboard_wget_bios(uaecptr addr)
+{
+       return (gfxboard_bget_bios(addr) << 8) | (gfxboard_bget_bios(addr + 1) << 0);
+}
+static uae_u32 REGPARAM2 gfxboard_lget_bios(uaecptr addr)
+{
+       return (gfxboard_bget_bios(addr + 0) << 24) | (gfxboard_bget_bios(addr + 1) << 16) | (gfxboard_bget_bios(addr + 2) << 8) | (gfxboard_bget_bios(addr + 3) << 0);
+}
 
 // PCem wrapper
 
-extern uint8_t(*pcem_linear_read_b)(uint32_t addr, void *priv);
-extern uint16_t(*pcem_linear_read_w)(uint32_t addr, void *priv);
-extern uint32_t(*pcem_linear_read_l)(uint32_t addr, void *priv);
-extern void (*pcem_linear_write_b)(uint32_t addr, uint8_t  val, void *priv);
-extern void (*pcem_linear_write_w)(uint32_t addr, uint16_t val, void *priv);
-extern void (*pcem_linear_write_l)(uint32_t addr, uint32_t val, void *priv);
-extern void *pcem_mapping_linear_priv;
-extern uae_u32 pcem_mapping_linear_offset;
-
-
-extern void put_mem_pcem(uaecptr, uae_u32, int);
-extern uae_u32 get_mem_pcem(uaecptr, int);
-
 static uae_u32 REGPARAM2 gfxboard_bget_vram_normal_pcem(uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
@@ -3884,26 +4318,24 @@ static uae_u32 REGPARAM2 gfxboard_bget_vram_longswap_pcem(uaecptr addr)
        struct rtggfxboard *gb = getgfxboard(addr);
        addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
        addr += gb->pcem_vram_offset;
-       uae_u8  v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
+       uae_u8 v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
        return v;
 }
 static uae_u32 REGPARAM2 gfxboard_wget_vram_longswap_pcem(uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       uae_u16 v;
        addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
        addr += gb->pcem_vram_offset;
-       v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
+       uae_u16 v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
        v = do_byteswap_16(v);
        return v;
 }
 static uae_u32 REGPARAM2 gfxboard_lget_vram_longswap_pcem(uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       uae_u32 v;
        addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
        addr += gb->pcem_vram_offset;
-       v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
+       uae_u32 v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
        v = do_byteswap_32(v);
        return v;
 }
@@ -3941,25 +4373,23 @@ static uae_u32 REGPARAM2 gfxboard_bget_vram_wordswap_pcem(uaecptr addr)
        addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
        addr += gb->pcem_vram_offset;
        addr ^= 1;
-       uae_u8  v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
+       uae_u8 v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
        return v;
 }
 static uae_u32 REGPARAM2 gfxboard_wget_vram_wordswap_pcem(uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       uae_u16 v;
        addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
        addr += gb->pcem_vram_offset;
-       v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
+       uae_u16 v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
        return v;
 }
 static uae_u32 REGPARAM2 gfxboard_lget_vram_wordswap_pcem(uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
-       uae_u32 v;
        addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
        addr += gb->pcem_vram_offset;
-       v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
+       uae_u32 v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
        v = (v >> 16) | (v << 16);
        return v;
 }
@@ -4256,9 +4686,6 @@ static void REGPARAM2 gfxboard_lput_vram_p4z2_pcem(uaecptr addr, uae_u32 l)
 
 
 
-extern void put_io_pcem(uaecptr, uae_u32, int);
-extern uae_u32 get_io_pcem(uaecptr, int);
-
 static uae_u32 REGPARAM2 gfxboard_lget_io_pcem(uaecptr addr)
 {
        struct rtggfxboard *gb = getgfxboard(addr);
index 8a6e184567ec7b9b4462b44e1eeb95657101e56f..e27b842ecf8e4c57c9efdf6df491cc27e9651e06 100644 (file)
@@ -76,6 +76,7 @@ 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
 
 
 struct gfxboard_mode
index 1842ff48b2b71010ace45f554d9efe77786df716..ffbd54822b4344c767b466601018f46529aa3511 100644 (file)
@@ -10,5 +10,8 @@ extern bool grex_init(struct autoconfig_info *aci);
 extern bool mediator_init(struct autoconfig_info *aci);
 extern bool mediator_init2(struct autoconfig_info *aci);
 extern bool pci_expansion_init(struct autoconfig_info *aci);
+extern struct pci_bridge *pci_bridge_get(void);
+extern struct pci_board_state *pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int slot, int func, struct autoconfig_info *aci, void *userdata);
+extern bool pci_validate_address(uaecptr, uae_u32, bool);
 
 #endif /* UAE_PCI_H */
index f905256377925d8d1e9164a2af54e51e5ea47928..2cbcdfc15799ea6b0662bc10545584f146782c45 100644 (file)
@@ -13,6 +13,9 @@ typedef bool(*pci_dev_init)(struct pci_board_state*,struct autoconfig_info*);
 typedef void(*pci_dev_reset)(struct pci_board_state*);
 typedef void(*pci_dev_hsync)(struct pci_board_state*);
 typedef void(*pci_dev_free)(struct pci_board_state*);
+typedef uae_u8(*pci_get_config_func)(uaecptr);
+typedef void(*pci_put_config_func)(uaecptr, uae_u8);
+typedef void(*pci_change_config_func)(struct pci_board_state*);
 
 typedef struct
 {
@@ -48,6 +51,11 @@ struct pci_board
        pci_dev_reset reset;
        pci_dev_hsync hsync;
        pci_addrbank bars[MAX_PCI_BARS];
+       bool dont_mask_io;
+       pci_get_config_func pci_get_config;
+       pci_put_config_func pci_put_config;
+       pci_change_config_func pci_change_config;
+
 };
 
 struct pci_board_state
@@ -67,6 +75,8 @@ struct pci_board_state
        bool io_map_active;
        struct pci_bridge *bridge;
        pci_dev_irq irq_callback;
+       struct pci_config dynamic_config;
+       void *userdata;
 };
 
 struct pci_bridge
@@ -75,8 +85,9 @@ struct pci_bridge
        int type;
        int endian_swap_config;
        uae_u32 io_offset;
+       uae_u32 memory_start_offset;
        int endian_swap_io;
-       uae_u32 memory_offset;
+       uae_u32 memory_window_offset;
        int endian_swap_memory;
        bool pcipcidma;
        bool amigapicdma;
index 1d16012484f8d3723aefef511b2aba2f92d2460c..4e7a3ac285578dcf666f94c6eb18d583faf46222 100644 (file)
@@ -197,6 +197,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
 #define ROMTYPE_ALF2           0x00100085
 #define ROMTYPE_SYNTHESIS      0x00100086
 #define ROMTYPE_MASTFB         0x00100087
+#define ROMTYPE_VOODOO3                0x00100088
 
 #define ROMTYPE_NOT                    0x00800000
 #define ROMTYPE_QUAD           0x01000000
index 5756984ea08f8b257ceb0aa92fe9f6444390e813..329fe35a1e53a83ce4ef551701a700a8a6005ea2 100644 (file)
@@ -2295,16 +2295,22 @@ void picasso_allocatewritewatch (int index, int gfxmemsize)
 
 static ULONG_PTR writewatchcount[MAX_RTG_BOARDS];
 static int watch_offset[MAX_RTG_BOARDS];
-void picasso_getwritewatch (int index, int offset)
+int picasso_getwritewatch (int index, int offset, uae_u8 ***gwwbufp, uae_u8 **startp)
 {
        ULONG ps;
        writewatchcount[index] = gwwbufsize[index];
        watch_offset[index] = offset;
+       uae_u8 *start = gfxmem_banks[index]->start + natmem_offset + offset;
        if (GetWriteWatch (WRITE_WATCH_FLAG_RESET, gfxmem_banks[index]->start + natmem_offset + offset, (gwwbufsize[index] - 1) * gwwpagesize[index], gwwbuf[index], &writewatchcount[index], &ps)) {
                write_log (_T("picasso_getwritewatch %d\n"), GetLastError ());
                writewatchcount[index] = 0;
-               return;
+               return -1;
        }
+       if (gwwbufp)
+               *gwwbufp = (uae_u8**)gwwbuf[index];
+       if (startp)
+               *startp = start;
+       return writewatchcount[index];
 }
 bool picasso_is_vram_dirty (int index, uaecptr addr, int size)
 {
index 5e10fc70e5cf2efed60623408d5ebe78b6b2087e..74b86a74255d4882bbbacaa47b78fb0cf87096f7 100644 (file)
@@ -640,7 +640,7 @@ extern bool picasso_is_active(int monid);
 extern int picasso_setwincursor(int monid);
 extern int picasso_palette(struct MyCLUTEntry *MCLUT, uae_u32 *clut);
 extern void picasso_allocatewritewatch (int index, int gfxmemsize);
-extern void picasso_getwritewatch (int index, int offset);
+extern int picasso_getwritewatch(int index, int offset, uae_u8 ***gwwbufp, uae_u8 **startp);
 extern bool picasso_is_vram_dirty (int index, uaecptr addr, int size);
 extern void picasso_statusline (int monid, uae_u8 *dst);
 extern void picasso_invalidate(int monid, int x, int y, int w, int h);
index b0b02da9f064bf8e3ba40ce9545027c2ab4a8739..9477f5f123e29168a44e494f4b8e56fcc6c64555 100644 (file)
       <OmitFramePointers>true</OmitFramePointers>
       <WholeProgramOptimization>false</WholeProgramOptimization>
       <AdditionalIncludeDirectories>..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;..\..\ppc\pearpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <ExceptionHandling>Sync</ExceptionHandling>
       <BasicRuntimeChecks>Default</BasicRuntimeChecks>
       <OmitFramePointers>false</OmitFramePointers>
       <WholeProgramOptimization>false</WholeProgramOptimization>
       <AdditionalIncludeDirectories>..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <ExceptionHandling>Sync</ExceptionHandling>
       <BasicRuntimeChecks>Default</BasicRuntimeChecks>
       <OmitFramePointers>true</OmitFramePointers>
       <WholeProgramOptimization>true</WholeProgramOptimization>
       <AdditionalIncludeDirectories>..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
-      <PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <StringPooling>true</StringPooling>
       <ExceptionHandling>Sync</ExceptionHandling>
       <BasicRuntimeChecks>Default</BasicRuntimeChecks>
     <ClCompile Include="..\..\pcem\vid_sdac_ramdac.cpp" />
     <ClCompile Include="..\..\pcem\vid_svga.cpp" />
     <ClCompile Include="..\..\pcem\vid_svga_render.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_banshee.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_banshee_blitter.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_blitter.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_display.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_fb.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_fifo.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_reg.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_render.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_setup.cpp" />
+    <ClCompile Include="..\..\pcem\vid_voodoo_texture.cpp" />
     <ClCompile Include="..\..\pcem\x86seg.cpp" />
     <ClCompile Include="..\..\pcem\x87.cpp" />
     <ClCompile Include="..\..\pcem\x87_timings.cpp" />
index 27a8b4eb2efe69d5cf25da7cb7b3ebca6bb92bfb..9b2d7a8d1234c9bd8081a6c80971655390e7c85a 100644 (file)
     <ClCompile Include="..\FX11\EffectRuntime.cpp">
       <Filter>win32\FX11</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_banshee.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_banshee_blitter.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_display.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_fifo.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_render.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_fb.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_reg.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_setup.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_blitter.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo_texture.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\pcem\vid_voodoo.cpp">
+      <Filter>pcem</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="..\resources\35floppy.ico">
index a8462bd947baa79d1ec41539d99567f4de5cce92..d01a1a0608ba6e502fcb80eba18cb3bb7c11f89d 100644 (file)
@@ -461,6 +461,70 @@ uint64_t timer_read(void)
        return read_processor_time();
 }
 
+static pc_timer_t *timer_head = NULL;
+
+void timer_enablex(pc_timer_t *timer)
+{
+       pc_timer_t *timer_node = timer_head;
+       if (timer->enabled)
+               timer_disablex(timer);
+       timer->enabled = 1;
+       if (!timer_head)
+       {
+               timer_head = timer;
+               timer->next = timer->prev = NULL;
+               return;
+       }
+       timer_node = timer_head;
+}
+void timer_disablex(pc_timer_t *timer)
+{
+       if (!timer->enabled)
+               return;
+       timer->enabled = 0;
+       if (timer->prev)
+               timer->prev->next = timer->next;
+       else
+               timer_head = timer->next;
+       if (timer->next)
+               timer->next->prev = timer->prev;
+       timer->prev = timer->next = NULL;
+}
+void timer_addx(pc_timer_t *timer, void (*callback)(void* p), void *p, int start_timer)
+{
+       memset(timer, 0, sizeof(pc_timer_t));
+
+       timer->callback = callback;
+       timer->p = p;
+       timer->enabled = 0;
+       timer->prev = timer->next = NULL;
+}
+void timer_set_delay_u64x(pc_timer_t *timer, uint64_t delay)
+{
+       timer_enablex(timer);
+}
+static void timer_remove_headx(void)
+{
+       if (timer_head)
+       {
+               pc_timer_t *timer = timer_head;
+               timer_head = timer->next;
+               if (timer_head) {
+                       timer_head->prev = NULL;
+               }
+               timer->next = timer->prev = NULL;
+               timer->enabled = 0;
+       }
+}
+
+void pcemglue_hsync(void)
+{
+       while (timer_head) {
+               timer_head->callback(timer_head->p);
+               timer_remove_headx();
+       }
+}
+
 void initpcemvideo(void *p, bool swapped)
 {
        int c, d, e;
@@ -536,6 +600,7 @@ void initpcemvideo(void *p, bool swapped)
        pcem_linear_write_l = dummy_lwrite;
        pcem_mapping_linear = NULL;
        pcem_mapping_linear_offset = 0;
+       timer_head = NULL;
 
 }
 
@@ -680,6 +745,37 @@ void thread_destroy_event(event_t *_event)
        uae_sem_destroy((uae_sem_t*)&_event);
 }
 
+typedef struct win_mutex_t
+{
+       HANDLE handle;
+} win_mutex_t;
+
+mutex_t* thread_create_mutex(void)
+{
+       win_mutex_t* mutex = xcalloc(win_mutex_t,1);
+       mutex->handle = CreateSemaphore(NULL, 1, 1, NULL);
+       return mutex;
+}
+
+void thread_lock_mutex(mutex_t* _mutex)
+{
+       win_mutex_t* mutex = (win_mutex_t*)_mutex;
+       WaitForSingleObject(mutex->handle, INFINITE);
+}
+
+void thread_unlock_mutex(mutex_t* _mutex)
+{
+       win_mutex_t* mutex = (win_mutex_t*)_mutex;
+       ReleaseSemaphore(mutex->handle, 1, NULL);
+}
+
+void thread_destroy_mutex(mutex_t* _mutex)
+{
+       win_mutex_t* mutex = (win_mutex_t*)_mutex;
+       CloseHandle(mutex->handle);
+       xfree(mutex);
+}
+
 static mem_mapping_t *getmm(uaecptr *addrp)
 {
        uaecptr addr = *addrp;
@@ -974,3 +1070,10 @@ void mem_mapping_enablex(mem_mapping_t *mapping)
        mapping_recalc(mapping);
 }
 
+void pcem_linear_mark(int offset)
+{
+       if (!pcem_mapping_linear)
+               return;
+       uae_u16 w = pcem_linear_read_w(offset, pcem_mapping_linear_priv);
+       pcem_linear_write_w(offset, w, pcem_mapping_linear_priv);
+}
\ No newline at end of file
index 8c5ed7aa78c1d6089e53e70f88ea6caa0c4258a7..1a8a32b962ef3a6a3192f831dbc0cf002fb60c08 100644 (file)
@@ -1,12 +1,22 @@
 
 extern void pcem_close(void);
+extern void pcemglue_hsync(void);
 
 uint8_t keyboard_at_read(uint16_t port, void *priv);
 uint8_t mem_read_romext(uint32_t addr, void *priv);
 uint16_t mem_read_romextw(uint32_t addr, void *priv);
 uint32_t mem_read_romextl(uint32_t addr, void *priv);
+void pcem_linear_mark(int offset);
 
 extern int SOUNDBUFLEN;
 extern int32_t *x86_sndbuffer[2];
 extern bool x86_sndbuffer_filled[2];
 
+extern void *pcem_mapping_linear_priv;
+extern uae_u32 pcem_mapping_linear_offset;
+extern uint8_t(*pcem_linear_read_b)(uint32_t addr, void* priv);
+extern uint16_t(*pcem_linear_read_w)(uint32_t addr, void* priv);
+extern uint32_t(*pcem_linear_read_l)(uint32_t addr, void* priv);
+extern void (*pcem_linear_write_b)(uint32_t addr, uint8_t  val, void* priv);
+extern void (*pcem_linear_write_w)(uint32_t addr, uint16_t val, void* priv);
+extern void (*pcem_linear_write_l)(uint32_t addr, uint32_t val, void* priv);
index ddcd9c004cfe79eba7e2821dc889bbca9b6255c8..f22acb7fbd0567359f94bec21191df64dd524403 100644 (file)
@@ -139,4 +139,12 @@ static inline void timer_set_p(pc_timer_t *timer, void *p)
         timer->p = p;
 }
 
+#ifdef UAE
+void timer_addx(pc_timer_t* timer, void (*callback)(void* p), void* p, int start_timer);
+void timer_enablex(pc_timer_t *timer);
+void timer_disablex(pc_timer_t *timer);
+void timer_set_delay_u64x(pc_timer_t *timer, uint64_t delay);
+#endif
+
+
 #endif /*_TIMER_H_*/
diff --git a/pcem/vid_ddc.h b/pcem/vid_ddc.h
new file mode 100644 (file)
index 0000000..7b8f8bd
--- /dev/null
@@ -0,0 +1,4 @@
+void ddc_init(void);
+void ddc_i2c_change(int new_clock, int new_data);
+int ddc_read_clock(void);
+int ddc_read_data(void);
index a4bbd73c89c8dabca1472c663a0c46d9c830a0f3..e0d6900d43fff915bddd1792df1d6b7851aebe7b 100644 (file)
@@ -50,7 +50,7 @@ typedef struct svga_t
         int set_reset_disabled;
         
         uint8_t egapal[16];
-        uint32_t pallook[256];
+        uint32_t pallook[512];
         PALETTE vgapal;
         
         int ramdac_type;
@@ -60,7 +60,7 @@ typedef struct svga_t
         int lowres, interlace;
         int linedbl, rowcount;
         double clock;
-        uint32_t ma_latch;
+        uint32_t ma_latch, ca_adj;
         int bpp;
         
         uint64_t dispontime, dispofftime;
@@ -93,6 +93,8 @@ typedef struct svga_t
         int fullchange;
         
         int video_res_x, video_res_y, video_bpp;
+        int video_res_override; /*If clear then SVGA code will set above variables, if
+                                  set then card code will*/
         int frames, fps;
 
         struct
index 55ed2f9151ed075337efe41897b23fa8d8d301a8..a2609cd0e6bdfee8fb1e1328738a5e49265bf9ae 100644 (file)
@@ -4,6 +4,13 @@
 #include "vid_svga.h"
 #include "vid_svga_render.h"
 
+void svga_render_null(svga_t* svga)
+{
+    if (svga->firstline_draw == 4000)
+        svga->firstline_draw = svga->displine;
+    svga->lastline_draw = svga->displine;
+}
+
 void svga_render_blank(svga_t *svga)
 {
         int x, xx;
index be8105f795452acf16d4a583f4b96b76d16c6024..06e5097ea35bc578b243e46a109f9f549ac92128 100644 (file)
@@ -9,6 +9,7 @@ extern int scrollcache;
 
 extern uint8_t edatlookup[4][4];
 
+void svga_render_null(svga_t* svga);
 void svga_render_blank(svga_t *svga);
 void svga_render_text_40(svga_t *svga);
 void svga_render_text_80(svga_t *svga);
index ed4553c6625a2502b9c4d16c563c5010253acb0c..4f5fcacb6b4072ff96ea5b8329b02042c983eeeb 100644 (file)
@@ -685,39 +685,39 @@ static void voodoo_recalcmapping(voodoo_set_t *set)
                         if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23))
                         {
                                 pclog("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
-                                mem_mapping_disable(&set->voodoos[0]->mapping);
-                                mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
+                                mem_mapping_disablex(&set->voodoos[0]->mapping);
+                                mem_mapping_set_addrx(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
                         }
                         else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr))
                         {
                                 pclog("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
-                                mem_mapping_disable(&set->voodoos[0]->mapping);
-                                mem_mapping_disable(&set->voodoos[1]->mapping);
-                                mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
+                                mem_mapping_disablex(&set->voodoos[0]->mapping);
+                                mem_mapping_disablex(&set->voodoos[1]->mapping);
+                                mem_mapping_set_addrx(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
                                 return;
                         }
                         else
                         {
                                 pclog("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
-                                mem_mapping_disable(&set->snoop_mapping);
-                                mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
+                                mem_mapping_disablex(&set->snoop_mapping);
+                                mem_mapping_set_addrx(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
                         }
                 }
                 else
                 {
                         pclog("voodoo_recalcmapping (pri) : disabled\n");
-                        mem_mapping_disable(&set->voodoos[0]->mapping);
+                        mem_mapping_disablex(&set->voodoos[0]->mapping);
                 }
 
                 if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr)
                 {
                         pclog("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr);
-                        mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000);
+                        mem_mapping_set_addrx(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000);
                 }
                 else
                 {
                         pclog("voodoo_recalcmapping (sec) : disabled\n");
-                        mem_mapping_disable(&set->voodoos[1]->mapping);
+                        mem_mapping_disablex(&set->voodoos[1]->mapping);
                 }
         }
         else
@@ -727,12 +727,12 @@ static void voodoo_recalcmapping(voodoo_set_t *set)
                 if (voodoo->pci_enable && voodoo->memBaseAddr)
                 {
                         pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr);
-                        mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000);
+                        mem_mapping_set_addrx(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000);
                 }
                 else
                 {
                         pclog("voodoo_recalcmapping : disabled\n");
-                        mem_mapping_disable(&voodoo->mapping);
+                        mem_mapping_disablex(&voodoo->mapping);
                 }
         }
 }
@@ -948,7 +948,7 @@ static void voodoo_speed_changed(void *p)
 void *voodoo_card_init()
 {
         int c;
-        voodoo_t *voodoo = malloc(sizeof(voodoo_t));
+        voodoo_t *voodoo = (voodoo_t*)malloc(sizeof(voodoo_t));
         memset(voodoo, 0, sizeof(voodoo_t));
 
         voodoo->bilinear_enabled = device_get_config_int("bilinear");
@@ -983,30 +983,31 @@ void *voodoo_card_init()
         
         pci_add(voodoo_pci_read, voodoo_pci_write, voodoo);
 
-        mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel,     NULL, MEM_MAPPING_EXTERNAL, voodoo);
+        mem_mapping_addx(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel,     NULL, MEM_MAPPING_EXTERNAL, voodoo);
 
-        voodoo->fb_mem = malloc(4 * 1024 * 1024);
-        voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024);
+        voodoo->fb_mem = (uint8_t*)malloc(4 * 1024 * 1024);
+        voodoo->tex_mem[0] = (uint8_t*)malloc(voodoo->texture_size * 1024 * 1024);
         if (voodoo->dual_tmus)
-                voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024);
+                voodoo->tex_mem[1] = (uint8_t*)malloc(voodoo->texture_size * 1024 * 1024);
         voodoo->tex_mem_w[0] = (uint16_t *)voodoo->tex_mem[0];
         voodoo->tex_mem_w[1] = (uint16_t *)voodoo->tex_mem[1];
         
         for (c = 0; c < TEX_CACHE_MAX; c++)
         {
-                voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
+                voodoo->texture_cache[0][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
                 voodoo->texture_cache[0][c].base = -1; /*invalid*/
                 voodoo->texture_cache[0][c].refcount = 0;
                 if (voodoo->dual_tmus)
                 {
-                        voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
+                        voodoo->texture_cache[1][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
                         voodoo->texture_cache[1][c].base = -1; /*invalid*/
                         voodoo->texture_cache[1][c].refcount = 0;
                 }
         }
 
+#if 0
         timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
-        
+#endif   
         voodoo->svga = svga_get_pri();
         voodoo->fbiInit0 = 0;
 
@@ -1031,8 +1032,9 @@ void *voodoo_card_init()
                 voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
         }
         voodoo->swap_mutex = thread_create_mutex();
+#if 0
         timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
-        
+#endif   
         for (c = 0; c < 0x100; c++)
         {
                 rgb332[c].r = c & 0xe0;
@@ -1094,7 +1096,7 @@ void *voodoo_card_init()
 void *voodoo_2d3d_card_init(int type)
 {
         int c;
-        voodoo_t *voodoo = malloc(sizeof(voodoo_t));
+        voodoo_t *voodoo = (voodoo_t*)malloc(sizeof(voodoo_t));
         memset(voodoo, 0, sizeof(voodoo_t));
 
         voodoo->bilinear_enabled = device_get_config_int("bilinear");
@@ -1112,18 +1114,18 @@ void *voodoo_2d3d_card_init(int type)
 
         for (c = 0; c < TEX_CACHE_MAX; c++)
         {
-                voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
+                voodoo->texture_cache[0][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
                 voodoo->texture_cache[0][c].base = -1; /*invalid*/
                 voodoo->texture_cache[0][c].refcount = 0;
                 if (voodoo->dual_tmus)
                 {
-                        voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
+                        voodoo->texture_cache[1][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
                         voodoo->texture_cache[1][c].base = -1; /*invalid*/
                         voodoo->texture_cache[1][c].refcount = 0;
                 }
         }
 
-        timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
+//        timer_addx(&voodoo->timer, voodoo_callback, voodoo, 1);
 
         voodoo->fbiInit0 = 0;
 
@@ -1149,7 +1151,6 @@ void *voodoo_2d3d_card_init(int type)
         }
         voodoo->swap_mutex = thread_create_mutex();
         timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
-
         for (c = 0; c < 0x100; c++)
         {
                 rgb332[c].r = c & 0xe0;
@@ -1210,7 +1211,7 @@ void *voodoo_2d3d_card_init(int type)
 
 void *voodoo_init()
 {
-        voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t));
+        voodoo_set_t *voodoo_set = (voodoo_set_t*)malloc(sizeof(voodoo_set_t));
         uint32_t tmuConfig = 1;
         int type;
         memset(voodoo_set, 0, sizeof(voodoo_set_t));
@@ -1218,11 +1219,11 @@ void *voodoo_init()
         type = device_get_config_int("type");
         
         voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1;
-        voodoo_set->voodoos[0] = voodoo_card_init();
+        voodoo_set->voodoos[0] = (voodoo_t*)voodoo_card_init();
         voodoo_set->voodoos[0]->set = voodoo_set;
         if (voodoo_set->nr_cards == 2)
         {
-                voodoo_set->voodoos[1] = voodoo_card_init();
+                voodoo_set->voodoos[1] = (voodoo_t*)voodoo_card_init();
                                 
                 voodoo_set->voodoos[1]->set = voodoo_set;
 
@@ -1261,7 +1262,7 @@ void *voodoo_init()
         if (voodoo_set->nr_cards == 2)
                 voodoo_set->voodoos[1]->tmuConfig = tmuConfig;
 
-        mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel,     NULL, MEM_MAPPING_EXTERNAL, voodoo_set);
+        mem_mapping_addx(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel,     NULL, MEM_MAPPING_EXTERNAL, voodoo_set);
                 
         return voodoo_set;
 }
@@ -1273,6 +1274,7 @@ void voodoo_card_close(voodoo_t *voodoo)
 #endif
         int c;
         
+#if 0
 #ifndef RELEASE_BUILD        
         if (voodoo->tex_mem[0])
         {
@@ -1286,6 +1288,7 @@ void voodoo_card_close(voodoo_t *voodoo)
                         fclose(f);
                 }
         }
+#endif
 #endif
 
         thread_kill(voodoo->fifo_thread);
@@ -1341,6 +1344,7 @@ static device_config_t voodoo_config[] =
                 .name = "type",
                 .description = "Voodoo type",
                 .type = CONFIG_SELECTION,
+                .default_int = 0,
                 .selection =
                 {
                         {
@@ -1358,13 +1362,13 @@ static device_config_t voodoo_config[] =
                         {
                                 .description = ""
                         }
-                },
-                .default_int = 0
+                }
         },
         {
                 .name = "framebuffer_memory",
                 .description = "Framebuffer memory size",
                 .type = CONFIG_SELECTION,
+                .default_int = 2,
                 .selection =
                 {
                         {
@@ -1378,13 +1382,13 @@ static device_config_t voodoo_config[] =
                         {
                                 .description = ""
                         }
-                },
-                .default_int = 2
+                }
         },
         {
                 .name = "texture_memory",
                 .description = "Texture memory size",
                 .type = CONFIG_SELECTION,
+                .default_int = 2,
                 .selection =
                 {
                         {
@@ -1398,8 +1402,7 @@ static device_config_t voodoo_config[] =
                         {
                                 .description = ""
                         }
-                },
-                .default_int = 2
+                }
         },
         {
                 .name = "bilinear",
@@ -1417,6 +1420,7 @@ static device_config_t voodoo_config[] =
                 .name = "render_threads",
                 .description = "Render threads",
                 .type = CONFIG_SELECTION,
+                .default_int = 2,
                 .selection =
                 {
                         {
@@ -1434,8 +1438,7 @@ static device_config_t voodoo_config[] =
                         {
                                 .description = ""
                         }
-                },
-                .default_int = 2
+                }
         },
         {
                 .name = "sli",
index 2ac803e526d5ab2745969b816e04455b27520db9..d332f06679031b338127bd45cf7d1385deac51d4 100644 (file)
@@ -88,6 +88,8 @@ typedef struct banshee_t
         uint32_t desktop_stride_tiled;
 
         int type;
+
+        int vblank_irq;
 } banshee_t;
 
 enum
@@ -148,6 +150,7 @@ enum
 #define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12)
 
 #define VIDPROCCFG_CURSOR_MODE (1 << 1)
+#define VIDPROCCFG_INTERLACE (1 << 3)
 #define VIDPROCCFG_HALF_MODE (1 << 4)
 #define VIDPROCCFG_OVERLAY_ENABLE (1 << 8)
 #define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11)
@@ -204,6 +207,31 @@ enum
 #define VIDSERIAL_I2C_SCK_R (1 << 26)
 #define VIDSERIAL_I2C_SDA_R (1 << 27)
 
+static int banshee_vga_vsync_enabled(banshee_t *banshee)
+{
+    if (!(banshee->svga.crtc[0x11] & 0x20) && (banshee->svga.crtc[0x11] & 0x10) && ((banshee->pciInit0 >> 18) & 1) != 0)
+        return 1;
+    return 0;
+}
+
+static void banshee_update_irqs(banshee_t *banshee)
+{
+    if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) {
+        pci_set_irq(NULL, PCI_INTA);
+    } else {
+        pci_clear_irq(NULL, PCI_INTA);
+    }
+}
+
+static void banshee_vblank_start(svga_t* svga)
+{
+    banshee_t *banshee = (banshee_t*)svga->p;
+    if (banshee->vblank_irq >= 0) {
+        banshee->vblank_irq = 1;
+        banshee_update_irqs(banshee);
+    }
+}
+
 static uint32_t banshee_status(banshee_t *banshee);
 
 static void banshee_out(uint16_t addr, uint8_t val, void *p)
@@ -231,10 +259,21 @@ static void banshee_out(uint16_t addr, uint8_t val, void *p)
                 svga->crtc[svga->crtcreg] = val;
                 if (old != val)
                 {
-                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
+                        if (svga->crtcreg == 0x11) {
+                            if (!(val & 0x10)) {
+                                if (banshee->vblank_irq > 0)
+                                    banshee->vblank_irq = -1;
+                            } else if (banshee->vblank_irq < 0) {
+                                banshee->vblank_irq = 0;
+                            }
+                            banshee_update_irqs(banshee);
+                            if ((val & ~0x30) == (old & ~0x30))
+                                old = val;
+                        }
+                        if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val))
                         {
-                                svga->fullchange = changeframecount;
-                                svga_recalctimings(svga);
+                            svga->fullchange = changeframecount;
+                            svga_recalctimings(svga);
                         }
                 }
                 break;
@@ -260,6 +299,8 @@ static uint8_t banshee_in(uint16_t addr, void *p)
                         temp = 0;
                 else
                         temp = 0x10;
+                if (banshee->vblank_irq > 0)
+                    temp |= 0x80;
                 break;
                 case 0x3D4:
                 temp = svga->crtcreg;
@@ -282,10 +323,10 @@ static void banshee_updatemapping(banshee_t *banshee)
         if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
         {
 //                pclog("Update mapping - PCI disabled\n");
-                mem_mapping_disable(&svga->mapping);
-                mem_mapping_disable(&banshee->linear_mapping);
-                mem_mapping_disable(&banshee->reg_mapping_low);
-                mem_mapping_disable(&banshee->reg_mapping_high);
+                mem_mapping_disablex(&svga->mapping);
+                mem_mapping_disablex(&banshee->linear_mapping);
+                mem_mapping_disablex(&banshee->reg_mapping_low);
+                mem_mapping_disablex(&banshee->reg_mapping_high);
                 return;
         }
 
@@ -293,28 +334,28 @@ static void banshee_updatemapping(banshee_t *banshee)
         switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
         {
                 case 0x0: /*128k at A0000*/
-                mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
+                mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x20000);
                 svga->banked_mask = 0xffff;
                 break;
                 case 0x4: /*64k at A0000*/
-                mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
+                mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000);
                 svga->banked_mask = 0xffff;
                 break;
                 case 0x8: /*32k at B0000*/
-                mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
+                mem_mapping_set_addrx(&svga->mapping, 0xb0000, 0x08000);
                 svga->banked_mask = 0x7fff;
                 break;
                 case 0xC: /*32k at B8000*/
-                mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
+                mem_mapping_set_addrx(&svga->mapping, 0xb8000, 0x08000);
                 svga->banked_mask = 0x7fff;
                 break;
         }
         
         pclog("Linear framebuffer %08X  ", banshee->memBaseAddr1);
-        mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20);
+        mem_mapping_set_addrx(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20);
         pclog("registers %08X\n", banshee->memBaseAddr0);
-        mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20);
-        mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20);
+        mem_mapping_set_addrx(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20);
+        mem_mapping_set_addrx(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20);
 }
 
 static void banshee_render_16bpp_tiled(svga_t *svga)
@@ -388,6 +429,7 @@ static void banshee_recalctimings(svga_t *svga)
         if (svga->crtc[0x1b] & 0x40) svga->vsyncstart  += 0x400;
 //        pclog("svga->hdisp=%i\n", svga->hdisp);
 
+        svga->interlace = 0;
         if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT)
         {
                 switch (VIDPROCCFG_DESKTOP_PIX_FORMAT)
@@ -436,6 +478,15 @@ static void banshee_recalctimings(svga_t *svga)
                         svga->htotal *= 2;
                 }
 
+                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;
 
                 svga->overlay.x = voodoo->overlay.start_x;
@@ -476,6 +527,8 @@ static void banshee_recalctimings(svga_t *svga)
                 svga->video_res_override = 0;
         }
 
+        svga->horizontal_linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
+
         if (((svga->miscout >> 2) & 3) == 3)
         {
                 int k = banshee->pllCtrl0 & 3;
@@ -547,6 +600,8 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
 
                 case Init_miscInit0:
                 banshee->miscInit0 = val;
+                extern void gfxboard_voodoo_lfb_endianswap(int);
+                gfxboard_voodoo_lfb_endianswap(val >> 30);
                 break;
                 case Init_miscInit1:
                 banshee->miscInit1 = val;
@@ -599,7 +654,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
 
                 case Video_vidProcCfg:                                
                 banshee->vidProcCfg = val;
-//                pclog("vidProcCfg=%08x\n", val);
+                //pclog("vidProcCfg=%08x\n", val);
                 banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT;
                 svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA;
                 svga->fullchange = changeframecount;
@@ -613,7 +668,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
                 else
                         banshee->voodoo->scrfilterEnabled = 0;
                 voodoo_threshold_check(banshee->voodoo);
-                pclog("Banshee Filter: %06x\n", val);
+                //pclog("Banshee Filter: %06x\n", val);
 
                 break;
 
@@ -647,7 +702,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
                 case Video_vidSerialParallelPort:
                 banshee->vidSerialParallelPort = val;
 //                pclog("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc);
-                ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0);
+                //ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0);
                 break;
 
                 case Video_vidScreenSize:
@@ -759,11 +814,11 @@ static uint32_t banshee_status(banshee_t *banshee)
         uint32_t ret;
 
         ret = 0;
-        if (fifo_size < 0x20)
-                ret |= fifo_size;
+        if (fifo_entries < 0x20)
+                ret |= 0x1f - fifo_entries;
         else
                 ret |= 0x1f;
-        if (fifo_size)
+        if (fifo_entries)
                 ret |= 0x20;
         if (swap_count < 7)
                 ret |= (swap_count << 28);
@@ -880,9 +935,9 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p)
 
                 case Video_vidSerialParallelPort:
                 ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R);
-                if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && ddc_read_clock())
+                if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && 0) //ddc_read_clock())
                         ret |= VIDSERIAL_DDC_DCK_R;
-                if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && ddc_read_data())
+                if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && 0) //ddc_read_data())
                         ret |= VIDSERIAL_DDC_DDA_R;
                 ret = ret & ~(VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R);
                 if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SCK_W)
@@ -1001,6 +1056,14 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p)
                 voodoo_flush(voodoo);
                 switch (addr & 0x1fc)
                 {
+                        case SST_status:
+                        ret = banshee_status(banshee);
+                        break;
+
+                        case SST_intrCtrl:
+                        ret = banshee->intrCtrl & 0x0030003f;
+                        break;
+
                         case 0x08:
                         ret = voodoo->banshee_blt.clip0Min;
                         break;
@@ -1232,7 +1295,11 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p)
                 break;
 
                 case 0x0100000: /*2D registers*/
-                voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val);
+                    if ((addr & 0x3fc) == SST_intrCtrl) {
+                        banshee->intrCtrl = val & 0x0030003f;
+                    } else {
+                        voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val);
+                    }
                 break;
                 
                 case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/
@@ -1314,9 +1381,10 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
         voodoo_t *voodoo = banshee->voodoo;
         svga_t *svga = &banshee->svga;
         
+#if 0
         cycles -= voodoo->read_time;
         cycles_lost += voodoo->read_time;
-
+#endif
         addr &= svga->decode_mask;
         if (addr >= voodoo->tile_base)
         {
@@ -1332,10 +1400,12 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
         if (addr >= svga->vram_max)
                 return 0xff;
 
+#if 0
         egareads++;
         cycles -= video_timing_read_b;
         cycles_lost += video_timing_read_b;
-        
+#endif
+
 //        pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
 
         return svga->vram[addr & svga->vram_mask];
@@ -1350,8 +1420,10 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
         if (addr & 1)
                 return banshee_read_linear(addr, p) | (banshee_read_linear(addr+1, p) << 8);
 
+#if 0
         cycles -= voodoo->read_time;
         cycles_lost += voodoo->read_time;
+#endif
 
         addr &= svga->decode_mask;
         if (addr >= voodoo->tile_base)
@@ -1368,9 +1440,11 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
         if (addr >= svga->vram_max)
                 return 0xff;
 
+#if 0
         egareads++;
         cycles -= video_timing_read_w;
         cycles_lost += video_timing_read_w;
+#endif
 
 //        pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
 
@@ -1386,8 +1460,10 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
         if (addr & 3)
                 return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr+2, p) << 16);
 
+#if 0
         cycles -= voodoo->read_time;
         cycles_lost += voodoo->read_time;
+#endif
 
         addr &= svga->decode_mask;
         if (addr >= voodoo->tile_base)
@@ -1404,9 +1480,11 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
         if (addr >= svga->vram_max)
                 return 0xff;
 
+#if 0
         egareads++;
         cycles -= video_timing_read_l;
         cycles_lost += video_timing_read_l;
+#endif
 
 //        pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
 
@@ -1460,8 +1538,10 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
                 return;
         }
 
+#if 0
         cycles -= voodoo->write_time;
         cycles_lost += voodoo->write_time;
+#endif
 
 //        pclog("write_linear: addr=%08x val=%02x\n", addr, val);
         addr &= svga->decode_mask;
@@ -1479,10 +1559,12 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
         if (addr >= svga->vram_max)
                 return;
 
+#if 0
         egawrites++;
 
         cycles -= video_timing_write_w;
         cycles_lost += video_timing_write_w;
+#endif
 
         svga->changedvram[addr >> 12] = changeframecount;
         *(uint16_t *)&svga->vram[addr & svga->vram_mask] = val;
@@ -1502,12 +1584,14 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
                 return;
         }
 
+#if 0
         if (addr == voodoo->last_write_addr+4)
                 timing = voodoo->burst_time;
         else
                 timing = voodoo->write_time;
         cycles -= timing;
         cycles_lost += timing;
+#endif
         voodoo->last_write_addr = addr;
 
 //        /*if (val) */pclog("write_linear_l: addr=%08x val=%08x  %08x\n", addr, val, voodoo->tile_base);
@@ -1527,10 +1611,12 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
         if (addr >= svga->vram_max)
                 return;
 
+#if 0
         egawrites += 4;
 
         cycles -= video_timing_write_l;
         cycles_lost += video_timing_write_l;
+#endif
 
         svga->changedvram[addr >> 12] = changeframecount;
         *(uint32_t *)&svga->vram[addr & svga->vram_mask] = val;
@@ -1604,7 +1690,8 @@ void banshee_hwcursor_draw(svga_t *svga, int displine)
         svga->hwcursor_latch.addr += 16;
         
         x_off = svga->hwcursor_latch.x;
-        
+        x_off <<= svga->horizontal_linedbl;
+
         if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE)
         {
                 /*X11 mode*/
@@ -2060,8 +2147,11 @@ static void banshee_overlay_draw(svga_t *svga, int displine)
                         case VIDPROCCFG_FILTER_MODE_DITHER_4X4:
                         if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled)
                         {
-                                uint8_t fil[(svga->overlay_latch.xsize) * 3];
-                                uint8_t fil3[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t fil[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t fil3[(svga->overlay_latch.xsize) * 3];
+                                uint8_t fil[4096 * 3];
+                                uint8_t fil3[4096 * 3];
+
 
                                 if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */
                                 {
@@ -2145,14 +2235,22 @@ static void banshee_overlay_draw(svga_t *svga, int displine)
                         case VIDPROCCFG_FILTER_MODE_DITHER_2X2:
                         if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled)
                         {
-                                uint8_t fil[(svga->overlay_latch.xsize) * 3];
-                                uint8_t soak[(svga->overlay_latch.xsize) * 3];
-                                uint8_t soak2[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t fil[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t soak[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t soak2[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t samp1[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t samp2[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t samp3[(svga->overlay_latch.xsize) * 3];
+                                //uint8_t samp4[(svga->overlay_latch.xsize) * 3];
+
+                                uint8_t fil[4096 * 3];
+                                uint8_t soak[4096 * 3];
+                                uint8_t soak2[4096 * 3];
+                                uint8_t samp1[4096 * 3];
+                                uint8_t samp2[4096 * 3];
+                                uint8_t samp3[4096 * 3];
+                                uint8_t samp4[4096 * 3];
 
-                                uint8_t samp1[(svga->overlay_latch.xsize) * 3];
-                                uint8_t samp2[(svga->overlay_latch.xsize) * 3];
-                                uint8_t samp3[(svga->overlay_latch.xsize) * 3];
-                                uint8_t samp4[(svga->overlay_latch.xsize) * 3];
 
                                 src = &svga->vram[src_addr2 & svga->vram_mask];
                                 OVERLAY_SAMPLE(banshee->overlay_buffer[1]);
@@ -2331,8 +2429,8 @@ static uint8_t banshee_pci_read(int func, int addr, void *p)
                 
                 case 0x18: ret = 0x01; break; /*ioBaseAddr*/
                 case 0x19: ret = banshee->ioBaseAddr >> 8; break;
-                case 0x1a: ret = 0x00; break;
-                case 0x1b: ret = 0x00; break;
+                case 0x1a: ret = banshee->ioBaseAddr >> 16; break;
+                case 0x1b: ret = banshee->ioBaseAddr >> 24; break;
 
                 /*Subsystem vendor ID*/
                 case 0x2c: ret = banshee->pci_regs[0x2c]; break;
@@ -2375,18 +2473,18 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p)
                 case PCI_REG_COMMAND:
                 if (val & PCI_COMMAND_IO)
                 {
-                        io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
+                        io_removehandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
                         if (banshee->ioBaseAddr)
-                                io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
+                                io_removehandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
 
-                        io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
+                        io_sethandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
                         if (banshee->ioBaseAddr)
-                                io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
+                                io_sethandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
                 }
                 else
                 {
-                        io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
-                        io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
+                        io_removehandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
+                        io_removehandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
                 }
                 banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27;
                 banshee_updatemapping(banshee);
@@ -2408,12 +2506,22 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p)
                 banshee_updatemapping(banshee);
                 return;
 
+                case 0x1a:
+                    banshee->ioBaseAddr &= 0xff00ffff;
+                    banshee->ioBaseAddr |= val << 16;
+                    break;
+                case 0x1b:
+                    banshee->ioBaseAddr &= 0x00ffffff;
+                    banshee->ioBaseAddr |= val << 24;
+                    break;
+
                 case 0x19:
                 if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO)
-                        io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
-                banshee->ioBaseAddr = val << 8;
+                        io_removehandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
+                banshee->ioBaseAddr &= 0xffff00ff;
+                banshee->ioBaseAddr |= val << 8;
                 if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr)
-                        io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
+                        io_sethandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
                 pclog("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr);
 //                s3_virge_updatemapping(virge); 
                 return;
@@ -2424,13 +2532,13 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p)
                 {
                         uint32_t addr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24);
                         pclog("Banshee bios_rom enabled at %08x\n", addr);
-                        mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x10000);
-                        mem_mapping_enable(&banshee->bios_rom.mapping);
+                        mem_mapping_set_addrx(&banshee->bios_rom.mapping, addr, 0x10000);
+                        mem_mapping_enablex(&banshee->bios_rom.mapping);
                 }
                 else
                 {
                         pclog("Banshee bios_rom disabled\n");
-                        mem_mapping_disable(&banshee->bios_rom.mapping);
+                        mem_mapping_disablex(&banshee->bios_rom.mapping);
                 }
                 return;
                 case 0x3c: 
@@ -2445,6 +2553,7 @@ static device_config_t banshee_sgram_config[] =
                 .name = "memory",
                 .description = "Memory size",
                 .type = CONFIG_SELECTION,
+                .default_int = 16,
                 .selection =
                 {
                         {
@@ -2458,8 +2567,7 @@ static device_config_t banshee_sgram_config[] =
                         {
                                 .description = ""
                         }
-                },
-                .default_int = 16
+                }
         },
         {
                 .name = "bilinear",
@@ -2477,6 +2585,7 @@ static device_config_t banshee_sgram_config[] =
                 .name = "render_threads",
                 .description = "Render threads",
                 .type = CONFIG_SELECTION,
+                .default_int = 2,
                 .selection =
                 {
                         {
@@ -2494,8 +2603,7 @@ static device_config_t banshee_sgram_config[] =
                         {
                                 .description = ""
                         }
-                },
-                .default_int = 2
+                }
         },
 #ifndef NO_CODEGEN
         {
@@ -2528,6 +2636,7 @@ static device_config_t banshee_sdram_config[] =
                 .name = "render_threads",
                 .description = "Render threads",
                 .type = CONFIG_SELECTION,
+                .default_int = 2,
                 .selection =
                 {
                         {
@@ -2546,7 +2655,6 @@ static device_config_t banshee_sdram_config[] =
                                 .description = ""
                         }
                 },
-                .default_int = 2
         },
 #ifndef NO_CODEGEN
         {
@@ -2561,16 +2669,29 @@ static device_config_t banshee_sdram_config[] =
         }
 };
 
+void voodoo_update_vram(void *p)
+{
+    banshee_t *banshee = (banshee_t*)p;
+    banshee->voodoo->vram = banshee->svga.vram;
+    banshee->voodoo->fb_mem = banshee->svga.vram;
+    banshee->voodoo->tex_mem[0] = banshee->svga.vram;
+    banshee->voodoo->tex_mem_w[0] = (uint16_t*)banshee->svga.vram;
+    banshee->voodoo->tex_mem[1] = banshee->svga.vram;
+    banshee->voodoo->tex_mem_w[1] = (uint16_t*)banshee->svga.vram;
+}
+
 static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_type)
 {
         int mem_size;
-        banshee_t *banshee = malloc(sizeof(banshee_t));
+        banshee_t *banshee = (banshee_t*)malloc(sizeof(banshee_t));
         memset(banshee, 0, sizeof(banshee_t));
         
         banshee->type = type;
+        banshee->intrCtrl = 0x80000000;
 
         rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
-        mem_mapping_disable(&banshee->bios_rom.mapping);
+        mem_mapping_disablex(&banshee->bios_rom.mapping);
 
         if (has_sgram)
                 mem_size = device_get_config_int("memory");
@@ -2584,7 +2705,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
                    banshee_overlay_draw);
         banshee->svga.vsync_callback = banshee_vsync_callback;
 
-        mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear,
+        mem_mapping_addx(&banshee->linear_mapping, 0, 0, banshee_read_linear,
                                                         banshee_read_linear_w,
                                                         banshee_read_linear_l,
                                                         banshee_write_linear,
@@ -2593,7 +2714,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
                                                         NULL,
                                                         MEM_MAPPING_EXTERNAL,
                                                         &banshee->svga);
-        mem_mapping_add(&banshee->reg_mapping_low, 0, 0,banshee_reg_read,
+        mem_mapping_addx(&banshee->reg_mapping_low, 0, 0,banshee_reg_read,
                                                         banshee_reg_readw,
                                                         banshee_reg_readl,
                                                         banshee_reg_write,
@@ -2602,7 +2723,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
                                                         NULL,
                                                         MEM_MAPPING_EXTERNAL,
                                                         banshee);
-        mem_mapping_add(&banshee->reg_mapping_high, 0,0,banshee_reg_read,
+        mem_mapping_addx(&banshee->reg_mapping_high, 0,0,banshee_reg_read,
                                                         banshee_reg_readw,
                                                         banshee_reg_readl,
                                                         banshee_reg_write,
@@ -2612,7 +2733,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
                                                         MEM_MAPPING_EXTERNAL,
                                                         banshee);
 
-//        io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
+//        io_sethandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
 
         banshee->svga.bpp = 8;
         banshee->svga.miscout = 1;
@@ -2626,7 +2747,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
 
         pci_add(banshee_pci_read, banshee_pci_write, banshee);
         
-        banshee->voodoo = voodoo_2d3d_card_init(voodoo_type);
+        banshee->voodoo = (voodoo_t*)voodoo_2d3d_card_init(voodoo_type);
         banshee->voodoo->p = banshee;
         banshee->voodoo->vram = banshee->svga.vram;
         banshee->voodoo->changedvram = banshee->svga.changedvram;
@@ -2641,7 +2762,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
 
         banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W;
 
-        ddc_init();
+        //ddc_init();
 
         switch (type)
         {
@@ -2677,6 +2798,8 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
                 break;
         }
 
+        banshee->svga.vblank_start = banshee_vblank_start;
+
         return banshee;
 }
 
index f6f0d031d8d869a8cb7aa31dc3b12a8adb1a89c7..8949ecdab983934639937beac636de36f2706125 100644 (file)
@@ -22,6 +22,8 @@
 #include "vid_voodoo_banshee_blitter.h"
 #include "vid_voodoo_render.h"
 
+#define MAX(a,b) ((a) > (b) ? (a) : (b))
+
 #define COMMAND_CMD_MASK                         (0xf)
 #define COMMAND_CMD_NOP                          (0 << 0)
 #define COMMAND_CMD_SCREEN_TO_SCREEN_BLT         (1 << 0)
index 35ed9e5751d6c687adfbc1b2cb2f97b1aa9a7283..581dfa652710e5d8691859c0dbd413149805e486 100644 (file)
@@ -3376,7 +3376,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
 {
         int c;
         int b = last_block[odd_even];
-        voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data;
+        voodoo_x86_data_t *voodoo_x86_data = (voodoo_x86_data_t*)voodoo->codegen_data;
         voodoo_x86_data_t *data;
         
         for (c = 0; c < 8; c++)
index c925d5b196cda177ed447d8309d6c6f40e1314fc..87c0f1dea5a77f6189429584e1829f0a61ae7d50 100644 (file)
@@ -3312,12 +3312,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
 }
 int voodoo_recomp = 0;
 
-static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even)
+static inline uint8_t *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even)
 {
         int c;
         int b = last_block[odd_even];
         voodoo_x86_data_t *data;
-        voodoo_x86_data_t *codegen_data = voodoo->codegen_data;
+        voodoo_x86_data_t *codegen_data = (voodoo_x86_data_t*)voodoo->codegen_data;
         
         for (c = 0; c < 8; c++)
         {
index 9ce92dde113b067682049d578df953f0e0b6df3b..34d7e13ce7816b6a226b4cf66ca56b9073677b66 100644 (file)
@@ -322,7 +322,8 @@ static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uin
        int x;
 
        // Scratchpad for avoiding feedback streaks
-        uint8_t fil3[(voodoo->h_disp) * 3];
+//        uint8_t fil3[(voodoo->h_disp) * 3];
+        uint8_t fil3[4096 * 3];
 
        /* 16 to 32-bit */
         for (x=0; x<column;x++)
@@ -388,7 +389,8 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin
        int x;
 
        // Scratchpad for blending filter
-        uint8_t fil3[(voodoo->h_disp) * 3];
+        //uint8_t fil3[(voodoo->h_disp) * 3];
+        uint8_t fil3[4096 * 3];
 
        /* 16 to 32-bit */
         for (x=0; x<column;x++)
@@ -495,7 +497,8 @@ void voodoo_callback(void *p)
 
                                 if (voodoo->scrfilter && voodoo->scrfilterEnabled)
                                 {
-                                        uint8_t fil[(voodoo->h_disp) * 3];              /* interleaved 24-bit RGB */
+                                        //uint8_t fil[(voodoo->h_disp) * 3];              /* interleaved 24-bit RGB */
+                                        uint8_t fil[4096 * 3];              /* interleaved 24-bit RGB */
 
                                        if (voodoo->type == VOODOO_2)
                                                voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line);
@@ -602,8 +605,11 @@ skip_draw:
                 voodoo->line = 0;
                 voodoo->v_retrace = 0;
         }
+
+#if 0
         if (voodoo->line_time)
                timer_advance_u64(&voodoo->timer, voodoo->line_time);
         else
                timer_advance_u64(&voodoo->timer, TIMER_USEC * 32);
+#endif
 }
index 59861f3f44ce97d5b7652d4a54e5a562045f6087..1c87316242c548b90b8d2dba761a306ceb565a3a 100644 (file)
@@ -25,7 +25,7 @@ void voodoo_wake_fifo_thread(voodoo_t *voodoo)
                   process one word and go back to sleep, requiring it to be woken on
                   almost every write. Instead, wait a short while so that the CPU
                   emulation writes more data so we have more batched-up work.*/
-               timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY);
+               timer_set_delay_u64x(&voodoo->wake_timer, WAKE_DELAY);
         }
 }
 
index 2116180707d26985abc5ddd378e1e3295b33c592..777d9cc39038662c3ba22bcf0b4915c4471b4ff4 100644 (file)
@@ -1,3 +1,6 @@
+
+#include <emmintrin.h>
+
 #include <math.h>
 #include <stddef.h>
 #include "ibm.h"
@@ -679,7 +682,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood
         int texels;
         int c;
 #ifndef NO_CODEGEN
-        uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y);
+        uint8_t (__cdecl *voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y);
 #endif
         int y_diff = SLI_ENABLED ? 2 : 1;
 
@@ -772,8 +775,9 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood
                 }
         }
 #ifndef NO_CODEGEN
+        typedef uint8_t(__cdecl *VOODOO_DRAW)(voodoo_state_t*,voodoo_params_t*, int,int);
         if (voodoo->use_recompiler)
-                voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even);
+                voodoo_draw = (VOODOO_DRAW)voodoo_get_block(voodoo, params, state, odd_even);
         else
                 voodoo_draw = NULL;
 #endif
index 9ba73dc635cad4db86d6228b845b7954fa4a2822..54a9be422ee03a1ca0a51c43a55c64f1f55de867 100644 (file)
@@ -1,3 +1,4 @@
+
 #if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__)
 #define NO_CODEGEN
 #endif
diff --git a/pci.cpp b/pci.cpp
index db2945a1be34c5267731a46126da00b216c7abeb..61697be1c8afdb95e1f4f343ce03333e401cfab3 100644 (file)
--- a/pci.cpp
+++ b/pci.cpp
@@ -3,7 +3,7 @@
 *
 * PCI Bridge board emulation
 *
-* Copyright 2015 Toni Wilen
+* Copyright 2015-2020 Toni Wilen
 * Hardware information by Radoslaw Kujawa
 *
 */
@@ -12,6 +12,7 @@
 #define PCI_DEBUG_MEMORY 0
 #define PCI_DEBUG_CONFIG 1
 #define PCI_DEBUG_BRIDGE 0
+#define PCI_DEBUG_IO_MISS 0
 
 #include "sysconfig.h"
 #include "sysdeps.h"
@@ -86,6 +87,15 @@ static struct pci_bridge *pci_bridge_alloc_zorro(int offset, struct romconfig *r
        return NULL;
 }
 
+struct pci_bridge *pci_bridge_get(void)
+{
+       // FIXME!
+       for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
+               if (bridges[i])
+                       return bridges[i];
+       }
+       return NULL;
+}
 
 static void pci_bridge_free(struct pci_bridge *pcib)
 {
@@ -106,18 +116,33 @@ static struct pci_board *pci_board_alloc(struct pci_config *config)
        return pci;
 }
 
-static void pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int slot, int func, struct autoconfig_info *aci)
+struct pci_board_state *pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int slot, int func, struct autoconfig_info *aci, void *userdata)
 {
        struct pci_board_state *pcibs = &pcib->boards[pcib->slot_cnt];
        pcib->slot_cnt++;
        pcibs->board = pci;
-       pcibs->slot = slot;
+       pcibs->slot = slot < 0 ? pcib->slot_cnt : slot;
        pcibs->func = func;
        pcibs->bridge = pcib;
        pcibs->irq_callback = pci_irq_callback;
+       pcibs->userdata = userdata;
        memset(pcibs->config_data, 0, sizeof pcibs->config_data);
+       if (pci->pci_get_config) {
+               struct pci_config *config = &pcibs->dynamic_config;
+               config->vendor = (pci->pci_get_config(1) << 8) | pci->pci_get_config(0);
+               config->device = (pci->pci_get_config(3) << 8) | pci->pci_get_config(2);
+               config->deviceclass = (pci->pci_get_config(10) << 16) | (pci->pci_get_config(9) << 8) | pci->pci_get_config(8);
+               config->revision = pci->pci_get_config(11);
+               config->subsystem = (pci->pci_get_config(0x2d) << 8) | pci->pci_get_config(0x2c);
+               config->subsystenvendor = (pci->pci_get_config(0x2f) << 8) | pci->pci_get_config(0x2e);
+               config->max_latency = pci->pci_get_config(0x3f);
+               config->min_grant = pci->pci_get_config(0x3e);
+               config->interruptpin = pci->pci_get_config(0x3d);
+       } else {
+               memcpy(&pcibs->dynamic_config, pci->config, sizeof(struct pci_config));
+       }
        for (int i = 0; i < MAX_PCI_BARS; i++) {
-               pcibs->bar_size[i] = pci->config->bars[i];
+               pcibs->bar_size[i] = pcibs->dynamic_config.bars[i];
        }
        if (pci->init)
                pci->init(pcibs, aci);
@@ -129,6 +154,7 @@ static void pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci,
                        }
                }
        }
+       return pcibs;
 }
 
 static void pci_free(void)
@@ -164,10 +190,11 @@ static void pci_rethink(void)
                for (int j = 0; j < MAX_PCI_BOARDS; j++) {
                        struct pci_board_state *pcibs = &pcib->boards[j];
                        if (pcibs->board) {
-                               const struct pci_config *c = pcibs->board->config;
+                               const struct pci_config *c = &pcibs->dynamic_config;
                                if (c->interruptpin) {
                                        if ((pcibs->config_data[5] & (1 << 3)) && !(pcibs->config_data[6] & (1 << (10 - 8)))) {
-                                               uae_u8 irq = 1 << (c->interruptpin - 1);;
+                                               uae_u8 pin = (c->interruptpin - 1 + pcibs->slot) & 3;
+                                               uae_u8 irq = 1 << pin;
                                                pcib->irq |= irq;
                                                if (irq & pcib->intena) {
                                                        safe_interrupt_set(IRQ_SOURCE_PCI, i, (pcib->intreq_mask & 0x2000) != 0);
@@ -190,7 +217,7 @@ static void set_pci_irq(struct pci_bridge *pcib, struct pci_board_state *pcibs,
 static void create_config_data(struct pci_board_state *s)
 {
        uae_u8 *d = s->config_data;
-       const struct pci_config *c = s->board->config;
+       const struct pci_config *c = &s->dynamic_config;
 
        // big endian, get/put functions will swap if needed.
        d[0] = c->device >> 8;
@@ -295,9 +322,14 @@ static struct pci_board_state *get_pci_board_state_config(struct pci_bridge *pci
 
 static int stored_board, stored_bar;
 
-static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaecptr addr, int *bar)
+static struct pci_board_state *get_pci_board_state(struct pci_bridge *pcib, uaecptr addr, bool io, int *bar)
 {
-       uaecptr addr2 = addr - pcib->io_offset;
+       uaecptr addr2 = addr;
+       if (io) {
+               addr2 -= pcib->io_offset;
+       } else {
+               addr2 -= pcib->memory_start_offset;
+       }
        struct pci_board_state *pcibs2 = &pcib->boards[stored_board];
        if (pcibs2) {
                if (pcibs2->bar_enabled[stored_bar] && addr2 >= pcibs2->bar_start[stored_bar] && addr2 <= pcibs2->bar_end[stored_bar]) {
@@ -326,14 +358,16 @@ static const pci_addrbank *get_pci_io(uaecptr *addrp, struct pci_board_state **p
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
                return NULL;
-       struct pci_board_state *pcibs = get_pci_board_state(pcib, addr, &bar);
+       struct pci_board_state *pcibs = get_pci_board_state(pcib, addr, true, &bar);
        if (!pcibs)
                return NULL;
        *pcibsp = pcibs;
        pcibs->selected_bar = bar;
        *endianswap = pcib->endian_swap_io;
        addr -= pcib->io_offset;
-       addr &= (pcibs->bar_size[bar] & ~1) - 1;
+       if (!pcibs->board->dont_mask_io) {
+               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);
 #endif
@@ -351,14 +385,13 @@ static const pci_addrbank *get_pci_mem(uaecptr *addrp, struct pci_board_state **
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
                return NULL;
-       struct pci_board_state *pcibs = get_pci_board_state(pcib, addr, &bar);
+       struct pci_board_state *pcibs = get_pci_board_state(pcib, addr, false, &bar);
        if (!pcibs)
                return NULL;
        *pcibsp = pcibs;
        pcibs->selected_bar = bar;
        *endianswap = pcib->endian_swap_memory;
-       addr &= pcibs->bar_size[bar] - 1;
-       addr -= pcib->memory_offset;
+       addr -= pcibs->bridge->memory_start_offset;
        *addrp = addr;
        return &pcibs->board->bars[bar];
 }
@@ -385,7 +418,27 @@ static uae_u8 *get_pci_config(uaecptr addr, int size, uae_u32 v, int *endianswap
 #if PCI_DEBUG_CONFIG
        write_log(_T("- Board %d/%d (%s)\n"), pcibs->slot, pcibs->func, pcibs->board->label);
 #endif
-       create_config_data(pcibs);
+       if (pcibs->board->pci_get_config) {
+               int off = addr & 0xff;
+               uae_u8 *c = pcibs->config_data;
+               if (size == 4 || size == -4) {
+                       c[off + 3] = pcibs->board->pci_get_config(off + 0);
+                       c[off + 2] = pcibs->board->pci_get_config(off + 1);
+                       c[off + 1] = pcibs->board->pci_get_config(off + 2);
+                       c[off + 0] = pcibs->board->pci_get_config(off + 3);
+               } else if (size == 2 || size == -2) {
+                       if (pcib->endian_swap_config) {
+                               c[(off ^ (pcib->endian_swap_config > 0 ? 0 : 2)) + 0] = pcibs->board->pci_get_config(off + 0);
+                               c[(off ^ (pcib->endian_swap_config > 0 ? 0 : 2)) + 1] = pcibs->board->pci_get_config(off + 1);
+                       } else {
+                               c[off + 1] = pcibs->board->pci_get_config((off ^ 2) + 0);
+                               c[off + 0] = pcibs->board->pci_get_config((off ^ 2) + 1);
+                       }
+                       *endianswap = 0;
+               }
+       } else {
+               create_config_data(pcibs);
+       }
        return pcibs->config_data;
 }
 
@@ -419,7 +472,7 @@ static void map_pci_banks(struct pci_board_state *pcibs, int type, bool enable)
        }
 }
 
-static void update_pci_config(uaecptr addr)
+static void update_pci_config(uaecptr addr, int size)
 {
        struct pci_bridge *pcib = get_pci_bridge(addr);
        if (!pcib)
@@ -428,32 +481,95 @@ static void update_pci_config(uaecptr addr)
        if (!pcibs)
                return;
        uae_u8 *d = pcibs->config_data;
-       const struct pci_config *c = pcibs->board->config;
+       bool config_changed = false;
        for (int i = 0; i < MAX_PCI_BARS; i++) {
                int off = i == MAX_PCI_BARS - 1 ? 0x30 : 0x10 + i * 4;
                if (pcibs->bar_size[i]) {
+                       uae_u32 obar = pcibs->bar[i];
                        pcibs->bar[i] = d[off + 0] << 24;
                        pcibs->bar[i] |= d[off + 1] << 16;
                        pcibs->bar[i] |= d[off + 2] <<  8;
                        pcibs->bar[i] |= d[off + 3] <<  0;
                        pcibs->bar[i] &= ~((pcibs->bar_size[i] & ~1) - 1);
                        pcibs->bar[i] |= (pcibs->bar_size[i] & 1);
+                       if (pcibs->bar[i] != obar) {
+                               if ((pcibs->io_map_active && (pcibs->bar[i] & 1)) || (pcibs->memory_map_active && !(pcibs->bar[i] & 1))) {
+                                       config_changed = true;
+                               }
+                       }
                } else {
                        pcibs->bar[i] = 0;
                }
        }
-       create_config_data(pcibs);
-       pcibs->io_map_active = (d[7] & 1) != 0;
-       pcibs->memory_map_active = (d[7] & 2) != 0;
+       if (pcibs->board->pci_put_config) {
+               int off = addr & 0xff;
+               if (size == 4) {
+                       pcibs->board->pci_put_config(off + 3, d[off + 0]);
+                       pcibs->board->pci_put_config(off + 2, d[off + 1]);
+                       pcibs->board->pci_put_config(off + 1, d[off + 2]);
+                       pcibs->board->pci_put_config(off + 0, d[off + 3]);
+               } else if (size == 2) {
+                       if (pcib->endian_swap_config) {
+                               pcibs->board->pci_put_config((off ^ (pcib->endian_swap_config > 0 ? 2 : 0)) + 1, d[off + 0]);
+                               pcibs->board->pci_put_config((off ^ (pcib->endian_swap_config > 0 ? 2 : 0)) + 0, d[off + 1]);
+                       } else {
+                               pcibs->board->pci_put_config(off + 0, d[off + 0]);
+                               pcibs->board->pci_put_config(off + 1, d[off + 1]);
+                       }
+               } else {
+                       pcibs->board->pci_put_config(off + 0, d[off + 0]);
+               }
+               if ((off >= 0x10 && off < 0x10 + (MAX_PCI_BARS - 1) * 4) || (off >= 0x30 && off < 0x34)) {
+                       int index;
+                       if (off >= 0x30) {
+                               index = MAX_PCI_BARS - 1;
+                       } else {
+                               index = (off - 0x10) / 4;
+                       }
+                       uae_u32 obar = pcibs->bar[index];
+                       pcibs->bar[index] = pcibs->board->pci_get_config(off + 3) << 24;
+                       pcibs->bar[index] |= pcibs->board->pci_get_config(off + 2) << 16;
+                       pcibs->bar[index] |= pcibs->board->pci_get_config(off + 1) << 8;
+                       pcibs->bar[index] |= pcibs->board->pci_get_config(off + 0) << 0;
+                       if (d[off + 0] == 0xff && d[off + 1] == 0xff && d[off + 2] == 0xff && (d[off + 3] & 0xfe) == 0xfe) {
+                               pcibs->bar_size[index] = ~((pcibs->bar[index] & ~1) - 1);
+                               if (pcibs->board->config->bars[index] & 1) {
+                                       pcibs->bar_size[index] |= 1;
+                               }
+                       }
+                       if (pcibs->bar[index] != obar) {
+                               if ((pcibs->io_map_active && (pcibs->bar[index] & 1)) || (pcibs->memory_map_active && !(pcibs->bar[index] & 1))) {
+                                       config_changed = true;
+                               }
+                       }
+               }
+
+
+       } else {
+               create_config_data(pcibs);
+       }
+       bool o_io = pcibs->io_map_active;
+       bool o_mm = pcibs->memory_map_active;
+       uae_u8 map;
+       if (pcibs->board->pci_get_config) {
+               map = pcibs->board->pci_get_config(7 ^ 3);
+       } else {
+               map = d[7];
+       }
+       pcibs->io_map_active = (map & 1) != 0;
+       pcibs->memory_map_active = (map & 2) != 0;
        map_pci_banks(pcibs, 1, pcibs->io_map_active);
        map_pci_banks(pcibs, 0, pcibs->memory_map_active);
+       if ((o_io != pcibs->io_map_active || o_mm != pcibs->memory_map_active || config_changed) && pcibs->board->pci_change_config) {
+               pcibs->board->pci_change_config(pcibs);
+       }
 }
 
 
 static uaecptr beswap(int endianswap, uaecptr addr)
 {
        if (endianswap > 0)
-               return (addr & ~3) | (3 - (addr & 3));
+               return addr ^ 3;;
        return addr;
 }
 
@@ -476,7 +592,7 @@ static uae_u32 REGPARAM2 pci_config_lget(uaecptr addr)
                        v |= config[offset + 0] << 0;
                }
 #if PCI_DEBUG_CONFIG
-               write_log(_T("- %08x\n"), v);
+               write_log(_T("-> %08x\n"), v);
 #endif
        }
        return v;
@@ -496,7 +612,7 @@ static uae_u32 REGPARAM2 pci_config_wget(uaecptr addr)
                        v |= config[(offset ^ (endianswap > 0 ? 2 : 0)) + 0] << 0;
                }
 #if PCI_DEBUG_CONFIG
-               write_log(_T("- %04x\n"), v);
+               write_log(_T("-> %04x\n"), v);
 #endif
        }
        return v;
@@ -514,7 +630,7 @@ static uae_u32 REGPARAM2 pci_config_bget(uaecptr addr)
                        v = config[beswap(endianswap, offset)];
                }
 #if PCI_DEBUG_CONFIG
-               write_log(_T("- %02x\n"), v);
+               write_log(_T("-> %02x\n"), v);
 #endif
        }
        return v;
@@ -536,7 +652,7 @@ static void REGPARAM2 pci_config_lput(uaecptr addr, uae_u32 b)
                        config[offset + 1] = b >> 8;
                        config[offset + 0] = b >> 0;
                }
-               update_pci_config(addr);
+               update_pci_config(addr, 4);
        }
 }
 static void REGPARAM2 pci_config_wput(uaecptr addr, uae_u32 b)
@@ -552,7 +668,7 @@ static void REGPARAM2 pci_config_wput(uaecptr addr, uae_u32 b)
                        config[(offset ^ (endianswap > 0 ? 2 : 0)) + 1] = b >> 8;
                        config[(offset ^ (endianswap > 0 ? 2 : 0)) + 0] = b >> 0;
                }
-               update_pci_config(addr);
+               update_pci_config(addr, 2);
        }
 }
 static void REGPARAM2 pci_config_bput(uaecptr addr, uae_u32 b)
@@ -566,21 +682,10 @@ static void REGPARAM2 pci_config_bput(uaecptr addr, uae_u32 b)
                } else {
                        config[beswap(endianswap, offset)] = b;
                }
-               update_pci_config(addr);
+               update_pci_config(addr, 1);
        }
 }
 
-static uae_u32 endianswap_long(uae_u32 v)
-{
-       v = (v >> 24) | ((v >> 8) & 0x0000ff00) | ((v << 8) & 0x00ff0000) | (v << 24);
-       return v;
-}
-static uae_u16 endianswap_word(uae_u16 v)
-{
-       v = (v >> 8) | (v << 8);
-       return v;
-}
-
 static uae_u32 REGPARAM2 pci_io_lget(uaecptr addr)
 {
        uae_u32 v = 0xffffffff;
@@ -593,9 +698,9 @@ static uae_u32 REGPARAM2 pci_io_lget(uaecptr addr)
                write_log(_T("-> %08x\n"), v);
 #endif
                if (endianswap)
-                       v = endianswap_long(v);
-       } else {
+                       v = do_byteswap_32(v);
 #if PCI_DEBUG_IO
+       } else {
                write_log(_T("-> X\n"), v);
 #endif
        }
@@ -610,19 +715,19 @@ static uae_u32 REGPARAM2 pci_io_wget(uaecptr addr)
        if (a && a->wget) {
                if (endianswap) {
                        v = a->wget(pcibs, addr ^ (endianswap > 0 ? 2 : 0));
-#if PCI_DEBUG_IO
+#if PCI_DEBUG_IO > 1
                        write_log(_T("-> %04x\n"), v);
 #endif
-                       v = endianswap_word(v);
+                       v = do_byteswap_16(v);
                } else {
                        v = a->wget(pcibs, addr);
-#if PCI_DEBUG_IO
+#if PCI_DEBUG_IO > 1
                        write_log(_T("-> %04x\n"), v);
 #endif
                }
-       } else {
 #if PCI_DEBUG_IO
-               write_log(_T("-> X\n"), v);
+       } else {
+               write_log(_T("!-> %02x\n"), v);
 #endif
        }
        return v;
@@ -636,18 +741,18 @@ static uae_u32 REGPARAM2 pci_io_bget(uaecptr addr)
        if (a && a->bget) {
                if (endianswap) {
                        v = a->bget(pcibs, beswap(endianswap, addr));
-#if PCI_DEBUG_IO
+#if PCI_DEBUG_IO > 1
                        write_log(_T("-> %02x\n"), v);
 #endif
                } else {
                        v = a->bget(pcibs, addr);
-#if PCI_DEBUG_IO
+#if PCI_DEBUG_IO > 1
                        write_log(_T("-> %02x\n"), v);
 #endif
                }
-       } else {
 #if PCI_DEBUG_IO
-               write_log(_T("-> X\n"), v);
+       } else {
+               write_log(_T("!-> %02x"), v);
 #endif
        }
        return v;
@@ -656,11 +761,21 @@ static void REGPARAM2 pci_io_lput(uaecptr addr, uae_u32 b)
 {
        int endianswap;
        struct pci_board_state *pcibs;
+       uaecptr addr2 = addr;
        const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -4);
-       if (a && a->lput) {
-               if (endianswap)
-                       b = endianswap_long(b);
-               a->lput(pcibs, addr, b);
+       if (a) {
+#if PCI_DEBUG_IO > 1
+               write_log(_T("pci_io_lput %08x = %08x = %08x\n"), addr, addr2, b);
+#endif
+               if (a->lput) {
+                       if (endianswap)
+                               b = do_byteswap_32(b);
+                       a->lput(pcibs, addr, b);
+               }
+#if PCI_DEBUG_IO_MISS
+       } else {
+               write_log(_T("pci_io_lput %08x\n"), addr);
+#endif
        }
 #if PCI_DEBUG_IO
        write_log(_T("<- %08x\n"), b);
@@ -671,13 +786,19 @@ static void REGPARAM2 pci_io_wput(uaecptr addr, uae_u32 b)
        int endianswap;
        struct pci_board_state *pcibs;
        const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -2);
-       if (a && a->wput) {
-               if (endianswap) {
-                       b = endianswap_word(b);
-                       a->wput(pcibs, addr ^ (endianswap > 0 ? 2 : 0), b);
-               } else {
-                       a->wput(pcibs, addr, b);
+       if (a) {
+               if (a->wput) {
+                       if (endianswap) {
+                               b = do_byteswap_16(b);
+                               a->wput(pcibs, addr ^ (endianswap > 0 ? 2 : 0), b);
+                       } else {
+                               a->wput(pcibs, addr, b);
+                       }
                }
+#if PCI_DEBUG_IO_MISS
+       } else {
+               write_log(_T("pci_io_wput %08x\n"), addr);
+#endif
        }
 #if PCI_DEBUG_IO
        write_log(_T("<- %04x\n"), b);
@@ -688,12 +809,18 @@ static void REGPARAM2 pci_io_bput(uaecptr addr, uae_u32 b)
        int endianswap;
        struct pci_board_state *pcibs;
        const pci_addrbank *a = get_pci_io(&addr, &pcibs, &endianswap, -1);
-       if (a && a->bput) {
-               if (endianswap) {
-                       a->bput(pcibs, beswap(endianswap, addr), b);
-               } else {
-                       a->bput(pcibs, addr, b);
+       if (a) {
+               if (a->bput) {
+                       if (endianswap) {
+                               a->bput(pcibs, beswap(endianswap, addr), b);
+                       } else {
+                               a->bput(pcibs, addr, b);
+                       }
                }
+#if PCI_DEBUG_IO_MISS
+       } else {
+               write_log(_T("pci_io_bput %08x\n"), addr);
+#endif
        }
 #if PCI_DEBUG_IO
        write_log(_T("<- %02x\n"), b);
@@ -709,7 +836,7 @@ static uae_u32 REGPARAM2 pci_mem_lget(uaecptr addr)
        if (a && a->lget) {
                v = a->lget(pcibs, addr);
                if (endianswap)
-                       v = endianswap_long(v);
+                       v = do_byteswap_32(v);
        }
        return v;
 }
@@ -722,7 +849,7 @@ static uae_u32 REGPARAM2 pci_mem_wget(uaecptr addr)
        if (a && a->wget) {
                if (endianswap) {
                        v = a->wget(pcibs, addr ^ (endianswap > 0 ? 2 : 0));
-                       v = endianswap_word(v);
+                       v = do_byteswap_16(v);
                } else {
                        v = a->wget(pcibs, addr);
                }
@@ -735,12 +862,18 @@ static uae_u32 REGPARAM2 pci_mem_bget(uaecptr addr)
        int endianswap;
        struct pci_board_state *pcibs;
        const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
-       if (a && a->bget) {
-               if (endianswap) {
-                       v = a->bget(pcibs, beswap(endianswap, addr));
-               } else {
-                       v = a->bget(pcibs, addr);
+       if (a) {
+               if (a->bget) {
+                       if (endianswap) {
+                               v = a->bget(pcibs, beswap(endianswap, addr));
+                       } else {
+                               v = a->bget(pcibs, addr);
+                       }
                }
+#if PCI_DEBUG_IO_MISS
+       } else {
+               write_log(_T("pci_mem_bget %08x\n", addr));
+#endif
        }
        return v;
 }
@@ -748,11 +881,21 @@ static void REGPARAM2 pci_mem_lput(uaecptr addr, uae_u32 b)
 {
        int endianswap;
        struct pci_board_state *pcibs;
+       uaecptr addr2 = addr;
        const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
-       if (a && a->lput) {
-               if (endianswap)
-                       b = endianswap_long(b);
-               a->lput(pcibs, addr, b);
+#if PCI_DEBUG_IO > 1
+       write_log(_T("pci_mem_lput %08x = %08x = %08x\n"), addr, addr2, b);
+#endif
+       if (a) {
+               if (a->lput) {
+                       if (endianswap)
+                               b = do_byteswap_32(b);
+                       a->lput(pcibs, addr, b);
+               }
+#if PCI_DEBUG_IO_MISS
+       } else {
+               write_log(_T("pci_mem_lput %08x\n"), addr);
+#endif
        }
 }
 static void REGPARAM2 pci_mem_wput(uaecptr addr, uae_u32 b)
@@ -760,13 +903,19 @@ static void REGPARAM2 pci_mem_wput(uaecptr addr, uae_u32 b)
        int endianswap;
        struct pci_board_state *pcibs;
        const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
-       if (a && a->wput) {
-               if (endianswap) {
-                       b = endianswap_word(b);
-                       a->wput(pcibs, addr ^ (endianswap > 0 ? 2 : 0), b);
-               } else {
-                       a->wput(pcibs, addr, b);
+       if (a) {
+               if (a->wput) {
+                       if (endianswap) {
+                               b = do_byteswap_16(b);
+                               a->wput(pcibs, addr ^ (endianswap > 0 ? 2 : 0), b);
+                       } else {
+                               a->wput(pcibs, addr, b);
+                       }
                }
+#if PCI_DEBUG_IO_MISS
+       } else {
+               write_log(_T("pci_mem_wput %08x\n"), addr);
+#endif
        }
 }
 static void REGPARAM2 pci_mem_bput(uaecptr addr, uae_u32 b)
@@ -774,12 +923,18 @@ static void REGPARAM2 pci_mem_bput(uaecptr addr, uae_u32 b)
        int endianswap;
        struct pci_board_state *pcibs;
        const pci_addrbank *a = get_pci_mem(&addr, &pcibs, &endianswap);
-       if (a && a->bput) {
-               if (endianswap) {
-                       a->bput(pcibs, beswap(endianswap, addr), b);
-               } else {
-                       a->bput(pcibs, addr, b);
+       if (a) {
+               if (a->bput) {
+                       if (endianswap) {
+                               a->bput(pcibs, beswap(endianswap, addr), b);
+                       } else {
+                               a->bput(pcibs, addr, b);
+                       }
                }
+#if PCI_DEBUG_IO
+       } else {
+               write_log(_T("pci_mem_bput %08x\n"), addr);
+#endif
        }
 }
 
@@ -892,6 +1047,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;
                                } 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;
@@ -955,24 +1111,25 @@ 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 = pcib->memory_offset;
+       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_offset = pcib->window << 18;
+               pcib->memory_start_offset = pcib->window << 18;
+               offset = pcib->memory_start_offset;
        } else {
                // 1200
                uae_u16 mask = pcib->board_size == 4 * 1024 * 1024 ? 0xffc0 : 0xff80;
                pcib->window = v & mask;
-               pcib->memory_offset = pcib->window << 16;
-       }
-       pcib->memory_offset -= pcib->baseaddress;
-#if PCI_DEBUG_BRIDGE
-       if (pcib->memory_offset != offset) {
-               write_log(_T("Mediator window: %08x offset: %08x\n"),
-                       pcib->memory_offset + pcib->baseaddress, pcib->memory_offset);
+               pcib->memory_start_offset = pcib->window << 16;
+               offset = pcib->memory_start_offset;
+               pcib->memory_start_offset -= pcib->baseaddress;
+               pcib->memory_start_offset = -pcib->memory_start_offset;
        }
+#if 0
+       write_log(_T"Mediator window: %08x %04x PC=%08x\n"), offset, v, M68K_GETPC);
 #endif
 }
 
@@ -1026,7 +1183,7 @@ static uae_u32 REGPARAM2 pci_bridge_wget_2(uaecptr addr)
                        int offset = addr & 0x1f;
                        v = 0;
                        if (offset == 2) {
-                               v = 0x2080; // id
+                               v = 0x2000 | do_byteswap_16(pcib->window); // id + window
                        } else if (offset == 10) {
                                v = pcib->irq | (pcib->intena << 4);
                        }
@@ -1084,6 +1241,7 @@ static void REGPARAM2 pci_bridge_bput_2(uaecptr addr, uae_u32 b)
                        if (offset == 7) {
                                // config/io mapping
                                if (b & 0x20) {
+                                       map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16);
                                        if (b & 0x80) {
                                                map_banks_z2(&pci_config_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16);
                                        } else {
@@ -1092,6 +1250,7 @@ static void REGPARAM2 pci_bridge_bput_2(uaecptr addr, uae_u32 b)
                                } else {
                                        map_banks_z2(&dummy_bank, (pcib->baseaddress_2 + 0x10000) >> 16, 0x10000 >> 16);
                                }
+                               memory_map_dump();
                        } else if (offset == 11) {
                                pcib->intena = b >> 4;
                        } else if (offset == 0x40) {
@@ -1198,9 +1357,37 @@ addrbank pci_bridge_bank_2 = {
        ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
 };
 
-static bool validate_pci_dma(struct pci_board_state *pcibs, uaecptr addr, int size)
+static int validate_dma_last_board;
+static int validate_dma_last_bridge;
+
+static bool validate_pci_dma(struct pci_board_state *pcibs, uaecptr addr, int size, struct pci_board_state **pcibsp, int *bar)
 {
        struct pci_bridge *pcib = pcibs->bridge;
+       if (pcib->pcipcidma) {
+               for (int i = 0; i < PCI_BRIDGE_MAX; i++) {
+                       struct pci_bridge *pcib = bridges[(i + validate_dma_last_bridge) % PCI_BRIDGE_MAX];
+                       if (!pcib)
+                               continue;
+                       for (int j = 0; j < MAX_PCI_BOARDS; j++) {
+                               struct pci_board_state *pcibs = &pcib->boards[(j + validate_dma_last_board) % MAX_PCI_BOARDS];
+                               if (pcibs->board) {
+                                       for (int k = 0; k < MAX_PCI_BARS - 1; k++) {
+                                               if (pcibs->bar_enabled[k] && addr >= pcibs->bar[k] && addr < pcibs->bar[k] + pcibs->bar_size[k] && !(pcibs->bar_size[k] & 1)) {
+                                                       if (pcibs->board->bars[k].bget && pcibs->board->bars[k].bput) {
+                                                               *bar = k;
+                                                               *pcibsp = pcibs;
+                                                               validate_dma_last_board = j;
+                                                               validate_dma_last_bridge = i;
+                                                               return true;
+                                                       } else {
+                                                               return false;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
        addrbank *ab = &get_mem_bank(addr);
        if (ab == &dummy_bank)
                return false;
@@ -1217,11 +1404,21 @@ static bool validate_pci_dma(struct pci_board_state *pcibs, uaecptr addr, int si
 
 void pci_write_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int size)
 {
-       if (validate_pci_dma(pcibs, addr, size)) {
-               while (size > 0) {
-                       put_byte(addr, *p++);
-                       addr++;
-                       size--;
+       struct pci_board_state *pcibs2 = NULL;
+       int bar;
+       if (validate_pci_dma(pcibs, addr, size, &pcibs2, &bar)) {
+               if (pcibs2) {
+                       while (size > 0) {
+                               pcibs2->board->bars[bar].bput(pcibs2, addr, *p++);
+                               addr++;
+                               size--;
+                       }
+               } else {
+                       while (size > 0) {
+                               put_byte(addr, *p++);
+                               addr++;
+                               size--;
+                       }
                }
        } else {
                write_log(_T("pci_write_dma invalid address %08x, size %d\n"), addr, size);
@@ -1234,11 +1431,21 @@ void pci_write_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int s
 }
 void pci_read_dma(struct pci_board_state *pcibs, uaecptr addr, uae_u8 *p, int size)
 {
-       if (validate_pci_dma(pcibs, addr, size)) {
-               while (size > 0) {
-                       *p++ = get_byte(addr);
-                       addr++;
-                       size--;
+       struct pci_board_state *pcibs2 = NULL;
+       int bar;
+       if (validate_pci_dma(pcibs, addr, size, &pcibs2, &bar)) {
+               if (pcibs2) {
+                       while (size > 0) {
+                               *p++ = pcibs2->board->bars[bar].bget(pcibs2, addr);
+                               addr++;
+                               size--;
+                       }
+               } else {
+                       while (size > 0) {
+                               *p++ = get_byte(addr);
+                               addr++;
+                               size--;
+                       }
                }
        } else {
                write_log(_T("pci_read_dma invalid address %08x, size %d\n"), addr, size);
@@ -1308,8 +1515,9 @@ void pci_dump(int log)
                                if (pcibs && pcibs != oldpcibs) {
                                        const struct pci_board *pci = pcibs->board;
                                        if (pcibs->board) {
+                                               const struct pci_config *cfg = &pcibs->dynamic_config;
                                                _stprintf(txt, _T(" - %08x Card %d/%d: [%04X/%04X] %s IO=%d MEM=%d\n"),
-                                                       start, pcibs->slot, pcibs->func, pci->config->vendor, pci->config->device, pci->label,
+                                                       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);
@@ -1465,22 +1673,45 @@ static const struct pci_board ncr_53c815_pci_board =
        }
 };
 
+bool pci_validate_address(uaecptr addr, uae_u32 size, bool io)
+{
+       struct pci_bridge *pcib = get_pci_bridge(addr);
+       if (!pcib)
+               return false;
+       const pci_addrbank *ab1 = NULL, *ab2 = NULL;
+       int endianswap1, endianswap2;
+       struct pci_board_state* pcibs;
+       uaecptr addr1 = addr, addr2 = addr + size - 1;
+       if (io) {
+               ab1 = get_pci_io(&addr1, &pcibs, &endianswap1, 4);
+               ab2 = get_pci_io(&addr2, &pcibs, &endianswap2, 4);
+       } else {
+               ab1 = get_pci_mem(&addr1, &pcibs, &endianswap1);
+               ab2 = get_pci_mem(&addr2, &pcibs, &endianswap2);
+       }
+       if (!ab1 || !ab2)
+               return false;
+       if (ab1 != ab2)
+               return false;
+       return true;
+}
+
 static void add_pci_devices(struct pci_bridge *pcib, struct autoconfig_info *aci)
 {
        int slot = 0;
 
        if (is_device_rom(&currprefs, ROMTYPE_NE2KPCI, 0) >= 0) {
-               pci_board_add(pcib, &ne2000_pci_board, slot++, 0, aci);
+               pci_board_add(pcib, &ne2000_pci_board, slot++, 0, aci, NULL);
        }
 
        if (is_device_rom(&currprefs, ROMTYPE_FM801, 0) >= 0) {
-               pci_board_add(pcib, &fm801_pci_board, slot, 0, aci);
-               pci_board_add(pcib, &fm801_pci_board_func1, slot, 1, aci);
+               pci_board_add(pcib, &fm801_pci_board, slot, 0, aci, NULL);
+               pci_board_add(pcib, &fm801_pci_board_func1, slot, 1, aci, NULL);
                slot++;
        }
 
        if (is_device_rom(&currprefs, ROMTYPE_ES1370, 0) >= 0) {
-               pci_board_add(pcib, &es1370_pci_board, slot++, 0, aci);
+               pci_board_add(pcib, &es1370_pci_board, slot++, 0, aci, NULL);
        }
 }
 
@@ -1522,7 +1753,7 @@ bool dkb_wildfire_pci_init(struct autoconfig_info *aci)
        pcib->configured = -1;
        pcib->pcipcidma = true;
        pcib->amigapicdma = true;
-       pci_board_add(pcib, &ncr_53c815_pci_board, 0, 0, aci);
+       pci_board_add(pcib, &ncr_53c815_pci_board, 0, 0, aci, NULL);
        map_banks(&pci_config_bank, 0x80000000 >> 16, 0x10000000 >> 16, 0);
        map_banks(&pci_mem_bank, 0x90000000 >> 16, 0x30000000 >> 16, 0);
        map_banks(&pci_io_bank, 0xc0000000 >> 16, 0x30000000 >> 16, 0);
diff --git a/x86.cpp b/x86.cpp
index c1280b1a7e0ae5d3818f67f1e2d407d017267928..17b88f8b7588b42cb9847496d26d17662c5e90ca 100644 (file)
--- a/x86.cpp
+++ b/x86.cpp
@@ -3310,9 +3310,28 @@ int device_get_config_int(const char *s)
        if (!strcmp(s, "dithering")) {
                return 1;
        }
+       if (!strcmp(s, "dacfilter")) {
+               return 1;
+       }
+       if (!strcmp(s, "recompiler")) {
+               return 1;
+       }
        if (!strcmp(s, "memory")) {
                return pcem_getvramsize() >> 20;
        }
+       if (!strcmp(s, "render_threads")) {
+#ifdef _WIN32
+               SYSTEM_INFO si;
+               GetSystemInfo(&si);
+               if (si.dwNumberOfProcessors >= 8)
+                       return 4;
+               if (si.dwNumberOfProcessors >= 4)
+                       return 2;
+               return 1;
+#else
+               return 4;
+#endif
+       }
 
 
        if (x86_global_settings < 0)