Voodoo 3 emulation from PCem.

This commit is contained in:
Toni Wilen 2020-12-21 21:23:51 +02:00
parent 02dbc440b5
commit 12c718bd28
28 changed files with 1306 additions and 283 deletions

View File

@ -5819,6 +5819,12 @@ const struct expansionromtype expansionroms[] = {
NULL, 0,
false, EXPANSIONTYPE_RTG
},
{
_T("vooodoo3_3k"), _T("Voodoo 3 3000"), _T("3dfx"),
NULL, NULL, NULL, NULL, ROMTYPE_VOODOO3 | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, false,
NULL, 0,
false, EXPANSIONTYPE_RTG
},
{
_T("x86vga"), _T("x86 VGA"), NULL,
NULL, NULL, NULL, NULL, ROMTYPE_x86_VGA | ROMTYPE_NONE, 0, 0, BOARD_IGNORE, true,

View File

@ -49,10 +49,19 @@ static bool memlogw = true;
#include "pcem/vid_s3_virge.h"
#include "pcem/vid_cl5429.h"
#include "pcem/vid_s3.h"
#include "pcem/vid_voodoo_banshee.h"
#include "pci.h"
#include "pci_hw.h"
#include "pcem/pcemglue.h"
#include "qemuvga/qemuuaeglue.h"
#include "qemuvga/vga.h"
extern void put_io_pcem(uaecptr, uae_u32, int);
extern uae_u32 get_io_pcem(uaecptr, int);
extern void put_mem_pcem(uaecptr, uae_u32, int);
extern uae_u32 get_mem_pcem(uaecptr, int);
#define MONITOR_SWITCH_DELAY 25
#define GFXBOARD_AUTOCONFIG_SIZE 131072
@ -112,6 +121,7 @@ struct gfxboard
struct gfxboard_func *func;
device_t *pcemdev;
uae_u8 er_flags;
bool pci;
};
#define ISP4() (gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z2 || gb->rbc->rtgmem_type == GFXBOARD_ID_PICASSO4_Z3)
@ -236,6 +246,14 @@ static const struct gfxboard boards[] =
0, 0xc1, &a2410_func
},
#endif
{
GFXBOARD_ID_VOODOO3,
_T("Voodoo 3 3000"), _T("3dfx"), _T("V3_3000"),
0, 0, 0,
0x00000000, 0x01000000, 0x01000000, 0x01000000, 0, 0, -1, false,
ROMTYPE_VOODOO3,
0, NULL, &voodoo_3_3000_device,0, true
},
{
GFXBOARD_ID_VGA,
_T("x86 bridgeboard VGA"), _T("x86"), _T("VGA"),
@ -329,6 +347,9 @@ struct rtggfxboard
addrbank gfxboard_bank_mmio_wbs_pcem;
addrbank gfxboard_bank_mmio_lbs_pcem;
addrbank gfxboard_bank_special_pcem;
addrbank gfxboard_bank_bios;
addrbank *old_pci_bank;
addrbank *gfxmem_bank;
uae_u8 *vram_back;
@ -348,6 +369,10 @@ struct rtggfxboard
int pcem_io_mask;
int pcem_vblank;
bool p4_revb;
uae_u8 *bios;
uae_u32 bios_mask;
int lfbbyteswapmode;
struct pci_board_state *pcibs;
void *userdata;
};
@ -384,6 +409,7 @@ DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mmio_pcem);
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mmio_wbs_pcem);
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mmio_lbs_pcem);
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, special_pcem);
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, bios);
static const addrbank tmpl_gfxboard_bank_memory = {
gfxboard_lget_mem, gfxboard_wget_mem, gfxboard_bget_mem,
@ -488,7 +514,6 @@ static const addrbank tmpl_gfxboard_bank_vram_p4z2_pcem = {
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
};
static const addrbank tmpl_gfxboard_bank_io_pcem = {
gfxboard_lget_io_pcem, gfxboard_wget_io_pcem, gfxboard_bget_io_pcem,
gfxboard_lput_io_pcem, gfxboard_wput_io_pcem, gfxboard_bput_io_pcem,
@ -554,6 +579,24 @@ static const addrbank tmpl_gfxboard_bank_special_pcem = {
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
};
static void REGPARAM2 dummy_lput(uaecptr addr, uae_u32 l)
{
}
static void REGPARAM2 dummy_wput(uaecptr addr, uae_u32 l)
{
}
static void REGPARAM2 dummy_bput(uaecptr addr, uae_u32 l)
{
}
static const addrbank tmpl_gfxboard_bank_bios = {
gfxboard_lget_bios, gfxboard_wget_bios, gfxboard_bget_bios,
dummy_lput, dummy_wput, dummy_bput,
default_xlate, default_check, NULL, NULL, _T("SVGA BIOS"),
dummy_lgeti, dummy_wgeti,
ABFLAG_ROM | ABFLAG_SAFE, S_READ, S_WRITE
};
static void ew(struct rtggfxboard *gb, int addr, uae_u32 value)
{
@ -605,13 +648,32 @@ void gfxboard_free_vram(int index)
extern uae_u8 *getpcembuffer32(int, int, int);
extern int svga_get_vtotal(void);
extern int svga_poll(void *p);
extern void voodoo_callback(void *p);
// PCEM
static void pcem_flush(struct rtggfxboard* gb, int index)
{
#if 0
uae_u8 **buf;
uae_u8 *start;
int cnt = picasso_getwritewatch(index, gb->vram_start_offset, &buf, &start);
if (cnt < 0) {
gb->pcemdev->force_redraw(gb->pcemobject);
} else {
for (int i = 0; i < cnt; i++) {
int offset = buf[i] - start;
pcem_linear_mark(offset);
}
}
#endif
}
void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
if (gb->pcemdev && gb->pcemobject) {
pcem_flush(gb, i);
if (rtg_visible[gb->monitor_id] >= 0 && gb->monswitch_delay == 0 && gb->monswitch_current == gb->monswitch_new) {
if (gb->gfxboard_surface == NULL) {
gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false, false);
@ -626,12 +688,15 @@ void video_blit_memtoscreen(int x, int y, int y1, int y2, int w, int h)
}
}
}
//picasso_getwritewatch(i, 0, NULL, NULL);
}
}
}
static int gfxboard_pcem_poll(struct rtggfxboard *gb)
{
if (!gb->vram)
return 0;
return svga_poll(gb->pcemobject2);
}
@ -641,12 +706,14 @@ static void gfxboard_rethink(void)
struct rtggfxboard* gb = &rtggfxboards[i];
if (gb->pcemdev && gb->pcemobject && gb->gfxboard_intreq && gb->gfxboard_intena) {
int irq = 0;
if (gb->board->irq == 2 && gb->gfxboard_intena != 6)
irq = 2;
else
irq = 6;
if (irq) {
safe_interrupt_set(IRQ_SOURCE_GFX, gb->monitor_id, irq == 6);
if (gb->board->irq > 0) {
if (gb->board->irq == 2 && gb->gfxboard_intena != 6)
irq = 2;
else
irq = 6;
if (irq > 0) {
safe_interrupt_set(IRQ_SOURCE_GFX, gb->monitor_id, irq == 6);
}
}
}
}
@ -678,6 +745,33 @@ static void gfxboard_hsync_handler(void)
}
}
}
pcemglue_hsync();
}
static void reinit_vram(struct rtggfxboard *gb, uaecptr vram, bool direct)
{
if (vram == gb->gfxmem_bank->start)
return;
gb->vram = NULL;
mapped_free(gb->gfxmem_bank);
gb->gfxmem_bank->flags &= ~ABFLAG_ALLOCINDIRECT;
if (!direct) {
gb->gfxmem_bank->flags |= ABFLAG_ALLOCINDIRECT;
}
gb->gfxmem_bank->label = _T("*");
gb->gfxmem_bank->start = vram;
mapped_malloc(gb->gfxmem_bank);
gb->vram = gb->gfxmem_bank->baseaddr;
gb->vramend = gb->gfxmem_bank->baseaddr + gb->gfxmem_bank->reserved_size;
gb->vramrealstart = gb->vram;
gb->vram += gb->vram_start_offset;
gb->vramend += gb->vram_start_offset;
if (gb->pcemdev) {
void svga_setvram(void *p, uint8_t *vram);
void voodoo_update_vram(void *p);
svga_setvram(gb->pcemobject2, gb->vram);
voodoo_update_vram(gb->pcemobject);
}
}
static void init_board (struct rtggfxboard *gb)
@ -713,6 +807,10 @@ static void init_board (struct rtggfxboard *gb)
if (gb->board->manufacturer) {
gb->gfxmem_bank->label = _T("*");
mapped_malloc(gb->gfxmem_bank);
} else if (gb->board->pci) {
// We don't know VRAM address until PCI bridge and
// PCI display card's BARs have been initialized
;
} else {
gb->gfxmem_bank->label = _T("*");
gb->vram_back = xmalloc(uae_u8, vramsize);
@ -731,8 +829,10 @@ static void init_board (struct rtggfxboard *gb)
//gb->gfxmem_bank->baseaddr = gb->vram;
// restore original value because this is checked against
// configured size in expansion.cpp
gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
if (!gb->board->pci) {
gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
}
gb->vga.vga.vram_size_mb = rbc->rtgmem_size >> 20;
gb->vgaioregion.opaque = &gb->vgaioregionptr;
gb->vgaioregion.data = gb;
@ -752,7 +852,9 @@ static void init_board (struct rtggfxboard *gb)
gb->fakesurface.data = gb;
vga_common_init(&gb->vga.vga);
gb->vga.vga.con = (void*)gb;
cirrus_init_common(&gb->vga, chiptype, 0, NULL, NULL, gb->board->manufacturer == 0, gb->board->romtype == ROMTYPE_x86_VGA);
if (chiptype) {
cirrus_init_common(&gb->vga, chiptype, 0, NULL, NULL, gb->board->manufacturer == 0, gb->board->romtype == ROMTYPE_x86_VGA);
}
gb->pcemdev = gb->board->pcemdev;
gb->pcem_pci_configured = false;
if (gb->pcemdev) {
@ -984,9 +1086,6 @@ static void vga_update_size_ext(struct rtggfxboard *gb)
static void gfxboard_set_fullrefresh(struct rtggfxboard *gb, int cnt)
{
gb->fullrefresh = cnt;
if (gb->pcemdev && gb->pcemobject) {
gb->pcemdev->force_redraw(gb->pcemobject);
}
}
static bool gfxboard_setmode_ext(struct rtggfxboard *gb)
@ -1266,16 +1365,30 @@ void gfxboard_refresh(int monid)
}
}
static void set_monswitch(struct rtggfxboard *gb, bool newval)
{
if (gb->monswitch_new == newval)
return;
gb->monswitch_new = newval;
gb->monswitch_delay = MONITOR_SWITCH_DELAY;
}
void gfxboard_intreq(void *p, int act, bool safe)
{
struct rtggfxboard *gb = (struct rtggfxboard*)p;
if (act) {
if (gb->board->irq && gb->gfxboard_intena) {
int irq = 0;
gb->gfxboard_intreq = 1;
if (gb->board->irq > 0) {
gb->gfxboard_intreq = 1;
} else {
gb->pcibs->irq_callback(gb->pcibs, true);
}
}
} else {
gb->gfxboard_intreq = 0;
if (gb->board->irq < 0) {
gb->pcibs->irq_callback(gb->pcibs, false);
}
}
gfxboard_rethink();
}
@ -1323,7 +1436,7 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
fcount++;
if ((fcount % 50) == 0) {
if (gb->pcemobject && gb->pcemdev->add_status_info) {
char txt[256];
char txt[1024];
txt[0] = 0;
gb->pcemdev->add_status_info(txt, sizeof(txt), gb->pcemobject);
TCHAR *s = au(txt);
@ -1332,6 +1445,10 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
}
}
}
if (gb->board->pci && gb->vram) {
bool svga_on(void* p);
set_monswitch(gb, svga_on(gb->pcemobject));
}
}
if (gb->monswitch_keep_trying) {
@ -1425,13 +1542,23 @@ void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
continue;
if (!gb->monswitch_delay && gb->monswitch_current && ad->picasso_on && ad->picasso_requested_on && !gb->resolutionchange) {
picasso_getwritewatch(i, gb->vram_start_offset);
if (!gb->pcemdev) {
if (picasso_getwritewatch(i, gb->vram_start_offset, NULL, NULL) < 0) {
gb->fullrefresh = 1;
}
if (gb->fullrefresh)
gb->vga.vga.graphic_mode = -1;
gb->vga_refresh_active = true;
gb->vga.vga.hw_ops->gfx_update(&gb->vga);
gb->vga_refresh_active = false;
} else {
if (gb->pcemobject) {
if (gb->fullrefresh) {
gb->pcemdev->force_redraw(gb->pcemobject);
} else {
pcem_flush(gb, i);
}
}
}
}
@ -1605,14 +1732,6 @@ static void reset_pci (struct rtggfxboard *gb)
gb->p4i2c = 0xff;
}
static void set_monswitch(struct rtggfxboard *gb, bool newval)
{
if (gb->monswitch_new == newval)
return;
gb->monswitch_new = newval;
gb->monswitch_delay = MONITOR_SWITCH_DELAY;
}
static void picassoiv_checkswitch (struct rtggfxboard *gb)
{
if (ISP4()) {
@ -2939,6 +3058,8 @@ static void gfxboard_free_board(struct rtggfxboard *gb)
gb->vramrealstart = NULL;
xfree(gb->fakesurface_surface);
gb->fakesurface_surface = NULL;
xfree(gb->bios);
gb->bios = NULL;
gb->configured_mem = 0;
gb->configured_regs = 0;
gb->monswitch_new = false;
@ -3348,6 +3469,281 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v)
}
}
static void pci_change_config(struct pci_board_state *pci)
{
struct rtggfxboard *gb = (struct rtggfxboard*)pci->userdata;
if (pci->memory_map_active) {
// direct access, bypass PCI emulation redirection for performance reasons
if (pci_validate_address(pci->bar[1] + pci->bridge->memory_start_offset, 0x02000000, false)) {
reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true);
gb->old_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset);
//map_banks(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0);
//map_banks(&gb->gfxboard_bank_memory, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0);
//memory_map_dump();
} else {
reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false);
}
}
}
void gfxboard_voodoo_lfb_endianswap(int m)
{
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
struct rtggfxboard *gb = &rtggfxboards[i];
if (gb->active && gb->board->romtype == ROMTYPE_VOODOO3) {
gb->lfbbyteswapmode = m;
if (gb->old_pci_bank && 0) {
if (0) {
map_banks(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0);
map_banks(&gb->gfxboard_bank_memory, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0);
} else {
map_banks(gb->old_pci_bank, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0);
map_banks(gb->old_pci_bank, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0);
}
}
return;
}
}
}
static void REGPARAM2 voodoo3_io_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
put_io_pcem(addr, b, 2);
}
static void REGPARAM2 voodoo3_io_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
put_io_pcem(addr, b, 1);
}
static void REGPARAM2 voodoo3_io_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
put_io_pcem(addr, b, 0);
}
static uae_u32 REGPARAM2 voodoo3_io_lget(struct pci_board_state *pcibs, uaecptr addr)
{
return get_io_pcem(addr, 2);
}
static uae_u32 REGPARAM2 voodoo3_io_wget(struct pci_board_state *pcibs, uaecptr addr)
{
return get_io_pcem(addr, 1);
}
static uae_u32 REGPARAM2 voodoo3_io_bget(struct pci_board_state *pcibs, uaecptr addr)
{
return get_io_pcem(addr, 0);
}
static void REGPARAM2 voodoo3_mb0_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
put_mem_pcem(addr, b, 2);
}
static void REGPARAM2 voodoo3_mb0_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
put_mem_pcem(addr, b, 1);
}
static void REGPARAM2 voodoo3_mb0_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
put_mem_pcem(addr, b, 0);
}
static uae_u32 REGPARAM2 voodoo3_mb0_lget(struct pci_board_state *pcibs, uaecptr addr)
{
return get_mem_pcem(addr, 2);
}
static uae_u32 REGPARAM2 voodoo3_mb0_wget(struct pci_board_state *pcibs, uaecptr addr)
{
return get_mem_pcem(addr, 1);
}
static uae_u32 REGPARAM2 voodoo3_mb0_bget(struct pci_board_state *pcibs, uaecptr addr)
{
return get_mem_pcem(addr, 0);
}
static void REGPARAM2 voodoo3_mb1_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
int m = gb->lfbbyteswapmode;
addr -= pcibs->bar[1];
addr &= 0x00ffffff;
switch (m)
{
case 0:
//((uae_u32*)(addr + gb->vram))[0] = b;
pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
break;
case 1:
//do_put_mem_long((uae_u32*)(addr + gb->vram), b);
b = do_byteswap_32(b);
pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
break;
case 2:
//((uae_u32*)(addr + gb->vram))[0] = b;
b = do_byteswap_32(b);
pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
break;
case 3:
b = (b >> 16) | (b << 16);
b = do_byteswap_32(b);
pcem_linear_write_l(addr, b, pcem_mapping_linear_priv);
//do_put_mem_long((uae_u32*)(addr + gb->vram), b);
break;
}
}
static uae_u32 REGPARAM2 voodoo3_mb1_lget(struct pci_board_state* pcibs, uaecptr addr)
{
struct rtggfxboard* gb = (struct rtggfxboard*)pcibs->userdata;
int m = gb->lfbbyteswapmode;
uae_u32 v = 0;
addr -= pcibs->bar[1];
addr &= 0x00ffffff;
switch (m)
{
case 0:
//v = ((uae_u32*)(addr + gb->vram))[0];
v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
break;
case 1:
//v = do_get_mem_long((uae_u32*)(addr + gb->vram));
v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
v = do_byteswap_32(v);
break;
case 2:
//v = ((uae_u32*)(addr + gb->vram))[0];
v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
v = do_byteswap_32(v);
break;
case 3:
//v = do_get_mem_long((uae_u32*)(addr + gb->vram));
v = pcem_linear_read_l(addr, pcem_mapping_linear_priv);
v = do_byteswap_32(v);
v = (v >> 16) | (v << 16);
break;
}
return v;
}
static void REGPARAM2 voodoo3_mb1_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
int m = gb->lfbbyteswapmode;
addr -= pcibs->bar[1];
addr &= 0x00ffffff;
switch (m)
{
case 0:
//*((uae_u16*)(addr + gb->vram)) = b;
pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
break;
case 1:
addr ^= 2;
b = do_byteswap_16(b);
//do_put_mem_word((uae_u16*)(addr + gb->vram), b);
pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
break;
case 2:
//do_put_mem_word((uae_u16*)(addr + gb->vram), b);
b = do_byteswap_16(b);
pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
break;
case 3:
//do_put_mem_word((uae_u16*)(addr + gb->vram), b);
b = do_byteswap_16(b);
pcem_linear_write_w(addr, b, pcem_mapping_linear_priv);
break;
}
}
static uae_u32 REGPARAM2 voodoo3_mb1_wget(struct pci_board_state* pcibs, uaecptr addr)
{
struct rtggfxboard* gb = (struct rtggfxboard*)pcibs->userdata;
int m = gb->lfbbyteswapmode;
uae_u32 v = 0;
addr -= pcibs->bar[1];
addr &= 0x00ffffff;
switch (m)
{
case 0:
//v = *((uae_u16*)(addr + gb->vram));
v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
break;
case 1:
addr ^= 2;
//v = *((uae_u16*)(addr + gb->vram));
v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
v = do_byteswap_16(v);
break;
case 2:
//v = do_get_mem_word((uae_u16*)(addr + gb->vram));
v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
v = do_byteswap_16(v);
break;
case 3:
//v = do_get_mem_word((uae_u16*)(addr + gb->vram));
v = pcem_linear_read_w(addr, pcem_mapping_linear_priv);
v = do_byteswap_16(v);
break;
}
return v;
}
static void REGPARAM2 voodoo3_mb1_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
{
struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
int m = gb->lfbbyteswapmode;
addr -= pcibs->bar[1];
addr &= 0x00ffffff;
pcem_linear_write_b(addr, b, pcem_mapping_linear_priv);
//do_put_mem_byte((uae_u8*)(addr + gb->vram), b);
}
static uae_u32 REGPARAM2 voodoo3_mb1_bget(struct pci_board_state *pcibs, uaecptr addr)
{
struct rtggfxboard *gb = (struct rtggfxboard*)pcibs->userdata;
int m = gb->lfbbyteswapmode;
addr -= pcibs->bar[1];
addr &= 0x00ffffff;
uae_u32 v = pcem_linear_read_b(addr, pcem_mapping_linear_priv);
//uae_u32 v = do_get_mem_byte((uae_u8*)(addr + gb->vram));
return v;
}
static uae_u32 REGPARAM2 voodoo3_bios_bget(struct pci_board_state *pcibs, uaecptr addr)
{
struct rtggfxboard* gb = getgfxboard(addr);
addr &= gb->bios_mask;
return gb->bios[addr];
}
static uae_u32 REGPARAM2 voodoo3_bios_wget(struct pci_board_state *pcibs, uaecptr addr)
{
return (voodoo3_bios_bget(pcibs, addr) << 0) | (voodoo3_bios_bget(pcibs, addr + 1) << 8);
}
static uae_u32 REGPARAM2 voodoo3_bios_lget(struct pci_board_state *pcibs, uaecptr addr)
{
return (voodoo3_bios_wget(pcibs, addr + 0) << 24) | (voodoo3_bios_wget(pcibs, addr + 1) << 16) | (voodoo3_bios_wget(pcibs, addr + 2) << 8) | (voodoo3_bios_wget(pcibs, addr + 3) << 0);
}
uae_u8 get_pci_pcem(uaecptr addr);
void put_pci_pcem(uaecptr addr, uae_u8 v);
static const struct pci_config voodoo3_pci_config =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 1, 0, 0, 0, 0 }
};
static const struct pci_board voodoo3_pci_board =
{
_T("VOODOO3"),
&voodoo3_pci_config, NULL, NULL, NULL, NULL,
{
{ voodoo3_mb0_lget, voodoo3_mb0_wget, voodoo3_mb0_bget, voodoo3_mb0_lput, voodoo3_mb0_wput, voodoo3_mb0_bput },
{ voodoo3_mb1_lget, voodoo3_mb1_wget, voodoo3_mb1_bget, voodoo3_mb1_lput, voodoo3_mb1_wput, voodoo3_mb1_bput },
{ voodoo3_io_lget, voodoo3_io_wget, voodoo3_io_bget, voodoo3_io_lput, voodoo3_io_wput, voodoo3_io_bput },
{ NULL },
{ NULL },
{ NULL },
{ voodoo3_bios_lget, voodoo3_bios_wget, voodoo3_bios_bget, NULL, NULL, NULL },
},
true,
get_pci_pcem, put_pci_pcem, pci_change_config
};
int gfxboard_get_index_from_id(int id)
{
if (id == GFXBOARD_UAE_Z2)
@ -3661,11 +4057,17 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->monswitch_keep_trying = true;
}
}
if (gb->board->pci) {
aci->zorro = -1;
}
aci->parent = aci;
if (!aci->doinit) {
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
static const int parent[] = { ROMTYPE_A1060, ROMTYPE_A2088, ROMTYPE_A2088T, ROMTYPE_A2286, ROMTYPE_A2386, 0 };
aci->parent_romtype = parent;
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3) {
static const int parent[] = { ROMTYPE_GREX, ROMTYPE_MEDIATOR, ROMTYPE_PROMETHEUS, 0 };
aci->parent_romtype = parent;
} else {
memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
}
@ -3714,6 +4116,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
memcpy(&gb->gfxboard_bank_mmio_wbs_pcem, &tmpl_gfxboard_bank_mmio_wbs_pcem, sizeof addrbank);
memcpy(&gb->gfxboard_bank_mmio_lbs_pcem, &tmpl_gfxboard_bank_mmio_lbs_pcem, sizeof addrbank);
memcpy(&gb->gfxboard_bank_special_pcem, &tmpl_gfxboard_bank_special_pcem, sizeof addrbank);
memcpy(&gb->gfxboard_bank_bios, &tmpl_gfxboard_bank_bios, sizeof addrbank);
gb->gfxboard_bank_memory.name = gb->memorybankname;
gb->gfxboard_bank_memory_nojit.name = gb->memorybanknamenojit;
@ -3727,6 +4130,36 @@ bool gfxboard_init_memory (struct autoconfig_info *aci)
gb->active = true;
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3) {
TCHAR path[MAX_DPATH];
fetch_rompath(path, sizeof path / sizeof(TCHAR));
_tcscat(path, _T("voodoo3.rom"));
struct zfile *zf = read_rom_name(path);
if (zf) {
gb->bios = xcalloc(uae_u8, 65536);
gb->bios_mask = 65535;
int size = zfile_fread(gb->bios, 1, 65536, zf);
zfile_fclose(zf);
write_log(_T("Voodoo 3 BIOS load, %d bytes\n"), size);
} else {
error_log(_T("Voodoo 3 BIOS ROM (<rom path>\\voodoo3.rom) failed to load!\n"));
}
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
init_board(gb);
copyvrambank(&gb->gfxboard_bank_memory, gb->gfxmem_bank, false);
gb->configured_mem = 1;
gb->configured_regs = 1;
struct pci_bridge *b = pci_bridge_get();
if (b) {
gb->pcibs = pci_board_add(b, &voodoo3_pci_board, -1, 0, aci, gb);
}
gb->gfxboard_intena = 1;
return true;
}
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
init_board(gb);
gb->configured_mem = 1;
@ -3809,22 +4242,23 @@ bool gfxboard_init_registers (struct autoconfig_info *aci)
return true;
}
static uae_u32 REGPARAM2 gfxboard_bget_bios(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);
addr &= gb->bios_mask;
return gb->bios[addr];
}
static uae_u32 REGPARAM2 gfxboard_wget_bios(uaecptr addr)
{
return (gfxboard_bget_bios(addr) << 8) | (gfxboard_bget_bios(addr + 1) << 0);
}
static uae_u32 REGPARAM2 gfxboard_lget_bios(uaecptr addr)
{
return (gfxboard_bget_bios(addr + 0) << 24) | (gfxboard_bget_bios(addr + 1) << 16) | (gfxboard_bget_bios(addr + 2) << 8) | (gfxboard_bget_bios(addr + 3) << 0);
}
// PCem wrapper
extern uint8_t(*pcem_linear_read_b)(uint32_t addr, void *priv);
extern uint16_t(*pcem_linear_read_w)(uint32_t addr, void *priv);
extern uint32_t(*pcem_linear_read_l)(uint32_t addr, void *priv);
extern void (*pcem_linear_write_b)(uint32_t addr, uint8_t val, void *priv);
extern void (*pcem_linear_write_w)(uint32_t addr, uint16_t val, void *priv);
extern void (*pcem_linear_write_l)(uint32_t addr, uint32_t val, void *priv);
extern void *pcem_mapping_linear_priv;
extern uae_u32 pcem_mapping_linear_offset;
extern void put_mem_pcem(uaecptr, uae_u32, int);
extern uae_u32 get_mem_pcem(uaecptr, int);
static uae_u32 REGPARAM2 gfxboard_bget_vram_normal_pcem(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);
@ -3884,26 +4318,24 @@ static uae_u32 REGPARAM2 gfxboard_bget_vram_longswap_pcem(uaecptr addr)
struct rtggfxboard *gb = getgfxboard(addr);
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addr += gb->pcem_vram_offset;
uae_u8 v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
uae_u8 v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
return v;
}
static uae_u32 REGPARAM2 gfxboard_wget_vram_longswap_pcem(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);
uae_u16 v;
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addr += gb->pcem_vram_offset;
v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
uae_u16 v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
v = do_byteswap_16(v);
return v;
}
static uae_u32 REGPARAM2 gfxboard_lget_vram_longswap_pcem(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);
uae_u32 v;
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addr += gb->pcem_vram_offset;
v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
uae_u32 v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
v = do_byteswap_32(v);
return v;
}
@ -3941,25 +4373,23 @@ static uae_u32 REGPARAM2 gfxboard_bget_vram_wordswap_pcem(uaecptr addr)
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addr += gb->pcem_vram_offset;
addr ^= 1;
uae_u8 v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
uae_u8 v = pcem_linear_read_b(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
return v;
}
static uae_u32 REGPARAM2 gfxboard_wget_vram_wordswap_pcem(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);
uae_u16 v;
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addr += gb->pcem_vram_offset;
v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
uae_u16 v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
return v;
}
static uae_u32 REGPARAM2 gfxboard_lget_vram_wordswap_pcem(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);
uae_u32 v;
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
addr += gb->pcem_vram_offset;
v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
uae_u32 v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
v = (v >> 16) | (v << 16);
return v;
}
@ -4256,9 +4686,6 @@ static void REGPARAM2 gfxboard_lput_vram_p4z2_pcem(uaecptr addr, uae_u32 l)
extern void put_io_pcem(uaecptr, uae_u32, int);
extern uae_u32 get_io_pcem(uaecptr, int);
static uae_u32 REGPARAM2 gfxboard_lget_io_pcem(uaecptr addr)
{
struct rtggfxboard *gb = getgfxboard(addr);

View File

@ -76,6 +76,7 @@ int pcem_getvramsize(void);
#define GFXBOARD_ID_CV643D_Z2 15
#define GFXBOARD_ID_CV643D_Z3 16
#define GFXBOARD_ID_CV64_Z3 17
#define GFXBOARD_ID_VOODOO3 18
struct gfxboard_mode

View File

@ -10,5 +10,8 @@ extern bool grex_init(struct autoconfig_info *aci);
extern bool mediator_init(struct autoconfig_info *aci);
extern bool mediator_init2(struct autoconfig_info *aci);
extern bool pci_expansion_init(struct autoconfig_info *aci);
extern struct pci_bridge *pci_bridge_get(void);
extern struct pci_board_state *pci_board_add(struct pci_bridge *pcib, const struct pci_board *pci, int slot, int func, struct autoconfig_info *aci, void *userdata);
extern bool pci_validate_address(uaecptr, uae_u32, bool);
#endif /* UAE_PCI_H */

View File

@ -13,6 +13,9 @@ typedef bool(*pci_dev_init)(struct pci_board_state*,struct autoconfig_info*);
typedef void(*pci_dev_reset)(struct pci_board_state*);
typedef void(*pci_dev_hsync)(struct pci_board_state*);
typedef void(*pci_dev_free)(struct pci_board_state*);
typedef uae_u8(*pci_get_config_func)(uaecptr);
typedef void(*pci_put_config_func)(uaecptr, uae_u8);
typedef void(*pci_change_config_func)(struct pci_board_state*);
typedef struct
{
@ -48,6 +51,11 @@ struct pci_board
pci_dev_reset reset;
pci_dev_hsync hsync;
pci_addrbank bars[MAX_PCI_BARS];
bool dont_mask_io;
pci_get_config_func pci_get_config;
pci_put_config_func pci_put_config;
pci_change_config_func pci_change_config;
};
struct pci_board_state
@ -67,6 +75,8 @@ struct pci_board_state
bool io_map_active;
struct pci_bridge *bridge;
pci_dev_irq irq_callback;
struct pci_config dynamic_config;
void *userdata;
};
struct pci_bridge
@ -75,8 +85,9 @@ struct pci_bridge
int type;
int endian_swap_config;
uae_u32 io_offset;
uae_u32 memory_start_offset;
int endian_swap_io;
uae_u32 memory_offset;
uae_u32 memory_window_offset;
int endian_swap_memory;
bool pcipcidma;
bool amigapicdma;

View File

@ -197,6 +197,7 @@ extern int decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size);
#define ROMTYPE_ALF2 0x00100085
#define ROMTYPE_SYNTHESIS 0x00100086
#define ROMTYPE_MASTFB 0x00100087
#define ROMTYPE_VOODOO3 0x00100088
#define ROMTYPE_NOT 0x00800000
#define ROMTYPE_QUAD 0x01000000

View File

@ -2295,16 +2295,22 @@ void picasso_allocatewritewatch (int index, int gfxmemsize)
static ULONG_PTR writewatchcount[MAX_RTG_BOARDS];
static int watch_offset[MAX_RTG_BOARDS];
void picasso_getwritewatch (int index, int offset)
int picasso_getwritewatch (int index, int offset, uae_u8 ***gwwbufp, uae_u8 **startp)
{
ULONG ps;
writewatchcount[index] = gwwbufsize[index];
watch_offset[index] = offset;
uae_u8 *start = gfxmem_banks[index]->start + natmem_offset + offset;
if (GetWriteWatch (WRITE_WATCH_FLAG_RESET, gfxmem_banks[index]->start + natmem_offset + offset, (gwwbufsize[index] - 1) * gwwpagesize[index], gwwbuf[index], &writewatchcount[index], &ps)) {
write_log (_T("picasso_getwritewatch %d\n"), GetLastError ());
writewatchcount[index] = 0;
return;
return -1;
}
if (gwwbufp)
*gwwbufp = (uae_u8**)gwwbuf[index];
if (startp)
*startp = start;
return writewatchcount[index];
}
bool picasso_is_vram_dirty (int index, uaecptr addr, int size)
{

View File

@ -640,7 +640,7 @@ extern bool picasso_is_active(int monid);
extern int picasso_setwincursor(int monid);
extern int picasso_palette(struct MyCLUTEntry *MCLUT, uae_u32 *clut);
extern void picasso_allocatewritewatch (int index, int gfxmemsize);
extern void picasso_getwritewatch (int index, int offset);
extern int picasso_getwritewatch(int index, int offset, uae_u8 ***gwwbufp, uae_u8 **startp);
extern bool picasso_is_vram_dirty (int index, uaecptr addr, int size);
extern void picasso_statusline (int monid, uae_u8 *dst);
extern void picasso_invalidate(int monid, int x, int y, int w, int h);

View File

@ -483,7 +483,7 @@
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;..\..\ppc\pearpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -637,7 +637,7 @@
<OmitFramePointers>false</OmitFramePointers>
<WholeProgramOptimization>false</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -795,7 +795,7 @@
<OmitFramePointers>true</OmitFramePointers>
<WholeProgramOptimization>true</WholeProgramOptimization>
<AdditionalIncludeDirectories>..\..\include;..\..;..\;..\resources;..\osdep;..\sounddep;..\..\slirp;..\..\ppc\pearpc;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>WINVER=0x0601;NDEBUG;_WIN32_IE=0x0700;WIN32;WIN64;PTR64;UAE;WINUAE;_HAS_STD_BYTE=0;SAHF_SETO_PROFITABLE;__amd64__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<ExceptionHandling>Sync</ExceptionHandling>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -976,6 +976,17 @@
<ClCompile Include="..\..\pcem\vid_sdac_ramdac.cpp" />
<ClCompile Include="..\..\pcem\vid_svga.cpp" />
<ClCompile Include="..\..\pcem\vid_svga_render.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_banshee.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_banshee_blitter.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_blitter.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_display.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_fb.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_fifo.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_reg.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_render.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_setup.cpp" />
<ClCompile Include="..\..\pcem\vid_voodoo_texture.cpp" />
<ClCompile Include="..\..\pcem\x86seg.cpp" />
<ClCompile Include="..\..\pcem\x87.cpp" />
<ClCompile Include="..\..\pcem\x87_timings.cpp" />

View File

@ -970,6 +970,39 @@
<ClCompile Include="..\FX11\EffectRuntime.cpp">
<Filter>win32\FX11</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_banshee.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_banshee_blitter.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_display.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_fifo.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_render.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_fb.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_reg.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_setup.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_blitter.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo_texture.cpp">
<Filter>pcem</Filter>
</ClCompile>
<ClCompile Include="..\..\pcem\vid_voodoo.cpp">
<Filter>pcem</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="..\resources\35floppy.ico">

View File

@ -461,6 +461,70 @@ uint64_t timer_read(void)
return read_processor_time();
}
static pc_timer_t *timer_head = NULL;
void timer_enablex(pc_timer_t *timer)
{
pc_timer_t *timer_node = timer_head;
if (timer->enabled)
timer_disablex(timer);
timer->enabled = 1;
if (!timer_head)
{
timer_head = timer;
timer->next = timer->prev = NULL;
return;
}
timer_node = timer_head;
}
void timer_disablex(pc_timer_t *timer)
{
if (!timer->enabled)
return;
timer->enabled = 0;
if (timer->prev)
timer->prev->next = timer->next;
else
timer_head = timer->next;
if (timer->next)
timer->next->prev = timer->prev;
timer->prev = timer->next = NULL;
}
void timer_addx(pc_timer_t *timer, void (*callback)(void* p), void *p, int start_timer)
{
memset(timer, 0, sizeof(pc_timer_t));
timer->callback = callback;
timer->p = p;
timer->enabled = 0;
timer->prev = timer->next = NULL;
}
void timer_set_delay_u64x(pc_timer_t *timer, uint64_t delay)
{
timer_enablex(timer);
}
static void timer_remove_headx(void)
{
if (timer_head)
{
pc_timer_t *timer = timer_head;
timer_head = timer->next;
if (timer_head) {
timer_head->prev = NULL;
}
timer->next = timer->prev = NULL;
timer->enabled = 0;
}
}
void pcemglue_hsync(void)
{
while (timer_head) {
timer_head->callback(timer_head->p);
timer_remove_headx();
}
}
void initpcemvideo(void *p, bool swapped)
{
int c, d, e;
@ -536,6 +600,7 @@ void initpcemvideo(void *p, bool swapped)
pcem_linear_write_l = dummy_lwrite;
pcem_mapping_linear = NULL;
pcem_mapping_linear_offset = 0;
timer_head = NULL;
}
@ -680,6 +745,37 @@ void thread_destroy_event(event_t *_event)
uae_sem_destroy((uae_sem_t*)&_event);
}
typedef struct win_mutex_t
{
HANDLE handle;
} win_mutex_t;
mutex_t* thread_create_mutex(void)
{
win_mutex_t* mutex = xcalloc(win_mutex_t,1);
mutex->handle = CreateSemaphore(NULL, 1, 1, NULL);
return mutex;
}
void thread_lock_mutex(mutex_t* _mutex)
{
win_mutex_t* mutex = (win_mutex_t*)_mutex;
WaitForSingleObject(mutex->handle, INFINITE);
}
void thread_unlock_mutex(mutex_t* _mutex)
{
win_mutex_t* mutex = (win_mutex_t*)_mutex;
ReleaseSemaphore(mutex->handle, 1, NULL);
}
void thread_destroy_mutex(mutex_t* _mutex)
{
win_mutex_t* mutex = (win_mutex_t*)_mutex;
CloseHandle(mutex->handle);
xfree(mutex);
}
static mem_mapping_t *getmm(uaecptr *addrp)
{
uaecptr addr = *addrp;
@ -974,3 +1070,10 @@ void mem_mapping_enablex(mem_mapping_t *mapping)
mapping_recalc(mapping);
}
void pcem_linear_mark(int offset)
{
if (!pcem_mapping_linear)
return;
uae_u16 w = pcem_linear_read_w(offset, pcem_mapping_linear_priv);
pcem_linear_write_w(offset, w, pcem_mapping_linear_priv);
}

View File

@ -1,12 +1,22 @@
extern void pcem_close(void);
extern void pcemglue_hsync(void);
uint8_t keyboard_at_read(uint16_t port, void *priv);
uint8_t mem_read_romext(uint32_t addr, void *priv);
uint16_t mem_read_romextw(uint32_t addr, void *priv);
uint32_t mem_read_romextl(uint32_t addr, void *priv);
void pcem_linear_mark(int offset);
extern int SOUNDBUFLEN;
extern int32_t *x86_sndbuffer[2];
extern bool x86_sndbuffer_filled[2];
extern void *pcem_mapping_linear_priv;
extern uae_u32 pcem_mapping_linear_offset;
extern uint8_t(*pcem_linear_read_b)(uint32_t addr, void* priv);
extern uint16_t(*pcem_linear_read_w)(uint32_t addr, void* priv);
extern uint32_t(*pcem_linear_read_l)(uint32_t addr, void* priv);
extern void (*pcem_linear_write_b)(uint32_t addr, uint8_t val, void* priv);
extern void (*pcem_linear_write_w)(uint32_t addr, uint16_t val, void* priv);
extern void (*pcem_linear_write_l)(uint32_t addr, uint32_t val, void* priv);

View File

@ -139,4 +139,12 @@ static inline void timer_set_p(pc_timer_t *timer, void *p)
timer->p = p;
}
#ifdef UAE
void timer_addx(pc_timer_t* timer, void (*callback)(void* p), void* p, int start_timer);
void timer_enablex(pc_timer_t *timer);
void timer_disablex(pc_timer_t *timer);
void timer_set_delay_u64x(pc_timer_t *timer, uint64_t delay);
#endif
#endif /*_TIMER_H_*/

4
pcem/vid_ddc.h Normal file
View File

@ -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);

View File

@ -50,7 +50,7 @@ typedef struct svga_t
int set_reset_disabled;
uint8_t egapal[16];
uint32_t pallook[256];
uint32_t pallook[512];
PALETTE vgapal;
int ramdac_type;
@ -60,7 +60,7 @@ typedef struct svga_t
int lowres, interlace;
int linedbl, rowcount;
double clock;
uint32_t ma_latch;
uint32_t ma_latch, ca_adj;
int bpp;
uint64_t dispontime, dispofftime;
@ -93,6 +93,8 @@ typedef struct svga_t
int fullchange;
int video_res_x, video_res_y, video_bpp;
int video_res_override; /*If clear then SVGA code will set above variables, if
set then card code will*/
int frames, fps;
struct

View File

@ -4,6 +4,13 @@
#include "vid_svga.h"
#include "vid_svga_render.h"
void svga_render_null(svga_t* svga)
{
if (svga->firstline_draw == 4000)
svga->firstline_draw = svga->displine;
svga->lastline_draw = svga->displine;
}
void svga_render_blank(svga_t *svga)
{
int x, xx;

View File

@ -9,6 +9,7 @@ extern int scrollcache;
extern uint8_t edatlookup[4][4];
void svga_render_null(svga_t* svga);
void svga_render_blank(svga_t *svga);
void svga_render_text_40(svga_t *svga);
void svga_render_text_80(svga_t *svga);

View File

@ -685,39 +685,39 @@ static void voodoo_recalcmapping(voodoo_set_t *set)
if (set->voodoos[0]->type == VOODOO_2 && set->voodoos[1]->initEnable & (1 << 23))
{
pclog("voodoo_recalcmapping (pri) with snoop : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
mem_mapping_disable(&set->voodoos[0]->mapping);
mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
mem_mapping_disablex(&set->voodoos[0]->mapping);
mem_mapping_set_addrx(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
}
else if (set->voodoos[1]->pci_enable && (set->voodoos[0]->memBaseAddr == set->voodoos[1]->memBaseAddr))
{
pclog("voodoo_recalcmapping (pri) (sec) same addr : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
mem_mapping_disable(&set->voodoos[0]->mapping);
mem_mapping_disable(&set->voodoos[1]->mapping);
mem_mapping_set_addr(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
mem_mapping_disablex(&set->voodoos[0]->mapping);
mem_mapping_disablex(&set->voodoos[1]->mapping);
mem_mapping_set_addrx(&set->snoop_mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
return;
}
else
{
pclog("voodoo_recalcmapping (pri) : memBaseAddr %08X\n", set->voodoos[0]->memBaseAddr);
mem_mapping_disable(&set->snoop_mapping);
mem_mapping_set_addr(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
mem_mapping_disablex(&set->snoop_mapping);
mem_mapping_set_addrx(&set->voodoos[0]->mapping, set->voodoos[0]->memBaseAddr, 0x01000000);
}
}
else
{
pclog("voodoo_recalcmapping (pri) : disabled\n");
mem_mapping_disable(&set->voodoos[0]->mapping);
mem_mapping_disablex(&set->voodoos[0]->mapping);
}
if (set->voodoos[1]->pci_enable && set->voodoos[1]->memBaseAddr)
{
pclog("voodoo_recalcmapping (sec) : memBaseAddr %08X\n", set->voodoos[1]->memBaseAddr);
mem_mapping_set_addr(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000);
mem_mapping_set_addrx(&set->voodoos[1]->mapping, set->voodoos[1]->memBaseAddr, 0x01000000);
}
else
{
pclog("voodoo_recalcmapping (sec) : disabled\n");
mem_mapping_disable(&set->voodoos[1]->mapping);
mem_mapping_disablex(&set->voodoos[1]->mapping);
}
}
else
@ -727,12 +727,12 @@ static void voodoo_recalcmapping(voodoo_set_t *set)
if (voodoo->pci_enable && voodoo->memBaseAddr)
{
pclog("voodoo_recalcmapping : memBaseAddr %08X\n", voodoo->memBaseAddr);
mem_mapping_set_addr(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000);
mem_mapping_set_addrx(&voodoo->mapping, voodoo->memBaseAddr, 0x01000000);
}
else
{
pclog("voodoo_recalcmapping : disabled\n");
mem_mapping_disable(&voodoo->mapping);
mem_mapping_disablex(&voodoo->mapping);
}
}
}
@ -948,7 +948,7 @@ static void voodoo_speed_changed(void *p)
void *voodoo_card_init()
{
int c;
voodoo_t *voodoo = malloc(sizeof(voodoo_t));
voodoo_t *voodoo = (voodoo_t*)malloc(sizeof(voodoo_t));
memset(voodoo, 0, sizeof(voodoo_t));
voodoo->bilinear_enabled = device_get_config_int("bilinear");
@ -983,30 +983,31 @@ void *voodoo_card_init()
pci_add(voodoo_pci_read, voodoo_pci_write, voodoo);
mem_mapping_add(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);
mem_mapping_addx(&voodoo->mapping, 0, 0, NULL, voodoo_readw, voodoo_readl, NULL, voodoo_writew, voodoo_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo);
voodoo->fb_mem = malloc(4 * 1024 * 1024);
voodoo->tex_mem[0] = malloc(voodoo->texture_size * 1024 * 1024);
voodoo->fb_mem = (uint8_t*)malloc(4 * 1024 * 1024);
voodoo->tex_mem[0] = (uint8_t*)malloc(voodoo->texture_size * 1024 * 1024);
if (voodoo->dual_tmus)
voodoo->tex_mem[1] = malloc(voodoo->texture_size * 1024 * 1024);
voodoo->tex_mem[1] = (uint8_t*)malloc(voodoo->texture_size * 1024 * 1024);
voodoo->tex_mem_w[0] = (uint16_t *)voodoo->tex_mem[0];
voodoo->tex_mem_w[1] = (uint16_t *)voodoo->tex_mem[1];
for (c = 0; c < TEX_CACHE_MAX; c++)
{
voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[0][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[0][c].base = -1; /*invalid*/
voodoo->texture_cache[0][c].refcount = 0;
if (voodoo->dual_tmus)
{
voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[1][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[1][c].base = -1; /*invalid*/
voodoo->texture_cache[1][c].refcount = 0;
}
}
#if 0
timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
#endif
voodoo->svga = svga_get_pri();
voodoo->fbiInit0 = 0;
@ -1031,8 +1032,9 @@ void *voodoo_card_init()
voodoo->render_thread[3] = thread_create(voodoo_render_thread_4, voodoo);
}
voodoo->swap_mutex = thread_create_mutex();
#if 0
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
#endif
for (c = 0; c < 0x100; c++)
{
rgb332[c].r = c & 0xe0;
@ -1094,7 +1096,7 @@ void *voodoo_card_init()
void *voodoo_2d3d_card_init(int type)
{
int c;
voodoo_t *voodoo = malloc(sizeof(voodoo_t));
voodoo_t *voodoo = (voodoo_t*)malloc(sizeof(voodoo_t));
memset(voodoo, 0, sizeof(voodoo_t));
voodoo->bilinear_enabled = device_get_config_int("bilinear");
@ -1112,18 +1114,18 @@ void *voodoo_2d3d_card_init(int type)
for (c = 0; c < TEX_CACHE_MAX; c++)
{
voodoo->texture_cache[0][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[0][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[0][c].base = -1; /*invalid*/
voodoo->texture_cache[0][c].refcount = 0;
if (voodoo->dual_tmus)
{
voodoo->texture_cache[1][c].data = malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[1][c].data = (uint32_t*)malloc((256*256 + 256*256 + 128*128 + 64*64 + 32*32 + 16*16 + 8*8 + 4*4 + 2*2) * 4);
voodoo->texture_cache[1][c].base = -1; /*invalid*/
voodoo->texture_cache[1][c].refcount = 0;
}
}
timer_add(&voodoo->timer, voodoo_callback, voodoo, 1);
// timer_addx(&voodoo->timer, voodoo_callback, voodoo, 1);
voodoo->fbiInit0 = 0;
@ -1149,7 +1151,6 @@ void *voodoo_2d3d_card_init(int type)
}
voodoo->swap_mutex = thread_create_mutex();
timer_add(&voodoo->wake_timer, voodoo_wake_timer, (void *)voodoo, 0);
for (c = 0; c < 0x100; c++)
{
rgb332[c].r = c & 0xe0;
@ -1210,7 +1211,7 @@ void *voodoo_2d3d_card_init(int type)
void *voodoo_init()
{
voodoo_set_t *voodoo_set = malloc(sizeof(voodoo_set_t));
voodoo_set_t *voodoo_set = (voodoo_set_t*)malloc(sizeof(voodoo_set_t));
uint32_t tmuConfig = 1;
int type;
memset(voodoo_set, 0, sizeof(voodoo_set_t));
@ -1218,11 +1219,11 @@ void *voodoo_init()
type = device_get_config_int("type");
voodoo_set->nr_cards = device_get_config_int("sli") ? 2 : 1;
voodoo_set->voodoos[0] = voodoo_card_init();
voodoo_set->voodoos[0] = (voodoo_t*)voodoo_card_init();
voodoo_set->voodoos[0]->set = voodoo_set;
if (voodoo_set->nr_cards == 2)
{
voodoo_set->voodoos[1] = voodoo_card_init();
voodoo_set->voodoos[1] = (voodoo_t*)voodoo_card_init();
voodoo_set->voodoos[1]->set = voodoo_set;
@ -1261,7 +1262,7 @@ void *voodoo_init()
if (voodoo_set->nr_cards == 2)
voodoo_set->voodoos[1]->tmuConfig = tmuConfig;
mem_mapping_add(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set);
mem_mapping_addx(&voodoo_set->snoop_mapping, 0, 0, NULL, voodoo_snoop_readw, voodoo_snoop_readl, NULL, voodoo_snoop_writew, voodoo_snoop_writel, NULL, MEM_MAPPING_EXTERNAL, voodoo_set);
return voodoo_set;
}
@ -1273,6 +1274,7 @@ void voodoo_card_close(voodoo_t *voodoo)
#endif
int c;
#if 0
#ifndef RELEASE_BUILD
if (voodoo->tex_mem[0])
{
@ -1286,6 +1288,7 @@ void voodoo_card_close(voodoo_t *voodoo)
fclose(f);
}
}
#endif
#endif
thread_kill(voodoo->fifo_thread);
@ -1341,6 +1344,7 @@ static device_config_t voodoo_config[] =
.name = "type",
.description = "Voodoo type",
.type = CONFIG_SELECTION,
.default_int = 0,
.selection =
{
{
@ -1358,13 +1362,13 @@ static device_config_t voodoo_config[] =
{
.description = ""
}
},
.default_int = 0
}
},
{
.name = "framebuffer_memory",
.description = "Framebuffer memory size",
.type = CONFIG_SELECTION,
.default_int = 2,
.selection =
{
{
@ -1378,13 +1382,13 @@ static device_config_t voodoo_config[] =
{
.description = ""
}
},
.default_int = 2
}
},
{
.name = "texture_memory",
.description = "Texture memory size",
.type = CONFIG_SELECTION,
.default_int = 2,
.selection =
{
{
@ -1398,8 +1402,7 @@ static device_config_t voodoo_config[] =
{
.description = ""
}
},
.default_int = 2
}
},
{
.name = "bilinear",
@ -1417,6 +1420,7 @@ static device_config_t voodoo_config[] =
.name = "render_threads",
.description = "Render threads",
.type = CONFIG_SELECTION,
.default_int = 2,
.selection =
{
{
@ -1434,8 +1438,7 @@ static device_config_t voodoo_config[] =
{
.description = ""
}
},
.default_int = 2
}
},
{
.name = "sli",

View File

@ -88,6 +88,8 @@ typedef struct banshee_t
uint32_t desktop_stride_tiled;
int type;
int vblank_irq;
} banshee_t;
enum
@ -148,6 +150,7 @@ enum
#define VGAINIT0_EXTENDED_SHIFT_OUT (1 << 12)
#define VIDPROCCFG_CURSOR_MODE (1 << 1)
#define VIDPROCCFG_INTERLACE (1 << 3)
#define VIDPROCCFG_HALF_MODE (1 << 4)
#define VIDPROCCFG_OVERLAY_ENABLE (1 << 8)
#define VIDPROCCFG_OVERLAY_CLUT_BYPASS (1 << 11)
@ -204,6 +207,31 @@ enum
#define VIDSERIAL_I2C_SCK_R (1 << 26)
#define VIDSERIAL_I2C_SDA_R (1 << 27)
static int banshee_vga_vsync_enabled(banshee_t *banshee)
{
if (!(banshee->svga.crtc[0x11] & 0x20) && (banshee->svga.crtc[0x11] & 0x10) && ((banshee->pciInit0 >> 18) & 1) != 0)
return 1;
return 0;
}
static void banshee_update_irqs(banshee_t *banshee)
{
if (banshee->vblank_irq > 0 && banshee_vga_vsync_enabled(banshee)) {
pci_set_irq(NULL, PCI_INTA);
} else {
pci_clear_irq(NULL, PCI_INTA);
}
}
static void banshee_vblank_start(svga_t* svga)
{
banshee_t *banshee = (banshee_t*)svga->p;
if (banshee->vblank_irq >= 0) {
banshee->vblank_irq = 1;
banshee_update_irqs(banshee);
}
}
static uint32_t banshee_status(banshee_t *banshee);
static void banshee_out(uint16_t addr, uint8_t val, void *p)
@ -231,10 +259,21 @@ static void banshee_out(uint16_t addr, uint8_t val, void *p)
svga->crtc[svga->crtcreg] = val;
if (old != val)
{
if (svga->crtcreg < 0xe || svga->crtcreg > 0x10)
if (svga->crtcreg == 0x11) {
if (!(val & 0x10)) {
if (banshee->vblank_irq > 0)
banshee->vblank_irq = -1;
} else if (banshee->vblank_irq < 0) {
banshee->vblank_irq = 0;
}
banshee_update_irqs(banshee);
if ((val & ~0x30) == (old & ~0x30))
old = val;
}
if (svga->crtcreg < 0xe || svga->crtcreg > 0x11 || (svga->crtcreg == 0x11 && old != val))
{
svga->fullchange = changeframecount;
svga_recalctimings(svga);
svga->fullchange = changeframecount;
svga_recalctimings(svga);
}
}
break;
@ -260,6 +299,8 @@ static uint8_t banshee_in(uint16_t addr, void *p)
temp = 0;
else
temp = 0x10;
if (banshee->vblank_irq > 0)
temp |= 0x80;
break;
case 0x3D4:
temp = svga->crtcreg;
@ -282,10 +323,10 @@ static void banshee_updatemapping(banshee_t *banshee)
if (!(banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_MEM))
{
// pclog("Update mapping - PCI disabled\n");
mem_mapping_disable(&svga->mapping);
mem_mapping_disable(&banshee->linear_mapping);
mem_mapping_disable(&banshee->reg_mapping_low);
mem_mapping_disable(&banshee->reg_mapping_high);
mem_mapping_disablex(&svga->mapping);
mem_mapping_disablex(&banshee->linear_mapping);
mem_mapping_disablex(&banshee->reg_mapping_low);
mem_mapping_disablex(&banshee->reg_mapping_high);
return;
}
@ -293,28 +334,28 @@ static void banshee_updatemapping(banshee_t *banshee)
switch (svga->gdcreg[6] & 0xc) /*Banked framebuffer*/
{
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x20000);
svga->banked_mask = 0xffff;
break;
case 0x4: /*64k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x10000);
mem_mapping_set_addrx(&svga->mapping, 0xa0000, 0x10000);
svga->banked_mask = 0xffff;
break;
case 0x8: /*32k at B0000*/
mem_mapping_set_addr(&svga->mapping, 0xb0000, 0x08000);
mem_mapping_set_addrx(&svga->mapping, 0xb0000, 0x08000);
svga->banked_mask = 0x7fff;
break;
case 0xC: /*32k at B8000*/
mem_mapping_set_addr(&svga->mapping, 0xb8000, 0x08000);
mem_mapping_set_addrx(&svga->mapping, 0xb8000, 0x08000);
svga->banked_mask = 0x7fff;
break;
}
pclog("Linear framebuffer %08X ", banshee->memBaseAddr1);
mem_mapping_set_addr(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20);
mem_mapping_set_addrx(&banshee->linear_mapping, banshee->memBaseAddr1, 32 << 20);
pclog("registers %08X\n", banshee->memBaseAddr0);
mem_mapping_set_addr(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20);
mem_mapping_set_addr(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20);
mem_mapping_set_addrx(&banshee->reg_mapping_low, banshee->memBaseAddr0, 8 << 20);
mem_mapping_set_addrx(&banshee->reg_mapping_high, banshee->memBaseAddr0 + 0xc00000, 20 << 20);
}
static void banshee_render_16bpp_tiled(svga_t *svga)
@ -388,6 +429,7 @@ static void banshee_recalctimings(svga_t *svga)
if (svga->crtc[0x1b] & 0x40) svga->vsyncstart += 0x400;
// pclog("svga->hdisp=%i\n", svga->hdisp);
svga->interlace = 0;
if (banshee->vgaInit0 & VGAINIT0_EXTENDED_SHIFT_OUT)
{
switch (VIDPROCCFG_DESKTOP_PIX_FORMAT)
@ -436,6 +478,15 @@ static void banshee_recalctimings(svga_t *svga)
svga->htotal *= 2;
}
if (banshee->vidProcCfg & VIDPROCCFG_INTERLACE)
{
svga->interlace = 1;
svga->vtotal *= 2;
svga->dispend *= 2;
svga->vblankstart *= 2;
svga->vsyncstart *= 2;
}
svga->overlay.ena = banshee->vidProcCfg & VIDPROCCFG_OVERLAY_ENABLE;
svga->overlay.x = voodoo->overlay.start_x;
@ -476,6 +527,8 @@ static void banshee_recalctimings(svga_t *svga)
svga->video_res_override = 0;
}
svga->horizontal_linedbl = svga->dispend * 9 / 10 >= svga->hdisp;
if (((svga->miscout >> 2) & 3) == 3)
{
int k = banshee->pllCtrl0 & 3;
@ -547,6 +600,8 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
case Init_miscInit0:
banshee->miscInit0 = val;
extern void gfxboard_voodoo_lfb_endianswap(int);
gfxboard_voodoo_lfb_endianswap(val >> 30);
break;
case Init_miscInit1:
banshee->miscInit1 = val;
@ -599,7 +654,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
case Video_vidProcCfg:
banshee->vidProcCfg = val;
// pclog("vidProcCfg=%08x\n", val);
//pclog("vidProcCfg=%08x\n", val);
banshee->overlay_pix_fmt = (val & VIDPROCCFG_OVERLAY_PIX_FORMAT_MASK) >> VIDPROCCFG_OVERLAY_PIX_FORMAT_SHIFT;
svga->hwcursor.ena = val & VIDPROCCFG_HWCURSOR_ENA;
svga->fullchange = changeframecount;
@ -613,7 +668,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
else
banshee->voodoo->scrfilterEnabled = 0;
voodoo_threshold_check(banshee->voodoo);
pclog("Banshee Filter: %06x\n", val);
//pclog("Banshee Filter: %06x\n", val);
break;
@ -647,7 +702,7 @@ static void banshee_ext_outl(uint16_t addr, uint32_t val, void *p)
case Video_vidSerialParallelPort:
banshee->vidSerialParallelPort = val;
// pclog("vidSerialParallelPort: write %08x %08x %04x(%08x):%08x\n", val, val & (VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W), CS,cs,cpu_state.pc);
ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0);
//ddc_i2c_change((val & VIDSERIAL_DDC_DCK_W) ? 1 : 0, (val & VIDSERIAL_DDC_DDA_W) ? 1 : 0);
break;
case Video_vidScreenSize:
@ -759,11 +814,11 @@ static uint32_t banshee_status(banshee_t *banshee)
uint32_t ret;
ret = 0;
if (fifo_size < 0x20)
ret |= fifo_size;
if (fifo_entries < 0x20)
ret |= 0x1f - fifo_entries;
else
ret |= 0x1f;
if (fifo_size)
if (fifo_entries)
ret |= 0x20;
if (swap_count < 7)
ret |= (swap_count << 28);
@ -880,9 +935,9 @@ static uint32_t banshee_ext_inl(uint16_t addr, void *p)
case Video_vidSerialParallelPort:
ret = banshee->vidSerialParallelPort & ~(VIDSERIAL_DDC_DCK_R | VIDSERIAL_DDC_DDA_R);
if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && ddc_read_clock())
if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DCK_W) && 0) //ddc_read_clock())
ret |= VIDSERIAL_DDC_DCK_R;
if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && ddc_read_data())
if ((banshee->vidSerialParallelPort & VIDSERIAL_DDC_DDA_W) && 0) //ddc_read_data())
ret |= VIDSERIAL_DDC_DDA_R;
ret = ret & ~(VIDSERIAL_I2C_SCK_R | VIDSERIAL_I2C_SDA_R);
if (banshee->vidSerialParallelPort & VIDSERIAL_I2C_SCK_W)
@ -1001,6 +1056,14 @@ static uint32_t banshee_reg_readl(uint32_t addr, void *p)
voodoo_flush(voodoo);
switch (addr & 0x1fc)
{
case SST_status:
ret = banshee_status(banshee);
break;
case SST_intrCtrl:
ret = banshee->intrCtrl & 0x0030003f;
break;
case 0x08:
ret = voodoo->banshee_blt.clip0Min;
break;
@ -1232,7 +1295,11 @@ static void banshee_reg_writel(uint32_t addr, uint32_t val, void *p)
break;
case 0x0100000: /*2D registers*/
voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val);
if ((addr & 0x3fc) == SST_intrCtrl) {
banshee->intrCtrl = val & 0x0030003f;
} else {
voodoo_queue_command(voodoo, (addr & 0x1fc) | FIFO_WRITEL_2DREG, val);
}
break;
case 0x0200000: case 0x0300000: case 0x0400000: case 0x0500000: /*3D registers*/
@ -1314,9 +1381,10 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
voodoo_t *voodoo = banshee->voodoo;
svga_t *svga = &banshee->svga;
#if 0
cycles -= voodoo->read_time;
cycles_lost += voodoo->read_time;
#endif
addr &= svga->decode_mask;
if (addr >= voodoo->tile_base)
{
@ -1332,10 +1400,12 @@ static uint8_t banshee_read_linear(uint32_t addr, void *p)
if (addr >= svga->vram_max)
return 0xff;
#if 0
egareads++;
cycles -= video_timing_read_b;
cycles_lost += video_timing_read_b;
#endif
// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
return svga->vram[addr & svga->vram_mask];
@ -1350,8 +1420,10 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
if (addr & 1)
return banshee_read_linear(addr, p) | (banshee_read_linear(addr+1, p) << 8);
#if 0
cycles -= voodoo->read_time;
cycles_lost += voodoo->read_time;
#endif
addr &= svga->decode_mask;
if (addr >= voodoo->tile_base)
@ -1368,9 +1440,11 @@ static uint16_t banshee_read_linear_w(uint32_t addr, void *p)
if (addr >= svga->vram_max)
return 0xff;
#if 0
egareads++;
cycles -= video_timing_read_w;
cycles_lost += video_timing_read_w;
#endif
// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
@ -1386,8 +1460,10 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
if (addr & 3)
return banshee_read_linear_w(addr, p) | (banshee_read_linear_w(addr+2, p) << 16);
#if 0
cycles -= voodoo->read_time;
cycles_lost += voodoo->read_time;
#endif
addr &= svga->decode_mask;
if (addr >= voodoo->tile_base)
@ -1404,9 +1480,11 @@ static uint32_t banshee_read_linear_l(uint32_t addr, void *p)
if (addr >= svga->vram_max)
return 0xff;
#if 0
egareads++;
cycles -= video_timing_read_l;
cycles_lost += video_timing_read_l;
#endif
// pclog("read_linear: addr=%08x val=%02x\n", addr, svga->vram[addr & svga->vram_mask]);
@ -1460,8 +1538,10 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
return;
}
#if 0
cycles -= voodoo->write_time;
cycles_lost += voodoo->write_time;
#endif
// pclog("write_linear: addr=%08x val=%02x\n", addr, val);
addr &= svga->decode_mask;
@ -1479,10 +1559,12 @@ static void banshee_write_linear_w(uint32_t addr, uint16_t val, void *p)
if (addr >= svga->vram_max)
return;
#if 0
egawrites++;
cycles -= video_timing_write_w;
cycles_lost += video_timing_write_w;
#endif
svga->changedvram[addr >> 12] = changeframecount;
*(uint16_t *)&svga->vram[addr & svga->vram_mask] = val;
@ -1502,12 +1584,14 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
return;
}
#if 0
if (addr == voodoo->last_write_addr+4)
timing = voodoo->burst_time;
else
timing = voodoo->write_time;
cycles -= timing;
cycles_lost += timing;
#endif
voodoo->last_write_addr = addr;
// /*if (val) */pclog("write_linear_l: addr=%08x val=%08x %08x\n", addr, val, voodoo->tile_base);
@ -1527,10 +1611,12 @@ static void banshee_write_linear_l(uint32_t addr, uint32_t val, void *p)
if (addr >= svga->vram_max)
return;
#if 0
egawrites += 4;
cycles -= video_timing_write_l;
cycles_lost += video_timing_write_l;
#endif
svga->changedvram[addr >> 12] = changeframecount;
*(uint32_t *)&svga->vram[addr & svga->vram_mask] = val;
@ -1604,7 +1690,8 @@ void banshee_hwcursor_draw(svga_t *svga, int displine)
svga->hwcursor_latch.addr += 16;
x_off = svga->hwcursor_latch.x;
x_off <<= svga->horizontal_linedbl;
if (banshee->vidProcCfg & VIDPROCCFG_CURSOR_MODE)
{
/*X11 mode*/
@ -2060,8 +2147,11 @@ static void banshee_overlay_draw(svga_t *svga, int displine)
case VIDPROCCFG_FILTER_MODE_DITHER_4X4:
if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled)
{
uint8_t fil[(svga->overlay_latch.xsize) * 3];
uint8_t fil3[(svga->overlay_latch.xsize) * 3];
//uint8_t fil[(svga->overlay_latch.xsize) * 3];
//uint8_t fil3[(svga->overlay_latch.xsize) * 3];
uint8_t fil[4096 * 3];
uint8_t fil3[4096 * 3];
if (banshee->vidProcCfg & VIDPROCCFG_H_SCALE_ENABLE) /* leilei HACK - don't know of real 4x1 hscaled behavior yet, double for now */
{
@ -2145,14 +2235,22 @@ static void banshee_overlay_draw(svga_t *svga, int displine)
case VIDPROCCFG_FILTER_MODE_DITHER_2X2:
if (banshee->voodoo->scrfilter && banshee->voodoo->scrfilterEnabled)
{
uint8_t fil[(svga->overlay_latch.xsize) * 3];
uint8_t soak[(svga->overlay_latch.xsize) * 3];
uint8_t soak2[(svga->overlay_latch.xsize) * 3];
//uint8_t fil[(svga->overlay_latch.xsize) * 3];
//uint8_t soak[(svga->overlay_latch.xsize) * 3];
//uint8_t soak2[(svga->overlay_latch.xsize) * 3];
//uint8_t samp1[(svga->overlay_latch.xsize) * 3];
//uint8_t samp2[(svga->overlay_latch.xsize) * 3];
//uint8_t samp3[(svga->overlay_latch.xsize) * 3];
//uint8_t samp4[(svga->overlay_latch.xsize) * 3];
uint8_t fil[4096 * 3];
uint8_t soak[4096 * 3];
uint8_t soak2[4096 * 3];
uint8_t samp1[4096 * 3];
uint8_t samp2[4096 * 3];
uint8_t samp3[4096 * 3];
uint8_t samp4[4096 * 3];
uint8_t samp1[(svga->overlay_latch.xsize) * 3];
uint8_t samp2[(svga->overlay_latch.xsize) * 3];
uint8_t samp3[(svga->overlay_latch.xsize) * 3];
uint8_t samp4[(svga->overlay_latch.xsize) * 3];
src = &svga->vram[src_addr2 & svga->vram_mask];
OVERLAY_SAMPLE(banshee->overlay_buffer[1]);
@ -2331,8 +2429,8 @@ static uint8_t banshee_pci_read(int func, int addr, void *p)
case 0x18: ret = 0x01; break; /*ioBaseAddr*/
case 0x19: ret = banshee->ioBaseAddr >> 8; break;
case 0x1a: ret = 0x00; break;
case 0x1b: ret = 0x00; break;
case 0x1a: ret = banshee->ioBaseAddr >> 16; break;
case 0x1b: ret = banshee->ioBaseAddr >> 24; break;
/*Subsystem vendor ID*/
case 0x2c: ret = banshee->pci_regs[0x2c]; break;
@ -2375,18 +2473,18 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p)
case PCI_REG_COMMAND:
if (val & PCI_COMMAND_IO)
{
io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
io_removehandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
if (banshee->ioBaseAddr)
io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
io_removehandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
io_sethandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
if (banshee->ioBaseAddr)
io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
io_sethandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
}
else
{
io_removehandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
io_removehandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
io_removehandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
}
banshee->pci_regs[PCI_REG_COMMAND] = val & 0x27;
banshee_updatemapping(banshee);
@ -2408,12 +2506,22 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p)
banshee_updatemapping(banshee);
return;
case 0x1a:
banshee->ioBaseAddr &= 0xff00ffff;
banshee->ioBaseAddr |= val << 16;
break;
case 0x1b:
banshee->ioBaseAddr &= 0x00ffffff;
banshee->ioBaseAddr |= val << 24;
break;
case 0x19:
if (banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO)
io_removehandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
banshee->ioBaseAddr = val << 8;
io_removehandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
banshee->ioBaseAddr &= 0xffff00ff;
banshee->ioBaseAddr |= val << 8;
if ((banshee->pci_regs[PCI_REG_COMMAND] & PCI_COMMAND_IO) && banshee->ioBaseAddr)
io_sethandler(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
io_sethandlerx(banshee->ioBaseAddr, 0x0100, banshee_ext_in, NULL, banshee_ext_inl, banshee_ext_out, NULL, banshee_ext_outl, banshee);
pclog("Banshee ioBaseAddr=%08x\n", banshee->ioBaseAddr);
// s3_virge_updatemapping(virge);
return;
@ -2424,13 +2532,13 @@ static void banshee_pci_write(int func, int addr, uint8_t val, void *p)
{
uint32_t addr = (banshee->pci_regs[0x32] << 16) | (banshee->pci_regs[0x33] << 24);
pclog("Banshee bios_rom enabled at %08x\n", addr);
mem_mapping_set_addr(&banshee->bios_rom.mapping, addr, 0x10000);
mem_mapping_enable(&banshee->bios_rom.mapping);
mem_mapping_set_addrx(&banshee->bios_rom.mapping, addr, 0x10000);
mem_mapping_enablex(&banshee->bios_rom.mapping);
}
else
{
pclog("Banshee bios_rom disabled\n");
mem_mapping_disable(&banshee->bios_rom.mapping);
mem_mapping_disablex(&banshee->bios_rom.mapping);
}
return;
case 0x3c:
@ -2445,6 +2553,7 @@ static device_config_t banshee_sgram_config[] =
.name = "memory",
.description = "Memory size",
.type = CONFIG_SELECTION,
.default_int = 16,
.selection =
{
{
@ -2458,8 +2567,7 @@ static device_config_t banshee_sgram_config[] =
{
.description = ""
}
},
.default_int = 16
}
},
{
.name = "bilinear",
@ -2477,6 +2585,7 @@ static device_config_t banshee_sgram_config[] =
.name = "render_threads",
.description = "Render threads",
.type = CONFIG_SELECTION,
.default_int = 2,
.selection =
{
{
@ -2494,8 +2603,7 @@ static device_config_t banshee_sgram_config[] =
{
.description = ""
}
},
.default_int = 2
}
},
#ifndef NO_CODEGEN
{
@ -2528,6 +2636,7 @@ static device_config_t banshee_sdram_config[] =
.name = "render_threads",
.description = "Render threads",
.type = CONFIG_SELECTION,
.default_int = 2,
.selection =
{
{
@ -2546,7 +2655,6 @@ static device_config_t banshee_sdram_config[] =
.description = ""
}
},
.default_int = 2
},
#ifndef NO_CODEGEN
{
@ -2561,16 +2669,29 @@ static device_config_t banshee_sdram_config[] =
}
};
void voodoo_update_vram(void *p)
{
banshee_t *banshee = (banshee_t*)p;
banshee->voodoo->vram = banshee->svga.vram;
banshee->voodoo->fb_mem = banshee->svga.vram;
banshee->voodoo->tex_mem[0] = banshee->svga.vram;
banshee->voodoo->tex_mem_w[0] = (uint16_t*)banshee->svga.vram;
banshee->voodoo->tex_mem[1] = banshee->svga.vram;
banshee->voodoo->tex_mem_w[1] = (uint16_t*)banshee->svga.vram;
}
static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_type)
{
int mem_size;
banshee_t *banshee = malloc(sizeof(banshee_t));
banshee_t *banshee = (banshee_t*)malloc(sizeof(banshee_t));
memset(banshee, 0, sizeof(banshee_t));
banshee->type = type;
banshee->intrCtrl = 0x80000000;
rom_init(&banshee->bios_rom, fn, 0xc0000, 0x10000, 0xffff, 0, MEM_MAPPING_EXTERNAL);
mem_mapping_disable(&banshee->bios_rom.mapping);
mem_mapping_disablex(&banshee->bios_rom.mapping);
if (has_sgram)
mem_size = device_get_config_int("memory");
@ -2584,7 +2705,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
banshee_overlay_draw);
banshee->svga.vsync_callback = banshee_vsync_callback;
mem_mapping_add(&banshee->linear_mapping, 0, 0, banshee_read_linear,
mem_mapping_addx(&banshee->linear_mapping, 0, 0, banshee_read_linear,
banshee_read_linear_w,
banshee_read_linear_l,
banshee_write_linear,
@ -2593,7 +2714,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
NULL,
MEM_MAPPING_EXTERNAL,
&banshee->svga);
mem_mapping_add(&banshee->reg_mapping_low, 0, 0,banshee_reg_read,
mem_mapping_addx(&banshee->reg_mapping_low, 0, 0,banshee_reg_read,
banshee_reg_readw,
banshee_reg_readl,
banshee_reg_write,
@ -2602,7 +2723,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
NULL,
MEM_MAPPING_EXTERNAL,
banshee);
mem_mapping_add(&banshee->reg_mapping_high, 0,0,banshee_reg_read,
mem_mapping_addx(&banshee->reg_mapping_high, 0,0,banshee_reg_read,
banshee_reg_readw,
banshee_reg_readl,
banshee_reg_write,
@ -2612,7 +2733,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
MEM_MAPPING_EXTERNAL,
banshee);
// io_sethandler(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
// io_sethandlerx(0x03c0, 0x0020, banshee_in, NULL, NULL, banshee_out, NULL, NULL, banshee);
banshee->svga.bpp = 8;
banshee->svga.miscout = 1;
@ -2626,7 +2747,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
pci_add(banshee_pci_read, banshee_pci_write, banshee);
banshee->voodoo = voodoo_2d3d_card_init(voodoo_type);
banshee->voodoo = (voodoo_t*)voodoo_2d3d_card_init(voodoo_type);
banshee->voodoo->p = banshee;
banshee->voodoo->vram = banshee->svga.vram;
banshee->voodoo->changedvram = banshee->svga.changedvram;
@ -2641,7 +2762,7 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
banshee->vidSerialParallelPort = VIDSERIAL_DDC_DCK_W | VIDSERIAL_DDC_DDA_W;
ddc_init();
//ddc_init();
switch (type)
{
@ -2677,6 +2798,8 @@ static void *banshee_init_common(char *fn, int has_sgram, int type, int voodoo_t
break;
}
banshee->svga.vblank_start = banshee_vblank_start;
return banshee;
}

View File

@ -22,6 +22,8 @@
#include "vid_voodoo_banshee_blitter.h"
#include "vid_voodoo_render.h"
#define MAX(a,b) ((a) > (b) ? (a) : (b))
#define COMMAND_CMD_MASK (0xf)
#define COMMAND_CMD_NOP (0 << 0)
#define COMMAND_CMD_SCREEN_TO_SCREEN_BLT (1 << 0)

View File

@ -3376,7 +3376,7 @@ static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params,
{
int c;
int b = last_block[odd_even];
voodoo_x86_data_t *voodoo_x86_data = voodoo->codegen_data;
voodoo_x86_data_t *voodoo_x86_data = (voodoo_x86_data_t*)voodoo->codegen_data;
voodoo_x86_data_t *data;
for (c = 0; c < 8; c++)

View File

@ -3312,12 +3312,12 @@ static inline void voodoo_generate(uint8_t *code_block, voodoo_t *voodoo, voodoo
}
int voodoo_recomp = 0;
static inline void *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even)
static inline uint8_t *voodoo_get_block(voodoo_t *voodoo, voodoo_params_t *params, voodoo_state_t *state, int odd_even)
{
int c;
int b = last_block[odd_even];
voodoo_x86_data_t *data;
voodoo_x86_data_t *codegen_data = voodoo->codegen_data;
voodoo_x86_data_t *codegen_data = (voodoo_x86_data_t*)voodoo->codegen_data;
for (c = 0; c < 8; c++)
{

View File

@ -322,7 +322,8 @@ static void voodoo_filterline_v1(voodoo_t *voodoo, uint8_t *fil, int column, uin
int x;
// Scratchpad for avoiding feedback streaks
uint8_t fil3[(voodoo->h_disp) * 3];
// uint8_t fil3[(voodoo->h_disp) * 3];
uint8_t fil3[4096 * 3];
/* 16 to 32-bit */
for (x=0; x<column;x++)
@ -388,7 +389,8 @@ static void voodoo_filterline_v2(voodoo_t *voodoo, uint8_t *fil, int column, uin
int x;
// Scratchpad for blending filter
uint8_t fil3[(voodoo->h_disp) * 3];
//uint8_t fil3[(voodoo->h_disp) * 3];
uint8_t fil3[4096 * 3];
/* 16 to 32-bit */
for (x=0; x<column;x++)
@ -495,7 +497,8 @@ void voodoo_callback(void *p)
if (voodoo->scrfilter && voodoo->scrfilterEnabled)
{
uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */
//uint8_t fil[(voodoo->h_disp) * 3]; /* interleaved 24-bit RGB */
uint8_t fil[4096 * 3]; /* interleaved 24-bit RGB */
if (voodoo->type == VOODOO_2)
voodoo_filterline_v2(voodoo, fil, voodoo->h_disp, src, voodoo->line);
@ -602,8 +605,11 @@ skip_draw:
voodoo->line = 0;
voodoo->v_retrace = 0;
}
#if 0
if (voodoo->line_time)
timer_advance_u64(&voodoo->timer, voodoo->line_time);
else
timer_advance_u64(&voodoo->timer, TIMER_USEC * 32);
#endif
}

View File

@ -25,7 +25,7 @@ void voodoo_wake_fifo_thread(voodoo_t *voodoo)
process one word and go back to sleep, requiring it to be woken on
almost every write. Instead, wait a short while so that the CPU
emulation writes more data so we have more batched-up work.*/
timer_set_delay_u64(&voodoo->wake_timer, WAKE_DELAY);
timer_set_delay_u64x(&voodoo->wake_timer, WAKE_DELAY);
}
}

View File

@ -1,3 +1,6 @@
#include <emmintrin.h>
#include <math.h>
#include <stddef.h>
#include "ibm.h"
@ -679,7 +682,7 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood
int texels;
int c;
#ifndef NO_CODEGEN
uint8_t (*voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y);
uint8_t (__cdecl *voodoo_draw)(voodoo_state_t *state, voodoo_params_t *params, int x, int real_y);
#endif
int y_diff = SLI_ENABLED ? 2 : 1;
@ -772,8 +775,9 @@ static void voodoo_half_triangle(voodoo_t *voodoo, voodoo_params_t *params, vood
}
}
#ifndef NO_CODEGEN
typedef uint8_t(__cdecl *VOODOO_DRAW)(voodoo_state_t*,voodoo_params_t*, int,int);
if (voodoo->use_recompiler)
voodoo_draw = voodoo_get_block(voodoo, params, state, odd_even);
voodoo_draw = (VOODOO_DRAW)voodoo_get_block(voodoo, params, state, odd_even);
else
voodoo_draw = NULL;
#endif

View File

@ -1,3 +1,4 @@
#if !(defined i386 || defined __i386 || defined __i386__ || defined _X86_ || defined WIN32 || defined _WIN32 || defined _WIN32) && !(defined __amd64__)
#define NO_CODEGEN
#endif

457
pci.cpp
View File

@ -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);

19
x86.cpp
View File

@ -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)