From bd55f1d94a11123b5eb4935a157e845ab05852e1 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Sun, 20 Jul 2014 17:59:52 +0300 Subject: [PATCH] Blizzard memory map emulation. --- cpuboard.cpp | 587 +++++++++++++++++++++++++++++++++++++++++++++ include/cpuboard.h | 16 ++ 2 files changed, 603 insertions(+) create mode 100644 cpuboard.cpp create mode 100644 include/cpuboard.h diff --git a/cpuboard.cpp b/cpuboard.cpp new file mode 100644 index 00000000..ed20bc49 --- /dev/null +++ b/cpuboard.cpp @@ -0,0 +1,587 @@ +/* +* UAE - The Un*x Amiga Emulator +* +* Misc accelerator board special features +* Blizzard 1230 IV, 1240/1260, 2060 +* +* Copyright 2014 Toni Wilen +* +*/ + +#include "sysconfig.h" +#include "sysdeps.h" + +#include "options.h" +#include "memory.h" +#include "zfile.h" +#include "rommgr.h" +#include "autoconf.h" +#include "cpuboard.h" +#include "custom.h" +#include "newcpu.h" + +#define BLIZZARD_RAM_BASE 0x68000000 +#define BLIZZARD_RAM_ALIAS_BASE 0x48000000 +#define BLIZZARD_MAPROM_BASE 0x4ff80000 +#define BLIZZARD_MAPROM_ENABLE 0x80ffff00 +#define BLIZZARD_BOARD_DISABLE 0x80fa0000 + +static int cpuboard_size = -1, cpuboard2_size = -1; +static int configured; +static int blizzard_jit; +static int maprom_state; +static uae_u32 maprom_base; +static int delayed_rom_protect; +static int f0rom_size, earom_size; + +static bool is_blizzard(void) +{ + return currprefs.cpuboard_type == BOARD_BLIZZARD_1230_IV || currprefs.cpuboard_type == BOARD_BLIZZARD_1260 || currprefs.cpuboard_type == BOARD_BLIZZARD_2060; +} + +extern addrbank blizzardram_bank; +extern addrbank blizzardram_nojit_bank; +extern addrbank blizzardmaprom_bank; +extern addrbank blizzardea_bank; +extern addrbank blizzardf0_bank; + +MEMORY_FUNCTIONS(blizzardram); + +addrbank blizzardram_bank = { + blizzardram_lget, blizzardram_wget, blizzardram_bget, + blizzardram_lput, blizzardram_wput, blizzardram_bput, + blizzardram_xlate, blizzardram_check, NULL, _T("Blizzard RAM"), + blizzardram_lget, blizzardram_wget, ABFLAG_RAM +}; + +MEMORY_BGET(blizzardram_nojit, 1); +MEMORY_WGET(blizzardram_nojit, 1); +MEMORY_LGET(blizzardram_nojit, 1); +MEMORY_CHECK(blizzardram_nojit); +MEMORY_XLATE(blizzardram_nojit); + +static void REGPARAM2 blizzardram_nojit_lput(uaecptr addr, uae_u32 l) +{ + uae_u32 *m; + +#ifdef JIT + special_mem |= S_WRITE; +#endif + addr &= blizzardram_nojit_bank.mask; + if (maprom_state && addr >= maprom_base) + return; + m = (uae_u32 *)(blizzardram_nojit_bank.baseaddr + addr); + do_put_mem_long(m, l); +} +static void REGPARAM2 blizzardram_nojit_wput(uaecptr addr, uae_u32 w) +{ + uae_u16 *m; + +#ifdef JIT + special_mem |= S_WRITE; +#endif + addr &= blizzardram_nojit_bank.mask; + if (maprom_state && addr >= maprom_base) + return; + m = (uae_u16 *)(blizzardram_nojit_bank.baseaddr + addr); + do_put_mem_word(m, w); +} +static void REGPARAM2 blizzardram_nojit_bput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + addr &= blizzardram_nojit_bank.mask; + if (maprom_state && addr >= maprom_base) + return; + blizzardram_nojit_bank.baseaddr[addr] = b; +} + +static addrbank blizzardram_nojit_bank = { + blizzardram_nojit_lget, blizzardram_nojit_wget, blizzardram_nojit_bget, + blizzardram_nojit_lput, blizzardram_nojit_wput, blizzardram_nojit_bput, + blizzardram_nojit_xlate, blizzardram_nojit_check, NULL, _T("Blizzard RAM"), + blizzardram_nojit_lget, blizzardram_nojit_wget, ABFLAG_RAM +}; + +MEMORY_BGET(blizzardmaprom, 1); +MEMORY_WGET(blizzardmaprom, 1); +MEMORY_LGET(blizzardmaprom, 1); +MEMORY_CHECK(blizzardmaprom); +MEMORY_XLATE(blizzardmaprom); + +static void no_rom_protect(void) +{ + if (delayed_rom_protect) + return; + delayed_rom_protect = 10; + protect_roms(false); +} + +static void REGPARAM2 blizzardmaprom_lput(uaecptr addr, uae_u32 l) +{ + uae_u32 *m; +#ifdef JIT + special_mem |= S_WRITE; +#endif + addr &= blizzardmaprom_bank.mask; + m = (uae_u32 *)(blizzardmaprom_bank.baseaddr + addr); + do_put_mem_long(m, l); + if (maprom_state) { + no_rom_protect(); + m = (uae_u32 *)(kickmem_bank.baseaddr + addr); + do_put_mem_long(m, l); + } +} +static void REGPARAM2 blizzardmaprom_wput(uaecptr addr, uae_u32 w) +{ + uae_u16 *m; +#ifdef JIT + special_mem |= S_WRITE; +#endif + addr &= blizzardmaprom_bank.mask; + m = (uae_u16 *)(blizzardmaprom_bank.baseaddr + addr); + do_put_mem_word(m, w); + if (maprom_state) { + no_rom_protect(); + m = (uae_u16 *)(kickmem_bank.baseaddr + addr); + do_put_mem_word(m, w); + } +} +static void REGPARAM2 blizzardmaprom_bput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + addr &= blizzardmaprom_bank.mask; + blizzardmaprom_bank.baseaddr[addr] = b; + if (maprom_state) { + no_rom_protect(); + kickmem_bank.baseaddr[addr] = b; + } +} +static addrbank blizzardmaprom_bank = { + blizzardmaprom_lget, blizzardmaprom_wget, blizzardmaprom_bget, + blizzardmaprom_lput, blizzardmaprom_wput, blizzardmaprom_bput, + blizzardmaprom_xlate, blizzardmaprom_check, NULL, _T("Blizzard MAPROM"), + blizzardmaprom_lget, blizzardmaprom_wget, ABFLAG_RAM +}; + +static void REGPARAM3 blizzardea_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 blizzardea_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 blizzardea_bput(uaecptr, uae_u32) REGPARAM; + +MEMORY_BGET(blizzardea, 0); +MEMORY_WGET(blizzardea, 0); +MEMORY_LGET(blizzardea, 0); +MEMORY_CHECK(blizzardea); +MEMORY_XLATE(blizzardea); + +static addrbank blizzardea_bank = { + blizzardea_lget, blizzardea_wget, blizzardea_bget, + blizzardea_lput, blizzardea_wput, blizzardea_bput, + blizzardea_xlate, blizzardea_check, NULL, _T("Blizzard EA Autoconfig"), + blizzardea_lget, blizzardea_wget, ABFLAG_IO | ABFLAG_SAFE +}; + +static void REGPARAM3 blizzarde8_lput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 blizzarde8_wput(uaecptr, uae_u32) REGPARAM; +static void REGPARAM3 blizzarde8_bput(uaecptr, uae_u32) REGPARAM; +static uae_u32 REGPARAM3 blizzarde8_lget(uaecptr) REGPARAM; +static uae_u32 REGPARAM3 blizzarde8_wget(uaecptr) REGPARAM; +static uae_u32 REGPARAM3 blizzarde8_bget(uaecptr) REGPARAM; +static int REGPARAM2 blizzarde8_check(uaecptr addr, uae_u32 size) +{ + return 0; +} +static uae_u8 *REGPARAM2 blizzarde8_xlate(uaecptr addr) +{ + return NULL; +} + +static addrbank blizzarde8_bank = { + blizzarde8_lget, blizzarde8_wget, blizzarde8_bget, + blizzarde8_lput, blizzarde8_wput, blizzarde8_bput, + blizzarde8_xlate, blizzarde8_check, NULL, _T("Blizzard E8 Autoconfig"), + blizzarde8_lget, blizzarde8_wget, ABFLAG_IO | ABFLAG_SAFE +}; + +// Blizzard F0 ROM is really slow, shoud slow it down to see color flashing.. + +static uae_u32 REGPARAM2 blizzardf0_lget(uaecptr addr) +{ +#ifdef JIT + special_mem |= S_READ; +#endif + uae_u32 *m; + + addr &= blizzardf0_bank.mask; + m = (uae_u32 *)(blizzardf0_bank.baseaddr + addr); + return do_get_mem_long(m); +} +static uae_u32 REGPARAM2 blizzardf0_wget(uaecptr addr) +{ +#ifdef JIT + special_mem |= S_READ; +#endif + uae_u16 *m, v; + + addr &= blizzardf0_bank.mask; + m = (uae_u16 *)(blizzardf0_bank.baseaddr + addr); + v = do_get_mem_word(m); + return v; +} +static uae_u32 REGPARAM2 blizzardf0_bget(uaecptr addr) +{ +#ifdef JIT + special_mem |= S_READ; +#endif + uae_u8 v; + addr &= blizzardf0_bank.mask; + v = blizzardf0_bank.baseaddr[addr]; + return v; +} + +MEMORY_CHECK(blizzardf0); +MEMORY_XLATE(blizzardf0); + +static addrbank blizzardf0_bank = { + blizzardf0_lget, blizzardf0_wget, blizzardf0_bget, + blizzardea_lput, blizzardea_wput, blizzardea_bput, + blizzardf0_xlate, blizzardf0_check, NULL, _T("Blizzard F00000"), + blizzardf0_lget, blizzardf0_wget, ABFLAG_ROM +}; + +static void REGPARAM2 blizzardea_lput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif +} +static void REGPARAM2 blizzardea_wput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif +} +static void REGPARAM2 blizzardea_bput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif +} + +static void REGPARAM2 blizzarde8_lput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif +} +static void REGPARAM2 blizzarde8_wput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif +} +static void REGPARAM2 blizzarde8_bput(uaecptr addr, uae_u32 b) +{ +#ifdef JIT + special_mem |= S_WRITE; +#endif + b &= 0xff; + addr &= 65535; + if (addr == 0x48 && !configured) { + map_banks(&blizzardea_bank, b, 0x20000 >> 16, 0x20000); + write_log(_T("Blizzard Z2 autoconfigured at %02X0000\n"), b); + configured = 1; + expamem_next(); + return; + } + if (addr == 0x4c && !configured) { + write_log(_T("Blizzard Z2 SHUT-UP!\n")); + configured = 1; + expamem_next(); + return; + } +} +static uae_u32 REGPARAM2 blizzarde8_bget(uaecptr addr) +{ + uae_u32 v = 0xffff; +#ifdef JIT + special_mem |= S_READ; +#endif + v = blizzardea_bank.baseaddr[addr & blizzardea_bank.mask]; + return v; +} +static uae_u32 REGPARAM2 blizzarde8_wget(uaecptr addr) +{ + uae_u32 v = 0xffff; +#ifdef JIT + special_mem |= S_READ; +#endif + v = (blizzardea_bank.baseaddr[addr & blizzardea_bank.mask] << 8) | blizzardea_bank.baseaddr[(addr + 1) & blizzardea_bank.mask]; + return v; +} +static uae_u32 REGPARAM2 blizzarde8_lget(uaecptr addr) +{ + uae_u32 v = 0xffff; +#ifdef JIT + special_mem |= S_READ; +#endif + v = (blizzarde8_wget(addr) << 16) | blizzarde8_wget(addr + 2); + return v; +} + +static void copymaprom(void) +{ + uae_u8 *src = get_real_address(BLIZZARD_MAPROM_BASE); + uae_u8 *dst = get_real_address(0xf80000); + protect_roms(false); + memcpy(dst, src, 524288); + protect_roms(true); +} + +static uae_u32 REGPARAM2 blizzardio_bget(uaecptr addr) +{ + return 0; +} +static void REGPARAM2 blizzardio_bput(uaecptr addr, uae_u32 v) +{ + if ((addr & 65535) == (BLIZZARD_MAPROM_ENABLE & 65535)) { + if (v != 0x42 || maprom_state || !currprefs.maprom) + return; + maprom_state = 1; + write_log(_T("Blizzard MAPROM enabled\n")); + copymaprom(); + } +} +static void REGPARAM2 blizzardio_wput(uaecptr addr, uae_u32 v) +{ + if((addr & 65535) == (BLIZZARD_BOARD_DISABLE & 65535)) { + if (v != 0xcafe) + return; + write_log(_T("Blizzard board disable!\n")); + cpu_halt(4); // not much choice.. + } +} + +static addrbank blizzardio_bank = { + blizzardio_bget, blizzardio_bget, blizzardio_bget, + blizzardio_wput, blizzardio_wput, blizzardio_bput, + default_xlate, default_check, NULL, _T("Blizzard IO"), + blizzardio_bget, blizzardio_bget, ABFLAG_IO +}; + +void cpuboard_vsync(void) +{ + if (delayed_rom_protect <= 0) + return; + delayed_rom_protect--; + if (delayed_rom_protect == 0) + protect_roms(true); +} + +void cpuboard_map(void) +{ + if (!currprefs.cpuboard_type) + return; + if (cpuboard_size) { + if (blizzard_jit) { + map_banks(&blizzardram_bank, blizzardram_bank.start >> 16, cpuboard_size >> 16, 0); + map_banks(&blizzardram_bank, BLIZZARD_RAM_BASE >> 16, cpuboard_size >> 16, 0); + } else { + for (int i = 0; i < 0x08000000; i += cpuboard_size) { + map_banks_nojitdirect(&blizzardram_nojit_bank, (BLIZZARD_RAM_ALIAS_BASE + i) >> 16, cpuboard_size >> 16, 0); + map_banks_nojitdirect(&blizzardram_nojit_bank, (BLIZZARD_RAM_BASE + i) >> 16, cpuboard_size >> 16, 0); + } + if (currprefs.maprom) { + for (int i = 0; i < 0x08000000; i += cpuboard_size) { + map_banks_nojitdirect(&blizzardmaprom_bank, (BLIZZARD_RAM_ALIAS_BASE + i + cpuboard_size - 524288) >> 16, 524288 >> 16, 0); + map_banks_nojitdirect(&blizzardmaprom_bank, (BLIZZARD_RAM_BASE + i + cpuboard_size - 524288) >> 16, 524288 >> 16, 0); + } + } + } + } + if (f0rom_size) + map_banks(&blizzardf0_bank, 0xf00000 >> 16, f0rom_size >> 16, 0); + if (is_blizzard()) { + map_banks(&blizzardio_bank, BLIZZARD_MAPROM_ENABLE >> 16, 65536 >> 16, 0); + map_banks(&blizzardio_bank, BLIZZARD_BOARD_DISABLE >> 16, 65536 >> 16, 0); + } +} + +void cpuboard_reset(bool hardreset) +{ + canbang = 0; + configured = false; + delayed_rom_protect = 0; + currprefs.cpuboardmem1_size = changed_prefs.cpuboardmem1_size; + if (hardreset || !currprefs.maprom) + maprom_state = 0; +} + +void cpuboard_cleanup(void) +{ + configured = false; + maprom_state = 0; + + if (blizzard_jit) { + mapped_free(blizzardram_bank.baseaddr); + } else { + xfree(blizzardram_nojit_bank.baseaddr); + } + blizzardram_bank.baseaddr = NULL; + blizzardram_nojit_bank.baseaddr = NULL; + blizzardmaprom_bank.baseaddr = NULL; + + mapped_free(blizzardf0_bank.baseaddr); + blizzardf0_bank.baseaddr = NULL; + + mapped_free(blizzardea_bank.baseaddr); + blizzardea_bank.baseaddr = NULL; + + cpuboard_size = cpuboard2_size = -1; +} + +void cpuboard_init(void) +{ + if (!currprefs.cpuboard_type) + return; + + if (cpuboard_size == currprefs.cpuboardmem1_size) + return; + + cpuboard_cleanup(); + + cpuboard_size = currprefs.cpuboardmem1_size; + + if (is_blizzard()) { + blizzardram_bank.start = BLIZZARD_RAM_ALIAS_BASE; + blizzardram_bank.allocated = cpuboard_size; + blizzardram_bank.mask = blizzardram_bank.allocated - 1; + + blizzardram_nojit_bank.start = blizzardram_bank.start; + blizzardram_nojit_bank.allocated = blizzardram_bank.allocated; + blizzardram_nojit_bank.mask = blizzardram_bank.mask; + + + blizzard_jit = 0 && BLIZZARD_RAM_BASE + blizzardram_bank.allocated <= max_z3fastmem && currprefs.jit_direct_compatible_memory; + if (blizzard_jit) { + if (cpuboard_size) + blizzardram_bank.baseaddr = mapped_malloc(blizzardram_bank.allocated, _T("blizzard")); + } else { + if (cpuboard_size) + blizzardram_bank.baseaddr = xmalloc(uae_u8, blizzardram_bank.allocated); + } + blizzardram_nojit_bank.baseaddr = blizzardram_bank.baseaddr; + + blizzardmaprom_bank.baseaddr = blizzardram_bank.baseaddr + cpuboard_size - 524288; + blizzardmaprom_bank.start = BLIZZARD_MAPROM_BASE; + blizzardmaprom_bank.allocated = 524288; + blizzardmaprom_bank.mask = 524288 - 1; + + maprom_base = blizzardram_bank.allocated - 524288; + + blizzardf0_bank.start = 0x00f00000; + blizzardf0_bank.allocated = 262144; + blizzardf0_bank.mask = blizzardf0_bank.allocated - 1; + blizzardf0_bank.baseaddr = mapped_malloc(blizzardf0_bank.allocated, _T("rom_f0")); + + blizzardea_bank.allocated = 2 * 65536; + blizzardea_bank.mask = blizzardea_bank.allocated - 1; + // Blizzard 12xx autoconfig ROM must be mapped at $ea0000-$ebffff, board requires it. + blizzardea_bank.baseaddr = mapped_malloc(blizzardea_bank.allocated, _T("rom_ea")); + } +} + +void cpuboard_clear(void) +{ +} + +bool cpuboard_maprom(void) +{ + if (!currprefs.cpuboard_type || !cpuboard_size) + return false; + if (maprom_state) + copymaprom(); + return true; +} + +addrbank *cpuboard_autoconfig_init(void) +{ + struct zfile *autoconfig_rom = NULL; + int roms[2]; + bool autoconf = true; + + switch (currprefs.cpuboard_type) + { + case BOARD_BLIZZARD_1230_IV: + roms[0] = 89; + break; + case BOARD_BLIZZARD_1260: + roms[0] = 90; + break; + case BOARD_BLIZZARD_2060: + roms[0] = 91; + break; + case BOARD_WARPENGINE_A4000: + roms[0] = 93; + break; + default: + expamem_next(); + return NULL; + } + roms[1] = -1; + + struct romlist *rl = getromlistbyids(roms); + if (rl) { + autoconfig_rom = read_rom(rl->rd); + } + if (!autoconfig_rom) { + write_log (_T("ROM id %d not found for CPU board emulation\n")); + expamem_next(); + return NULL; + } + protect_roms(false); + if (currprefs.cpuboard_type == BOARD_BLIZZARD_2060) { + f0rom_size = 65536; + earom_size = 131072; + // 2060 = 2x32k + for (int i = 0; i < 32768; i++) { + uae_u8 b = 0xff; + zfile_fread(&b, 1, 1, autoconfig_rom); + blizzardf0_bank.baseaddr[i * 2 + 1] = b; + zfile_fread(&b, 1, 1, autoconfig_rom); + blizzardf0_bank.baseaddr[i * 2 + 0] = b; + zfile_fread(&b, 1, 1, autoconfig_rom); + blizzardea_bank.baseaddr[i * 2 + 1] = b; + zfile_fread(&b, 1, 1, autoconfig_rom); + blizzardea_bank.baseaddr[i * 2 + 0] = b; + } + } else if (currprefs.cpuboard_type == BOARD_WARPENGINE_A4000) { + f0rom_size = 0; + earom_size = 0; + autoconf = false; + } else { + f0rom_size = 65536; + earom_size = 131072; + // 12xx = 1x32k + for (int i = 0; i < 16384; i++) { + uae_u8 b = 0xff; + zfile_fread(&b, 1, 1, autoconfig_rom); + blizzardf0_bank.baseaddr[i] = b; + zfile_fread(&b, 1, 1, autoconfig_rom); + blizzardea_bank.baseaddr[i] = b; + } + } + protect_roms(true); + zfile_fclose(autoconfig_rom); + + if (f0rom_size) + map_banks(&blizzardf0_bank, 0xf00000 >> 16, f0rom_size >> 16, 0); + if (!autoconf) { + expamem_next(); + return NULL; + } + return &blizzarde8_bank; +} diff --git a/include/cpuboard.h b/include/cpuboard.h new file mode 100644 index 00000000..ce5e5771 --- /dev/null +++ b/include/cpuboard.h @@ -0,0 +1,16 @@ + +extern addrbank *cpuboard_autoconfig_init(void); +extern bool cpuboard_maprom(void); +extern void cpuboard_map(void); +extern void cpuboard_reset(bool); +extern void cpuboard_cleanup(void); +extern void cpuboard_init(void); +extern void cpuboard_clear(void); +extern void cpuboard_vsync(void); + +extern addrbank blizzardram_bank; + +#define BOARD_BLIZZARD_1230_IV 1 +#define BOARD_BLIZZARD_1260 2 +#define BOARD_BLIZZARD_2060 3 +#define BOARD_WARPENGINE_A4000 4 -- 2.47.3