mirror of
https://github.com/LIV2/WinUAE.git
synced 2025-12-06 00:12:52 +00:00
6085 lines
175 KiB
C++
6085 lines
175 KiB
C++
/*
|
||
* UAE - The Un*x Amiga Emulator
|
||
*
|
||
* Cirrus Logic based graphics board emulation
|
||
*
|
||
* Copyright 2013 Toni Wilen
|
||
*
|
||
*/
|
||
|
||
#define VRAMLOG 0
|
||
#define MEMLOGR 0
|
||
#define MEMLOGW 0
|
||
#define MEMLOGINDIRECT 0
|
||
#define REGDEBUG 0
|
||
#define MEMDEBUG 0
|
||
#define MEMDEBUGMASK 0x7fffff
|
||
#define MEMDEBUGTEST 0x3fc000
|
||
#define MEMDEBUGCLEAR 0
|
||
#define SPCDEBUG 0
|
||
#define PICASSOIV_DEBUG_IO 0
|
||
|
||
#if MEMLOGR
|
||
static bool memlogr = true;
|
||
static bool memlogw = true;
|
||
#endif
|
||
|
||
#define BYTESWAP_WORD -1
|
||
#define BYTESWAP_LONG 1
|
||
|
||
#include "sysconfig.h"
|
||
#include "sysdeps.h"
|
||
|
||
#include "options.h"
|
||
#include "uae.h"
|
||
#include "memory.h"
|
||
#include "debug.h"
|
||
#include "custom.h"
|
||
#include "newcpu.h"
|
||
#include "picasso96.h"
|
||
#include "statusline.h"
|
||
#include "rommgr.h"
|
||
#include "zfile.h"
|
||
#include "gfxboard.h"
|
||
#include "rommgr.h"
|
||
#include "xwin.h"
|
||
#include "devices.h"
|
||
#include "gfxfilter.h"
|
||
#include "flashrom.h"
|
||
#include "pcem/device.h"
|
||
#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
|
||
|
||
#define BOARD_REGISTERS_SIZE 0x00010000
|
||
|
||
#define BOARD_MANUFACTURER_PICASSO 2167
|
||
#define BOARD_MODEL_MEMORY_PICASSOII 11
|
||
#define BOARD_MODEL_REGISTERS_PICASSOII 12
|
||
|
||
#define BOARD_MODEL_MEMORY_PICASSOIV 24
|
||
#define BOARD_MODEL_REGISTERS_PICASSOIV 23
|
||
#define PICASSOIV_REG 0x00600000
|
||
#define PICASSOIV_IO 0x00200000
|
||
#define PICASSOIV_VRAM1 0x01000000
|
||
#define PICASSOIV_VRAM2 0x00800000
|
||
#define PICASSOIV_ROM_OFFSET 0x0200
|
||
#define PICASSOIV_FLASH_OFFSET 0x8000
|
||
#define PICASSOIV_FLASH_BANK 0x10000
|
||
#define PICASSOIV_MAX_FLASH (GFXBOARD_AUTOCONFIG_SIZE - 32768)
|
||
|
||
#define PICASSOIV_BANK_UNMAPFLASH 2
|
||
#define PICASSOIV_BANK_MAPRAM 4
|
||
#define PICASSOIV_BANK_FLASHBANK 128
|
||
|
||
#define PICASSOIV_INT_VBLANK 128
|
||
|
||
#define BOARD_MANUFACTURER_PICCOLO 2195
|
||
#define BOARD_MODEL_MEMORY_PICCOLO 5
|
||
#define BOARD_MODEL_REGISTERS_PICCOLO 6
|
||
#define BOARD_MODEL_MEMORY_PICCOLO64 10
|
||
#define BOARD_MODEL_REGISTERS_PICCOLO64 11
|
||
|
||
#define BOARD_MANUFACTURER_SPECTRUM 2193
|
||
#define BOARD_MODEL_MEMORY_SPECTRUM 1
|
||
#define BOARD_MODEL_REGISTERS_SPECTRUM 2
|
||
|
||
struct gfxboard
|
||
{
|
||
int id;
|
||
const TCHAR *name;
|
||
const TCHAR *manufacturername;
|
||
const TCHAR *configname;
|
||
int manufacturer;
|
||
int model_memory;
|
||
int model_registers;
|
||
int model_extra;
|
||
int serial;
|
||
int vrammin;
|
||
int vrammax;
|
||
int banksize;
|
||
int chiptype;
|
||
int configtype;
|
||
int irq;
|
||
bool swap;
|
||
uae_u32 romtype;
|
||
uae_u8 er_type;
|
||
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)
|
||
|
||
// Picasso II: 8* 4x256 (1M) or 16* 4x256 (2M)
|
||
// Piccolo: 8* 4x256 + 2* 16x256 (2M)
|
||
|
||
static const struct gfxboard boards[] =
|
||
{
|
||
{
|
||
GFXBOARD_ID_A2410,
|
||
_T("A2410 [Zorro II]"), _T("Commodore"), _T("A2410"),
|
||
1030, 0, 0, 0,
|
||
0x00000000, 0x00200000, 0x00200000, 0x10000, 0, 0, 2, false,
|
||
0, 0xc1, &a2410_func
|
||
},
|
||
{
|
||
GFXBOARD_ID_SPECTRUM_Z2,
|
||
_T("Spectrum 28/24 [Zorro II]"), _T("Great Valley Products"), _T("Spectrum28/24_Z2"),
|
||
BOARD_MANUFACTURER_SPECTRUM, BOARD_MODEL_MEMORY_SPECTRUM, BOARD_MODEL_REGISTERS_SPECTRUM, 0,
|
||
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 6, true,
|
||
0, 0, NULL, &gd5428_swapped_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_SPECTRUM_Z3,
|
||
_T("Spectrum 28/24 [Zorro III]"), _T("Great Valley Products"), _T("Spectrum28/24_Z3"),
|
||
BOARD_MANUFACTURER_SPECTRUM, BOARD_MODEL_MEMORY_SPECTRUM, BOARD_MODEL_REGISTERS_SPECTRUM, 0,
|
||
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 3, 6, true,
|
||
0, 0, NULL, &gd5428_swapped_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_PICCOLO_Z2,
|
||
_T("Piccolo [Zorro II]"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("Piccolo_Z2"),
|
||
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, 0,
|
||
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 6, true,
|
||
0, 0, NULL, &gd5426_swapped_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_PICCOLO_Z3,
|
||
_T("Piccolo [Zorro III]"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("Piccolo_Z3"),
|
||
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO, 0,
|
||
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 3, 6, true,
|
||
0, 0, NULL, &gd5426_swapped_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_SD64_Z2,
|
||
_T("Piccolo SD64 [Zorro II]"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("PiccoloSD64_Z2"),
|
||
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, 0,
|
||
0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 2, 6, true,
|
||
0, 0, NULL, &gd5434_vlb_swapped_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_SD64_Z3,
|
||
_T("Piccolo SD64 [Zorro III]"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("PiccoloSD64_Z3"),
|
||
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64, 0,
|
||
0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 3, 6, true,
|
||
0, 0, NULL, &gd5434_vlb_swapped_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_CV64_Z3,
|
||
_T("CyberVision 64 [Zorro III]"), _T("Phase 5"), _T("CV64_Z3"),
|
||
8512, 34, 0, 0,
|
||
0x00000000, 0x00200000, 0x00400000, 0x20000000, 0, 3, 2, false,
|
||
0, 0, NULL, &s3_cybervision_trio64_device, 0x40
|
||
},
|
||
{
|
||
GFXBOARD_ID_CV643D_Z2,
|
||
_T("CyberVision 64/3D [Zorro II]"), _T("Phase 5"), _T("CV643D_Z2"),
|
||
8512, 67, 0, 0,
|
||
0x00000000, 0x00400000, 0x00400000, 0x00400000, 0, 2, 2, false,
|
||
0, 0, NULL, &s3_virge_device, 0xc0
|
||
},
|
||
{
|
||
GFXBOARD_ID_CV643D_Z3,
|
||
_T("CyberVision 64/3D [Zorro III]"), _T("Phase 5"), _T("CV643D_Z3"),
|
||
8512, 67, 0, 0,
|
||
0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 3, 2, false,
|
||
0, 0, NULL, &s3_virge_device, 0x40
|
||
},
|
||
{
|
||
GFXBOARD_ID_PICASSO2,
|
||
_T("Picasso II [Zorro II]"), _T("Village Tronic"), _T("PicassoII"),
|
||
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII, 0,
|
||
0x00020000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 0, false,
|
||
0, 0, NULL, &gd5426_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_PICASSO2PLUS,
|
||
_T("Picasso II+ [Zorro II]"), _T("Village Tronic"), _T("PicassoII+"),
|
||
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII, 0,
|
||
0x00100000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 2, false,
|
||
0, 0, NULL, &gd5428_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_PICASSO4_Z2,
|
||
_T("Picasso IV [Zorro II]"), _T("Village Tronic"), _T("PicassoIV_Z2"),
|
||
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, BOARD_MODEL_REGISTERS_PICASSOIV, 0,
|
||
0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5446, 2, 2, false,
|
||
ROMTYPE_PICASSOIV,
|
||
0, NULL, &gd5446_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_PICASSO4_Z3,
|
||
_T("Picasso IV [Zorro III]"), _T("Village Tronic"), _T("PicassoIV_Z3"),
|
||
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, 0, 0,
|
||
0x00000000, 0x00400000, 0x00400000, 0x02000000, CIRRUS_ID_CLGD5446, 3, 2, false,
|
||
ROMTYPE_PICASSOIV,
|
||
0, NULL, &gd5446_device
|
||
},
|
||
{
|
||
GFXBOARD_ID_HARLEQUIN,
|
||
_T("Harlequin [Zorro II]"), _T("ACS"), _T("Harlequin_PAL"),
|
||
2118, 100, 0, 0,
|
||
0x00000000, 0x00200000, 0x00200000, 0x10000, 0, 0, 2, false,
|
||
ROMTYPE_HARLEQUIN, 0xc2, &harlequin_func
|
||
},
|
||
#if 0
|
||
{
|
||
_T("Resolver"), _T("DMI"), _T("Resolver"),
|
||
2129, 1, 0,
|
||
0x00000000, 0x00200000, 0x00200000, 0x10000, 0, 0, 2, false,
|
||
0, 0xc1, &a2410_func
|
||
},
|
||
#endif
|
||
{
|
||
GFXBOARD_ID_VOODOO3_PCI,
|
||
_T("Voodoo 3 3000 [PCI]"), _T("3dfx"), _T("V3_3000"),
|
||
0, 0, 0, 0,
|
||
0x00000000, 0x01000000, 0x01000000, 0x01000000, 0, 0, -1, false,
|
||
ROMTYPE_VOODOO3,
|
||
0, NULL, &voodoo_3_3000_device, 0, true
|
||
},
|
||
{
|
||
GFXBOARD_ID_S3VIRGE_PCI,
|
||
_T("Virge [PCI]"), _T("S3"), _T("S3VIRGE_PCI"),
|
||
0, 0, 0, 0,
|
||
0x00000000, 0x00400000, 0x00400000, 0x10000000, 0, 0, -1, false,
|
||
0, 0, NULL, &s3_virge_device, 0, true
|
||
},
|
||
{
|
||
GFXBOARD_ID_VGA,
|
||
_T("x86 bridgeboard VGA [ISA]"), _T("x86"), _T("VGA"),
|
||
0, 0, 0, 0,
|
||
0x00000000, 0x00100000, 0x00200000, 0x00000000, CIRRUS_ID_CLGD5426, 0, 0, false,
|
||
ROMTYPE_x86_VGA
|
||
},
|
||
{
|
||
GFXBOARD_ID_PIXEL64,
|
||
_T("Pixel64 [AteoBus]"), _T("At<EFBFBD>o Concepts"), _T("Pixel64"),
|
||
2026, 255, 254, 0, // 255: type=$c7 flags=$40, 254: type=$c2 flags=$40 128k, 252: type=$c2 flags=$40, 128k
|
||
0x00000000, 0x00200000, 0x00200000, 0x00400000, CIRRUS_ID_CLGD5434, 2, 0, false,
|
||
0, 0, NULL, &gd5434_vlb_swapped_device
|
||
},
|
||
{
|
||
NULL
|
||
}
|
||
};
|
||
|
||
struct rtggfxboard
|
||
{
|
||
bool active;
|
||
int rtg_index;
|
||
int monitor_id;
|
||
struct rtgboardconfig *rbc;
|
||
TCHAR memorybankname[100];
|
||
TCHAR memorybanknamenojit[100];
|
||
TCHAR wbsmemorybankname[100];
|
||
TCHAR lbsmemorybankname[100];
|
||
TCHAR regbankname[100];
|
||
|
||
int configured_mem, configured_regs;
|
||
const struct gfxboard *board;
|
||
uae_u8 expamem_lo;
|
||
uae_u8 *automemory;
|
||
uae_u32 banksize_mask;
|
||
uaecptr io_start, io_end;
|
||
uaecptr mem_start[2], mem_end[2];
|
||
|
||
uae_u8 picassoiv_bank, picassoiv_flifi;
|
||
uae_u8 p4autoconfig[256];
|
||
struct zfile *p4rom;
|
||
void *p4flashrom;
|
||
bool p4z2;
|
||
uae_u32 p4_mmiobase;
|
||
uae_u32 p4_special_mask;
|
||
uae_u32 p4_special_start;
|
||
uae_u32 p4_vram_bank[2];
|
||
uae_u32 device_data;
|
||
|
||
CirrusVGAState vga;
|
||
uae_u8 *vram, *vramend, *vramrealstart;
|
||
int vram_start_offset;
|
||
int vrammask;
|
||
uae_u32 gfxboardmem_start;
|
||
bool monswitch_current, monswitch_new;
|
||
bool monswitch_keep_trying;
|
||
bool monswitch_reset;
|
||
int monswitch_delay;
|
||
int fullrefresh;
|
||
int resolutionchange;
|
||
uae_u8 *gfxboard_surface, *fakesurface_surface;
|
||
bool gfxboard_intreq;
|
||
int gfxboard_intena;
|
||
bool vram_enabled, vram_offset_enabled;
|
||
hwaddr vram_offset[2];
|
||
uae_u8 cirrus_pci[0x44];
|
||
uae_u8 p4i2c;
|
||
uae_u8 p4_pci[0x44];
|
||
int vga_width, vga_height, vga_width_mult, vga_height_mult;
|
||
bool vga_refresh_active;
|
||
int device_settings;
|
||
|
||
uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr;
|
||
|
||
const MemoryRegionOps *vgaio, *vgaram, *vgalowram, *vgammio;
|
||
MemoryRegion vgaioregion, vgavramregion;
|
||
DisplaySurface gfxsurface, fakesurface;
|
||
|
||
addrbank gfxboard_bank_memory;
|
||
addrbank gfxboard_bank_memory_nojit;
|
||
addrbank gfxboard_bank_wbsmemory;
|
||
addrbank gfxboard_bank_lbsmemory;
|
||
addrbank gfxboard_bank_nbsmemory;
|
||
addrbank gfxboard_bank_registers;
|
||
addrbank gfxboard_bank_registers2;
|
||
addrbank gfxboard_bank_special;
|
||
|
||
addrbank gfxboard_bank_vram_pcem;
|
||
addrbank gfxboard_bank_vram_normal_pcem;
|
||
addrbank gfxboard_bank_vram_wordswap_pcem;
|
||
addrbank gfxboard_bank_vram_longswap_pcem;
|
||
addrbank gfxboard_bank_vram_cv_1_pcem;
|
||
addrbank gfxboard_bank_vram_p4z2_pcem;
|
||
addrbank gfxboard_bank_io_pcem;
|
||
addrbank gfxboard_bank_io_swap_pcem;
|
||
addrbank gfxboard_bank_io_swap2_pcem;
|
||
addrbank gfxboard_bank_pci_pcem;
|
||
addrbank gfxboard_bank_mmio_pcem;
|
||
addrbank gfxboard_bank_mmio_wbs_pcem;
|
||
addrbank gfxboard_bank_mmio_lbs_pcem;
|
||
addrbank gfxboard_bank_special_pcem;
|
||
addrbank gfxboard_bank_bios;
|
||
|
||
addrbank *original_pci_bank;
|
||
|
||
addrbank *gfxmem_bank;
|
||
uae_u8 *vram_back;
|
||
|
||
struct autoconfig_info *aci;
|
||
|
||
struct gfxboard_func *func;
|
||
|
||
device_t *pcemdev;
|
||
void *pcemobject; // device_t
|
||
void *pcemobject2; // svga_t
|
||
int pcem_mmio_offset;
|
||
int pcem_mmio_mask;
|
||
bool pcem_pci_configured;
|
||
int pcem_data[2];
|
||
int pcem_vram_offset;
|
||
int pcem_vram_mask;
|
||
int pcem_io_mask;
|
||
int pcem_vblank;
|
||
bool p4_revb;
|
||
uae_u8 *bios;
|
||
uae_u32 bios_mask;
|
||
int lfbbyteswapmode;
|
||
int mmiobyteswapmode;
|
||
struct pci_board_state *pcibs;
|
||
bool pcem_direct;
|
||
|
||
int width_redraw, height_redraw;
|
||
|
||
void *userdata;
|
||
};
|
||
|
||
static struct rtggfxboard rtggfxboards[MAX_RTG_BOARDS];
|
||
static struct rtggfxboard *only_gfx_board;
|
||
static int rtg_visible[MAX_AMIGADISPLAYS];
|
||
static int rtg_initial[MAX_AMIGADISPLAYS];
|
||
static int total_active_gfx_boards;
|
||
static int vram_ram_a8;
|
||
static DisplaySurface fakesurface;
|
||
|
||
DECLARE_MEMORY_FUNCTIONS(gfxboard);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, mem_nojit);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, bsmem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, wbsmem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, lbsmem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, nbsmem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, regs);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboards, regs);
|
||
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, vram_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, vram_normal_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, vram_wordswap_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, vram_longswap_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, vram_cv_1_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, vram_p4z2_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, io_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, io_swap_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, io_swap2_pcem);
|
||
DECLARE_MEMORY_FUNCTIONS_WITH_SUFFIX(gfxboard, pci_pcem);
|
||
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,
|
||
gfxboard_lput_mem, gfxboard_wput_mem, gfxboard_bput_mem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
|
||
gfxboard_lget_mem, gfxboard_wget_mem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL, 0, 0
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_memory_nojit = {
|
||
gfxboard_lget_mem_nojit, gfxboard_wget_mem_nojit, gfxboard_bget_mem_nojit,
|
||
gfxboard_lput_mem_nojit, gfxboard_wput_mem_nojit, gfxboard_bput_mem_nojit,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
|
||
gfxboard_lget_mem_nojit, gfxboard_wget_mem_nojit,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE | ABFLAG_CACHE_ENABLE_ALL, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_wbsmemory = {
|
||
gfxboard_lget_wbsmem, gfxboard_wget_wbsmem, gfxboard_bget_wbsmem,
|
||
gfxboard_lput_wbsmem, gfxboard_wput_wbsmem, gfxboard_bput_wbsmem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
|
||
gfxboard_lget_wbsmem, gfxboard_wget_wbsmem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE | ABFLAG_CACHE_ENABLE_ALL, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_lbsmemory = {
|
||
gfxboard_lget_lbsmem, gfxboard_wget_lbsmem, gfxboard_bget_lbsmem,
|
||
gfxboard_lput_lbsmem, gfxboard_wput_lbsmem, gfxboard_bput_lbsmem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, NULL,
|
||
gfxboard_lget_lbsmem, gfxboard_wget_lbsmem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE | ABFLAG_CACHE_ENABLE_ALL, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_nbsmemory = {
|
||
gfxboard_lget_nbsmem, gfxboard_wget_nbsmem, gfxboard_bget_bsmem,
|
||
gfxboard_lput_nbsmem, gfxboard_wput_nbsmem, gfxboard_bput_bsmem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("Picasso IV banked VRAM"),
|
||
gfxboard_lget_nbsmem, gfxboard_wget_nbsmem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE | ABFLAG_CACHE_ENABLE_ALL, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_registers = {
|
||
gfxboard_lget_regs, gfxboard_wget_regs, gfxboard_bget_regs,
|
||
gfxboard_lput_regs, gfxboard_wput_regs, gfxboard_bput_regs,
|
||
default_xlate, default_check, NULL, NULL, NULL,
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_registers2 = {
|
||
gfxboard_lget_regs, gfxboard_wget_regs, gfxboard_bget_regs,
|
||
gfxboard_lput_regs, gfxboard_wput_regs, gfxboard_bput_regs,
|
||
default_xlate, default_check, NULL, NULL, NULL,
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
|
||
static const addrbank tmpl_gfxboard_bank_special = {
|
||
gfxboards_lget_regs, gfxboards_wget_regs, gfxboards_bget_regs,
|
||
gfxboards_lput_regs, gfxboards_wput_regs, gfxboards_bput_regs,
|
||
default_xlate, default_check, NULL, NULL, _T("Picasso IV MISC"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_vram_pcem = {
|
||
gfxboard_lget_vram_pcem, gfxboard_wget_vram_pcem, gfxboard_bget_vram_pcem,
|
||
gfxboard_lput_vram_pcem, gfxboard_wput_vram_pcem, gfxboard_bput_vram_pcem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM"),
|
||
gfxboard_lget_vram_pcem, gfxboard_wget_vram_pcem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_vram_normal_pcem = {
|
||
gfxboard_lget_vram_normal_pcem, gfxboard_wget_vram_normal_pcem, gfxboard_bget_vram_normal_pcem,
|
||
gfxboard_lput_vram_normal_pcem, gfxboard_wput_vram_normal_pcem, gfxboard_bput_vram_normal_pcem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (NOSWAP)"),
|
||
gfxboard_lget_vram_normal_pcem, gfxboard_wget_vram_normal_pcem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_vram_wordswap_pcem = {
|
||
gfxboard_lget_vram_wordswap_pcem, gfxboard_wget_vram_wordswap_pcem, gfxboard_bget_vram_wordswap_pcem,
|
||
gfxboard_lput_vram_wordswap_pcem, gfxboard_wput_vram_wordswap_pcem, gfxboard_bput_vram_wordswap_pcem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (WORDSWAP)"),
|
||
gfxboard_lget_vram_wordswap_pcem, gfxboard_wget_vram_wordswap_pcem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_vram_longswap_pcem = {
|
||
gfxboard_lget_vram_longswap_pcem, gfxboard_wget_vram_longswap_pcem, gfxboard_bget_vram_longswap_pcem,
|
||
gfxboard_lput_vram_longswap_pcem, gfxboard_wput_vram_longswap_pcem, gfxboard_bput_vram_longswap_pcem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (LONGSWAP)"),
|
||
gfxboard_lget_vram_longswap_pcem, gfxboard_wget_vram_longswap_pcem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_vram_cv_1_pcem = {
|
||
gfxboard_lget_vram_cv_1_pcem, gfxboard_wget_vram_cv_1_pcem, gfxboard_bget_vram_cv_1_pcem,
|
||
gfxboard_lput_vram_cv_1_pcem, gfxboard_wput_vram_cv_1_pcem, gfxboard_bput_vram_cv_1_pcem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (CV64)"),
|
||
gfxboard_lget_vram_cv_1_pcem, gfxboard_wget_vram_cv_1_pcem,
|
||
ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_PPCIOSPACE, S_READ | S_N_ADDR, S_WRITE | S_N_ADDR
|
||
};
|
||
static const addrbank tmpl_gfxboard_bank_vram_p4z2_pcem = {
|
||
gfxboard_lget_vram_p4z2_pcem, gfxboard_wget_vram_p4z2_pcem, gfxboard_bget_vram_p4z2_pcem,
|
||
gfxboard_lput_vram_p4z2_pcem, gfxboard_wput_vram_p4z2_pcem, gfxboard_bput_vram_p4z2_pcem,
|
||
gfxboard_xlate, gfxboard_check, NULL, NULL, _T("PCem SVGA VRAM (PIVZ2)"),
|
||
gfxboard_lget_vram_p4z2_pcem, gfxboard_wget_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,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA IO SWAP"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_io_swap_pcem = {
|
||
gfxboard_lget_io_swap_pcem, gfxboard_wget_io_swap_pcem, gfxboard_bget_io_swap_pcem,
|
||
gfxboard_lput_io_swap_pcem, gfxboard_wput_io_swap_pcem, gfxboard_bput_io_swap_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA IO SWAP"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_io_swap2_pcem = {
|
||
gfxboard_lget_io_swap2_pcem, gfxboard_wget_io_swap2_pcem, gfxboard_bget_io_swap2_pcem,
|
||
gfxboard_lput_io_swap2_pcem, gfxboard_wput_io_swap2_pcem, gfxboard_bput_io_swap2_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA IO SWAP2"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_pci_pcem = {
|
||
gfxboard_lget_pci_pcem, gfxboard_wget_pci_pcem, gfxboard_bget_pci_pcem,
|
||
gfxboard_lput_pci_pcem, gfxboard_wput_pci_pcem, gfxboard_bput_pci_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA PCI"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_mmio_pcem = {
|
||
gfxboard_lget_mmio_pcem, gfxboard_wget_mmio_pcem, gfxboard_bget_mmio_pcem,
|
||
gfxboard_lput_mmio_pcem, gfxboard_wput_mmio_pcem, gfxboard_bput_mmio_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA MMIO"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_mmio_wbs_pcem = {
|
||
gfxboard_lget_mmio_wbs_pcem, gfxboard_wget_mmio_wbs_pcem, gfxboard_bget_mmio_wbs_pcem,
|
||
gfxboard_lput_mmio_wbs_pcem, gfxboard_wput_mmio_wbs_pcem, gfxboard_bput_mmio_wbs_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA MMIO WORDSWAP"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
static const addrbank tmpl_gfxboard_bank_mmio_lbs_pcem = {
|
||
gfxboard_lget_mmio_lbs_pcem, gfxboard_wget_mmio_lbs_pcem, gfxboard_bget_mmio_lbs_pcem,
|
||
gfxboard_lput_mmio_lbs_pcem, gfxboard_wput_mmio_lbs_pcem, gfxboard_bput_mmio_lbs_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA MMIO WORDSWAP"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
ABFLAG_IO | ABFLAG_SAFE, S_READ, S_WRITE
|
||
};
|
||
|
||
|
||
static const addrbank tmpl_gfxboard_bank_special_pcem = {
|
||
gfxboard_lget_special_pcem, gfxboard_wget_special_pcem, gfxboard_bget_special_pcem,
|
||
gfxboard_lput_special_pcem, gfxboard_wput_special_pcem, gfxboard_bput_special_pcem,
|
||
default_xlate, default_check, NULL, NULL, _T("PCem SVGA SPC"),
|
||
dummy_lgeti, dummy_wgeti,
|
||
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)
|
||
{
|
||
addr &= 0xffff;
|
||
if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
|
||
gb->automemory[addr] = (value & 0xf0);
|
||
gb->automemory[addr + 2] = (value & 0x0f) << 4;
|
||
} else {
|
||
gb->automemory[addr] = ~(value & 0xf0);
|
||
gb->automemory[addr + 2] = ~((value & 0x0f) << 4);
|
||
}
|
||
}
|
||
|
||
int gfxboard_get_devnum(struct uae_prefs *p, int index)
|
||
{
|
||
int devnum = 0;
|
||
uae_u32 romtype = gfxboard_get_romtype(&p->rtgboards[index]);
|
||
if (!romtype)
|
||
return devnum;
|
||
for (int i = 0; i < index; i++) {
|
||
if (gfxboard_get_romtype(&p->rtgboards[i]) == romtype)
|
||
devnum++;
|
||
}
|
||
return devnum;
|
||
}
|
||
|
||
void gfxboard_get_a8_vram(int index)
|
||
{
|
||
addrbank *ab = gfxmem_banks[index];
|
||
if (vram_ram_a8 > 0) {
|
||
addrbank *prev = gfxmem_banks[vram_ram_a8 - 1];
|
||
ab->baseaddr = prev->baseaddr;
|
||
} else {
|
||
mapped_malloc(ab);
|
||
vram_ram_a8 = index + 1;
|
||
}
|
||
}
|
||
|
||
void gfxboard_free_vram(int index)
|
||
{
|
||
addrbank *ab = gfxmem_banks[index];
|
||
if (vram_ram_a8 - 1 == index || vram_ram_a8 == 0) {
|
||
mapped_free(ab);
|
||
}
|
||
if (vram_ram_a8 - 1 == index)
|
||
vram_ram_a8 = 0;
|
||
}
|
||
|
||
extern uae_u8 *getpcembuffer32(int, int, int);
|
||
extern int svga_get_vtotal(void *p);
|
||
extern int svga_poll(void *p);
|
||
extern void voodoo_callback(void *p);
|
||
|
||
// PCEM
|
||
static void pcem_flush(struct rtggfxboard* gb, int index)
|
||
{
|
||
if (gb->pcem_direct) {
|
||
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 = (int)(buf[i] - start);
|
||
pcem_linear_mark(offset);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
if (gb->gfxboard_surface) {
|
||
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id];
|
||
if (w != gb->width_redraw || h != gb->height_redraw) {
|
||
for (int y = 0; y < vidinfo->maxheight; y++) {
|
||
uae_u8 *d = gb->gfxboard_surface + y * vidinfo->rowbytes;
|
||
if (y < h) {
|
||
if (vidinfo->maxwidth > w) {
|
||
memset(d + w * vidinfo->pixbytes, 0, (vidinfo->maxwidth - w) * vidinfo->pixbytes);
|
||
}
|
||
} else {
|
||
memset(d, 0, vidinfo->maxwidth * vidinfo->pixbytes);
|
||
}
|
||
}
|
||
gb->width_redraw = w;
|
||
gb->height_redraw = h;
|
||
y1 = 0;
|
||
y2 = h;
|
||
}
|
||
for (int yy = y1; yy < y2 && yy < vidinfo->maxheight; yy++) {
|
||
uae_u8 *d = gb->gfxboard_surface + yy * vidinfo->rowbytes;
|
||
uae_u8 *s = getpcembuffer32(x, y, yy);
|
||
int ww = w > vidinfo->maxwidth ? vidinfo->maxwidth : w;
|
||
memcpy(d, s, ww * vidinfo->pixbytes);
|
||
}
|
||
}
|
||
}
|
||
if (gb->pcem_direct) {
|
||
picasso_getwritewatch(i, 0, NULL, NULL);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static int gfxboard_pcem_poll(struct rtggfxboard *gb)
|
||
{
|
||
static int toggle;
|
||
if (!gb->vram)
|
||
return 0;
|
||
// 1, 3, 1, 3,.. because some software needs to see hsync period.
|
||
int v = svga_poll(gb->pcemobject2);
|
||
if (toggle) {
|
||
if (!v) {
|
||
v |= svga_poll(gb->pcemobject2);
|
||
if (!v) {
|
||
v |= svga_poll(gb->pcemobject2);
|
||
}
|
||
}
|
||
toggle = 0;
|
||
} else {
|
||
toggle = 1;
|
||
}
|
||
return v;
|
||
}
|
||
|
||
static void gfxboard_rethink(void)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (gb->pcemdev && gb->pcemobject && gb->gfxboard_intreq && gb->gfxboard_intena) {
|
||
int irq = 0;
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
extern int p96syncrate;
|
||
|
||
static void gfxboard_hsync_handler(void)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (!gb->active)
|
||
continue;
|
||
if (gb->func && gb->userdata) {
|
||
gb->func->hsync(gb->userdata);
|
||
}
|
||
if (gb->pcemdev && gb->pcemobject2 && !gb->pcem_vblank) {
|
||
static int pollcnt;
|
||
int total = svga_get_vtotal(gb->pcemobject2);
|
||
if (total <= 0)
|
||
total = p96syncrate;
|
||
int pollsize = (total << 8) / p96syncrate;
|
||
pollcnt += pollsize;
|
||
while (pollcnt >= 256) {
|
||
if (gfxboard_pcem_poll(gb)) {
|
||
gb->pcem_vblank = 1;
|
||
pollcnt &= 0xff;
|
||
break;
|
||
}
|
||
pollcnt -= 256;
|
||
}
|
||
}
|
||
}
|
||
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);
|
||
svga_setvram(gb->pcemobject2, gb->vram);
|
||
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) {
|
||
void voodoo_update_vram(void *p);
|
||
voodoo_update_vram(gb->pcemobject);
|
||
}
|
||
}
|
||
}
|
||
|
||
static void init_board (struct rtggfxboard *gb)
|
||
{
|
||
struct rtgboardconfig *rbc = gb->rbc;
|
||
int vramsize = gb->board->vrammax;
|
||
int chiptype = gb->board->chiptype;
|
||
|
||
if (gb->board->romtype == ROMTYPE_x86_VGA) {
|
||
struct romconfig *rc = get_device_romconfig(&currprefs, gb->board->romtype, 0);
|
||
chiptype = CIRRUS_ID_CLGD5426;
|
||
if (rc && rc->device_settings == 1) {
|
||
chiptype = CIRRUS_ID_CLGD5429;
|
||
}
|
||
}
|
||
|
||
gb->active = true;
|
||
gb->vga_width = 0;
|
||
gb->vga_height = 0;
|
||
mapped_free(gb->gfxmem_bank);
|
||
gb->vram_start_offset = 0;
|
||
if (ISP4() && !gb->p4z2) { // JIT direct compatibility hack
|
||
gb->vram_start_offset = 0x01000000;
|
||
}
|
||
vramsize += gb->vram_start_offset;
|
||
xfree (gb->fakesurface_surface);
|
||
gb->fakesurface_surface = xmalloc (uae_u8, 4 * 10000);
|
||
gb->vram_offset[0] = gb->vram_offset[1] = 0;
|
||
gb->vram_enabled = true;
|
||
gb->vram_offset_enabled = false;
|
||
gb->gfxmem_bank->reserved_size = vramsize;
|
||
gb->gfxmem_bank->start = gb->gfxboardmem_start;
|
||
if (gb->board->manufacturer) {
|
||
gb->gfxmem_bank->flags |= ABFLAG_ALLOCINDIRECT | ABFLAG_PPCIOSPACE;
|
||
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->flags |= ABFLAG_ALLOCINDIRECT | ABFLAG_PPCIOSPACE;
|
||
gb->gfxmem_bank->label = _T("*");
|
||
gb->vram_back = xmalloc(uae_u8, vramsize);
|
||
if (&get_mem_bank(0x800000) == &dummy_bank)
|
||
gb->gfxmem_bank->start = 0x800000;
|
||
else
|
||
gb->gfxmem_bank->start = 0xa00000;
|
||
gfxboard_get_a8_vram(gb->rbc->rtg_index);
|
||
}
|
||
gb->vrammask = vramsize - 1;
|
||
gb->vram = gb->gfxmem_bank->baseaddr;
|
||
gb->vramend = gb->gfxmem_bank->baseaddr + vramsize;
|
||
gb->vramrealstart = gb->vram;
|
||
gb->vram += gb->vram_start_offset;
|
||
gb->vramend += gb->vram_start_offset;
|
||
//gb->gfxmem_bank->baseaddr = gb->vram;
|
||
// restore original value because this is checked against
|
||
// configured size in expansion.cpp
|
||
if (!gb->board->pci) {
|
||
gb->gfxmem_bank->allocated_size = rbc->rtgmem_size;
|
||
gb->gfxmem_bank->reserved_size = rbc->rtgmem_size;
|
||
}
|
||
gb->vga.vga.vram_size_mb = rbc->rtgmem_size >> 20;
|
||
gb->vgaioregion.opaque = &gb->vgaioregionptr;
|
||
gb->vgaioregion.data = gb;
|
||
gb->vgavramregion.opaque = &gb->vgavramregionptr;
|
||
gb->vgavramregion.data = gb;
|
||
gb->vga.vga.vram.opaque = &gb->vgavramregionptr;
|
||
gb->vga.vga.vram.data = gb;
|
||
gb->vga.cirrus_vga_io.data = gb;
|
||
gb->vga.low_mem_container.data = gb;
|
||
gb->vga.low_mem.data = gb;
|
||
gb->vga.cirrus_bank[0].data = gb;
|
||
gb->vga.cirrus_bank[1].data = gb;
|
||
gb->vga.cirrus_linear_io.data = gb;
|
||
gb->vga.cirrus_linear_bitblt_io.data = gb;
|
||
gb->vga.cirrus_mmio_io.data = gb;
|
||
gb->gfxsurface.data = gb;
|
||
gb->fakesurface.data = gb;
|
||
vga_common_init(&gb->vga.vga);
|
||
gb->vga.vga.con = (void*)gb;
|
||
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) {
|
||
extern void initpcemvideo(void*, bool);
|
||
extern void *svga_get_object(void);
|
||
initpcemvideo(gb, gb->board->swap);
|
||
gb->pcemobject = gb->pcemdev->init();
|
||
gb->pcemobject2 = svga_get_object();
|
||
}
|
||
picasso_allocatewritewatch(gb->rbc->rtg_index, gb->rbc->rtgmem_size);
|
||
|
||
device_add_hsync(gfxboard_hsync_handler);
|
||
device_add_rethink(gfxboard_rethink);
|
||
}
|
||
|
||
static int GetBytesPerPixel(RGBFTYPE RGBfmt)
|
||
{
|
||
switch (RGBfmt)
|
||
{
|
||
case RGBFB_CLUT:
|
||
return 1;
|
||
|
||
case RGBFB_A8R8G8B8:
|
||
case RGBFB_A8B8G8R8:
|
||
case RGBFB_R8G8B8A8:
|
||
case RGBFB_B8G8R8A8:
|
||
return 4;
|
||
|
||
case RGBFB_B8G8R8:
|
||
case RGBFB_R8G8B8:
|
||
return 3;
|
||
|
||
case RGBFB_R5G5B5:
|
||
case RGBFB_R5G6B5:
|
||
case RGBFB_R5G6B5PC:
|
||
case RGBFB_R5G5B5PC:
|
||
case RGBFB_B5G6R5PC:
|
||
case RGBFB_B5G5R5PC:
|
||
return 2;
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
static void gfxboard_unlock(struct rtggfxboard *gb)
|
||
{
|
||
if (gb->gfxboard_surface) {
|
||
gfx_unlock_picasso(gb->monitor_id, true);
|
||
gb->gfxboard_surface = NULL;
|
||
}
|
||
}
|
||
|
||
static bool gfxboard_setmode(struct rtggfxboard *gb, struct gfxboard_mode *mode)
|
||
{
|
||
struct amigadisplay *ad = &adisplays[gb->monitor_id];
|
||
struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id];
|
||
|
||
state->Width = mode->width;
|
||
state->Height = mode->height;
|
||
state->VirtualWidth = state->Width;
|
||
state->VirtualHeight = state->Height;
|
||
state->HLineDBL = mode->hlinedbl ? mode->hlinedbl : 1;
|
||
state->VLineDBL = mode->vlinedbl ? mode->vlinedbl : 1;
|
||
int bpp = GetBytesPerPixel(mode->mode);
|
||
state->BytesPerPixel = bpp;
|
||
state->BytesPerRow = mode->width * bpp;
|
||
state->RGBFormat = mode->mode;
|
||
write_log(_T("GFXBOARD %dx%dx%d\n"), mode->width, mode->height, bpp);
|
||
if (!ad->picasso_requested_on && !ad->picasso_on) {
|
||
ad->picasso_requested_on = true;
|
||
set_config_changed();
|
||
}
|
||
gfxboard_unlock(gb);
|
||
return true;
|
||
}
|
||
|
||
static void gfxboard_free_slot2(struct rtggfxboard *gb)
|
||
{
|
||
struct amigadisplay *ad = &adisplays[gb->monitor_id];
|
||
gb->active = false;
|
||
if (rtg_visible[gb->monitor_id] == gb->rtg_index) {
|
||
rtg_visible[gb->monitor_id] = -1;
|
||
ad->picasso_requested_on = false;
|
||
set_config_changed();
|
||
}
|
||
if (gb->pcemdev) {
|
||
if (gb->pcemobject) {
|
||
gb->pcemdev->close(gb->pcemobject);
|
||
gb->pcemobject = NULL;
|
||
}
|
||
}
|
||
gb->userdata = NULL;
|
||
gb->func = NULL;
|
||
xfree(gb->automemory);
|
||
gb->automemory = NULL;
|
||
}
|
||
|
||
static const struct gfxboard *find_board(int id)
|
||
{
|
||
for (int i = 0; boards[i].id; i++) {
|
||
if (id == boards[i].id)
|
||
return &boards[i];
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
bool gfxboard_allocate_slot(int board, int idx)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[idx];
|
||
const struct gfxboard *gfxb = find_board(board);
|
||
if (!gfxb)
|
||
return false;
|
||
gb->active = true;
|
||
gb->rtg_index = idx;
|
||
gb->board = gfxb;
|
||
return true;
|
||
}
|
||
void gfxboard_free_slot(int idx)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[idx];
|
||
gfxboard_free_slot2(gb);
|
||
}
|
||
|
||
static int gfx_temp_bank_idx;
|
||
|
||
static uae_u32 REGPARAM2 gtb_wget(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[gfx_temp_bank_idx];
|
||
addr &= gb->banksize_mask;
|
||
return 0;
|
||
}
|
||
static uae_u32 REGPARAM2 gtb_bget(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[gfx_temp_bank_idx];
|
||
addr &= gb->banksize_mask;
|
||
if (addr < GFXBOARD_AUTOCONFIG_SIZE)
|
||
return gb->automemory[addr];
|
||
return 0xff;
|
||
}
|
||
static void REGPARAM2 gtb_bput(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[gfx_temp_bank_idx];
|
||
b &= 0xff;
|
||
addr &= gb->banksize_mask;
|
||
if (addr == 0x48) {
|
||
gfx_temp_bank_idx++;
|
||
map_banks_z2(gb->gfxmem_bank, expamem_board_pointer >> 16, expamem_board_size >> 16);
|
||
gb->func->configured(gb->userdata, expamem_board_pointer);
|
||
expamem_next(gb->gfxmem_bank, NULL);
|
||
return;
|
||
}
|
||
if (addr == 0x4c) {
|
||
expamem_shutup(gb->gfxmem_bank);
|
||
return;
|
||
}
|
||
}
|
||
static void REGPARAM2 gtb_wput(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[gfx_temp_bank_idx];
|
||
b &= 0xffff;
|
||
addr &= gb->banksize_mask;
|
||
if (addr == 0x44) {
|
||
gfx_temp_bank_idx++;
|
||
map_banks_z3(gb->gfxmem_bank, expamem_board_pointer >> 16, expamem_board_size >> 16);
|
||
gb->func->configured(gb->userdata, expamem_board_pointer);
|
||
expamem_next(gb->gfxmem_bank, NULL);
|
||
return;
|
||
}
|
||
}
|
||
|
||
static addrbank gfx_temp_bank =
|
||
{
|
||
gtb_wget, gtb_wget, gtb_bget,
|
||
gtb_wput, gtb_wput, gtb_bput,
|
||
default_xlate, default_check, NULL, NULL, _T("GFXBOARD_AUTOCONFIG"),
|
||
gtb_wget, gtb_wget,
|
||
ABFLAG_IO, S_READ, S_WRITE
|
||
};
|
||
|
||
bool gfxboard_init_board(struct autoconfig_info *aci)
|
||
{
|
||
const struct gfxboard *gfxb = find_board(aci->prefs->rtgboards[aci->devnum].rtgmem_type);
|
||
if (!gfxb)
|
||
return false;
|
||
struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
|
||
gb->func = gfxb->func;
|
||
gb->pcemdev = gfxb->pcemdev;
|
||
gb->monitor_id = aci->prefs->rtgboards[aci->devnum].monitor_id;
|
||
memset(aci->autoconfig_bytes, 0xff, sizeof aci->autoconfig_bytes);
|
||
if (!gb->automemory)
|
||
gb->automemory = xmalloc(uae_u8, GFXBOARD_AUTOCONFIG_SIZE);
|
||
memset(gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
|
||
ew(gb, 0x00, gfxb->er_type);
|
||
ew(gb, 0x04, gfxb->model_memory);
|
||
ew(gb, 0x10, (gfxb->manufacturer >> 8) & 0xff);
|
||
ew(gb, 0x14, (gfxb->manufacturer >> 0) & 0xff);
|
||
ew(gb, 0x18, (gfxb->serial >> 24) & 0xff);
|
||
ew(gb, 0x1c, (gfxb->serial >> 16) & 0xff);
|
||
ew(gb, 0x20, (gfxb->serial >> 8) & 0xff);
|
||
ew(gb, 0x24, (gfxb->serial >> 0) & 0xff);
|
||
memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
|
||
if (!gb->func->init(aci))
|
||
return false;
|
||
for(int i = 0; i < sizeof aci->autoconfig_bytes; i++) {
|
||
if (aci->autoconfig_bytes[i] != 0xff)
|
||
ew(gb, i * 4, aci->autoconfig_bytes[i]);
|
||
}
|
||
memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
|
||
if (!aci->doinit)
|
||
return true;
|
||
gb->banksize_mask = gfxb->banksize - 1;
|
||
gb->userdata = aci->userdata;
|
||
gb->active = true;
|
||
gb->rtg_index = aci->devnum;
|
||
gb->board = gfxb;
|
||
gfx_temp_bank_idx = aci->devnum;
|
||
gb->gfxmem_bank = aci->addrbank;
|
||
aci->addrbank = &gfx_temp_bank;
|
||
|
||
device_add_hsync(gfxboard_hsync_handler);
|
||
device_add_rethink(gfxboard_rethink);
|
||
|
||
return true;
|
||
}
|
||
|
||
static void vga_update_size_ext(struct rtggfxboard *gb)
|
||
{
|
||
if (!gb->pcemdev) {
|
||
// this forces qemu_console_resize() call
|
||
gb->vga.vga.graphic_mode = -1;
|
||
gb->vga.vga.monid = gb->monitor_id;
|
||
gb->vga.vga.hw_ops->gfx_update(&gb->vga);
|
||
}
|
||
}
|
||
|
||
static void gfxboard_set_fullrefresh(struct rtggfxboard *gb, int cnt)
|
||
{
|
||
gb->fullrefresh = cnt;
|
||
if (gb->func) {
|
||
gb->func->refresh(gb->userdata);
|
||
}
|
||
}
|
||
|
||
static bool gfxboard_setmode_ext(struct rtggfxboard *gb)
|
||
{
|
||
int bpp;
|
||
|
||
if (gb->pcemdev) {
|
||
bpp = 32;
|
||
} else {
|
||
bpp = gb->vga.vga.get_bpp(&gb->vga.vga);
|
||
if (bpp == 0)
|
||
bpp = 8;
|
||
vga_update_size_ext(gb);
|
||
}
|
||
if (gb->vga_width <= 16 || gb->vga_height <= 16)
|
||
return false;
|
||
struct gfxboard_mode mode;
|
||
mode.width = gb->vga_width;
|
||
mode.height = gb->vga_height;
|
||
mode.hlinedbl = gb->vga_width_mult ? gb->vga_width_mult : 1;
|
||
mode.vlinedbl = gb->vga_height_mult ? gb->vga_height_mult : 1;
|
||
mode.mode = RGBFB_NONE;
|
||
for (int i = 0; i < RGBFB_MaxFormats; i++) {
|
||
RGBFTYPE t = (RGBFTYPE)i;
|
||
if (GetBytesPerPixel(t) == bpp / 8) {
|
||
mode.mode = t;
|
||
break;
|
||
}
|
||
}
|
||
gfxboard_setmode(gb, &mode);
|
||
gfx_set_picasso_modeinfo(gb->monitor_id, mode.mode);
|
||
gfxboard_set_fullrefresh(gb, 2);
|
||
return true;
|
||
}
|
||
|
||
bool gfxboard_set(int monid, bool rtg)
|
||
{
|
||
bool r;
|
||
struct amigadisplay *ad = &adisplays[monid];
|
||
r = ad->picasso_on;
|
||
if (rtg) {
|
||
ad->picasso_requested_on = 1;
|
||
} else {
|
||
ad->picasso_requested_on = 0;
|
||
}
|
||
set_config_changed();
|
||
return r;
|
||
}
|
||
|
||
void gfxboard_rtg_disable(int monid, int index)
|
||
{
|
||
if (monid > 0)
|
||
return;
|
||
if (index == rtg_visible[monid] && rtg_visible[monid] >= 0) {
|
||
struct rtggfxboard *gb = &rtggfxboards[index];
|
||
if (rtg_visible[monid] >= 0 && gb->func) {
|
||
gb->func->toggle(gb->userdata, 0);
|
||
}
|
||
rtg_visible[monid] = -1;
|
||
}
|
||
}
|
||
|
||
bool gfxboard_rtg_enable_initial(int monid, int index)
|
||
{
|
||
struct amigadisplay *ad = &adisplays[monid];
|
||
// if some RTG already enabled and located in monitor 0, don't override
|
||
if ((rtg_visible[monid] >= 0 || rtg_initial[monid] >= 0) && !monid)
|
||
return false;
|
||
if (ad->picasso_on)
|
||
return false;
|
||
rtg_initial[monid] = index;
|
||
gfxboard_toggle(monid, index, false);
|
||
// check_prefs_picasso() calls gfxboard_toggle when ready
|
||
return true;
|
||
}
|
||
|
||
bool gfxboard_switch_away(int monid)
|
||
{
|
||
if (!monid) {
|
||
struct amigadisplay *ad = &adisplays[monid];
|
||
if (ad->picasso_requested_on) {
|
||
ad->picasso_requested_on = false;
|
||
set_config_changed();
|
||
}
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
int gfxboard_toggle(int monid, int index, int log)
|
||
{
|
||
bool initial = false;
|
||
struct rtggfxboard *gb;
|
||
|
||
if (rtg_visible[monid] < 0 && rtg_initial[monid] >= 0 && rtg_initial[monid] < MAX_RTG_BOARDS) {
|
||
index = rtg_initial[monid];
|
||
initial = true;
|
||
}
|
||
|
||
gfxboard_rtg_disable(monid, rtg_visible[monid]);
|
||
|
||
rtg_visible[monid] = -1;
|
||
|
||
if (index < 0)
|
||
goto end;
|
||
|
||
gb = &rtggfxboards[index];
|
||
if (!gb->active)
|
||
goto end;
|
||
|
||
if (gb->func) {
|
||
bool r = gb->func->toggle(gb->userdata, 1);
|
||
if (r) {
|
||
rtg_initial[monid] = MAX_RTG_BOARDS;
|
||
rtg_visible[monid] = gb->rtg_index;
|
||
if (log && !monid)
|
||
statusline_add_message(STATUSTYPE_DISPLAY, _T("RTG %d: %s"), index + 1, gb->board->name);
|
||
return index;
|
||
}
|
||
goto end;
|
||
}
|
||
|
||
if (gb->vram == NULL)
|
||
return -1;
|
||
vga_update_size_ext(gb);
|
||
if (gb->vga_width > 16 && gb->vga_height > 16) {
|
||
if (!gfxboard_setmode_ext(gb))
|
||
goto end;
|
||
rtg_initial[monid] = MAX_RTG_BOARDS;
|
||
rtg_visible[monid] = gb->rtg_index;
|
||
gb->monswitch_new = true;
|
||
gb->monswitch_delay = 1;
|
||
if (log && !monid)
|
||
statusline_add_message(STATUSTYPE_DISPLAY, _T("RTG %d: %s"), index + 1, gb->board->name);
|
||
return index;
|
||
}
|
||
end:
|
||
if (initial) {
|
||
rtg_initial[monid] = -1;
|
||
return -2;
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
static bool gfxboard_checkchanged(struct rtggfxboard *gb)
|
||
{
|
||
struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id];
|
||
int bpp;
|
||
if (gb->pcemdev) {
|
||
bpp = 32;
|
||
} else {
|
||
bpp = gb->vga.vga.get_bpp(&gb->vga.vga);
|
||
if (bpp == 0)
|
||
bpp = 8;
|
||
}
|
||
if (gb->vga_width <= 16 || gb->vga_height <= 16)
|
||
return false;
|
||
if (state->Width != gb->vga_width ||
|
||
state->Height != gb->vga_height ||
|
||
state->BytesPerPixel != bpp / 8)
|
||
return true;
|
||
return false;
|
||
}
|
||
|
||
DisplaySurface *qemu_console_surface(QemuConsole *con)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)con;
|
||
return &gb->gfxsurface;
|
||
}
|
||
|
||
void gfxboard_resize(int width, int height, int hmult, int vmult, void *p)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard *)p;
|
||
if (width != gb->vga_width || gb->vga_height != height) {
|
||
gb->resolutionchange = 5;
|
||
}
|
||
gb->vga_width = width;
|
||
gb->vga_height = height;
|
||
gb->vga_width_mult = hmult;
|
||
gb->vga_height_mult = vmult;
|
||
}
|
||
|
||
void qemu_console_resize(QemuConsole *con, int width, int height)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard *)con;
|
||
if (width != gb->vga_width || gb->vga_height != height) {
|
||
gb->resolutionchange = 5;
|
||
}
|
||
gb->vga_width = width;
|
||
gb->vga_height = height;
|
||
gb->vga_width_mult = 1;
|
||
gb->vga_height_mult = 1;
|
||
}
|
||
|
||
void linear_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
|
||
{
|
||
}
|
||
|
||
void vga_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (gb->vga.vga.graphic_mode != 1)
|
||
return;
|
||
if (!gb->fullrefresh) {
|
||
gfxboard_set_fullrefresh(gb, 1);
|
||
}
|
||
}
|
||
|
||
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
|
||
int linesize, uint8_t *data,
|
||
bool byteswap)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (data >= gb->vram && data < gb->vramend) {
|
||
struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id];
|
||
state->XYOffset = (int)((gb->vram - data) + gfxmem_banks[gb->rtg_index]->start);
|
||
gb->resolutionchange = 1;
|
||
return &gb->fakesurface;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
int surface_bits_per_pixel(DisplaySurface *s)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
|
||
if (rtg_visible[gb->monitor_id] < 0)
|
||
return 32;
|
||
if (s == &gb->fakesurface)
|
||
return 32;
|
||
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id];
|
||
return vidinfo->pixbytes * 8;
|
||
}
|
||
int surface_bytes_per_pixel(DisplaySurface *s)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
|
||
if (rtg_visible[gb->monitor_id] < 0)
|
||
return 4;
|
||
if (s == &gb->fakesurface)
|
||
return 4;
|
||
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id];
|
||
return vidinfo->pixbytes;
|
||
}
|
||
|
||
int surface_stride(DisplaySurface *s)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
|
||
if (rtg_visible[gb->monitor_id] < 0)
|
||
return 0;
|
||
if (s == &gb->fakesurface || !gb->vga_refresh_active)
|
||
return 0;
|
||
if (gb->gfxboard_surface == NULL)
|
||
gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false);
|
||
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[gb->monitor_id];
|
||
return vidinfo->rowbytes;
|
||
}
|
||
uint8_t *surface_data(DisplaySurface *s)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)s->data;
|
||
if (!gb)
|
||
return NULL;
|
||
if (rtg_visible[gb->monitor_id] < 0)
|
||
return NULL;
|
||
if (gb->resolutionchange)
|
||
return NULL;
|
||
if (s == &gb->fakesurface || !gb->vga_refresh_active)
|
||
return gb->fakesurface_surface;
|
||
if (gb->gfxboard_surface == NULL)
|
||
gb->gfxboard_surface = gfx_lock_picasso(gb->monitor_id, false);
|
||
return gb->gfxboard_surface;
|
||
}
|
||
|
||
void gfxboard_refresh(int monid)
|
||
{
|
||
if (monid >= 0) {
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtgboardconfig *rbc = &currprefs.rtgboards[i];
|
||
if (rbc->monitor_id == monid && rbc->rtgmem_size) {
|
||
if (rbc->rtgmem_type >= GFXBOARD_HARDWARE) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
gfxboard_set_fullrefresh(gb, 2);
|
||
} else {
|
||
picasso_refresh(monid);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtgboardconfig *rbc = &currprefs.rtgboards[i];
|
||
if (rbc->rtgmem_size) {
|
||
gfxboard_refresh(rbc->monitor_id);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
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) {
|
||
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();
|
||
}
|
||
|
||
void gfxboard_vsync_handler(bool full_redraw_required, bool redraw_required)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
struct amigadisplay *ad = &adisplays[gb->monitor_id];
|
||
struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id];
|
||
|
||
if (gb->func) {
|
||
|
||
if (gb->userdata) {
|
||
struct gfxboard_mode mode = { 0 };
|
||
mode.redraw_required = full_redraw_required;
|
||
gb->func->vsync(gb->userdata, &mode);
|
||
if (mode.mode && mode.width && mode.height) {
|
||
if (state->Width != mode.width ||
|
||
state->Height != mode.height ||
|
||
state->RGBFormat != mode.mode ||
|
||
!ad->picasso_on) {
|
||
if (mode.width && mode.height && mode.mode) {
|
||
gfxboard_setmode(gb, &mode);
|
||
gfx_set_picasso_modeinfo(gb->monitor_id, mode.mode);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
} else if (gb->configured_mem > 0 && gb->configured_regs > 0) {
|
||
|
||
if (gb->pcemdev) {
|
||
static int fcount;
|
||
if (!gb->pcem_vblank && gb->pcemobject2) {
|
||
int max = svga_get_vtotal(gb->pcemobject2);
|
||
while (max-- > 0) {
|
||
if (gfxboard_pcem_poll(gb))
|
||
break;
|
||
}
|
||
}
|
||
gb->pcem_vblank = 0;
|
||
extern int console_logging;
|
||
if (console_logging) {
|
||
fcount++;
|
||
if ((fcount % 50) == 0) {
|
||
if (gb->pcemobject && gb->pcemdev->add_status_info) {
|
||
char txt[1024];
|
||
txt[0] = 0;
|
||
gb->pcemdev->add_status_info(txt, sizeof(txt), gb->pcemobject);
|
||
TCHAR *s = au(txt);
|
||
write_log(_T("%s"), s);
|
||
xfree(s);
|
||
}
|
||
}
|
||
}
|
||
if (gb->board->pci && gb->vram) {
|
||
bool svga_on(void *p);
|
||
bool on = svga_on(gb->pcemobject2);
|
||
set_monswitch(gb, on);
|
||
}
|
||
}
|
||
|
||
if (gb->monswitch_keep_trying) {
|
||
vga_update_size_ext(gb);
|
||
if (gb->vga_width > 16 && gb->vga_height > 16) {
|
||
gb->monswitch_keep_trying = false;
|
||
gb->monswitch_new = true;
|
||
gb->monswitch_delay = 0;
|
||
}
|
||
}
|
||
|
||
if (gb->monswitch_new != gb->monswitch_current) {
|
||
if (gb->monswitch_delay > 0)
|
||
gb->monswitch_delay--;
|
||
if (gb->monswitch_delay == 0) {
|
||
if (!gb->monswitch_new && rtg_visible[gb->monitor_id] == i) {
|
||
gfxboard_rtg_disable(gb->monitor_id, i);
|
||
}
|
||
gb->monswitch_current = gb->monswitch_new;
|
||
vga_update_size_ext(gb);
|
||
write_log(_T("GFXBOARD %d MONITOR=%d ACTIVE=%d\n"), i, gb->monitor_id, gb->monswitch_current);
|
||
if (gb->monitor_id > 0) {
|
||
if (gb->monswitch_new)
|
||
gfxboard_toggle(gb->monitor_id, i, 0);
|
||
} else {
|
||
if (gb->monswitch_current) {
|
||
if (!gfxboard_rtg_enable_initial(gb->monitor_id, i)) {
|
||
// Nothing visible? Re-enable our display.
|
||
if (rtg_visible[gb->monitor_id] < 0) {
|
||
gfxboard_toggle(gb->monitor_id, i, 0);
|
||
}
|
||
}
|
||
} else {
|
||
gfxboard_switch_away(gb->monitor_id);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
gb->monswitch_delay = 0;
|
||
}
|
||
// Vertical Sync End Register, 0x20 = Disable Vertical Interrupt, 0x10 = Clear Vertical Interrupt.
|
||
if (!gb->pcemdev && gb->board->irq) {
|
||
if ((!(gb->vga.vga.cr[0x11] & 0x20) && (gb->vga.vga.cr[0x11] & 0x10) && !(gb->vga.vga.gr[0x17] & 4))) {
|
||
if (gb->gfxboard_intena) {
|
||
gb->gfxboard_intreq = true;
|
||
//write_log(_T("VGA interrupt %d\n"), gb->board->irq);
|
||
if (gb->board->irq == 2)
|
||
INTREQ(0x8000 | 0x0008);
|
||
else
|
||
INTREQ(0x8000 | 0x2000);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
struct amigadisplay *ad = &adisplays[gb->monitor_id];
|
||
struct picasso96_state_struct *state = &picasso96_state[gb->monitor_id];
|
||
|
||
if (gb->monitor_id == 0) {
|
||
// if default monitor: show rtg_visible
|
||
if (rtg_visible[gb->monitor_id] < 0)
|
||
continue;
|
||
if (i != rtg_visible[gb->monitor_id])
|
||
continue;
|
||
}
|
||
|
||
if (gb->configured_mem <= 0 || gb->configured_regs <= 0)
|
||
continue;
|
||
|
||
if (gb->monswitch_current && gb->resolutionchange) {
|
||
if (gb->resolutionchange == 1) {
|
||
gb->resolutionchange = 0;
|
||
if (gfxboard_checkchanged(gb)) {
|
||
if (!gfxboard_setmode_ext(gb)) {
|
||
gfxboard_rtg_disable(gb->monitor_id, i);
|
||
}
|
||
}
|
||
} else if (gb->resolutionchange > 1) {
|
||
gb->resolutionchange--;
|
||
}
|
||
continue;
|
||
}
|
||
|
||
if (!redraw_required)
|
||
continue;
|
||
|
||
if (!gb->monswitch_delay && gb->monswitch_current && ad->picasso_on && ad->picasso_requested_on && !gb->resolutionchange) {
|
||
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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (ad->picasso_on && !gb->resolutionchange) {
|
||
if (gb->fullrefresh > 0)
|
||
gb->fullrefresh--;
|
||
}
|
||
gfxboard_unlock(gb);
|
||
}
|
||
}
|
||
|
||
double gfxboard_get_vsync (void)
|
||
{
|
||
return vblank_hz; // FIXME
|
||
}
|
||
|
||
void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h)
|
||
{
|
||
picasso_invalidate(0, x, y, w, h);
|
||
}
|
||
|
||
void memory_region_init_alias(MemoryRegion *mr,
|
||
const char *name,
|
||
MemoryRegion *orig,
|
||
hwaddr offset,
|
||
uint64_t size)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (!stricmp(name, "vga.bank0")) {
|
||
mr->opaque = &gb->vgabank0regionptr;
|
||
} else if (!stricmp(name, "vga.bank1")) {
|
||
mr->opaque = &gb->vgabank1regionptr;
|
||
}
|
||
}
|
||
|
||
static void jit_reset (void)
|
||
{
|
||
#ifdef JIT
|
||
if (currprefs.cachesize && (!currprefs.comptrustbyte || !currprefs.comptrustword || !currprefs.comptrustlong)) {
|
||
flush_icache (3);
|
||
}
|
||
#endif
|
||
}
|
||
|
||
static void remap_vram (struct rtggfxboard *gb, hwaddr offset0, hwaddr offset1, bool enabled)
|
||
{
|
||
jit_reset ();
|
||
gb->vram_offset[0] = offset0;
|
||
gb->vram_offset[1] = offset1;
|
||
#if VRAMLOG
|
||
if (gb->vram_enabled != enabled)
|
||
write_log (_T("VRAM state=%d\n"), enabled);
|
||
bool was_vram_offset_enabled = gb->vram_offset_enabled;
|
||
#endif
|
||
gb->vram_enabled = enabled && (gb->vga.vga.sr[0x07] & 0x01);
|
||
#if 0
|
||
vram_enabled = false;
|
||
#endif
|
||
// offset==0 and offset1==0x8000: linear vram mapping
|
||
gb->vram_offset_enabled = offset0 != 0 || offset1 != 0x8000;
|
||
#if VRAMLOG
|
||
if (gb->vram_offset_enabled || was_vram_offset_enabled)
|
||
write_log (_T("VRAM offset %08x and %08x\n"), offset0, offset1);
|
||
#endif
|
||
}
|
||
|
||
void memory_region_set_alias_offset(MemoryRegion *mr, hwaddr offset)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (mr->opaque == &gb->vgabank0regionptr) {
|
||
if (offset != gb->vram_offset[0]) {
|
||
//write_log (_T("vgavramregion0 %08x\n"), offset);
|
||
remap_vram (gb, offset, gb->vram_offset[1], gb->vram_enabled);
|
||
}
|
||
} else if (mr->opaque == &gb->vgabank1regionptr) {
|
||
if (offset != gb->vram_offset[1]) {
|
||
//write_log (_T("vgavramregion1 %08x\n"), offset);
|
||
remap_vram (gb, gb->vram_offset[0], offset, gb->vram_enabled);
|
||
}
|
||
} else if (mr->opaque == &gb->vgaioregionptr) {
|
||
write_log (_T("vgaioregion %d\n"), offset);
|
||
} else {
|
||
write_log (_T("unknown region %d\n"), offset);
|
||
}
|
||
|
||
}
|
||
void memory_region_set_enabled(MemoryRegion *mr, bool enabled)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (mr->opaque == &gb->vgabank0regionptr || mr->opaque == &gb->vgabank1regionptr) {
|
||
if (enabled != gb->vram_enabled) {
|
||
//write_log (_T("enable vgavramregion %d\n"), enabled);
|
||
remap_vram (gb, gb->vram_offset[0], gb->vram_offset[1], enabled);
|
||
}
|
||
} else if (mr->opaque == &gb->vgaioregionptr) {
|
||
write_log (_T("enable vgaioregion %d\n"), enabled);
|
||
} else {
|
||
write_log (_T("enable unknown region %d\n"), enabled);
|
||
}
|
||
}
|
||
void memory_region_reset_dirty(MemoryRegion *mr, hwaddr addr,
|
||
hwaddr size, unsigned client)
|
||
{
|
||
//write_log (_T("memory_region_reset_dirty %08x %08x\n"), addr, size);
|
||
}
|
||
bool memory_region_get_dirty(MemoryRegion *mr, hwaddr addr,
|
||
hwaddr size, unsigned client)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (mr->opaque != &gb->vgavramregionptr)
|
||
return false;
|
||
//write_log (_T("memory_region_get_dirty %08x %08x\n"), addr, size);
|
||
if (gb->fullrefresh)
|
||
return true;
|
||
return picasso_is_vram_dirty (gb->rtg_index, addr + gb->gfxmem_bank->start, size);
|
||
}
|
||
|
||
static QEMUResetHandler *reset_func;
|
||
static void *reset_parm;
|
||
void qemu_register_reset(QEMUResetHandler *func, void *opaque)
|
||
{
|
||
reset_func = func;
|
||
reset_parm = opaque;
|
||
reset_func (reset_parm);
|
||
}
|
||
|
||
static void p4_pci_check (struct rtggfxboard *gb)
|
||
{
|
||
uaecptr b0, b1;
|
||
|
||
b0 = gb->p4_pci[0x10 + 2] << 16;
|
||
b1 = gb->p4_pci[0x14 + 2] << 16;
|
||
|
||
gb->p4_vram_bank[0] = b0;
|
||
gb->p4_vram_bank[1] = b1;
|
||
|
||
// write_log (_T("%08X %08X\n"), gb->p4_vram_bank[0], gb->p4_vram_bank[1]);
|
||
}
|
||
|
||
static void reset_pci (struct rtggfxboard *gb)
|
||
{
|
||
gb->cirrus_pci[0] = 0x00;
|
||
gb->cirrus_pci[1] = 0xb8;
|
||
gb->cirrus_pci[2] = 0x10;
|
||
gb->cirrus_pci[3] = 0x13;
|
||
|
||
gb->cirrus_pci[4] = 2;
|
||
gb->cirrus_pci[5] = 0;
|
||
gb->cirrus_pci[6] = 0;
|
||
gb->cirrus_pci[7] &= ~(1 | 2 | 32);
|
||
|
||
gb->cirrus_pci[8] = 3;
|
||
gb->cirrus_pci[9] = 0;
|
||
gb->cirrus_pci[10] = 0;
|
||
gb->cirrus_pci[11] = 68;
|
||
|
||
gb->cirrus_pci[0x10] &= ~1; // B revision
|
||
gb->cirrus_pci[0x13] &= ~1; // memory
|
||
|
||
gb->p4i2c = 0xff;
|
||
}
|
||
|
||
static void picassoiv_checkswitch (struct rtggfxboard *gb)
|
||
{
|
||
if (ISP4()) {
|
||
uae_u8 v = 0;
|
||
bool rtg_active = (gb->picassoiv_flifi & 1) == 0;
|
||
if (gb->pcemdev) {
|
||
if (gb->pcemobject) {
|
||
extern uae_u8 pcem_read_io(int, int);
|
||
v = pcem_read_io(0x3d5, 0x51);
|
||
}
|
||
} else {
|
||
v = gb->vga.vga.cr[0x51];
|
||
}
|
||
if (!(v & 8))
|
||
rtg_active = true;
|
||
// do not switch to P4 RTG until monitor switch is set to native at least
|
||
// once after reset.
|
||
if (gb->monswitch_reset && rtg_active)
|
||
return;
|
||
set_monswitch(gb, rtg_active);
|
||
gb->monswitch_reset = false;
|
||
}
|
||
}
|
||
|
||
static void bput_regtest (struct rtggfxboard *gb, uaecptr addr, uae_u8 v)
|
||
{
|
||
addr += 0x3b0;
|
||
if (addr == 0x3d5) { // CRxx
|
||
if (gb->vga.vga.cr_index == 0x11) {
|
||
if (!(gb->vga.vga.cr[0x11] & 0x10)) {
|
||
gb->gfxboard_intreq = false;
|
||
}
|
||
}
|
||
}
|
||
if (!(gb->vga.vga.sr[0x07] & 0x01) && gb->vram_enabled) {
|
||
remap_vram (gb, gb->vram_offset[0], gb->vram_offset[1], false);
|
||
}
|
||
picassoiv_checkswitch (gb);
|
||
}
|
||
|
||
static uae_u8 bget_regtest (struct rtggfxboard *gb, uaecptr addr, uae_u8 v)
|
||
{
|
||
addr += 0x3b0;
|
||
// Input Status 0
|
||
if (addr == 0x3c2) {
|
||
if (gb->gfxboard_intreq) {
|
||
// Disable Vertical Interrupt == 0?
|
||
// Clear Vertical Interrupt == 1
|
||
// GR17 bit 2 = INTR disable
|
||
if (!(gb->vga.vga.cr[0x11] & 0x20) && (gb->vga.vga.cr[0x11] & 0x10) && !(gb->vga.vga.gr[0x17] & 4)) {
|
||
v |= 0x80; // VGA Interrupt Pending
|
||
}
|
||
}
|
||
v |= 0x10; // DAC sensing
|
||
}
|
||
if (addr == 0x3c5) {
|
||
if (gb->vga.vga.sr_index == 8) {
|
||
// TODO: DDC
|
||
}
|
||
}
|
||
return v;
|
||
}
|
||
|
||
void vga_io_put(int board, int portnum, uae_u8 v)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[board];
|
||
if (!gb->vgaio)
|
||
return;
|
||
portnum -= 0x3b0;
|
||
bput_regtest(gb, portnum, v);
|
||
gb->vgaio->write(&gb->vga, portnum, v, 1);
|
||
}
|
||
uae_u8 vga_io_get(int board, int portnum)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[board];
|
||
uae_u8 v = 0xff;
|
||
if (!gb->vgaio)
|
||
return v;
|
||
portnum -= 0x3b0;
|
||
v = (uae_u8)gb->vgaio->read(&gb->vga, portnum, 1);
|
||
v = bget_regtest(gb, portnum, v);
|
||
return v;
|
||
}
|
||
void vga_ram_put(int board, int offset, uae_u8 v)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[board];
|
||
if (!gb->vgalowram)
|
||
return;
|
||
offset -= 0xa0000;
|
||
gb->vgalowram->write(&gb->vga, offset, v, 1);
|
||
}
|
||
uae_u8 vga_ram_get(int board, int offset)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[board];
|
||
if (!gb->vgalowram)
|
||
return 0xff;
|
||
offset -= 0xa0000;
|
||
return (uae_u8)gb->vgalowram->read(&gb->vga, offset, 1);
|
||
}
|
||
void vgalfb_ram_put(int board, int offset, uae_u8 v)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[board];
|
||
if (!gb->vgaram)
|
||
return;
|
||
gb->vgaram->write(&gb->vga, offset, v, 1);
|
||
}
|
||
uae_u8 vgalfb_ram_get(int board, int offset)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[board];
|
||
if (!gb->vgaram)
|
||
return 0xff;
|
||
return (uae_u8)gb->vgaram->read(&gb->vga, offset, 1);
|
||
}
|
||
|
||
void *memory_region_get_ram_ptr(MemoryRegion *mr)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (mr->opaque == &gb->vgavramregionptr)
|
||
return gb->vram;
|
||
return NULL;
|
||
}
|
||
|
||
void memory_region_init_ram(MemoryRegion *mr,
|
||
const char *name,
|
||
uint64_t size)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (!stricmp (name, "vga.vram")) {
|
||
gb->vgavramregion.opaque = mr->opaque;
|
||
}
|
||
}
|
||
|
||
void memory_region_init_io(MemoryRegion *mr,
|
||
const MemoryRegionOps *ops,
|
||
void *opaque,
|
||
const char *name,
|
||
uint64_t size)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)mr->data;
|
||
if (!stricmp (name, "cirrus-io")) {
|
||
gb->vgaio = ops;
|
||
mr->opaque = gb->vgaioregion.opaque;
|
||
} else if (!stricmp (name, "cirrus-linear-io")) {
|
||
gb->vgaram = ops;
|
||
} else if (!stricmp (name, "cirrus-low-memory")) {
|
||
gb->vgalowram = ops;
|
||
} else if (!stricmp (name, "cirrus-mmio")) {
|
||
gb->vgammio = ops;
|
||
}
|
||
}
|
||
|
||
int is_surface_bgr(DisplaySurface *surface)
|
||
{
|
||
if (!surface || !surface->data)
|
||
return 0;
|
||
struct rtggfxboard *gb = (struct rtggfxboard*)surface->data;
|
||
return gb->board->swap;
|
||
}
|
||
|
||
static uaecptr fixaddr_bs (struct rtggfxboard *gb, uaecptr addr, int mask, int *bs)
|
||
{
|
||
bool swapped = false;
|
||
addr &= gb->gfxmem_bank->mask;
|
||
if (gb->p4z2) {
|
||
if (addr < 0x200000) {
|
||
addr |= gb->p4_vram_bank[0];
|
||
if (addr >= 0x400000 && addr < 0x600000) {
|
||
*bs = BYTESWAP_WORD;
|
||
swapped = true;
|
||
} else if (addr >= 0x800000 && addr < 0xa00000) {
|
||
*bs = BYTESWAP_LONG;
|
||
swapped = true;
|
||
}
|
||
} else {
|
||
addr |= gb->p4_vram_bank[1];
|
||
if (addr >= 0x600000 && addr < 0x800000) {
|
||
*bs = BYTESWAP_WORD;
|
||
swapped = true;
|
||
} else if (addr >= 0xa00000 && addr < 0xc00000) {
|
||
*bs = BYTESWAP_LONG;
|
||
swapped = true;
|
||
}
|
||
}
|
||
}
|
||
#ifdef JIT
|
||
if (mask && (gb->vram_offset_enabled || !gb->vram_enabled || swapped || gb->p4z2))
|
||
special_mem |= mask;
|
||
#endif
|
||
if (gb->vram_offset_enabled) {
|
||
if (addr & 0x8000) {
|
||
addr += gb->vram_offset[1] & ~0x8000;
|
||
} else {
|
||
addr += gb->vram_offset[0];
|
||
}
|
||
}
|
||
addr &= gb->gfxmem_bank->mask;
|
||
return addr;
|
||
}
|
||
|
||
STATIC_INLINE uaecptr fixaddr (struct rtggfxboard *gb, uaecptr addr, int mask)
|
||
{
|
||
#ifdef JIT
|
||
if (mask && (gb->vram_offset_enabled || !gb->vram_enabled))
|
||
special_mem |= mask;
|
||
#endif
|
||
if (gb->vram_offset_enabled) {
|
||
if (addr & 0x8000) {
|
||
addr += gb->vram_offset[1] & ~0x8000;
|
||
} else {
|
||
addr += gb->vram_offset[0];
|
||
}
|
||
}
|
||
addr &= gb->gfxmem_bank->mask;
|
||
return addr;
|
||
}
|
||
|
||
STATIC_INLINE uaecptr fixaddr (struct rtggfxboard *gb, uaecptr addr)
|
||
{
|
||
if (gb->vram_offset_enabled) {
|
||
if (addr & 0x8000) {
|
||
addr += gb->vram_offset[1] & ~0x8000;
|
||
} else {
|
||
addr += gb->vram_offset[0];
|
||
}
|
||
}
|
||
addr &= gb->gfxmem_bank->mask;
|
||
return addr;
|
||
}
|
||
|
||
STATIC_INLINE const MemoryRegionOps *getvgabank (struct rtggfxboard *gb, uaecptr *paddr)
|
||
{
|
||
uaecptr addr = *paddr;
|
||
addr &= gb->gfxmem_bank->mask;
|
||
*paddr = addr;
|
||
return gb->vgaram;
|
||
}
|
||
|
||
static uae_u32 gfxboard_lget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
|
||
{
|
||
uae_u32 v;
|
||
if (!gb->vram_enabled) {
|
||
const MemoryRegionOps *bank = getvgabank(gb, &addr);
|
||
if (bs < 0) { // WORD
|
||
v = ((uae_u8)bank->read(&gb->vga, addr + 1, 1)) << 24;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 0, 1)) << 16;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 3, 1)) << 8;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 2, 1)) << 0;
|
||
} else if (bs > 0) { // LONG
|
||
v = ((uae_u8)bank->read(&gb->vga, addr + 3, 1)) << 24;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 2, 1)) << 16;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 1, 1)) << 8;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 0, 1)) << 0;
|
||
} else {
|
||
v = ((uae_u8)bank->read(&gb->vga, addr + 0, 1)) << 24;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 1, 1)) << 16;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 2, 1)) << 8;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 3, 1)) << 0;
|
||
}
|
||
} else {
|
||
uae_u8 *m = gb->vram + addr;
|
||
if (bs < 0) {
|
||
v = (*((uae_u16*)(m + 0))) << 16;
|
||
v |= (*((uae_u16*)(m + 2))) << 0;
|
||
} else if (bs > 0) {
|
||
v = *((uae_u32*)m);
|
||
} else {
|
||
v = do_get_mem_long((uae_u32*)m);
|
||
}
|
||
}
|
||
#if MEMLOGR
|
||
#if MEMLOGINDIRECT
|
||
if (!vram_enabled || vram_offset_enabled)
|
||
#endif
|
||
if (memlogr)
|
||
write_log (_T("R %08X L %08X BS=%d EN=%d\n"), addr, v, bs, gb->vram_enabled);
|
||
#endif
|
||
return v;
|
||
}
|
||
static uae_u16 gfxboard_wget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
|
||
{
|
||
uae_u32 v;
|
||
if (!gb->vram_enabled) {
|
||
const MemoryRegionOps *bank = getvgabank (gb, &addr);
|
||
if (bs) {
|
||
v = ((uae_u8)bank->read(&gb->vga, addr + 0, 1)) << 0;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 1, 1)) << 8;
|
||
} else {
|
||
v = ((uae_u8)bank->read(&gb->vga, addr + 0, 1)) << 8;
|
||
v |= ((uae_u8)bank->read(&gb->vga, addr + 1, 1)) << 0;
|
||
}
|
||
} else {
|
||
uae_u8 *m = gb->vram + addr;
|
||
if (bs)
|
||
v = *((uae_u16*)m);
|
||
else
|
||
v = do_get_mem_word ((uae_u16*)m);
|
||
}
|
||
#if MEMLOGR
|
||
#if MEMLOGINDIRECT
|
||
if (!vram_enabled || vram_offset_enabled)
|
||
#endif
|
||
if (memlogr)
|
||
write_log (_T("R %08X W %08X BS=%d EN=%d\n"), addr, v, bs, gb->vram_enabled);
|
||
#endif
|
||
return v;
|
||
}
|
||
static uae_u8 gfxboard_bget_vram (struct rtggfxboard *gb, uaecptr addr, int bs)
|
||
{
|
||
uae_u32 v;
|
||
if (!gb->vram_enabled) {
|
||
const MemoryRegionOps *bank = getvgabank (gb, &addr);
|
||
if (bs)
|
||
v = (uae_u8)bank->read(&gb->vga, addr ^ 1, 1);
|
||
else
|
||
v = (uae_u8)bank->read(&gb->vga, addr + 0, 1);
|
||
} else {
|
||
if (bs)
|
||
v = gb->vram[addr ^ 1];
|
||
else
|
||
v = gb->vram[addr];
|
||
}
|
||
#if MEMLOGR
|
||
#if MEMLOGINDIRECT
|
||
if (!vram_enabled || vram_offset_enabled)
|
||
#endif
|
||
if (memlogr)
|
||
write_log (_T("R %08X B %08X BS=0 EN=%d\n"), addr, v, gb->vram_enabled);
|
||
#endif
|
||
return v;
|
||
}
|
||
|
||
static void gfxboard_lput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u32 l, int bs)
|
||
{
|
||
#if MEMDEBUG
|
||
if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && (MEMDEBUGCLEAR || l))
|
||
write_log (_T("%08X L %08X %08X\n"), addr, l, M68K_GETPC);
|
||
#endif
|
||
#if MEMLOGW
|
||
#if MEMLOGINDIRECT
|
||
if (!vram_enabled || vram_offset_enabled)
|
||
#endif
|
||
if (memlogw)
|
||
write_log (_T("W %08X L %08X\n"), addr, l);
|
||
#endif
|
||
if (!gb->vram_enabled) {
|
||
const MemoryRegionOps *bank = getvgabank (gb, &addr);
|
||
if (bs < 0) { // WORD
|
||
bank->write (&gb->vga, addr + 1, l >> 24, 1);
|
||
bank->write (&gb->vga, addr + 0, (l >> 16) & 0xff, 1);
|
||
bank->write (&gb->vga, addr + 3, (l >> 8) & 0xff, 1);
|
||
bank->write (&gb->vga, addr + 2, (l >> 0) & 0xff, 1);
|
||
} else if (bs > 0) { // LONG
|
||
bank->write (&gb->vga, addr + 3, l >> 24, 1);
|
||
bank->write (&gb->vga, addr + 2, (l >> 16) & 0xff, 1);
|
||
bank->write (&gb->vga, addr + 1, (l >> 8) & 0xff, 1);
|
||
bank->write (&gb->vga, addr + 0, (l >> 0) & 0xff, 1);
|
||
} else {
|
||
bank->write (&gb->vga, addr + 0, l >> 24, 1);
|
||
bank->write (&gb->vga, addr + 1, (l >> 16) & 0xff, 1);
|
||
bank->write (&gb->vga, addr + 2, (l >> 8) & 0xff, 1);
|
||
bank->write (&gb->vga, addr + 3, (l >> 0) & 0xff, 1);
|
||
}
|
||
} else {
|
||
uae_u8 *m = gb->vram + addr;
|
||
if (bs < 0) {
|
||
*((uae_u16*)(m + 0)) = l >> 16;
|
||
*((uae_u16*)(m + 2)) = l >> 0;
|
||
} else if (bs > 0) {
|
||
*((uae_u32*)m) = l;
|
||
} else {
|
||
do_put_mem_long ((uae_u32*) m, l);
|
||
}
|
||
}
|
||
}
|
||
static void gfxboard_wput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u16 w, int bs)
|
||
{
|
||
#if MEMDEBUG
|
||
if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && (MEMDEBUGCLEAR || w))
|
||
write_log (_T("%08X W %04X %08X\n"), addr, w & 0xffff, M68K_GETPC);
|
||
#endif
|
||
#if MEMLOGW
|
||
#if MEMLOGINDIRECT
|
||
if (!vram_enabled || vram_offset_enabled)
|
||
#endif
|
||
if (memlogw)
|
||
write_log (_T("W %08X W %04X\n"), addr, w & 0xffff);
|
||
#endif
|
||
if (!gb->vram_enabled) {
|
||
const MemoryRegionOps *bank = getvgabank (gb, &addr);
|
||
if (bs) {
|
||
bank->write(&gb->vga, addr + 0, (w >> 0) & 0xff, 1);
|
||
bank->write(&gb->vga, addr + 1, w >> 8, 1);
|
||
} else {
|
||
bank->write(&gb->vga, addr + 0, w >> 8, 1);
|
||
bank->write(&gb->vga, addr + 1, (w >> 0) & 0xff, 1);
|
||
}
|
||
} else {
|
||
uae_u8 *m = gb->vram + addr;
|
||
if (bs)
|
||
*((uae_u16*)m) = w;
|
||
else
|
||
do_put_mem_word ((uae_u16*)m, w);
|
||
}
|
||
}
|
||
static void gfxboard_bput_vram (struct rtggfxboard *gb, uaecptr addr, uae_u8 b, int bs)
|
||
{
|
||
#if MEMDEBUG
|
||
if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && (MEMDEBUGCLEAR || b))
|
||
write_log (_T("%08X B %02X %08X\n"), addr, b & 0xff, M68K_GETPC);
|
||
#endif
|
||
#if MEMLOGW
|
||
#if MEMLOGINDIRECT
|
||
if (!vram_enabled || vram_offset_enabled)
|
||
#endif
|
||
if (memlogw)
|
||
write_log (_T("W %08X B %02X\n"), addr, b & 0xff);
|
||
#endif
|
||
if (!gb->vram_enabled) {
|
||
const MemoryRegionOps *bank = getvgabank (gb, &addr);
|
||
#ifdef JIT
|
||
special_mem |= S_WRITE;
|
||
#endif
|
||
if (bs)
|
||
bank->write(&gb->vga, addr ^ 1, b, 1);
|
||
else
|
||
bank->write(&gb->vga, addr, b, 1);
|
||
} else {
|
||
if (bs)
|
||
gb->vram[addr ^ 1] = b;
|
||
else
|
||
gb->vram[addr] = b;
|
||
}
|
||
}
|
||
|
||
static struct rtggfxboard *lastgetgfxboard;
|
||
static rtggfxboard *getgfxboard(uaecptr addr)
|
||
{
|
||
#ifdef JIT
|
||
special_mem = S_WRITE | S_READ;
|
||
#endif
|
||
if (only_gfx_board)
|
||
return only_gfx_board;
|
||
if (lastgetgfxboard) {
|
||
if (addr >= lastgetgfxboard->mem_start[0] && addr < lastgetgfxboard->mem_end[0])
|
||
return lastgetgfxboard;
|
||
if (addr >= lastgetgfxboard->io_start && addr < lastgetgfxboard->io_end)
|
||
return lastgetgfxboard;
|
||
if (addr >= lastgetgfxboard->mem_start[1] && addr < lastgetgfxboard->mem_end[1])
|
||
return lastgetgfxboard;
|
||
lastgetgfxboard = NULL;
|
||
}
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (!gb->active)
|
||
continue;
|
||
if (gb->configured_mem < 0 || gb->configured_regs < 0) {
|
||
lastgetgfxboard = gb;
|
||
return gb;
|
||
} else {
|
||
if (addr >= gb->io_start && addr < gb->io_end) {
|
||
lastgetgfxboard = gb;
|
||
return gb;
|
||
}
|
||
if (addr >= gb->mem_start[0] && addr < gb->mem_end[0]) {
|
||
lastgetgfxboard = gb;
|
||
return gb;
|
||
}
|
||
if (addr >= gb->mem_start[1] && addr < gb->mem_end[1]) {
|
||
lastgetgfxboard = gb;
|
||
return gb;
|
||
}
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
|
||
// LONG byteswapped VRAM
|
||
static uae_u32 REGPARAM2 gfxboard_lget_lbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_lget_vram (gb, addr, BYTESWAP_LONG);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_lbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_wget_vram (gb, addr, BYTESWAP_LONG);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_lbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_bget_vram (gb, addr, BYTESWAP_LONG);
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_lput_lbsmem (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_lput_vram (gb, addr, l, BYTESWAP_LONG);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_lbsmem (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_wput_vram (gb, addr, w, BYTESWAP_LONG);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_lbsmem (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_bput_vram (gb, addr, w, BYTESWAP_LONG);
|
||
}
|
||
|
||
// WORD byteswapped VRAM
|
||
static uae_u32 REGPARAM2 gfxboard_lget_wbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_lget_vram (gb, addr, BYTESWAP_WORD);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_wbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_wget_vram (gb, addr, BYTESWAP_WORD);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_wbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_bget_vram (gb, addr, BYTESWAP_WORD);
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_lput_wbsmem (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_lput_vram (gb, addr, l, BYTESWAP_WORD);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_wbsmem (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_wput_vram (gb, addr, w, BYTESWAP_WORD);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_wbsmem (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_bput_vram (gb, addr, w, BYTESWAP_WORD);
|
||
}
|
||
|
||
// normal or byteswapped (banked) vram
|
||
static uae_u32 REGPARAM2 gfxboard_lget_nbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int bs = 0;
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr_bs (gb, addr, 0, &bs);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_lget_vram (gb, addr, bs);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_nbsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int bs = 0;
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr_bs (gb, addr, 0, &bs);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_wget_vram (gb, addr, bs);
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_lput_nbsmem (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int bs = 0;
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr_bs (gb, addr, 0, &bs);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_lput_vram (gb, addr, l, bs);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_nbsmem (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int bs = 0;
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr_bs (gb, addr, 0, &bs);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_wput_vram (gb, addr, w, bs);
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_bsmem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int bs = 0;
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, 0);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_bget_vram (gb, addr, bs);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_bsmem (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int bs = 0;
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr_bs (gb, addr, 0, &bs);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_bput_vram (gb, addr, b, bs);
|
||
}
|
||
|
||
// normal vram
|
||
static uae_u32 REGPARAM2 gfxboard_lget_mem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, S_READ);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_lget_vram (gb, addr, 0);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_mem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, S_READ);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_wget_vram (gb, addr, 0);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_mem (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, S_READ);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_bget_vram (gb, addr, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_mem (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, S_WRITE);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_lput_vram (gb, addr, l, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_mem (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, S_WRITE);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_wput_vram (gb, addr, w, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_mem (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr(gb, addr, S_WRITE);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_bput_vram (gb, addr, b, 0);
|
||
}
|
||
|
||
// normal vram, no jit direct
|
||
static uae_u32 REGPARAM2 gfxboard_lget_mem_nojit (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr (gb, addr);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_lget_vram (gb, addr, 0);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_mem_nojit (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr (gb, addr);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_wget_vram (gb, addr, 0);
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_mem_nojit (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr (gb, addr);
|
||
if (addr == -1)
|
||
return 0;
|
||
return gfxboard_bget_vram (gb, addr, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_mem_nojit (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr (gb, addr);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_lput_vram (gb, addr, l, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_mem_nojit (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr (gb, addr);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_wput_vram (gb, addr, w, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_mem_nojit (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr = fixaddr (gb, addr);
|
||
if (addr == -1)
|
||
return;
|
||
gfxboard_bput_vram (gb, addr, b, 0);
|
||
}
|
||
|
||
static int REGPARAM2 gfxboard_check (uaecptr addr, uae_u32 size)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr &= gb->gfxmem_bank->mask;
|
||
return (addr + size) <= gb->rbc->rtgmem_size;
|
||
}
|
||
static uae_u8 *REGPARAM2 gfxboard_xlate (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr -= gb->gfxboardmem_start & gb->gfxmem_bank->mask;
|
||
addr &= gb->gfxmem_bank->mask;
|
||
return gb->vram + addr;
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_mem_autoconfig (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u32 v = 0;
|
||
addr &= 65535;
|
||
if (addr < GFXBOARD_AUTOCONFIG_SIZE)
|
||
v = gb->automemory[addr];
|
||
return v;
|
||
}
|
||
|
||
static void copyvrambank(addrbank *dst, const addrbank *src, bool unsafe)
|
||
{
|
||
dst->start = src->start;
|
||
dst->startmask = src->startmask;
|
||
dst->mask = src->mask;
|
||
dst->allocated_size = src->allocated_size;
|
||
dst->reserved_size = src->reserved_size;
|
||
dst->baseaddr = src->baseaddr;
|
||
dst->flags = src->flags;
|
||
dst->jit_read_flag = src->jit_read_flag;
|
||
dst->jit_write_flag = src->jit_write_flag;
|
||
if (unsafe) {
|
||
dst->jit_read_flag |= S_READ | S_N_ADDR;
|
||
dst->jit_write_flag |= S_WRITE | S_N_ADDR;
|
||
dst->flags |= ABFLAG_ALLOCINDIRECT | ABFLAG_PPCIOSPACE;
|
||
}
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
if (gb->board->configtype == 2)
|
||
return;
|
||
int boardnum = gb->rbc->rtgmem_type;
|
||
b &= 0xffff;
|
||
addr &= 65535;
|
||
if (addr == 0x44) {
|
||
uae_u32 start = expamem_board_pointer;
|
||
if (!expamem_z3hack(&currprefs)) {
|
||
start = ((b & 0xff00) | gb->expamem_lo) << 16;
|
||
}
|
||
gb->gfxboardmem_start = start;
|
||
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
|
||
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
|
||
gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
|
||
if (gb->board->pcemdev) {
|
||
if (boardnum == GFXBOARD_ID_CV643D_Z3) {
|
||
gb->gfxboardmem_start += 0x4000000;
|
||
}
|
||
}
|
||
init_board(gb);
|
||
copyvrambank(&gb->gfxboard_bank_memory, gb->gfxmem_bank, true);
|
||
copyvrambank(&gb->gfxboard_bank_vram_pcem, gb->gfxmem_bank, true);
|
||
if (ISP4() && !gb->board->pcemdev) {
|
||
if (validate_banks_z3(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, expamem_board_size >> 16)) {
|
||
// main vram
|
||
map_banks_z3(&gb->gfxboard_bank_memory, (gb->gfxmem_bank->start + PICASSOIV_VRAM1) >> 16, 0x400000 >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_wbsmemory, (gb->gfxmem_bank->start + PICASSOIV_VRAM1 + 0x400000) >> 16, 0x400000 >> 16);
|
||
// secondary
|
||
map_banks_z3(&gb->gfxboard_bank_memory_nojit, (gb->gfxmem_bank->start + PICASSOIV_VRAM2) >> 16, 0x400000 >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_wbsmemory, (gb->gfxmem_bank->start + PICASSOIV_VRAM2 + 0x400000) >> 16, 0x400000 >> 16);
|
||
// regs
|
||
map_banks_z3(&gb->gfxboard_bank_registers, (gb->gfxmem_bank->start + PICASSOIV_REG) >> 16, 0x200000 >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_special, gb->gfxmem_bank->start >> 16, PICASSOIV_REG >> 16);
|
||
}
|
||
gb->picassoiv_bank = 0;
|
||
gb->picassoiv_flifi = 1;
|
||
gb->configured_regs = gb->gfxmem_bank->start >> 16;
|
||
|
||
} else if (gb->board->pcemdev) {
|
||
|
||
if (boardnum == GFXBOARD_ID_CV64_Z3) {
|
||
|
||
map_banks_z3(&gb->gfxboard_bank_special_pcem, (start + 0x40000) >> 16, 1);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_cv_1_pcem, (start + 0x1400000) >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_cv_1_pcem, (start + 0x3400000) >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_io_pcem, (start + 0x2000000) >> 16, 1);
|
||
gb->pcem_mmio_offset = 0x1000000;
|
||
gb->pcem_mmio_mask = 0xffff;
|
||
gb->pcem_io_mask = 0xffff;
|
||
gb->configured_regs = gb->gfxmem_bank->start >> 16;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV643D_Z3) {
|
||
|
||
map_banks_z3(&gb->gfxboard_bank_vram_pcem, (start + 0x4000000) >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_pcem, (start + 0x4400000) >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_pcem, (start + 0x4800000) >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_pcem, (start + 0x4c00000) >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_mmio_pcem, (start + 0x5000000) >> 16, 1);
|
||
map_banks_z3(&gb->gfxboard_bank_mmio_wbs_pcem, (start + 0x5800000) >> 16, 1);
|
||
map_banks_z3(&gb->gfxboard_bank_mmio_lbs_pcem, (start + 0x7000000) >> 16, 1);
|
||
map_banks_z3(&gb->gfxboard_bank_special_pcem, (start + 0x8000000) >> 16, 1);
|
||
map_banks_z3(&gb->gfxboard_bank_io_swap2_pcem, (start + 0xc000000) >> 16, 4);
|
||
map_banks_z3(&gb->gfxboard_bank_pci_pcem, (start + 0xc0e0000) >> 16, 4);
|
||
gb->pcem_mmio_offset = 0x1000000;
|
||
gb->pcem_mmio_mask = 0xffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
gb->configured_regs = gb->gfxmem_bank->start >> 16;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PICASSO4_Z3) {
|
||
|
||
gb->p4_special_start = start;
|
||
map_banks_z3(&gb->gfxboard_bank_special_pcem, start >> 16, PICASSOIV_REG >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_io_swap_pcem, (start + PICASSOIV_REG) >> 16, 4);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_longswap_pcem, (start + PICASSOIV_VRAM1) >> 16, 0x400000 >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_wordswap_pcem, (start + PICASSOIV_VRAM1 + 0x400000) >> 16, 0x400000 >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_longswap_pcem, (start + PICASSOIV_VRAM2) >> 16, 0x400000 >> 16);
|
||
map_banks_z3(&gb->gfxboard_bank_vram_wordswap_pcem, (start + PICASSOIV_VRAM2 + 0x400000) >> 16, 0x400000 >> 16);
|
||
gb->pcem_mmio_offset = 0xb8000;
|
||
gb->pcem_mmio_mask = 0xffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
|
||
gb->picassoiv_bank = 0;
|
||
gb->picassoiv_flifi = 1;
|
||
gb->configured_regs = gb->gfxmem_bank->start >> 16;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PICCOLO_Z3 || boardnum == GFXBOARD_ID_SPECTRUM_Z3) {
|
||
|
||
// VRAM +0x800000. WORD/LONG endian swap hardware.
|
||
map_banks_z3(&gb->gfxboard_bank_vram_pcem, start >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
gb->pcem_vram_offset = 0x800000;
|
||
gb->pcem_vram_mask = 0x1fffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_SD64_Z3) {
|
||
|
||
map_banks_z3(&gb->gfxboard_bank_vram_pcem, start >> 16, gb->gfxboard_bank_vram_pcem.allocated_size >> 16);
|
||
gb->pcem_vram_offset = 0x800000;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
|
||
}
|
||
|
||
} else {
|
||
map_banks_z3(&gb->gfxboard_bank_memory, gb->gfxmem_bank->start >> 16, gb->board->banksize >> 16);
|
||
}
|
||
|
||
gb->mem_start[0] = start;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
gb->configured_mem = gb->gfxmem_bank->start >> 16;
|
||
expamem_next (&gb->gfxboard_bank_memory, NULL);
|
||
return;
|
||
}
|
||
if (addr == 0x4c) {
|
||
gb->configured_mem = 0xff;
|
||
expamem_shutup(&gb->gfxboard_bank_memory);
|
||
return;
|
||
}
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int boardnum = gb->rbc->rtgmem_type;
|
||
b &= 0xff;
|
||
addr &= 65535;
|
||
if (addr == 0x48) {
|
||
if (gb->board->configtype == 2) {
|
||
addrbank *ab;
|
||
if (ISP4() && !gb->board->pcemdev) {
|
||
ab = &gb->gfxboard_bank_nbsmemory;
|
||
copyvrambank(ab, gb->gfxmem_bank, true);
|
||
map_banks_z2 (ab, b, 0x00200000 >> 16);
|
||
if (gb->configured_mem <= 0) {
|
||
gb->configured_mem = b;
|
||
gb->gfxboardmem_start = b << 16;
|
||
init_board(gb);
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + 0x00200000;
|
||
} else {
|
||
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
|
||
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
|
||
gb->mem_start[1] = b << 16;
|
||
gb->mem_end[1] = gb->mem_start[1] + 0x00200000;
|
||
}
|
||
|
||
} else if (gb->board->pcemdev) {
|
||
|
||
copyvrambank(&gb->gfxboard_bank_vram_pcem, gb->gfxmem_bank, true);
|
||
|
||
if (boardnum == GFXBOARD_ID_CV643D_Z2) {
|
||
|
||
ab = &gb->gfxboard_bank_memory;
|
||
copyvrambank(ab, gb->gfxmem_bank, true);
|
||
uaecptr start = b << 16;
|
||
gb->gfxboardmem_start = b << 16;
|
||
map_banks_z2(&gb->gfxboard_bank_vram_pcem, start >> 16, (gb->board->banksize - (0x400000 - 0x3a0000)) >> 16);
|
||
map_banks_z2(&gb->gfxboard_bank_special_pcem, (start + 0x3a0000) >> 16, (0x400000 - 0x3a0000) >> 16);
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
|
||
init_board(gb);
|
||
|
||
gb->pcem_vram_offset = 0;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
gb->pcem_mmio_offset = 0x1000000;
|
||
gb->pcem_mmio_mask = 0xffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
gb->configured_mem = gb->gfxmem_bank->start >> 16;
|
||
gb->configured_regs = gb->gfxmem_bank->start >> 16;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PICASSO4_Z2) {
|
||
|
||
ab = &gb->gfxboard_bank_memory;
|
||
copyvrambank(ab, gb->gfxmem_bank, true);
|
||
map_banks_z2(&gb->gfxboard_bank_vram_p4z2_pcem, b, 0x00200000 >> 16);
|
||
if (gb->configured_mem <= 0) {
|
||
gb->configured_mem = b;
|
||
gb->gfxboardmem_start = b << 16;
|
||
init_board(gb);
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + 0x00200000;
|
||
gb->pcem_vram_offset = 0;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
gb->pcem_mmio_offset = 0xb8000;
|
||
gb->pcem_mmio_mask = 0xffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
} else {
|
||
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
|
||
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
|
||
gb->mem_start[1] = b << 16;
|
||
gb->mem_end[1] = gb->mem_start[1] + 0x00200000;
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PICCOLO_Z2 || boardnum == GFXBOARD_ID_SPECTRUM_Z2) {
|
||
|
||
ab = &gb->gfxboard_bank_vram_pcem;
|
||
gb->gfxboardmem_start = b << 16;
|
||
map_banks_z2(ab, b, gb->board->banksize >> 16);
|
||
|
||
init_board(gb);
|
||
|
||
gb->configured_mem = b;
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
|
||
gb->pcem_vram_offset = 0x800000;
|
||
gb->pcem_vram_mask = 0x1fffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_SD64_Z2) {
|
||
|
||
ab = &gb->gfxboard_bank_vram_pcem;
|
||
gb->gfxboardmem_start = b << 16;
|
||
map_banks_z2(ab, b, gb->board->banksize >> 16);
|
||
|
||
init_board(gb);
|
||
|
||
gb->configured_mem = b;
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
gb->pcem_vram_offset = 0x800000;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PIXEL64) {
|
||
|
||
ab = &gb->gfxboard_bank_vram_pcem;
|
||
gb->gfxboardmem_start = b << 16;
|
||
map_banks_z2(ab, b, 0x200000 >> 16);
|
||
map_banks_z2(&gb->gfxboard_bank_vram_wordswap_pcem, b + (0x200000 >> 16), 0x200000 >> 16);
|
||
|
||
init_board(gb);
|
||
|
||
gb->configured_mem = b;
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
|
||
gb->pcem_vram_offset = 0x800000;
|
||
gb->pcem_vram_mask = 0x1fffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
|
||
} else {
|
||
|
||
// Picasso II, Picasso II+
|
||
// Piccolo Z2
|
||
|
||
ab = &gb->gfxboard_bank_vram_pcem;
|
||
gb->gfxboardmem_start = b << 16;
|
||
map_banks_z2(ab, b, gb->board->banksize >> 16);
|
||
|
||
init_board(gb);
|
||
|
||
gb->configured_mem = b;
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
gb->pcem_vram_offset = 0x00200000 + 0x800000;
|
||
gb->pcem_vram_mask = 0x3fffff;
|
||
gb->pcem_io_mask = 0x3fff;
|
||
|
||
}
|
||
|
||
} else {
|
||
|
||
ab = &gb->gfxboard_bank_memory;
|
||
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem;
|
||
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem;
|
||
gb->gfxboard_bank_memory.wget = gfxboard_wget_mem;
|
||
gb->gfxboard_bank_memory.wput = gfxboard_wput_mem;
|
||
gb->gfxboardmem_start = b << 16;
|
||
init_board (gb);
|
||
copyvrambank(ab, gb->gfxmem_bank, true);
|
||
map_banks_z2 (ab, b, gb->board->banksize >> 16);
|
||
gb->configured_mem = b;
|
||
gb->mem_start[0] = b << 16;
|
||
gb->mem_end[0] = gb->mem_start[0] + gb->board->banksize;
|
||
|
||
}
|
||
expamem_next (ab, NULL);
|
||
} else {
|
||
gb->expamem_lo = b & 0xff;
|
||
}
|
||
return;
|
||
}
|
||
if (addr == 0x4c) {
|
||
gb->configured_mem = 0xff;
|
||
expamem_shutup(&gb->gfxboard_bank_memory);
|
||
return;
|
||
}
|
||
}
|
||
|
||
static uaecptr mungeaddr (struct rtggfxboard *gb, uaecptr addr, bool write)
|
||
{
|
||
addr &= 65535;
|
||
if (addr >= 0x2000) {
|
||
if (addr == 0x46e8) {
|
||
// wakeup register
|
||
return 0;
|
||
}
|
||
write_log (_T("GFXBOARD: %c unknown IO address %x\n"), write ? 'W' : 'R', addr);
|
||
return 0;
|
||
}
|
||
if (addr >= 0x1000) {
|
||
if (gb->board->manufacturer == BOARD_MANUFACTURER_PICASSO) {
|
||
if (addr == 0x1001) {
|
||
gb->gfxboard_intena = 1;
|
||
return 0;
|
||
}
|
||
if (addr == 0x1000) {
|
||
gb->gfxboard_intena = 0;
|
||
return 0;
|
||
}
|
||
}
|
||
if ((addr & 0xfff) < 0x3b0) {
|
||
write_log (_T("GFXBOARD: %c unknown IO address %x\n"), write ? 'W' : 'R', addr);
|
||
return 0;
|
||
}
|
||
addr++;
|
||
}
|
||
addr &= 0x0fff;
|
||
if (addr == 0x102) {
|
||
// POS102
|
||
return 0;
|
||
}
|
||
if (addr < 0x3b0) {
|
||
write_log (_T("GFXBOARD: %c unknown IO address %x\n"), write ? 'W' : 'R', addr);
|
||
return 0;
|
||
}
|
||
addr -= 0x3b0;
|
||
return addr;
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_lget_regs (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u32 v = 0xffffffff;
|
||
addr = mungeaddr (gb, addr, false);
|
||
if (addr)
|
||
v = (uae_u32)gb->vgaio->read (&gb->vga, addr, 4);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_regs (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u16 v = 0xffff;
|
||
addr = mungeaddr (gb, addr, false);
|
||
if (addr) {
|
||
uae_u8 v1, v2;
|
||
v1 = (uae_u8)gb->vgaio->read (&gb->vga, addr + 0, 1);
|
||
v1 = bget_regtest (gb, addr + 0, v1);
|
||
v2 = (uae_u8)gb->vgaio->read (&gb->vga, addr + 1, 1);
|
||
v2 = bget_regtest (gb, addr + 1, v2);
|
||
v = (v1 << 8) | v2;
|
||
}
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_regs (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u8 v = 0xff;
|
||
addr &= 65535;
|
||
if (addr >= 0x8000) {
|
||
write_log (_T("GFX SPECIAL BGET IO %08X\n"), addr);
|
||
return 0;
|
||
}
|
||
addr = mungeaddr (gb, addr, false);
|
||
if (addr) {
|
||
v = (uae_u8)gb->vgaio->read (&gb->vga, addr, 1);
|
||
v = bget_regtest (gb, addr, v);
|
||
#if REGDEBUG
|
||
write_log(_T("GFX VGA BYTE GET IO %04X = %02X PC=%08x\n"), addr & 65535, v & 0xff, M68K_GETPC);
|
||
#endif
|
||
}
|
||
return v;
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_lput_regs (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
|
||
addr = mungeaddr (gb, addr, true);
|
||
if (addr) {
|
||
gb->vgaio->write (&gb->vga, addr + 0, l >> 24, 1);
|
||
bput_regtest (gb, addr + 0, (l >> 24));
|
||
gb->vgaio->write (&gb->vga, addr + 1, (l >> 16) & 0xff, 1);
|
||
bput_regtest (gb, addr + 0, (l >> 16));
|
||
gb->vgaio->write (&gb->vga, addr + 2, (l >> 8) & 0xff, 1);
|
||
bput_regtest (gb, addr + 0, (l >> 8));
|
||
gb->vgaio->write (&gb->vga, addr + 3, (l >> 0) & 0xff, 1);
|
||
bput_regtest (gb, addr + 0, (l >> 0));
|
||
#if REGDEBUG
|
||
write_log(_T("GFX VGA LONG PUT IO %04X = %04X PC=%08x\n"), addr & 65535, l, M68K_GETPC);
|
||
#endif
|
||
}
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_regs (uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = mungeaddr (gb, addr, true);
|
||
if (addr) {
|
||
gb->vgaio->write (&gb->vga, addr + 0, (w >> 8) & 0xff, 1);
|
||
bput_regtest (gb, addr + 0, (w >> 8));
|
||
gb->vgaio->write (&gb->vga, addr + 1, (w >> 0) & 0xff, 1);
|
||
bput_regtest (gb, addr + 1, (w >> 0));
|
||
#if REGDEBUG
|
||
write_log(_T("GFX VGA WORD PUT IO %04X = %04X PC=%08x\n"), addr & 65535, w & 0xffff, M68K_GETPC);
|
||
#endif
|
||
}
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_regs (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= 65535;
|
||
if (addr >= 0x8000) {
|
||
write_log (_T("GFX SPECIAL BPUT IO %08X = %02X\n"), addr, b & 0xff);
|
||
switch (gb->board->manufacturer)
|
||
{
|
||
case BOARD_MANUFACTURER_PICASSO:
|
||
{
|
||
if ((addr & 1) == 0) {
|
||
int idx = addr >> 12;
|
||
if (idx == 0x0b || idx == 0x09) {
|
||
set_monswitch(gb, false);
|
||
} else if (idx == 0x0a || idx == 0x08) {
|
||
set_monswitch(gb, true);
|
||
}
|
||
}
|
||
}
|
||
break;
|
||
case BOARD_MANUFACTURER_PICCOLO:
|
||
case BOARD_MANUFACTURER_SPECTRUM:
|
||
set_monswitch(gb, (b & 0x20) != 0);
|
||
gb->gfxboard_intena = (b & 0x40) != 0;
|
||
break;
|
||
}
|
||
return;
|
||
}
|
||
addr = mungeaddr (gb, addr, true);
|
||
if (addr) {
|
||
gb->vgaio->write (&gb->vga, addr, b & 0xff, 1);
|
||
bput_regtest (gb, addr, b);
|
||
#if REGDEBUG
|
||
write_log(_T("GFX VGA BYTE PUT IO %04X = %02X PC=%08x\n"), addr & 65535, b & 0xff, M68K_GETPC);
|
||
#endif
|
||
}
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_regs_autoconfig (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u32 v = 0;
|
||
addr &= 65535;
|
||
if (addr < GFXBOARD_AUTOCONFIG_SIZE)
|
||
v = gb->automemory[addr];
|
||
return v;
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int boardnum = gb->rbc->rtgmem_type;
|
||
addrbank *ab;
|
||
b &= 0xff;
|
||
addr &= 65535;
|
||
if (addr == 0x48) {
|
||
gb->gfxboard_bank_registers.bget = gfxboard_bget_regs;
|
||
gb->gfxboard_bank_registers.bput = gfxboard_bput_regs;
|
||
|
||
if (gb->p4z2 && !gb->pcemdev) {
|
||
|
||
ab = &gb->gfxboard_bank_special;
|
||
map_banks_z2(ab, b, gb->gfxboard_bank_special.reserved_size >> 16);
|
||
gb->io_start = b << 16;
|
||
gb->io_end = gb->io_start + gb->gfxboard_bank_special.reserved_size;
|
||
|
||
} else if (gb->pcemdev) {
|
||
|
||
ab = &gb->gfxboard_bank_special_pcem;
|
||
int size = (boardnum == GFXBOARD_ID_PICASSO4_Z2 || boardnum == GFXBOARD_ID_PIXEL64) ? 0x20000 : 0x10000;
|
||
map_banks_z2(ab, b, size >> 16);
|
||
gb->io_start = b << 16;
|
||
gb->io_end = gb->io_start + size;
|
||
gb->p4_special_start = gb->io_start;
|
||
|
||
} else {
|
||
|
||
ab = &gb->gfxboard_bank_registers;
|
||
map_banks_z2(ab, b, gb->gfxboard_bank_registers.reserved_size >> 16);
|
||
gb->io_start = b << 16;
|
||
gb->io_end = gb->io_start + gb->gfxboard_bank_registers.reserved_size;
|
||
|
||
}
|
||
gb->configured_regs = b;
|
||
expamem_next (ab, NULL);
|
||
return;
|
||
}
|
||
if (addr == 0x4c) {
|
||
gb->configured_regs = 0xff;
|
||
expamem_next (NULL, NULL);
|
||
return;
|
||
}
|
||
}
|
||
|
||
static void gfxboard_free_board(struct rtggfxboard *gb)
|
||
{
|
||
if (gb->rbc) {
|
||
if (gb->func) {
|
||
if (gb->userdata)
|
||
gb->func->free(gb->userdata);
|
||
gfxboard_free_slot2(gb);
|
||
gb->rbc = NULL;
|
||
return;
|
||
}
|
||
}
|
||
if (gb->pcemdev) {
|
||
if (gb->pcemobject) {
|
||
gb->pcemdev->close(gb->pcemobject);
|
||
gb->pcemobject = NULL;
|
||
gb->pcemobject2 = NULL;
|
||
}
|
||
}
|
||
if (gb->vram && gb->gfxmem_bank->baseaddr) {
|
||
gb->gfxmem_bank->baseaddr = gb->vramrealstart;
|
||
gfxboard_free_vram(gb->rbc->rtg_index);
|
||
}
|
||
gb->gfxmem_bank = NULL;
|
||
gb->vram = NULL;
|
||
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;
|
||
gb->monswitch_current = false;
|
||
gb->monswitch_delay = -1;
|
||
gb->monswitch_reset = true;
|
||
gb->resolutionchange = 0;
|
||
gb->gfxboard_intreq = false;
|
||
gb->gfxboard_intena = 0;
|
||
gb->picassoiv_bank = 0;
|
||
gb->active = false;
|
||
flash_free(gb->p4flashrom);
|
||
gb->p4flashrom = NULL;
|
||
zfile_fclose(gb->p4rom);
|
||
gb->p4rom = NULL;
|
||
}
|
||
|
||
void gfxboard_free(void)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
gfxboard_free_board(gb);
|
||
}
|
||
}
|
||
|
||
void gfxboard_reset (void)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
gb->rbc = &currprefs.rtgboards[gb->rtg_index];
|
||
if (gb->func) {
|
||
if (gb->userdata) {
|
||
gb->func->reset(gb->userdata);
|
||
}
|
||
gfxboard_free_board(gb);
|
||
} else {
|
||
if (gb->rbc->rtgmem_type >= GFXBOARD_HARDWARE) {
|
||
gb->board = find_board(gb->rbc->rtgmem_type);
|
||
}
|
||
gfxboard_free_board(gb);
|
||
if (gb->board) {
|
||
if (gb->board->configtype == 3)
|
||
gb->gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
|
||
if (reset_func)
|
||
reset_func (reset_parm);
|
||
}
|
||
}
|
||
if (gb->monitor_id > 0) {
|
||
close_rtg(gb->monitor_id, true);
|
||
}
|
||
}
|
||
for (int i = 0; i < MAX_AMIGADISPLAYS; i++) {
|
||
rtg_visible[i] = -1;
|
||
rtg_initial[i] = -1;
|
||
}
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboards_lget_regs (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u32 v = 0;
|
||
addr &= gb->p4_special_mask;
|
||
// pci config
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
addr2 -= 0x800;
|
||
v = gb->p4_pci[addr2 + 0] << 24;
|
||
v |= gb->p4_pci[addr2 + 1] << 16;
|
||
v |= gb->p4_pci[addr2 + 2] << 8;
|
||
v |= gb->p4_pci[addr2 + 3] << 0;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV PCI LGET %08x %08x\n"), addr, v);
|
||
#endif
|
||
} else if (addr2 >= 0x1000 && addr2 < 0x1040) {
|
||
addr2 -= 0x1000;
|
||
v = gb->cirrus_pci[addr2 + 0] << 24;
|
||
v |= gb->cirrus_pci[addr2 + 1] << 16;
|
||
v |= gb->cirrus_pci[addr2 + 2] << 8;
|
||
v |= gb->cirrus_pci[addr2 + 3] << 0;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV CL PCI LGET %08x %08x\n"), addr, v);
|
||
#endif
|
||
}
|
||
return v;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
v = ((uae_u8)gb->vgammio->read(&gb->vga, addr2 + 0, 1)) << 24;
|
||
v |= ((uae_u8)gb->vgammio->read(&gb->vga, addr2 + 1, 1)) << 16;
|
||
v |= ((uae_u8)gb->vgammio->read(&gb->vga, addr2 + 2, 1)) << 8;
|
||
v |= ((uae_u8)gb->vgammio->read(&gb->vga, addr2 + 3, 1)) << 0;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV MMIO LGET %08x %08x\n"), addr, v);
|
||
#endif
|
||
return v;
|
||
}
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV LGET %08x %08x\n"), addr, v);
|
||
#endif
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboards_wget_regs (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u16 v = 0;
|
||
addr &= gb->p4_special_mask;
|
||
// pci config
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
addr2 -= 0x800;
|
||
v = gb->p4_pci[addr2 + 0] << 8;
|
||
v |= gb->p4_pci[addr2 + 1] << 0;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV PCI WGET %08x %04x\n"), addr, v);
|
||
#endif
|
||
} else if (addr2 >= 0x1000 && addr2 < 0x1040) {
|
||
addr2 -= 0x1000;
|
||
v = gb->cirrus_pci[addr2 + 0] << 8;
|
||
v |= gb->cirrus_pci[addr2 + 1] << 0;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV CL PCI WGET %08x %04x\n"), addr, v);
|
||
#endif
|
||
}
|
||
return v;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
v = ((uae_u8)gb->vgammio->read(&gb->vga, addr2 + 0, 1)) << 8;
|
||
v |= ((uae_u8)gb->vgammio->read(&gb->vga, addr2 + 1, 1)) << 0;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV MMIO WGET %08x %04x\n"), addr, v & 0xffff);
|
||
#endif
|
||
return v;
|
||
}
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV WGET %04x %04x\n"), addr, v);
|
||
#endif
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u8 v = 0xff;
|
||
addr &= gb->p4_special_mask;
|
||
|
||
#if PICASSOIV_DEBUG_IO > 1
|
||
write_log(_T("PicassoIV CL REG BGET %08x PC=%08x\n"), addr, M68K_GETPC);
|
||
#endif
|
||
|
||
// pci config
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
v = 0;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
if (addr2 == 0x802) {
|
||
v = 2; // bridge version?
|
||
} else if (addr2 == 0x808) {
|
||
v = 4; // bridge revision
|
||
} else {
|
||
addr2 -= 0x800;
|
||
v = gb->p4_pci[addr2];
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV PCI BGET %08x %02x\n"), addr, v);
|
||
#endif
|
||
} else if (addr2 >= 0x1000 && addr2 <= 0x1040) {
|
||
addr2 -= 0x1000;
|
||
v = gb->cirrus_pci[addr2];
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV CL PCI BGET %08x %02x\n"), addr, v);
|
||
#endif
|
||
}
|
||
return v;
|
||
}
|
||
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
v = (uae_u8)gb->vgammio->read(&gb->vga, addr2, 1);
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV MMIO BGET %08x %02x\n"), addr, v & 0xff);
|
||
#endif
|
||
return v;
|
||
}
|
||
}
|
||
if (addr == 0) {
|
||
v = gb->picassoiv_bank;
|
||
return v;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
|
||
v = 0;
|
||
if (addr == 0x404) {
|
||
v = 0x70; // FLIFI revision
|
||
// FLIFI type in use
|
||
if (currprefs.chipset_mask & CSMASK_AGA)
|
||
v |= 4 | 8;
|
||
else
|
||
v |= 8;
|
||
} else if (addr == 0x406) {
|
||
// FLIFI I2C
|
||
// bit 0 = clock out
|
||
// bit 1 = data out
|
||
// bit 2 = clock in
|
||
// bit 7 = data in
|
||
v = gb->p4i2c & 3;
|
||
if (v & 1)
|
||
v |= 4;
|
||
if (v & 2)
|
||
v |= 0x80;
|
||
} else if (addr == 0x408) {
|
||
v = gb->gfxboard_intreq ? 0x80 : 0;
|
||
} else if (gb->p4z2 && addr >= 0x10000) {
|
||
addr -= 0x10000;
|
||
uaecptr addr2 = mungeaddr (gb, addr, true);
|
||
if (addr2) {
|
||
v = (uae_u8)gb->vgaio->read(&gb->vga, addr2, 1);
|
||
v = bget_regtest(gb, addr2, v);
|
||
//write_log(_T("P4 VGA read %08X=%02X PC=%08x\n"), addr2, v, M68K_GETPC);
|
||
}
|
||
//write_log (_T("PicassoIV IO %08x %02x\n"), addr, v);
|
||
return v;
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
if (addr != 0x408)
|
||
write_log (_T("PicassoIV BGET %08x %02x\n"), addr, v);
|
||
#endif
|
||
} else {
|
||
addr += ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 * 2 : 0);
|
||
addr /= 2;
|
||
v = flash_read(gb->p4flashrom, addr);
|
||
}
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboards_lput_regs (uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->p4_special_mask;
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
addr2 -= 0x800;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV PCI LPUT %08x %08x\n"), addr, l);
|
||
#endif
|
||
gb->p4_pci[addr2 + 0] = l >> 24;
|
||
gb->p4_pci[addr2 + 1] = l >> 16;
|
||
gb->p4_pci[addr2 + 2] = l >> 8;
|
||
gb->p4_pci[addr2 + 3] = l >> 0;
|
||
p4_pci_check (gb);
|
||
} else if (addr2 >= 0x1000 && addr2 < 0x1040) {
|
||
addr2 -= 0x1000;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV CL PCI LPUT %08x %08x\n"), addr, l);
|
||
#endif
|
||
gb->cirrus_pci[addr2 + 0] = l >> 24;
|
||
gb->cirrus_pci[addr2 + 1] = l >> 16;
|
||
gb->cirrus_pci[addr2 + 2] = l >> 8;
|
||
gb->cirrus_pci[addr2 + 3] = l >> 0;
|
||
reset_pci (gb);
|
||
}
|
||
return;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV MMIO LPUT %08x %08x\n"), addr, l);
|
||
#endif
|
||
uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
gb->vgammio->write(&gb->vga, addr2 + 0, l >> 24, 1);
|
||
gb->vgammio->write(&gb->vga, addr2 + 1, l >> 16, 1);
|
||
gb->vgammio->write(&gb->vga, addr2 + 2, l >> 8, 1);
|
||
gb->vgammio->write(&gb->vga, addr2 + 3, l >> 0, 1);
|
||
return;
|
||
}
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV LPUT %08x %08x\n"), addr, l);
|
||
#endif
|
||
}
|
||
static void REGPARAM2 gfxboards_wput_regs (uaecptr addr, uae_u32 v)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u16 w = (uae_u16)v;
|
||
addr &= gb->p4_special_mask;
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
addr2 -= 0x800;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV PCI WPUT %08x %04x\n"), addr, w & 0xffff);
|
||
#endif
|
||
gb->p4_pci[addr2 + 0] = w >> 8;
|
||
gb->p4_pci[addr2 + 1] = w >> 0;
|
||
p4_pci_check (gb);
|
||
} else if (addr2 >= 0x1000 && addr2 < 0x1040) {
|
||
addr2 -= 0x1000;
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV CL PCI WPUT %08x %04x\n"), addr, w & 0xffff);
|
||
#endif
|
||
gb->cirrus_pci[addr2 + 0] = w >> 8;
|
||
gb->cirrus_pci[addr2 + 1] = w >> 0;
|
||
reset_pci (gb);
|
||
}
|
||
return;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV MMIO LPUT %08x %08x\n"), addr, w & 0xffff);
|
||
#endif
|
||
uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
gb->vgammio->write(&gb->vga, addr2 + 0, w >> 8, 1);
|
||
gb->vgammio->write(&gb->vga, addr2 + 1, (w >> 0) & 0xff, 1);
|
||
return;
|
||
}
|
||
}
|
||
if (gb->p4z2 && addr >= 0x10000) {
|
||
addr -= 0x10000;
|
||
addr = mungeaddr (gb, addr, true);
|
||
if (addr) {
|
||
gb->vgaio->write (&gb->vga, addr + 0, w >> 8, 1);
|
||
bput_regtest (gb, addr + 0, w >> 8);
|
||
gb->vgaio->write (&gb->vga, addr + 1, (w >> 0) & 0xff, 1);
|
||
bput_regtest (gb, addr + 1, w >> 0);
|
||
}
|
||
return;
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV WPUT %08x %04x\n"), addr, w & 0xffff);
|
||
#endif
|
||
}
|
||
|
||
static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u8 b = (uae_u8)v;
|
||
addr &= gb->p4_special_mask;
|
||
|
||
#if PICASSOIV_DEBUG_IO > 1
|
||
write_log(_T("PicassoIV CL REG BPUT %08x %02x PC=%08x\n"), addr, v, M68K_GETPC);
|
||
#endif
|
||
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
addr2 -= 0x800;
|
||
gb->p4_pci[addr2] = b;
|
||
p4_pci_check (gb);
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV PCI BPUT %08x %02x\n"), addr, b & 0xff);
|
||
#endif
|
||
} else if (addr2 >= 0x1000 && addr2 < 0x1040) {
|
||
addr2 -= 0x1000;
|
||
gb->cirrus_pci[addr2] = b;
|
||
reset_pci (gb);
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV CL PCI BPUT %08x %02x\n"), addr, b & 0xff);
|
||
#endif
|
||
}
|
||
return;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV MMIO BPUT %08x %08x\n"), addr, b & 0xff);
|
||
#endif
|
||
uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
gb->vgammio->write(&gb->vga, addr2, b, 1);
|
||
return;
|
||
}
|
||
}
|
||
if (gb->p4z2 && addr >= 0x10000 && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH)) {
|
||
addr -= 0x10000;
|
||
addr = mungeaddr (gb, addr, true);
|
||
if (addr) {
|
||
gb->vgaio->write (&gb->vga, addr, b & 0xff, 1);
|
||
bput_regtest (gb, addr, b);
|
||
//write_log(_T("P4 VGA write %08x=%02x PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
|
||
if (addr == 0x404) {
|
||
gb->picassoiv_flifi = b;
|
||
picassoiv_checkswitch(gb);
|
||
} else if (addr == 0x406) {
|
||
gb->p4i2c = b;
|
||
}
|
||
}
|
||
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log (_T("PicassoIV BPUT %08x %02X\n"), addr, b & 0xff);
|
||
#endif
|
||
if (addr == 0) {
|
||
gb->picassoiv_bank = b;
|
||
}
|
||
}
|
||
|
||
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->pci) {
|
||
if (gb->lfbbyteswapmode != m) {
|
||
gb->lfbbyteswapmode = m;
|
||
if (gb->original_pci_bank) {
|
||
if (!m) {
|
||
gb->pcem_direct = true;
|
||
write_log(_T("Voodoo direct VRAM mode\n"));
|
||
map_banks(gb->gfxmem_bank, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0);
|
||
map_banks(gb->gfxmem_bank, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0);
|
||
} else {
|
||
gb->pcem_direct = false;
|
||
write_log(_T("Voodoo indirect VRAM mode (%d)\n"), m);
|
||
map_banks(gb->original_pci_bank, gb->gfxmem_bank->start >> 16, 0x01000000 >> 16, 0);
|
||
map_banks(gb->original_pci_bank, (gb->gfxmem_bank->start + 0x01000000) >> 16, 0x01000000 >> 16, 0);
|
||
}
|
||
}
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
|
||
static void pci_change_config(struct pci_board_state *pci)
|
||
{
|
||
struct rtggfxboard *gb = (struct rtggfxboard *)pci->userdata;
|
||
struct romconfig *rc = get_device_romconfig(&currprefs, gb->board->romtype, 0);
|
||
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI) {
|
||
if (pci->memory_map_active) {
|
||
// direct access, bypass PCI emulation redirection for performance reasons
|
||
if (rc && (rc->device_settings & 1) && pci_validate_address(pci->bar[1] + pci->bridge->memory_start_offset, 0x02000000, false)) {
|
||
if (!gb->original_pci_bank) {
|
||
gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset);
|
||
}
|
||
reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true);
|
||
int m = gb->lfbbyteswapmode;
|
||
gb->lfbbyteswapmode = -1;
|
||
gfxboard_voodoo_lfb_endianswap(m);
|
||
} else {
|
||
reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false);
|
||
}
|
||
}
|
||
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI) {
|
||
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, gb->rbc->rtgmem_size, false)) {
|
||
reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, true);
|
||
gb->original_pci_bank = &get_mem_bank(pci->bar[1] + pci->bridge->memory_start_offset);
|
||
} else {
|
||
reinit_vram(gb, pci->bar[1] + pci->bridge->memory_start_offset, false);
|
||
}
|
||
}
|
||
} else if (gb->rbc->rtgmem_type == GFXBOARD_ID_S3VIRGE_PCI) {
|
||
if (pci->memory_map_active) {
|
||
reinit_vram(gb, pci->bar[0] + pci->bridge->memory_start_offset, false);
|
||
}
|
||
}
|
||
}
|
||
|
||
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;
|
||
switch (m)
|
||
{
|
||
case 1:
|
||
case 3:
|
||
addr ^= 3;
|
||
break;
|
||
}
|
||
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;
|
||
switch (m)
|
||
{
|
||
case 1:
|
||
case 3:
|
||
addr ^= 3;
|
||
break;
|
||
}
|
||
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);
|
||
if (!gb->bios)
|
||
return 0;
|
||
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, 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 },
|
||
{ NULL }
|
||
},
|
||
true,
|
||
get_pci_pcem, put_pci_pcem, pci_change_config
|
||
};
|
||
|
||
void gfxboard_s3virge_lfb_endianswap(int m)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (gb->active && gb->board->pci) {
|
||
gb->lfbbyteswapmode = m;
|
||
}
|
||
}
|
||
}
|
||
void gfxboard_s3virge_lfb_endianswap2(int m)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (gb->active && gb->board->pci) {
|
||
gb->mmiobyteswapmode = m;
|
||
}
|
||
}
|
||
}
|
||
|
||
static int s3virgeaddr(struct pci_board_state *pcibs, uaecptr *addrp)
|
||
{
|
||
uaecptr addr = *addrp;
|
||
int swap = 0;
|
||
if (addr >= pcibs->bar[0] + 0x02000000 && addr < pcibs->bar[0] + 0x03000000) {
|
||
// LFB BE
|
||
addr = ((addr - pcibs->bar[0]) & 0x3fffff) + pcibs->bar[0];
|
||
swap = -1;
|
||
} else if (addr >= pcibs->bar[0] + 0x03000000 && addr < pcibs->bar[0] + 0x04000000) {
|
||
// MMIO BE
|
||
addr = ((addr - pcibs->bar[0]) & 0xffff) + pcibs->bar[0] + 0x01000000;
|
||
swap = addr & 0x8000 ? 1 : 2;
|
||
} else if (addr >= pcibs->bar[0] + 0x00000000 && addr < pcibs->bar[0] + 0x01000000) {
|
||
// LFB LE
|
||
addr = ((addr - pcibs->bar[0]) & 0x3fffff) + pcibs->bar[0];
|
||
swap = -2;
|
||
} else if (addr >= pcibs->bar[0] + 0x01000000 && addr < pcibs->bar[0] + 0x02000000) {
|
||
// MMIO LE
|
||
addr = ((addr - pcibs->bar[0]) & 0xffff) + pcibs->bar[0] + 0x01000000;
|
||
}
|
||
*addrp = addr;
|
||
return swap;
|
||
}
|
||
|
||
static void REGPARAM2 s3virge_mb0_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
|
||
{
|
||
int swap = s3virgeaddr(pcibs, &addr);
|
||
if (swap > 0) {
|
||
if (swap == 1)
|
||
b = do_byteswap_32(b);
|
||
} else if (swap == -1) {
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int m = gb->lfbbyteswapmode;
|
||
switch (m)
|
||
{
|
||
case 0:
|
||
default:
|
||
break;
|
||
case 1:
|
||
b = do_byteswap_32(b);
|
||
b = (b >> 16) | (b << 16);
|
||
break;
|
||
}
|
||
} else if (swap < -1) {
|
||
|
||
}
|
||
put_mem_pcem(addr, b, 2);
|
||
}
|
||
static void REGPARAM2 s3virge_mb0_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
|
||
{
|
||
int swap = s3virgeaddr(pcibs, &addr);
|
||
if (swap > 0) {
|
||
if (swap == 1)
|
||
b = do_byteswap_16(b);
|
||
} else if (swap <= -1) {
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int m = gb->lfbbyteswapmode;
|
||
switch (m)
|
||
{
|
||
case 0:
|
||
default:
|
||
break;
|
||
case 1:
|
||
b = do_byteswap_16(b);
|
||
break;
|
||
}
|
||
} else if (swap < -1) {
|
||
|
||
}
|
||
put_mem_pcem(addr, b, 1);
|
||
}
|
||
static void REGPARAM2 s3virge_mb0_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
|
||
{
|
||
int swap = s3virgeaddr(pcibs, &addr);
|
||
put_mem_pcem(addr, b, 0);
|
||
}
|
||
static uae_u32 REGPARAM2 s3virge_mb0_lget(struct pci_board_state *pcibs, uaecptr addr)
|
||
{
|
||
int swap = s3virgeaddr(pcibs, &addr);
|
||
uae_u32 v = get_mem_pcem(addr, 2);
|
||
if (swap > 0) {
|
||
if (swap == 1)
|
||
v = do_byteswap_32(v);
|
||
} else if (swap == -1) {
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int m = gb->lfbbyteswapmode;
|
||
switch (m)
|
||
{
|
||
case 0:
|
||
default:
|
||
break;
|
||
case 1:
|
||
v = (v >> 16) | (v << 16);
|
||
v = do_byteswap_32(v);
|
||
break;
|
||
}
|
||
} else if (swap < -1) {
|
||
|
||
}
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 s3virge_mb0_wget(struct pci_board_state *pcibs, uaecptr addr)
|
||
{
|
||
int swap = s3virgeaddr(pcibs, &addr);
|
||
uae_u32 v = get_mem_pcem(addr, 1);
|
||
if (swap > 0) {
|
||
if (swap == 1)
|
||
v = do_byteswap_16(v);
|
||
} else if (swap == -1) {
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int m = gb->lfbbyteswapmode;
|
||
switch (m)
|
||
{
|
||
case 0:
|
||
default:
|
||
break;
|
||
case 1:
|
||
v = do_byteswap_16(v);
|
||
break;
|
||
}
|
||
} else if (swap < -1) {
|
||
|
||
}
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 s3virge_mb0_bget(struct pci_board_state *pcibs, uaecptr addr)
|
||
{
|
||
int swap = s3virgeaddr(pcibs, &addr);
|
||
uae_u32 v = get_mem_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
|
||
static void REGPARAM2 s3virge_io_lput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
|
||
{
|
||
put_io_pcem(addr, b, 2);
|
||
}
|
||
static void REGPARAM2 s3virge_io_wput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
|
||
{
|
||
put_io_pcem(addr, b, 1);
|
||
}
|
||
static void REGPARAM2 s3virge_io_bput(struct pci_board_state *pcibs, uaecptr addr, uae_u32 b)
|
||
{
|
||
//write_log(_T("s3virge_io_bput(%08x,%02x) PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
|
||
put_io_pcem(addr, b, 0);
|
||
}
|
||
static uae_u32 REGPARAM2 s3virge_io_lget(struct pci_board_state *pcibs, uaecptr addr)
|
||
{
|
||
return get_io_pcem(addr, 2);
|
||
}
|
||
static uae_u32 REGPARAM2 s3virge_io_wget(struct pci_board_state *pcibs, uaecptr addr)
|
||
{
|
||
return get_io_pcem(addr, 1);
|
||
}
|
||
static uae_u32 REGPARAM2 s3virge_io_bget(struct pci_board_state *pcibs, uaecptr addr)
|
||
{
|
||
uae_u32 v = get_io_pcem(addr, 0);
|
||
//write_log(_T("s3virge_io_bget(%08x,%02x) PC=%08x\n"), addr, v & 0xff, M68K_GETPC);
|
||
return v;
|
||
}
|
||
|
||
static const struct pci_config s3virge_pci_config =
|
||
{
|
||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0 }
|
||
};
|
||
|
||
static const struct pci_board s3virge_pci_board =
|
||
{
|
||
_T("S3VIRGE"),
|
||
&s3virge_pci_config, NULL, NULL, NULL, NULL, NULL,
|
||
{
|
||
{ s3virge_mb0_lget, s3virge_mb0_wget, s3virge_mb0_bget, s3virge_mb0_lput, s3virge_mb0_wput, s3virge_mb0_bput },
|
||
{ NULL },
|
||
{ NULL },
|
||
{ NULL },
|
||
{ NULL },
|
||
{ NULL },
|
||
{ voodoo3_bios_lget, voodoo3_bios_wget, voodoo3_bios_bget, NULL, NULL, NULL },
|
||
{ s3virge_io_lget, s3virge_io_wget, s3virge_io_bget, s3virge_io_lput, s3virge_io_wput, s3virge_io_bput }
|
||
},
|
||
true,
|
||
get_pci_pcem, put_pci_pcem, pci_change_config
|
||
};
|
||
|
||
|
||
int gfxboard_get_index_from_id(int id)
|
||
{
|
||
if (id == GFXBOARD_UAE_Z2)
|
||
return GFXBOARD_UAE_Z2;
|
||
if (id == GFXBOARD_UAE_Z3)
|
||
return GFXBOARD_UAE_Z3;
|
||
const struct gfxboard *b = find_board(id);
|
||
return (int)(b - &boards[0] + GFXBOARD_HARDWARE);
|
||
}
|
||
|
||
int gfxboard_get_id_from_index(int index)
|
||
{
|
||
if (index == GFXBOARD_UAE_Z2)
|
||
return GFXBOARD_UAE_Z2;
|
||
if (index == GFXBOARD_UAE_Z3)
|
||
return GFXBOARD_UAE_Z3;
|
||
const struct gfxboard *b = &boards[index - GFXBOARD_HARDWARE];
|
||
if (!b->id)
|
||
return -1;
|
||
return b->id;
|
||
}
|
||
|
||
const TCHAR *gfxboard_get_name(int type)
|
||
{
|
||
if (type == GFXBOARD_UAE_Z2)
|
||
return _T("UAE [Zorro II]");
|
||
if (type == GFXBOARD_UAE_Z3)
|
||
return _T("UAE [Zorro III]");
|
||
const struct gfxboard *b = find_board(type);
|
||
if (!b)
|
||
return NULL;
|
||
return b->name;
|
||
}
|
||
|
||
const TCHAR *gfxboard_get_manufacturername(int type)
|
||
{
|
||
if (type == GFXBOARD_UAE_Z2)
|
||
return NULL;
|
||
if (type == GFXBOARD_UAE_Z3)
|
||
return NULL;
|
||
const struct gfxboard *b = find_board(type);
|
||
if (!b)
|
||
return NULL;
|
||
return b->manufacturername;
|
||
}
|
||
|
||
const TCHAR *gfxboard_get_configname(int type)
|
||
{
|
||
if (type == GFXBOARD_UAE_Z2)
|
||
return _T("ZorroII");
|
||
if (type == GFXBOARD_UAE_Z3)
|
||
return _T("ZorroIII");
|
||
const struct gfxboard *b = find_board(type);
|
||
if (!b)
|
||
return NULL;
|
||
return b->configname;
|
||
}
|
||
|
||
struct gfxboard_func *gfxboard_get_func(struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type == GFXBOARD_UAE_Z2)
|
||
return NULL;
|
||
if (type == GFXBOARD_UAE_Z3)
|
||
return NULL;
|
||
const struct gfxboard *b = find_board(type);
|
||
if (!b)
|
||
return NULL;
|
||
return b->func;
|
||
}
|
||
|
||
int gfxboard_get_configtype(struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type == GFXBOARD_UAE_Z2)
|
||
return 2;
|
||
if (type == GFXBOARD_UAE_Z3)
|
||
return 3;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
return gb->board->configtype;
|
||
}
|
||
|
||
bool gfxboard_need_byteswap (struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type < GFXBOARD_HARDWARE)
|
||
return false;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
return gb->board->swap;
|
||
}
|
||
|
||
int gfxboard_get_autoconfig_size(struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type == GFXBOARD_ID_PICASSO4_Z3)
|
||
return 32 * 1024 * 1024;
|
||
return -1;
|
||
}
|
||
|
||
int gfxboard_get_vram_min (struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type < GFXBOARD_HARDWARE)
|
||
return -1;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
return gb->board->vrammin;
|
||
}
|
||
|
||
int gfxboard_get_vram_max (struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type < GFXBOARD_HARDWARE)
|
||
return -1;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
return gb->board->vrammax;
|
||
}
|
||
|
||
int gfxboard_is_registers (struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type < 2)
|
||
return 0;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
if (gb->board->model_extra > 0)
|
||
return 2;
|
||
return gb->board->model_registers > 0 ? 1 : 0;
|
||
}
|
||
|
||
int gfxboard_num_boards (struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type < 2)
|
||
return 1;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
if (gb->board->id == GFXBOARD_ID_PICASSO4_Z2) {
|
||
if (rbc->rtgmem_size < 0x400000)
|
||
return 2;
|
||
return 3;
|
||
}
|
||
if (gb->board->model_registers == 0)
|
||
return 1;
|
||
return 2;
|
||
}
|
||
|
||
uae_u32 gfxboard_get_romtype(struct rtgboardconfig *rbc)
|
||
{
|
||
int type = rbc->rtgmem_type;
|
||
if (type < 2)
|
||
return 0;
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
gb->board = find_board(type);
|
||
return gb->board->romtype;
|
||
}
|
||
|
||
static void gfxboard_init (struct autoconfig_info *aci, struct rtggfxboard *gb)
|
||
{
|
||
struct uae_prefs *p = aci->prefs;
|
||
gb->rtg_index = aci->devnum;
|
||
if (!gb->automemory)
|
||
gb->automemory = xmalloc (uae_u8, GFXBOARD_AUTOCONFIG_SIZE);
|
||
memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
|
||
struct rtgboardconfig *rbc = &p->rtgboards[gb->rtg_index];
|
||
gb->rbc = rbc;
|
||
gb->monitor_id = rbc->monitor_id;
|
||
if (!aci->doinit)
|
||
return;
|
||
gb->gfxmem_bank = gfxmem_banks[gb->rtg_index];
|
||
gb->gfxmem_bank->mask = gb->rbc->rtgmem_size - 1;
|
||
gb->p4z2 = false;
|
||
gb->banksize_mask = gb->board->banksize - 1;
|
||
memset (gb->cirrus_pci, 0, sizeof gb->cirrus_pci);
|
||
reset_pci (gb);
|
||
}
|
||
|
||
static void copyp4autoconfig (struct rtggfxboard *gb, int startoffset)
|
||
{
|
||
int size = 0;
|
||
int offset = 0;
|
||
memset (gb->automemory, 0xff, 64);
|
||
while (size < 32) {
|
||
uae_u8 b = gb->p4autoconfig[size + startoffset];
|
||
gb->automemory[offset] = b;
|
||
offset += 2;
|
||
size++;
|
||
}
|
||
}
|
||
|
||
static void loadp4rom (struct rtggfxboard *gb)
|
||
{
|
||
int size, offset;
|
||
uae_u8 b;
|
||
// rom loader code
|
||
zfile_fseek (gb->p4rom, 256, SEEK_SET);
|
||
offset = PICASSOIV_ROM_OFFSET;
|
||
size = 0;
|
||
while (size < 4096 - 256) {
|
||
if (!zfile_fread (&b, 1, 1, gb->p4rom))
|
||
break;
|
||
gb->automemory[offset] = b;
|
||
offset += 2;
|
||
size++;
|
||
}
|
||
// main flash code
|
||
zfile_fseek (gb->p4rom, 16384, SEEK_SET);
|
||
zfile_fread (&gb->automemory[PICASSOIV_FLASH_OFFSET / 2], 1, PICASSOIV_MAX_FLASH, gb->p4rom);
|
||
gb->p4flashrom = flash_new(gb->automemory, 131072, 131072, 0x01, 0x20, gb->p4rom, 0);
|
||
write_log (_T("PICASSOIV: flash rom loaded\n"));
|
||
}
|
||
|
||
bool gfxboard_init_memory (struct autoconfig_info *aci)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
|
||
int bank;
|
||
uae_u8 z2_flags, z3_flags, type;
|
||
struct uae_prefs *p = aci->prefs;
|
||
uae_u8 flags = 0;
|
||
bool ext_size = false;
|
||
|
||
gfxboard_init (aci, gb);
|
||
|
||
memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
|
||
|
||
z2_flags = 0x05; // 1M
|
||
z3_flags = 0;
|
||
bank = gb->board->banksize;
|
||
bank /= 0x00100000;
|
||
if (bank >= 16) {
|
||
ext_size = true;
|
||
bank /= 16;
|
||
while (bank > 1) {
|
||
z3_flags++;
|
||
bank >>= 1;
|
||
}
|
||
} else {
|
||
while (bank > 1) {
|
||
z2_flags++;
|
||
bank >>= 1;
|
||
}
|
||
z2_flags &= 7;
|
||
}
|
||
if (gb->board->configtype == 3) {
|
||
type = 0x80;
|
||
flags |= 0x10;
|
||
if (ext_size) {
|
||
flags |= 0x20;
|
||
type |= z3_flags;
|
||
} else {
|
||
type |= z2_flags;
|
||
}
|
||
} else {
|
||
type = z2_flags | 0xc0;
|
||
}
|
||
type |= gb->board->model_registers && !gb->board->model_extra ? 0x08 : 0x00;
|
||
flags |= gb->board->er_flags;
|
||
|
||
ew(gb, 0x04, gb->board->model_memory);
|
||
ew(gb, 0x10, gb->board->manufacturer >> 8);
|
||
ew(gb, 0x14, gb->board->manufacturer);
|
||
|
||
uae_u32 ser = gb->board->serial;
|
||
ew(gb, 0x18, ser >> 24); /* ser.no. Byte 0 */
|
||
ew(gb, 0x1c, ser >> 16); /* ser.no. Byte 1 */
|
||
ew(gb, 0x20, ser >> 8); /* ser.no. Byte 2 */
|
||
ew(gb, 0x24, ser >> 0); /* ser.no. Byte 3 */
|
||
|
||
ew(gb, 0x00, type);
|
||
ew(gb, 0x08, flags);
|
||
|
||
if (ISP4()) {
|
||
int roms[] = { 91, -1 };
|
||
struct romlist *rl = getromlistbyids(roms, NULL);
|
||
TCHAR path[MAX_DPATH];
|
||
fetch_rompath (path, sizeof path / sizeof (TCHAR));
|
||
|
||
if (rl) {
|
||
gb->p4rom = flashromfile_open(rl->path);
|
||
}
|
||
|
||
if (!gb->p4rom && p->picassoivromfile[0] && zfile_exists(p->picassoivromfile))
|
||
gb->p4rom = flashromfile_open(p->picassoivromfile);
|
||
|
||
if (!gb->p4rom) {
|
||
_tcscat (path, _T("picasso_iv_flash.rom"));
|
||
gb->p4rom = flashromfile_open(path);
|
||
if (!gb->p4rom)
|
||
gb->p4rom = flashromfile_open(_T("picasso_iv_flash.rom"));
|
||
}
|
||
if (gb->p4rom) {
|
||
zfile_fread (gb->p4autoconfig, sizeof gb->p4autoconfig, 1, gb->p4rom);
|
||
copyp4autoconfig (gb, gb->board->configtype == 3 ? 192 : 0);
|
||
if (gb->board->configtype == 3) {
|
||
loadp4rom (gb);
|
||
gb->p4_mmiobase = 0x200000;
|
||
gb->p4_special_mask = 0x7fffff;
|
||
} else {
|
||
gb->p4z2 = true;
|
||
gb->p4_mmiobase = 0x8000;
|
||
gb->p4_special_mask = 0x1ffff;
|
||
}
|
||
gb->gfxboard_intena = 1;
|
||
} else {
|
||
error_log (_T("Picasso IV: '%s' flash rom image not found!\nAvailable from http://www.sophisticated-development.de/\nPIV_FlashImageXX -> picasso_iv_flash.rom"), path);
|
||
gui_message (_T("Picasso IV: '%s' flash rom image not found!\nAvailable from http://www.sophisticated-development.de/\nPIV_FlashImageXX -> picasso_iv_flash.rom"), path);
|
||
}
|
||
}
|
||
|
||
aci->label = gb->board->name;
|
||
aci->direct_vram = true;
|
||
aci->addrbank = &gb->gfxboard_bank_memory;
|
||
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VGA) {
|
||
aci->zorro = -1;
|
||
if (gb->monitor_id > 0) {
|
||
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->board->pci) {
|
||
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);
|
||
}
|
||
return true;
|
||
}
|
||
|
||
gb->configured_mem = -1;
|
||
gb->rtg_index = aci->devnum;
|
||
|
||
total_active_gfx_boards = 0;
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
if (p->rtgboards[i].rtgmem_size && p->rtgboards[i].rtgmem_type >= GFXBOARD_HARDWARE) {
|
||
total_active_gfx_boards++;
|
||
}
|
||
}
|
||
only_gfx_board = NULL;
|
||
if (total_active_gfx_boards == 1)
|
||
only_gfx_board = gb;
|
||
|
||
|
||
_stprintf(gb->memorybankname, _T("%s VRAM"), gb->board->name);
|
||
_stprintf(gb->memorybanknamenojit, _T("%s VRAM NOJIT"), gb->board->name);
|
||
_stprintf(gb->wbsmemorybankname, _T("%s VRAM WORDSWAP"), gb->board->name);
|
||
_stprintf(gb->lbsmemorybankname, _T("%s VRAM LONGSWAP"), gb->board->name);
|
||
_stprintf(gb->regbankname, _T("%s REG"), gb->board->name);
|
||
|
||
memcpy(&gb->gfxboard_bank_memory, &tmpl_gfxboard_bank_memory, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_wbsmemory, &tmpl_gfxboard_bank_wbsmemory, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_lbsmemory, &tmpl_gfxboard_bank_lbsmemory, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_nbsmemory, &tmpl_gfxboard_bank_nbsmemory, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_registers, &tmpl_gfxboard_bank_registers, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_registers2, &tmpl_gfxboard_bank_registers2, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_special, &tmpl_gfxboard_bank_special, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_memory_nojit, &tmpl_gfxboard_bank_memory_nojit, sizeof addrbank);
|
||
|
||
memcpy(&gb->gfxboard_bank_vram_pcem, &tmpl_gfxboard_bank_vram_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_vram_normal_pcem, &tmpl_gfxboard_bank_vram_normal_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_vram_wordswap_pcem, &tmpl_gfxboard_bank_vram_wordswap_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_vram_longswap_pcem, &tmpl_gfxboard_bank_vram_longswap_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_vram_cv_1_pcem, &tmpl_gfxboard_bank_vram_cv_1_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_vram_p4z2_pcem, &tmpl_gfxboard_bank_vram_p4z2_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_io_swap_pcem, &tmpl_gfxboard_bank_io_swap_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_io_swap2_pcem, &tmpl_gfxboard_bank_io_swap2_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_io_pcem, &tmpl_gfxboard_bank_io_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_pci_pcem, &tmpl_gfxboard_bank_pci_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_mmio_pcem, &tmpl_gfxboard_bank_mmio_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_mmio_wbs_pcem, &tmpl_gfxboard_bank_mmio_wbs_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_mmio_lbs_pcem, &tmpl_gfxboard_bank_mmio_lbs_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_special_pcem, &tmpl_gfxboard_bank_special_pcem, sizeof addrbank);
|
||
memcpy(&gb->gfxboard_bank_bios, &tmpl_gfxboard_bank_bios, sizeof addrbank);
|
||
|
||
gb->gfxboard_bank_memory.name = gb->memorybankname;
|
||
gb->gfxboard_bank_memory_nojit.name = gb->memorybanknamenojit;
|
||
gb->gfxboard_bank_wbsmemory.name = gb->wbsmemorybankname;
|
||
gb->gfxboard_bank_lbsmemory.name = gb->lbsmemorybankname;
|
||
gb->gfxboard_bank_registers.name = gb->regbankname;
|
||
gb->gfxboard_bank_registers2.name = gb->regbankname;
|
||
|
||
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
|
||
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
|
||
gb->gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
|
||
|
||
gb->active = true;
|
||
|
||
if (gb->board->pci) {
|
||
|
||
TCHAR path[MAX_DPATH];
|
||
fetch_rompath(path, sizeof path / sizeof(TCHAR));
|
||
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI)
|
||
_tcscat(path, _T("voodoo3.rom"));
|
||
else
|
||
_tcscat(path, _T("s3virge.rom"));
|
||
struct zfile *zf = read_rom_name(path);
|
||
if (zf) {
|
||
gb->bios = xcalloc(uae_u8, 65536);
|
||
gb->bios_mask = 65535;
|
||
int size = (int)zfile_fread(gb->bios, 1, 65536, zf);
|
||
zfile_fclose(zf);
|
||
write_log(_T("PCI RTG board BIOS load, %d bytes\n"), size);
|
||
} else {
|
||
error_log(_T("PCI RTG board BIOS ROM (%s) failed to load!\n"), path);
|
||
}
|
||
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) {
|
||
if (gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO3_PCI || gb->rbc->rtgmem_type == GFXBOARD_ID_VOODOO5_PCI)
|
||
gb->pcibs = pci_board_add(b, &voodoo3_pci_board, -1, 0, aci, gb);
|
||
else
|
||
gb->pcibs = pci_board_add(b, &s3virge_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;
|
||
gb->configured_regs = 1;
|
||
return true;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
bool gfxboard_init_memory_p4_z2 (struct autoconfig_info *aci)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
|
||
if (gb->board->configtype == 3) {
|
||
aci->addrbank = &expamem_null;
|
||
return true;
|
||
}
|
||
|
||
copyp4autoconfig (gb, 64);
|
||
memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
|
||
aci->addrbank = &gb->gfxboard_bank_memory;
|
||
aci->label = gb->board->name;
|
||
aci->parent_of_previous = true;
|
||
aci->direct_vram = true;
|
||
|
||
if (!aci->doinit)
|
||
return true;
|
||
|
||
memcpy(&gb->gfxboard_bank_memory, &tmpl_gfxboard_bank_memory, sizeof addrbank);
|
||
gb->gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
|
||
gb->gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
|
||
return true;
|
||
}
|
||
|
||
bool gfxboard_init_registersx(struct autoconfig_info *aci, int regnum)
|
||
{
|
||
struct rtggfxboard *gb = &rtggfxboards[aci->devnum];
|
||
int size;
|
||
|
||
if (regnum && !gb->board->model_extra) {
|
||
aci->addrbank = &expamem_null;
|
||
return true;
|
||
}
|
||
if (!regnum && !gb->board->model_registers) {
|
||
aci->addrbank = &expamem_null;
|
||
return true;
|
||
}
|
||
|
||
memset (gb->automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
|
||
if (gb->rbc->rtgmem_type == GFXBOARD_ID_PIXEL64) {
|
||
ew(gb, 0x00, 0xc0 | 0x02); // 128 Z2
|
||
size = BOARD_REGISTERS_SIZE * 2;
|
||
} else {
|
||
ew(gb, 0x00, 0xc0 | 0x01); // 64k Z2
|
||
size = BOARD_REGISTERS_SIZE;
|
||
}
|
||
|
||
ew (gb, 0x04, regnum ? gb->board->model_extra : gb->board->model_registers);
|
||
ew (gb, 0x10, gb->board->manufacturer >> 8);
|
||
ew (gb, 0x14, gb->board->manufacturer);
|
||
|
||
uae_u32 ser = gb->board->serial;
|
||
ew (gb, 0x18, ser >> 24); /* ser.no. Byte 0 */
|
||
ew (gb, 0x1c, ser >> 16); /* ser.no. Byte 1 */
|
||
ew (gb, 0x20, ser >> 8); /* ser.no. Byte 2 */
|
||
ew (gb, 0x24, ser >> 0); /* ser.no. Byte 3 */
|
||
|
||
if (ISP4()) {
|
||
uae_u8 v;
|
||
copyp4autoconfig (gb, 128);
|
||
loadp4rom (gb);
|
||
if (aci->doinit) {
|
||
v = (((gb->automemory[0] & 0xf0) | (gb->automemory[2] >> 4)) & 3) - 1;
|
||
gb->gfxboard_bank_special.reserved_size = 0x10000 << v;
|
||
}
|
||
}
|
||
|
||
memcpy(aci->autoconfig_raw, gb->automemory, sizeof aci->autoconfig_raw);
|
||
aci->label = gb->board->name;
|
||
|
||
aci->addrbank = regnum ? &gb->gfxboard_bank_registers2 : &gb->gfxboard_bank_registers;
|
||
aci->parent_of_previous = true;
|
||
|
||
if (!aci->doinit)
|
||
return true;
|
||
|
||
if (regnum) {
|
||
gb->gfxboard_bank_registers2.bget = gfxboard_bget_regs_autoconfig;
|
||
gb->gfxboard_bank_registers2.bput = gfxboard_bput_regs_autoconfig;
|
||
gb->gfxboard_bank_registers2.reserved_size = size;
|
||
gb->configured_regs = -2;
|
||
} else {
|
||
gb->gfxboard_bank_registers.bget = gfxboard_bget_regs_autoconfig;
|
||
gb->gfxboard_bank_registers.bput = gfxboard_bput_regs_autoconfig;
|
||
gb->gfxboard_bank_registers.reserved_size = size;
|
||
gb->configured_regs = -1;
|
||
}
|
||
|
||
|
||
return true;
|
||
}
|
||
|
||
bool gfxboard_init_registers(struct autoconfig_info *aci)
|
||
{
|
||
return gfxboard_init_registersx(aci, 0);
|
||
}
|
||
bool gfxboard_init_registers2(struct autoconfig_info *aci)
|
||
{
|
||
return gfxboard_init_registersx(aci, 1);
|
||
}
|
||
|
||
|
||
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
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_vram_normal_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);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_vram_normal_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);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_vram_normal_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);
|
||
v = do_byteswap_32(v);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_vram_normal_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_b(addr + pcem_mapping_linear_offset, b, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_vram_normal_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_w(addr + pcem_mapping_linear_offset, w, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_vram_normal_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
l = do_byteswap_32(l);
|
||
pcem_linear_write_l(addr + pcem_mapping_linear_offset, l, pcem_mapping_linear_priv);
|
||
}
|
||
|
||
|
||
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);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_vram_longswap_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
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);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
uae_u32 v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
v = do_byteswap_32(v);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_vram_longswap_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_b(addr + pcem_mapping_linear_offset, b, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_vram_longswap_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
w = do_byteswap_16(w);
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_w(addr + pcem_mapping_linear_offset, w, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_vram_longswap_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
l = do_byteswap_32(l);
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_l(addr + pcem_mapping_linear_offset, l, pcem_mapping_linear_priv);
|
||
}
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_vram_wordswap_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(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);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_vram_wordswap_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
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);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
uae_u32 v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
v = (v >> 16) | (v << 16);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_vram_wordswap_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
addr ^= 1;
|
||
pcem_linear_write_b(addr + pcem_mapping_linear_offset, b, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_vram_wordswap_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_w(addr + pcem_mapping_linear_offset, w, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_vram_wordswap_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
l = (l >> 16) | (l << 16);
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_l(addr + pcem_mapping_linear_offset, l, pcem_mapping_linear_priv);
|
||
}
|
||
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_vram_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 & gb->pcem_vram_mask) + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_vram_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u16 v;
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
if (addr & 0x800000) {
|
||
;
|
||
} else if (addr & 0x400000) {
|
||
;
|
||
} else {
|
||
addr ^= 2;
|
||
}
|
||
v = pcem_linear_read_w((addr & gb->pcem_vram_mask) + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
if (addr & 0x800000) {
|
||
v = do_byteswap_16(v);
|
||
} else if (addr & 0x400000) {
|
||
;
|
||
} else {
|
||
;
|
||
}
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_vram_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 & gb->pcem_vram_mask) + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
if (addr & 0x800000) {
|
||
v = do_byteswap_32(v);
|
||
} else if (addr & 0x400000) {
|
||
v = (v >> 16) | (v << 16);
|
||
} else {
|
||
;
|
||
}
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_vram_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_b(addr + pcem_mapping_linear_offset, b, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_vram_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
if (addr & 0x800000) {
|
||
w = do_byteswap_16(w);
|
||
} else if (addr & 0x400000) {
|
||
;
|
||
} else {
|
||
addr ^= 2;
|
||
}
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_w(addr + pcem_mapping_linear_offset, w, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_vram_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
if (addr & 0x800000) {
|
||
l = do_byteswap_32(l);
|
||
} else if (addr & 0x400000) {
|
||
l = (l >> 16) | (l << 16);
|
||
} else {
|
||
;
|
||
}
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_l(addr + pcem_mapping_linear_offset, l, pcem_mapping_linear_priv);
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_vram_cv_1_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);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_vram_cv_1_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u16 v;
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
if (gb->device_data & 0x40) {
|
||
addr ^= 2;
|
||
} else if (gb->device_data & 0x20) {
|
||
;
|
||
}
|
||
v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
if (gb->device_data & 0x40) {
|
||
;
|
||
} else if (gb->device_data & 0x20) {
|
||
;
|
||
} else {
|
||
v = do_byteswap_16(v);
|
||
}
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_vram_cv_1_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);
|
||
if (gb->device_data & 0x40) {
|
||
;
|
||
} else if (gb->device_data & 0x20) {
|
||
v = (v >> 16) | (v << 16);
|
||
} else {
|
||
v = do_byteswap_32(v);
|
||
}
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_vram_cv_1_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
pcem_linear_write_b(addr + pcem_mapping_linear_offset, b, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_vram_cv_1_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
if (gb->device_data & 0x40) {
|
||
addr ^= 2;
|
||
} else if (gb->device_data & 0x20) {
|
||
;
|
||
} else {
|
||
w = do_byteswap_16(w);
|
||
}
|
||
pcem_linear_write_w(addr + pcem_mapping_linear_offset, w, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_vram_cv_1_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
addr &= gb->pcem_vram_mask;
|
||
if (gb->device_data & 0x40) {
|
||
;
|
||
} else if (gb->device_data & 0x20) {
|
||
l = (l >> 16) | (l << 16);
|
||
} else {
|
||
l = do_byteswap_32(l);
|
||
}
|
||
pcem_linear_write_l(addr + pcem_mapping_linear_offset, l, pcem_mapping_linear_priv);
|
||
}
|
||
|
||
|
||
static int p4z2swap(struct rtggfxboard *gb, uaecptr addr)
|
||
{
|
||
uae_u32 offset;
|
||
if (addr & 0x200000) {
|
||
offset = gb->p4_vram_bank[1];
|
||
} else {
|
||
offset = gb->p4_vram_bank[0];
|
||
}
|
||
if (offset & 0x800000)
|
||
return 1;
|
||
if (offset & 0x400000)
|
||
return 2;
|
||
return 0;
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_vram_p4z2_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
addr += gb->pcem_vram_offset;
|
||
int swap = p4z2swap(gb, addr);
|
||
if (swap) {
|
||
addr ^= 1;
|
||
}
|
||
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_p4z2_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u16 v;
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
v = pcem_linear_read_w(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
int swap = p4z2swap(gb, addr);
|
||
if (swap == 0 || swap == 1) {
|
||
v = do_byteswap_16(v);
|
||
}
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_vram_p4z2_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
uae_u32 v;
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
v = pcem_linear_read_l(addr + pcem_mapping_linear_offset, pcem_mapping_linear_priv);
|
||
int swap = p4z2swap(gb, addr);
|
||
if (swap == 1) {
|
||
v = do_byteswap_32(v);
|
||
} else if (swap == 0) {
|
||
v = (do_byteswap_16(v >> 16) << 0) | (do_byteswap_16(v >> 0) << 16);
|
||
} else {
|
||
v = (v >> 16) | (v << 16);
|
||
}
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_vram_p4z2_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
int swap = p4z2swap(gb, addr);
|
||
if (swap) {
|
||
addr ^= 1;
|
||
}
|
||
pcem_linear_write_b(addr + pcem_mapping_linear_offset, b, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_vram_p4z2_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
int swap = p4z2swap(gb, addr);
|
||
if (swap == 0 || swap == 1) {
|
||
w = do_byteswap_16(w);
|
||
}
|
||
pcem_linear_write_w(addr + pcem_mapping_linear_offset, w, pcem_mapping_linear_priv);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_vram_p4z2_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
int swap = p4z2swap(gb, addr);
|
||
if (swap == 1) {
|
||
l = do_byteswap_32(l);
|
||
} else if (swap == 0) {
|
||
l = (do_byteswap_16(l >> 16) << 0) | (do_byteswap_16(l >> 0) << 16);
|
||
} else {
|
||
l = (l >> 16) | (l << 16);
|
||
}
|
||
pcem_linear_write_l(addr + pcem_mapping_linear_offset, l, pcem_mapping_linear_priv);
|
||
}
|
||
|
||
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_lget_io_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u32 v = get_io_pcem(addr, 2);
|
||
v = do_byteswap_32(v);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_io_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u16 v = get_io_pcem(addr, 1);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_io_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u32 v = get_io_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_io_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
l = do_byteswap_32(l);
|
||
put_io_pcem(addr, l, 2);
|
||
picassoiv_checkswitch(gb);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_io_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
put_io_pcem(addr, w, 1);
|
||
picassoiv_checkswitch(gb);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_io_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
put_io_pcem(addr, b, 0);
|
||
picassoiv_checkswitch(gb);
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_lget_io_swap_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u32 v = get_io_pcem(addr, 2);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_io_swap_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u16 v = get_io_pcem(addr, 1);
|
||
v = do_byteswap_16(v);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_io_swap_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u32 v = get_io_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_io_swap_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
put_io_pcem(addr, l, 2);
|
||
picassoiv_checkswitch(gb);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_io_swap_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
w = do_byteswap_16(w);
|
||
put_io_pcem(addr, w, 1);
|
||
picassoiv_checkswitch(gb);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_io_swap_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
put_io_pcem(addr, b, 0);
|
||
picassoiv_checkswitch(gb);
|
||
}
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_lget_io_swap2_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
uae_u32 v = get_io_pcem(addr, 2);
|
||
v = do_byteswap_32(v);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_io_swap2_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
addr ^= 2;
|
||
uae_u16 v = get_io_pcem(addr, 1);
|
||
v = do_byteswap_16(v);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_bget_io_swap2_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
addr ^= 3;
|
||
uae_u32 v = get_io_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_io_swap2_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
l = do_byteswap_32(l);
|
||
put_io_pcem(addr, l, 2);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_io_swap2_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
addr ^= 2;
|
||
w = do_byteswap_16(w);
|
||
put_io_pcem(addr, w, 1);
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_io_swap2_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_io_mask;
|
||
addr ^= 3;
|
||
put_io_pcem(addr, b, 0);
|
||
}
|
||
|
||
|
||
void put_pci_pcem(uaecptr addr, uae_u8 v);
|
||
uae_u8 get_pci_pcem(uaecptr addr);
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_pci_pcem(uaecptr addr)
|
||
{
|
||
addr ^= 3;
|
||
uae_u8 v = get_pci_pcem(addr & 0xfff);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_pci_pcem(uaecptr addr)
|
||
{
|
||
uae_u16 v;
|
||
v = gfxboard_bget_pci_pcem(addr) << 8;
|
||
v |= gfxboard_bget_pci_pcem(addr + 1) << 0;
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_pci_pcem(uaecptr addr)
|
||
{
|
||
uae_u32 v;
|
||
v = gfxboard_wget_pci_pcem(addr) << 16;
|
||
v |= gfxboard_wget_pci_pcem(addr + 2) << 0;
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_pci_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
addr ^= 3;
|
||
put_pci_pcem(addr & 0xfff, b);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_pci_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
gfxboard_bput_pci_pcem(addr, w >> 8);
|
||
gfxboard_bput_pci_pcem(addr + 1, w & 0xff);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_pci_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
gfxboard_wput_pci_pcem(addr, l >> 16);
|
||
gfxboard_wput_pci_pcem(addr + 2, l & 0xffff);
|
||
}
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_mmio_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
addr ^= 3;
|
||
uae_u8 v = get_mem_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_mmio_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
addr ^= 2;
|
||
uae_u16 v;
|
||
v = get_mem_pcem(addr, 1);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_mmio_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u32 v;
|
||
v = get_mem_pcem(addr, 2);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_mmio_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
addr ^= 3;
|
||
#if 0
|
||
write_log(_T("gfxboard_bput_mmio_wbs_pcem(%08x, %08x)\n"), addr, b);
|
||
#endif
|
||
put_mem_pcem(addr, b, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_mmio_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
addr ^= 2;
|
||
#if 0
|
||
write_log(_T("gfxboard_wput_mmio_wbs_pcem(%08x, %08x)\n"), addr, w);
|
||
#endif
|
||
put_mem_pcem(addr, w, 1);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_mmio_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_lput_mmio_wbs_pcem(%08x, %08x)\n"), addr, l);
|
||
#endif
|
||
put_mem_pcem(addr, l, 2);
|
||
}
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_mmio_wbs_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u8 v = get_mem_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_mmio_wbs_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u16 v;
|
||
v = get_mem_pcem(addr, 1);
|
||
v = do_byteswap_16(v);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_mmio_wbs_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u32 v;
|
||
v = get_mem_pcem(addr, 2);
|
||
v = do_byteswap_32(v);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_mmio_wbs_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_bput_mmio_wbs_pcem(%08x, %08x)\n"), addr, b);
|
||
#endif
|
||
put_mem_pcem(addr, b, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_mmio_wbs_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_wput_mmio_wbs_pcem(%08x, %08x)\n"), addr, w);
|
||
#endif
|
||
w = do_byteswap_16(w);
|
||
put_mem_pcem(addr, w, 1);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_mmio_wbs_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_lput_mmio_wbs_pcem(%08x, %08x)\n"), addr, l);
|
||
#endif
|
||
l = do_byteswap_32(l);
|
||
put_mem_pcem(addr, l, 2);
|
||
}
|
||
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_mmio_lbs_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u8 v = get_mem_pcem(addr, 0);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_mmio_lbs_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u16 v;
|
||
v = get_mem_pcem(addr, 1);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_mmio_lbs_pcem(uaecptr addr)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
uae_u32 v;
|
||
v = get_mem_pcem(addr, 2);
|
||
return v;
|
||
}
|
||
static void REGPARAM2 gfxboard_bput_mmio_lbs_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_bput_mmio_wbs_pcem(%08x, %08x)\n"), addr, b);
|
||
#endif
|
||
put_mem_pcem(addr, b, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_mmio_lbs_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_wput_mmio_wbs_pcem(%08x, %08x)\n"), addr, w);
|
||
#endif
|
||
put_mem_pcem(addr, w, 1);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_mmio_lbs_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
addr &= gb->pcem_mmio_mask;
|
||
addr += gb->pcem_mmio_offset;
|
||
#if 0
|
||
write_log(_T("gfxboard_lput_mmio_wbs_pcem(%08x, %08x)\n"), addr, l);
|
||
#endif
|
||
put_mem_pcem(addr, l, 2);
|
||
}
|
||
|
||
|
||
static void special_pcem_put(uaecptr addr, uae_u32 v, int size)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int boardnum = gb->rbc->rtgmem_type;
|
||
|
||
#if SPCDEBUG
|
||
// if ((addr & 0xfffff) != 0x40021)
|
||
write_log(_T("PCEM SPECIAL PUT %08x %08x %d PC=%08x\n"), addr, v, size, M68K_GETPC);
|
||
#endif
|
||
|
||
if (boardnum == GFXBOARD_ID_PIXEL64) {
|
||
|
||
addr &= 0xffff;
|
||
if (size) {
|
||
put_io_pcem(addr + 0, (v >> 8) & 0xff, 0);
|
||
put_io_pcem(addr + 1, (v >> 0) & 0xff, 0);
|
||
} else if (size == 0) {
|
||
put_io_pcem(addr, v & 0xff, 0);
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV643D_Z2) {
|
||
|
||
uaecptr addr2 = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
uaecptr addrd = addr2 + gb->gfxboardmem_start;
|
||
if (gb->pcem_pci_configured) {
|
||
if (addr2 >= 0x3c0000 && addr2 < 0x3d0000) {
|
||
addrd &= 0x3fff;
|
||
if (size == 1) {
|
||
addrd ^= 2;
|
||
} else {
|
||
addrd ^= 3;
|
||
}
|
||
put_io_pcem(addrd, v, size);
|
||
return;
|
||
} else if (addr2 == 0x3a0000 + 4) {
|
||
// Z2 IO/MMIO (What does this do?)
|
||
gb->pcem_data[0] = v;
|
||
return;
|
||
} else if (addr2 == 0x3a0000 + 8) {
|
||
// Z2 endian select
|
||
gb->pcem_data[1] = v;
|
||
gb->pcem_vram_offset = (v & 0xc0) << 16;
|
||
return;
|
||
} else if (addr2 == 0x3a0000 + 0) {
|
||
if (size == 1) {
|
||
set_monswitch(gb, (v & 1) == 0);
|
||
}
|
||
return;
|
||
} else if (addr2 == 0x3a0000 + 12) {
|
||
if (size == 1) {
|
||
gb->gfxboard_intena = (v & 2) != 0;
|
||
}
|
||
return;
|
||
}
|
||
} else {
|
||
if (addr2 >= 0x3c0000 && addr2 < 0x3c8000) {
|
||
addrd &= 0xfff;
|
||
if (size == 0)
|
||
gfxboard_bput_pci_pcem(addrd, v);
|
||
else if (size == 1)
|
||
gfxboard_wput_pci_pcem(addrd, v);
|
||
else
|
||
gfxboard_lput_pci_pcem(addrd, v);
|
||
if (size == 2) {
|
||
gb->pcem_pci_configured = true;
|
||
}
|
||
return;
|
||
}
|
||
}
|
||
if (addr2 >= 0x3c8000 && addr2 < 0x3d0000) {
|
||
if (size == 0)
|
||
gfxboard_bput_mmio_pcem(addrd, v);
|
||
else if (size == 1)
|
||
gfxboard_wput_mmio_pcem(addrd, v);
|
||
else
|
||
gfxboard_lput_mmio_pcem(addrd, v);
|
||
} else if (addr2 >= 0x3e8000 && addr2 < 0x3f0000) {
|
||
if (size == 0)
|
||
gfxboard_bput_mmio_pcem(addrd, v);
|
||
else if (size == 1)
|
||
gfxboard_wput_mmio_pcem(addrd, v);
|
||
else
|
||
gfxboard_lput_mmio_pcem(addrd, v);
|
||
} else if (addr2 >= 0x3e0000 && addr2 < 0x3e8000) {
|
||
if (size == 0)
|
||
gfxboard_bput_mmio_wbs_pcem(addrd, v);
|
||
else if (size == 1)
|
||
gfxboard_wput_mmio_wbs_pcem(addrd, v);
|
||
else
|
||
gfxboard_lput_mmio_wbs_pcem(addrd, v);
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV64_Z3) {
|
||
addr &= 0xffff;
|
||
if (addr == 1) {
|
||
// bit 3 = interrupt enable
|
||
// bit 4 = switcher
|
||
// bit 5 = byteswap (1 = word swap)
|
||
// bit 6 = byteswap (1 = long swap)
|
||
// bit 7 = interrupt level (0=6, 1 = 2)
|
||
if (size == 0) {
|
||
set_monswitch(gb, (v & 0x10) != 0);
|
||
gb->gfxboard_intena = (v & 0x08) != 0;
|
||
if (gb->gfxboard_intena) {
|
||
if (v & 0x80)
|
||
gb->gfxboard_intena = 2;
|
||
else
|
||
gb->gfxboard_intena = 6;
|
||
}
|
||
gb->device_data = v;
|
||
}
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV643D_Z3) {
|
||
addr &= 0xffff;
|
||
if (addr == 0) {
|
||
if (size == 1) {
|
||
set_monswitch(gb, (v & 1) == 0);
|
||
}
|
||
} else if (addr == 12) {
|
||
if (size == 1) {
|
||
gb->gfxboard_intena = (v & 2) != 0;
|
||
}
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PICASSO2 || boardnum == GFXBOARD_ID_PICASSO2PLUS) {
|
||
// CL54xx
|
||
addr &= 0xffff;
|
||
if (addr & 0x8000) {
|
||
if (size == 0) {
|
||
write_log(_T("GFX SPECIAL BPUT IO %08X = %02X\n"), addr, v & 0xff);
|
||
if ((addr & 0x2001) == 0x2000) {
|
||
int idx = addr >> 12;
|
||
if (idx == 0x0b || idx == 0x09) {
|
||
set_monswitch(gb, false);
|
||
} else if (idx == 0x0a || idx == 0x08) {
|
||
set_monswitch(gb, true);
|
||
}
|
||
}
|
||
if (boardnum == GFXBOARD_ID_PICASSO2PLUS) {
|
||
if ((addr & 0x1001) == 0x1000) {
|
||
gb->gfxboard_intena = false;
|
||
}
|
||
if ((addr & 0x1001) == 0x1001) {
|
||
gb->gfxboard_intena = true;
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
if (addr & 0x1000) {
|
||
addr |= 1;
|
||
}
|
||
addr &= 0x0fff;
|
||
if (size == 1) {
|
||
put_io_pcem(addr + 0, (v >> 8) & 0xff, 0);
|
||
put_io_pcem(addr + 1, (v >> 0) & 0xff, 0);
|
||
} else if (size == 0) {
|
||
put_io_pcem(addr, v & 0xff, 0);
|
||
}
|
||
}
|
||
} else if (boardnum == GFXBOARD_ID_PICCOLO_Z3 || boardnum == GFXBOARD_ID_PICCOLO_Z2 || boardnum == GFXBOARD_ID_SPECTRUM_Z3 || boardnum == GFXBOARD_ID_SPECTRUM_Z2
|
||
|| boardnum == GFXBOARD_ID_SD64_Z2 || boardnum == GFXBOARD_ID_SD64_Z3) {
|
||
if ((addr & 0x8001) == 0x8000) {
|
||
set_monswitch(gb, (v & 0x20) != 0);
|
||
gb->gfxboard_intena = (v & 0x40) != 0;
|
||
} else {
|
||
addr &= 0x0fff;
|
||
if (size == 1) {
|
||
put_io_pcem(addr + 0, (v >> 8) & 0xff, 0);
|
||
put_io_pcem(addr + 1, (v >> 0) & 0xff, 0);
|
||
} else if (size == 0) {
|
||
put_io_pcem(addr, v & 0xff, 0);
|
||
} else if (size == 2) {
|
||
put_io_pcem(addr + 0, (v >> 24) & 0xff, 0);
|
||
put_io_pcem(addr + 1, (v >> 16) & 0xff, 0);
|
||
put_io_pcem(addr + 2, (v >> 8) & 0xff, 0);
|
||
put_io_pcem(addr + 3, (v >> 0) & 0xff, 0);
|
||
}
|
||
}
|
||
} else if (boardnum == GFXBOARD_ID_PICASSO4_Z3 || boardnum == GFXBOARD_ID_PICASSO4_Z2) {
|
||
|
||
addr = (addr - gb->p4_special_start) & gb->p4_special_mask;
|
||
|
||
#if PICASSOIV_DEBUG_IO > 1
|
||
write_log(_T("PicassoIV CL REG PUT %08x %02x PC=%08x\n"), addr, v, M68K_GETPC);
|
||
#endif
|
||
|
||
if ((addr >= 0x400000 && addr < 0xa00000) || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
addr2 -= 0x800;
|
||
if (size == 2) {
|
||
gb->p4_pci[addr2 + 0] = v >> 24;
|
||
gb->p4_pci[addr2 + 1] = v >> 16;
|
||
gb->p4_pci[addr2 + 2] = v >> 8;
|
||
gb->p4_pci[addr2 + 3] = v >> 0;
|
||
p4_pci_check(gb);
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV PCI PUT %08x %08x %d\n"), addr, v, size);
|
||
#endif
|
||
} else if (addr2 >= 0x1000 && addr2 < 0x1040) {
|
||
addr2 -= 0x1000;
|
||
if (size == 0) {
|
||
gfxboard_bput_pci_pcem(addr2 ^ 3, v);
|
||
} else if (size == 1) {
|
||
gfxboard_wput_pci_pcem(addr2 ^ 3, v);
|
||
} else {
|
||
gfxboard_lput_pci_pcem(addr2 ^ 3, v);
|
||
}
|
||
//gb->cirrus_pci[addr2] = b;
|
||
// reset_pci(gb);
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV CL PCI PUT %08x %08x %d\n"), addr, v, size);
|
||
#endif
|
||
}
|
||
return;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
|
||
if (size == 0) {
|
||
if (addr == 0x404) {
|
||
gb->picassoiv_flifi = v;
|
||
picassoiv_checkswitch(gb);
|
||
} else if (addr == 0x406) {
|
||
gb->p4i2c = v;
|
||
}
|
||
}
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV MMIO PUT %08x %08x %d PC=%08x\n"), addr, v, size, M68K_GETPC);
|
||
#endif
|
||
addr -= gb->p4_mmiobase;
|
||
if (gb->p4_revb) {
|
||
if (addr < 0x100) {
|
||
goto end;
|
||
} else {
|
||
addr -= 0x100;
|
||
}
|
||
}
|
||
if (size == 2) {
|
||
v = do_byteswap_32(v);
|
||
} else if (size == 1) {
|
||
v = do_byteswap_16(v);
|
||
}
|
||
put_mem_pcem(addr + gb->pcem_mmio_offset, v, size);
|
||
picassoiv_checkswitch(gb);
|
||
// uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
// gb->vgammio->write(&gb->vga, addr2, b, 1);
|
||
goto end;
|
||
}
|
||
}
|
||
if (gb->p4z2 && addr >= 0x10000 && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH)) {
|
||
addr -= 0x10000;
|
||
if (size == 2) {
|
||
v = do_byteswap_32(v);
|
||
} else if (size == 1) {
|
||
v = do_byteswap_16(v);
|
||
}
|
||
put_io_pcem(addr, v, size);
|
||
picassoiv_checkswitch(gb);
|
||
// addr = mungeaddr(gb, addr, true);
|
||
// if (addr) {
|
||
// gb->vgaio->write(&gb->vga, addr, b & 0xff, 1);
|
||
// bput_regtest(gb, addr, b);
|
||
//write_log(_T("P4 VGA write %08x=%02x PC=%08x\n"), addr, b & 0xff, M68K_GETPC);
|
||
// }
|
||
goto end;
|
||
}
|
||
if (!(gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH)) {
|
||
if (addr >= PICASSOIV_FLASH_OFFSET / 2) {
|
||
addr /= 2;
|
||
addr += ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? PICASSOIV_FLASH_BANK : 0);
|
||
flash_write(gb->p4flashrom, addr, v);
|
||
}
|
||
}
|
||
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV BPUT %08x %08X %d\n"), addr, v, size);
|
||
#endif
|
||
if (addr == 0) {
|
||
if (size == 0) {
|
||
gb->picassoiv_bank = v;
|
||
}
|
||
}
|
||
end:;
|
||
}
|
||
}
|
||
|
||
static uae_u32 special_pcem_get(uaecptr addr, int size)
|
||
{
|
||
struct rtggfxboard *gb = getgfxboard(addr);
|
||
int boardnum = gb->rbc->rtgmem_type;
|
||
uae_u32 v = 0;
|
||
|
||
#if SPCDEBUG
|
||
// if ((addr & 0xfffff) != 0x40021)
|
||
write_log(_T("PCEM SPECIAL GET %08x %d PC=%08x\n"), addr, size, M68K_GETPC);
|
||
#endif
|
||
|
||
if (boardnum == GFXBOARD_ID_PIXEL64) {
|
||
|
||
if (size) {
|
||
v = get_io_pcem(addr + 0, 0) << 8;
|
||
v |= get_io_pcem(addr + 1, 0) << 0;
|
||
} else if (size == 0) {
|
||
v = get_io_pcem(addr, 0);
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV643D_Z2) {
|
||
|
||
uaecptr addr2 = (addr - gb->gfxboardmem_start) & gb->banksize_mask;
|
||
uaecptr addrd = addr2 + gb->gfxboardmem_start;
|
||
if (gb->pcem_pci_configured) {
|
||
// -> IO
|
||
if (addr2 >= 0x3c0000 && addr2 < 0x3c8000) {
|
||
addrd &= 0x3fff;
|
||
if (size == 0) {
|
||
addrd ^= 3;
|
||
} else if (size == 1) {
|
||
addrd ^= 2;
|
||
}
|
||
v = get_io_pcem(addrd, size);
|
||
}
|
||
} else {
|
||
if (addr2 >= 0x3c0000 && addr2 < 0x3c8000) {
|
||
if (size == 0)
|
||
v = gfxboard_bget_pci_pcem(addrd);
|
||
else if (size == 1)
|
||
v = gfxboard_wget_pci_pcem(addrd);
|
||
else
|
||
v = gfxboard_lget_pci_pcem(addrd);
|
||
}
|
||
}
|
||
if (addr2 >= 0x3c8000 && addr2 < 0x3d0000) {
|
||
if (size == 0)
|
||
v = gfxboard_bget_mmio_pcem(addrd);
|
||
else if (size == 1)
|
||
v = gfxboard_wget_mmio_pcem(addrd);
|
||
else
|
||
v = gfxboard_lget_mmio_pcem(addrd);
|
||
} else if (addr2 >= 0x3e8000 && addr2 < 0x3f0000) {
|
||
if (size == 0)
|
||
v = gfxboard_bget_mmio_pcem(addrd);
|
||
else if (size == 1)
|
||
v = gfxboard_wget_mmio_pcem(addrd);
|
||
else
|
||
v = gfxboard_lget_mmio_pcem(addrd);
|
||
} else if (addr2 >= 0x3e0000 && addr2 < 0x3e8000) {
|
||
if (size == 0)
|
||
v = gfxboard_bget_mmio_wbs_pcem(addrd);
|
||
else if (size == 1)
|
||
v = gfxboard_wget_mmio_wbs_pcem(addrd);
|
||
else
|
||
v = gfxboard_lget_mmio_wbs_pcem(addrd);
|
||
}
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV64_Z3) {
|
||
|
||
v = 0;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_CV643D_Z3) {
|
||
|
||
v = 0;
|
||
|
||
} else if (boardnum == GFXBOARD_ID_PICASSO2 || boardnum == GFXBOARD_ID_PICASSO2PLUS) {
|
||
// CL54xx
|
||
addr &= 0xffff;
|
||
if (addr & 0x8000) {
|
||
v = 0;
|
||
} else {
|
||
if (addr & 0x1000)
|
||
addr |= 1;
|
||
addr &= 0x0fff;
|
||
if (size == 1) {
|
||
v = get_io_pcem(addr + 0, 0) << 8;
|
||
v |= get_io_pcem(addr + 1, 0) << 0;
|
||
} else if (size == 0) {
|
||
v = get_io_pcem(addr, 0);
|
||
}
|
||
}
|
||
} else if (boardnum == GFXBOARD_ID_PICCOLO_Z3 || boardnum == GFXBOARD_ID_PICCOLO_Z2 || boardnum == GFXBOARD_ID_SPECTRUM_Z3 || boardnum == GFXBOARD_ID_SPECTRUM_Z2
|
||
|| boardnum == GFXBOARD_ID_SD64_Z2 || boardnum == GFXBOARD_ID_SD64_Z3) {
|
||
addr &= 0x0fff;
|
||
if (size == 1) {
|
||
v = get_io_pcem(addr + 0, 0) << 8;
|
||
v |= get_io_pcem(addr + 1, 0) << 0;
|
||
} else if (size == 0) {
|
||
v = get_io_pcem(addr, 0);
|
||
} else if (size == 2) {
|
||
v = get_io_pcem(addr + 0, 0) << 24;
|
||
v |= get_io_pcem(addr + 1, 0) << 16;
|
||
v |= get_io_pcem(addr + 2, 0) << 8;
|
||
v |= get_io_pcem(addr + 3, 0) << 0;
|
||
}
|
||
} else if (boardnum == GFXBOARD_ID_PICASSO4_Z3 || boardnum == GFXBOARD_ID_PICASSO4_Z2) {
|
||
|
||
addr = (addr - gb->p4_special_start) & gb->p4_special_mask;
|
||
|
||
// pci config
|
||
if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) {
|
||
uae_u32 addr2 = addr & 0xffff;
|
||
v = 0;
|
||
if (addr2 >= 0x0800 && addr2 < 0x840) {
|
||
if (addr2 == 0x802) {
|
||
v = 2; // bridge version?
|
||
} else if (addr2 == 0x808) {
|
||
v = 4; // bridge revision
|
||
} else {
|
||
addr2 -= 0x800;
|
||
v = gb->p4_pci[addr2];
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV PCI GET %08x %02x\n"), addr, v);
|
||
#endif
|
||
} else if (addr2 >= 0x1000 && addr2 <= 0x1040) {
|
||
if (size == 0) {
|
||
v = gfxboard_bget_pci_pcem(addr2 ^ 3);
|
||
} else if (size == 1) {
|
||
v = gfxboard_wget_pci_pcem(addr2 ^ 3);
|
||
} else {
|
||
v = gfxboard_lget_pci_pcem(addr2 ^ 3);
|
||
}
|
||
// addr2 -= 0x1000;
|
||
// v = gb->cirrus_pci[addr2];
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV CL PCI GET %08x %02x\n"), addr, v);
|
||
#endif
|
||
}
|
||
return v;
|
||
}
|
||
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
|
||
// memory mapped io
|
||
if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) {
|
||
addr -= gb->p4_mmiobase;
|
||
if (gb->p4_revb) {
|
||
if (addr < 0x100) {
|
||
return 0;
|
||
} else {
|
||
addr -= 0x100;
|
||
}
|
||
}
|
||
v = get_mem_pcem(addr + gb->pcem_mmio_offset, size);
|
||
if (size == 2) {
|
||
v = do_byteswap_32(v);
|
||
} else if (size == 1) {
|
||
v = do_byteswap_16(v);
|
||
}
|
||
// uae_u32 addr2 = addr - gb->p4_mmiobase;
|
||
// v = gb->vgammio->read(&gb->vga, addr2, 1);
|
||
#if PICASSOIV_DEBUG_IO
|
||
write_log(_T("PicassoIV MMIO GET %08x %02x\n"), addr, v & 0xff);
|
||
#endif
|
||
return v;
|
||
}
|
||
}
|
||
if (addr == 0) {
|
||
v = gb->picassoiv_bank;
|
||
return v;
|
||
}
|
||
if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
|
||
v = 0;
|
||
if (addr == 0x404) {
|
||
v = 0x70; // FLIFI revision
|
||
// FLIFI type in use
|
||
if (currprefs.chipset_mask & CSMASK_AGA)
|
||
v |= 4 | 8;
|
||
else
|
||
v |= 8;
|
||
} else if (addr == 0x406) {
|
||
// FLIFI I2C
|
||
// bit 0 = clock out
|
||
// bit 1 = data out
|
||
// bit 2 = clock in
|
||
// bit 7 = data in
|
||
v = gb->p4i2c & 3;
|
||
if (v & 1)
|
||
v |= 4;
|
||
if (v & 2)
|
||
v |= 0x80;
|
||
} else if (addr == 0x408) {
|
||
v = gb->gfxboard_intreq ? 0x80 : 0;
|
||
} else if (gb->p4z2 && addr >= 0x10000) {
|
||
addr -= 0x10000;
|
||
v = get_io_pcem(addr, size);
|
||
if (size == 2) {
|
||
v = do_byteswap_32(v);
|
||
} else if (size == 1) {
|
||
v = do_byteswap_16(v);
|
||
}
|
||
// uaecptr addr2 = mungeaddr(gb, addr, true);
|
||
// if (addr2) {
|
||
// v = gb->vgaio->read(&gb->vga, addr2, 1);
|
||
// v = bget_regtest(gb, addr2, v);
|
||
//write_log(_T("P4 VGA read %08X=%02X PC=%08x\n"), addr2, v, M68K_GETPC);
|
||
// }
|
||
//write_log (_T("PicassoIV IO %08x %02x\n"), addr, v);
|
||
return v;
|
||
}
|
||
#if PICASSOIV_DEBUG_IO
|
||
if (addr != 0x408)
|
||
write_log(_T("PicassoIV BGET %08x %02x\n"), addr, v);
|
||
#endif
|
||
} else {
|
||
if (addr < PICASSOIV_FLASH_OFFSET / 2) {
|
||
v = gb->automemory[addr];
|
||
return v;
|
||
}
|
||
addr /= 2;
|
||
addr += (gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? PICASSOIV_FLASH_BANK : 0;
|
||
v = flash_read(gb->p4flashrom, addr);
|
||
}
|
||
|
||
}
|
||
return v;
|
||
}
|
||
|
||
static uae_u32 REGPARAM2 gfxboard_bget_special_pcem(uaecptr addr)
|
||
{
|
||
uae_u32 v = special_pcem_get(addr, 0);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_wget_special_pcem(uaecptr addr)
|
||
{
|
||
uae_u32 v = special_pcem_get(addr, 1);
|
||
return v;
|
||
}
|
||
static uae_u32 REGPARAM2 gfxboard_lget_special_pcem(uaecptr addr)
|
||
{
|
||
uae_u32 v = special_pcem_get(addr, 2);
|
||
return v;
|
||
}
|
||
|
||
static void REGPARAM2 gfxboard_bput_special_pcem(uaecptr addr, uae_u32 b)
|
||
{
|
||
special_pcem_put(addr, b, 0);
|
||
}
|
||
static void REGPARAM2 gfxboard_wput_special_pcem(uaecptr addr, uae_u32 w)
|
||
{
|
||
special_pcem_put(addr, w, 1);
|
||
}
|
||
static void REGPARAM2 gfxboard_lput_special_pcem(uaecptr addr, uae_u32 l)
|
||
{
|
||
special_pcem_put(addr, l, 2);
|
||
}
|
||
|
||
void *pcem_getvram(int size)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtggfxboard *gb = &rtggfxboards[i];
|
||
if (gb->pcemdev) {
|
||
return gb->vram;
|
||
}
|
||
}
|
||
return NULL;
|
||
}
|
||
int pcem_getvramsize(void)
|
||
{
|
||
for (int i = 0; i < MAX_RTG_BOARDS; i++) {
|
||
struct rtgboardconfig *c = &currprefs.rtgboards[i];
|
||
int type = c->rtgmem_type;
|
||
if (type >= GFXBOARD_HARDWARE) {
|
||
const struct gfxboard *gfxb = find_board(type);
|
||
if (gfxb->pcemdev) {
|
||
return c->rtgmem_size;
|
||
}
|
||
}
|
||
}
|
||
return 0;
|
||
}
|
||
|
||
|
||
bool gfxboard_isgfxboardscreen(int monid)
|
||
{
|
||
int index = rtg_visible[monid];
|
||
if (index < 0)
|
||
return false;
|
||
struct rtgboardconfig *rbc = &currprefs.rtgboards[index];
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
return gb->active && rtg_visible[monid] >= 0;
|
||
}
|
||
uae_u8 *gfxboard_getrtgbuffer(int monid, int *widthp, int *heightp, int *pitch, int *depth, uae_u8 *palette)
|
||
{
|
||
int index = rtg_visible[monid];
|
||
if (index < 0)
|
||
return NULL;
|
||
struct rtgboardconfig *rbc = &currprefs.rtgboards[index];
|
||
|
||
if (rbc->rtgmem_type < GFXBOARD_HARDWARE) {
|
||
return uaegfx_getrtgbuffer(monid, widthp, heightp, pitch, depth, palette);
|
||
}
|
||
|
||
struct rtggfxboard *gb = &rtggfxboards[rbc->rtg_index];
|
||
struct picasso_vidbuf_description *vidinfo = &picasso_vidinfo[monid];
|
||
struct picasso96_state_struct *state = &picasso96_state[monid];
|
||
|
||
if (!gb->pcemdev)
|
||
return NULL;
|
||
|
||
int width = state->VirtualWidth;
|
||
int height = state->VirtualHeight;
|
||
if (!width || !height)
|
||
return NULL;
|
||
|
||
uae_u8 *dst = xmalloc(uae_u8, width * height * 4);
|
||
if (!dst)
|
||
return NULL;
|
||
|
||
uae_u8 *d = dst;
|
||
for (int yy = 0; yy < height; yy++) {
|
||
uae_u8 *s = getpcembuffer32(32, 0, yy);
|
||
memcpy(d, s, width * 4);
|
||
d += width * 4;
|
||
}
|
||
|
||
*widthp = width;
|
||
*heightp = height;
|
||
*pitch = width * 4;
|
||
*depth = 4 * 8;
|
||
|
||
return dst;
|
||
}
|
||
void gfxboard_freertgbuffer(int monid, uae_u8 *dst)
|
||
{
|
||
int index = rtg_visible[monid];
|
||
if (index < 0) {
|
||
uaegfx_freertgbuffer(monid, dst);
|
||
return;
|
||
}
|
||
struct rtgboardconfig *rbc = &currprefs.rtgboards[index];
|
||
|
||
if (rbc->rtgmem_type < GFXBOARD_HARDWARE) {
|
||
uaegfx_freertgbuffer(monid, dst);
|
||
return;
|
||
}
|
||
|
||
xfree(dst);
|
||
}
|