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,
#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
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)
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"),
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;
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;
};
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,
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,
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)
{
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);
}
}
}
+ //picasso_getwritewatch(i, 0, NULL, NULL);
}
}
}
static int gfxboard_pcem_poll(struct rtggfxboard *gb)
{
+ if (!gb->vram)
+ return 0;
return svga_poll(gb->pcemobject2);
}
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);
+ }
}
}
}
}
}
}
+ 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)
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);
//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;
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) {
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)
}
}
+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();
}
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);
}
}
}
+ if (gb->board->pci && gb->vram) {
+ bool svga_on(void* p);
+ set_monswitch(gb, svga_on(gb->pcemobject));
+ }
}
if (gb->monswitch_keep_trying) {
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);
+ }
+ }
}
}
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()) {
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;
}
}
+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)
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);
}
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;
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;
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);
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;
}
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;
}
-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);
#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
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 */
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
{
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
bool io_map_active;
struct pci_bridge *bridge;
pci_dev_irq irq_callback;
+ struct pci_config dynamic_config;
+ void *userdata;
};
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;
#define ROMTYPE_ALF2 0x00100085
#define ROMTYPE_SYNTHESIS 0x00100086
#define ROMTYPE_MASTFB 0x00100087
+#define ROMTYPE_VOODOO3 0x00100088
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000
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)
{
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);
<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" />
<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">
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;
pcem_linear_write_l = dummy_lwrite;
pcem_mapping_linear = NULL;
pcem_mapping_linear_offset = 0;
+ timer_head = NULL;
}
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;
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
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);
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_*/
--- /dev/null
+void ddc_init(void);
+void ddc_i2c_change(int new_clock, int new_data);
+int ddc_read_clock(void);
+int ddc_read_data(void);
int set_reset_disabled;
uint8_t egapal[16];
- uint32_t pallook[256];
+ uint32_t pallook[512];
PALETTE vgapal;
int ramdac_type;
int lowres, interlace;
int linedbl, rowcount;
double clock;
- uint32_t ma_latch;
+ uint32_t ma_latch, ca_adj;
int bpp;
uint64_t dispontime, dispofftime;
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
#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;
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);
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
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);
}
}
}
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");
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;
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;
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");
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;
}
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;
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));
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;
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;
}
#endif
int c;
+#if 0
#ifndef RELEASE_BUILD
if (voodoo->tex_mem[0])
{
fclose(f);
}
}
+#endif
#endif
thread_kill(voodoo->fifo_thread);
.name = "type",
.description = "Voodoo type",
.type = CONFIG_SELECTION,
+ .default_int = 0,
.selection =
{
{
{
.description = ""
}
- },
- .default_int = 0
+ }
},
{
.name = "framebuffer_memory",
.description = "Framebuffer memory size",
.type = CONFIG_SELECTION,
+ .default_int = 2,
.selection =
{
{
{
.description = ""
}
- },
- .default_int = 2
+ }
},
{
.name = "texture_memory",
.description = "Texture memory size",
.type = CONFIG_SELECTION,
+ .default_int = 2,
.selection =
{
{
{
.description = ""
}
- },
- .default_int = 2
+ }
},
{
.name = "bilinear",
.name = "render_threads",
.description = "Render threads",
.type = CONFIG_SELECTION,
+ .default_int = 2,
.selection =
{
{
{
.description = ""
}
- },
- .default_int = 2
+ }
},
{
.name = "sli",
uint32_t desktop_stride_tiled;
int type;
+
+ int vblank_irq;
} banshee_t;
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)
#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)
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;
temp = 0;
else
temp = 0x10;
+ if (banshee->vblank_irq > 0)
+ temp |= 0x80;
break;
case 0x3D4:
temp = svga->crtcreg;
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;
}
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)
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)
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;
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;
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;
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;
else
banshee->voodoo->scrfilterEnabled = 0;
voodoo_threshold_check(banshee->voodoo);
- pclog("Banshee Filter: %06x\n", val);
+ //pclog("Banshee Filter: %06x\n", val);
break;
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:
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);
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)
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;
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*/
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)
{
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];
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)
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]);
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)
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]);
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;
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;
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);
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;
svga->hwcursor_latch.addr += 16;
x_off = svga->hwcursor_latch.x;
-
+ x_off <<= svga->horizontal_linedbl;
+
if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE)
{
/*X11 mode*/
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 */
{
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]);
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;
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);
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;
{
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:
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
+ .default_int = 16,
.selection =
{
{
{
.description = ""
}
- },
- .default_int = 16
+ }
},
{
.name = "bilinear",
.name = "render_threads",
.description = "Render threads",
.type = CONFIG_SELECTION,
+ .default_int = 2,
.selection =
{
{
{
.description = ""
}
- },
- .default_int = 2
+ }
},
#ifndef NO_CODEGEN
{
.name = "render_threads",
.description = "Render threads",
.type = CONFIG_SELECTION,
+ .default_int = 2,
.selection =
{
{
.description = ""
}
},
- .default_int = 2
},
#ifndef NO_CODEGEN
{
}
};
+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");
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,
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,
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,
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;
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;
banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W;
- ddc_init();
+ //ddc_init();
switch (type)
{
break;
}
+ banshee->svga.vblank_start = banshee_vblank_start;
+
return banshee;
}
#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)
{
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++)
}
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++)
{
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++)
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++)
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);
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
}
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);
}
}
+
+#include <emmintrin.h>
+
#include <math.h>
#include <stddef.h>
#include "ibm.h"
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;
}
}
#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
+
#if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__)
#define NO_CODEGEN
#endif
*
* PCI Bridge board emulation
*
-* Copyright 2015 Toni Wilen
+* Copyright 2015-2020 Toni Wilen
* Hardware information by Radoslaw Kujawa
*
*/
#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"
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)
{
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);
}
}
}
+ return pcibs;
}
static void pci_free(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);
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;
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]) {
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
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];
}
#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;
}
}
}
-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)
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;
}
v |= config[offset + 0] << 0;
}
#if PCI_DEBUG_CONFIG
- write_log(_T("- %08x\n"), v);
+ write_log(_T("-> %08x\n"), v);
#endif
}
return v;
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;
v = config[beswap(endianswap, offset)];
}
#if PCI_DEBUG_CONFIG
- write_log(_T("- %02x\n"), v);
+ write_log(_T("-> %02x\n"), v);
#endif
}
return v;
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)
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)
} 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;
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
}
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;
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;
{
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);
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);
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);
if (a && a->lget) {
v = a->lget(pcibs, addr);
if (endianswap)
- v = endianswap_long(v);
+ v = do_byteswap_32(v);
}
return v;
}
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);
}
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;
}
{
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)
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)
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
}
}
}
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;
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
}
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);
}
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 {
} 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) {
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;
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);
}
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);
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);
}
};
+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);
}
}
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);
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)