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

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"
        !            21: #include "savestate.h"
1.1       root       22: 
1.1.1.2   root       23: #ifdef USE_MAPPED_MEMORY
1.1       root       24: #include <sys/mman.h>
                     25: #endif
                     26: 
1.1.1.8   root       27: /* Set by each memory handler that does not simply access real memory.  */
                     28: int special_mem;
                     29: 
1.1       root       30: int ersatzkickfile = 0;
                     31: 
1.1.1.4   root       32: uae_u32 allocated_chipmem;
                     33: uae_u32 allocated_fastmem;
                     34: uae_u32 allocated_bogomem;
                     35: uae_u32 allocated_gfxmem;
                     36: uae_u32 allocated_z3fastmem;
                     37: uae_u32 allocated_a3000mem;
                     38: 
1.1.1.9 ! root       39: static long chip_filepos;
        !            40: static long bogo_filepos;
        !            41: static long rom_filepos;
        !            42: 
1.1.1.3   root       43: addrbank *mem_banks[65536];
1.1.1.9 ! root       44: 
        !            45: /* This has two functions. It either holds a host address that, when added
        !            46:    to the 68k address, gives the host address corresponding to that 68k
        !            47:    address (in which case the value in this array is even), OR it holds the
        !            48:    same value as mem_banks, for those banks that have baseaddr==0. In that
        !            49:    case, bit 0 is set (the memory access routines will take care of it).  */
        !            50: 
        !            51: uae_u8 *baseaddr[65536];
1.1       root       52: 
1.1.1.2   root       53: #ifdef NO_INLINE_MEMORY_ACCESS
1.1.1.5   root       54: __inline__ uae_u32 longget (uaecptr addr)
1.1.1.2   root       55: {
1.1.1.5   root       56:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
1.1.1.2   root       57: }
1.1.1.5   root       58: __inline__ uae_u32 wordget (uaecptr addr)
1.1.1.2   root       59: {
1.1.1.5   root       60:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
1.1.1.2   root       61: }
1.1.1.5   root       62: __inline__ uae_u32 byteget (uaecptr addr)
1.1.1.2   root       63: {
1.1.1.5   root       64:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
1.1.1.2   root       65: }
1.1.1.5   root       66: __inline__ void longput (uaecptr addr, uae_u32 l)
1.1.1.2   root       67: {
1.1.1.5   root       68:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
1.1.1.2   root       69: }
1.1.1.5   root       70: __inline__ void wordput (uaecptr addr, uae_u32 w)
1.1.1.2   root       71: {
1.1.1.5   root       72:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
1.1.1.2   root       73: }
1.1.1.5   root       74: __inline__ void byteput (uaecptr addr, uae_u32 b)
1.1.1.2   root       75: {
1.1.1.5   root       76:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
1.1.1.2   root       77: }
                     78: #endif
                     79: 
1.1.1.3   root       80: uae_u32 chipmem_mask, kickmem_mask, bogomem_mask, a3000mem_mask;
1.1       root       81: 
1.1.1.3   root       82: /* A dummy bank that only contains zeros */
                     83: 
1.1.1.4   root       84: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                     85: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                     86: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                     87: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                     88: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                     89: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                     90: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                     91: 
                     92: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                     93: {
1.1.1.8   root       94:     special_mem |= S_READ;
1.1.1.4   root       95:     if (currprefs.illegal_mem)
                     96:        write_log ("Illegal lget at %08lx\n", addr);
                     97: 
1.1.1.9 ! root       98:     return 0xFFFFFFFF;
1.1       root       99: }
                    100: 
1.1.1.4   root      101: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
1.1       root      102: {
1.1.1.8   root      103:     special_mem |= S_READ;
1.1.1.4   root      104:     if (currprefs.illegal_mem)
                    105:        write_log ("Illegal wget at %08lx\n", addr);
                    106: 
1.1.1.9 ! root      107:     return 0xFFFF;
1.1       root      108: }
                    109: 
1.1.1.4   root      110: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
1.1       root      111: {
1.1.1.8   root      112:     special_mem |= S_READ;
1.1.1.4   root      113:     if (currprefs.illegal_mem)
                    114:        write_log ("Illegal bget at %08lx\n", addr);
                    115: 
1.1.1.9 ! root      116:     return 0xFF;
1.1       root      117: }
                    118: 
1.1.1.4   root      119: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
1.1       root      120: {
1.1.1.8   root      121:     special_mem |= S_WRITE;
1.1.1.4   root      122:     if (currprefs.illegal_mem)
                    123:        write_log ("Illegal lput at %08lx\n", addr);
1.1.1.3   root      124: }
1.1.1.4   root      125: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      126: {
1.1.1.8   root      127:     special_mem |= S_WRITE;
1.1.1.4   root      128:     if (currprefs.illegal_mem)
                    129:        write_log ("Illegal wput at %08lx\n", addr);
1.1.1.3   root      130: }
1.1.1.4   root      131: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      132: {
1.1.1.8   root      133:     special_mem |= S_WRITE;
1.1.1.4   root      134:     if (currprefs.illegal_mem)
                    135:        write_log ("Illegal bput at %08lx\n", addr);
1.1       root      136: }
                    137: 
1.1.1.4   root      138: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
1.1       root      139: {
1.1.1.9 ! root      140:     special_mem |= S_READ;
1.1.1.4   root      141:     if (currprefs.illegal_mem)
                    142:        write_log ("Illegal check at %08lx\n", addr);
                    143: 
1.1       root      144:     return 0;
                    145: }
                    146: 
1.1.1.3   root      147: /* A3000 "motherboard resources" bank.  */
1.1.1.4   root      148: static uae_u32 mbres_lget (uaecptr) REGPARAM;
                    149: static uae_u32 mbres_wget (uaecptr) REGPARAM;
                    150: static uae_u32 mbres_bget (uaecptr) REGPARAM;
                    151: static void mbres_lput (uaecptr, uae_u32) REGPARAM;
                    152: static void mbres_wput (uaecptr, uae_u32) REGPARAM;
                    153: static void mbres_bput (uaecptr, uae_u32) REGPARAM;
                    154: static int mbres_check (uaecptr addr, uae_u32 size) REGPARAM;
1.1.1.3   root      155: 
                    156: static int mbres_val = 0;
                    157: 
1.1.1.4   root      158: uae_u32 REGPARAM2 mbres_lget (uaecptr addr)
1.1.1.3   root      159: {
1.1.1.8   root      160:     special_mem |= S_READ;
1.1.1.4   root      161:     if (currprefs.illegal_mem)
                    162:        write_log ("Illegal lget at %08lx\n", addr);
                    163: 
1.1       root      164:     return 0;
                    165: }
                    166: 
1.1.1.4   root      167: uae_u32 REGPARAM2 mbres_wget (uaecptr addr)
1.1       root      168: {
1.1.1.8   root      169:     special_mem |= S_READ;
1.1.1.4   root      170:     if (currprefs.illegal_mem)
                    171:        write_log ("Illegal wget at %08lx\n", addr);
                    172: 
1.1       root      173:     return 0;
                    174: }
                    175: 
1.1.1.4   root      176: uae_u32 REGPARAM2 mbres_bget (uaecptr addr)
1.1.1.3   root      177: {
1.1.1.8   root      178:     special_mem |= S_READ;
1.1.1.4   root      179:     if (currprefs.illegal_mem)
                    180:        write_log ("Illegal bget at %08lx\n", addr);
                    181: 
1.1.1.3   root      182:     return (addr & 0xFFFF) == 3 ? mbres_val : 0;
                    183: }
                    184: 
1.1.1.4   root      185: void REGPARAM2 mbres_lput (uaecptr addr, uae_u32 l)
1.1       root      186: {
1.1.1.8   root      187:     special_mem |= S_WRITE;
1.1.1.4   root      188:     if (currprefs.illegal_mem)
                    189:        write_log ("Illegal lput at %08lx\n", addr);
1.1       root      190: }
1.1.1.4   root      191: void REGPARAM2 mbres_wput (uaecptr addr, uae_u32 w)
1.1       root      192: {
1.1.1.8   root      193:     special_mem |= S_WRITE;
1.1.1.4   root      194:     if (currprefs.illegal_mem)
                    195:        write_log ("Illegal wput at %08lx\n", addr);
1.1       root      196: }
1.1.1.4   root      197: void REGPARAM2 mbres_bput (uaecptr addr, uae_u32 b)
1.1       root      198: {
1.1.1.8   root      199:     special_mem |= S_WRITE;
1.1.1.4   root      200:     if (currprefs.illegal_mem)
                    201:        write_log ("Illegal bput at %08lx\n", addr);
                    202: 
1.1.1.3   root      203:     if ((addr & 0xFFFF) == 3)
                    204:        mbres_val = b;
1.1       root      205: }
                    206: 
1.1.1.4   root      207: int REGPARAM2 mbres_check (uaecptr addr, uae_u32 size)
1.1       root      208: {
1.1.1.4   root      209:     if (currprefs.illegal_mem)
                    210:        write_log ("Illegal check at %08lx\n", addr);
                    211: 
1.1       root      212:     return 0;
                    213: }
                    214: 
                    215: /* Chip memory */
                    216: 
1.1.1.3   root      217: uae_u8 *chipmemory;
1.1       root      218: 
1.1.1.4   root      219: static int chipmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    220: static uae_u8 *chipmem_xlate (uaecptr addr) REGPARAM;
1.1       root      221: 
1.1.1.4   root      222: uae_u32 REGPARAM2 chipmem_lget (uaecptr addr)
1.1       root      223: {
1.1.1.3   root      224:     uae_u32 *m;
1.1.1.8   root      225: 
1.1       root      226:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      227:     addr &= chipmem_mask;
1.1.1.3   root      228:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      229:     return do_get_mem_long (m);
1.1       root      230: }
                    231: 
1.1.1.4   root      232: uae_u32 REGPARAM2 chipmem_wget (uaecptr addr)
1.1       root      233: {
1.1.1.3   root      234:     uae_u16 *m;
1.1.1.8   root      235: 
1.1       root      236:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      237:     addr &= chipmem_mask;
1.1.1.3   root      238:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      239:     return do_get_mem_word (m);
1.1       root      240: }
                    241: 
1.1.1.4   root      242: uae_u32 REGPARAM2 chipmem_bget (uaecptr addr)
1.1       root      243: {
                    244:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      245:     addr &= chipmem_mask;
1.1       root      246:     return chipmemory[addr];
                    247: }
                    248: 
1.1.1.4   root      249: void REGPARAM2 chipmem_lput (uaecptr addr, uae_u32 l)
1.1       root      250: {
1.1.1.3   root      251:     uae_u32 *m;
1.1.1.8   root      252: 
1.1       root      253:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      254:     addr &= chipmem_mask;
1.1.1.3   root      255:     m = (uae_u32 *)(chipmemory + addr);
1.1.1.5   root      256:     do_put_mem_long (m, l);
1.1       root      257: }
                    258: 
1.1.1.4   root      259: void REGPARAM2 chipmem_wput (uaecptr addr, uae_u32 w)
1.1       root      260: {
1.1.1.3   root      261:     uae_u16 *m;
1.1.1.8   root      262: 
1.1       root      263:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      264:     addr &= chipmem_mask;
1.1.1.3   root      265:     m = (uae_u16 *)(chipmemory + addr);
1.1.1.5   root      266:     do_put_mem_word (m, w);
1.1       root      267: }
                    268: 
1.1.1.4   root      269: void REGPARAM2 chipmem_bput (uaecptr addr, uae_u32 b)
1.1       root      270: {
                    271:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      272:     addr &= chipmem_mask;
1.1       root      273:     chipmemory[addr] = b;
                    274: }
                    275: 
1.1.1.4   root      276: int REGPARAM2 chipmem_check (uaecptr addr, uae_u32 size)
1.1       root      277: {
                    278:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      279:     addr &= chipmem_mask;
1.1.1.4   root      280:     return (addr + size) <= allocated_chipmem;
1.1       root      281: }
                    282: 
1.1.1.4   root      283: uae_u8 REGPARAM2 *chipmem_xlate (uaecptr addr)
1.1       root      284: {
                    285:     addr -= chipmem_start & chipmem_mask;
1.1.1.2   root      286:     addr &= chipmem_mask;
1.1       root      287:     return chipmemory + addr;
                    288: }
                    289: 
                    290: /* Slow memory */
                    291: 
1.1.1.3   root      292: static uae_u8 *bogomemory;
1.1       root      293: 
1.1.1.4   root      294: static uae_u32 bogomem_lget (uaecptr) REGPARAM;
                    295: static uae_u32 bogomem_wget (uaecptr) REGPARAM;
                    296: static uae_u32 bogomem_bget (uaecptr) REGPARAM;
                    297: static void bogomem_lput (uaecptr, uae_u32) REGPARAM;
                    298: static void bogomem_wput (uaecptr, uae_u32) REGPARAM;
                    299: static void bogomem_bput (uaecptr, uae_u32) REGPARAM;
                    300: static int bogomem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    301: static uae_u8 *bogomem_xlate (uaecptr addr) REGPARAM;
1.1       root      302: 
1.1.1.4   root      303: uae_u32 REGPARAM2 bogomem_lget (uaecptr addr)
1.1       root      304: {
1.1.1.3   root      305:     uae_u32 *m;
1.1       root      306:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      307:     addr &= bogomem_mask;
1.1.1.3   root      308:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      309:     return do_get_mem_long (m);
1.1       root      310: }
                    311: 
1.1.1.4   root      312: uae_u32 REGPARAM2 bogomem_wget (uaecptr addr)
1.1       root      313: {
1.1.1.3   root      314:     uae_u16 *m;
1.1       root      315:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      316:     addr &= bogomem_mask;
1.1.1.3   root      317:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      318:     return do_get_mem_word (m);
1.1       root      319: }
                    320: 
1.1.1.4   root      321: uae_u32 REGPARAM2 bogomem_bget (uaecptr addr)
1.1       root      322: {
                    323:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      324:     addr &= bogomem_mask;
1.1       root      325:     return bogomemory[addr];
                    326: }
                    327: 
1.1.1.4   root      328: void REGPARAM2 bogomem_lput (uaecptr addr, uae_u32 l)
1.1       root      329: {
1.1.1.3   root      330:     uae_u32 *m;
1.1       root      331:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      332:     addr &= bogomem_mask;
1.1.1.3   root      333:     m = (uae_u32 *)(bogomemory + addr);
1.1.1.5   root      334:     do_put_mem_long (m, l);
1.1       root      335: }
                    336: 
1.1.1.4   root      337: void REGPARAM2 bogomem_wput (uaecptr addr, uae_u32 w)
1.1       root      338: {
1.1.1.3   root      339:     uae_u16 *m;
1.1       root      340:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      341:     addr &= bogomem_mask;
1.1.1.3   root      342:     m = (uae_u16 *)(bogomemory + addr);
1.1.1.5   root      343:     do_put_mem_word (m, w);
1.1       root      344: }
                    345: 
1.1.1.4   root      346: void REGPARAM2 bogomem_bput (uaecptr addr, uae_u32 b)
1.1       root      347: {
                    348:     addr -= bogomem_start & bogomem_mask;
1.1.1.2   root      349:     addr &= bogomem_mask;
1.1       root      350:     bogomemory[addr] = b;
                    351: }
                    352: 
1.1.1.4   root      353: int REGPARAM2 bogomem_check (uaecptr addr, uae_u32 size)
1.1       root      354: {
1.1.1.2   root      355:     addr -= bogomem_start & bogomem_mask;
                    356:     addr &= bogomem_mask;
1.1.1.4   root      357:     return (addr + size) <= allocated_bogomem;
1.1       root      358: }
                    359: 
1.1.1.4   root      360: uae_u8 REGPARAM2 *bogomem_xlate (uaecptr addr)
1.1       root      361: {
1.1.1.2   root      362:     addr -= bogomem_start & bogomem_mask;
                    363:     addr &= bogomem_mask;
1.1       root      364:     return bogomemory + addr;
                    365: }
                    366: 
1.1.1.3   root      367: /* A3000 motherboard fast memory */
                    368: 
                    369: static uae_u8 *a3000memory;
1.1       root      370: 
1.1.1.4   root      371: static uae_u32 a3000mem_lget (uaecptr) REGPARAM;
                    372: static uae_u32 a3000mem_wget (uaecptr) REGPARAM;
                    373: static uae_u32 a3000mem_bget (uaecptr) REGPARAM;
                    374: static void a3000mem_lput (uaecptr, uae_u32) REGPARAM;
                    375: static void a3000mem_wput (uaecptr, uae_u32) REGPARAM;
                    376: static void a3000mem_bput (uaecptr, uae_u32) REGPARAM;
                    377: static int a3000mem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    378: static uae_u8 *a3000mem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      379: 
1.1.1.4   root      380: uae_u32 REGPARAM2 a3000mem_lget (uaecptr addr)
1.1.1.3   root      381: {
                    382:     uae_u32 *m;
                    383:     addr -= a3000mem_start & a3000mem_mask;
                    384:     addr &= a3000mem_mask;
                    385:     m = (uae_u32 *)(a3000memory + addr);
1.1.1.5   root      386:     return do_get_mem_long (m);
1.1.1.3   root      387: }
1.1       root      388: 
1.1.1.4   root      389: uae_u32 REGPARAM2 a3000mem_wget (uaecptr addr)
1.1.1.3   root      390: {
                    391:     uae_u16 *m;
                    392:     addr -= a3000mem_start & a3000mem_mask;
                    393:     addr &= a3000mem_mask;
                    394:     m = (uae_u16 *)(a3000memory + addr);
1.1.1.5   root      395:     return do_get_mem_word (m);
1.1.1.3   root      396: }
1.1       root      397: 
1.1.1.4   root      398: uae_u32 REGPARAM2 a3000mem_bget (uaecptr addr)
1.1       root      399: {
1.1.1.3   root      400:     addr -= a3000mem_start & a3000mem_mask;
                    401:     addr &= a3000mem_mask;
                    402:     return a3000memory[addr];
1.1       root      403: }
                    404: 
1.1.1.4   root      405: void REGPARAM2 a3000mem_lput (uaecptr addr, uae_u32 l)
1.1       root      406: {
1.1.1.3   root      407:     uae_u32 *m;
                    408:     addr -= a3000mem_start & a3000mem_mask;
                    409:     addr &= a3000mem_mask;
                    410:     m = (uae_u32 *)(a3000memory + addr);
1.1.1.5   root      411:     do_put_mem_long (m, l);
1.1.1.3   root      412: }
                    413: 
1.1.1.4   root      414: void REGPARAM2 a3000mem_wput (uaecptr addr, uae_u32 w)
1.1.1.3   root      415: {
                    416:     uae_u16 *m;
                    417:     addr -= a3000mem_start & a3000mem_mask;
                    418:     addr &= a3000mem_mask;
                    419:     m = (uae_u16 *)(a3000memory + addr);
1.1.1.5   root      420:     do_put_mem_word (m, w);
1.1.1.3   root      421: }
                    422: 
1.1.1.4   root      423: void REGPARAM2 a3000mem_bput (uaecptr addr, uae_u32 b)
1.1.1.3   root      424: {
                    425:     addr -= a3000mem_start & a3000mem_mask;
                    426:     addr &= a3000mem_mask;
                    427:     a3000memory[addr] = b;
                    428: }
                    429: 
1.1.1.4   root      430: int REGPARAM2 a3000mem_check (uaecptr addr, uae_u32 size)
1.1.1.3   root      431: {
                    432:     addr -= a3000mem_start & a3000mem_mask;
                    433:     addr &= a3000mem_mask;
1.1.1.4   root      434:     return (addr + size) <= allocated_a3000mem;
1.1       root      435: }
                    436: 
1.1.1.3   root      437: uae_u8 REGPARAM2 *a3000mem_xlate(uaecptr addr)
                    438: {
                    439:     addr -= a3000mem_start & a3000mem_mask;
                    440:     addr &= a3000mem_mask;
                    441:     return a3000memory + addr;
                    442: }
                    443: 
                    444: /* Kick memory */
                    445: 
                    446: uae_u8 *kickmemory;
                    447: 
1.1.1.4   root      448: static uae_u32 kickmem_lget (uaecptr) REGPARAM;
                    449: static uae_u32 kickmem_wget (uaecptr) REGPARAM;
                    450: static uae_u32 kickmem_bget (uaecptr) REGPARAM;
                    451: static void  kickmem_lput (uaecptr, uae_u32) REGPARAM;
                    452: static void  kickmem_wput (uaecptr, uae_u32) REGPARAM;
                    453: static void  kickmem_bput (uaecptr, uae_u32) REGPARAM;
                    454: static int  kickmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    455: static uae_u8 *kickmem_xlate (uaecptr addr) REGPARAM;
1.1.1.3   root      456: 
1.1.1.4   root      457: uae_u32 REGPARAM2 kickmem_lget (uaecptr addr)
1.1       root      458: {
1.1.1.3   root      459:     uae_u32 *m;
1.1       root      460:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      461:     addr &= kickmem_mask;
1.1.1.3   root      462:     m = (uae_u32 *)(kickmemory + addr);
1.1.1.5   root      463:     return do_get_mem_long (m);
1.1       root      464: }
                    465: 
1.1.1.4   root      466: uae_u32 REGPARAM2 kickmem_wget (uaecptr addr)
1.1       root      467: {
1.1.1.3   root      468:     uae_u16 *m;
1.1       root      469:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      470:     addr &= kickmem_mask;
1.1.1.3   root      471:     m = (uae_u16 *)(kickmemory + addr);
1.1.1.5   root      472:     return do_get_mem_word (m);
1.1       root      473: }
                    474: 
1.1.1.4   root      475: uae_u32 REGPARAM2 kickmem_bget (uaecptr addr)
1.1       root      476: {
                    477:     addr -= kickmem_start & kickmem_mask;
1.1.1.2   root      478:     addr &= kickmem_mask;
1.1       root      479:     return kickmemory[addr];
                    480: }
                    481: 
1.1.1.4   root      482: void REGPARAM2 kickmem_lput (uaecptr addr, uae_u32 b)
1.1       root      483: {
1.1.1.4   root      484:     if (currprefs.illegal_mem)
                    485:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      486: }
                    487: 
1.1.1.4   root      488: void REGPARAM2 kickmem_wput (uaecptr addr, uae_u32 b)
1.1       root      489: {
1.1.1.4   root      490:     if (currprefs.illegal_mem)
                    491:        write_log ("Illegal kickmem wput at %08lx\n", addr);
1.1       root      492: }
                    493: 
1.1.1.4   root      494: void REGPARAM2 kickmem_bput (uaecptr addr, uae_u32 b)
1.1       root      495: {
1.1.1.4   root      496:     if (currprefs.illegal_mem)
                    497:        write_log ("Illegal kickmem lput at %08lx\n", addr);
1.1       root      498: }
                    499: 
1.1.1.4   root      500: int REGPARAM2 kickmem_check (uaecptr addr, uae_u32 size)
1.1       root      501: {
1.1.1.2   root      502:     addr -= kickmem_start & kickmem_mask;
                    503:     addr &= kickmem_mask;
1.1.1.4   root      504:     return (addr + size) <= kickmem_size;
1.1       root      505: }
                    506: 
1.1.1.4   root      507: uae_u8 REGPARAM2 *kickmem_xlate (uaecptr addr)
1.1       root      508: {
1.1.1.2   root      509:     addr -= kickmem_start & kickmem_mask;
                    510:     addr &= kickmem_mask;
1.1       root      511:     return kickmemory + addr;
                    512: }
                    513: 
1.1.1.3   root      514: /* Default memory access functions */
                    515: 
1.1.1.4   root      516: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
1.1.1.3   root      517: {
                    518:     return 0;
                    519: }
                    520: 
1.1.1.4   root      521: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
1.1.1.3   root      522: {
                    523:     write_log ("Your Amiga program just did something terribly stupid\n");
                    524:     uae_reset();
                    525:     return kickmem_xlate (get_long (0xF80000)); /* So we don't crash. */
                    526: }
                    527: 
1.1.1.4   root      528: static int load_kickstart (void)
1.1       root      529: {
                    530:     int i;
1.1.1.3   root      531:     uae_u32 cksum = 0, prevck = 0;
                    532:     unsigned char buffer[20];
                    533: 
1.1.1.6   root      534:     FILE *f = zfile_open (currprefs.romfile, "rb");
1.1.1.3   root      535: 
                    536:     if (f == NULL) {
                    537:        write_log ("No Kickstart ROM found.\n");
1.1.1.6   root      538: #if defined AMIGA || defined __POS__
1.1.1.2   root      539: #define USE_UAE_ERSATZ "USE_UAE_ERSATZ"
1.1.1.6   root      540:        if (!getenv (USE_UAE_ERSATZ)) {
                    541:            fprintf (stderr, "Using current ROM. (create ENV:%s to "
                    542:                     "use uae's ROM replacement)\n", USE_UAE_ERSATZ);
                    543:            memcpy (kickmemory, (char*)0x1000000 - kickmem_size, kickmem_size);
1.1.1.2   root      544:            goto chk_sum;
                    545:        }
                    546: #endif
1.1       root      547:        return 0;
                    548:     }
1.1.1.3   root      549: 
                    550:     i = fread (buffer, 1, 11, f);
                    551:     if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) != 0)
                    552:        fseek (f, 0, SEEK_SET);
                    553: 
                    554:     i = fread (kickmemory, 1, kickmem_size, f);
1.1       root      555:     if (i == kickmem_size/2) {
                    556:        memcpy (kickmemory + kickmem_size/2, kickmemory, kickmem_size/2);
                    557:     } else if (i != kickmem_size) {
1.1.1.3   root      558:        write_log ("Error while reading Kickstart.\n");
1.1       root      559:        return 0;
                    560:     }
                    561:     zfile_close (f);
1.1.1.3   root      562: 
                    563:     cloanto_rom = 0;
                    564:     if (strncmp ((char *)buffer, "AMIROMTYPE1", 11) == 0) {
                    565:        FILE *keyf;
                    566:        uae_u8 *p;
                    567:        long size, cnt, t;
                    568: 
                    569:        cloanto_rom = 1;
                    570:        write_log ("ROM image is an encrypted \"Amiga Forever\" ROM file.\n");
1.1.1.6   root      571:        if (strlen (currprefs.keyfile) == 0) {
1.1.1.3   root      572:            write_log ("No filename given for ROM key file.\n");
                    573:            return 0;
                    574:        }
1.1.1.6   root      575:        keyf = zfile_open (currprefs.keyfile, "rb");
1.1.1.3   root      576:        if (keyf == 0) {
                    577:            write_log ("Could not find ROM key file.\n");
                    578:            return 0;
                    579:        }
                    580:        p = (uae_u8 *)xmalloc (524288);
                    581:        size = fread (p, 1, 524288, keyf);
                    582: 
                    583:        for (t = cnt = 0; cnt < kickmem_size; cnt++, t = (t + 1) % size) {
                    584:            kickmemory[cnt] ^= p[t];
                    585:            if (i == cnt+1)
                    586:                t = size-1;
                    587:        }
                    588:        fclose (keyf);
                    589:        free (p);
                    590:     }
1.1.1.2   root      591: #if defined(AMIGA)
                    592:     chk_sum:
                    593: #endif
                    594: 
1.1       root      595:     for (i = 0; i < kickmem_size; i+=4) {
1.1.1.3   root      596:        uae_u32 data = kickmemory[i]*65536*256 + kickmemory[i+1]*65536 + kickmemory[i+2]*256 + kickmemory[i+3];
1.1       root      597:        cksum += data;
                    598:        if (cksum < prevck)
                    599:            cksum++;
                    600:        prevck = cksum;
                    601:     }
1.1.1.2   root      602:     if (cksum != 0xFFFFFFFFul) {
1.1.1.4   root      603:        write_log ("Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
1.1       root      604:     }
                    605:     return 1;
                    606: }
                    607: 
                    608: /* Address banks */
                    609: 
                    610: addrbank dummy_bank = {
                    611:     dummy_lget, dummy_wget, dummy_bget,
                    612:     dummy_lput, dummy_wput, dummy_bput,
1.1.1.9 ! root      613:     default_xlate, dummy_check, NULL
1.1       root      614: };
                    615: 
1.1.1.3   root      616: addrbank mbres_bank = {
                    617:     mbres_lget, mbres_wget, mbres_bget,
                    618:     mbres_lput, mbres_wput, mbres_bput,
1.1.1.9 ! root      619:     default_xlate, mbres_check, NULL
1.1.1.3   root      620: };
                    621: 
1.1       root      622: addrbank chipmem_bank = {
                    623:     chipmem_lget, chipmem_wget, chipmem_bget,
                    624:     chipmem_lput, chipmem_wput, chipmem_bput,
1.1.1.9 ! root      625:     chipmem_xlate, chipmem_check, NULL
1.1       root      626: };
                    627: 
                    628: addrbank bogomem_bank = {
                    629:     bogomem_lget, bogomem_wget, bogomem_bget,
                    630:     bogomem_lput, bogomem_wput, bogomem_bput,
1.1.1.9 ! root      631:     bogomem_xlate, bogomem_check, NULL
1.1       root      632: };
                    633: 
1.1.1.3   root      634: addrbank a3000mem_bank = {
                    635:     a3000mem_lget, a3000mem_wget, a3000mem_bget,
                    636:     a3000mem_lput, a3000mem_wput, a3000mem_bput,
1.1.1.9 ! root      637:     a3000mem_xlate, a3000mem_check, NULL
1.1.1.3   root      638: };
                    639: 
1.1       root      640: addrbank kickmem_bank = {
                    641:     kickmem_lget, kickmem_wget, kickmem_bget,
                    642:     kickmem_lput, kickmem_wput, kickmem_bput,
1.1.1.9 ! root      643:     kickmem_xlate, kickmem_check, NULL
1.1       root      644: };
                    645: 
                    646: char *address_space, *good_address_map;
                    647: int good_address_fd;
1.1.1.4   root      648: 
1.1.1.9 ! root      649: #ifndef NATMEM_OFFSET
        !           650: 
        !           651: uae_u8 *mapped_malloc (size_t s, char* file)
1.1.1.4   root      652: {
1.1.1.9 ! root      653:     return malloc (s);
1.1.1.4   root      654: }
                    655: 
1.1.1.9 ! root      656: void mapped_free (uae_u8 *p)
1.1       root      657: {
1.1.1.9 ! root      658:     free (p);
        !           659: }
        !           660: #else
1.1.1.3   root      661: 
1.1.1.9 ! root      662: #include <sys/ipc.h>
        !           663: #include <sys/shm.h>
        !           664: #include <unistd.h>
        !           665: #include <sys/mman.h>
        !           666: 
        !           667: shmpiece *shm_start=NULL;
        !           668: int canbang=1;
        !           669: 
        !           670: static void dumplist(void)
        !           671: {
        !           672:     shmpiece *x=shm_start;
        !           673:     printf ("Start Dump:\n");
        !           674:     while (x) {
        !           675:        printf ("  this=%p, Native %p, id %d, prev=%p, next=%p, size=0x%08x\n",
        !           676:                x, x->native_address, x->id, x->prev, x->next,x->size);
        !           677:        x = x->next;
1.1.1.2   root      678:     }
1.1.1.9 ! root      679:     printf ("End Dump:\n");
        !           680: }
1.1       root      681: 
1.1.1.9 ! root      682: static shmpiece *find_shmpiece (uae_u8 *base)
        !           683: {
        !           684:     shmpiece *x = shm_start;
1.1       root      685: 
1.1.1.9 ! root      686:     while (x && x->native_address != base)
        !           687:        x = x->next;
        !           688:     if (!x) {
        !           689:        printf("NATMEM: Failure to find mapping at %p\n",base);
        !           690:        dumplist();
        !           691:        canbang = 0;
        !           692:        return 0;
        !           693:     }
        !           694:     return x;
        !           695: }
1.1.1.3   root      696: 
1.1.1.9 ! root      697: static void delete_shmmaps (uae_u32 start, uae_u32 size)
        !           698: {
        !           699:     if (!canbang)
        !           700:        return;
        !           701: 
        !           702:     while (size) {
        !           703:        uae_u8 *base = mem_banks[bankindex(start)]->baseaddr;
        !           704:        if (base) {
        !           705:            shmpiece *x;
        !           706:            base = ((uae_u8*)NATMEM_OFFSET)+start;
        !           707: 
        !           708:            x = find_shmpiece (base);
        !           709:            if (! x)
        !           710:                return;
        !           711: 
        !           712:            if (x->size > size) {
        !           713:                printf("NATMEM: Failure to delete mapping at %08x(size %08x, delsize %08x)\n",start,x->size,size);
        !           714:                dumplist();
        !           715:                canbang = 0;
        !           716:                return;
        !           717:            }
        !           718:            shmdt (x->native_address);
        !           719:            size -= x->size;
        !           720:            start += x->size;
        !           721:            if (x->next)
        !           722:                x->next->prev = x->prev;  /* remove this one from the list */
        !           723:            if (x->prev)
        !           724:                x->prev->next = x->next;
        !           725:            else
        !           726:                shm_start = x->next;
        !           727:            free(x);
        !           728:        } else {
        !           729:            size -= 0x10000;
        !           730:            start += 0x10000;
        !           731:        }
1.1.1.3   root      732:     }
1.1.1.9 ! root      733: }
        !           734:  
        !           735: static void add_shmmaps (uae_u32 start, addrbank *what)
        !           736: {
        !           737:     shmpiece *x = shm_start;
        !           738:     shmpiece *y;
        !           739:     uae_u8 *base = what->baseaddr;
        !           740: 
        !           741:     if (!canbang)
        !           742:        return;
        !           743:     if (!base)
        !           744:        return;
        !           745: 
        !           746:     x = find_shmpiece (base);
        !           747:     if (! x)
        !           748:        return;
        !           749:     y = malloc (sizeof (shmpiece));
        !           750:     *y = *x;
        !           751:     base = ((uae_u8*)NATMEM_OFFSET) + start;
        !           752:     y->native_address = shmat (y->id,base,0);
        !           753:     if (y->native_address == (void*)-1) {
        !           754:        printf("NATMEM: Failure to map existing at %08x(%p)\n",start,base);
        !           755:        perror("shmat");
        !           756:        dumplist();
        !           757:        canbang = 0;
        !           758:        return;
1.1.1.2   root      759:     }
1.1.1.9 ! root      760:     y->next = shm_start;
        !           761:     y->prev = NULL;
        !           762:     if (y->next)
        !           763:        y->next->prev = y;
        !           764:     shm_start = y;
        !           765: }
        !           766: 
        !           767: uae_u8 *mapped_malloc (size_t s, char *file)
        !           768: {
        !           769:     int  id;
        !           770:     void *answer;
        !           771:     shmpiece *x;
        !           772: 
        !           773:     if (!canbang) 
        !           774:        return malloc (s);
        !           775: 
        !           776:     id = shmget (IPC_PRIVATE, s, 0x1ff);
        !           777:     if (id == 1) {
        !           778:        canbang = 0;
        !           779:        return mapped_malloc (s, file);
        !           780:     }
        !           781:     answer = shmat (id,0,0);
        !           782:     shmctl (id,IPC_RMID,NULL);
        !           783:     if (answer != (void*)-1) {
        !           784:        x = malloc (sizeof(shmpiece));
        !           785:        x->native_address = answer;
        !           786:        x->id = id;
        !           787:        x->size = s;
        !           788:        x->next = shm_start;
        !           789:        x->prev = NULL;
        !           790:        if (x->next)
        !           791:            x->next->prev = x;
        !           792:        shm_start = x;
        !           793: 
        !           794:        return answer;
        !           795:     }
        !           796:     canbang = 0;
        !           797:     return mapped_malloc (s, file);
        !           798: }
        !           799: 
        !           800: void mapped_free (uae_u8 base)
        !           801: {
        !           802:     shmpiece *x = find_shmpiece (base);
        !           803:     if (! x)
        !           804:        abort ();
        !           805:     shmdt (x->native_address);
        !           806: }
        !           807: 
1.1       root      808: #endif
1.1.1.6   root      809: 
1.1.1.9 ! root      810: static void init_mem_banks (void)
        !           811: {
        !           812:     int i;
        !           813:     for (i = 0; i < 65536; i++)
        !           814:        put_mem_bank (i << 16, &dummy_bank, 0);
        !           815: }
        !           816: 
        !           817: static void allocate_memory (void)
        !           818: {
        !           819:     if (allocated_chipmem != currprefs.chipmem_size) {
        !           820:        if (chipmemory)
        !           821:            mapped_free (chipmemory);
        !           822:        chipmemory = 0;
        !           823: 
        !           824:        allocated_chipmem = currprefs.chipmem_size;
        !           825:        chipmem_mask = allocated_chipmem - 1;
        !           826: 
        !           827:        chipmemory = mapped_malloc (allocated_chipmem, "chip");
        !           828:        if (chipmemory == 0) {
        !           829:            write_log ("Fatal error: out of memory for chipmem.\n");
        !           830:            allocated_chipmem = 0;
        !           831:        } else
        !           832:            do_put_mem_long ((uae_u32 *)(chipmemory + 4), 0);
        !           833:     }
        !           834: 
        !           835:     if (allocated_bogomem != currprefs.bogomem_size) {
        !           836:        if (bogomemory)
        !           837:            mapped_free (bogomemory);
        !           838:        bogomemory = 0;
        !           839: 
        !           840:        allocated_bogomem = currprefs.bogomem_size;
        !           841:        bogomem_mask = allocated_bogomem - 1;
        !           842: 
        !           843:        if (allocated_bogomem) {
        !           844:            bogomemory = mapped_malloc (allocated_bogomem, "bogo");
        !           845:            if (bogomemory == 0) {
        !           846:                write_log ("Out of memory for bogomem.\n");
        !           847:                allocated_bogomem = 0;
        !           848:            }
        !           849:        }
        !           850:     }
        !           851:     if (allocated_a3000mem != currprefs.a3000mem_size) {
        !           852:        if (a3000memory)
        !           853:            mapped_free (a3000memory);
        !           854:        a3000memory = 0;
        !           855: 
        !           856:        allocated_a3000mem = currprefs.a3000mem_size;
        !           857:        a3000mem_mask = allocated_a3000mem - 1;
        !           858: 
        !           859:        if (allocated_a3000mem) {
        !           860:            a3000memory = mapped_malloc (allocated_a3000mem, "a3000");
        !           861:            if (a3000memory == 0) {
        !           862:                write_log ("Out of memory for a3000mem.\n");
        !           863:                allocated_a3000mem = 0;
        !           864:            }
        !           865:        }
        !           866:     }
        !           867: 
        !           868:     if (savestate_state == STATE_RESTORE) {
        !           869:        fseek (savestate_file, chip_filepos, SEEK_SET);
        !           870:        fread (chipmemory, 1, allocated_chipmem, savestate_file);
        !           871:        if (allocated_bogomem > 0) {
        !           872:            fseek (savestate_file, bogo_filepos, SEEK_SET);
        !           873:            fread (bogomemory, 1, allocated_bogomem, savestate_file);
        !           874:        }
        !           875:     }
        !           876:     chipmem_bank.baseaddr = chipmemory;
        !           877:     bogomem_bank.baseaddr = bogomemory;
        !           878: }
        !           879: 
        !           880: void memory_reset (void)
        !           881: {
        !           882:     int i, custom_start;
        !           883: 
        !           884: #ifdef NATMEM_OFFSET
        !           885:     delete_shmmaps (0, 0xFFFF0000);
        !           886: #endif
1.1.1.4   root      887:     init_mem_banks ();
1.1.1.3   root      888: 
1.1.1.9 ! root      889:     currprefs.chipmem_size = changed_prefs.chipmem_size;
        !           890:     currprefs.bogomem_size = changed_prefs.bogomem_size;
        !           891:     currprefs.a3000mem_size = changed_prefs.a3000mem_size;
        !           892: 
        !           893:     allocate_memory ();
        !           894: 
        !           895:     /* Map the chipmem into all of the lower 8MB */
        !           896:     i = allocated_chipmem > 0x200000 ? (allocated_chipmem >> 16) : 32;
        !           897:     map_banks (&chipmem_bank, 0x00, i, allocated_chipmem);
        !           898: 
1.1.1.3   root      899:     custom_start = 0xC0;
1.1       root      900: 
1.1.1.9 ! root      901:     map_banks (&custom_bank, custom_start, 0xE0 - custom_start, 0);
        !           902:     map_banks (&cia_bank, 0xA0, 32, 0);
        !           903:     map_banks (&clock_bank, 0xDC, 1, 0);
1.1.1.3   root      904: 
                    905:     /* @@@ Does anyone have a clue what should be in the 0x200000 - 0xA00000
                    906:      * range on an Amiga without expansion memory?  */
1.1.1.4   root      907:     custom_start = allocated_chipmem >> 16;
1.1.1.3   root      908:     if (custom_start < 0x20)
                    909:        custom_start = 0x20;
1.1.1.9 ! root      910:     map_banks (&dummy_bank, custom_start, 0xA0 - custom_start, 0);
1.1.1.3   root      911:     /*map_banks (&mbres_bank, 0xDE, 1);*/
                    912: 
1.1.1.9 ! root      913:     if (bogomemory != 0) {
        !           914:        int t = allocated_bogomem >> 16;
        !           915:        if (t > 0x1C)
        !           916:            t = 0x1C;
        !           917:        map_banks (&bogomem_bank, 0xC0, t, allocated_bogomem);
        !           918:     }
1.1.1.4   root      919:     if (a3000memory != 0)
1.1.1.9 ! root      920:        map_banks (&a3000mem_bank, a3000mem_start >> 16, allocated_a3000mem >> 16,
        !           921:                   allocated_a3000mem);
        !           922: 
        !           923:     map_banks (&rtarea_bank, 0xF0, 1, 0);
        !           924: 
        !           925:     map_banks (&kickmem_bank, 0xF8, 8, 0);
        !           926:     map_banks (&expamem_bank, 0xE8, 1, 0);
        !           927: 
        !           928:     if (cloanto_rom)
        !           929:        map_banks (&kickmem_bank, 0xE0, 8, 0);
        !           930: }
        !           931: 
        !           932: void memory_init (void)
        !           933: {
        !           934:     allocated_chipmem = 0;
        !           935:     allocated_bogomem = 0;
        !           936:     allocated_a3000mem = 0;
        !           937:     kickmemory = 0;
        !           938:     chipmemory = 0;
        !           939:     a3000memory = 0;
        !           940:     bogomemory = 0;
        !           941: 
        !           942:     kickmemory = mapped_malloc (kickmem_size, "kick");
        !           943:     kickmem_bank.baseaddr = kickmemory;
1.1.1.3   root      944: 
1.1.1.4   root      945:     if (! load_kickstart ()) {
1.1.1.3   root      946:        init_ersatz_rom (kickmemory);
1.1       root      947:        ersatzkickfile = 1;
                    948:     }
1.1.1.3   root      949: 
1.1.1.9 ! root      950:     init_mem_banks ();
        !           951:     memory_reset ();
1.1.1.4   root      952: 
                    953:     kickmem_mask = kickmem_size - 1;
1.1       root      954: }
                    955: 
1.1.1.9 ! root      956: void map_banks (addrbank *bank, int start, int size, int realsize)
1.1       root      957: {
                    958:     int bnr;
1.1.1.3   root      959:     unsigned long int hioffs = 0, endhioffs = 0x100;
1.1.1.9 ! root      960:     int real_left;
        !           961:     addrbank* orgbank = bank;
        !           962:     uae_u32 realstart = start;
        !           963:     
        !           964:     flush_icache(1); /* Sure don't want to keep any old mappings around! */
        !           965: #ifdef NATMEM_OFFSET
        !           966:     delete_shmmaps (start << 16, size << 16);
        !           967: #endif
        !           968:  
        !           969:     if (!realsize)
        !           970:        realsize = size << 16;
        !           971:     real_left = 0;
        !           972: 
        !           973:     if ((size << 16) < realsize) {
        !           974:        fprintf (stderr, "Please report to [email protected], and mention:\n");
        !           975:        fprintf (stderr, "Broken mapping, size=%x, realsize=%x\n",size,realsize);
        !           976:        fprintf (stderr, "Start is %x\n",start);
        !           977:        fprintf (stderr, "Reducing memory sizes, especially chipmem, may fix this problem\n");
        !           978:        abort ();
        !           979:     }
1.1.1.3   root      980: 
                    981:     if (start >= 0x100) {
1.1.1.9 ! root      982:        for (bnr = start; bnr < start + size; bnr++) {
        !           983:            if (!real_left) {
        !           984:                realstart = bnr;
        !           985:                real_left = realsize>>16;
        !           986: #ifdef NATMEM_OFFSET
        !           987:                add_shmmaps (realstart << 16, bank);
        !           988: #endif
        !           989:            }
        !           990:            put_mem_bank (bnr << 16, bank, realstart<<16);
        !           991:            real_left--;
        !           992:        }
1.1.1.3   root      993:        return;
                    994:     }
1.1.1.9 ! root      995:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100) {
        !           996:        real_left=0;
        !           997:        for (bnr = start; bnr < start+size; bnr++) {
        !           998:            if (!real_left) {
        !           999:                realstart = bnr + hioffs;
        !          1000:                real_left = realsize >> 16;
        !          1001: #ifdef NATMEM_OFFSET
        !          1002:                add_shmmaps (realstart << 16, bank);
        !          1003: #endif
        !          1004:            }
        !          1005:            put_mem_bank((bnr + hioffs) << 16, bank,realstart<<16);
        !          1006:            real_left--;
        !          1007:        }
        !          1008:     }
        !          1009: }
        !          1010: 
        !          1011: 
        !          1012: /* memory save/restore code */
        !          1013: 
        !          1014: uae_u8 *save_cram (int *len)
        !          1015: {
        !          1016:     *len = allocated_chipmem;
        !          1017:     return chipmemory;
        !          1018: }
        !          1019: 
        !          1020: uae_u8 *save_bram (int *len)
        !          1021: {
        !          1022:     *len = allocated_bogomem;
        !          1023:     return bogomemory;
        !          1024: }
        !          1025: 
        !          1026: void restore_cram (int len, long filepos)
        !          1027: {
        !          1028:     chip_filepos = filepos;
        !          1029:     changed_prefs.chipmem_size = len;
        !          1030: }
        !          1031: 
        !          1032: void restore_bram (int len, long filepos)
        !          1033: {
        !          1034:     bogo_filepos = filepos;
        !          1035:     changed_prefs.bogomem_size = len;
        !          1036: }
        !          1037: 
        !          1038: uae_u8 *restore_rom (uae_u8 *src)
        !          1039: {
        !          1040:     restore_u32 ();
        !          1041:     restore_u32 ();
        !          1042:     restore_u32 ();
        !          1043:     restore_u32 ();
        !          1044:     restore_u32 ();
        !          1045: 
        !          1046:     return src;
        !          1047: }
        !          1048: 
        !          1049: uae_u8 *save_rom (int first, int *len)
        !          1050: {
        !          1051:     static int count;
        !          1052:     uae_u8 *dst, *dstbak;
        !          1053:     uae_u8 *mem_real_start;
        !          1054:     int mem_start, mem_size, mem_type, i, saverom;
        !          1055: 
        !          1056:     saverom = 0;
        !          1057:     if (first) count = 0;
        !          1058:     for (;;) {
        !          1059:        mem_type = count;
        !          1060:         switch (count)
        !          1061:            {
        !          1062:            case 0: /* Kickstart ROM */
        !          1063:            mem_start = 0xf80000;
        !          1064:            mem_real_start = kickmemory;
        !          1065:            mem_size = kickmem_size;
        !          1066:            /* 256KB or 512KB ROM? */
        !          1067:            for(i = 0; i < mem_size / 2 - 4; i++) {
        !          1068:                if(longget (i + mem_start) != longget(i + mem_start + mem_size / 2)) break;
        !          1069:            }
        !          1070:            if(i == mem_size / 2 - 4) {
        !          1071:                mem_size /= 2;
        !          1072:                mem_start += 262144;
        !          1073:            }
        !          1074:            mem_type = 0;
        !          1075:            break;
        !          1076:            default:
        !          1077:            return 0;
        !          1078:        }
        !          1079:         count++;
        !          1080:        if (mem_size) break;
        !          1081:     }
        !          1082:     dstbak = dst = malloc (4 + 4 + 4 + 4 + 4 + mem_size);
        !          1083:     save_u32 (mem_start);
        !          1084:     save_u32 (mem_size);
        !          1085:     save_u32 (mem_type);
        !          1086:     save_u32 (longget (mem_start + 12)); /* version+revision */
        !          1087:     save_u32 (0);
        !          1088:     sprintf (dst, "Kickstart %d.%d", wordget(mem_start + 12), wordget(mem_start + 14));
        !          1089:     dst += strlen (dst) + 1;
        !          1090:     if (saverom) {
        !          1091:        for(i = 0; i < mem_size; i++) *dst++ = byteget(mem_start + i);
        !          1092:     }
        !          1093:     *len = dst - dstbak;
        !          1094:     return dstbak;
1.1       root     1095: }

unix.superglobalmegacorp.com

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