WinUAE/gfxboard.cpp
2015-09-25 20:29:29 +03:00

2328 lines
60 KiB
C++
Raw Blame History

/*
* 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 MEMDEBUG 0
#define MEMDEBUGMASK 0x7fffff
#define MEMDEBUGTEST 0x1ff000
#define PICASSOIV_DEBUG_IO 0
#if MEMLOGR
static bool memlogr = false;
static bool memlogw = false;
#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 "qemuvga/qemuuaeglue.h"
#include "qemuvga/vga.h"
#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 0x8000
#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
{
const TCHAR *name;
const TCHAR *manufacturername;
const TCHAR *configname;
int manufacturer;
int model_memory;
int model_registers;
int serial;
int vrammin;
int vrammax;
int banksize;
int chiptype;
int configtype;
int irq;
bool swap;
uae_u32 romtype;
};
#define ISP4() (currprefs.rtgmem_type == GFXBOARD_PICASSO4_Z2 || currprefs.rtgmem_type == GFXBOARD_PICASSO4_Z3)
// Picasso II: 8* 4x256 (1M) or 16* 4x256 (2M)
// Piccolo: 8* 4x256 + 2* 16x256 (2M)
static struct gfxboard boards[] =
{
{
_T("Picasso II"), _T("Village Tronic"), _T("PicassoII"),
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII,
0x00020000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 0, false
},
{
_T("Picasso II+"), _T("Village Tronic"), _T("PicassoII+"),
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOII, BOARD_MODEL_REGISTERS_PICASSOII,
0x00100000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 2, false
},
{
_T("Piccolo Zorro II"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("Piccolo_Z2"),
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO,
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 2, 6, true
},
{
_T("Piccolo Zorro III"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("Piccolo_Z3"),
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO, BOARD_MODEL_REGISTERS_PICCOLO,
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5426, 3, 6, true
},
{
_T("Piccolo SD64 Zorro II"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("PiccoloSD64_Z2"),
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64,
0x00000000, 0x00200000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5434, 2, 6, true
},
{
_T("Piccolo SD64 Zorro III"), _T("Ingenieurb<EFBFBD>ro Helfrich"), _T("PiccoloSD64_Z3"),
BOARD_MANUFACTURER_PICCOLO, BOARD_MODEL_MEMORY_PICCOLO64, BOARD_MODEL_REGISTERS_PICCOLO64,
0x00000000, 0x00200000, 0x00400000, 0x04000000, CIRRUS_ID_CLGD5434, 3, 6, true
},
{
_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,
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 2, 6, true
},
{
_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,
0x00000000, 0x00100000, 0x00200000, 0x00200000, CIRRUS_ID_CLGD5428, 3, 6, true
},
{
_T("Picasso IV Zorro II"), _T("Village Tronic"), _T("PicassoIV_Z2"),
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, BOARD_MODEL_REGISTERS_PICASSOIV,
0x00000000, 0x00400000, 0x00400000, 0x00400000, CIRRUS_ID_CLGD5446, 2, 2, false,
ROMTYPE_PICASSOIV
},
{
// REG:00600000 IO:00200000 VRAM:01000000
_T("Picasso IV Zorro III"), _T("Village Tronic"), _T("PicassoIV_Z3"),
BOARD_MANUFACTURER_PICASSO, BOARD_MODEL_MEMORY_PICASSOIV, 0,
0x00000000, 0x00400000, 0x00400000, 0x04000000, CIRRUS_ID_CLGD5446, 3, 2, false,
ROMTYPE_PICASSOIV
},
{
_T("A2410"), _T("Commodore"), _T("A2410"),
1030, 0, 0,
0x00000000, 0x00200000, 0x00200000, 0x00000000, 0, 0, 2, false
},
{
_T("x86 bridgeboard VGA"), _T("x86"), _T("VGA"),
0, 0, 0,
0x00000000, 0x00100000, 0x00100000, 0x00000000, CIRRUS_ID_CLGD5426, 0, 0, false,
ROMTYPE_x86_VGA
},
{
NULL
}
};
static TCHAR memorybankname[40];
static TCHAR wbsmemorybankname[40];
static TCHAR lbsmemorybankname[40];
static TCHAR regbankname[40];
static int configured_mem, configured_regs;
static struct gfxboard *board;
static uae_u8 expamem_lo;
static uae_u8 *automemory;
static uae_u32 banksize_mask;
static uae_u8 picassoiv_bank, picassoiv_flifi;
static uae_u8 p4autoconfig[256];
static struct zfile *p4rom;
static bool p4z2;
static uae_u32 p4_mmiobase;
static uae_u32 p4_special_mask;
static uae_u32 p4_vram_bank[2];
static CirrusVGAState vga;
static uae_u8 *vram, *vramrealstart;
static int vram_start_offset;
static uae_u32 gfxboardmem_start;
static bool monswitch_current, monswitch_new;
static bool monswitch_reset;
static int monswitch_delay;
static int fullrefresh;
static bool modechanged;
static uae_u8 *gfxboard_surface, *fakesurface_surface;
static bool gfxboard_vblank;
static bool gfxboard_intena;
static bool vram_enabled, vram_offset_enabled;
static hwaddr vram_offset[2];
static uae_u8 cirrus_pci[0x44];
static uae_u8 p4_pci[0x44];
static int vga_width, vga_height;
static bool vga_refresh_active;
static bool vga_changed;
static uae_u32 vgaioregionptr, vgavramregionptr, vgabank0regionptr, vgabank1regionptr;
static const MemoryRegionOps *vgaio, *vgaram, *vgalowram, *vgammio;
static MemoryRegion vgaioregion, vgavramregion;
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);
static addrbank 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, 0, 0
};
static addrbank 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, S_READ, S_WRITE
};
static addrbank 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, S_READ, S_WRITE
};
static addrbank 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, S_READ, S_WRITE
};
static addrbank 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, S_READ, S_WRITE
};
static addrbank 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 addrbank 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 void init_board (void)
{
int vramsize = board->vrammax;
vga_width = 0;
mapped_free(&gfxmem_bank);
vram_start_offset = 0;
if (ISP4() && !p4z2) // JIT direct compatibility hack
vram_start_offset = 0x01000000;
vramsize += vram_start_offset;
xfree (fakesurface_surface);
fakesurface_surface = xmalloc (uae_u8, 4 * 10000);
vram_offset[0] = vram_offset[1] = 0;
vram_enabled = true;
vram_offset_enabled = false;
if (board->manufacturer) {
gfxmem_bank.label = board->configtype == 3 ? _T("z3_gfx") : _T("z2_gfx");
} else {
gfxmem_bank.label = _T("ram_a8");
}
gfxmem_bank.allocated = vramsize;
mapped_malloc (&gfxmem_bank);
vram = gfxmem_bank.baseaddr;
vramrealstart = vram;
vram += vram_start_offset;
gfxmem_bank.baseaddr = vram;
gfxmem_bank.allocated = currprefs.rtgmem_size;
vga.vga.vram_size_mb = currprefs.rtgmem_size >> 20;
vgaioregion.opaque = &vgaioregionptr;
vgavramregion.opaque = &vgavramregionptr;
vga.vga.vram.opaque = &vgavramregionptr;
vga_common_init(&vga.vga);
cirrus_init_common(&vga, board->chiptype, 0, NULL, NULL, board->manufacturer == 0);
picasso_allocatewritewatch (currprefs.rtgmem_size);
}
static void vga_update_size(void)
{
// this forces qemu_console_resize() call
vga.vga.graphic_mode = -1;
vga.vga.hw_ops->gfx_update(&vga);
}
static bool gfxboard_setmode(void)
{
int bpp = vga.vga.get_bpp(&vga.vga);
if (bpp == 0)
bpp = 8;
vga_update_size();
if (vga_width <= 16 || vga_height <= 16)
return false;
picasso96_state.Width = vga_width;
picasso96_state.Height = vga_height;
picasso96_state.BytesPerPixel = bpp / 8;
picasso96_state.RGBFormat = RGBFB_CLUT;
write_log(_T("GFXBOARD %dx%dx%d\n"), vga_width, vga_height, bpp);
gfx_set_picasso_modeinfo(vga_width, vga_height, bpp, RGBFB_NONE);
fullrefresh = 2;
vga_changed = false;
return true;
}
bool gfxboard_toggle (int mode)
{
if (currprefs.rtgmem_type == GFXBOARD_A2410) {
return tms_toggle(mode);
}
if (vram == NULL)
return false;
if (monswitch_current) {
vga_width = 0;
monswitch_new = false;
monswitch_delay = 1;
picasso_requested_on = 0;
return true;
} else {
vga_update_size();
if (vga_width > 16 && vga_height > 16) {
if (!gfxboard_setmode())
return false;
monswitch_new = true;
monswitch_delay = 1;
picasso_requested_on = 1;
return true;
}
}
return false;
}
static bool gfxboard_checkchanged (void)
{
int bpp = vga.vga.get_bpp (&vga.vga);
if (bpp == 0)
bpp = 8;
if (vga_width <= 16 || vga_height <= 16)
return false;
if (picasso96_state.Width != vga_width ||
picasso96_state.Height != vga_height ||
picasso96_state.BytesPerPixel != bpp / 8)
return true;
return false;
}
static DisplaySurface gfxsurface, fakesurface;
DisplaySurface *qemu_console_surface(QemuConsole *con)
{
if (picasso_on)
return &gfxsurface;
modechanged = true;
return &fakesurface;
}
void qemu_console_resize(QemuConsole *con, int width, int height)
{
if (width != vga_width || vga_height != height)
vga_changed = true;
vga_width = width;
vga_height = height;
}
void linear_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
{
}
void vga_memory_region_set_dirty(MemoryRegion *mr, hwaddr addr, hwaddr size)
{
if (vga.vga.graphic_mode != 1)
return;
if (!fullrefresh)
fullrefresh = 1;
}
#if 0
static uae_u8 pal64 (uae_u8 v)
{
v = (v << 2) | ((v >> 2) & 3);
return v;
}
#endif
DisplaySurface* qemu_create_displaysurface_from(int width, int height, int bpp,
int linesize, uint8_t *data,
bool byteswap)
{
modechanged = true;
return &fakesurface;
}
int surface_bits_per_pixel(DisplaySurface *s)
{
if (s == &fakesurface)
return 32;
return picasso_vidinfo.pixbytes * 8;
}
int surface_bytes_per_pixel(DisplaySurface *s)
{
if (s == &fakesurface)
return 4;
return picasso_vidinfo.pixbytes;
}
int surface_stride(DisplaySurface *s)
{
if (s == &fakesurface || !vga_refresh_active)
return 0;
if (gfxboard_surface == NULL)
gfxboard_surface = gfx_lock_picasso (false, false);
return picasso_vidinfo.rowbytes;
}
uint8_t *surface_data(DisplaySurface *s)
{
if (vga_changed)
return NULL;
if (s == &fakesurface || !vga_refresh_active)
return fakesurface_surface;
if (gfxboard_surface == NULL)
gfxboard_surface = gfx_lock_picasso (false, false);
return gfxboard_surface;
}
void gfxboard_refresh (void)
{
fullrefresh = 2;
}
void gfxboard_hsync_handler(void)
{
if (currprefs.rtgmem_type == GFXBOARD_A2410) {
tms_hsync_handler();
}
}
void gfxboard_vsync_handler (void)
{
if (currprefs.rtgmem_type == GFXBOARD_A2410) {
tms_vsync_handler();
return;
}
if (!configured_mem || !configured_regs)
return;
if (monswitch_current && (modechanged || gfxboard_checkchanged ())) {
modechanged = false;
if (!gfxboard_setmode ()) {
picasso_requested_on = 0;
return;
}
init_hz_p96 ();
picasso_requested_on = 1;
return;
}
if (monswitch_new != monswitch_current) {
if (monswitch_delay > 0)
monswitch_delay--;
if (monswitch_delay == 0) {
if (!monswitch_new)
picasso_requested_on = 0;
monswitch_current = monswitch_new;
vga_update_size();
write_log (_T("GFXBOARD ACTIVE=%d\n"), monswitch_current);
}
} else {
monswitch_delay = 0;
}
if (!monswitch_delay && monswitch_current && picasso_on && picasso_requested_on && !vga_changed) {
picasso_getwritewatch (vram_start_offset);
if (fullrefresh)
vga.vga.graphic_mode = -1;
vga_refresh_active = true;
vga.vga.hw_ops->gfx_update(&vga);
vga_refresh_active = false;
}
if (picasso_on && !vga_changed) {
if (currprefs.leds_on_screen & STATUSLINE_RTG) {
if (gfxboard_surface == NULL) {
gfxboard_surface = gfx_lock_picasso (false, false);
}
if (gfxboard_surface) {
if (!(currprefs.leds_on_screen & STATUSLINE_TARGET))
picasso_statusline (gfxboard_surface);
}
}
if (fullrefresh > 0)
fullrefresh--;
}
if (gfxboard_surface)
gfx_unlock_picasso (true);
gfxboard_surface = NULL;
// Vertical Sync End Register, 0x20 = Disable Vertical Interrupt, 0x10 = Clear Vertical Interrupt.
if (board->irq) {
if ((!(vga.vga.cr[0x11] & 0x20) && (vga.vga.cr[0x11] & 0x10) && !(vga.vga.gr[0x17] & 4))) {
if (gfxboard_intena) {
gfxboard_vblank = true;
if (board->irq == 2)
INTREQ (0x8000 | 0x0008);
else
INTREQ (0x8000 | 0x2000);
}
}
}
}
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 (x, y, w, h);
}
void memory_region_init_alias(MemoryRegion *mr,
const char *name,
MemoryRegion *orig,
hwaddr offset,
uint64_t size)
{
if (!stricmp(name, "vga.bank0")) {
mr->opaque = &vgabank0regionptr;
} else if (!stricmp(name, "vga.bank1")) {
mr->opaque = &vgabank1regionptr;
}
}
static void jit_reset (void)
{
#ifdef JIT
if (currprefs.cachesize && (!currprefs.comptrustbyte || !currprefs.comptrustword || !currprefs.comptrustlong)) {
flush_icache (0, 3);
}
#endif
}
static void remap_vram (hwaddr offset0, hwaddr offset1, bool enabled)
{
jit_reset ();
vram_offset[0] = offset0;
vram_offset[1] = offset1;
#if VRAMLOG
if (vram_enabled != enabled)
write_log (_T("VRAM state=%d\n"), enabled);
bool was_vram_offset_enabled = vram_offset_enabled;
#endif
vram_enabled = enabled && (vga.vga.sr[0x07] & 0x01);
#if 0
vram_enabled = false;
#endif
// offset==0 and offset1==0x8000: linear vram mapping
vram_offset_enabled = offset0 != 0 || offset1 != 0x8000;
#if VRAMLOG
if (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)
{
if (mr->opaque == &vgabank0regionptr) {
if (offset != vram_offset[0]) {
//write_log (_T("vgavramregion0 %08x\n"), offset);
remap_vram (offset, vram_offset[1], vram_enabled);
}
} else if (mr->opaque == &vgabank1regionptr) {
if (offset != vram_offset[1]) {
//write_log (_T("vgavramregion1 %08x\n"), offset);
remap_vram (vram_offset[0], offset, vram_enabled);
}
} else if (mr->opaque == &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)
{
if (mr->opaque == &vgabank0regionptr || mr->opaque == &vgabank1regionptr) {
if (enabled != vram_enabled) {
//write_log (_T("enable vgavramregion %d\n"), enabled);
remap_vram (vram_offset[0], vram_offset[1], enabled);
}
} else if (mr->opaque == &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)
{
if (mr->opaque != &vgavramregionptr)
return false;
//write_log (_T("memory_region_get_dirty %08x %08x\n"), addr, size);
if (fullrefresh)
return true;
return picasso_is_vram_dirty (addr + 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 (void)
{
uaecptr b0, b1;
b0 = p4_pci[0x10 + 2] << 16;
b1 = p4_pci[0x14 + 2] << 16;
p4_vram_bank[0] = b0;
p4_vram_bank[1] = b1;
#if PICASSOIV_DEBUG_IO
write_log (_T("%08X %08X\n"), p4_vram_bank[0], p4_vram_bank[1]);
#endif
}
static void reset_pci (void)
{
cirrus_pci[0] = 0x00;
cirrus_pci[1] = 0xb8;
cirrus_pci[2] = 0x10;
cirrus_pci[3] = 0x13;
cirrus_pci[4] = 2;
cirrus_pci[5] = 0;
cirrus_pci[6] = 0;
cirrus_pci[7] &= ~(1 | 2 | 32);
cirrus_pci[8] = 3;
cirrus_pci[9] = 0;
cirrus_pci[10] = 0;
cirrus_pci[11] = 68;
cirrus_pci[0x10] &= ~1; // B revision
cirrus_pci[0x13] &= ~1; // memory
}
static void set_monswitch(bool newval)
{
if (monswitch_new == newval)
return;
monswitch_new = newval;
monswitch_delay = MONITOR_SWITCH_DELAY;
}
static void picassoiv_checkswitch (void)
{
if (ISP4()) {
bool rtg_active = (picassoiv_flifi & 1) == 0 || (vga.vga.cr[0x51] & 8) == 0;
// do not switch to P4 RTG until monitor switch is set to native at least
// once after reset.
if (monswitch_reset && rtg_active)
return;
monswitch_reset = false;
set_monswitch(rtg_active);
}
}
static void bput_regtest (uaecptr addr, uae_u8 v)
{
addr += 0x3b0;
if (addr == 0x3d5) { // CRxx
if (vga.vga.cr_index == 0x11) {
if (!(vga.vga.cr[0x11] & 0x10)) {
gfxboard_vblank = false;
}
}
}
if (!(vga.vga.sr[0x07] & 0x01) && vram_enabled) {
remap_vram (vram_offset[0], vram_offset[1], false);
}
picassoiv_checkswitch ();
}
static uae_u8 bget_regtest (uaecptr addr, uae_u8 v)
{
addr += 0x3b0;
// Input Status 0
if (addr == 0x3c2) {
if (gfxboard_vblank) {
// Disable Vertical Interrupt == 0?
// Clear Vertical Interrupt == 1
// GR17 bit 2 = INTR disable
if (!(vga.vga.cr[0x11] & 0x20) && (vga.vga.cr[0x11] & 0x10) && !(vga.vga.gr[0x17] & 4)) {
v |= 0x80; // VGA Interrupt Pending
}
}
v |= 0x10; // DAC sensing
}
if (addr == 0x3c5) {
if (vga.vga.sr_index == 8) {
// TODO: DDC
}
}
return v;
}
void vga_io_put(int portnum, uae_u8 v)
{
if (!vgaio)
return;
portnum -= 0x3b0;
bput_regtest(portnum, v);
vgaio->write(&vga, portnum, v, 1);
}
uae_u8 vga_io_get(int portnum)
{
uae_u8 v = 0xff;
if (!vgaio)
return v;
portnum -= 0x3b0;
v = vgaio->read(&vga, portnum, 1);
v = bget_regtest(portnum, v);
return v;
}
void vga_ram_put(int offset, uae_u8 v)
{
if (!vgalowram)
return;
offset -= 0xa0000;
vgalowram->write(&vga, offset, v, 1);
}
uae_u8 vga_ram_get(int offset)
{
if (!vgalowram)
return 0xff;
offset -= 0xa0000;
return vgalowram->read(&vga, offset, 1);
}
void *memory_region_get_ram_ptr(MemoryRegion *mr)
{
if (mr->opaque == &vgavramregionptr)
return vram;
return NULL;
}
void memory_region_init_ram(MemoryRegion *mr,
const char *name,
uint64_t size)
{
if (!stricmp (name, "vga.vram")) {
vgavramregion.opaque = mr->opaque;
}
}
void memory_region_init_io(MemoryRegion *mr,
const MemoryRegionOps *ops,
void *opaque,
const char *name,
uint64_t size)
{
if (!stricmp (name, "cirrus-io")) {
vgaio = ops;
mr->opaque = vgaioregion.opaque;
} else if (!stricmp (name, "cirrus-linear-io")) {
vgaram = ops;
} else if (!stricmp (name, "cirrus-low-memory")) {
vgalowram = ops;
} else if (!stricmp (name, "cirrus-mmio")) {
vgammio = ops;
}
}
int is_surface_bgr(DisplaySurface *surface)
{
return board->swap;
}
static uaecptr fixaddr_bs (uaecptr addr, int mask, int *bs)
{
bool swapped = false;
addr &= gfxmem_bank.mask;
if (p4z2) {
if (addr < 0x200000) {
addr |= 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 |= 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 && (vram_offset_enabled || !vram_enabled || swapped || p4z2))
special_mem |= mask;
#endif
if (vram_offset_enabled) {
if (addr & 0x8000) {
addr += vram_offset[1] & ~0x8000;
} else {
addr += vram_offset[0];
}
}
addr &= gfxmem_bank.mask;
return addr;
}
STATIC_INLINE uaecptr fixaddr (uaecptr addr, int mask)
{
#ifdef JIT
if (mask && (vram_offset_enabled || !vram_enabled))
special_mem |= mask;
#endif
if (vram_offset_enabled) {
if (addr & 0x8000) {
addr += vram_offset[1] & ~0x8000;
} else {
addr += vram_offset[0];
}
}
addr &= gfxmem_bank.mask;
return addr;
}
STATIC_INLINE uaecptr fixaddr (uaecptr addr)
{
if (vram_offset_enabled) {
if (addr & 0x8000) {
addr += vram_offset[1] & ~0x8000;
} else {
addr += vram_offset[0];
}
}
addr &= gfxmem_bank.mask;
return addr;
}
STATIC_INLINE const MemoryRegionOps *getvgabank (uaecptr *paddr)
{
uaecptr addr = *paddr;
addr &= gfxmem_bank.mask;
*paddr = addr;
return vgaram;
}
static uae_u32 gfxboard_lget_vram (uaecptr addr, int bs)
{
uae_u32 v;
if (!vram_enabled) {
const MemoryRegionOps *bank = getvgabank (&addr);
addr &= gfxmem_bank.mask;
if (bs < 0) { // WORD
v = bank->read (&vga, addr + 1, 1) << 24;
v |= bank->read (&vga, addr + 0, 1) << 16;
v |= bank->read (&vga, addr + 3, 1) << 8;
v |= bank->read (&vga, addr + 2, 1) << 0;
} else if (bs > 0) { // LONG
v = bank->read (&vga, addr + 3, 1) << 24;
v |= bank->read (&vga, addr + 2, 1) << 16;
v |= bank->read (&vga, addr + 1, 1) << 8;
v |= bank->read (&vga, addr + 0, 1) << 0;
} else {
v = bank->read (&vga, addr + 0, 1) << 24;
v |= bank->read (&vga, addr + 1, 1) << 16;
v |= bank->read (&vga, addr + 2, 1) << 8;
v |= bank->read (&vga, addr + 3, 1) << 0;
}
} else {
uae_u8 *m = 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, vram_enabled);
#endif
return v;
}
static uae_u16 gfxboard_wget_vram (uaecptr addr, int bs)
{
uae_u32 v;
if (!vram_enabled) {
const MemoryRegionOps *bank = getvgabank (&addr);
if (bs) {
v = bank->read (&vga, addr + 0, 1) << 0;
v |= bank->read (&vga, addr + 1, 1) << 8;
} else {
v = bank->read (&vga, addr + 0, 1) << 8;
v |= bank->read (&vga, addr + 1, 1) << 0;
}
} else {
uae_u8 *m = 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, vram_enabled);
#endif
return v;
}
static uae_u8 gfxboard_bget_vram (uaecptr addr, int bs)
{
uae_u32 v;
if (!vram_enabled) {
const MemoryRegionOps *bank = getvgabank (&addr);
if (bs)
v = bank->read (&vga, addr ^ 1, 1);
else
v = bank->read (&vga, addr + 0, 1);
} else {
if (bs)
v = vram[addr ^ 1];
else
v = 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, vram_enabled);
#endif
return v;
}
static void gfxboard_lput_vram (uaecptr addr, uae_u32 l, int bs)
{
#if MEMDEBUG
if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && l)
write_log (_T("%08X L %08X\n"), addr, l);
#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 (!vram_enabled) {
const MemoryRegionOps *bank = getvgabank (&addr);
if (bs < 0) { // WORD
bank->write (&vga, addr + 1, l >> 24, 1);
bank->write (&vga, addr + 0, (l >> 16) & 0xff, 1);
bank->write (&vga, addr + 3, (l >> 8) & 0xff, 1);
bank->write (&vga, addr + 2, (l >> 0) & 0xff, 1);
} else if (bs > 0) { // LONG
bank->write (&vga, addr + 3, l >> 24, 1);
bank->write (&vga, addr + 2, (l >> 16) & 0xff, 1);
bank->write (&vga, addr + 1, (l >> 8) & 0xff, 1);
bank->write (&vga, addr + 0, (l >> 0) & 0xff, 1);
} else {
bank->write (&vga, addr + 0, l >> 24, 1);
bank->write (&vga, addr + 1, (l >> 16) & 0xff, 1);
bank->write (&vga, addr + 2, (l >> 8) & 0xff, 1);
bank->write (&vga, addr + 3, (l >> 0) & 0xff, 1);
}
} else {
uae_u8 *m = 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 (uaecptr addr, uae_u16 w, int bs)
{
#if MEMDEBUG
if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && w)
write_log (_T("%08X W %04X\n"), addr, w & 0xffff);
#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 (!vram_enabled) {
const MemoryRegionOps *bank = getvgabank (&addr);
if (bs) {
bank->write (&vga, addr + 0, (w >> 0) & 0xff, 1);
bank->write (&vga, addr + 1, w >> 8, 1);
} else {
bank->write (&vga, addr + 0, w >> 8, 1);
bank->write (&vga, addr + 1, (w >> 0) & 0xff, 1);
}
} else {
uae_u8 *m = vram + addr;
if (bs)
*((uae_u16*)m) = w;
else
do_put_mem_word ((uae_u16*)m, w);
}
}
static void gfxboard_bput_vram (uaecptr addr, uae_u8 b, int bs)
{
#if MEMDEBUG
if ((addr & MEMDEBUGMASK) >= MEMDEBUGTEST && b)
write_log (_T("%08X B %02X\n"), addr, b & 0xff);
#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 (!vram_enabled) {
const MemoryRegionOps *bank = getvgabank (&addr);
#ifdef JIT
special_mem |= S_WRITE;
#endif
if (bs)
bank->write (&vga, addr ^ 1, b, 1);
else
bank->write (&vga, addr, b, 1);
} else {
if (bs)
vram[addr ^ 1] = b;
else
vram[addr] = b;
}
}
// LONG byteswapped VRAM
static uae_u32 REGPARAM2 gfxboard_lget_lbsmem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_lget_vram (addr, BYTESWAP_LONG);
}
static uae_u32 REGPARAM2 gfxboard_wget_lbsmem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_wget_vram (addr, BYTESWAP_LONG);
}
static uae_u32 REGPARAM2 gfxboard_bget_lbsmem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_bget_vram (addr, BYTESWAP_LONG);
}
static void REGPARAM2 gfxboard_lput_lbsmem (uaecptr addr, uae_u32 l)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return;
gfxboard_lput_vram (addr, l, BYTESWAP_LONG);
}
static void REGPARAM2 gfxboard_wput_lbsmem (uaecptr addr, uae_u32 w)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return;
gfxboard_wput_vram (addr, w, BYTESWAP_LONG);
}
static void REGPARAM2 gfxboard_bput_lbsmem (uaecptr addr, uae_u32 w)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return;
gfxboard_bput_vram (addr, w, BYTESWAP_LONG);
}
// WORD byteswapped VRAM
static uae_u32 REGPARAM2 gfxboard_lget_wbsmem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_lget_vram (addr, BYTESWAP_WORD);
}
static uae_u32 REGPARAM2 gfxboard_wget_wbsmem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_wget_vram (addr, BYTESWAP_WORD);
}
static uae_u32 REGPARAM2 gfxboard_bget_wbsmem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_bget_vram (addr, BYTESWAP_WORD);
}
static void REGPARAM2 gfxboard_lput_wbsmem (uaecptr addr, uae_u32 l)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return;
gfxboard_lput_vram (addr, l, BYTESWAP_WORD);
}
static void REGPARAM2 gfxboard_wput_wbsmem (uaecptr addr, uae_u32 w)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return;
gfxboard_wput_vram (addr, w, BYTESWAP_WORD);
}
static void REGPARAM2 gfxboard_bput_wbsmem (uaecptr addr, uae_u32 w)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return;
gfxboard_bput_vram (addr, w, BYTESWAP_WORD);
}
// normal or byteswapped (banked) vram
static uae_u32 REGPARAM2 gfxboard_lget_nbsmem (uaecptr addr)
{
int bs = 0;
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr_bs (addr, 0, &bs);
if (addr == -1)
return 0;
// activate_debugger();
return gfxboard_lget_vram (addr, bs);
}
static uae_u32 REGPARAM2 gfxboard_wget_nbsmem (uaecptr addr)
{
int bs = 0;
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr_bs (addr, 0, &bs);
if (addr == -1)
return 0;
return gfxboard_wget_vram (addr, bs);
}
static void REGPARAM2 gfxboard_lput_nbsmem (uaecptr addr, uae_u32 l)
{
int bs = 0;
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr_bs (addr, 0, &bs);
if (addr == -1)
return;
gfxboard_lput_vram (addr, l, bs);
}
static void REGPARAM2 gfxboard_wput_nbsmem (uaecptr addr, uae_u32 w)
{
int bs = 0;
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr_bs (addr, 0, &bs);
if (addr == -1)
return;
gfxboard_wput_vram (addr, w, bs);
}
static uae_u32 REGPARAM2 gfxboard_bget_bsmem (uaecptr addr)
{
int bs = 0;
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, 0);
if (addr == -1)
return 0;
return gfxboard_bget_vram (addr, bs);
}
static void REGPARAM2 gfxboard_bput_bsmem (uaecptr addr, uae_u32 b)
{
int bs = 0;
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr_bs (addr, 0, &bs);
if (addr == -1)
return;
gfxboard_bput_vram (addr, b, bs);
}
// normal vram
static uae_u32 REGPARAM2 gfxboard_lget_mem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, S_READ);
if (addr == -1)
return 0;
return gfxboard_lget_vram (addr, 0);
}
static uae_u32 REGPARAM2 gfxboard_wget_mem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, S_READ);
if (addr == -1)
return 0;
return gfxboard_wget_vram (addr, 0);
}
static uae_u32 REGPARAM2 gfxboard_bget_mem (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, S_READ);
if (addr == -1)
return 0;
return gfxboard_bget_vram (addr, 0);
}
static void REGPARAM2 gfxboard_lput_mem (uaecptr addr, uae_u32 l)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, S_WRITE);
if (addr == -1)
return;
gfxboard_lput_vram (addr, l, 0);
}
static void REGPARAM2 gfxboard_wput_mem (uaecptr addr, uae_u32 w)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, S_WRITE);
if (addr == -1)
return;
gfxboard_wput_vram (addr, w, 0);
}
static void REGPARAM2 gfxboard_bput_mem (uaecptr addr, uae_u32 b)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr, S_WRITE);
if (addr == -1)
return;
gfxboard_bput_vram (addr, b, 0);
}
// normal vram, no jit direct
static uae_u32 REGPARAM2 gfxboard_lget_mem_nojit (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr);
if (addr == -1)
return 0;
return gfxboard_lget_vram (addr, 0);
}
static uae_u32 REGPARAM2 gfxboard_wget_mem_nojit (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr);
if (addr == -1)
return 0;
return gfxboard_wget_vram (addr, 0);
}
static uae_u32 REGPARAM2 gfxboard_bget_mem_nojit (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr);
if (addr == -1)
return 0;
return gfxboard_bget_vram (addr, 0);
}
static void REGPARAM2 gfxboard_lput_mem_nojit (uaecptr addr, uae_u32 l)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr);
if (addr == -1)
return;
gfxboard_lput_vram (addr, l, 0);
}
static void REGPARAM2 gfxboard_wput_mem_nojit (uaecptr addr, uae_u32 w)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr);
if (addr == -1)
return;
gfxboard_wput_vram (addr, w, 0);
}
static void REGPARAM2 gfxboard_bput_mem_nojit (uaecptr addr, uae_u32 b)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr = fixaddr (addr);
if (addr == -1)
return;
gfxboard_bput_vram (addr, b, 0);
}
static int REGPARAM2 gfxboard_check (uaecptr addr, uae_u32 size)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr &= gfxmem_bank.mask;
return (addr + size) <= currprefs.rtgmem_size;
}
static uae_u8 *REGPARAM2 gfxboard_xlate (uaecptr addr)
{
addr -= gfxboardmem_start & gfxmem_bank.mask;
addr &= gfxmem_bank.mask;
return vram + addr;
}
static uae_u32 REGPARAM2 gfxboard_bget_mem_autoconfig (uaecptr addr)
{
uae_u32 v = 0;
addr &= 65535;
if (addr < GFXBOARD_AUTOCONFIG_SIZE)
v = automemory[addr];
return v;
}
static void REGPARAM2 gfxboard_wput_mem_autoconfig (uaecptr addr, uae_u32 b)
{
if (board->configtype == 2)
return;
b &= 0xffff;
addr &= 65535;
if (addr == 0x44) {
uae_u32 start;
if (!expamem_z3hack(&currprefs)) {
start = (b & 0xff00) | expamem_lo;
gfxmem_bank.start = start << 16;
}
gfxboard_bank_memory.bget = gfxboard_bget_mem;
gfxboard_bank_memory.bput = gfxboard_bput_mem;
gfxboard_bank_memory.wput = gfxboard_wput_mem;
init_board ();
if (ISP4()) {
if (validate_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, expamem_z3_size >> 16)) {
// main vram
map_banks_z3(&gfxboard_bank_memory, (gfxmem_bank.start + PICASSOIV_VRAM1) >> 16, 0x400000 >> 16);
map_banks_z3(&gfxboard_bank_wbsmemory, (gfxmem_bank.start + PICASSOIV_VRAM1 + 0x400000) >> 16, 0x400000 >> 16);
// secondary
map_banks_z3(&gfxboard_bank_memory_nojit, (gfxmem_bank.start + PICASSOIV_VRAM2) >> 16, 0x400000 >> 16);
map_banks_z3(&gfxboard_bank_wbsmemory, (gfxmem_bank.start + PICASSOIV_VRAM2 + 0x400000) >> 16, 0x400000 >> 16);
// regs
map_banks_z3(&gfxboard_bank_registers, (gfxmem_bank.start + PICASSOIV_REG) >> 16, 0x200000 >> 16);
map_banks_z3(&gfxboard_bank_special, gfxmem_bank.start >> 16, PICASSOIV_REG >> 16);
}
picassoiv_bank = 0;
picassoiv_flifi = 1;
configured_regs = gfxmem_bank.start >> 16;
} else {
map_banks_z3(&gfxboard_bank_memory, gfxmem_bank.start >> 16, board->banksize >> 16);
}
configured_mem = gfxmem_bank.start >> 16;
gfxboardmem_start = gfxmem_bank.start;
expamem_next (&gfxboard_bank_memory, NULL);
return;
}
if (addr == 0x4c) {
configured_mem = 0xff;
expamem_shutup(&gfxboard_bank_memory);
return;
}
}
static void REGPARAM2 gfxboard_bput_mem_autoconfig (uaecptr addr, uae_u32 b)
{
b &= 0xff;
addr &= 65535;
if (addr == 0x48) {
if (board->configtype == 2) {
addrbank *ab;
if (ISP4()) {
ab = &gfxboard_bank_nbsmemory;
if (configured_mem == 0)
init_board ();
map_banks_z2 (ab, b, 0x00200000 >> 16);
if (configured_mem == 0) {
configured_mem = b;
gfxboardmem_start = b << 16;
} else {
gfxboard_bank_memory.bget = gfxboard_bget_mem;
gfxboard_bank_memory.bput = gfxboard_bput_mem;
}
} else {
ab = &gfxboard_bank_memory;
gfxboard_bank_memory.bget = gfxboard_bget_mem;
gfxboard_bank_memory.bput = gfxboard_bput_mem;
init_board ();
map_banks_z2 (ab, b, board->banksize >> 16);
configured_mem = b;
gfxboardmem_start = b << 16;
}
expamem_next (ab, NULL);
} else {
expamem_lo = b & 0xff;
}
return;
}
if (addr == 0x4c) {
configured_mem = 0xff;
expamem_shutup(&gfxboard_bank_memory);
return;
}
}
static uaecptr mungeaddr (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 (board->manufacturer == BOARD_MANUFACTURER_PICASSO) {
if (addr == 0x1001) {
gfxboard_intena = true;
return 0;
}
if (addr == 0x1000) {
gfxboard_intena = false;
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)
{
uae_u32 v = 0xffffffff;
addr = mungeaddr (addr, false);
if (addr)
v = vgaio->read (&vga, addr, 4);
return v;
}
static uae_u32 REGPARAM2 gfxboard_wget_regs (uaecptr addr)
{
uae_u16 v = 0xffff;
addr = mungeaddr (addr, false);
if (addr) {
uae_u8 v1, v2;
v1 = vgaio->read (&vga, addr + 0, 1);
v1 = bget_regtest (addr + 0, v1);
v2 = vgaio->read (&vga, addr + 1, 1);
v2 = bget_regtest (addr + 1, v2);
v = (v1 << 8) | v2;
}
return v;
}
static uae_u32 REGPARAM2 gfxboard_bget_regs (uaecptr addr)
{
uae_u8 v = 0xff;
addr &= 65535;
if (addr >= 0x8000) {
write_log (_T("GFX SPECIAL BGET IO %08X\n"), addr);
return 0;
}
addr = mungeaddr (addr, false);
if (addr) {
v = vgaio->read (&vga, addr, 1);
v = bget_regtest (addr, v);
}
return v;
}
static void REGPARAM2 gfxboard_lput_regs (uaecptr addr, uae_u32 l)
{
//write_log (_T("GFX LONG PUT IO %04X = %04X\n"), addr & 65535, l);
addr = mungeaddr (addr, true);
if (addr) {
vgaio->write (&vga, addr + 0, l >> 24, 1);
bput_regtest (addr + 0, (l >> 24));
vgaio->write (&vga, addr + 1, (l >> 16) & 0xff, 1);
bput_regtest (addr + 0, (l >> 16));
vgaio->write (&vga, addr + 2, (l >> 8) & 0xff, 1);
bput_regtest (addr + 0, (l >> 8));
vgaio->write (&vga, addr + 3, (l >> 0) & 0xff, 1);
bput_regtest (addr + 0, (l >> 0));
}
}
static void REGPARAM2 gfxboard_wput_regs (uaecptr addr, uae_u32 w)
{
//write_log (_T("GFX WORD PUT IO %04X = %04X\n"), addr & 65535, w & 0xffff);
addr = mungeaddr (addr, true);
if (addr) {
vgaio->write (&vga, addr + 0, (w >> 8) & 0xff, 1);
bput_regtest (addr + 0, (w >> 8));
vgaio->write (&vga, addr + 1, (w >> 0) & 0xff, 1);
bput_regtest (addr + 1, (w >> 0));
}
}
static void REGPARAM2 gfxboard_bput_regs (uaecptr addr, uae_u32 b)
{
//write_log (_T("GFX BYTE PUT IO %04X = %02X\n"), addr & 65535, b & 0xff);
addr &= 65535;
if (addr >= 0x8000) {
write_log (_T("GFX SPECIAL BPUT IO %08X = %02X\n"), addr, b & 0xff);
switch (board->manufacturer)
{
case BOARD_MANUFACTURER_PICASSO:
{
if ((addr & 1) == 0) {
int idx = addr >> 12;
if (idx == 0x0b || idx == 0x09) {
set_monswitch(false);
} else if (idx == 0x0a || idx == 0x08) {
set_monswitch(true);
}
}
}
break;
case BOARD_MANUFACTURER_PICCOLO:
case BOARD_MANUFACTURER_SPECTRUM:
set_monswitch((b & 0x20) != 0);
gfxboard_intena = (b & 0x40) != 0;
break;
}
return;
}
addr = mungeaddr (addr, true);
if (addr) {
vgaio->write (&vga, addr, b & 0xff, 1);
bput_regtest (addr, b);
}
}
static uae_u32 REGPARAM2 gfxboard_bget_regs_autoconfig (uaecptr addr)
{
uae_u32 v = 0;
addr &= 65535;
if (addr < GFXBOARD_AUTOCONFIG_SIZE)
v = automemory[addr];
return v;
}
static void REGPARAM2 gfxboard_bput_regs_autoconfig (uaecptr addr, uae_u32 b)
{
addrbank *ab;
b &= 0xff;
addr &= 65535;
if (addr == 0x48) {
gfxboard_bank_registers.bget = gfxboard_bget_regs;
gfxboard_bank_registers.bput = gfxboard_bput_regs;
if (p4z2) {
ab = &gfxboard_bank_special;
map_banks_z2(ab, b, gfxboard_bank_special.allocated >> 16);
} else {
ab = &gfxboard_bank_registers;
map_banks_z2(ab, b, gfxboard_bank_registers.allocated >> 16);
}
configured_regs = b;
expamem_next (ab, NULL);
return;
}
if (addr == 0x4c) {
configured_regs = 0xff;
expamem_next (NULL, NULL);
return;
}
}
void gfxboard_free(void)
{
if (currprefs.rtgmem_type == GFXBOARD_A2410) {
tms_free();
return;
}
if (vram) {
gfxmem_bank.baseaddr = vramrealstart;
mapped_free (&gfxmem_bank);
}
vram = NULL;
vramrealstart = NULL;
xfree (fakesurface_surface);
fakesurface_surface = NULL;
configured_mem = 0;
configured_regs = 0;
monswitch_new = false;
monswitch_current = false;
monswitch_delay = -1;
monswitch_reset = true;
modechanged = false;
gfxboard_vblank = false;
gfxboard_intena = false;
picassoiv_bank = 0;
}
void gfxboard_reset (void)
{
if (currprefs.rtgmem_type == GFXBOARD_A2410) {
tms_reset();
return;
}
if (currprefs.rtgmem_type >= GFXBOARD_HARDWARE) {
board = &boards[currprefs.rtgmem_type - GFXBOARD_HARDWARE];
gfxmem_bank.mask = currprefs.rtgmem_size - 1;
}
gfxboard_free();
if (board) {
if (board->configtype == 3)
gfxboard_bank_memory.wput = gfxboard_wput_mem_autoconfig;
if (reset_func)
reset_func (reset_parm);
}
}
static uae_u32 REGPARAM2 gfxboards_lget_regs (uaecptr addr)
{
uae_u32 v = 0;
addr &= p4_special_mask;
// pci config
if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (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 = p4_pci[addr2 + 0] << 24;
v |= p4_pci[addr2 + 1] << 16;
v |= p4_pci[addr2 + 2] << 8;
v |= 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 = cirrus_pci[addr2 + 0] << 24;
v |= cirrus_pci[addr2 + 1] << 16;
v |= cirrus_pci[addr2 + 2] << 8;
v |= 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 (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
// memory mapped io
if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
uae_u32 addr2 = addr - p4_mmiobase;
v = vgammio->read(&vga, addr2 + 0, 1) << 24;
v |= vgammio->read(&vga, addr2 + 1, 1) << 16;
v |= vgammio->read(&vga, addr2 + 2, 1) << 8;
v |= vgammio->read(&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)
{
uae_u16 v = 0;
addr &= p4_special_mask;
// pci config
if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (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 = p4_pci[addr2 + 0] << 8;
v |= 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 = cirrus_pci[addr2 + 0] << 8;
v |= 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 (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
// memory mapped io
if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
uae_u32 addr2 = addr - p4_mmiobase;
v = vgammio->read(&vga, addr2 + 0, 1) << 8;
v |= vgammio->read(&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)
{
uae_u8 v = 0xff;
addr &= p4_special_mask;
// pci config
if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (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) {
addr2 -= 0x800;
v = p4_pci[addr2];
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV PCI BGET %08x %02x\n"), addr, v);
#endif
} else if (addr2 >= 0x800 && addr2 <= 0x1000) {
if (addr2 == 0x802)
v = 2; // ???
if (addr2 == 0x808)
v = 4; // bridge revision
#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 = cirrus_pci[addr2];
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV CL PCI BGET %08x %02x\n"), addr, v);
#endif
}
return v;
}
if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
// memory mapped io
if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
uae_u32 addr2 = addr - p4_mmiobase;
v = vgammio->read(&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 = picassoiv_bank;
return v;
}
if (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 == 0x408) {
v = gfxboard_vblank ? 0x80 : 0;
} else if (p4z2 && addr >= 0x10000) {
addr -= 0x10000;
uaecptr addr2 = mungeaddr (addr, true);
if (addr2) {
v = vgaio->read (&vga, addr2, 1);
v = bget_regtest (addr2, v);
}
//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) {
v = automemory[addr];
return v;
}
addr -= PICASSOIV_FLASH_OFFSET;
addr /= 2;
v = automemory[addr + PICASSOIV_FLASH_OFFSET + ((picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 : 0)];
}
return v;
}
static void REGPARAM2 gfxboards_lput_regs (uaecptr addr, uae_u32 l)
{
addr &= p4_special_mask;
if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (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
p4_pci[addr2 + 0] = l >> 24;
p4_pci[addr2 + 1] = l >> 16;
p4_pci[addr2 + 2] = l >> 8;
p4_pci[addr2 + 3] = l >> 0;
p4_pci_check ();
} 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
cirrus_pci[addr2 + 0] = l >> 24;
cirrus_pci[addr2 + 1] = l >> 16;
cirrus_pci[addr2 + 2] = l >> 8;
cirrus_pci[addr2 + 3] = l >> 0;
reset_pci ();
}
return;
}
if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
// memory mapped io
if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV MMIO LPUT %08x %08x\n"), addr, l);
#endif
uae_u32 addr2 = addr - p4_mmiobase;
vgammio->write(&vga, addr2 + 0, l >> 24, 1);
vgammio->write(&vga, addr2 + 1, l >> 16, 1);
vgammio->write(&vga, addr2 + 2, l >> 8, 1);
vgammio->write(&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)
{
uae_u16 w = (uae_u16)v;
addr &= p4_special_mask;
if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (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
p4_pci[addr2 + 0] = w >> 8;
p4_pci[addr2 + 1] = w >> 0;
p4_pci_check ();
} 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
cirrus_pci[addr2 + 0] = w >> 8;
cirrus_pci[addr2 + 1] = w >> 0;
reset_pci ();
}
return;
}
if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
// memory mapped io
if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV MMIO LPUT %08x %08x\n"), addr, w & 0xffff);
#endif
uae_u32 addr2 = addr - p4_mmiobase;
vgammio->write(&vga, addr2 + 0, w >> 8, 1);
vgammio->write(&vga, addr2 + 1, (w >> 0) & 0xff, 1);
return;
}
}
if (p4z2 && addr >= 0x10000) {
addr -= 0x10000;
addr = mungeaddr (addr, true);
if (addr) {
vgaio->write (&vga, addr + 0, w >> 8, 1);
bput_regtest (addr + 0, w >> 8);
vgaio->write (&vga, addr + 1, (w >> 0) & 0xff, 1);
bput_regtest (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)
{
uae_u8 b = (uae_u8)v;
addr &= p4_special_mask;
if (addr >= 0x400000 || (p4z2 && !(picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (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;
p4_pci[addr2] = b;
p4_pci_check ();
#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;
cirrus_pci[addr2] = b;
reset_pci ();
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV CL PCI BPUT %08x %02x\n"), addr, b & 0xff);
#endif
}
return;
}
if (picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) {
if (addr == 0x404) {
picassoiv_flifi = b;
picassoiv_checkswitch ();
}
}
if (picassoiv_bank & PICASSOIV_BANK_MAPRAM) {
// memory mapped io
if (addr >= p4_mmiobase && addr < p4_mmiobase + 0x8000) {
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV MMIO BPUT %08x %08x\n"), addr, b & 0xff);
#endif
uae_u32 addr2 = addr - p4_mmiobase;
vgammio->write(&vga, addr2, b, 1);
return;
}
}
if (p4z2 && addr >= 0x10000) {
addr -= 0x10000;
addr = mungeaddr (addr, true);
if (addr) {
vgaio->write (&vga, addr, b & 0xff, 1);
bput_regtest (addr, b);
}
return;
}
#if PICASSOIV_DEBUG_IO
write_log (_T("PicassoIV BPUT %08x %02X\n"), addr, b & 0xff);
#endif
if (addr == 0) {
picassoiv_bank = b;
}
}
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 (*)");
return boards[type - GFXBOARD_HARDWARE].name;
}
const TCHAR *gfxboard_get_manufacturername(int type)
{
if (type == GFXBOARD_UAE_Z2)
return NULL;
if (type == GFXBOARD_UAE_Z3)
return NULL;
return boards[type - GFXBOARD_HARDWARE].manufacturername;
}
const TCHAR *gfxboard_get_configname(int type)
{
if (type == GFXBOARD_UAE_Z2)
return _T("ZorroII");
if (type == GFXBOARD_UAE_Z3)
return _T("ZorroIII");
return boards[type - GFXBOARD_HARDWARE].configname;
}
int gfxboard_get_configtype(int type)
{
if (type == GFXBOARD_UAE_Z2)
return 2;
if (type == GFXBOARD_UAE_Z3)
return 3;
board = &boards[type - GFXBOARD_HARDWARE];
return board->configtype;
}
bool gfxboard_need_byteswap (int type)
{
if (type < GFXBOARD_HARDWARE)
return false;
board = &boards[type - GFXBOARD_HARDWARE];
return board->swap;
}
int gfxboard_get_autoconfig_size(int type)
{
if (type == GFXBOARD_PICASSO4_Z3)
return 32 * 1024 * 1024;
return -1;
}
int gfxboard_get_vram_min (int type)
{
if (type < GFXBOARD_HARDWARE)
return -1;
board = &boards[type - GFXBOARD_HARDWARE];
return board->vrammin;
}
int gfxboard_get_vram_max (int type)
{
if (type < GFXBOARD_HARDWARE)
return -1;
board = &boards[type - GFXBOARD_HARDWARE];
return board->vrammax;
}
bool gfxboard_is_registers (int type)
{
if (type < 2)
return false;
board = &boards[type - 2];
return board->model_registers != 0;
}
int gfxboard_num_boards (int type)
{
if (type < 2)
return 1;
board = &boards[type - 2];
if (type == GFXBOARD_PICASSO4_Z2)
return 3;
if (board->model_registers == 0)
return 1;
return 2;
}
uae_u32 gfxboard_get_romtype(int type)
{
if (type < 2)
return 0;
board = &boards[type - 2];
return board->romtype;
}
static void gfxboard_init (void)
{
if (!automemory)
automemory = xmalloc (uae_u8, GFXBOARD_AUTOCONFIG_SIZE);
memset (automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
p4z2 = false;
zfile_fclose (p4rom);
p4rom = NULL;
banksize_mask = board->banksize - 1;
memset (cirrus_pci, 0, sizeof cirrus_pci);
reset_pci ();
}
static void copyp4autoconfig (int startoffset)
{
int size = 0;
int offset = 0;
memset (automemory, 0xff, 64);
while (size < 32) {
uae_u8 b = p4autoconfig[size + startoffset];
automemory[offset] = b;
offset += 2;
size++;
}
}
static void loadp4rom (void)
{
int size, offset;
uae_u8 b;
// rom loader code
zfile_fseek (p4rom, 256, SEEK_SET);
offset = PICASSOIV_ROM_OFFSET;
size = 0;
while (size < 4096 - 256) {
if (!zfile_fread (&b, 1, 1, p4rom))
break;
automemory[offset] = b;
offset += 2;
size++;
}
// main flash code
zfile_fseek (p4rom, 16384, SEEK_SET);
zfile_fread (&automemory[PICASSOIV_FLASH_OFFSET], 1, PICASSOIV_MAX_FLASH, p4rom);
zfile_fclose (p4rom);
p4rom = NULL;
write_log (_T("PICASSOIV: flash rom loaded\n"));
}
static void ew (int addr, uae_u32 value)
{
addr &= 0xffff;
if (addr == 00 || addr == 02 || addr == 0x40 || addr == 0x42) {
automemory[addr] = (value & 0xf0);
automemory[addr + 2] = (value & 0x0f) << 4;
} else {
automemory[addr] = ~(value & 0xf0);
automemory[addr + 2] = ~((value & 0x0f) << 4);
}
}
addrbank *gfxboard_init_memory (int devnum)
{
int bank;
uae_u8 z2_flags, z3_flags, type;
gfxboard_init ();
memset (automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
z2_flags = 0x05; // 1M
z3_flags = 0x06; // 1M
bank = board->banksize;
bank /= 0x00100000;
while (bank > 1) {
z2_flags++;
z3_flags++;
bank >>= 1;
}
if (board->configtype == 3) {
type = 0x00 | 0x08 | 0x80; // 16M Z3
ew (0x08, z3_flags | 0x10 | 0x20);
} else {
type = z2_flags | 0x08 | 0xc0;
}
ew (0x04, board->model_memory);
ew (0x10, board->manufacturer >> 8);
ew (0x14, board->manufacturer);
uae_u32 ser = board->serial;
ew (0x18, ser >> 24); /* ser.no. Byte 0 */
ew (0x1c, ser >> 16); /* ser.no. Byte 1 */
ew (0x20, ser >> 8); /* ser.no. Byte 2 */
ew (0x24, ser >> 0); /* ser.no. Byte 3 */
ew (0x00, type);
if (ISP4()) {
int roms[] = { 91, -1 };
struct romlist *rl = getromlistbyids(roms, NULL);
TCHAR path[MAX_DPATH];
fetch_rompath (path, sizeof path / sizeof (TCHAR));
p4rom = read_device_rom(&currprefs, ROMTYPE_PICASSOIV, 0, roms);
if (!p4rom && currprefs.picassoivromfile[0])
p4rom = read_rom_name(currprefs.picassoivromfile);
if (!p4rom && rl)
p4rom = read_rom(rl->rd);
if (!p4rom) {
_tcscat (path, _T("picasso_iv_flash.rom"));
p4rom = read_rom_name (path);
if (!p4rom)
p4rom = read_rom_name (_T("picasso_iv_flash.rom"));
}
if (p4rom) {
zfile_fread (p4autoconfig, sizeof p4autoconfig, 1, p4rom);
copyp4autoconfig (board->configtype == 3 ? 192 : 0);
if (board->configtype == 3) {
loadp4rom ();
p4_mmiobase = 0x200000;
p4_special_mask = 0x7fffff;
} else {
p4z2 = true;
p4_mmiobase = 0x8000;
p4_special_mask = 0x1ffff;
}
gfxboard_intena = true;
} 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);
}
}
_stprintf (memorybankname, _T("%s VRAM"), board->name);
_stprintf (wbsmemorybankname, _T("%s VRAM WORDSWAP"), board->name);
_stprintf (lbsmemorybankname, _T("%s VRAM LONGSWAP"), board->name);
_stprintf (regbankname, _T("%s REG"), board->name);
gfxboard_bank_memory.name = memorybankname;
gfxboard_bank_memory_nojit.name = memorybankname;
gfxboard_bank_wbsmemory.name = wbsmemorybankname;
gfxboard_bank_lbsmemory.name = lbsmemorybankname;
gfxboard_bank_registers.name = regbankname;
gfxboard_bank_memory.bget = gfxboard_bget_mem_autoconfig;
gfxboard_bank_memory.bput = gfxboard_bput_mem_autoconfig;
if (currprefs.rtgmem_type == GFXBOARD_VGA) {
init_board();
configured_mem = 1;
configured_regs = 1;
return &expamem_null;
}
return &gfxboard_bank_memory;
}
addrbank *gfxboard_init_memory_p4_z2 (int devnum)
{
if (board->configtype == 3)
return &expamem_null;
copyp4autoconfig (64);
return &gfxboard_bank_memory;
}
addrbank *gfxboard_init_registers (int devnum)
{
if (!board->model_registers)
return &expamem_null;
memset (automemory, 0xff, GFXBOARD_AUTOCONFIG_SIZE);
ew (0x00, 0xc0 | 0x01); // 64k Z2
ew (0x04, board->model_registers);
ew (0x10, board->manufacturer >> 8);
ew (0x14, board->manufacturer);
uae_u32 ser = board->serial;
ew (0x18, ser >> 24); /* ser.no. Byte 0 */
ew (0x1c, ser >> 16); /* ser.no. Byte 1 */
ew (0x20, ser >> 8); /* ser.no. Byte 2 */
ew (0x24, ser >> 0); /* ser.no. Byte 3 */
gfxboard_bank_registers.allocated = BOARD_REGISTERS_SIZE;
if (ISP4()) {
uae_u8 v;
copyp4autoconfig (128);
loadp4rom ();
v = (((automemory[0] & 0xf0) | (automemory[2] >> 4)) & 3) - 1;
gfxboard_bank_special.allocated = 0x10000 << v;
}
gfxboard_bank_registers.bget = gfxboard_bget_regs_autoconfig;
gfxboard_bank_registers.bput = gfxboard_bput_regs_autoconfig;
return &gfxboard_bank_registers;
}