--- uae/src/memory.c 2018/04/24 17:16:43 1.1.1.16 +++ uae/src/memory.c 2018/04/24 17:18:31 1.1.1.17 @@ -12,6 +12,7 @@ #include "options.h" #include "uae.h" #include "memory.h" +#include "romlist.h" #include "ersatz.h" #include "zfile.h" #include "custom.h" @@ -20,14 +21,12 @@ #include "autoconf.h" #include "savestate.h" #include "crc32.h" +#include "gui.h" #ifdef USE_MAPPED_MEMORY #include #endif -/* Set by each memory handler that does not simply access real memory. */ -int special_mem; - int ersatzkickfile = 0; uae_u32 allocated_chipmem; @@ -35,226 +34,18 @@ uae_u32 allocated_fastmem; uae_u32 allocated_bogomem; uae_u32 allocated_gfxmem; uae_u32 allocated_z3fastmem; -uae_u32 allocated_a3000mem; - -static long chip_filepos; -static long bogo_filepos; -static long rom_filepos; - -/* ROM management. */ -struct romlist { - char *path; - struct romdata *rd; -}; - -static struct romlist *rl; -static int romlist_cnt; - -void romlist_add (char *path, struct romdata *rd) -{ - struct romlist *rl2; - - romlist_cnt++; - rl = realloc (rl, sizeof (struct romlist) * romlist_cnt); - rl2 = rl + romlist_cnt - 1; - rl2->path = my_strdup (path); - rl2->rd = rd; -} - -char *romlist_get (struct romdata *rd) -{ - int i; - - if (!rd) - return 0; - for (i = 0; i < romlist_cnt; i++) { - if (rl[i].rd == rd) - return rl[i].path; - } - return 0; -} - -void romlist_clear (void) -{ - free (rl); - rl = 0; - romlist_cnt = 0; -} - -static struct romdata roms[] = { - { "Cloanto Amiga Forever ROM key", 0, 0, 0x869ae1b1, 2069, 0, 0, 1, ROMTYPE_KEY }, - - { "Kickstart v1.0 (A1000)(NTSC)", 0, 0, 0x299790ff, 262144, 1, 0, 0, ROMTYPE_KICK }, - { "Kickstart v1.1 (A1000)(NTSC)", 31, 34, 0xd060572a, 262144, 2, 0, 0, ROMTYPE_KICK }, - { "Kickstart v1.1 (A1000)(PAL)", 31, 34, 0xec86dae2, 262144, 3, 0, 0, ROMTYPE_KICK }, - { "Kickstart v1.2 (A1000)", 33, 166, 0x9ed783d0, 262144, 4, 0, 0, ROMTYPE_KICK }, - { "Kickstart v1.2 (A500,A1000,A2000)", 33, 180, 0xa6ce1636, 262144, 5, 0, 0, ROMTYPE_KICK }, - { "Kickstart v1.3 (A500,A1000,A2000)", 34, 5, 0xc4f0f55f, 262144, 6, 60, 0, ROMTYPE_KICK }, - { "Kickstart v1.3 (A3000)", 34, 5, 0xe0f37258, 262144, 32, 0, 0, ROMTYPE_KICK }, - - { "Kickstart v2.04 (A500+)", 37, 175, 0xc3bdb240, 524288, 7, 0, 0, ROMTYPE_KICK }, - { "Kickstart v2.05 (A600)", 37, 299, 0x83028fb5, 524288, 8, 0, 0, ROMTYPE_KICK }, - { "Kickstart v2.05 (A600HD)", 37, 300, 0x64466c2a, 524288, 9, 0, 0, ROMTYPE_KICK }, - { "Kickstart v2.05 (A600HD)", 37, 350, 0x43b0df7b, 524288, 10, 0, 0, ROMTYPE_KICK }, - - { "Kickstart v3.0 (A1200)", 39, 106, 0x6c9b07d2, 524288, 11, 0, 0, ROMTYPE_KICK }, - { "Kickstart v3.0 (A4000)", 39, 106, 0x9e6ac152, 524288, 12, 2, 0, ROMTYPE_KICK }, - { "Kickstart v3.1 (A4000)", 40, 70, 0x2b4566f1, 524288, 13, 2, 0, ROMTYPE_KICK }, - { "Kickstart v3.1 (A500,A600,A2000)", 40, 63, 0xfc24ae0d, 524288, 14, 0, 0, ROMTYPE_KICK }, - { "Kickstart v3.1 (A1200)", 40, 68, 0x1483a091, 524288, 15, 1, 0, ROMTYPE_KICK }, - { "Kickstart v3.1 (A4000)(Cloanto)", 40, 68, 0x43b6dd22, 524288, 31, 2, 1, ROMTYPE_KICK }, - { "Kickstart v3.1 (A4000)", 40, 68, 0xd6bae334, 524288, 16, 2, 0, ROMTYPE_KICK }, - { "Kickstart v3.1 (A4000T)", 40, 70, 0x75932c3a, 524288, 17, 2, 0, ROMTYPE_KICK }, - - { "CD32 Kickstart v3.1", 40, 60, 0x1e62d4a5, 524288, 18, 1, 0, ROMTYPE_KICKCD32 }, - { "CD32 Extended", 40, 60, 0x87746be2, 524288, 19, 1, 0, ROMTYPE_EXTCD32 }, - - { "CDTV Extended v1.00", 0, 0, 0x42baa124, 262144, 20, 0, 0, ROMTYPE_EXTCDTV }, - { "CDTV Extended v2.30", 0, 0, 0x30b54232, 262144, 21, 0, 0, ROMTYPE_EXTCDTV }, - { "CDTV Extended v2.07", 0, 0, 0xceae68d2, 262144, 22, 0, 0, ROMTYPE_EXTCDTV }, - - { "A1000 Bootstrap", 0, 0, 0x62f11c04, 8192, 23, 0, 0, ROMTYPE_KICK }, - { "A1000 Bootstrap", 0, 0, 0x0b1ad2d0, 65536, 24, 0, 0, ROMTYPE_KICK }, - - { "Action Replay Mk I v1.50", 0, 0, 0xd4ce0675, 65536, 25, 0, 0, ROMTYPE_AR }, - { "Action Replay Mk II v2.05", 0, 0, 0x1287301f , 131072, 26, 0, 0, ROMTYPE_AR }, - { "Action Replay Mk II v2.12", 0, 0, 0x804d0361 , 131072, 27, 0, 0, ROMTYPE_AR }, - { "Action Replay Mk II v2.14", 0, 0, 0x49650e4f, 131072, 28, 0, 0, ROMTYPE_AR }, - { "Action Replay Mk III v3.09", 0, 0, 0x0ed9b5aa, 262144, 29, 0, 0, ROMTYPE_AR }, - { "Action Replay Mk III v3.17", 0, 0, 0xc8a16406, 262144, 30, 0, 0, ROMTYPE_AR }, - - { "SportTime Table Hockey\0ar_airh", 0, 0, 0, 0, 33, 0, 0, ROMTYPE_ARCADIA }, - { "SportTime Bowling\0ar_bowl", 0, 0, 0, 0, 34, 0, 0, ROMTYPE_ARCADIA }, - { "World Darts\0ar_dart", 0, 0, 0, 0, 35, 0, 0, ROMTYPE_ARCADIA }, - { "Magic Johnson's Fast Break\0ar_fast", 0, 0, 0, 0, 36, 0, 0, ROMTYPE_ARCADIA }, - { "Leader Board Golf\0ar_ldrb", 0, 0, 0, 0, 37, 0, 0, ROMTYPE_ARCADIA }, - { "Leader Board Golf (alt)\0ar_ldrba", 0, 0, 0, 0, 38, 0, 0, ROMTYPE_ARCADIA }, - { "Ninja Mission\0ar_ninj", 0, 0, 0, 0, 39, 0, 0, ROMTYPE_ARCADIA }, - { "Road Wars\0ar_rdwr", 0, 0, 0, 0, 40, 0, 0, ROMTYPE_ARCADIA }, - { "Sidewinder\0ar_sdwr", 0, 0, 0, 0, 41, 0, 0, ROMTYPE_ARCADIA }, - { "Cool Spot\0ar_spot", 0, 0, 0, 0, 42, 0, 0, ROMTYPE_ARCADIA }, - { "Space Ranger\0ar_sprg", 0, 0, 0, 0, 43, 0, 0, ROMTYPE_ARCADIA }, - { "Xenon\0ar_xeon", 0, 0, 0, 0, 44, 0, 0, ROMTYPE_ARCADIA }, - - { NULL, 0, 0, 0, 0, 0, 0, 0, 0 } -}; - -static void decode_cloanto_rom_do (uae_u8 *mem, int size, int real_size, uae_u8 *key, int keysize) -{ - long cnt, t; - for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize) { - mem[cnt] ^= key[t]; - if (real_size == cnt + 1) - t = keysize - 1; - } -} - -static int decode_cloanto_rom (uae_u8 *mem, int size, int real_size) -{ - FILE *keyf; - uae_u8 *p; - int keysize; - - if (strlen (currprefs.keyfile) == 0) { - write_log ("No filename given for ROM key file and ROM image is an encrypted \"Amiga Forever\" ROM file.\n"); - return 0; - } - keyf = zfile_open (currprefs.keyfile, "rb"); - if (keyf == 0) { - write_log ("Could not find specified ROM key-file.\n"); - return 0; - } - - p = (uae_u8 *) xmalloc (524288); - keysize = fread (p, 1, 524288, keyf); - decode_cloanto_rom_do (mem, size, real_size, p, keysize); - fclose (keyf); - free (p); - return 1; -} - -struct romdata *getromdatabyname (char *name) -{ - char tmp[1024]; - int i = 0; - while (roms[i].name) { - getromname (&roms[i], tmp); - if (!strcmp (tmp, name) || !strcmp (roms[i].name, name)) - return &roms[i]; - i++; - } - return 0; -} - -struct romdata *getromdatabyid (int id) -{ - int i = 0; - while (roms[i].name) { - if (id == roms[i].id) - return &roms[i]; - i++; - } - return 0; -} +uae_u32 allocated_a3000lmem; +uae_u32 allocated_a3000hmem; -struct romdata *getromdatabycrc (uae_u32 crc32) -{ - int i = 0; - while (roms[i].name) { - if (crc32 == roms[i].crc32) - return &roms[i]; - i++; - } - return 0; -} +static long chip_filepos, bogo_filepos, a3000lmem_filepos, a3000hmem_filepos; -struct romdata *getromdatabydata (uae_u8 *rom, int size) -{ - int i; - uae_u32 crc32a, crc32b, crc32c; - uae_u8 tmp[4]; - uae_u8 *tmpbuf = NULL; - - if (size > 11 && !memcmp (rom, "AMIROMTYPE1", 11)) { - uae_u8 *tmpbuf = xmalloc (size); - int tmpsize = size - 11; - memcpy (tmpbuf, rom + 11, tmpsize); - decode_cloanto_rom (tmpbuf, tmpsize, tmpsize); - rom = tmpbuf; - size = tmpsize; - } - crc32a = get_crc32 (rom, size); - crc32b = get_crc32 (rom, size / 2); - /* ignore AR IO-port range until we have full dump */ - memcpy (tmp, rom, 4); - memset (rom, 0, 4); - crc32c = get_crc32 (rom, size); - memcpy (rom, tmp, 4); - i = 0; - while (roms[i].name) { - if (roms[i].crc32) { - if (crc32a == roms[i].crc32 || crc32b == roms[i].crc32) - return &roms[i]; - if (crc32c == roms[i].crc32 && roms[i].type == ROMTYPE_AR) - return &roms[i]; - } - i++; - } - free (tmpbuf); - return 0; -} +/* Set if we notice during initialization that settings changed, + and we must clear all memory to prevent bogus contents from confusing + the Kickstart. */ +static int need_hardreset; -void getromname (struct romdata *rd, char *name) -{ - name[0] = 0; - if (rd->type == ROMTYPE_ARCADIA) - strcat (name, "Arcadia "); - strcat (name, rd->name); - if (rd->revision) - sprintf (name + strlen (name), " rev %d.%d", rd->version, rd->revision); - if (rd->size > 0) - sprintf (name + strlen (name), " (%dk)", (rd->size + 1023) / 1024); -} +/* The address space setting used during the last reset. */ +static int last_address_space_24; addrbank *mem_banks[65536]; @@ -293,7 +84,9 @@ __inline__ void byteput (uaecptr addr, u } #endif -uae_u32 chipmem_mask, kickmem_mask, extendedkickmem_mask, bogomem_mask, a3000mem_mask; +static uae_u32 chipmem_mask, chipmem_full_mask; +static uae_u32 kickmem_mask, extendedkickmem_mask, bogomem_mask; +static uae_u32 a3000lmem_mask, a3000hmem_mask; static int illegal_count; /* A dummy bank that only contains zeros */ @@ -308,7 +101,6 @@ static int dummy_check (uaecptr addr, ua uae_u32 REGPARAM2 dummy_lget (uaecptr addr) { - special_mem |= S_READ; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -321,7 +113,6 @@ uae_u32 REGPARAM2 dummy_lget (uaecptr ad uae_u32 REGPARAM2 dummy_wget (uaecptr addr) { - special_mem |= S_READ; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -334,7 +125,6 @@ uae_u32 REGPARAM2 dummy_wget (uaecptr ad uae_u32 REGPARAM2 dummy_bget (uaecptr addr) { - special_mem |= S_READ; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -347,7 +137,6 @@ uae_u32 REGPARAM2 dummy_bget (uaecptr ad void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l) { - special_mem |= S_WRITE; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -355,9 +144,9 @@ void REGPARAM2 dummy_lput (uaecptr addr, } } } + void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w) { - special_mem |= S_WRITE; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -365,9 +154,9 @@ void REGPARAM2 dummy_wput (uaecptr addr, } } } + void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b) { - special_mem |= S_WRITE; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -378,7 +167,6 @@ void REGPARAM2 dummy_bput (uaecptr addr, int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size) { - special_mem |= S_READ; if (currprefs.illegal_mem) { if (illegal_count < 20) { illegal_count++; @@ -389,74 +177,6 @@ int REGPARAM2 dummy_check (uaecptr addr, return 0; } -/* A3000 "motherboard resources" bank. */ -static uae_u32 mbres_lget (uaecptr) REGPARAM; -static uae_u32 mbres_wget (uaecptr) REGPARAM; -static uae_u32 mbres_bget (uaecptr) REGPARAM; -static void mbres_lput (uaecptr, uae_u32) REGPARAM; -static void mbres_wput (uaecptr, uae_u32) REGPARAM; -static void mbres_bput (uaecptr, uae_u32) REGPARAM; -static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM; - -static int mbres_val = 0; - -uae_u32 REGPARAM2 mbres_lget (uaecptr addr) -{ - special_mem |= S_READ; - if (currprefs.illegal_mem) - write_log ("Illegal lget at %08lx\n", addr); - - return 0; -} - -uae_u32 REGPARAM2 mbres_wget (uaecptr addr) -{ - special_mem |= S_READ; - if (currprefs.illegal_mem) - write_log ("Illegal wget at %08lx\n", addr); - - return 0; -} - -uae_u32 REGPARAM2 mbres_bget (uaecptr addr) -{ - special_mem |= S_READ; - if (currprefs.illegal_mem) - write_log ("Illegal bget at %08lx\n", addr); - - return (addr & 0xFFFF) == 3 ? mbres_val : 0; -} - -void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l) -{ - special_mem |= S_WRITE; - if (currprefs.illegal_mem) - write_log ("Illegal lput at %08lx\n", addr); -} -void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w) -{ - special_mem |= S_WRITE; - if (currprefs.illegal_mem) - write_log ("Illegal wput at %08lx\n", addr); -} -void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b) -{ - special_mem |= S_WRITE; - if (currprefs.illegal_mem) - write_log ("Illegal bput at %08lx\n", addr); - - if ((addr & 0xFFFF) == 3) - mbres_val = b; -} - -int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size) -{ - if (currprefs.illegal_mem) - write_log ("Illegal check at %08lx\n", addr); - - return 0; -} - /* Chip memory */ uae_u8 *chipmemory; @@ -518,6 +238,26 @@ void REGPARAM2 chipmem_bput (uaecptr add chipmemory[addr] = b; } +uae_u32 REGPARAM2 chipmem_agnus_wget (uaecptr addr) +{ + uae_u16 *m; + + addr &= chipmem_full_mask; + m = (uae_u16 *)(chipmemory + addr); + return do_get_mem_word (m); +} + +void REGPARAM2 chipmem_agnus_wput (uaecptr addr, uae_u32 w) +{ + uae_u16 *m; + + addr &= chipmem_full_mask; + if (addr >= allocated_chipmem) + return; + m = (uae_u16 *)(chipmemory + addr); + do_put_mem_word (m, w); +} + int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size) { addr -= chipmem_start & chipmem_mask; @@ -609,86 +349,143 @@ uae_u8 REGPARAM2 *bogomem_xlate (uaecptr return bogomemory + addr; } -/* A3000 motherboard fast memory */ +/* A3000 motherboard fastmemory. */ +static uae_u8 *a3000lmemory, *a3000hmemory; +uae_u32 a3000lmem_start, a3000hmem_start; + +static uae_u32 a3000lmem_lget (uaecptr) REGPARAM; +static uae_u32 a3000lmem_wget (uaecptr) REGPARAM; +static uae_u32 a3000lmem_bget (uaecptr) REGPARAM; +static void a3000lmem_lput (uaecptr, uae_u32) REGPARAM; +static void a3000lmem_wput (uaecptr, uae_u32) REGPARAM; +static void a3000lmem_bput (uaecptr, uae_u32) REGPARAM; +static int a3000lmem_check (uaecptr addr, uae_u32 size) REGPARAM; -static uae_u8 *a3000memory; +static uae_u32 REGPARAM2 a3000lmem_lget (uaecptr addr) +{ + uae_u32 *m; + addr &= a3000lmem_mask; + m = (uae_u32 *)(a3000lmemory + addr); + return do_get_mem_long (m); +} + +static uae_u32 REGPARAM2 a3000lmem_wget (uaecptr addr) +{ + uae_u16 *m; + addr &= a3000lmem_mask; + m = (uae_u16 *)(a3000lmemory + addr); + return do_get_mem_word (m); +} -static uae_u32 a3000mem_lget (uaecptr) REGPARAM; -static uae_u32 a3000mem_wget (uaecptr) REGPARAM; -static uae_u32 a3000mem_bget (uaecptr) REGPARAM; -static void a3000mem_lput (uaecptr, uae_u32) REGPARAM; -static void a3000mem_wput (uaecptr, uae_u32) REGPARAM; -static void a3000mem_bput (uaecptr, uae_u32) REGPARAM; -static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM; -static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM; +static uae_u32 REGPARAM2 a3000lmem_bget (uaecptr addr) +{ + addr &= a3000lmem_mask; + return a3000lmemory[addr]; +} -uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr) +static void REGPARAM2 a3000lmem_lput (uaecptr addr, uae_u32 l) { uae_u32 *m; - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - m = (uae_u32 *)(a3000memory + addr); + addr &= a3000lmem_mask; + m = (uae_u32 *)(a3000lmemory + addr); + do_put_mem_long (m, l); +} + +static void REGPARAM2 a3000lmem_wput (uaecptr addr, uae_u32 w) +{ + uae_u16 *m; + addr &= a3000lmem_mask; + m = (uae_u16 *)(a3000lmemory + addr); + do_put_mem_word (m, w); +} + +static void REGPARAM2 a3000lmem_bput (uaecptr addr, uae_u32 b) +{ + addr &= a3000lmem_mask; + a3000lmemory[addr] = b; +} + +static int REGPARAM2 a3000lmem_check (uaecptr addr, uae_u32 size) +{ + addr &= a3000lmem_mask; + return (addr + size) <= allocated_a3000lmem; +} + +static uae_u8 *REGPARAM2 a3000lmem_xlate (uaecptr addr) +{ + addr &= a3000lmem_mask; + return a3000lmemory + addr; +} + +static uae_u32 a3000hmem_lget (uaecptr) REGPARAM; +static uae_u32 a3000hmem_wget (uaecptr) REGPARAM; +static uae_u32 a3000hmem_bget (uaecptr) REGPARAM; +static void a3000hmem_lput (uaecptr, uae_u32) REGPARAM; +static void a3000hmem_wput (uaecptr, uae_u32) REGPARAM; +static void a3000hmem_bput (uaecptr, uae_u32) REGPARAM; +static int a3000hmem_check (uaecptr addr, uae_u32 size) REGPARAM; +static uae_u8 *a3000hmem_xlate (uaecptr addr) REGPARAM; + +static uae_u32 REGPARAM2 a3000hmem_lget (uaecptr addr) +{ + uae_u32 *m; + addr &= a3000hmem_mask; + m = (uae_u32 *)(a3000hmemory + addr); return do_get_mem_long (m); } -uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr) +static uae_u32 REGPARAM2 a3000hmem_wget (uaecptr addr) { uae_u16 *m; - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - m = (uae_u16 *)(a3000memory + addr); + addr &= a3000hmem_mask; + m = (uae_u16 *)(a3000hmemory + addr); return do_get_mem_word (m); } -uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr) +static uae_u32 REGPARAM2 a3000hmem_bget (uaecptr addr) { - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - return a3000memory[addr]; + addr &= a3000hmem_mask; + return a3000hmemory[addr]; } -void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l) +static void REGPARAM2 a3000hmem_lput (uaecptr addr, uae_u32 l) { uae_u32 *m; - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - m = (uae_u32 *)(a3000memory + addr); + addr &= a3000hmem_mask; + m = (uae_u32 *)(a3000hmemory + addr); do_put_mem_long (m, l); } -void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w) +static void REGPARAM2 a3000hmem_wput (uaecptr addr, uae_u32 w) { uae_u16 *m; - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - m = (uae_u16 *)(a3000memory + addr); + addr &= a3000hmem_mask; + m = (uae_u16 *)(a3000hmemory + addr); do_put_mem_word (m, w); } -void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b) +static void REGPARAM2 a3000hmem_bput (uaecptr addr, uae_u32 b) { - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - a3000memory[addr] = b; + addr &= a3000hmem_mask; + a3000hmemory[addr] = b; } -int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size) +static int REGPARAM2 a3000hmem_check (uaecptr addr, uae_u32 size) { - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - return (addr + size) <= allocated_a3000mem; + addr &= a3000hmem_mask; + return (addr + size) <= allocated_a3000hmem; } -uae_u8 REGPARAM2 *a3000mem_xlate (uaecptr addr) +static uae_u8 *REGPARAM2 a3000hmem_xlate (uaecptr addr) { - addr -= a3000mem_start & a3000mem_mask; - addr &= a3000mem_mask; - return a3000memory + addr; + addr &= a3000hmem_mask; + return a3000hmemory + addr; } /* Kick memory */ uae_u8 *kickmemory; +uae_u16 kickstart_version; /* * A1000 kickstart RAM handling @@ -701,17 +498,24 @@ static int a1000_kickstart_mode; static uae_u8 *a1000_bootrom; static void a1000_handle_kickstart (int mode) { + if (!a1000_bootrom) + return; if (mode == 0) { a1000_kickstart_mode = 0; memcpy (kickmemory, kickmemory + 262144, 262144); + kickstart_version = (kickmemory[262144 + 12] << 8) | kickmemory[262144 + 13]; } else { a1000_kickstart_mode = 1; - memset (kickmemory, 0, 262144); - memcpy (kickmemory, a1000_bootrom, 8192); - memcpy (kickmemory + 131072, a1000_bootrom, 8192); + memcpy (kickmemory, a1000_bootrom, 262144); + kickstart_version = 0; } } +void a1000_reset (void) +{ + a1000_handle_kickstart (1); +} + static uae_u32 kickmem_lget (uaecptr) REGPARAM; static uae_u32 kickmem_wget (uaecptr) REGPARAM; static uae_u32 kickmem_bget (uaecptr) REGPARAM; @@ -835,7 +639,7 @@ static void extendedkickmem_bput (uaecpt static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM; static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM; -uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr) +static uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr) { uae_u32 *m; addr -= extendedkickmem_start & extendedkickmem_mask; @@ -844,7 +648,7 @@ uae_u32 REGPARAM2 extendedkickmem_lget ( return do_get_mem_long (m); } -uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr) +static uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr) { uae_u16 *m; addr -= extendedkickmem_start & extendedkickmem_mask; @@ -853,39 +657,39 @@ uae_u32 REGPARAM2 extendedkickmem_wget ( return do_get_mem_word (m); } -uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr) +static uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr) { addr -= extendedkickmem_start & extendedkickmem_mask; addr &= extendedkickmem_mask; return extendedkickmemory[addr]; } -void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b) { if (currprefs.illegal_mem) write_log ("Illegal extendedkickmem lput at %08lx\n", addr); } -void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b) { if (currprefs.illegal_mem) write_log ("Illegal extendedkickmem wput at %08lx\n", addr); } -void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b) +static void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b) { if (currprefs.illegal_mem) write_log ("Illegal extendedkickmem lput at %08lx\n", addr); } -int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size) +static int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size) { addr -= extendedkickmem_start & extendedkickmem_mask; addr &= extendedkickmem_mask; return (addr + size) <= extendedkickmem_size; } -uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr) +static uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr) { addr -= extendedkickmem_start & extendedkickmem_mask; addr &= extendedkickmem_mask; @@ -903,7 +707,11 @@ uae_u8 REGPARAM2 *default_xlate (uaecptr { write_log ("Your Amiga program just did something terribly stupid\n"); uae_reset (1); - return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */ + + set_special (SPCFLAG_RESTORE_SANITY); + /* rtarea_bank has an infinite loop in m68k space, which we use to avoid a + * crash. */ + return rtarea_bank.xlateaddr (0xF0FFC0); } /* Address banks */ @@ -911,43 +719,43 @@ uae_u8 REGPARAM2 *default_xlate (uaecptr addrbank dummy_bank = { dummy_lget, dummy_wget, dummy_bget, dummy_lput, dummy_wput, dummy_bput, - default_xlate, dummy_check, NULL -}; - -addrbank mbres_bank = { - mbres_lget, mbres_wget, mbres_bget, - mbres_lput, mbres_wput, mbres_bput, - default_xlate, mbres_check, NULL + default_xlate, dummy_check, NULL, NULL }; addrbank chipmem_bank = { chipmem_lget, chipmem_wget, chipmem_bget, chipmem_lput, chipmem_wput, chipmem_bput, - chipmem_xlate, chipmem_check, NULL + chipmem_xlate, chipmem_check, NULL, "Chip memory" }; addrbank bogomem_bank = { bogomem_lget, bogomem_wget, bogomem_bget, bogomem_lput, bogomem_wput, bogomem_bput, - bogomem_xlate, bogomem_check, NULL + bogomem_xlate, bogomem_check, NULL, "Slow memory" }; -addrbank a3000mem_bank = { - a3000mem_lget, a3000mem_wget, a3000mem_bget, - a3000mem_lput, a3000mem_wput, a3000mem_bput, - a3000mem_xlate, a3000mem_check, NULL +addrbank a3000lmem_bank = { + a3000lmem_lget, a3000lmem_wget, a3000lmem_bget, + a3000lmem_lput, a3000lmem_wput, a3000lmem_bput, + a3000lmem_xlate, a3000lmem_check, NULL, "RAMSEY memory (low)" +}; + +addrbank a3000hmem_bank = { + a3000hmem_lget, a3000hmem_wget, a3000hmem_bget, + a3000hmem_lput, a3000hmem_wput, a3000hmem_bput, + a3000hmem_xlate, a3000hmem_check, NULL, "RAMSEY memory (high)" }; addrbank kickmem_bank = { kickmem_lget, kickmem_wget, kickmem_bget, kickmem_lput, kickmem_wput, kickmem_bput, - kickmem_xlate, kickmem_check, NULL + kickmem_xlate, kickmem_check, NULL, "Kickstart ROM" }; addrbank extendedkickmem_bank = { extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget, extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput, - extendedkickmem_xlate, extendedkickmem_check, NULL + extendedkickmem_xlate, extendedkickmem_check, NULL, "Extended Kickstart ROM" }; static int kickstart_checksum (uae_u8 *mem, int size) @@ -967,46 +775,69 @@ static int kickstart_checksum (uae_u8 *m return 0; } -static int read_kickstart (FILE *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom) +static const char kickstring[] = "exec.library"; + +static int read_kickstart (struct zfile *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom) { unsigned char buffer[20]; - int i, cr = 0; + int i, j, cr = 0; if (cloanto_rom) *cloanto_rom = 0; - i = fread (buffer, 1, 11, f); + i = zfile_fread (buffer, 1, 11, f); if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) { - fseek (f, 0, SEEK_SET); + zfile_fseek (f, 0, SEEK_SET); } else { cr = 1; } - i = fread (mem, 1, size, f); - if (i == 8192) { - a1000_bootrom = malloc (8192); - memcpy (a1000_bootrom, kickmemory, 8192); - a1000_handle_kickstart (1); - } else if (i == size / 2) { - memcpy (mem + size / 2, mem, i); - } else if (i != size) { - write_log ("Error while reading Kickstart.\n"); - zfile_close (f); + if (cloanto_rom) + *cloanto_rom = cr; + + i = zfile_fread (mem, 1, size, f); + + if (i != 8192 && i != 65536 && i != 131072 && i != 262144 && i != 524288 && i != 524288 * 2 && i != 524288 * 4) { + gui_message ("Error while reading Kickstart ROM file."); return 0; } - zfile_close (f); + if (i == size / 2) + memcpy (mem + size / 2, mem, size / 2); + + if (cr) { + if (!decode_cloanto_rom (mem, size, i, 0)) + return 0; + } + if (currprefs.cs_a1000ram) { + int off = 0; + a1000_bootrom = xcalloc (262144, 1); + while (off + i < 262144) { + memcpy (a1000_bootrom + off, kickmemory, i); + off += i; + } + memset (kickmemory, 0, kickmem_size); + a1000_handle_kickstart (1); + dochecksum = 0; + i = 524288; + } + + zfile_fclose (f); + + for (j = 0; j < 256 && i >= 262144; j++) { + if (!memcmp (mem + j, kickstring, strlen (kickstring) + 1)) + break; + } - if (cr) - decode_cloanto_rom (mem, size, i); - if (dochecksum && i >= 262144) + if (j == 256 || i < 262144) + dochecksum = 0; + if (dochecksum) kickstart_checksum (mem, size); - if (cloanto_rom) - *cloanto_rom = cr; + return 1; } static int load_extendedkickstart (void) { - FILE *f; + struct zfile *f; int size; if (strlen (currprefs.romextfile) == 0) @@ -1017,13 +848,13 @@ static int load_extendedkickstart (void) return 0; } - fseek (f, 0, SEEK_END); - size = ftell (f); + zfile_fseek (f, 0, SEEK_END); + size = zfile_ftell (f); if (size > 300000) extendedkickmem_size = 524288; else extendedkickmem_size = 262144; - fseek (f, 0, SEEK_SET); + zfile_fseek (f, 0, SEEK_SET); switch (extromtype ()) { case EXTENDED_ROM_CDTV: @@ -1036,17 +867,126 @@ static int load_extendedkickstart (void) break; } read_kickstart (f, extendedkickmemory, 524288, 0, 0); - fclose (f); return 1; } +static void kickstart_fix_checksum (uae_u8 *mem, int size) +{ + uae_u32 cksum = 0, prevck = 0; + int i, ch = size == 524288 ? 0x7ffe8 : 0x3e; + + mem[ch] = 0; + mem[ch + 1] = 0; + mem[ch + 2] = 0; + mem[ch + 3] = 0; + for (i = 0; i < size; i+=4) { + uae_u32 data = (mem[i] << 24) | (mem[i + 1] << 16) | (mem[i + 2] << 8) | mem[i + 3]; + cksum += data; + if (cksum < prevck) + cksum++; + prevck = cksum; + } + cksum ^= 0xffffffff; + mem[ch++] = cksum >> 24; + mem[ch++] = cksum >> 16; + mem[ch++] = cksum >> 8; + mem[ch++] = cksum >> 0; +} + +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 compatability. + */ + 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 ("Kickstart KickShifted @%04.4X\n", i); + patched++; + } + } + return patched; +} + +/* disable incompatible drivers */ +static int patch_residents (uae_u8 *kickmemory, int size) +{ + int i, j, patched = 0; + char *residents[] = { + "NCR scsi.device", + "scsi.device", "carddisk.device", "card.resource", + NULL + }; + uaecptr base = size == 524288 ? 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)) { + write_log ("KSPatcher: '%s' at %08.8X disabled\n", residents[j], i + base); + kickmemory[i] = 0x4b; /* destroy RTC_MATCHWORD */ + patched++; + break; + } + j++; + } + } + } + } + return patched; +} + +static void patch_kick(void) +{ + int patched = 0; + if (kickmem_size >= 524288 && currprefs.kickshifter) + patched += patch_shapeshifter (kickmemory); + patched += patch_residents (kickmemory, kickmem_size); + if (extendedkickmemory) { + patched += patch_residents (extendedkickmemory, extendedkickmem_size); + if (patched) + kickstart_fix_checksum (extendedkickmemory, extendedkickmem_size); + } + if (patched) + kickstart_fix_checksum (kickmemory, kickmem_size); +} + static int load_kickstart (void) { - FILE *f = zfile_open (currprefs.romfile, "rb"); + struct zfile *f = NULL; + int i; + + if (currprefs.rom_crc32) { + for (i = 0;; i++) { + struct romlist *rl = romlist_from_idx (i, ROMTYPE_KICK, 1); + if (!rl) + break; + if (rl->rd->crc32 == currprefs.rom_crc32) { + f = zfile_open (rl->path, "rb"); + break; + } + } + } else + f = zfile_open (currprefs.romfile, "rb"); if (f == NULL) { -#if defined(AMIGA)||defined(__POS__) +#if defined (AMIGA) #define USE_UAE_ERSATZ "USE_UAE_ERSATZ" if (!getenv (USE_UAE_ERSATZ)) { write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ); @@ -1061,30 +1001,11 @@ static int load_kickstart (void) if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom)) return 0; -#if defined(AMIGA) +#if defined (AMIGA) chk_sum: #endif + kickstart_version = (kickmemory[12] << 8) | kickmemory[13]; - if (currprefs.kickshifter) { - /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer. - Changes 'lea $400,a0' to 'lea $2000,a0' for ShapeShifter compatability. - NOTE: lea is 0x41f8, so we should do this better with a search for - 0x41f80400 --> 0x41f82000 - */ - if (kickmemory[0x24a] == 0x04 && kickmemory[0x24b] == 0x00) { /* Kick 3.0 */ - kickmemory[0x24a] = 0x20; - kickmemory[0x7ffea] -= 0x1c; - write_log ("Kickstart KickShifted\n"); - } else if (kickmemory[0x26e] == 0x04 && kickmemory[0x26f] == 0x00) { /* Kick 3.1 */ - kickmemory[0x26e] = 0x20; - kickmemory[0x7ffea] -= 0x1c; - write_log ("Kickstart KickShifted\n"); - } else if (kickmemory[0x24e] == 0x04 && kickmemory[0x24f] == 0x00) { /* Kick 2.04 */ - kickmemory[0x24e] = 0x20; - kickmemory[0x7ffea] -= 0x1c; - write_log ("Kickstart KickShifted\n"); - } - } return 1; } @@ -1155,7 +1076,7 @@ static void delete_shmmaps (uae_u32 star return; if (x->size > size) { - printf ("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n", start, x->size, size); + printf ("NATMEM: Failure to delete mapping at %08x (size %08x, delsize %08x)\n", start, x->size, size); dumplist (); canbang = 0; return; @@ -1196,7 +1117,7 @@ static void add_shmmaps (uae_u32 start, base = ((uae_u8 *) NATMEM_OFFSET) + start; y->native_address = shmat (y->id, base, 0); if (y->native_address == (void *) -1) { - printf ("NATMEM: Failure to map existing at %08x(%p)\n", start, base); + printf ("NATMEM: Failure to map existing at %08x (%p)\n", start, base); perror ("shmat"); dumplist (); canbang = 0; @@ -1262,21 +1183,31 @@ static void init_mem_banks (void) static void allocate_memory (void) { if (allocated_chipmem != currprefs.chipmem_size) { + int memsize; if (chipmemory) mapped_free (chipmemory); chipmemory = 0; - allocated_chipmem = currprefs.chipmem_size; + memsize = allocated_chipmem = currprefs.chipmem_size; chipmem_mask = allocated_chipmem - 1; - chipmemory = mapped_malloc (allocated_chipmem, "chip"); + if (memsize < 0x100000) + memsize = 0x100000; + chipmemory = mapped_malloc (memsize, "chip"); if (chipmemory == 0) { write_log ("Fatal error: out of memory for chipmem.\n"); allocated_chipmem = 0; - } else - do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0); + } else { + need_hardreset = 1; + if (memsize != allocated_chipmem) + memset (chipmemory + allocated_chipmem, 0xff, memsize - allocated_chipmem); + } } + chipmem_full_mask = allocated_chipmem - 1; + if ((currprefs.chipset_mask & CSMASK_ECS_AGNUS) && allocated_chipmem < 0x100000) + chipmem_full_mask = 0x100000 - 1; + if (allocated_bogomem != currprefs.bogomem_size) { if (bogomemory) mapped_free (bogomemory); @@ -1292,39 +1223,78 @@ static void allocate_memory (void) allocated_bogomem = 0; } } + need_hardreset = 1; } - if (allocated_a3000mem != currprefs.a3000mem_size) { - if (a3000memory) - mapped_free (a3000memory); - a3000memory = 0; - - allocated_a3000mem = currprefs.a3000mem_size; - a3000mem_mask = allocated_a3000mem - 1; - - if (allocated_a3000mem) { - a3000memory = mapped_malloc (allocated_a3000mem, "a3000"); - if (a3000memory == 0) { - write_log ("Out of memory for a3000mem.\n"); - allocated_a3000mem = 0; + + if (allocated_a3000lmem != currprefs.mbresmem_low_size) { + if (a3000lmemory) + mapped_free (a3000lmemory); + a3000lmemory = 0; + + allocated_a3000lmem = currprefs.mbresmem_low_size; + a3000lmem_mask = allocated_a3000lmem - 1; + a3000lmem_start = 0x08000000 - allocated_a3000lmem; + if (allocated_a3000lmem) { + a3000lmemory = mapped_malloc (allocated_a3000lmem, "ramsey_low"); + if (a3000lmemory == 0) { + write_log ("Out of memory for a3000lowmem.\n"); + allocated_a3000lmem = 0; + } + } + need_hardreset = 1; + } + + if (allocated_a3000hmem != currprefs.mbresmem_high_size) { + if (a3000hmemory) + mapped_free (a3000hmemory); + a3000hmemory = 0; + + allocated_a3000hmem = currprefs.mbresmem_high_size; + a3000hmem_mask = allocated_a3000hmem - 1; + a3000hmem_start = 0x08000000; + if (allocated_a3000hmem) { + a3000hmemory = mapped_malloc (allocated_a3000hmem, "ramsey_high"); + if (a3000hmemory == 0) { + write_log ("Out of memory for a3000highmem.\n"); + allocated_a3000hmem = 0; } } + need_hardreset = 1; } if (savestate_state == STATE_RESTORE) { - fseek (savestate_file, chip_filepos, SEEK_SET); - fread (chipmemory, 1, allocated_chipmem, savestate_file); + restore_ram (chip_filepos, chipmemory); if (allocated_bogomem > 0) { - fseek (savestate_file, bogo_filepos, SEEK_SET); - fread (bogomemory, 1, allocated_bogomem, savestate_file); + restore_ram (bogo_filepos, bogomemory); } + if (allocated_a3000lmem > 0) + restore_ram (a3000lmem_filepos, a3000lmemory); + if (allocated_a3000hmem > 0) + restore_ram (a3000hmem_filepos, a3000hmemory); } chipmem_bank.baseaddr = chipmemory; bogomem_bank.baseaddr = bogomemory; + a3000lmem_bank.baseaddr = a3000lmemory; + a3000hmem_bank.baseaddr = a3000hmemory; +} + +void map_overlay (int chip) +{ + int i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32; + addrbank *cb; + + cb = &chipmem_bank; + if (chip) + map_banks (cb, 0, i, allocated_chipmem); + else + map_banks (&kickmem_bank, 0, i, 0x80000); + if (savestate_state != STATE_RESTORE) + m68k_setpc (m68k_getpc ()); } void memory_reset (void) { - int i, custom_start; + int bnk, bnk_end; #ifdef NATMEM_OFFSET delete_shmmaps (0, 0xFFFF0000); @@ -1333,55 +1303,105 @@ void memory_reset (void) currprefs.chipmem_size = changed_prefs.chipmem_size; currprefs.bogomem_size = changed_prefs.bogomem_size; - currprefs.a3000mem_size = changed_prefs.a3000mem_size; + currprefs.mbresmem_low_size = changed_prefs.mbresmem_low_size; + currprefs.mbresmem_high_size = changed_prefs.mbresmem_high_size; + currprefs.chipset_mask = changed_prefs.chipset_mask; + currprefs.cs_a1000ram = changed_prefs.cs_a1000ram; + currprefs.cs_fatgaryrev = changed_prefs.cs_fatgaryrev; + currprefs.cs_ramseyrev = changed_prefs.cs_ramseyrev; + currprefs.cs_ide = changed_prefs.cs_ide; + currprefs.bootrom = changed_prefs.bootrom; + + need_hardreset = 0; + /* Use changed_prefs, as m68k_reset is called later. */ + if (last_address_space_24 != changed_prefs.address_space_24) + need_hardreset = 1; + last_address_space_24 = changed_prefs.address_space_24; allocate_memory (); - if (strcmp (currprefs.romfile, changed_prefs.romfile) != 0 || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0) { + if (currprefs.rom_crc32 != changed_prefs.rom_crc32 + || strcmp (currprefs.romfile, changed_prefs.romfile) != 0 + || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0) + { ersatzkickfile = 0; + a1000_handle_kickstart (0); + free (a1000_bootrom); + a1000_bootrom = 0; + a1000_kickstart_mode = 0; + + currprefs.rom_crc32 = changed_prefs.rom_crc32; memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile); memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile); - /* Clear out whatever data remains across a reset. */ - memset (chipmemory, 0, allocated_chipmem); + need_hardreset = 1; if (!load_kickstart ()) { init_ersatz_rom (kickmemory); ersatzkickfile = 1; } + patch_kick (); } - /* Map the chipmem into all of the lower 8MB */ - i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32; - map_banks (&chipmem_bank, 0x00, i, allocated_chipmem); - - custom_start = 0xC0; - map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0); + map_banks (&custom_bank, 0xC0, 0xE0 - 0xC0, 0); map_banks (&cia_bank, 0xA0, 32, 0); - map_banks (&clock_bank, 0xDC, 1, 0); - - /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000 - * range on an Amiga without expansion memory? */ - custom_start = allocated_chipmem >> 16; - if (custom_start < 0x20) - custom_start = 0x20; - map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0); - /*map_banks (&mbres_bank, 0xDE, 1); */ + if (!currprefs.cs_a1000ram) + /* D80000 - DDFFFF not mapped (A1000 = custom chips) */ + map_banks (&dummy_bank, 0xD8, 6, 0); + + /* map "nothing" to 0x200000 - 0x9FFFFF (0xBEFFFF if PCMCIA or AGA) */ + bnk = allocated_chipmem >> 16; + if (bnk < 0x20) + bnk = 0x20; + bnk_end = (currprefs.chipset_mask & CSMASK_AGA) ? 0xBF : 0xA0; + map_banks (&dummy_bank, bnk, bnk_end - bnk, 0); + if (currprefs.chipset_mask & CSMASK_AGA) + map_banks (&dummy_bank, 0xc0, 0xd8 - 0xc0, 0); if (bogomemory != 0) { int t = allocated_bogomem >> 16; if (t > 0x1C) t = 0x1C; + if (t > 0x10 && ((currprefs.chipset_mask & CSMASK_AGA) || currprefs.cpu_model >= 68020)) + t = 0x10; map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem); } - if (a3000memory != 0) - map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16, allocated_a3000mem); - - map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0); + if (currprefs.cs_ide) { + if (currprefs.cs_ide == 1) { + map_banks (&gayle_bank, 0xD8, 6, 0); + map_banks (&gayle2_bank, 0xDD, 2, 0); + // map_banks (&gayle_attr_bank, 0xA0, 8, 0); only if PCMCIA card inserted */ + } + if (currprefs.cs_ide == 2) { + map_banks (&gayle_bank, 0xDD, 1, 0); + } + if (currprefs.cs_ide < 0) { + map_banks (&gayle_bank, 0xD8, 6, 0); + map_banks (&gayle_bank, 0xDD, 1, 0); + } + } + if (currprefs.cs_rtc) + map_banks (&clock_bank, 0xDC, 1, 0); + if (currprefs.cs_fatgaryrev >= 0 || currprefs.cs_ramseyrev >= 0) + map_banks (&mbres_bank, 0xDE, 1, 0); + + if (a3000lmemory != 0) + map_banks (&a3000lmem_bank, a3000lmem_start >> 16, allocated_a3000lmem >> 16, 0); + if (a3000hmemory != 0) + map_banks (&a3000hmem_bank, a3000hmem_start >> 16, allocated_a3000hmem >> 16, 0); + + if (currprefs.bootrom) { + uae_boot_rom = 1; + map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0); + } else + uae_boot_rom = 0; map_banks (&kickmem_bank, 0xF8, 8, 0); - if (a1000_bootrom) - a1000_handle_kickstart (1); + + a1000_reset (); map_banks (&expamem_bank, 0xE8, 1, 0); + /* Map the chipmem into all of the lower 8MB */ + map_overlay (1); + switch (extromtype ()) { case EXTENDED_ROM_CDTV: map_banks (&extendedkickmem_bank, 0xF0, 4, 0); @@ -1393,17 +1413,20 @@ void memory_reset (void) if (cloanto_rom) map_banks (&kickmem_bank, 0xE0, 8, 0); } + + if (need_hardreset) + memory_hardreset (); } void memory_init (void) { allocated_chipmem = 0; allocated_bogomem = 0; - allocated_a3000mem = 0; kickmemory = 0; extendedkickmemory = 0; chipmemory = 0; - a3000memory = 0; + allocated_a3000lmem = allocated_a3000hmem = 0; + a3000lmemory = a3000hmemory = 0; bogomemory = 0; kickmemory = mapped_malloc (kickmem_size, "kick"); @@ -1424,8 +1447,10 @@ void memory_init (void) void memory_cleanup (void) { - if (a3000memory) - mapped_free (a3000memory); + if (a3000lmemory) + mapped_free (a3000lmemory); + if (a3000hmemory) + mapped_free (a3000hmemory); if (bogomemory) mapped_free (bogomemory); if (kickmemory) @@ -1435,13 +1460,28 @@ void memory_cleanup (void) if (chipmemory) mapped_free (chipmemory); - a3000memory = 0; + a3000lmemory = a3000hmemory = 0; bogomemory = 0; kickmemory = 0; a1000_bootrom = 0; chipmemory = 0; } +void memory_hardreset (void) +{ + if (savestate_state == STATE_RESTORE) + return; + if (chipmemory) + memset (chipmemory, 0, allocated_chipmem); + if (bogomemory) + memset (bogomemory, 0, allocated_bogomem); + if (a3000lmemory) + memset (a3000lmemory, 0, allocated_a3000lmem); + if (a3000hmemory) + memset (a3000hmemory, 0, allocated_a3000hmem); + expansion_clear (); +} + void map_banks (addrbank *bank, int start, int size, int realsize) { int bnr; @@ -1480,7 +1520,8 @@ void map_banks (addrbank *bank, int star } return; } - if (currprefs.address_space_24) + /* Already in currprefs, since we get called after m68k_reset. */ + if (last_address_space_24) endhioffs = 0x10000; for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) { int real_left = 0; @@ -1513,6 +1554,18 @@ uae_u8 *save_bram (int *len) return bogomemory; } +uae_u8 *save_a3000lram (int *len) +{ + *len = allocated_a3000lmem; + return a3000lmemory; +} + +uae_u8 *save_a3000hram (int *len) +{ + *len = allocated_a3000hmem; + return a3000hmemory; +} + void restore_cram (int len, long filepos) { chip_filepos = filepos; @@ -1525,9 +1578,23 @@ void restore_bram (int len, long filepos changed_prefs.bogomem_size = len; } +void restore_a3000lram (int len, size_t filepos) +{ + a3000lmem_filepos = filepos; + changed_prefs.mbresmem_low_size = len; +} + +void restore_a3000hram (int len, size_t filepos) +{ + a3000hmem_filepos = filepos; + changed_prefs.mbresmem_high_size = len; +} + const uae_u8 *restore_rom (const uae_u8 *src) { + struct romdata *rom; uae_u32 crc32; + char *romname; int i; restore_u32 (); @@ -1536,12 +1603,9 @@ const uae_u8 *restore_rom (const uae_u8 restore_u32 (); crc32 = restore_u32 (); - for (i = 0; i < romlist_cnt; i++) { - if (rl[i].rd->crc32 == crc32 && crc32) { - strncpy (changed_prefs.romfile, rl[i].path, 255); - break; - } - } + rom = getromdatabycrc (crc32); + if (rom) + changed_prefs.rom_crc32 = crc32; return src; } @@ -1599,3 +1663,94 @@ uae_u8 *save_rom (int first, int *len, u *len = dst - dstbak; return dstbak; } + +/* memory helpers */ + +static int addr_valid (char *txt, uaecptr addr, uae_u32 len) +{ + addrbank *ab = &get_mem_bank (addr); + if (ab == 0 || addr < 0x100 + || len < 0 || len > 16777215 || !valid_address (addr, len)) { + write_log ("corrupt %s pointer %x (%d) detected!\n", txt, addr, len); + return 0; + } + return 1; +} + +void memcpyha_safe (uaecptr dst, const uae_u8 *src, int size) +{ + if (!addr_valid ("memcpyha", dst, size)) + return; + while (size--) + put_byte (dst++, *src++); +} + +void memcpyha (uaecptr dst, const uae_u8 *src, int size) +{ + while (size--) + put_byte (dst++, *src++); +} + +void memcpyah_safe (uae_u8 *dst, uaecptr src, int size) +{ + if (!addr_valid ("memcpyah", src, size)) + return; + while (size--) + *dst++ = get_byte (src++); +} + +void memcpyah (uae_u8 *dst, uaecptr src, int size) +{ + while (size--) + *dst++ = get_byte (src++); +} + +char *strcpyah_safe (char *dst, uaecptr src) +{ + char *res = dst; + uae_u8 b; + do { + if (!addr_valid ("strcpyah", src, 1)) + return res; + b = get_byte (src++); + *dst++ = b; + } while (b); + return res; +} + +uaecptr strcpyha_safe (uaecptr dst, const char *src) +{ + uaecptr res = dst; + uae_u8 b; + do { + if (!addr_valid ("strcpyha", dst, 1)) + return res; + b = *src++; + put_byte (dst++, b); + } while (b); + return res; +} + +uae_u32 strncpyha (uae_u32 dst, const char *src, int size) +{ + uae_u32 res = dst; + while (size--) { + put_byte (dst++, *src); + if (!*src++) + return res; + } + return res; +} + +uae_u32 strncpyha_safe (uae_u32 dst, const char *src, int size) +{ + uae_u32 res = dst; + while (size--) { + if (!addr_valid ("strcpyha", dst, 1)) + return res; + put_byte (dst++, *src); + if (!*src++) + return res; + } + return res; +}