From 6adb0d00ee47cf4c503eadbc21bd32ece9963ec2 Mon Sep 17 00:00:00 2001 From: Dimitris Panokostas Date: Mon, 29 Jun 2020 22:31:16 +0200 Subject: [PATCH] Updated memory.cpp from latest upstream --- src/memory.cpp | 1543 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 1376 insertions(+), 167 deletions(-) diff --git a/src/memory.cpp b/src/memory.cpp index 7bcf39e0..abe44ae2 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -26,20 +26,103 @@ #include "gayle.h" #include "devices.h" +bool canbang; static bool rom_write_enabled; #ifdef JIT /* Set by each memory handler that does not simply access real memory. */ int special_mem; #endif static int mem_hardreset; +static bool roms_modified; -static size_t bootrom_filepos, chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos; +static bool isdirectjit(void) +{ + return currprefs.cachesize && !currprefs.comptrustbyte; +} + +static bool canjit(void) +{ + if (currprefs.cpu_model < 68020 || currprefs.address_space_24) + return false; + return true; +} + +static bool needmman(void) +{ + if (!jit_direct_compatible_memory) + return false; + + if (canjit()) + return true; + return false; +} + +static void nocanbang(void) +{ + if (canbang) { + write_log(_T("Switching JIT direct off!\n")); + } + canbang = 0; +} + +uae_u8 ce_banktype[65536]; +uae_u8 ce_cachable[65536]; + +static size_t bootrom_filepos, chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos, mem25bit_filepos; + +/* Set if we notice during initialization that settings changed, +and we must clear all memory to prevent bogus contents from confusing +the Kickstart. */ +static bool need_hardreset; +static int bogomem_aliasing; /* The address space setting used during the last reset. */ static bool last_address_space_24; addrbank *mem_banks[MEMORY_BANKS]; +/* This has two functions. It either holds a host address that, when added +to the 68k address, gives the host address corresponding to that 68k +address (in which case the value in this array is even), OR it holds the +same value as mem_banks, for those banks that have baseaddr==0. In that +case, bit 0 is set (the memory access routines will take care of it). */ + +uae_u8* baseaddr[MEMORY_BANKS]; + +#ifdef NO_INLINE_MEMORY_ACCESS +__inline__ uae_u32 longget(uaecptr addr) +{ + return call_mem_get_func(get_mem_bank(addr).lget, addr); +} +__inline__ uae_u32 wordget(uaecptr addr) +{ + return call_mem_get_func(get_mem_bank(addr).wget, addr); +} +__inline__ uae_u32 byteget(uaecptr addr) +{ + return call_mem_get_func(get_mem_bank(addr).bget, addr); +} +__inline__ void longput(uaecptr addr, uae_u32 l) +{ + call_mem_put_func(get_mem_bank(addr).lput, addr, l); +} +__inline__ void wordput(uaecptr addr, uae_u32 w) +{ + call_mem_put_func(get_mem_bank(addr).wput, addr, w); +} +__inline__ void byteput(uaecptr addr, uae_u32 b) +{ + call_mem_put_func(get_mem_bank(addr).bput, addr, b); +} +#endif + +extern bool debugmem_initialized; + +bool real_address_allowed(void) +{ + return debugmem_initialized == false; +} + int addr_valid(const TCHAR* txt, uaecptr addr, uae_u32 len) { addrbank* ab = &get_mem_bank(addr); @@ -50,6 +133,7 @@ int addr_valid(const TCHAR* txt, uaecptr addr, uae_u32 len) return 1; } +static int illegal_count; /* A dummy bank that only contains zeros */ static uae_u32 REGPARAM3 dummy_lget (uaecptr) REGPARAM; @@ -60,10 +144,111 @@ static void REGPARAM3 dummy_wput (uaecptr, uae_u32) REGPARAM; static void REGPARAM3 dummy_bput (uaecptr, uae_u32) REGPARAM; static int REGPARAM3 dummy_check (uaecptr addr, uae_u32 size) REGPARAM; +/* fake UAE ROM */ + +extern addrbank fakeuaebootrom_bank; +MEMORY_FUNCTIONS(fakeuaebootrom); + #define MAX_ILG 1000 #define NONEXISTINGDATA 0 //#define NONEXISTINGDATA 0xffffffff +static bool map_uae_boot_rom_direct(void) +{ + if (!fakeuaebootrom_bank.allocated_size) { + fakeuaebootrom_bank.start = 0xf00000; + fakeuaebootrom_bank.reserved_size = 65536; + fakeuaebootrom_bank.mask = fakeuaebootrom_bank.reserved_size - 1; + if (!mapped_malloc(&fakeuaebootrom_bank)) + return false; + // create jump table to real uae boot rom + for (int i = 0xff00; i < 0xfff8; i += 8) { + uae_u8* p = fakeuaebootrom_bank.baseaddr + i; + p[0] = 0x4e; + p[1] = 0xf9; + uaecptr p2 = rtarea_base + i; + p[2] = p2 >> 24; + p[3] = p2 >> 16; + p[4] = p2 >> 8; + p[5] = p2 >> 0; + } + } + map_banks(&fakeuaebootrom_bank, 0xf0, 1, 1); + write_log(_T("Mapped fake UAE Boot ROM jump table.\n")); + return true; +} + +// if access looks like old style hook call and f00000 space is unused, redirect to UAE boot ROM. +static bool maybe_map_boot_rom(uaecptr addr) +{ + if (currprefs.uaeboard >= 2 && &get_mem_bank(0xf00000) == &dummy_bank && !currprefs.mmu_model) { + uae_u32 pc = M68K_GETPC; + if (addr >= 0xf0ff00 && addr <= 0xf0fff8 && (((valid_address(pc, 2) && (pc < 0xf00000 || pc >= 0x01000000) && !currprefs.cpu_compatible) || (pc == addr && currprefs.cpu_compatible)))) { + bool check2 = currprefs.cpu_compatible; + if (!check2) { + uae_u32 w = get_word(pc); + // JSR xxxxxxxx or JSR (an) + if (w == 0x4eb9 || (w & 0xfff8) == 0x4e90) + check2 = true; + } + if (check2) { + if (map_uae_boot_rom_direct()) { + if (&get_mem_bank(0xf00000) == &fakeuaebootrom_bank) { + return true; + } + } + } + } + } + return false; +} + +static void dummylog(int rw, uaecptr addr, int size, uae_u32 val, int ins) +{ + /* ignore Zorro3 expansion space */ + if (addr >= AUTOCONFIG_Z3 && addr <= AUTOCONFIG_Z3 + 0x200) + return; + /* autoconfig and extended rom */ + if (addr >= 0xe00000 && addr <= 0xf7ffff) + return; + /* motherboard ram */ + if (addr >= 0x08000000 && addr <= 0x08000007) + return; + if (addr >= 0x07f00000 && addr <= 0x07f00007) + return; + if (addr >= 0x07f7fff0 && addr <= 0x07ffffff) + return; + //if (debugmem_extinvalidmem(addr, val, rw ? size : -size)) + // return; + //if ((illegal_count >= MAX_ILG && MAX_ILG > 0) && !memwatch_access_validator) + // return; + if (MAX_ILG >= 0) + illegal_count++; + if (ins) { + write_log(_T("WARNING: Illegal opcode %cget at %08x PC=%x\n"), + size == 2 ? 'w' : 'l', addr, M68K_GETPC); + } + else if (rw) { + write_log(_T("Illegal %cput at %08x=%08x PC=%x\n"), + size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, val, M68K_GETPC); + } + else { + write_log(_T("Illegal %cget at %08x PC=%x\n"), + size == 1 ? 'b' : size == 2 ? 'w' : 'l', addr, M68K_GETPC); + } +} + +// 250ms delay +static void gary_wait(uaecptr addr, int size, bool write) +{ + static int cnt = 50; + + if (cnt > 0) { + write_log(_T("Gary timeout: %08x %d %c PC=%08x\n"), addr, size, write ? 'W' : 'R', M68K_GETPC); + cnt--; + } +} + static bool gary_nonrange(uaecptr addr) { if (currprefs.cs_fatgaryrev < 0) @@ -81,6 +266,16 @@ static bool gary_nonrange(uaecptr addr) return true; } +void dummy_put(uaecptr addr, int size, uae_u32 val) +{ + if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) { + if (gary_timeout) + gary_wait(addr, size, true); + if (gary_toenb && currprefs.mmu_model) + exception2(addr, true, size, regs.s ? 4 : 0); + } +} + static uae_u32 nonexistingdata(void) { if (currprefs.cs_unmapped_space == 1) @@ -129,7 +324,15 @@ uae_u32 dummy_get(uaecptr addr, int size, bool inst, uae_u32 defvalue) { uae_u32 v = defvalue; + if ((size == 2 || size == 4) && inst && maybe_map_boot_rom(addr)) { + if (size == 2) + return get_word(addr); + return get_long(addr); + } + if (gary_nonrange(addr) || (size > 1 && gary_nonrange(addr + size - 1))) { + if (gary_timeout) + gary_wait(addr, size, false); if (gary_toenb) exception2(addr, false, size, (regs.s ? 4 : 0) | (inst ? 0 : 1)); return v; @@ -159,12 +362,15 @@ static uae_u32 REGPARAM2 dummy_bget(uaecptr addr) static void REGPARAM2 dummy_lput(uaecptr addr, uae_u32 l) { + dummy_put(addr, 4, l); } static void REGPARAM2 dummy_wput(uaecptr addr, uae_u32 w) { + dummy_put(addr, 2, w); } static void REGPARAM2 dummy_bput(uaecptr addr, uae_u32 b) { + dummy_put(addr, 1, b); } static int REGPARAM2 dummy_check(uaecptr addr, uae_u32 size) @@ -172,6 +378,14 @@ static int REGPARAM2 dummy_check(uaecptr addr, uae_u32 size) return 0; } +static void REGPARAM2 none_put(uaecptr addr, uae_u32 v) +{ +} +static uae_u32 REGPARAM2 ones_get(uaecptr addr) +{ + return 0xffffffff; +} + addrbank *get_sub_bank(uaecptr *paddr) { int i; @@ -243,7 +457,79 @@ uae_u8 *REGPARAM3 sub_bank_xlate(uaecptr addr) REGPARAM /* Chip memory */ -uae_u32 chipmem_full_mask; +static uae_u32 chipmem_full_mask; +static uae_u32 chipmem_full_size; + +static int REGPARAM3 chipmem_check(uaecptr addr, uae_u32 size) REGPARAM; +static uae_u8* REGPARAM3 chipmem_xlate(uaecptr addr) REGPARAM; + +#ifdef AGA + +/* AGA ce-chipram access */ + +static void ce2_timeout(void) +{ +#ifdef CPUEMU_13 + wait_cpu_cycle_read(0, -1); +#endif +} + +static uae_u32 REGPARAM2 chipmem_lget_ce2(uaecptr addr) +{ + uae_u32* m; + + addr &= chipmem_bank.mask; + m = (uae_u32*)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + return do_get_mem_long(m); +} + +static uae_u32 REGPARAM2 chipmem_wget_ce2(uaecptr addr) +{ + uae_u16* m, v; + + addr &= chipmem_bank.mask; + m = (uae_u16*)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + v = do_get_mem_word(m); + return v; +} + +static uae_u32 REGPARAM2 chipmem_bget_ce2(uaecptr addr) +{ + addr &= chipmem_bank.mask; + ce2_timeout(); + return chipmem_bank.baseaddr[addr]; +} + +static void REGPARAM2 chipmem_lput_ce2(uaecptr addr, uae_u32 l) +{ + uae_u32* m; + + addr &= chipmem_bank.mask; + m = (uae_u32*)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + do_put_mem_long(m, l); +} + +static void REGPARAM2 chipmem_wput_ce2(uaecptr addr, uae_u32 w) +{ + uae_u16* m; + + addr &= chipmem_bank.mask; + m = (uae_u16*)(chipmem_bank.baseaddr + addr); + ce2_timeout(); + do_put_mem_word(m, w); +} + +static void REGPARAM2 chipmem_bput_ce2(uaecptr addr, uae_u32 b) +{ + addr &= chipmem_bank.mask; + ce2_timeout(); + chipmem_bank.baseaddr[addr] = b; +} + +#endif static uae_u32 REGPARAM2 chipmem_lget(uaecptr addr) { @@ -296,19 +582,100 @@ void REGPARAM2 chipmem_bput(uaecptr addr, uae_u32 b) chipmem_bank.baseaddr[addr] = b; } +/* cpu chipmem access inside agnus addressable ram but no ram available */ +static uae_u32 chipmem_dummy(void) +{ + /* not really right but something random that has more ones than zeros.. */ + return 0xffff & ~((1 << (uaerand() & 31)) | (1 << (uaerand() & 31))); +} + +static void REGPARAM2 chipmem_dummy_bput(uaecptr addr, uae_u32 b) +{ +} +static void REGPARAM2 chipmem_dummy_wput(uaecptr addr, uae_u32 b) +{ +} +static void REGPARAM2 chipmem_dummy_lput(uaecptr addr, uae_u32 b) +{ +} + +static uae_u32 REGPARAM2 chipmem_dummy_bget(uaecptr addr) +{ + return chipmem_dummy(); +} +static uae_u32 REGPARAM2 chipmem_dummy_wget(uaecptr addr) +{ + return chipmem_dummy(); +} +static uae_u32 REGPARAM2 chipmem_dummy_lget(uaecptr addr) +{ + return (chipmem_dummy() << 16) | chipmem_dummy(); +} + +static uae_u32 REGPARAM2 chipmem_agnus_lget(uaecptr addr) +{ + uae_u32* m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 3) + return 0; + m = (uae_u32*)(chipmem_bank.baseaddr + addr); + return do_get_mem_long(m); +} + +uae_u32 REGPARAM2 chipmem_agnus_wget(uaecptr addr) +{ + uae_u16* m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 1) + return 0; + m = (uae_u16*)(chipmem_bank.baseaddr + addr); + return do_get_mem_word(m); +} + +static uae_u32 REGPARAM2 chipmem_agnus_bget(uaecptr addr) +{ + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size) + return 0; + return chipmem_bank.baseaddr[addr]; +} + +static void REGPARAM2 chipmem_agnus_lput(uaecptr addr, uae_u32 l) +{ + uae_u32* m; + + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size - 3) + return; + m = (uae_u32*)(chipmem_bank.baseaddr + addr); + do_put_mem_long(m, l); +} + void REGPARAM2 chipmem_agnus_wput(uaecptr addr, uae_u32 w) { uae_u16 *m; addr &= chipmem_full_mask; - m = (uae_u16 *)(chipmem_bank.baseaddr + addr); + if (addr >= chipmem_full_size - 1) + return; + m = (uae_u16*)(chipmem_bank.baseaddr + addr); do_put_mem_word(m, w); } +static void REGPARAM2 chipmem_agnus_bput(uaecptr addr, uae_u32 b) +{ + addr &= chipmem_full_mask; + if (addr >= chipmem_full_size) + return; + chipmem_bank.baseaddr[addr] = b; +} + static int REGPARAM2 chipmem_check(uaecptr addr, uae_u32 size) { addr &= chipmem_bank.mask; - return (addr + size) <= chipmem_bank.reserved_size; + return (addr + size) <= chipmem_full_size; } static uae_u8 *REGPARAM2 chipmem_xlate(uaecptr addr) @@ -317,6 +684,125 @@ static uae_u8 *REGPARAM2 chipmem_xlate(uaecptr addr) return chipmem_bank.baseaddr + addr; } +STATIC_INLINE void REGPARAM2 chipmem_lput_bigmem(uaecptr addr, uae_u32 v) +{ + put_long(addr, v); +} +STATIC_INLINE void REGPARAM2 chipmem_wput_bigmem(uaecptr addr, uae_u32 v) +{ + put_word(addr, v); +} +STATIC_INLINE void REGPARAM2 chipmem_bput_bigmem(uaecptr addr, uae_u32 v) +{ + put_byte(addr, v); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_lget_bigmem(uaecptr addr) +{ + return get_long(addr); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_wget_bigmem(uaecptr addr) +{ + return get_word(addr); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_bget_bigmem(uaecptr addr) +{ + return get_byte(addr); +} +STATIC_INLINE int REGPARAM2 chipmem_check_bigmem(uaecptr addr, uae_u32 size) +{ + return valid_address(addr, size); +} +STATIC_INLINE uae_u8* REGPARAM2 chipmem_xlate_bigmem(uaecptr addr) +{ + return get_real_address(addr); +} + +STATIC_INLINE void REGPARAM2 chipmem_lput_debugmem(uaecptr addr, uae_u32 v) +{ + //if (addr < debugmem_chiplimit) + // debugmem_chiphit(addr, v, 4); + put_long(addr, v); +} +STATIC_INLINE void REGPARAM2 chipmem_wput_debugmem(uaecptr addr, uae_u32 v) +{ + //if (addr < debugmem_chiplimit) + //debugmem_chiphit(addr, v, 2); + put_word(addr, v); +} +STATIC_INLINE void REGPARAM2 chipmem_bput_debugmem(uaecptr addr, uae_u32 v) +{ + //if (addr < debugmem_chiplimit) + //debugmem_chiphit(addr, v, 1); + put_byte(addr, v); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_lget_debugmem(uaecptr addr) +{ + //if (addr < debugmem_chiplimit) + //return debugmem_chiphit(addr, 0, -4); + return get_long(addr); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_wget_debugmem(uaecptr addr) +{ + //if (addr < debugmem_chiplimit) + //return debugmem_chiphit(addr, 0, -2); + return get_word(addr); +} +STATIC_INLINE uae_u32 REGPARAM2 chipmem_bget_debugmem(uaecptr addr) +{ + //if (addr < debugmem_chiplimit) + //return debugmem_chiphit(addr, 0, -1); + return get_byte(addr); +} +STATIC_INLINE int REGPARAM2 chipmem_check_debugmem(uaecptr addr, uae_u32 size) +{ + return valid_address(addr, size); +} +STATIC_INLINE uae_u8* REGPARAM2 chipmem_xlate_debugmem(uaecptr addr) +{ + return get_real_address(addr); +} + +uae_u32(REGPARAM2* chipmem_lget_indirect)(uaecptr); +uae_u32(REGPARAM2* chipmem_wget_indirect)(uaecptr); +uae_u32(REGPARAM2* chipmem_bget_indirect)(uaecptr); +void (REGPARAM2* chipmem_lput_indirect)(uaecptr, uae_u32); +void (REGPARAM2* chipmem_wput_indirect)(uaecptr, uae_u32); +void (REGPARAM2* chipmem_bput_indirect)(uaecptr, uae_u32); +int (REGPARAM2* chipmem_check_indirect)(uaecptr, uae_u32); +uae_u8* (REGPARAM2* chipmem_xlate_indirect)(uaecptr); + +void chipmem_setindirect(void) +{ + if (debugmem_bank.baseaddr && 0) { + chipmem_lget_indirect = chipmem_lget_debugmem; + chipmem_wget_indirect = chipmem_wget_debugmem; + chipmem_bget_indirect = chipmem_bget_debugmem; + chipmem_lput_indirect = chipmem_lput_debugmem; + chipmem_wput_indirect = chipmem_wput_debugmem; + chipmem_bput_indirect = chipmem_bput_debugmem; + chipmem_check_indirect = chipmem_check_bigmem; + chipmem_xlate_indirect = chipmem_xlate_bigmem; + } else if (currprefs.z3chipmem_size) { + chipmem_lget_indirect = chipmem_lget_bigmem; + chipmem_wget_indirect = chipmem_wget_bigmem; + chipmem_bget_indirect = chipmem_bget_bigmem; + chipmem_lput_indirect = chipmem_lput_bigmem; + chipmem_wput_indirect = chipmem_wput_bigmem; + chipmem_bput_indirect = chipmem_bput_bigmem; + chipmem_check_indirect = chipmem_check_bigmem; + chipmem_xlate_indirect = chipmem_xlate_bigmem; + } else { + chipmem_lget_indirect = chipmem_lget; + chipmem_wget_indirect = chipmem_agnus_wget; + chipmem_bget_indirect = chipmem_agnus_bget; + chipmem_lput_indirect = chipmem_lput; + chipmem_wput_indirect = chipmem_agnus_wput; + chipmem_bput_indirect = chipmem_agnus_bput; + chipmem_check_indirect = chipmem_check; + chipmem_xlate_indirect = chipmem_xlate; + } +} + /* Slow memory */ MEMORY_FUNCTIONS(bogomem); @@ -326,6 +812,16 @@ MEMORY_FUNCTIONS(bogomem); MEMORY_FUNCTIONS(a3000lmem); MEMORY_FUNCTIONS(a3000hmem); +/* 25bit memory (0x01000000) */ + +MEMORY_FUNCTIONS(mem25bit); + +/* debugger memory */ + +MEMORY_FUNCTIONS(debugmem); +MEMORY_WGETI(debugmem); +MEMORY_LGETI(debugmem); + /* Kick memory */ uae_u16 kickstart_version; @@ -339,18 +835,18 @@ uae_u16 kickstart_version; */ static int a1000_kickstart_mode; static uae_u8 *a1000_bootrom; -static void a1000_handle_kickstart (int mode) +static void a1000_handle_kickstart(int mode) { if (!a1000_bootrom) return; - protect_roms (false); + protect_roms(false); if (mode == 0) { a1000_kickstart_mode = 0; - memcpy (kickmem_bank.baseaddr, kickmem_bank.baseaddr + ROM_SIZE_256, ROM_SIZE_256); + memcpy(kickmem_bank.baseaddr, kickmem_bank.baseaddr + ROM_SIZE_256, ROM_SIZE_256); kickstart_version = (kickmem_bank.baseaddr[ROM_SIZE_256 + 12] << 8) | kickmem_bank.baseaddr[ROM_SIZE_256 + 13]; } else { a1000_kickstart_mode = 1; - memcpy (kickmem_bank.baseaddr, a1000_bootrom, ROM_SIZE_256); + memcpy(kickmem_bank.baseaddr, a1000_bootrom, ROM_SIZE_256); kickstart_version = 0; } if (kickstart_version == 0xffff) @@ -388,7 +884,7 @@ static void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b) } else a1000_handle_kickstart (0); } else if (currprefs.illegal_mem) { - write_log (_T("Illegal kickmem lput at %08x PC=%08x\n"), addr, M68K_GETPC); + write_log (_T("Illegal kickmem lput at %08x\n"), addr); } } @@ -408,7 +904,7 @@ static void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b) } else a1000_handle_kickstart (0); } else if (currprefs.illegal_mem) { - write_log (_T("Illegal kickmem wput at %08x PC=%08x\n"), addr, M68K_GETPC); + write_log (_T("Illegal kickmem wput at %08x\n"), addr); } } @@ -425,7 +921,7 @@ static void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b) } else a1000_handle_kickstart (0); } else if (currprefs.illegal_mem) { - write_log (_T("Illegal kickmem bput at %08x PC=%08x\n"), addr, M68K_GETPC); + write_log (_T("Illegal kickmem bput at %08x\n"), addr); } } @@ -518,13 +1014,19 @@ uae_u8 *REGPARAM2 default_xlate(uaecptr addr) return kickmem_xlate(2); } + if (maybe_map_boot_rom(addr)) + return get_real_address(addr); + be_recursive++; int size = currprefs.cpu_model >= 68020 ? 4 : 2; if (quit_program == 0) { /* do this only in 68010+ mode, there are some tricky A500 programs.. */ - if (currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) + if ((currprefs.cpu_model > 68000 || !currprefs.cpu_compatible) && !currprefs.mmu_model) { +#if defined(ENFORCER) + enforcer_disable(); +#endif if (be_cnt < 3) { write_log(_T("Your Amiga program just did something terribly stupid %08X PC=%08X\n"), addr, M68K_GETPC); @@ -553,20 +1055,62 @@ addrbank dummy_bank = { ABFLAG_NONE, S_READ, S_WRITE }; +addrbank ones_bank = { + ones_get, ones_get, ones_get, + none_put, none_put, none_put, + default_xlate, dummy_check, NULL, NULL, _T("Ones"), + dummy_wgeti, + ABFLAG_NONE, S_READ, S_WRITE +}; + addrbank chipmem_bank = { chipmem_lget, chipmem_wget, chipmem_bget, chipmem_lput, chipmem_wput, chipmem_bput, chipmem_xlate, chipmem_check, NULL, _T("chip"), _T("Chip memory"), chipmem_wget, - ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CHIPRAM, 0, 0 + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CHIPRAM | ABFLAG_CACHE_ENABLE_BOTH, 0, 0 }; +addrbank chipmem_dummy_bank = { + chipmem_dummy_lget, chipmem_dummy_wget, chipmem_dummy_bget, + chipmem_dummy_lput, chipmem_dummy_wput, chipmem_dummy_bput, + default_xlate, dummy_check, NULL, NULL, _T("Dummy Chip memory"), + dummy_wgeti, + ABFLAG_IO | ABFLAG_CHIPRAM, S_READ, S_WRITE +}; + +#ifdef AGA +addrbank chipmem_bank_ce2 = { + chipmem_lget_ce2, chipmem_wget_ce2, chipmem_bget_ce2, + chipmem_lput_ce2, chipmem_wput_ce2, chipmem_bput_ce2, + chipmem_xlate, chipmem_check, NULL, NULL, _T("Chip memory (68020 'ce')"), + chipmem_wget_ce2, + ABFLAG_RAM | ABFLAG_CHIPRAM | ABFLAG_CACHE_ENABLE_BOTH, S_READ, S_WRITE +}; +#endif + addrbank bogomem_bank = { bogomem_lget, bogomem_wget, bogomem_bget, bogomem_lput, bogomem_wput, bogomem_bput, bogomem_xlate, bogomem_check, NULL, _T("bogo"), _T("Slow memory"), bogomem_wget, - ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_BOTH, 0, 0 +}; + +addrbank mem25bit_bank = { + mem25bit_lget, mem25bit_wget, mem25bit_bget, + mem25bit_lput, mem25bit_wput, mem25bit_bput, + mem25bit_xlate, mem25bit_check, NULL, _T("25bitmem"), _T("25bit memory"), + mem25bit_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL, 0, 0 +}; + +addrbank debugmem_bank = { + debugmem_lget, debugmem_wget, debugmem_bget, + debugmem_lput, debugmem_wput, debugmem_bput, + debugmem_xlate, debugmem_check, NULL, _T("debugmem"), _T("debugger memory"), + debugmem_wgeti, + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL, 0, 0 }; addrbank a3000lmem_bank = { @@ -574,7 +1118,7 @@ addrbank a3000lmem_bank = { a3000lmem_lput, a3000lmem_wput, a3000lmem_bput, a3000lmem_xlate, a3000lmem_check, NULL, _T("ramsey_low"), _T("RAMSEY memory (low)"), a3000lmem_wget, - ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, 0 }; addrbank a3000hmem_bank = { @@ -582,7 +1126,7 @@ addrbank a3000hmem_bank = { a3000hmem_lput, a3000hmem_wput, a3000hmem_bput, a3000hmem_xlate, a3000hmem_check, NULL, _T("ramsey_high"), _T("RAMSEY memory (high)"), a3000hmem_wget, - ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, 0 }; addrbank kickmem_bank = { @@ -590,7 +1134,15 @@ addrbank kickmem_bank = { kickmem_lput, kickmem_wput, kickmem_bput, kickmem_xlate, kickmem_check, NULL, _T("kick"), _T("Kickstart ROM"), kickmem_wget, - ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE + ABFLAG_ROM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, S_WRITE +}; + +addrbank kickram_bank = { + kickmem_lget, kickmem_wget, kickmem_bget, + kickmem2_lput, kickmem2_wput, kickmem2_bput, + kickmem_xlate, kickmem_check, NULL, NULL, _T("Kickstart Shadow RAM"), + kickmem_wget, + ABFLAG_UNK | ABFLAG_SAFE | ABFLAG_CACHE_ENABLE_ALL, 0, S_WRITE }; addrbank extendedkickmem_bank = { @@ -598,14 +1150,21 @@ addrbank extendedkickmem_bank = { extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput, extendedkickmem_xlate, extendedkickmem_check, NULL, NULL, _T("Extended Kickstart ROM"), extendedkickmem_wget, - ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE + ABFLAG_ROM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, S_WRITE }; addrbank extendedkickmem2_bank = { extendedkickmem2_lget, extendedkickmem2_wget, extendedkickmem2_bget, extendedkickmem2_lput, extendedkickmem2_wput, extendedkickmem2_bput, extendedkickmem2_xlate, extendedkickmem2_check, NULL, _T("rom_a8"), _T("Extended 2nd Kickstart ROM"), extendedkickmem2_wget, - ABFLAG_ROM | ABFLAG_THREADSAFE, 0, S_WRITE + ABFLAG_ROM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, S_WRITE +}; +addrbank fakeuaebootrom_bank = { + fakeuaebootrom_lget, fakeuaebootrom_wget, mem25bit_bget, + fakeuaebootrom_lput, fakeuaebootrom_wput, mem25bit_bput, + fakeuaebootrom_xlate, fakeuaebootrom_check, NULL, _T("*"), _T("fakeuaerom"), + fakeuaebootrom_wget, + ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 }; MEMORY_FUNCTIONS(custmem1); @@ -616,14 +1175,14 @@ addrbank custmem1_bank = { custmem1_lput, custmem1_wput, custmem1_bput, custmem1_xlate, custmem1_check, NULL, _T("custmem1"), _T("Non-autoconfig RAM #1"), custmem1_wget, - ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, 0 }; addrbank custmem2_bank = { custmem2_lget, custmem2_wget, custmem2_bget, custmem2_lput, custmem2_wput, custmem2_bput, custmem2_xlate, custmem2_check, NULL, _T("custmem2"), _T("Non-autoconfig RAM #2"), custmem2_wget, - ABFLAG_RAM | ABFLAG_THREADSAFE, 0, 0 + ABFLAG_RAM | ABFLAG_THREADSAFE | ABFLAG_CACHE_ENABLE_ALL | ABFLAG_DIRECTACCESS, 0, 0 }; static bool singlebit(uae_u32 v) @@ -831,6 +1390,16 @@ static bool load_extendedkickstart (const TCHAR *romextfile, int type) if (_tcslen(romextfile) == 0) return false; +#ifdef ARCADIA + if (is_arcadia_rom(romextfile) == ARCADIA_BIOS) { + extendedkickmem_type = EXTENDED_ROM_ARCADIA; + return false; + } + if (is_alg_rom(romextfile)) { + type = EXTENDED_ROM_ALG; + + } +#endif f = read_rom_name (romextfile); if (!f) { notify_user(NUMSG_NOEXTROM); @@ -874,15 +1443,16 @@ static bool load_extendedkickstart (const TCHAR *romextfile, int type) mapped_malloc (&extendedkickmem_bank); extendedkickmem_bank.start = 0xe00000; break; - //case EXTENDED_ROM_ALG: - // extendedkickmem_bank.label = _T("rom_f0"); - // mapped_malloc(&extendedkickmem_bank); - // extendedkickmem_bank.start = 0xf00000; - // break; + case EXTENDED_ROM_ALG: + extendedkickmem_bank.label = _T("rom_f0"); + mapped_malloc(&extendedkickmem_bank); + extendedkickmem_bank.start = 0xf00000; + break; } - if (extendedkickmem_bank.baseaddr) - { + if (extendedkickmem_bank.baseaddr) { read_kickstart (f, extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size, 0, 1); + if (extendedkickmem_type == EXTENDED_ROM_ALG) + descramble_alg(extendedkickmem_bank.baseaddr, 262144); extendedkickmem_bank.mask = extendedkickmem_bank.allocated_size - 1; ret = true; } @@ -895,13 +1465,19 @@ extern unsigned char arosrom[]; extern unsigned int arosrom_len; static bool load_kickstart_replacement(void) { - struct zfile* f = zfile_fopen_data(_T("aros.gz"), arosrom_len, arosrom); +#ifdef AMIBERRY + struct zfile* f = zfile_fopen_data(_T("aros-ext.bin"), arosrom_len, arosrom); + if (!f) + return false; +#else + f = zfile_fopen_data(_T("aros.gz"), arosrom_len, arosrom); if (!f) return false; f = zfile_gunzip(f); if (!f) return false; - +#endif + extendedkickmem_bank.reserved_size = ROM_SIZE_512; extendedkickmem_bank.mask = ROM_SIZE_512 - 1; extendedkickmem_bank.label = _T("rom_e0"); @@ -909,6 +1485,13 @@ static bool load_kickstart_replacement(void) mapped_malloc(&extendedkickmem_bank); read_kickstart(f, extendedkickmem_bank.baseaddr, ROM_SIZE_512, 0, 1); +#ifdef AMIBERRY + zfile_fclose(f); + f = zfile_fopen_data(_T("aros-rom.bin"), arosrom_len, arosrom); + if (!f) + return false; +#endif + kickmem_bank.reserved_size = ROM_SIZE_512; kickmem_bank.mask = ROM_SIZE_512 - 1; read_kickstart(f, kickmem_bank.baseaddr, ROM_SIZE_512, 1, 0); @@ -921,7 +1504,8 @@ static bool load_kickstart_replacement(void) currprefs.fastmem[0].size == 0 && currprefs.z3fastmem[0].size == 0 && currprefs.mbresmem_high_size == 0 && - currprefs.mbresmem_low_size == 0) { + currprefs.mbresmem_low_size == 0 && + currprefs.cpuboardmem1_size == 0) { changed_prefs.custom_memory_addrs[0] = currprefs.custom_memory_addrs[0] = 0xa80000; changed_prefs.custom_memory_sizes[0] = currprefs.custom_memory_sizes[0] = 512 * 1024; @@ -936,6 +1520,29 @@ static bool load_kickstart_replacement(void) return true; } +static int patch_shapeshifter(uae_u8* kickmemory) +{ + /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer. + * Changes 'lea $400,a0' and 'lea $1000,a0' to 'lea $3000,a0' for + * ShapeShifter compatibility. + */ + int i, patched = 0; + uae_u8 kickshift1[] = { 0x41, 0xf8, 0x04, 0x00 }; + uae_u8 kickshift2[] = { 0x41, 0xf8, 0x10, 0x00 }; + uae_u8 kickshift3[] = { 0x43, 0xf8, 0x04, 0x00 }; + + for (i = 0x200; i < 0x300; i++) { + if (!memcmp(kickmemory + i, kickshift1, sizeof(kickshift1)) || + !memcmp(kickmemory + i, kickshift2, sizeof(kickshift2)) || + !memcmp(kickmemory + i, kickshift3, sizeof(kickshift3))) { + kickmemory[i + 2] = 0x30; + write_log(_T("Kickstart KickShifted @%04X\n"), i); + patched++; + } + } + return patched; +} + /* disable incompatible drivers */ static int patch_residents(uae_u8* kickmemory, int size) { @@ -944,25 +1551,27 @@ static int patch_residents(uae_u8* kickmemory, int size) // "scsi.device", "carddisk.device", "card.resource" }; uaecptr base = size == ROM_SIZE_512 ? 0xf80000 : 0xfc0000; - for (i = 0; i < size - 100; i++) { - if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) { - uaecptr addr; - addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0); - if (addr != i + base) - continue; - addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0); - if (addr >= base && addr < base + size) { - j = 0; - while (residents[j]) { - if (!memcmp(residents[j], kickmemory + addr - base, strlen(residents[j]) + 1)) { - TCHAR* s = au(residents[j]); - write_log(_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base); - xfree(s); - kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */ - patched++; - break; + if (is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0) < 0) { + for (i = 0; i < size - 100; i++) { + if (kickmemory[i] == 0x4a && kickmemory[i + 1] == 0xfc) { + uaecptr addr; + addr = (kickmemory[i + 2] << 24) | (kickmemory[i + 3] << 16) | (kickmemory[i + 4] << 8) | (kickmemory[i + 5] << 0); + if (addr != i + base) + continue; + addr = (kickmemory[i + 14] << 24) | (kickmemory[i + 15] << 16) | (kickmemory[i + 16] << 8) | (kickmemory[i + 17] << 0); + if (addr >= base && addr < base + size) { + j = 0; + while (residents[j]) { + if (!memcmp(residents[j], kickmemory + addr - base, strlen(residents[j]) + 1)) { + TCHAR* s = au(residents[j]); + write_log(_T("KSPatcher: '%s' at %08X disabled\n"), s, i + base); + xfree(s); + kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */ + patched++; + break; + } + j++; } - j++; } } } @@ -973,19 +1582,21 @@ static int patch_residents(uae_u8* kickmemory, int size) static void patch_kick(void) { int patched = 0; - patched += patch_residents (kickmem_bank.baseaddr, kickmem_bank.allocated_size); + if (kickmem_bank.allocated_size >= ROM_SIZE_512 && currprefs.kickshifter) + patched += patch_shapeshifter(kickmem_bank.baseaddr); + patched += patch_residents(kickmem_bank.baseaddr, kickmem_bank.allocated_size); if (extendedkickmem_bank.baseaddr) { - patched += patch_residents (extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size); + patched += patch_residents(extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size); if (patched) - kickstart_fix_checksum (extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size); + kickstart_fix_checksum(extendedkickmem_bank.baseaddr, extendedkickmem_bank.allocated_size); } if (patched) - kickstart_fix_checksum (kickmem_bank.baseaddr, kickmem_bank.allocated_size); + kickstart_fix_checksum(kickmem_bank.baseaddr, kickmem_bank.allocated_size); } -static struct zfile *get_kickstart_filehandle(struct uae_prefs *p) +static struct zfile* get_kickstart_filehandle(struct uae_prefs* p) { - struct zfile *f; + struct zfile* f; TCHAR tmprom[MAX_DPATH], tmprom2[MAX_DPATH]; f = read_rom_name(p->romfile); @@ -1001,7 +1612,15 @@ static struct zfile *get_kickstart_filehandle(struct uae_prefs *p) _stprintf(tmprom2, _T("%skick.rom"), start_path_data); f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); if (f == NULL) { - f = read_rom_name_guess (tmprom, tmprom2); + _stprintf(tmprom2, _T("%s../shared/rom/kick.rom"), start_path_data); + f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); + if (f == NULL) { + _stprintf(tmprom2, _T("%s../System/rom/kick.rom"), start_path_data); + f = rom_fopen(tmprom2, _T("rb"), ZFD_NORMAL); + if (f == NULL) { + f = read_rom_name_guess(tmprom, tmprom2); + } + } } } } @@ -1012,7 +1631,6 @@ static struct zfile *get_kickstart_filehandle(struct uae_prefs *p) return f; } -extern struct zfile *read_executable_rom(struct zfile*, int size, int blocks); static const uae_u8 romend[20] = { 0x00, 0x08, 0x00, 0x00, 0x00, 0x18, 0x00, 0x19, 0x00, 0x1a, 0x00, 0x1b, 0x00, 0x1c, 0x00, 0x1d, 0x00, 0x1e, 0x00, 0x1f @@ -1042,6 +1660,30 @@ static int load_kickstart (void) maxsize = ROM_SIZE_512; + //if ((tmp[0] == 0x00 && tmp[1] == 0x00 && tmp[2] == 0x03 && tmp[3] == 0xf3 && + // tmp[4] == 0x00 && tmp[5] == 0x00 && tmp[6] == 0x00 && tmp[7] == 0x00) || + // (tmp[0] == 0x7f && tmp[1] == 'E' && tmp[2] == 'L' && tmp[3] == 'F')) { + // struct zfile* zf = read_executable_rom(f, ROM_SIZE_512, 3); + // if (zf) { + // int size = zfile_size(zf); + // zfile_fclose(f); + // f = zf; + // if (size > ROM_SIZE_512) { + // maxsize = zfile_size(zf); + // singlebigrom = true; + // extendedkickmem2_bank.reserved_size = size; + // extendedkickmem2_bank.mask = extendedkickmem2_bank.allocated_size - 1; + // extendedkickmem2_bank.start = size > 2 * ROM_SIZE_512 ? 0xa00000 : 0xa80000; + // mapped_malloc(&extendedkickmem2_bank); + // read_kickstart(f, extendedkickmem2_bank.baseaddr, size, 0, 1); + // memset(kickmem_bank.baseaddr, 0, ROM_SIZE_512); + // memcpy(kickmem_bank.baseaddr, extendedkickmem2_bank.baseaddr, 0xd0); + // memcpy(kickmem_bank.baseaddr + ROM_SIZE_512 - 20, romend, sizeof(romend)); + // kickstart_fix_checksum(kickmem_bank.baseaddr, ROM_SIZE_512); + // } + // } + //} + if (!singlebigrom) { zfile_fseek(f, 0, SEEK_END); filesize = zfile_ftell(f); @@ -1115,28 +1757,114 @@ err: return 0; } +static void set_direct_memory(addrbank* ab) +{ + if (!(ab->flags & ABFLAG_DIRECTACCESS)) + return; + ab->baseaddr_direct_r = ab->baseaddr; + if (!(ab->flags & ABFLAG_ROM)) + ab->baseaddr_direct_w = ab->baseaddr; +} + + static void init_mem_banks(void) { // unsigned so i << 16 won't overflow to negative when i >= 32768 - for (auto& mem_bank : mem_banks) - mem_bank = &dummy_bank; + for (unsigned int i = 0; i < MEMORY_BANKS; i++) + put_mem_bank(i << 16, &dummy_bank, 0); +#ifdef NATMEM_OFFSET + //delete_shmmaps(0, 0xFFFF0000); +#endif } -static void map_banks_set(addrbank *bank, int start, int size, int realsize) +static void map_banks_set(addrbank* bank, int start, int size, int realsize) { + bank->startmask = start << 16; map_banks(bank, start, size, realsize); } static void allocate_memory(void) { - if (chipmem_bank.reserved_size != currprefs.chipmem_size) { + bogomem_aliasing = 0; + + bool bogoreset = (bogomem_bank.flags & ABFLAG_NOALLOC) != 0 && + (chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size); + + mapped_free(&fakeuaebootrom_bank); + + if (bogoreset) { + mapped_free(&chipmem_bank); + mapped_free(&bogomem_bank); + } + + /* emulate 0.5M+0.5M with 1M Agnus chip ram aliasing */ + if (currprefs.chipmem_size == 0x80000 && currprefs.bogomem_size >= 0x80000 && + (currprefs.chipset_mask & CSMASK_ECS_AGNUS) && !(currprefs.chipset_mask & CSMASK_AGA) && currprefs.cpu_model < 68020) { + if ((chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size)) { + int memsize1, memsize2; + mapped_free(&chipmem_bank); + mapped_free(&bogomem_bank); + bogomem_bank.reserved_size = 0; + memsize1 = chipmem_bank.reserved_size = currprefs.chipmem_size; + memsize2 = bogomem_bank.reserved_size = currprefs.bogomem_size; + chipmem_bank.mask = chipmem_bank.reserved_size - 1; + chipmem_bank.start = chipmem_start_addr; + chipmem_full_mask = bogomem_bank.reserved_size * 2 - 1; + chipmem_full_size = 0x80000 * 2; + chipmem_bank.reserved_size = memsize1 + memsize2; + mapped_malloc(&chipmem_bank); + chipmem_bank.reserved_size = currprefs.chipmem_size; + chipmem_bank.allocated_size = currprefs.chipmem_size; + bogomem_bank.baseaddr = chipmem_bank.baseaddr + memsize1; + bogomem_bank.mask = bogomem_bank.reserved_size - 1; + bogomem_bank.start = bogomem_start_addr; + bogomem_bank.flags |= ABFLAG_NOALLOC; + bogomem_bank.allocated_size = bogomem_bank.reserved_size; + if (chipmem_bank.baseaddr == 0) { + write_log(_T("Fatal error: out of memory for chipmem.\n")); + chipmem_bank.reserved_size = 0; + } else { + need_hardreset = true; + } + } + bogomem_aliasing = 1; + } else if (currprefs.chipmem_size == 0x80000 && currprefs.bogomem_size >= 0x80000 && + !(currprefs.chipset_mask & CSMASK_ECS_AGNUS) && currprefs.cs_1mchipjumper && currprefs.cpu_model < 68020) { + if ((chipmem_bank.reserved_size != currprefs.chipmem_size || bogomem_bank.reserved_size != currprefs.bogomem_size)) { + int memsize1, memsize2; + mapped_free(&chipmem_bank); + mapped_free(&bogomem_bank); + bogomem_bank.reserved_size = 0; + memsize1 = chipmem_bank.reserved_size = currprefs.chipmem_size; + memsize2 = bogomem_bank.reserved_size = currprefs.bogomem_size; + chipmem_bank.mask = chipmem_bank.reserved_size - 1; + chipmem_bank.start = chipmem_start_addr; + chipmem_full_mask = chipmem_bank.reserved_size - 1; + chipmem_full_size = chipmem_bank.reserved_size; + chipmem_bank.reserved_size = memsize1 + memsize2; + mapped_malloc(&chipmem_bank); + chipmem_bank.reserved_size = currprefs.chipmem_size; + chipmem_bank.allocated_size = currprefs.chipmem_size; + bogomem_bank.baseaddr = chipmem_bank.baseaddr + memsize1; + bogomem_bank.mask = bogomem_bank.reserved_size - 1; + bogomem_bank.start = chipmem_bank.start + currprefs.chipmem_size; + bogomem_bank.flags |= ABFLAG_NOALLOC; + if (chipmem_bank.baseaddr == 0) { + write_log(_T("Fatal error: out of memory for chipmem.\n")); + chipmem_bank.reserved_size = 0; + } else { + need_hardreset = true; + } + } + bogomem_aliasing = 2; + } + + if (chipmem_bank.reserved_size != currprefs.chipmem_size || bogoreset) { int memsize; mapped_free(&chipmem_bank); - if (currprefs.chipmem_size > 2 * 1024 * 1024) { - free_fastmemory(0); - } + chipmem_bank.flags &= ~ABFLAG_NOALLOC; - memsize = chipmem_bank.reserved_size = currprefs.chipmem_size; + memsize = chipmem_bank.reserved_size = chipmem_full_size = currprefs.chipmem_size; chipmem_full_mask = chipmem_bank.mask = chipmem_bank.reserved_size - 1; chipmem_bank.start = chipmem_start_addr; if (!currprefs.cachesize && memsize < 0x100000) @@ -1150,8 +1878,8 @@ static void allocate_memory(void) if (chipmem_bank.baseaddr == 0) { write_log(_T("Fatal error: out of memory for chipmem.\n")); chipmem_bank.reserved_size = 0; - } - else { + } else { + need_hardreset = true; if (memsize > chipmem_bank.allocated_size) memset(chipmem_bank.baseaddr + chipmem_bank.allocated_size, 0xff, memsize - chipmem_bank.allocated_size); } @@ -1163,32 +1891,60 @@ static void allocate_memory(void) chipmem_full_mask = 0x100000 - 1; if (chipmem_bank.allocated_size > 0x100000 && chipmem_bank.allocated_size < 0x200000) chipmem_full_mask = chipmem_bank.mask = 0x200000 - 1; + } else if (currprefs.cs_1mchipjumper) { + chipmem_full_mask = 0x80000 - 1; } } } - if (bogomem_bank.reserved_size != currprefs.bogomem_size) { - mapped_free(&bogomem_bank); - bogomem_bank.reserved_size = 0; + if (bogomem_bank.reserved_size != currprefs.bogomem_size || bogoreset) { + if (!(bogomem_bank.reserved_size == 0x200000 && currprefs.bogomem_size == 0x180000)) { + mapped_free(&bogomem_bank); + bogomem_bank.flags &= ~ABFLAG_NOALLOC; + bogomem_bank.reserved_size = 0; - if (currprefs.bogomem_size > 0x1c0000) - currprefs.bogomem_size = 0x1c0000; - if (currprefs.bogomem_size > 0x180000 && ((currprefs.chipset_mask & CSMASK_AGA) || (currprefs.cpu_model >= 68020))) - currprefs.bogomem_size = 0x180000; + bogomem_bank.reserved_size = currprefs.bogomem_size; + if (bogomem_bank.reserved_size >= 0x180000) + bogomem_bank.reserved_size = 0x200000; + bogomem_bank.mask = bogomem_bank.reserved_size - 1; + bogomem_bank.start = bogomem_start_addr; - bogomem_bank.reserved_size = currprefs.bogomem_size; - if (bogomem_bank.reserved_size >= 0x180000) - bogomem_bank.reserved_size = 0x200000; - bogomem_bank.mask = bogomem_bank.reserved_size - 1; - bogomem_bank.start = bogomem_start_addr; + if (bogomem_bank.reserved_size) { + if (!mapped_malloc(&bogomem_bank)) { + write_log(_T("Out of memory for bogomem.\n")); + bogomem_bank.reserved_size = 0; + } + } + need_hardreset = true; + } + } + if (debugmem_bank.reserved_size != currprefs.debugmem_size) { + mapped_free(&debugmem_bank); - if (bogomem_bank.reserved_size) { - if (!mapped_malloc(&bogomem_bank)) { - write_log(_T("Out of memory for bogomem.\n")); - bogomem_bank.reserved_size = 0; + debugmem_bank.reserved_size = currprefs.debugmem_size; + debugmem_bank.mask = debugmem_bank.reserved_size - 1; + debugmem_bank.start = currprefs.debugmem_start; + if (debugmem_bank.reserved_size) { + if (!mapped_malloc(&debugmem_bank)) { + write_log(_T("Out of memory for debugger memory.\n")); + debugmem_bank.reserved_size = 0; } } } + if (mem25bit_bank.reserved_size != currprefs.mem25bit_size) { + mapped_free(&mem25bit_bank); + + mem25bit_bank.reserved_size = currprefs.mem25bit_size; + mem25bit_bank.mask = mem25bit_bank.reserved_size - 1; + mem25bit_bank.start = 0x01000000; + if (mem25bit_bank.reserved_size) { + if (!mapped_malloc(&mem25bit_bank)) { + write_log(_T("Out of memory for 25 bit memory.\n")); + mem25bit_bank.reserved_size = 0; + } + } + need_hardreset = true; + } if (a3000lmem_bank.reserved_size != currprefs.mbresmem_low_size) { mapped_free(&a3000lmem_bank); @@ -1201,6 +1957,7 @@ static void allocate_memory(void) a3000lmem_bank.reserved_size = 0; } } + need_hardreset = true; } if (a3000hmem_bank.reserved_size != currprefs.mbresmem_high_size) { mapped_free(&a3000hmem_bank); @@ -1214,48 +1971,159 @@ static void allocate_memory(void) a3000hmem_bank.reserved_size = 0; } } + need_hardreset = true; } allocate_memory_custombanks(); +#ifdef SAVESTATE if (savestate_state == STATE_RESTORE) { if (bootrom_filepos) { - if (currprefs.uaeboard < 0) - currprefs.uaeboard = 0; protect_roms(false); restore_ram(bootrom_filepos, rtarea_bank.baseaddr); protect_roms(true); + if (currprefs.uaeboard >= 2) { + map_banks_set(&rtarea_bank, rtarea_base >> 16, 1, 0); + } } restore_ram(chip_filepos, chipmem_bank.baseaddr); if (bogomem_bank.allocated_size > 0) restore_ram(bogo_filepos, bogomem_bank.baseaddr); + if (mem25bit_bank.allocated_size > 0) + restore_ram(mem25bit_filepos, mem25bit_bank.baseaddr); if (a3000lmem_bank.allocated_size > 0) restore_ram(a3000lmem_filepos, a3000lmem_bank.baseaddr); if (a3000hmem_bank.allocated_size > 0) restore_ram(a3000hmem_filepos, a3000hmem_bank.baseaddr); } +#endif + +#ifdef AGA + chipmem_bank_ce2.baseaddr = chipmem_bank.baseaddr; +#endif bootrom_filepos = 0; chip_filepos = 0; bogo_filepos = 0; a3000lmem_filepos = 0; a3000hmem_filepos = 0; + //cpuboard_init(); } +static void fill_ce_banks(void) +{ + int i; + + if (currprefs.cpu_model <= 68010) { + memset(ce_banktype, CE_MEMBANK_FAST16, sizeof ce_banktype); + } else { + memset(ce_banktype, CE_MEMBANK_FAST32, sizeof ce_banktype); + } + + addrbank* ab = &get_mem_bank(0); + if (ab && (ab->flags & ABFLAG_CHIPRAM)) { + for (i = 0; i < (0x200000 >> 16); i++) { + ce_banktype[i] = (currprefs.cs_mbdmac || (currprefs.chipset_mask & CSMASK_AGA)) ? CE_MEMBANK_CHIP32 : CE_MEMBANK_CHIP16; + } + } + if (!currprefs.cs_slowmemisfast) { + for (i = (0xc00000 >> 16); i < (0xe00000 >> 16); i++) + ce_banktype[i] = ce_banktype[0]; + for (i = (bogomem_bank.start >> 16); i < ((bogomem_bank.start + bogomem_bank.allocated_size) >> 16); i++) + ce_banktype[i] = ce_banktype[0]; + } + for (i = (0xd00000 >> 16); i < (0xe00000 >> 16); i++) { + ce_banktype[i] = CE_MEMBANK_CHIP16; + } + for (i = (0xa00000 >> 16); i < (0xc00000 >> 16); i++) { + addrbank* b; + ce_banktype[i] = CE_MEMBANK_CIA; + b = &get_mem_bank(i << 16); + if (b && !(b->flags & ABFLAG_CIA)) { + ce_banktype[i] = CE_MEMBANK_FAST32; + } + } + // CD32 ROM is 16-bit + if (currprefs.cs_cd32cd) { + for (i = (0xe00000 >> 16); i < (0xe80000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_FAST16; + for (i = (0xf80000 >> 16); i <= (0xff0000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_FAST16; + } + + // A4000T NCR is 32-bit + if (is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0) >= 0) { + ce_banktype[0xdd0000 >> 16] = CE_MEMBANK_FAST32; + } + + if (currprefs.cs_toshibagary) { + for (i = (0xe80000 >> 16); i < (0xf80000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_CHIP16; + } + + if (currprefs.cs_romisslow) { + for (i = (0xe00000 >> 16); i < (0xe80000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_CHIP16; + for (i = (0xf80000 >> 16); i < (0x1000000 >> 16); i++) + ce_banktype[i] = CE_MEMBANK_CHIP16; + } + + if (currprefs.address_space_24) { + for (i = 1; i < 256; i++) + memcpy(&ce_banktype[i * 256], &ce_banktype[0], 256); + } +} + +static int overlay_state; + void map_overlay(int chip) { int size; addrbank* cb; - int currPC = m68k_getpc(); + if (chip < 0) + chip = overlay_state; + + //if (currprefs.cs_compatible == CP_CASABLANCA) { + // casablanca_map_overlay(); + // return; + //} + size = chipmem_bank.allocated_size >= 0x180000 ? (chipmem_bank.allocated_size >> 16) : 32; + if (bogomem_aliasing) + size = 8; cb = &chipmem_bank; if (chip) { map_banks(&dummy_bank, 0, size, 0); - map_banks(cb, 0, size, chipmem_bank.allocated_size); + if (!isdirectjit()) { + if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && bogomem_bank.allocated_size == 0) { + map_banks(cb, 0, size, chipmem_bank.allocated_size); + int start = chipmem_bank.allocated_size >> 16; + if (chipmem_bank.allocated_size < 0x100000) { + if (currprefs.cs_1mchipjumper) { + int dummy = (0x100000 - chipmem_bank.allocated_size) >> 16; + map_banks(&chipmem_dummy_bank, start, dummy, 0); + map_banks(&chipmem_dummy_bank, start + 16, dummy, 0); + } + } + else if (chipmem_bank.allocated_size < 0x200000 && chipmem_bank.allocated_size > 0x100000) { + int dummy = (0x200000 - chipmem_bank.allocated_size) >> 16; + map_banks(&chipmem_dummy_bank, start, dummy, 0); + } + } + else { + int mapsize = 32; + if ((chipmem_bank.allocated_size >> 16) > mapsize) + mapsize = chipmem_bank.allocated_size >> 16; + map_banks(cb, 0, mapsize, chipmem_bank.allocated_size); + } + } + else { + map_banks(cb, 0, chipmem_bank.allocated_size >> 16, 0); + } } else { addrbank* rb = NULL; - if (size < 32) + if (size < 32 && bogomem_aliasing == 0) size = 32; cb = &get_mem_bank(0xf00000); if (!rb && cb && (cb->flags & ABFLAG_ROM) && get_word(0xf00000) == 0x1114) @@ -1267,8 +2135,11 @@ void map_overlay(int chip) rb = &kickmem_bank; map_banks(rb, 0, size, 0x80000); } + overlay_state = chip; + fill_ce_banks(); + //cpuboard_overlay_override(); if (!isrestore() && valid_address(regs.pc, 4)) - m68k_setpc_normal(currPC); + m68k_setpc_normal(m68k_getpc()); } void memory_clear(void) @@ -1280,21 +2151,30 @@ void memory_clear(void) memset(chipmem_bank.baseaddr, 0, chipmem_bank.allocated_size); if (bogomem_bank.baseaddr) memset(bogomem_bank.baseaddr, 0, bogomem_bank.allocated_size); + if (mem25bit_bank.baseaddr) + memset(mem25bit_bank.baseaddr, 0, mem25bit_bank.allocated_size); if (a3000lmem_bank.baseaddr) memset(a3000lmem_bank.baseaddr, 0, a3000lmem_bank.allocated_size); if (a3000hmem_bank.baseaddr) memset(a3000hmem_bank.baseaddr, 0, a3000hmem_bank.allocated_size); expansion_clear(); + //cpuboard_clear(); } static void restore_roms(void) { + roms_modified = false; protect_roms(false); write_log(_T("ROM loader.. (%s)\n"), currprefs.romfile); kickstart_rom = 1; + a1000_handle_kickstart(0); + xfree(a1000_bootrom); + a1000_bootrom = 0; + a1000_kickstart_mode = 0; memcpy(currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile); memcpy(currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile); + need_hardreset = true; mapped_free(&extendedkickmem_bank); mapped_free(&extendedkickmem2_bank); extendedkickmem_bank.reserved_size = 0; @@ -1303,20 +2183,15 @@ static void restore_roms(void) load_extendedkickstart(currprefs.romextfile, 0); load_extendedkickstart(currprefs.romextfile2, EXTENDED_ROM_CDTV); kickmem_bank.mask = ROM_SIZE_512 - 1; - if (!load_kickstart()) - { - if (_tcslen(currprefs.romfile) > 0) - { + if (!load_kickstart ()) { + if (_tcslen (currprefs.romfile) > 0) { error_log(_T("Failed to open '%s'\n"), currprefs.romfile); notify_user(NUMSG_NOROM); } load_kickstart_replacement(); - } - else - { + } else { struct romdata *rd = getromdatabydata(kickmem_bank.baseaddr, kickmem_bank.reserved_size); - if (rd) - { + if (rd) { write_log(_T("Known ROM '%s' loaded\n"), rd->name); if ((rd->cpu & 8) && changed_prefs.cpu_model < 68030) { @@ -1352,9 +2227,7 @@ static void restore_roms(void) if (currprefs.cs_ide != IDE_A4000) changed_prefs.cs_ide = currprefs.cs_ide = -1; } - } - else - { + } else { write_log(_T("Unknown ROM '%s' loaded\n"), currprefs.romfile); } } @@ -1384,20 +2257,37 @@ bool read_kickstart_version(struct uae_prefs *p) return true; } -static void memory_init (void); +void reload_roms(void) +{ + if (roms_modified) + restore_roms(); +} + +void memory_restore(void) +{ + last_address_space_24 = currprefs.address_space_24; + //cpuboard_map(); + map_banks_set(&kickmem_bank, 0xF8, 8, 0); +} void memory_reset(void) { int bnk, bnk_end; bool gayleorfatgary; + //alg_flag = 0; + need_hardreset = false; rom_write_enabled = true; /* Use changed_prefs, as m68k_reset is called later. */ + if (last_address_space_24 != changed_prefs.address_space_24) + need_hardreset = true; last_address_space_24 = changed_prefs.address_space_24; if (mem_hardreset > 2) memory_init(); + memset(ce_cachable, CACHE_ENABLE_INS, sizeof ce_cachable); + be_cnt = be_recursive = 0; currprefs.chipmem_size = changed_prefs.chipmem_size; currprefs.bogomem_size = changed_prefs.bogomem_size; @@ -1412,22 +2302,31 @@ void memory_reset(void) currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev; currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev; currprefs.cs_unmapped_space = changed_prefs.cs_unmapped_space; + //cpuboard_reset(); - gayleorfatgary = ((currprefs.chipset_mask & CSMASK_AGA) || currprefs.cs_pcmcia || currprefs.cs_ide > 0) && !currprefs.cs_cd32cd; + gayleorfatgary = ((currprefs.chipset_mask & CSMASK_AGA) || currprefs.cs_pcmcia || currprefs.cs_ide > 0 || currprefs.cs_mbdmac) && !currprefs.cs_cd32cd; init_mem_banks(); allocate_memory(); + chipmem_setindirect(); - if (mem_hardreset > 1 - || _tcscmp (currprefs.romfile, changed_prefs.romfile) != 0 - || _tcscmp (currprefs.romextfile, changed_prefs.romextfile) != 0) + if (mem_hardreset > 1 || ((roms_modified || a1000_bootrom) && is_hardreset()) + || _tcscmp(currprefs.romfile, changed_prefs.romfile) != 0 + || _tcscmp(currprefs.romextfile, changed_prefs.romextfile) != 0) { restore_roms(); } + if ((cloanto_rom || extendedkickmem_bank.allocated_size) && currprefs.maprom && currprefs.maprom < 0x01000000) + { + currprefs.maprom = changed_prefs.maprom = 0x00a80000; + if (extendedkickmem2_bank.allocated_size) // can't do if 2M ROM + currprefs.maprom = changed_prefs.maprom = 0; + } + map_banks(&custom_bank, 0xC0, 0xE0 - 0xC0, 0); map_banks(&cia_bank, 0xA0, 32, 0); - if (currprefs.cs_rtc != 3) + if (!currprefs.cs_a1000ram && currprefs.cs_rtc != 3) /* D80000 - DDFFFF not mapped (A1000 or A2000 = custom chips) */ map_banks(&dummy_bank, 0xD8, 6, 0); @@ -1438,13 +2337,12 @@ void memory_reset(void) bnk_end = currprefs.cs_cd32cd ? 0xBE : (gayleorfatgary ? 0xBF : 0xA0); map_banks(&dummy_bank, bnk, bnk_end - bnk, 0); if (gayleorfatgary) { - // a4000 = custom chips from 0xc0 to 0xd0 - if (currprefs.cs_ide == IDE_A4000) + // a3000 or a4000 = custom chips from 0xc0 to 0xd0 + if (currprefs.cs_ide == IDE_A4000 || currprefs.cs_mbdmac) map_banks(&dummy_bank, 0xd0, 8, 0); else map_banks(&dummy_bank, 0xc0, 0xd8 - 0xc0, 0); - } - else if (currprefs.cs_cd32cd) { + } else if (currprefs.cs_cd32cd) { // CD32: 0xc0 to 0xd0 map_banks(&dummy_bank, 0xd0, 8, 0); // strange 64k custom mirror @@ -1457,16 +2355,18 @@ void memory_reset(void) t = 0x1C; if (t > 0x18 && ((currprefs.chipset_mask & CSMASK_AGA) || (currprefs.cpu_model >= 68020 && !currprefs.address_space_24))) t = 0x18; - map_banks(&bogomem_bank, 0xC0, t, 0); + if (bogomem_aliasing == 2) + map_banks(&bogomem_bank, 0x08, t, 0); + else + map_banks(&bogomem_bank, 0xC0, t, 0); } - if (currprefs.cs_ide || currprefs.cs_pcmcia) - { - if (currprefs.cs_ide == IDE_A600A1200 || currprefs.cs_pcmcia) - { + if (currprefs.cs_ide || currprefs.cs_pcmcia) { + if (currprefs.cs_ide == IDE_A600A1200 || currprefs.cs_pcmcia) { map_banks(&gayle_bank, 0xD8, 6, 0); map_banks(&gayle2_bank, 0xDD, 2, 0); } - if (currprefs.cs_ide == IDE_A4000) + gayle_map_pcmcia(); + if (currprefs.cs_ide == IDE_A4000 || is_device_rom(&currprefs, ROMTYPE_SCSI_A4000T, 0)) map_banks(&gayle_bank, 0xDD, 1, 0); if (currprefs.cs_ide < 0 && !currprefs.cs_pcmcia) map_banks(&gayle_bank, 0xD8, 6, 0); @@ -1487,11 +2387,20 @@ void memory_reset(void) map_banks(&gayle2_bank, 0xDD, 2, 0); } #endif + if (mem25bit_bank.baseaddr) + map_banks(&mem25bit_bank, mem25bit_bank.start >> 16, mem25bit_bank.allocated_size >> 16, 0); if (a3000lmem_bank.baseaddr) map_banks(&a3000lmem_bank, a3000lmem_bank.start >> 16, a3000lmem_bank.allocated_size >> 16, 0); if (a3000hmem_bank.baseaddr) map_banks(&a3000hmem_bank, a3000hmem_bank.start >> 16, a3000hmem_bank.allocated_size >> 16, 0); + if (debugmem_bank.baseaddr) + map_banks(&debugmem_bank, debugmem_bank.start >> 16, debugmem_bank.allocated_size >> 16, 0); + //cpuboard_map(); map_banks_set(&kickmem_bank, 0xF8, 8, 0); + //if (currprefs.maprom) { + // if (!cpuboard_maprom()) + // map_banks_set(&kickram_bank, currprefs.maprom >> 16, extendedkickmem2_bank.allocated_size ? 32 : (extendedkickmem_bank.allocated_size ? 16 : 8), 0); + //} /* map beta Kickstarts at 0x200000/0xC00000/0xF00000 */ if (kickmem_bank.baseaddr[0] == 0x11 && kickmem_bank.baseaddr[2] == 0x4e && kickmem_bank.baseaddr[3] == 0xf9 && kickmem_bank.baseaddr[4] == 0x00) { uae_u32 addr = kickmem_bank.baseaddr[5]; @@ -1503,10 +2412,16 @@ void memory_reset(void) map_banks_set(&kickmem_bank, addr, 8, 0); } + if (a1000_bootrom) + a1000_handle_kickstart(1); + #ifdef AUTOCONFIG expansion_map(); #endif + if (a3000_f0) + map_banks_set(&extendedkickmem_bank, 0xf0, 1, 0); + /* Map the chipmem into all of the lower 8MB */ map_overlay(1); @@ -1524,6 +2439,10 @@ void memory_reset(void) map_banks_set(&extendedkickmem_bank, 0xE0, 8, 0); break; #endif + //case EXTENDED_ROM_ALG: + // map_banks_set(&extendedkickmem_bank, 0xF0, 4, 0); + // alg_map_banks(); + // break; } #ifdef AUTOCONFIG @@ -1537,8 +2456,7 @@ void memory_reset(void) if (currprefs.cs_ksmirror_a8) { if (extendedkickmem2_bank.allocated_size) { map_banks_set(&extendedkickmem2_bank, extendedkickmem2_bank.start >> 16, extendedkickmem2_bank.allocated_size >> 16, 0); - } - else { + } else { struct romdata* rd = getromdatabypath(currprefs.cartfile); if (!rd || rd->id != 63) { if (extendedkickmem_type == EXTENDED_ROM_CD32 || extendedkickmem_type == EXTENDED_ROM_KS) @@ -1548,20 +2466,38 @@ void memory_reset(void) map_banks(&kickmem_bank, 0xa8, 8, 0); } } - } - else if (extendedkickmem2_bank.allocated_size && extendedkickmem2_bank.baseaddr) { + } else if (extendedkickmem2_bank.allocated_size && extendedkickmem2_bank.baseaddr) { map_banks_set(&extendedkickmem2_bank, extendedkickmem2_bank.start >> 16, extendedkickmem2_bank.allocated_size >> 16, 0); } +#ifdef ARCADIA + if (is_arcadia_rom(currprefs.romextfile) == ARCADIA_BIOS) { + if (_tcscmp(currprefs.romextfile, changed_prefs.romextfile) != 0) + memcpy(currprefs.romextfile, changed_prefs.romextfile, sizeof currprefs.romextfile); + if (_tcscmp(currprefs.cartfile, changed_prefs.cartfile) != 0) + memcpy(currprefs.cartfile, changed_prefs.cartfile, sizeof currprefs.cartfile); + arcadia_unmap(); + is_arcadia_rom(currprefs.romextfile); + is_arcadia_rom(currprefs.cartfile); + arcadia_map_banks(); + } +#endif + #ifdef ACTION_REPLAY - action_replay_memory_reset(); +#ifdef ARCADIA + if (!arcadia_bios) { +#endif + action_replay_memory_reset(); +#ifdef ARCADIA + } +#endif #endif for (int i = 0; i < 2; i++) { if (currprefs.custom_memory_sizes[i]) { map_banks(i == 0 ? &custmem1_bank : &custmem2_bank, - currprefs.custom_memory_addrs[i] >> 16, - currprefs.custom_memory_sizes[i] >> 16, 0); + currprefs.custom_memory_addrs[i] >> 16, + currprefs.custom_memory_sizes[i] >> 16, 0); if (currprefs.custom_memory_mask[i]) { for (int j = currprefs.custom_memory_addrs[i]; j & currprefs.custom_memory_mask[i]; j += currprefs.custom_memory_sizes[i]) { map_banks(i == 0 ? &custmem1_bank : &custmem2_bank, j >> 16, currprefs.custom_memory_sizes[i] >> 16, 0); @@ -1576,7 +2512,7 @@ void memory_reset(void) write_log (_T("memory init end\n")); } -static void memory_init (void) +void memory_init (void) { init_mem_banks(); virtualdevice_init(); @@ -1590,6 +2526,7 @@ static void memory_init (void) extendedkickmem2_bank.reserved_size = 0; extendedkickmem_type = 0; chipmem_bank.baseaddr = 0; + mem25bit_bank.reserved_size = mem25bit_bank.reserved_size = 0; a3000lmem_bank.reserved_size = a3000hmem_bank.reserved_size = 0; a3000lmem_bank.baseaddr = a3000hmem_bank.baseaddr = NULL; bogomem_bank.baseaddr = NULL; @@ -1602,6 +2539,7 @@ static void memory_init (void) memset(kickmem_bank.baseaddr, 0, ROM_SIZE_512); _tcscpy(currprefs.romfile, _T("")); currprefs.romextfile[0] = 0; + //cpuboard_reset(); #ifdef ACTION_REPLAY action_replay_unload(0); @@ -1615,24 +2553,39 @@ static void memory_init (void) void memory_cleanup(void) { + mapped_free(&mem25bit_bank); mapped_free(&a3000lmem_bank); mapped_free(&a3000hmem_bank); mapped_free(&bogomem_bank); mapped_free(&kickmem_bank); + xfree(a1000_bootrom); mapped_free(&chipmem_bank); mapped_free(&custmem1_bank); mapped_free(&custmem2_bank); + mapped_free(&fakeuaebootrom_bank); bogomem_bank.baseaddr = NULL; kickmem_bank.baseaddr = NULL; + mem25bit_bank.baseaddr = NULL; a3000lmem_bank.baseaddr = a3000hmem_bank.baseaddr = NULL; + a1000_bootrom = NULL; + a1000_kickstart_mode = 0; chipmem_bank.baseaddr = NULL; custmem1_bank.baseaddr = NULL; custmem2_bank.baseaddr = NULL; + //cpuboard_cleanup(); #ifdef ACTION_REPLAY action_replay_cleanup(); #endif +#ifdef ARCADIA + arcadia_unmap(); +#endif +} + +void set_roms_modified(void) +{ + roms_modified = true; } void memory_hardreset (int mode) @@ -1642,7 +2595,7 @@ void memory_hardreset (int mode) } // do not map if it conflicts with custom banks -void map_banks_cond(addrbank *bank, int start, int size, int realsize) +void map_banks_cond(addrbank* bank, int start, int size, int realsize) { for (int i = 0; i < MAX_CUSTOM_MEMORY_ADDRS; i++) { int cstart = currprefs.custom_memory_addrs[i] >> 16; @@ -1659,13 +2612,130 @@ void map_banks_cond(addrbank *bank, int start, int size, int realsize) map_banks(bank, start, size, realsize); } -static void map_banks2(addrbank* bank, int start, int size, int realsize) +#ifdef WITH_THREADED_CPU + +struct addrbank_thread { + addrbank* orig; + addrbank ab; +}; + +#define MAX_THREAD_BANKS 200 +static addrbank_thread* thread_banks[MAX_THREAD_BANKS]; +addrbank* thread_mem_banks[MEMORY_BANKS]; +static int thread_banks_used; + +static void REGPARAM2 threadcpu_lput(uaecptr addr, uae_u32 l) { - int bnr; + //write_log(_T("LPUT %08x %08x %08x\n"), addr, l, M68K_GETPC); + + process_cpu_indirect_memory_write(addr, l, 2); +} +static void REGPARAM2 threadcpu_wput(uaecptr addr, uae_u32 w) +{ + //write_log(_T("WPUT %08x %08x %08x\n"), addr, w, M68K_GETPC); + + process_cpu_indirect_memory_write(addr, w, 1); +} +static void REGPARAM2 threadcpu_bput(uaecptr addr, uae_u32 b) +{ + //write_log(_T("BPUT %08x %08x %08x\n"), addr, b, M68K_GETPC); + + process_cpu_indirect_memory_write(addr, b, 0); +} +static uae_u32 REGPARAM2 threadcpu_lget(uaecptr addr) +{ + uae_u32 v = process_cpu_indirect_memory_read(addr, 2); + + //write_log(_T("LGET %08x %08x %08x\n"), addr, v, M68K_GETPC); + + return v; +} +static uae_u32 REGPARAM2 threadcpu_wget(uaecptr addr) +{ + uae_u32 v = process_cpu_indirect_memory_read(addr, 1); + + //write_log(_T("WGET %08x %08x %08x\n"), addr, v, M68K_GETPC); + + return v; +} +static uae_u32 REGPARAM2 threadcpu_bget(uaecptr addr) +{ + uae_u32 v = process_cpu_indirect_memory_read(addr, 0); + + //write_log(_T("BGET %08x %08x %08x\n"), addr, v, M68K_GETPC); + + return v; +} + +static addrbank* get_bank_cpu_thread(addrbank* bank) +{ + if ((bank->flags & ABFLAG_THREADSAFE) && !(bank->flags & ABFLAG_IO)) + return bank; + if (bank == &dummy_bank) + return bank; + + for (int i = 0; i < thread_banks_used; i++) { + if (thread_banks[i]->orig == bank) { + return &thread_banks[i]->ab; + } + } + struct addrbank_thread* at = thread_banks[thread_banks_used]; + if (!at) + at = xcalloc(addrbank_thread, 1); + thread_banks[thread_banks_used++] = at; + at->orig = bank; + memcpy(&at->ab, bank, sizeof(addrbank)); + addrbank* tb = &at->ab; + tb->jit_read_flag = S_READ; + tb->jit_write_flag = S_WRITE; + tb->lget = threadcpu_lget; + tb->wget = threadcpu_wget; + tb->bget = threadcpu_bget; + tb->lput = threadcpu_lput; + tb->wput = threadcpu_wput; + tb->bput = threadcpu_bput; + // wgeti/lgeti should always point to real RAM + return tb; +} +#endif + +static void set_memory_cacheable(int bnr, addrbank* bank) +{ + uae_u8 cc = bank->flags >> ABFLAG_CACHE_SHIFT; + if (!currprefs.mmu_model) { + // if no MMU emulation, make sure chip RAM is not data cacheable + if (bank->flags & ABFLAG_CHIPRAM) { + cc &= ~(CACHE_ENABLE_DATA | CACHE_ENABLE_DATA_BURST); + } + } + ce_cachable[bnr] = cc; +} + +static void map_banks2(addrbank* bank, int start, int size, int realsize, int quick) +{ + int bnr, old; unsigned long int hioffs = 0, endhioffs = 0x100; uae_u32 realstart = start; + addrbank* orig_bank = NULL; + bank->flags |= ABFLAG_MAPPED; + +#ifdef WITH_THREADED_CPU + if (currprefs.cpu_thread) { + addrbank* b = bank; + bank = get_bank_cpu_thread(bank); + if (b != bank) + orig_bank = b; + } +#endif + + //if (quick <= 0) + //old = debug_bankchange(-1); flush_icache_hard(3); /* Sure don't want to keep any old mappings around! */ +#ifdef NATMEM_OFFSET + //if (!quick) + //delete_shmmaps(start << 16, size << 16); +#endif if (!realsize) realsize = size << 16; @@ -1677,11 +2747,31 @@ static void map_banks2(addrbank* bank, int start, int size, int realsize) #ifndef ADDRESS_SPACE_24BIT if (start >= 0x100) { + int real_left = 0; for (bnr = start; bnr < start + size; bnr++) { - mem_banks[bnr] = bank; - } + if (!real_left) { + realstart = bnr; + real_left = realsize >> 16; +#ifdef NATMEM_OFFSET + //if (!quick) + //add_shmmaps(realstart << 16, bank); +#endif + } + put_mem_bank(bnr << 16, bank, realstart << 16); + set_memory_cacheable(bnr, bank); +#ifdef WITH_THREADED_CPU + if (currprefs.cpu_thread) { + if (orig_bank) + put_mem_bank(bnr << 16, orig_bank, realstart << 16); + thread_mem_banks[bnr] = orig_bank; + } +#endif + real_left--; + } + //if (quick <= 0) + //debug_bankchange(old); return; - } + } #endif if (last_address_space_24) endhioffs = 0x10000; @@ -1689,24 +2779,93 @@ static void map_banks2(addrbank* bank, int start, int size, int realsize) endhioffs = 0x100; #endif for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) { + int real_left = 0; for (bnr = start; bnr < start + size; bnr++) { - mem_banks[bnr + hioffs] = bank; + if (!real_left) { + realstart = bnr + hioffs; + real_left = realsize >> 16; +#ifdef NATMEM_OFFSET + //if (!quick) + //add_shmmaps(realstart << 16, bank); +#endif + } + put_mem_bank((bnr + hioffs) << 16, bank, realstart << 16); + set_memory_cacheable(bnr + hioffs, bank); +#ifdef WITH_THREADED_CPU + if (currprefs.cpu_thread) { + if (orig_bank) + put_mem_bank((bnr + hioffs) << 16, bank, realstart << 16); + thread_mem_banks[bnr + hioffs] = orig_bank; + } +#endif + real_left--; + } + } + //if (quick <= 0) + //debug_bankchange(old); + fill_ce_banks(); +} + +#ifdef WITH_PPC +static void ppc_generate_map_banks(addrbank* bank, int start, int size) +{ + uae_u32 bankaddr = start << 16; + uae_u32 banksize = size << 16; + if (bank->sub_banks) { + uae_u32 subbankaddr = bankaddr; + addrbank* ab = NULL; + for (int i = 0; i <= 65536; i += MEMORY_MIN_SUBBANK) { + uae_u32 addr = bankaddr + i; + addrbank* ab2 = get_sub_bank(&addr); + if (ab2 != ab && ab != NULL) { + ppc_map_banks(subbankaddr, (bankaddr + i) - subbankaddr, ab->name, (ab->flags & ABFLAG_PPCIOSPACE) ? NULL : ab->baseaddr, ab == &dummy_bank); + subbankaddr = bankaddr + i; + } + ab = ab2; + } + } else { + uae_u8* baseaddr = bank->baseaddr; + if (baseaddr) { + baseaddr += bankaddr - bank->start; + } + // ABFLAG_PPCIOSPACE = map as indirect even if baseaddr is non-NULL + ppc_map_banks(bankaddr, banksize, bank->name, (bank->flags & ABFLAG_PPCIOSPACE) ? NULL : baseaddr, bank == &dummy_bank); + } +} +#endif + +static addrbank* highram_temp_bank[65536 - 0x100]; + +void restore_banks(void) +{ + for (int bnr = 0x100; bnr < 65536; bnr++) { + if (highram_temp_bank[bnr - 0x100]) { + map_banks(highram_temp_bank[bnr - 0x100], bnr, 1, 0); + } else { + map_banks(&dummy_bank, bnr, 1, 0); } } } -void map_banks (addrbank *bank, int start, int size, int realsize) +void map_banks(addrbank* bank, int start, int size, int realsize) { if (start == 0xffffffff) return; if (start >= 0x100) { + int real_left = 0; + for (int bnr = start; bnr < start + size; bnr++) { + highram_temp_bank[bnr - 0x100] = bank; + } if (currprefs.address_space_24) return; } - map_banks2 (bank, start, size, realsize); + map_banks2(bank, start, size, realsize, 0); +#ifdef WITH_PPC + ppc_generate_map_banks(bank, start, size); +#endif } -bool validate_banks_z3(addrbank *bank, int start, int size) +bool validate_banks_z3(addrbank* bank, int start, int size) { if (start < 0x1000 || size <= 0) { error_log(_T("Z3 invalid map_banks(%s) start=%08x size=%08x\n"), bank->name, start << 16, size << 16); @@ -1718,7 +2877,7 @@ bool validate_banks_z3(addrbank *bank, int start, int size) return false; } for (int i = start; i < start + size; i++) { - addrbank *ab = &get_mem_bank(start << 16); + addrbank* ab = &get_mem_bank(start << 16); if (ab != &dummy_bank && ab != bank) { error_log(_T("Z3 map_banks(%s) attempting to override existing memory bank '%s' at %08x!\n"), bank->name, ab->name, i << 16); return false; @@ -1727,14 +2886,14 @@ bool validate_banks_z3(addrbank *bank, int start, int size) return true; } -void map_banks_z3(addrbank *bank, int start, int size) +void map_banks_z3(addrbank* bank, int start, int size) { if (!validate_banks_z3(bank, start, size)) return; map_banks(bank, start, size, 0); } -bool validate_banks_z2(addrbank *bank, int start, int size) +bool validate_banks_z2(addrbank* bank, int start, int size) { if (start < 0x20 || (start >= 0xa0 && start < 0xe9) || start >= 0xf0) { error_log(_T("Z2 map_banks(%s) with invalid start address %08X\n"), bank->name, start << 16); @@ -1760,7 +2919,7 @@ bool validate_banks_z2(addrbank *bank, int start, int size) return false; } for (int i = start; i < start + size; i++) { - addrbank *ab = &get_mem_bank(start << 16); + addrbank* ab = &get_mem_bank(start << 16); if (ab != &dummy_bank) { error_log(_T("Z2 map_banks(%s) attempting to override existing memory bank '%s' at %08x!\n"), bank->name, ab->name, i << 16); return false; @@ -1770,11 +2929,37 @@ bool validate_banks_z2(addrbank *bank, int start, int size) } -void map_banks_z2(addrbank *bank, int start, int size) +void map_banks_z2(addrbank* bank, int start, int size) { if (!validate_banks_z2(bank, start, size)) return; - map_banks (bank, start, size, 0); + map_banks(bank, start, size, 0); +} + +uae_u32 map_banks_z2_autosize(addrbank* bank, int start) +{ + uae_u32 size = expansion_board_size(bank); + if (!size) { + error_log(_T("Z2 map_banks(%s) %08x, invalid size!\n"), bank->name, start << 16); + return 0; + } + map_banks_z2(bank, start, size >> 16); + return size; +} + +void map_banks_quick(addrbank* bank, int start, int size, int realsize) +{ + map_banks2(bank, start, size, realsize, 1); +#ifdef WITH_PPC + ppc_generate_map_banks(bank, start, size); +#endif +} +void map_banks_nojitdirect(addrbank* bank, int start, int size, int realsize) +{ + map_banks2(bank, start, size, realsize, -1); +#ifdef WITH_PPC + ppc_generate_map_banks(bank, start, size); +#endif } #ifdef SAVESTATE @@ -1801,6 +2986,12 @@ uae_u8 *save_bram (int *len) return bogomem_bank.baseaddr; } +static uae_u8* save_mem25bitram(int* len) +{ + *len = mem25bit_bank.allocated_size; + return mem25bit_bank.baseaddr; +} + uae_u8 *save_a3000lram(int *len) { *len = a3000lmem_bank.allocated_size; @@ -1842,61 +3033,61 @@ void restore_a3000hram (int len, size_t filepos) changed_prefs.mbresmem_high_size = len; } -uae_u8 *restore_rom (uae_u8 *src) +uae_u8* restore_rom(uae_u8* src) { uae_u32 crc32, mem_start, mem_size, mem_type, version; - TCHAR *s, *romn; + TCHAR* s, * romn; int i, crcdet; - struct romlist *rl = romlist_getit (); + struct romlist* rl = romlist_getit(); - mem_start = restore_u32 (); - mem_size = restore_u32 (); - mem_type = restore_u32 (); - version = restore_u32 (); - crc32 = restore_u32 (); - romn = restore_string (); + mem_start = restore_u32(); + mem_size = restore_u32(); + mem_type = restore_u32(); + version = restore_u32(); + crc32 = restore_u32(); + romn = restore_string(); crcdet = 0; - for (i = 0; i < romlist_count (); i++) { + for (i = 0; i < romlist_count(); i++) { if (rl[i].rd->crc32 == crc32 && crc32) { - if (zfile_exists (rl[i].path)) { + if (zfile_exists(rl[i].path)) { switch (mem_type) { case 0: - _tcsncpy (changed_prefs.romfile, rl[i].path, 255); + _tcsncpy(changed_prefs.romfile, rl[i].path, 255); break; case 1: - _tcsncpy (changed_prefs.romextfile, rl[i].path, 255); + _tcsncpy(changed_prefs.romextfile, rl[i].path, 255); break; } - write_log (_T("ROM '%s' = '%s'\n"), romn, rl[i].path); + write_log(_T("ROM '%s' = '%s'\n"), romn, rl[i].path); crcdet = 1; } else { - write_log (_T("ROM '%s' = '%s' invalid rom scanner path!"), romn, rl[i].path); + write_log(_T("ROM '%s' = '%s' invalid rom scanner path!"), romn, rl[i].path); } break; } } - s = restore_string (); + s = restore_string(); if (!crcdet) { - if (zfile_exists (s)) { + if (zfile_exists(s)) { switch (mem_type) { case 0: - _tcsncpy (changed_prefs.romfile, s, 255); + _tcsncpy(changed_prefs.romfile, s, 255); break; case 1: - _tcsncpy (changed_prefs.romextfile, s, 255); + _tcsncpy(changed_prefs.romextfile, s, 255); break; } - write_log (_T("ROM detected (path) as '%s'\n"), s); + write_log(_T("ROM detected (path) as '%s'\n"), s); crcdet = 1; } } - xfree (s); + xfree(s); if (!crcdet) - write_log (_T("WARNING: ROM '%s' %d.%d (CRC32=%08x %08x-%08x) not found!\n"), + write_log(_T("WARNING: ROM '%s' %d.%d (CRC32=%08x %08x-%08x) not found!\n"), romn, version >> 16, version & 0xffff, crc32, mem_start, mem_start + mem_size - 1); - xfree (romn); + xfree(romn); return src; } @@ -2002,15 +3193,33 @@ void memcpyah (uae_u8 *dst, uaecptr src, int size) while (size--) *dst++ = get_byte (src++); } -uaecptr strcpyha_safe(uaecptr dst, const uae_char *src) +uae_char* strcpyah_safe(uae_char* dst, uaecptr src, int maxsize) +{ + uae_char* res = dst; + uae_u8 b; + dst[0] = 0; + do { + if (!addr_valid(_T("_tcscpyah"), src, 1)) + return res; + b = get_byte(src++); + *dst++ = b; + *dst = 0; + maxsize--; + if (maxsize <= 1) + break; + } while (b); + return res; +} +uaecptr strcpyha_safe(uaecptr dst, const uae_char* src) { uaecptr res = dst; uae_u8 b; do { - if (!addr_valid (_T("_tcscpyha"), dst, 1)) + if (!addr_valid(_T("_tcscpyha"), dst, 1)) return res; b = *src++; - put_byte (dst++, b); + put_byte(dst++, b); } while (b); return res; } +