Annotation of uae/src/memory.c, revision 1.1.1.14

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Memory management
                      5:   *
                      6:   * (c) 1995 Bernd Schmidt
                      7:   */
                      8: 
                      9: #include "sysconfig.h"
                     10: #include "sysdeps.h"
                     11: 
                     12: #include "config.h"
                     13: #include "options.h"
1.1.1.3   root       14: #include "uae.h"
1.1       root       15: #include "memory.h"
                     16: #include "ersatz.h"
                     17: #include "zfile.h"
1.1.1.9   root       18: #include "custom.h"
                     19: #include "events.h"
                     20: #include "newcpu.h"
1.1.1.11  root       21: #include "autoconf.h"
1.1.1.9   root       22: #include "savestate.h"
1.1       root       23: 
1.1.1.2   root       24: #ifdef USE_MAPPED_MEMORY
1.1       root       25: #include <sys/mman.h>
                     26: #endif
                     27: 
1.1.1.8   root       28: /* Set by each memory handler that does not simply access real memory.  */
                     29: int special_mem;
                     30: 
1.1       root       31: int ersatzkickfile = 0;
                     32: 
1.1.1.4   root       33: uae_u32 allocated_chipmem;
                     34: uae_u32 allocated_fastmem;
                     35: uae_u32 allocated_bogomem;
                     36: uae_u32 allocated_gfxmem;
                     37: uae_u32 allocated_z3fastmem;
                     38: uae_u32 allocated_a3000mem;
                     39: 
1.1.1.9   root       40: static long chip_filepos;
                     41: static long bogo_filepos;
                     42: static long rom_filepos;
                     43: 
1.1.1.14! root       44: /* ROM management.  */
        !            45: struct romlist {
        !            46:     char *path;
        !            47:     struct romdata *rd;
        !            48: };
        !            49: 
        !            50: static struct romlist *rl;
        !            51: static int romlist_cnt;
        !            52: 
        !            53: void romlist_add (char *path, struct romdata *rd)
        !            54: {
        !            55:     struct romlist *rl2;
        !            56: 
        !            57:     romlist_cnt++;
        !            58:     rl = realloc (rl, sizeof (struct romlist) * romlist_cnt);
        !            59:     rl2 = rl + romlist_cnt - 1;
        !            60:     rl2->path = my_strdup (path);
        !            61:     rl2->rd = rd;
        !            62: }
        !            63: 
        !            64: char *romlist_get (struct romdata *rd)
        !            65: {
        !            66:     int i;
        !            67:     
        !            68:     if (!rd)
        !            69:        return 0;
        !            70:     for (i = 0; i < romlist_cnt; i++) {
        !            71:        if (rl[i].rd == rd)
        !            72:            return rl[i].path;
        !            73:     }
        !            74:     return 0;
        !            75: }
        !            76: 
        !            77: void romlist_clear (void)
        !            78: {
        !            79:     free (rl);
        !            80:     rl = 0;
        !            81:     romlist_cnt = 0;
        !            82: }
        !            83: 
        !            84: static struct romdata roms[] = {
        !            85:     { "Cloanto Amiga Forever ROM key", 0, 0, 0x869ae1b1, 2069, 0, 0, 1, ROMTYPE_KEY },
        !            86: 
        !            87:     { "Kickstart v1.0 (A1000)(NTSC)", 0, 0, 0x299790ff, 262144, 1, 0, 0, ROMTYPE_KICK },
        !            88:     { "Kickstart v1.1 (A1000)(NTSC)", 31, 34, 0xd060572a, 262144, 2, 0, 0, ROMTYPE_KICK },
        !            89:     { "Kickstart v1.1 (A1000)(PAL)", 31, 34, 0xec86dae2, 262144, 3, 0, 0, ROMTYPE_KICK },
        !            90:     { "Kickstart v1.2 (A1000)", 33, 166, 0x9ed783d0, 262144, 4, 0, 0, ROMTYPE_KICK },
        !            91:     { "Kickstart v1.2 (A500,A1000,A2000)", 33, 180, 0xa6ce1636, 262144, 5, 0, 0, ROMTYPE_KICK },
        !            92:     { "Kickstart v1.3 (A500,A1000,A2000)", 34, 5, 0xc4f0f55f, 262144, 6, 60, 0, ROMTYPE_KICK },
        !            93:     { "Kickstart v1.3 (A3000)", 34, 5, 0xe0f37258, 262144, 32, 0, 0, ROMTYPE_KICK },
        !            94: 
        !            95:     { "Kickstart v2.04 (A500+)", 37, 175, 0xc3bdb240, 524288, 7, 0, 0, ROMTYPE_KICK },
        !            96:     { "Kickstart v2.05 (A600)", 37, 299, 0x83028fb5, 524288, 8, 0, 0, ROMTYPE_KICK },
        !            97:     { "Kickstart v2.05 (A600HD)", 37, 300, 0x64466c2a, 524288, 9, 0, 0, ROMTYPE_KICK },
        !            98:     { "Kickstart v2.05 (A600HD)", 37, 350, 0x43b0df7b, 524288, 10, 0, 0, ROMTYPE_KICK },
        !            99: 
        !           100:     { "Kickstart v3.0 (A1200)", 39, 106, 0x6c9b07d2, 524288, 11, 0, 0, ROMTYPE_KICK },
        !           101:     { "Kickstart v3.0 (A4000)", 39, 106, 0x9e6ac152, 524288, 12, 2, 0, ROMTYPE_KICK },
        !           102:     { "Kickstart v3.1 (A4000)", 40, 70, 0x2b4566f1, 524288, 13, 2, 0, ROMTYPE_KICK },
        !           103:     { "Kickstart v3.1 (A500,A600,A2000)", 40, 63, 0xfc24ae0d, 524288, 14, 0, 0, ROMTYPE_KICK },
        !           104:     { "Kickstart v3.1 (A1200)", 40, 68, 0x1483a091, 524288, 15, 1, 0, ROMTYPE_KICK },
        !           105:     { "Kickstart v3.1 (A4000)(Cloanto)", 40, 68, 0x43b6dd22, 524288, 31, 2, 1, ROMTYPE_KICK },
        !           106:     { "Kickstart v3.1 (A4000)", 40, 68, 0xd6bae334, 524288, 16, 2, 0, ROMTYPE_KICK },
        !           107:     { "Kickstart v3.1 (A4000T)", 40, 70, 0x75932c3a, 524288, 17, 2, 0, ROMTYPE_KICK },
        !           108: 
        !           109:     { "CD32 Kickstart v3.1", 40, 60, 0x1e62d4a5, 524288, 18, 1, 0, ROMTYPE_KICKCD32 },
        !           110:     { "CD32 Extended", 40, 60, 0x87746be2, 524288, 19, 1, 0, ROMTYPE_EXTCD32 },
        !           111: 
        !           112:     { "CDTV Extended v1.00", 0, 0, 0x42baa124, 262144, 20, 0, 0, ROMTYPE_EXTCDTV },
        !           113:     { "CDTV Extended v2.30", 0, 0, 0x30b54232, 262144, 21, 0, 0, ROMTYPE_EXTCDTV },
        !           114:     { "CDTV Extended v2.07", 0, 0, 0xceae68d2, 262144, 22, 0, 0, ROMTYPE_EXTCDTV },
        !           115: 
        !           116:     { "A1000 Bootstrap", 0, 0, 0x62f11c04, 8192, 23, 0, 0, ROMTYPE_KICK },
        !           117:     { "A1000 Bootstrap", 0, 0, 0x0b1ad2d0, 65536, 24, 0, 0, ROMTYPE_KICK },
        !           118: 
        !           119:     { "Action Replay Mk I v1.50", 0, 0, 0xd4ce0675, 65536, 25, 0, 0, ROMTYPE_AR },
        !           120:     { "Action Replay Mk II v2.05", 0, 0, 0x1287301f , 131072, 26, 0, 0, ROMTYPE_AR },
        !           121:     { "Action Replay Mk II v2.12", 0, 0, 0x804d0361 , 131072, 27, 0, 0, ROMTYPE_AR },
        !           122:     { "Action Replay Mk II v2.14", 0, 0, 0x49650e4f, 131072, 28, 0, 0, ROMTYPE_AR },
        !           123:     { "Action Replay Mk III v3.09", 0, 0, 0x0ed9b5aa, 262144, 29, 0, 0, ROMTYPE_AR },
        !           124:     { "Action Replay Mk III v3.17", 0, 0, 0xc8a16406, 262144, 30, 0, 0, ROMTYPE_AR },
        !           125: 
        !           126:     { "SportTime Table Hockey\0ar_airh", 0, 0, 0, 0, 33, 0, 0, ROMTYPE_ARCADIA },
        !           127:     { "SportTime Bowling\0ar_bowl", 0, 0, 0, 0, 34, 0, 0, ROMTYPE_ARCADIA },
        !           128:     { "World Darts\0ar_dart", 0, 0, 0, 0, 35, 0, 0, ROMTYPE_ARCADIA },
        !           129:     { "Magic Johnson's Fast Break\0ar_fast", 0, 0, 0, 0, 36, 0, 0, ROMTYPE_ARCADIA },
        !           130:     { "Leader Board Golf\0ar_ldrb", 0, 0, 0, 0, 37, 0, 0, ROMTYPE_ARCADIA },
        !           131:     { "Leader Board Golf (alt)\0ar_ldrba", 0, 0, 0, 0, 38, 0, 0, ROMTYPE_ARCADIA },
        !           132:     { "Ninja Mission\0ar_ninj", 0, 0, 0, 0, 39, 0, 0, ROMTYPE_ARCADIA },
        !           133:     { "Road Wars\0ar_rdwr", 0, 0, 0, 0, 40, 0, 0, ROMTYPE_ARCADIA },
        !           134:     { "Sidewinder\0ar_sdwr", 0, 0, 0, 0, 41, 0, 0, ROMTYPE_ARCADIA },
        !           135:     { "Cool Spot\0ar_spot", 0, 0, 0, 0, 42, 0, 0, ROMTYPE_ARCADIA },
        !           136:     { "Space Ranger\0ar_sprg", 0, 0, 0, 0, 43, 0, 0, ROMTYPE_ARCADIA },
        !           137:     { "Xenon\0ar_xeon", 0, 0, 0, 0, 44, 0, 0, ROMTYPE_ARCADIA },
        !           138: 
        !           139:     { NULL, 0, 0, 0, 0, 0, 0, 0, 0 }
        !           140: };
        !           141: 
        !           142: static int decode_cloanto_rom (uae_u8 *mem, int size, int real_size)
        !           143: {
        !           144:     FILE *keyf;
        !           145:     uae_u8 *p;
        !           146:     long cnt, t;
        !           147:     int keysize;
        !           148: 
        !           149:     if (strlen (currprefs.keyfile) == 0) {
        !           150:        write_log ("No filename given for ROM key file and ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
        !           151:        return 0;
        !           152:     }
        !           153:     keyf = zfile_open (currprefs.keyfile, "rb");
        !           154:     if (keyf == 0) {
        !           155:        write_log ("Could not find specified ROM key-file.\n");
        !           156:        return 0;
        !           157:     }
        !           158: 
        !           159:     p = (uae_u8 *) xmalloc (524288);
        !           160:     keysize = fread (p, 1, 524288, keyf);
        !           161:     for (t = cnt = 0; cnt < size; cnt++, t = (t + 1) % keysize) {
        !           162:        mem[cnt] ^= p[t];
        !           163:        if (real_size == cnt + 1)
        !           164:            t = keysize - 1;
        !           165:     }
        !           166:     fclose (keyf);
        !           167:     free (p);
        !           168:     return 1;
        !           169: }
        !           170: 
1.1.1.3   root      171: addrbank *mem_banks[65536];
1.1.1.9   root      172: 
                    173: /* This has two functions. It either holds a host address that, when added
                    174:    to the 68k address, gives the host address corresponding to that 68k
                    175:    address (in which case the value in this array is even), OR it holds the
                    176:    same value as mem_banks, for those banks that have baseaddr==0. In that
                    177:    case, bit 0 is set (the memory access routines will take care of it).  */
                    178: 
                    179: uae_u8 *baseaddr[65536];
1.1       root      180: 
1.1.1.2   root      181: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5   root      182: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2   root      183: {
1.1.1.5   root      184:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2   root      185: }
1.1.1.5   root      186: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2   root      187: {
1.1.1.5   root      188:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2   root      189: }
1.1.1.5   root      190: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2   root      191: {
1.1.1.5   root      192:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2   root      193: }
1.1.1.5   root      194: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2   root      195: {
1.1.1.5   root      196:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2   root      197: }
1.1.1.5   root      198: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2   root      199: {
1.1.1.5   root      200:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2   root      201: }
1.1.1.5   root      202: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2   root      203: {
1.1.1.5   root      204:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2   root      205: }
                    206: #endif
                    207: 
1.1.1.12  root      208: uae_u32 chipmem_mask, kickmem_mask, extendedkickmem_mask, bogomem_mask, a3000mem_mask;
1.1       root      209: 
1.1.1.11  root      210: static int illegal_count;
1.1.1.3   root      211: /* A dummy bank that only contains zeros */
                    212: 
1.1.1.4   root      213: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                    214: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                    215: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                    216: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                    217: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                    218: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                    219: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                    220: 
                    221: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                    222: {
1.1.1.8   root      223:     special_mem |= S_READ;
1.1.1.11  root      224:     if (currprefs.illegal_mem) {
                    225:        if (illegal_count < 20) {
                    226:            illegal_count++;
                    227:            write_log ("Illegal lget at %08lx\n", addr);
                    228:        }
                    229:     }
1.1.1.4   root      230: 
1.1.1.9   root      231:     return 0xFFFFFFFF;
1.1       root      232: }
                    233: 
1.1.1.4   root      234: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1       root      235: {
1.1.1.8   root      236:     special_mem |= S_READ;
1.1.1.11  root      237:     if (currprefs.illegal_mem) {
                    238:        if (illegal_count < 20) {
                    239:            illegal_count++;
                    240:            write_log ("Illegal wget at %08lx\n", addr);
                    241:        }
                    242:     }
1.1.1.12  root      243: 
1.1.1.9   root      244:     return 0xFFFF;
1.1       root      245: }
                    246: 
1.1.1.4   root      247: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1       root      248: {
1.1.1.8   root      249:     special_mem |= S_READ;
1.1.1.11  root      250:     if (currprefs.illegal_mem) {
                    251:        if (illegal_count < 20) {
                    252:            illegal_count++;
                    253:            write_log ("Illegal bget at %08lx\n", addr);
                    254:        }
                    255:     }
1.1.1.4   root      256: 
1.1.1.9   root      257:     return 0xFF;
1.1       root      258: }
                    259: 
1.1.1.4   root      260: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1       root      261: {
1.1.1.8   root      262:     special_mem |= S_WRITE;
1.1.1.11  root      263:     if (currprefs.illegal_mem) {
                    264:        if (illegal_count < 20) {
                    265:            illegal_count++;
                    266:            write_log ("Illegal lput at %08lx\n", addr);
                    267:        }
                    268:     }
1.1.1.3   root      269: }
1.1.1.4   root      270: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      271: {
1.1.1.8   root      272:     special_mem |= S_WRITE;
1.1.1.11  root      273:     if (currprefs.illegal_mem) {
                    274:        if (illegal_count < 20) {
                    275:            illegal_count++;
                    276:            write_log ("Illegal wput at %08lx\n", addr);
                    277:        }
                    278:     }
1.1.1.3   root      279: }
1.1.1.4   root      280: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      281: {
1.1.1.8   root      282:     special_mem |= S_WRITE;
1.1.1.11  root      283:     if (currprefs.illegal_mem) {
                    284:        if (illegal_count < 20) {
                    285:            illegal_count++;
                    286:            write_log ("Illegal bput at %08lx\n", addr);
                    287:        }
                    288:     }
1.1       root      289: }
                    290: 
1.1.1.4   root      291: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1       root      292: {
1.1.1.9   root      293:     special_mem |= S_READ;
1.1.1.11  root      294:     if (currprefs.illegal_mem) {
                    295:        if (illegal_count < 20) {
                    296:            illegal_count++;
                    297:            write_log ("Illegal check at %08lx\n", addr);
                    298:        }
                    299:     }
1.1.1.4   root      300: 
1.1       root      301:     return 0;
                    302: }
                    303: 
1.1.1.3   root      304: /* A3000 "motherboard resources" bank.  */
1.1.1.4   root      305: static uae_u32 mbres_lget (uaecptr) REGPARAM;
                    306: static uae_u32 mbres_wget (uaecptr) REGPARAM;
                    307: static uae_u32 mbres_bget (uaecptr) REGPARAM;
                    308: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
                    309: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
                    310: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
                    311: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3   root      312: 
                    313: static int mbres_val = 0;
                    314: 
1.1.1.4   root      315: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3   root      316: {
1.1.1.8   root      317:     special_mem |= S_READ;
1.1.1.4   root      318:     if (currprefs.illegal_mem)
                    319:        write_log ("Illegal lget at %08lx\n", addr);
                    320: 
1.1       root      321:     return 0;
                    322: }
                    323: 
1.1.1.4   root      324: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1       root      325: {
1.1.1.8   root      326:     special_mem |= S_READ;
1.1.1.4   root      327:     if (currprefs.illegal_mem)
                    328:        write_log ("Illegal wget at %08lx\n", addr);
                    329: 
1.1       root      330:     return 0;
                    331: }
                    332: 
1.1.1.4   root      333: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3   root      334: {
1.1.1.8   root      335:     special_mem |= S_READ;
1.1.1.4   root      336:     if (currprefs.illegal_mem)
                    337:        write_log ("Illegal bget at %08lx\n", addr);
                    338: 
1.1.1.3   root      339:     return (addr & 0xFFFF) == 3 ? mbres_val : 0;
                    340: }
                    341: 
1.1.1.4   root      342: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1       root      343: {
1.1.1.8   root      344:     special_mem |= S_WRITE;
1.1.1.4   root      345:     if (currprefs.illegal_mem)
                    346:        write_log ("Illegal lput at %08lx\n", addr);
1.1       root      347: }
1.1.1.4   root      348: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1       root      349: {
1.1.1.8   root      350:     special_mem |= S_WRITE;
1.1.1.4   root      351:     if (currprefs.illegal_mem)
                    352:        write_log ("Illegal wput at %08lx\n", addr);
1.1       root      353: }
1.1.1.4   root      354: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1       root      355: {
1.1.1.8   root      356:     special_mem |= S_WRITE;
1.1.1.4   root      357:     if (currprefs.illegal_mem)
                    358:        write_log ("Illegal bput at %08lx\n", addr);
                    359: 
1.1.1.3   root      360:     if ((addr & 0xFFFF) == 3)
                    361:        mbres_val = b;
1.1       root      362: }
                    363: 
1.1.1.4   root      364: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1       root      365: {
1.1.1.4   root      366:     if (currprefs.illegal_mem)
                    367:        write_log ("Illegal check at %08lx\n", addr);
                    368: 
1.1       root      369:     return 0;
                    370: }
                    371: 
                    372: /* Chip memory */
                    373: 
1.1.1.3   root      374: uae_u8 *chipmemory;
1.1       root      375: 
1.1.1.4   root      376: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    377: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1       root      378: 
1.1.1.4   root      379: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1       root      380: {
1.1.1.3   root      381:     uae_u32 *m;
1.1.1.8   root      382: 
1.1       root      383:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      384:     addr &= chipmem_mask;
1.1.1.3   root      385:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      386:     return do_get_mem_long (m);
1.1       root      387: }
                    388: 
1.1.1.4   root      389: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1       root      390: {
1.1.1.3   root      391:     uae_u16 *m;
1.1.1.8   root      392: 
1.1       root      393:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      394:     addr &= chipmem_mask;
1.1.1.3   root      395:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      396:     return do_get_mem_word (m);
1.1       root      397: }
                    398: 
1.1.1.4   root      399: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1       root      400: {
                    401:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      402:     addr &= chipmem_mask;
1.1       root      403:     return chipmemory[addr];
                    404: }
                    405: 
1.1.1.4   root      406: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1       root      407: {
1.1.1.3   root      408:     uae_u32 *m;
1.1.1.8   root      409: 
1.1       root      410:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      411:     addr &= chipmem_mask;
1.1.1.3   root      412:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      413:     do_put_mem_long (m, l);
1.1       root      414: }
                    415: 
1.1.1.4   root      416: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1       root      417: {
1.1.1.3   root      418:     uae_u16 *m;
1.1.1.8   root      419: 
1.1       root      420:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      421:     addr &= chipmem_mask;
1.1.1.3   root      422:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      423:     do_put_mem_word (m, w);
1.1       root      424: }
                    425: 
1.1.1.4   root      426: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1       root      427: {
                    428:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      429:     addr &= chipmem_mask;
1.1       root      430:     chipmemory[addr] = b;
                    431: }
                    432: 
1.1.1.4   root      433: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1       root      434: {
                    435:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      436:     addr &= chipmem_mask;
1.1.1.4   root      437:     return (addr + size) <= allocated_chipmem;
1.1       root      438: }
                    439: 
1.1.1.4   root      440: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1       root      441: {
                    442:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      443:     addr &= chipmem_mask;
1.1       root      444:     return chipmemory + addr;
                    445: }
                    446: 
                    447: /* Slow memory */
                    448: 
1.1.1.3   root      449: static uae_u8 *bogomemory;
1.1       root      450: 
1.1.1.4   root      451: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
                    452: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
                    453: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
                    454: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
                    455: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
                    456: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
                    457: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    458: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1       root      459: 
1.1.1.4   root      460: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1       root      461: {
1.1.1.3   root      462:     uae_u32 *m;
1.1       root      463:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      464:     addr &= bogomem_mask;
1.1.1.3   root      465:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      466:     return do_get_mem_long (m);
1.1       root      467: }
                    468: 
1.1.1.4   root      469: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1       root      470: {
1.1.1.3   root      471:     uae_u16 *m;
1.1       root      472:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      473:     addr &= bogomem_mask;
1.1.1.3   root      474:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      475:     return do_get_mem_word (m);
1.1       root      476: }
                    477: 
1.1.1.4   root      478: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1       root      479: {
                    480:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      481:     addr &= bogomem_mask;
1.1       root      482:     return bogomemory[addr];
                    483: }
                    484: 
1.1.1.4   root      485: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1       root      486: {
1.1.1.3   root      487:     uae_u32 *m;
1.1       root      488:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      489:     addr &= bogomem_mask;
1.1.1.3   root      490:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      491:     do_put_mem_long (m, l);
1.1       root      492: }
                    493: 
1.1.1.4   root      494: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1       root      495: {
1.1.1.3   root      496:     uae_u16 *m;
1.1       root      497:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      498:     addr &= bogomem_mask;
1.1.1.3   root      499:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      500:     do_put_mem_word (m, w);
1.1       root      501: }
                    502: 
1.1.1.4   root      503: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1       root      504: {
                    505:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      506:     addr &= bogomem_mask;
1.1       root      507:     bogomemory[addr] = b;
                    508: }
                    509: 
1.1.1.4   root      510: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1       root      511: {
1.1.1.2   root      512:     addr -= bogomem_start & bogomem_mask;
                    513:     addr &= bogomem_mask;
1.1.1.4   root      514:     return (addr + size) <= allocated_bogomem;
1.1       root      515: }
                    516: 
1.1.1.4   root      517: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1       root      518: {
1.1.1.2   root      519:     addr -= bogomem_start & bogomem_mask;
                    520:     addr &= bogomem_mask;
1.1       root      521:     return bogomemory + addr;
                    522: }
                    523: 
1.1.1.3   root      524: /* A3000 motherboard fast memory */
                    525: 
                    526: static uae_u8 *a3000memory;
1.1       root      527: 
1.1.1.4   root      528: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
                    529: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
                    530: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
                    531: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
                    532: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
                    533: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
                    534: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    535: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      536: 
1.1.1.4   root      537: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3   root      538: {
                    539:     uae_u32 *m;
                    540:     addr -= a3000mem_start & a3000mem_mask;
                    541:     addr &= a3000mem_mask;
                    542:     m = (uae_u32 *)(a3000memory + addr);
1.1.1.5   root      543:     return do_get_mem_long (m);
1.1.1.3   root      544: }
1.1       root      545: 
1.1.1.4   root      546: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3   root      547: {
                    548:     uae_u16 *m;
                    549:     addr -= a3000mem_start & a3000mem_mask;
                    550:     addr &= a3000mem_mask;
                    551:     m = (uae_u16 *)(a3000memory + addr);
1.1.1.5   root      552:     return do_get_mem_word (m);
1.1.1.3   root      553: }
1.1       root      554: 
1.1.1.4   root      555: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1       root      556: {
1.1.1.3   root      557:     addr -= a3000mem_start & a3000mem_mask;
                    558:     addr &= a3000mem_mask;
                    559:     return a3000memory[addr];
1.1       root      560: }
                    561: 
1.1.1.4   root      562: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1       root      563: {
1.1.1.3   root      564:     uae_u32 *m;
                    565:     addr -= a3000mem_start & a3000mem_mask;
                    566:     addr &= a3000mem_mask;
                    567:     m = (uae_u32 *)(a3000memory + addr);
1.1.1.5   root      568:     do_put_mem_long (m, l);
1.1.1.3   root      569: }
                    570: 
1.1.1.4   root      571: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      572: {
                    573:     uae_u16 *m;
                    574:     addr -= a3000mem_start & a3000mem_mask;
                    575:     addr &= a3000mem_mask;
                    576:     m = (uae_u16 *)(a3000memory + addr);
1.1.1.5   root      577:     do_put_mem_word (m, w);
1.1.1.3   root      578: }
                    579: 
1.1.1.4   root      580: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      581: {
                    582:     addr -= a3000mem_start & a3000mem_mask;
                    583:     addr &= a3000mem_mask;
                    584:     a3000memory[addr] = b;
                    585: }
                    586: 
1.1.1.4   root      587: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3   root      588: {
                    589:     addr -= a3000mem_start & a3000mem_mask;
                    590:     addr &= a3000mem_mask;
1.1.1.4   root      591:     return (addr + size) <= allocated_a3000mem;
1.1       root      592: }
                    593: 
1.1.1.12  root      594: uae_u8 REGPARAM2 *a3000mem_xlate (uaecptr addr)
1.1.1.3   root      595: {
                    596:     addr -= a3000mem_start & a3000mem_mask;
                    597:     addr &= a3000mem_mask;
                    598:     return a3000memory + addr;
                    599: }
                    600: 
                    601: /* Kick memory */
                    602: 
                    603: uae_u8 *kickmemory;
                    604: 
1.1.1.12  root      605: /*
                    606:  * A1000 kickstart RAM handling
                    607:  *
                    608:  * RESET instruction unhides boot ROM and disables write protection
                    609:  * write access to boot ROM hides boot ROM and enables write protection
                    610:  *
                    611:  */
                    612: static int a1000_kickstart_mode;
                    613: static uae_u8 *a1000_bootrom;
                    614: static void a1000_handle_kickstart (int mode)
                    615: {
                    616:     if (mode == 0) {
                    617:        a1000_kickstart_mode = 0;
                    618:        memcpy (kickmemory, kickmemory + 262144, 262144);
                    619:     } else {
                    620:        a1000_kickstart_mode = 1;
                    621:        memset (kickmemory, 0, 262144);
                    622:        memcpy (kickmemory, a1000_bootrom, 8192);
                    623:        memcpy (kickmemory + 131072, a1000_bootrom, 8192);
                    624:     }
                    625: }
                    626: 
1.1.1.4   root      627: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
                    628: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
                    629: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
1.1.1.12  root      630: static void kickmem_lput (uaecptr, uae_u32) REGPARAM;
                    631: static void kickmem_wput (uaecptr, uae_u32) REGPARAM;
                    632: static void kickmem_bput (uaecptr, uae_u32) REGPARAM;
                    633: static int kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.4   root      634: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      635: 
1.1.1.4   root      636: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1       root      637: {
1.1.1.3   root      638:     uae_u32 *m;
1.1       root      639:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      640:     addr &= kickmem_mask;
1.1.1.3   root      641:     m = (uae_u32 *)(kickmemory + addr);
1.1.1.5   root      642:     return do_get_mem_long (m);
1.1       root      643: }
                    644: 
1.1.1.4   root      645: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1       root      646: {
1.1.1.3   root      647:     uae_u16 *m;
1.1       root      648:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      649:     addr &= kickmem_mask;
1.1.1.3   root      650:     m = (uae_u16 *)(kickmemory + addr);
1.1.1.5   root      651:     return do_get_mem_word (m);
1.1       root      652: }
                    653: 
1.1.1.4   root      654: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1       root      655: {
                    656:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      657:     addr &= kickmem_mask;
1.1       root      658:     return kickmemory[addr];
                    659: }
                    660: 
1.1.1.4   root      661: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1       root      662: {
1.1.1.12  root      663:     uae_u32 *m;
                    664:     if (a1000_kickstart_mode) {
                    665:        if (addr >= 0xfc0000) {
                    666:            addr -= kickmem_start & kickmem_mask;
                    667:            addr &= kickmem_mask;
                    668:            m = (uae_u32 *)(kickmemory + addr);
                    669:            do_put_mem_long (m, b);
                    670:            return;
                    671:        } else
                    672:            a1000_handle_kickstart (0);
                    673:     } else if (currprefs.illegal_mem)
1.1.1.4   root      674:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      675: }
                    676: 
1.1.1.4   root      677: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1       root      678: {
1.1.1.12  root      679:     uae_u16 *m;
                    680:     if (a1000_kickstart_mode) {
                    681:        if (addr >= 0xfc0000) {
                    682:            addr -= kickmem_start & kickmem_mask;
                    683:            addr &= kickmem_mask;
                    684:            m = (uae_u16 *)(kickmemory + addr);
                    685:            do_put_mem_word (m, b);
                    686:            return;
                    687:        } else
                    688:            a1000_handle_kickstart (0);
                    689:     } else if (currprefs.illegal_mem)
1.1.1.4   root      690:        write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1       root      691: }
                    692: 
1.1.1.4   root      693: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1       root      694: {
1.1.1.12  root      695:     if (a1000_kickstart_mode) {
                    696:        if (addr >= 0xfc0000) {
                    697:            addr -= kickmem_start & kickmem_mask;
                    698:            addr &= kickmem_mask;
                    699:            kickmemory[addr] = b;
                    700:            return;
                    701:        } else
                    702:            a1000_handle_kickstart (0);
                    703:     } else if (currprefs.illegal_mem)
1.1.1.4   root      704:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      705: }
                    706: 
1.1.1.4   root      707: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1       root      708: {
1.1.1.2   root      709:     addr -= kickmem_start & kickmem_mask;
                    710:     addr &= kickmem_mask;
1.1.1.4   root      711:     return (addr + size) <= kickmem_size;
1.1       root      712: }
                    713: 
1.1.1.4   root      714: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1       root      715: {
1.1.1.2   root      716:     addr -= kickmem_start & kickmem_mask;
                    717:     addr &= kickmem_mask;
1.1       root      718:     return kickmemory + addr;
                    719: }
                    720: 
1.1.1.12  root      721: /* CD32/CDTV extended kick memory */
1.1.1.3   root      722: 
1.1.1.12  root      723: uae_u8 *extendedkickmemory;
                    724: static int extendedkickmem_size;
                    725: static uae_u32 extendedkickmem_start;
                    726: 
                    727: #define EXTENDED_ROM_CD32 1
                    728: #define EXTENDED_ROM_CDTV 2
                    729: 
                    730: static int extromtype (void)
                    731: {
                    732:     switch (extendedkickmem_size) {
                    733:     case 524288:
                    734:        return EXTENDED_ROM_CD32;
                    735:     case 262144:
                    736:        return EXTENDED_ROM_CDTV;
                    737:     }
1.1.1.3   root      738:     return 0;
                    739: }
                    740: 
1.1.1.12  root      741: static uae_u32 extendedkickmem_lget (uaecptr) REGPARAM;
                    742: static uae_u32 extendedkickmem_wget (uaecptr) REGPARAM;
                    743: static uae_u32 extendedkickmem_bget (uaecptr) REGPARAM;
                    744: static void extendedkickmem_lput (uaecptr, uae_u32) REGPARAM;
                    745: static void extendedkickmem_wput (uaecptr, uae_u32) REGPARAM;
                    746: static void extendedkickmem_bput (uaecptr, uae_u32) REGPARAM;
                    747: static int extendedkickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    748: static uae_u8 *extendedkickmem_xlate (uaecptr addr) REGPARAM;
                    749: 
                    750: uae_u32 REGPARAM2 extendedkickmem_lget (uaecptr addr)
1.1.1.3   root      751: {
1.1.1.12  root      752:     uae_u32 *m;
                    753:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    754:     addr &= extendedkickmem_mask;
                    755:     m = (uae_u32 *)(extendedkickmemory + addr);
                    756:     return do_get_mem_long (m);
1.1.1.3   root      757: }
                    758: 
1.1.1.12  root      759: uae_u32 REGPARAM2 extendedkickmem_wget (uaecptr addr)
1.1       root      760: {
1.1.1.12  root      761:     uae_u16 *m;
                    762:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    763:     addr &= extendedkickmem_mask;
                    764:     m = (uae_u16 *)(extendedkickmemory + addr);
                    765:     return do_get_mem_word (m);
                    766: }
1.1.1.3   root      767: 
1.1.1.12  root      768: uae_u32 REGPARAM2 extendedkickmem_bget (uaecptr addr)
                    769: {
                    770:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    771:     addr &= extendedkickmem_mask;
                    772:     return extendedkickmemory[addr];
                    773: }
1.1.1.3   root      774: 
1.1.1.12  root      775: void REGPARAM2 extendedkickmem_lput (uaecptr addr, uae_u32 b)
                    776: {
                    777:     if (currprefs.illegal_mem)
                    778:        write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
                    779: }
1.1.1.3   root      780: 
1.1.1.12  root      781: void REGPARAM2 extendedkickmem_wput (uaecptr addr, uae_u32 b)
                    782: {
                    783:     if (currprefs.illegal_mem)
                    784:        write_log ("Illegal extendedkickmem wput at %08lx\n", addr);
                    785: }
1.1.1.3   root      786: 
1.1.1.12  root      787: void REGPARAM2 extendedkickmem_bput (uaecptr addr, uae_u32 b)
                    788: {
                    789:     if (currprefs.illegal_mem)
                    790:        write_log ("Illegal extendedkickmem lput at %08lx\n", addr);
                    791: }
1.1.1.3   root      792: 
1.1.1.12  root      793: int REGPARAM2 extendedkickmem_check (uaecptr addr, uae_u32 size)
                    794: {
                    795:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    796:     addr &= extendedkickmem_mask;
                    797:     return (addr + size) <= extendedkickmem_size;
                    798: }
1.1.1.3   root      799: 
1.1.1.12  root      800: uae_u8 REGPARAM2 *extendedkickmem_xlate (uaecptr addr)
                    801: {
                    802:     addr -= extendedkickmem_start & extendedkickmem_mask;
                    803:     addr &= extendedkickmem_mask;
                    804:     return extendedkickmemory + addr;
                    805: }
1.1.1.2   root      806: 
1.1.1.12  root      807: /* Default memory access functions */
                    808: 
                    809: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
                    810: {
                    811:     return 0;
                    812: }
                    813: 
                    814: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
                    815: {
                    816:     write_log ("Your Amiga program just did something terribly stupid\n");
                    817:     uae_reset ();
                    818:     return kickmem_xlate (get_long (0xF80000));        /* So we don't crash. */
1.1       root      819: }
                    820: 
                    821: /* Address banks */
                    822: 
                    823: addrbank dummy_bank = {
                    824:     dummy_lget, dummy_wget, dummy_bget,
                    825:     dummy_lput, dummy_wput, dummy_bput,
1.1.1.9   root      826:     default_xlate, dummy_check, NULL
1.1       root      827: };
                    828: 
1.1.1.3   root      829: addrbank mbres_bank = {
                    830:     mbres_lget, mbres_wget, mbres_bget,
                    831:     mbres_lput, mbres_wput, mbres_bput,
1.1.1.9   root      832:     default_xlate, mbres_check, NULL
1.1.1.3   root      833: };
                    834: 
1.1       root      835: addrbank chipmem_bank = {
                    836:     chipmem_lget, chipmem_wget, chipmem_bget,
                    837:     chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.9   root      838:     chipmem_xlate, chipmem_check, NULL
1.1       root      839: };
                    840: 
                    841: addrbank bogomem_bank = {
                    842:     bogomem_lget, bogomem_wget, bogomem_bget,
                    843:     bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.9   root      844:     bogomem_xlate, bogomem_check, NULL
1.1       root      845: };
                    846: 
1.1.1.3   root      847: addrbank a3000mem_bank = {
                    848:     a3000mem_lget, a3000mem_wget, a3000mem_bget,
                    849:     a3000mem_lput, a3000mem_wput, a3000mem_bput,
1.1.1.9   root      850:     a3000mem_xlate, a3000mem_check, NULL
1.1.1.3   root      851: };
                    852: 
1.1       root      853: addrbank kickmem_bank = {
                    854:     kickmem_lget, kickmem_wget, kickmem_bget,
                    855:     kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.9   root      856:     kickmem_xlate, kickmem_check, NULL
1.1       root      857: };
                    858: 
1.1.1.12  root      859: addrbank extendedkickmem_bank = {
                    860:     extendedkickmem_lget, extendedkickmem_wget, extendedkickmem_bget,
                    861:     extendedkickmem_lput, extendedkickmem_wput, extendedkickmem_bput,
                    862:     extendedkickmem_xlate, extendedkickmem_check, NULL
                    863: };
                    864: 
                    865: static int kickstart_checksum (uae_u8 *mem, int size)
                    866: {
                    867:     uae_u32 cksum = 0, prevck = 0;
                    868:     int i;
                    869:     for (i = 0; i < size; i += 4) {
                    870:        uae_u32 data = mem[i] * 65536 * 256 + mem[i + 1] * 65536 + mem[i + 2] * 256 + mem[i + 3];
                    871:        cksum += data;
                    872:        if (cksum < prevck)
                    873:            cksum++;
                    874:        prevck = cksum;
                    875:     }
                    876:     if (cksum != 0xFFFFFFFFul) {
                    877:        write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
                    878:     }
                    879:     return 0;
                    880: }
                    881: 
                    882: static int read_kickstart (FILE *f, uae_u8 *mem, int size, int dochecksum, int *cloanto_rom)
                    883: {
                    884:     unsigned char buffer[20];
                    885:     int i, cr = 0;
                    886: 
                    887:     if (cloanto_rom)
                    888:        *cloanto_rom = 0;
                    889:     i = fread (buffer, 1, 11, f);
                    890:     if (strncmp ((char *) buffer, "AMIROMTYPE1", 11) != 0) {
                    891:        fseek (f, 0, SEEK_SET);
                    892:     } else {
                    893:        cr = 1;
                    894:     }
                    895: 
                    896:     i = fread (mem, 1, size, f);
                    897:     if (i == 8192) {
                    898:        a1000_bootrom = malloc (8192);
                    899:        memcpy (a1000_bootrom, kickmemory, 8192);
                    900:        a1000_handle_kickstart (1);
                    901:     } else if (i == size / 2) {
                    902:        memcpy (mem + size / 2, mem, i);
                    903:     } else if (i != size) {
                    904:        write_log ("Error while reading Kickstart.\n");
                    905:        zfile_close (f);
                    906:        return 0;
                    907:     }
                    908:     zfile_close (f);
                    909: 
                    910:     if (cr)
                    911:        decode_cloanto_rom (mem, size, i);
                    912:     if (dochecksum && i >= 262144)
                    913:        kickstart_checksum (mem, size);
                    914:     if (cloanto_rom)
                    915:        *cloanto_rom = cr;
                    916:     return 1;
                    917: }
                    918: 
                    919: static int load_extendedkickstart (void)
                    920: {
                    921:     FILE *f;
                    922:     int size;
                    923: 
                    924:     if (strlen (currprefs.romextfile) == 0)
                    925:        return 0;
                    926:     f = zfile_open (currprefs.romextfile, "rb");
                    927:     if (!f) {
                    928:        write_log ("No extended Kickstart ROM found");
                    929:        return 0;
                    930:     }
                    931: 
                    932:     fseek (f, 0, SEEK_END);
                    933:     size = ftell (f);
                    934:     if (size > 300000)
                    935:        extendedkickmem_size = 524288;
                    936:     else
                    937:        extendedkickmem_size = 262144;
                    938:     fseek (f, 0, SEEK_SET);
                    939: 
                    940:     switch (extromtype ()) {
                    941:     case EXTENDED_ROM_CDTV:
                    942:        extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_f0");
                    943:        extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
                    944:        break;
                    945:     case EXTENDED_ROM_CD32:
                    946:        extendedkickmemory = (uae_u8 *) mapped_malloc (extendedkickmem_size, "rom_e0");
                    947:        extendedkickmem_bank.baseaddr = (uae_u8 *) extendedkickmemory;
                    948:        break;
                    949:     }
                    950:     read_kickstart (f, extendedkickmemory, 524288, 0, 0);
                    951:     fclose (f);
                    952:     return 1;
                    953: }
                    954: 
                    955: 
                    956: static int load_kickstart (void)
                    957: {
                    958:     FILE *f = zfile_open (currprefs.romfile, "rb");
                    959: 
                    960:     if (f == NULL) {
                    961: #if defined(AMIGA)||defined(__POS__)
                    962: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
                    963:        if (!getenv (USE_UAE_ERSATZ)) {
                    964:            write_log ("Using current ROM. (create ENV:%s to " "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
                    965:            memcpy (kickmemory, (char *) 0x1000000 - kickmem_size, kickmem_size);
                    966:            kickstart_checksum (kickmemory, kickmem_size);
                    967:            goto chk_sum;
                    968:        }
                    969: #endif
                    970:        return 0;
                    971:     }
                    972: 
                    973:     if (!read_kickstart (f, kickmemory, kickmem_size, 1, &cloanto_rom))
                    974:        return 0;
                    975: 
                    976: #if defined(AMIGA)
                    977:   chk_sum:
                    978: #endif
                    979: 
                    980:     if (currprefs.kickshifter) {
                    981:        /* Patch Kickstart ROM for ShapeShifter - from Christian Bauer.
                    982:           Changes 'lea $400,a0' to 'lea $2000,a0' for ShapeShifter compatability.
                    983:           NOTE: lea is 0x41f8, so we should do this better with a search for
                    984:           0x41f80400 --> 0x41f82000
                    985:        */
                    986:        if (kickmemory[0x24a] == 0x04 && kickmemory[0x24b] == 0x00) {   /* Kick 3.0 */
                    987:            kickmemory[0x24a] = 0x20;
                    988:            kickmemory[0x7ffea] -= 0x1c;
                    989:            write_log ("Kickstart KickShifted\n");
                    990:        } else if (kickmemory[0x26e] == 0x04 && kickmemory[0x26f] == 0x00) {    /* Kick 3.1 */
                    991:            kickmemory[0x26e] = 0x20;
                    992:            kickmemory[0x7ffea] -= 0x1c;
                    993:            write_log ("Kickstart KickShifted\n");
                    994:        } else if (kickmemory[0x24e] == 0x04 && kickmemory[0x24f] == 0x00) {    /* Kick 2.04 */
                    995:            kickmemory[0x24e] = 0x20;
                    996:            kickmemory[0x7ffea] -= 0x1c;
                    997:            write_log ("Kickstart KickShifted\n");
                    998:        }
                    999:     }
                   1000:     return 1;
                   1001: }
                   1002: 
1.1       root     1003: char *address_space, *good_address_map;
                   1004: int good_address_fd;
1.1.1.4   root     1005: 
1.1.1.9   root     1006: #ifndef NATMEM_OFFSET
                   1007: 
1.1.1.12  root     1008: uae_u8 *mapped_malloc (size_t s, char *file)
1.1.1.4   root     1009: {
1.1.1.13  root     1010:     return calloc (s, 1);
1.1.1.4   root     1011: }
                   1012: 
1.1.1.9   root     1013: void mapped_free (uae_u8 *p)
1.1       root     1014: {
1.1.1.9   root     1015:     free (p);
                   1016: }
                   1017: #else
1.1.1.3   root     1018: 
1.1.1.9   root     1019: #include <sys/ipc.h>
                   1020: #include <sys/shm.h>
                   1021: #include <unistd.h>
                   1022: #include <sys/mman.h>
                   1023: 
1.1.1.12  root     1024: shmpiece *shm_start = NULL;
                   1025: int canbang = 1;
1.1.1.9   root     1026: 
1.1.1.12  root     1027: static void dumplist (void)
1.1.1.9   root     1028: {
1.1.1.12  root     1029:     shmpiece *x = shm_start;
1.1.1.9   root     1030:     printf ("Start Dump:\n");
                   1031:     while (x) {
                   1032:        printf ("  this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
1.1.1.12  root     1033:                x, x->native_address, x->id, x->prev, x->next, x->size);
1.1.1.9   root     1034:        x = x->next;
1.1.1.2   root     1035:     }
1.1.1.9   root     1036:     printf ("End Dump:\n");
                   1037: }
1.1       root     1038: 
1.1.1.9   root     1039: static shmpiece *find_shmpiece (uae_u8 *base)
                   1040: {
                   1041:     shmpiece *x = shm_start;
1.1       root     1042: 
1.1.1.9   root     1043:     while (x && x->native_address != base)
                   1044:        x = x->next;
                   1045:     if (!x) {
1.1.1.12  root     1046:        printf ("NATMEM: Failure to find mapping at %p\n", base);
                   1047:        dumplist ();
1.1.1.9   root     1048:        canbang = 0;
                   1049:        return 0;
                   1050:     }
                   1051:     return x;
                   1052: }
1.1.1.3   root     1053: 
1.1.1.9   root     1054: static void delete_shmmaps (uae_u32 start, uae_u32 size)
                   1055: {
                   1056:     if (!canbang)
                   1057:        return;
                   1058: 
                   1059:     while (size) {
1.1.1.12  root     1060:        uae_u8 *base = mem_banks[bankindex (start)]->baseaddr;
1.1.1.9   root     1061:        if (base) {
                   1062:            shmpiece *x;
1.1.1.12  root     1063:            base = ((uae_u8 *) NATMEM_OFFSET) + start;
1.1.1.9   root     1064: 
                   1065:            x = find_shmpiece (base);
1.1.1.12  root     1066:            if (!x)
1.1.1.9   root     1067:                return;
                   1068: 
                   1069:            if (x->size > size) {
1.1.1.12  root     1070:                printf ("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n", start, x->size, size);
                   1071:                dumplist ();
1.1.1.9   root     1072:                canbang = 0;
                   1073:                return;
                   1074:            }
                   1075:            shmdt (x->native_address);
                   1076:            size -= x->size;
                   1077:            start += x->size;
                   1078:            if (x->next)
1.1.1.12  root     1079:                x->next->prev = x->prev;        /* remove this one from the list */
1.1.1.9   root     1080:            if (x->prev)
                   1081:                x->prev->next = x->next;
                   1082:            else
                   1083:                shm_start = x->next;
1.1.1.12  root     1084:            free (x);
1.1.1.9   root     1085:        } else {
                   1086:            size -= 0x10000;
                   1087:            start += 0x10000;
                   1088:        }
1.1.1.3   root     1089:     }
1.1.1.9   root     1090: }
1.1.1.12  root     1091: 
1.1.1.9   root     1092: static void add_shmmaps (uae_u32 start, addrbank *what)
                   1093: {
                   1094:     shmpiece *x = shm_start;
                   1095:     shmpiece *y;
                   1096:     uae_u8 *base = what->baseaddr;
                   1097: 
                   1098:     if (!canbang)
                   1099:        return;
                   1100:     if (!base)
                   1101:        return;
                   1102: 
                   1103:     x = find_shmpiece (base);
1.1.1.12  root     1104:     if (!x)
1.1.1.9   root     1105:        return;
                   1106:     y = malloc (sizeof (shmpiece));
                   1107:     *y = *x;
1.1.1.12  root     1108:     base = ((uae_u8 *) NATMEM_OFFSET) + start;
                   1109:     y->native_address = shmat (y->id, base, 0);
                   1110:     if (y->native_address == (void *) -1) {
                   1111:        printf ("NATMEM: Failure to map existing at %08x(%p)\n", start, base);
                   1112:        perror ("shmat");
                   1113:        dumplist ();
1.1.1.9   root     1114:        canbang = 0;
                   1115:        return;
1.1.1.2   root     1116:     }
1.1.1.9   root     1117:     y->next = shm_start;
                   1118:     y->prev = NULL;
                   1119:     if (y->next)
                   1120:        y->next->prev = y;
                   1121:     shm_start = y;
                   1122: }
                   1123: 
                   1124: uae_u8 *mapped_malloc (size_t s, char *file)
                   1125: {
1.1.1.12  root     1126:     int id;
1.1.1.9   root     1127:     void *answer;
                   1128:     shmpiece *x;
                   1129: 
1.1.1.12  root     1130:     if (!canbang)
1.1.1.9   root     1131:        return malloc (s);
                   1132: 
1.1.1.12  root     1133:     id = shmget (IPC_PRIVATE, s, 0x1ff, file);
1.1.1.9   root     1134:     if (id == 1) {
                   1135:        canbang = 0;
                   1136:        return mapped_malloc (s, file);
                   1137:     }
1.1.1.12  root     1138:     answer = shmat (id, 0, 0);
                   1139:     shmctl (id, IPC_RMID, NULL);
                   1140:     if (answer != (void *) -1) {
                   1141:        x = malloc (sizeof (shmpiece));
1.1.1.9   root     1142:        x->native_address = answer;
                   1143:        x->id = id;
                   1144:        x->size = s;
                   1145:        x->next = shm_start;
                   1146:        x->prev = NULL;
                   1147:        if (x->next)
                   1148:            x->next->prev = x;
                   1149:        shm_start = x;
                   1150: 
                   1151:        return answer;
                   1152:     }
                   1153:     canbang = 0;
                   1154:     return mapped_malloc (s, file);
                   1155: }
                   1156: 
1.1.1.10  root     1157: void mapped_free (uae_u8 *base)
1.1.1.9   root     1158: {
                   1159:     shmpiece *x = find_shmpiece (base);
1.1.1.12  root     1160:     if (!x)
1.1.1.9   root     1161:        abort ();
                   1162:     shmdt (x->native_address);
                   1163: }
                   1164: 
1.1       root     1165: #endif
1.1.1.6   root     1166: 
1.1.1.9   root     1167: static void init_mem_banks (void)
                   1168: {
                   1169:     int i;
                   1170:     for (i = 0; i < 65536; i++)
                   1171:        put_mem_bank (i << 16, &dummy_bank, 0);
                   1172: }
                   1173: 
                   1174: static void allocate_memory (void)
                   1175: {
                   1176:     if (allocated_chipmem != currprefs.chipmem_size) {
                   1177:        if (chipmemory)
                   1178:            mapped_free (chipmemory);
                   1179:        chipmemory = 0;
                   1180: 
                   1181:        allocated_chipmem = currprefs.chipmem_size;
                   1182:        chipmem_mask = allocated_chipmem - 1;
                   1183: 
                   1184:        chipmemory = mapped_malloc (allocated_chipmem, "chip");
                   1185:        if (chipmemory == 0) {
                   1186:            write_log ("Fatal error: out of memory for chipmem.\n");
                   1187:            allocated_chipmem = 0;
                   1188:        } else
                   1189:            do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
                   1190:     }
                   1191: 
                   1192:     if (allocated_bogomem != currprefs.bogomem_size) {
                   1193:        if (bogomemory)
                   1194:            mapped_free (bogomemory);
                   1195:        bogomemory = 0;
                   1196: 
                   1197:        allocated_bogomem = currprefs.bogomem_size;
                   1198:        bogomem_mask = allocated_bogomem - 1;
                   1199: 
                   1200:        if (allocated_bogomem) {
                   1201:            bogomemory = mapped_malloc (allocated_bogomem, "bogo");
                   1202:            if (bogomemory == 0) {
                   1203:                write_log ("Out of memory for bogomem.\n");
                   1204:                allocated_bogomem = 0;
                   1205:            }
                   1206:        }
                   1207:     }
                   1208:     if (allocated_a3000mem != currprefs.a3000mem_size) {
                   1209:        if (a3000memory)
                   1210:            mapped_free (a3000memory);
                   1211:        a3000memory = 0;
                   1212: 
                   1213:        allocated_a3000mem = currprefs.a3000mem_size;
                   1214:        a3000mem_mask = allocated_a3000mem - 1;
                   1215: 
                   1216:        if (allocated_a3000mem) {
                   1217:            a3000memory = mapped_malloc (allocated_a3000mem, "a3000");
                   1218:            if (a3000memory == 0) {
                   1219:                write_log ("Out of memory for a3000mem.\n");
                   1220:                allocated_a3000mem = 0;
                   1221:            }
                   1222:        }
                   1223:     }
                   1224: 
                   1225:     if (savestate_state == STATE_RESTORE) {
                   1226:        fseek (savestate_file, chip_filepos, SEEK_SET);
                   1227:        fread (chipmemory, 1, allocated_chipmem, savestate_file);
                   1228:        if (allocated_bogomem > 0) {
                   1229:            fseek (savestate_file, bogo_filepos, SEEK_SET);
                   1230:            fread (bogomemory, 1, allocated_bogomem, savestate_file);
                   1231:        }
                   1232:     }
                   1233:     chipmem_bank.baseaddr = chipmemory;
                   1234:     bogomem_bank.baseaddr = bogomemory;
                   1235: }
                   1236: 
                   1237: void memory_reset (void)
                   1238: {
                   1239:     int i, custom_start;
                   1240: 
                   1241: #ifdef NATMEM_OFFSET
                   1242:     delete_shmmaps (0, 0xFFFF0000);
                   1243: #endif
1.1.1.4   root     1244:     init_mem_banks ();
1.1.1.3   root     1245: 
1.1.1.9   root     1246:     currprefs.chipmem_size = changed_prefs.chipmem_size;
                   1247:     currprefs.bogomem_size = changed_prefs.bogomem_size;
                   1248:     currprefs.a3000mem_size = changed_prefs.a3000mem_size;
                   1249: 
                   1250:     allocate_memory ();
                   1251: 
1.1.1.12  root     1252:     if (strcmp (currprefs.romfile, changed_prefs.romfile) != 0 || strcmp (currprefs.keyfile, changed_prefs.keyfile) != 0) {
1.1.1.10  root     1253:        ersatzkickfile = 0;
                   1254:        memcpy (currprefs.romfile, changed_prefs.romfile, sizeof currprefs.romfile);
                   1255:        memcpy (currprefs.keyfile, changed_prefs.keyfile, sizeof currprefs.keyfile);
                   1256:        /* Clear out whatever data remains across a reset.  */
                   1257:        memset (chipmemory, 0, allocated_chipmem);
1.1.1.12  root     1258:        if (!load_kickstart ()) {
1.1.1.10  root     1259:            init_ersatz_rom (kickmemory);
                   1260:            ersatzkickfile = 1;
                   1261:        }
1.1.1.12  root     1262:     }
1.1.1.9   root     1263:     /* Map the chipmem into all of the lower 8MB */
                   1264:     i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
                   1265:     map_banks (&chipmem_bank, 0x00, i, allocated_chipmem);
                   1266: 
1.1.1.3   root     1267:     custom_start = 0xC0;
1.1       root     1268: 
1.1.1.9   root     1269:     map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0);
                   1270:     map_banks (&cia_bank, 0xA0, 32, 0);
                   1271:     map_banks (&clock_bank, 0xDC, 1, 0);
1.1.1.3   root     1272: 
                   1273:     /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
                   1274:      * range on an Amiga without expansion memory?  */
1.1.1.4   root     1275:     custom_start = allocated_chipmem >> 16;
1.1.1.3   root     1276:     if (custom_start < 0x20)
                   1277:        custom_start = 0x20;
1.1.1.9   root     1278:     map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
1.1.1.12  root     1279:     /*map_banks (&mbres_bank, 0xDE, 1); */
1.1.1.3   root     1280: 
1.1.1.9   root     1281:     if (bogomemory != 0) {
                   1282:        int t = allocated_bogomem >> 16;
                   1283:        if (t > 0x1C)
                   1284:            t = 0x1C;
                   1285:        map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
                   1286:     }
1.1.1.4   root     1287:     if (a3000memory != 0)
1.1.1.12  root     1288:        map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16, allocated_a3000mem);
1.1.1.9   root     1289: 
1.1.1.11  root     1290:     map_banks (&rtarea_bank, RTAREA_BASE >> 16, 1, 0);
1.1.1.9   root     1291: 
                   1292:     map_banks (&kickmem_bank, 0xF8, 8, 0);
1.1.1.12  root     1293:     if (a1000_bootrom)
                   1294:        a1000_handle_kickstart (1);
1.1.1.9   root     1295:     map_banks (&expamem_bank, 0xE8, 1, 0);
                   1296: 
1.1.1.12  root     1297:     switch (extromtype ()) {
                   1298:     case EXTENDED_ROM_CDTV:
                   1299:        map_banks (&extendedkickmem_bank, 0xF0, 4, 0);
                   1300:        break;
                   1301:     case EXTENDED_ROM_CD32:
                   1302:        map_banks (&extendedkickmem_bank, 0xE0, 8, 0);
                   1303:        break;
                   1304:     default:
                   1305:        if (cloanto_rom)
                   1306:            map_banks (&kickmem_bank, 0xE0, 8, 0);
                   1307:     }
1.1.1.9   root     1308: }
                   1309: 
                   1310: void memory_init (void)
                   1311: {
                   1312:     allocated_chipmem = 0;
                   1313:     allocated_bogomem = 0;
                   1314:     allocated_a3000mem = 0;
                   1315:     kickmemory = 0;
1.1.1.12  root     1316:     extendedkickmemory = 0;
1.1.1.9   root     1317:     chipmemory = 0;
                   1318:     a3000memory = 0;
                   1319:     bogomemory = 0;
                   1320: 
                   1321:     kickmemory = mapped_malloc (kickmem_size, "kick");
                   1322:     kickmem_bank.baseaddr = kickmemory;
1.1.1.3   root     1323: 
1.1.1.12  root     1324:     load_extendedkickstart ();
                   1325:     if (!load_kickstart ()) {
1.1.1.3   root     1326:        init_ersatz_rom (kickmemory);
1.1       root     1327:        ersatzkickfile = 1;
                   1328:     }
1.1.1.3   root     1329: 
1.1.1.9   root     1330:     init_mem_banks ();
                   1331:     memory_reset ();
1.1.1.4   root     1332: 
                   1333:     kickmem_mask = kickmem_size - 1;
1.1.1.12  root     1334:     extendedkickmem_mask = extendedkickmem_size - 1;
1.1       root     1335: }
                   1336: 
1.1.1.12  root     1337: void memory_cleanup (void)
1.1.1.10  root     1338: {
                   1339:     if (a3000memory)
                   1340:        mapped_free (a3000memory);
                   1341:     if (bogomemory)
                   1342:        mapped_free (bogomemory);
                   1343:     if (kickmemory)
                   1344:        mapped_free (kickmemory);
1.1.1.12  root     1345:     if (a1000_bootrom)
                   1346:        free (a1000_bootrom);
1.1.1.10  root     1347:     if (chipmemory)
                   1348:        mapped_free (chipmemory);
1.1.1.12  root     1349: 
1.1.1.10  root     1350:     a3000memory = 0;
                   1351:     bogomemory = 0;
                   1352:     kickmemory = 0;
1.1.1.12  root     1353:     a1000_bootrom = 0;
1.1.1.10  root     1354:     chipmemory = 0;
                   1355: }
                   1356: 
1.1.1.9   root     1357: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1       root     1358: {
                   1359:     int bnr;
1.1.1.3   root     1360:     unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.12  root     1361:     addrbank *orgbank = bank;
1.1.1.9   root     1362:     uae_u32 realstart = start;
1.1.1.12  root     1363: 
                   1364:     flush_icache (1);          /* Sure don't want to keep any old mappings around! */
1.1.1.9   root     1365: #ifdef NATMEM_OFFSET
                   1366:     delete_shmmaps (start << 16, size << 16);
                   1367: #endif
1.1.1.12  root     1368: 
1.1.1.9   root     1369:     if (!realsize)
                   1370:        realsize = size << 16;
                   1371: 
                   1372:     if ((size << 16) < realsize) {
1.1.1.11  root     1373:        write_log ("Please report to [email protected], and mention:\n");
1.1.1.12  root     1374:        write_log ("Broken mapping, size=%x, realsize=%x\n", size, realsize);
                   1375:        write_log ("Start is %x\n", start);
1.1.1.11  root     1376:        write_log ("Reducing memory sizes, especially chipmem, may fix this problem\n");
1.1.1.9   root     1377:        abort ();
                   1378:     }
1.1.1.3   root     1379: 
                   1380:     if (start >= 0x100) {
1.1.1.10  root     1381:        int real_left = 0;
1.1.1.9   root     1382:        for (bnr = start; bnr < start + size; bnr++) {
                   1383:            if (!real_left) {
                   1384:                realstart = bnr;
1.1.1.12  root     1385:                real_left = realsize >> 16;
1.1.1.9   root     1386: #ifdef NATMEM_OFFSET
                   1387:                add_shmmaps (realstart << 16, bank);
                   1388: #endif
                   1389:            }
1.1.1.12  root     1390:            put_mem_bank (bnr << 16, bank, realstart << 16);
1.1.1.9   root     1391:            real_left--;
                   1392:        }
1.1.1.3   root     1393:        return;
                   1394:     }
1.1.1.10  root     1395:     if (currprefs.address_space_24)
                   1396:        endhioffs = 0x10000;
1.1.1.9   root     1397:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
1.1.1.10  root     1398:        int real_left = 0;
1.1.1.12  root     1399:        for (bnr = start; bnr < start + size; bnr++) {
1.1.1.9   root     1400:            if (!real_left) {
                   1401:                realstart = bnr + hioffs;
                   1402:                real_left = realsize >> 16;
                   1403: #ifdef NATMEM_OFFSET
                   1404:                add_shmmaps (realstart << 16, bank);
                   1405: #endif
                   1406:            }
1.1.1.12  root     1407:            put_mem_bank ((bnr + hioffs) << 16, bank, realstart << 16);
1.1.1.9   root     1408:            real_left--;
                   1409:        }
                   1410:     }
                   1411: }
                   1412: 
                   1413: 
                   1414: /* memory save/restore code */
                   1415: 
                   1416: uae_u8 *save_cram (int *len)
                   1417: {
                   1418:     *len = allocated_chipmem;
                   1419:     return chipmemory;
                   1420: }
                   1421: 
                   1422: uae_u8 *save_bram (int *len)
                   1423: {
                   1424:     *len = allocated_bogomem;
                   1425:     return bogomemory;
                   1426: }
                   1427: 
                   1428: void restore_cram (int len, long filepos)
                   1429: {
                   1430:     chip_filepos = filepos;
                   1431:     changed_prefs.chipmem_size = len;
                   1432: }
                   1433: 
                   1434: void restore_bram (int len, long filepos)
                   1435: {
                   1436:     bogo_filepos = filepos;
                   1437:     changed_prefs.bogomem_size = len;
                   1438: }
                   1439: 
                   1440: uae_u8 *restore_rom (uae_u8 *src)
                   1441: {
                   1442:     restore_u32 ();
                   1443:     restore_u32 ();
                   1444:     restore_u32 ();
                   1445:     restore_u32 ();
                   1446:     restore_u32 ();
                   1447: 
                   1448:     return src;
                   1449: }
                   1450: 
                   1451: uae_u8 *save_rom (int first, int *len)
                   1452: {
                   1453:     static int count;
                   1454:     uae_u8 *dst, *dstbak;
                   1455:     uae_u8 *mem_real_start;
                   1456:     int mem_start, mem_size, mem_type, i, saverom;
                   1457: 
                   1458:     saverom = 0;
1.1.1.12  root     1459:     if (first)
                   1460:        count = 0;
1.1.1.9   root     1461:     for (;;) {
                   1462:        mem_type = count;
1.1.1.12  root     1463:        switch (count) {
                   1464:        case 0:         /* Kickstart ROM */
1.1.1.9   root     1465:            mem_start = 0xf80000;
                   1466:            mem_real_start = kickmemory;
                   1467:            mem_size = kickmem_size;
                   1468:            /* 256KB or 512KB ROM? */
1.1.1.12  root     1469:            for (i = 0; i < mem_size / 2 - 4; i++) {
                   1470:                if (longget (i + mem_start) != longget (i + mem_start + mem_size / 2))
                   1471:                    break;
1.1.1.9   root     1472:            }
1.1.1.12  root     1473:            if (i == mem_size / 2 - 4) {
1.1.1.9   root     1474:                mem_size /= 2;
                   1475:                mem_start += 262144;
                   1476:            }
                   1477:            mem_type = 0;
                   1478:            break;
1.1.1.12  root     1479:        default:
1.1.1.9   root     1480:            return 0;
                   1481:        }
1.1.1.12  root     1482:        count++;
                   1483:        if (mem_size)
                   1484:            break;
1.1.1.9   root     1485:     }
                   1486:     dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
                   1487:     save_u32 (mem_start);
                   1488:     save_u32 (mem_size);
                   1489:     save_u32 (mem_type);
1.1.1.12  root     1490:     save_u32 (longget (mem_start + 12));       /* version+revision */
1.1.1.9   root     1491:     save_u32 (0);
1.1.1.12  root     1492:     sprintf (dst, "Kickstart %d.%d", wordget (mem_start + 12), wordget (mem_start + 14));
1.1.1.9   root     1493:     dst += strlen (dst) + 1;
                   1494:     if (saverom) {
1.1.1.12  root     1495:        for (i = 0; i < mem_size; i++)
                   1496:            *dst++ = byteget (mem_start + i);
1.1.1.9   root     1497:     }
                   1498:     *len = dst - dstbak;
                   1499:     return dstbak;
1.1       root     1500: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.