From: Toni Wilen Date: Mon, 21 Dec 2020 19:23:51 +0000 (+0200) Subject: Voodoo 3 emulation from PCem. X-Git-Tag: 4900~234 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=12c718bd285d4f123bf0171a029d42c2411d3cfc;p=francis%2Fwinuae.git Voodoo 3 emulation from PCem. --- diff --git a/expansion.cpp b/expansion.cpp index ee157c26..b9b52fbc 100644 --- a/expansion.cpp +++ b/expansion.cpp @@ -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, diff --git a/gfxboard.cpp b/gfxboard.cpp index 111588cf..a87297a4 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -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 (\\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); diff --git a/include/gfxboard.h b/include/gfxboard.h index 8a6e1845..e27b842e 100644 --- a/include/gfxboard.h +++ b/include/gfxboard.h @@ -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 diff --git a/include/pci.h b/include/pci.h index 1842ff48..ffbd5482 100644 --- a/include/pci.h +++ b/include/pci.h @@ -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 */ diff --git a/include/pci_hw.h b/include/pci_hw.h index f9052563..2cbcdfc1 100644 --- a/include/pci_hw.h +++ b/include/pci_hw.h @@ -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; diff --git a/include/rommgr.h b/include/rommgr.h index 1d160124..4e7a3ac2 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -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 diff --git a/od-win32/picasso96_win.cpp b/od-win32/picasso96_win.cpp index 5756984e..329fe35a 100644 --- a/od-win32/picasso96_win.cpp +++ b/od-win32/picasso96_win.cpp @@ -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) { diff --git a/od-win32/picasso96_win.h b/od-win32/picasso96_win.h index 5e10fc70..74b86a74 100644 --- a/od-win32/picasso96_win.h +++ b/od-win32/picasso96_win.h @@ -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); diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj b/od-win32/winuae_msvc15/winuae_msvc.vcxproj index b0b02da9..9477f5f1 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj @@ -483,7 +483,7 @@ true false ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;..\..\ppc\pearpc;%(AdditionalIncludeDirectories) - WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions) + WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions) true Sync Default @@ -637,7 +637,7 @@ false false ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;%(AdditionalIncludeDirectories) - WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions) + WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions) true Sync Default @@ -795,7 +795,7 @@ true true ..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;%(AdditionalIncludeDirectories) - WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions) + WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions) true Sync Default @@ -976,6 +976,17 @@ + + + + + + + + + + + diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters index 27a8b4eb..9b2d7a8d 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters @@ -970,6 +970,39 @@ win32\FX11 + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + + + pcem + diff --git a/pcem/pcemglue.cpp b/pcem/pcemglue.cpp index a8462bd9..d01a1a06 100644 --- a/pcem/pcemglue.cpp +++ b/pcem/pcemglue.cpp @@ -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 diff --git a/pcem/pcemglue.h b/pcem/pcemglue.h index 8c5ed7aa..1a8a32b9 100644 --- a/pcem/pcemglue.h +++ b/pcem/pcemglue.h @@ -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); diff --git a/pcem/timer.h b/pcem/timer.h index ddcd9c00..f22acb7f 100644 --- a/pcem/timer.h +++ b/pcem/timer.h @@ -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 index 00000000..7b8f8bd2 --- /dev/null +++ b/pcem/vid_ddc.h @@ -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); diff --git a/pcem/vid_svga.h b/pcem/vid_svga.h index a4bbd73c..e0d6900d 100644 --- a/pcem/vid_svga.h +++ b/pcem/vid_svga.h @@ -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 diff --git a/pcem/vid_svga_render.cpp b/pcem/vid_svga_render.cpp index 55ed2f91..a2609cd0 100644 --- a/pcem/vid_svga_render.cpp +++ b/pcem/vid_svga_render.cpp @@ -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; diff --git a/pcem/vid_svga_render.h b/pcem/vid_svga_render.h index be8105f7..06e5097e 100644 --- a/pcem/vid_svga_render.h +++ b/pcem/vid_svga_render.h @@ -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); diff --git a/pcem/vid_voodoo.cpp b/pcem/vid_voodoo.cpp index ed4553c6..4f5fcacb 100644 --- a/pcem/vid_voodoo.cpp +++ b/pcem/vid_voodoo.cpp @@ -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", diff --git a/pcem/vid_voodoo_banshee.cpp b/pcem/vid_voodoo_banshee.cpp index 2ac803e5..d332f066 100644 --- a/pcem/vid_voodoo_banshee.cpp +++ b/pcem/vid_voodoo_banshee.cpp @@ -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; } diff --git a/pcem/vid_voodoo_banshee_blitter.cpp b/pcem/vid_voodoo_banshee_blitter.cpp index f6f0d031..8949ecda 100644 --- a/pcem/vid_voodoo_banshee_blitter.cpp +++ b/pcem/vid_voodoo_banshee_blitter.cpp @@ -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) diff --git a/pcem/vid_voodoo_codegen_x86-64.h b/pcem/vid_voodoo_codegen_x86-64.h index 35ed9e57..581dfa65 100644 --- a/pcem/vid_voodoo_codegen_x86-64.h +++ b/pcem/vid_voodoo_codegen_x86-64.h @@ -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++) diff --git a/pcem/vid_voodoo_codegen_x86.h b/pcem/vid_voodoo_codegen_x86.h index c925d5b1..87c0f1de 100644 --- a/pcem/vid_voodoo_codegen_x86.h +++ b/pcem/vid_voodoo_codegen_x86.h @@ -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++) { diff --git a/pcem/vid_voodoo_display.cpp b/pcem/vid_voodoo_display.cpp index 9ce92dde..34d7e13c 100644 --- a/pcem/vid_voodoo_display.cpp +++ b/pcem/vid_voodoo_display.cpp @@ -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; xh_disp) * 3]; + //uint8_t fil3[(voodoo->h_disp) * 3]; + uint8_t fil3[4096 * 3]; /* 16 to 32-bit */ for (x=0; xscrfilter && 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 } diff --git a/pcem/vid_voodoo_fifo.cpp b/pcem/vid_voodoo_fifo.cpp index 59861f3f..1c873162 100644 --- a/pcem/vid_voodoo_fifo.cpp +++ b/pcem/vid_voodoo_fifo.cpp @@ -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); } } diff --git a/pcem/vid_voodoo_render.cpp b/pcem/vid_voodoo_render.cpp index 21161807..777d9cc3 100644 --- a/pcem/vid_voodoo_render.cpp +++ b/pcem/vid_voodoo_render.cpp @@ -1,3 +1,6 @@ + +#include + #include #include #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 diff --git a/pcem/vid_voodoo_render.h b/pcem/vid_voodoo_render.h index 9ba73dc6..54a9be42 100644 --- a/pcem/vid_voodoo_render.h +++ b/pcem/vid_voodoo_render.h @@ -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 db2945a1..61697be1 100644 --- 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 c1280b1a..17b88f8b 100644 --- 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)