Annotation of hatari/src/uae-cpu/memory.c, revision 1.1.1.2

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Memory management
                      5:   *
                      6:   * (c) 1995 Bernd Schmidt
1.1.1.2 ! root        7:   *
        !             8:   * Adaptation to Hatari by Thomas Huth
1.1       root        9:   */
                     10: 
                     11: /*#include "sysconfig.h"*/
                     12: #include "sysdeps.h"
                     13: #include "hatari-glue.h"
                     14: #include "maccess.h"
                     15: #include "memory.h"
                     16: #include "../includes/tos.h"
                     17: /*
                     18: #include "config.h"
                     19: #include "options.h"
                     20: #include "uae.h"
                     21: */
                     22: #ifdef USE_MAPPED_MEMORY
                     23: #include <sys/mman.h>
                     24: #endif
                     25: 
                     26: #include "../includes/intercept.h"
                     27: 
                     28: 
                     29: extern   unsigned char STRam[16*1024*1024];  /* See hatari.c */
                     30: 
                     31: 
                     32: /* Set by each memory handler that does not simply access real memory.  */
                     33: int special_mem;
                     34: 
                     35: uae_u32 allocated_STmem;
                     36: uae_u32 allocated_TTmem;
                     37: 
                     38: uae_u32 STmem_mask, ROMmem_mask, IOmem_mask, TTmem_mask;
                     39: 
                     40: 
                     41: #ifdef SAVE_MEMORY_BANKS
                     42: addrbank *mem_banks[65536];
                     43: #else
                     44: addrbank mem_banks[65536];
                     45: #endif
                     46: 
                     47: #ifdef NO_INLINE_MEMORY_ACCESS
                     48: __inline__ uae_u32 longget (uaecptr addr)
                     49: {
                     50:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
                     51: }
                     52: __inline__ uae_u32 wordget (uaecptr addr)
                     53: {
                     54:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
                     55: }
                     56: __inline__ uae_u32 byteget (uaecptr addr)
                     57: {
                     58:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
                     59: }
                     60: __inline__ void longput (uaecptr addr, uae_u32 l)
                     61: {
                     62:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
                     63: }
                     64: __inline__ void wordput (uaecptr addr, uae_u32 w)
                     65: {
                     66:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
                     67: }
                     68: __inline__ void byteput (uaecptr addr, uae_u32 b)
                     69: {
                     70:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
                     71: }
                     72: #endif
                     73: 
                     74: 
                     75: /* A dummy bank that only contains zeros */
                     76: 
                     77: static uae_u32 dummy_lget (uaecptr) REGPARAM;
                     78: static uae_u32 dummy_wget (uaecptr) REGPARAM;
                     79: static uae_u32 dummy_bget (uaecptr) REGPARAM;
                     80: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
                     81: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
                     82: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
                     83: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
                     84: 
                     85: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
                     86: {
                     87:     special_mem |= S_READ;
                     88:     if (illegal_mem)
                     89:        write_log ("Illegal lget at %08lx\n", addr);
                     90: 
                     91:     return 0;
                     92: }
                     93: 
                     94: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
                     95: {
                     96:     special_mem |= S_READ;
                     97:     if (illegal_mem)
                     98:        write_log ("Illegal wget at %08lx\n", addr);
                     99: 
                    100:     return 0;
                    101: }
                    102: 
                    103: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
                    104: {
                    105:     special_mem |= S_READ;
                    106:     if (illegal_mem)
                    107:        write_log ("Illegal bget at %08lx\n", addr);
                    108: 
                    109:     return 0;
                    110: }
                    111: 
                    112: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
                    113: {
                    114:     special_mem |= S_WRITE;
                    115:     if (illegal_mem)
                    116:        write_log ("Illegal lput at %08lx\n", addr);
                    117: }
                    118: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
                    119: {
                    120:     special_mem |= S_WRITE;
                    121:     if (illegal_mem)
                    122:        write_log ("Illegal wput at %08lx\n", addr);
                    123: }
                    124: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
                    125: {
                    126:     special_mem |= S_WRITE;
                    127:     if (illegal_mem)
                    128:        write_log ("Illegal bput at %08lx\n", addr);
                    129: }
                    130: 
                    131: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
                    132: {
                    133:     if (illegal_mem)
                    134:        write_log ("Illegal check at %08lx\n", addr);
                    135: 
                    136:     return 0;
                    137: }
                    138: 
                    139: 
                    140: /* ST RAM memory */
                    141: 
                    142: uae_u8 *STmemory;
                    143: 
                    144: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    145: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
                    146: 
                    147: uae_u32 REGPARAM2 STmem_lget (uaecptr addr)
                    148: {
                    149:     uae_u32 *m;
                    150: 
                    151:     addr -= STmem_start & STmem_mask;
                    152:     addr &= STmem_mask;
                    153:     m = (uae_u32 *)(STmemory + addr);
                    154:     return do_get_mem_long (m);
                    155: }
                    156: 
                    157: uae_u32 REGPARAM2 STmem_wget (uaecptr addr)
                    158: {
                    159:     uae_u16 *m;
                    160: 
                    161:     addr -= STmem_start & STmem_mask;
                    162:     addr &= STmem_mask;
                    163:     m = (uae_u16 *)(STmemory + addr);
                    164:     return do_get_mem_word (m);
                    165: }
                    166: 
                    167: uae_u32 REGPARAM2 STmem_bget (uaecptr addr)
                    168: {
                    169:     addr -= STmem_start & STmem_mask;
                    170:     addr &= STmem_mask;
                    171:     return STmemory[addr];
                    172: }
                    173: 
                    174: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l)
                    175: {
                    176:     uae_u32 *m;
                    177: 
                    178:     addr -= STmem_start & STmem_mask;
                    179:     addr &= STmem_mask;
                    180:     m = (uae_u32 *)(STmemory + addr);
                    181:     do_put_mem_long (m, l);
                    182: }
                    183: 
                    184: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w)
                    185: {
                    186:     uae_u16 *m;
                    187: 
                    188:     addr -= STmem_start & STmem_mask;
                    189:     addr &= STmem_mask;
                    190:     m = (uae_u16 *)(STmemory + addr);
                    191:     do_put_mem_word (m, w);
                    192: }
                    193: 
                    194: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b)
                    195: {
                    196:     addr -= STmem_start & STmem_mask;
                    197:     addr &= STmem_mask;
                    198:     STmemory[addr] = b;
                    199: }
                    200: 
                    201: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size)
                    202: {
                    203:     addr -= STmem_start & STmem_mask;
                    204:     addr &= STmem_mask;
                    205:     return (addr + size) <= allocated_STmem;
                    206: }
                    207: 
                    208: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr)
                    209: {
                    210:     addr -= STmem_start & STmem_mask;
                    211:     addr &= STmem_mask;
                    212:     return STmemory + addr;
                    213: }
                    214: 
                    215: 
                    216: /* TT fast memory */
                    217: 
                    218: static uae_u8 *TTmemory;
                    219: 
                    220: static uae_u32 TTmem_lget (uaecptr) REGPARAM;
                    221: static uae_u32 TTmem_wget (uaecptr) REGPARAM;
                    222: static uae_u32 TTmem_bget (uaecptr) REGPARAM;
                    223: static void TTmem_lput (uaecptr, uae_u32) REGPARAM;
                    224: static void TTmem_wput (uaecptr, uae_u32) REGPARAM;
                    225: static void TTmem_bput (uaecptr, uae_u32) REGPARAM;
                    226: static int TTmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    227: static uae_u8 *TTmem_xlate (uaecptr addr) REGPARAM;
                    228: 
                    229: uae_u32 REGPARAM2 TTmem_lget (uaecptr addr)
                    230: {
                    231:     uae_u32 *m;
                    232:     addr -= TTmem_start & TTmem_mask;
                    233:     addr &= TTmem_mask;
                    234:     m = (uae_u32 *)(TTmemory + addr);
                    235:     return do_get_mem_long (m);
                    236: }
                    237: 
                    238: uae_u32 REGPARAM2 TTmem_wget (uaecptr addr)
                    239: {
                    240:     uae_u16 *m;
                    241:     addr -= TTmem_start & TTmem_mask;
                    242:     addr &= TTmem_mask;
                    243:     m = (uae_u16 *)(TTmemory + addr);
                    244:     return do_get_mem_word (m);
                    245: }
                    246: 
                    247: uae_u32 REGPARAM2 TTmem_bget (uaecptr addr)
                    248: {
                    249:     addr -= TTmem_start & TTmem_mask;
                    250:     addr &= TTmem_mask;
                    251:     return TTmemory[addr];
                    252: }
                    253: 
                    254: void REGPARAM2 TTmem_lput (uaecptr addr, uae_u32 l)
                    255: {
                    256:     uae_u32 *m;
                    257:     addr -= TTmem_start & TTmem_mask;
                    258:     addr &= TTmem_mask;
                    259:     m = (uae_u32 *)(TTmemory + addr);
                    260:     do_put_mem_long (m, l);
                    261: }
                    262: 
                    263: void REGPARAM2 TTmem_wput (uaecptr addr, uae_u32 w)
                    264: {
                    265:     uae_u16 *m;
                    266:     addr -= TTmem_start & TTmem_mask;
                    267:     addr &= TTmem_mask;
                    268:     m = (uae_u16 *)(TTmemory + addr);
                    269:     do_put_mem_word (m, w);
                    270: }
                    271: 
                    272: void REGPARAM2 TTmem_bput (uaecptr addr, uae_u32 b)
                    273: {
                    274:     addr -= TTmem_start & TTmem_mask;
                    275:     addr &= TTmem_mask;
                    276:     TTmemory[addr] = b;
                    277: }
                    278: 
                    279: int REGPARAM2 TTmem_check (uaecptr addr, uae_u32 size)
                    280: {
                    281:     addr -= TTmem_start & TTmem_mask;
                    282:     addr &= TTmem_mask;
                    283:     return (addr + size) <= allocated_TTmem;
                    284: }
                    285: 
                    286: uae_u8 REGPARAM2 *TTmem_xlate(uaecptr addr)
                    287: {
                    288:     addr -= TTmem_start & TTmem_mask;
                    289:     addr &= TTmem_mask;
                    290:     return TTmemory + addr;
                    291: }
                    292: 
                    293: /* ROM memory */
                    294: 
                    295: uae_u8 *ROMmemory;
                    296: 
                    297: static uae_u32 ROMmem_lget (uaecptr) REGPARAM;
                    298: static uae_u32 ROMmem_wget (uaecptr) REGPARAM;
                    299: static uae_u32 ROMmem_bget (uaecptr) REGPARAM;
                    300: static void  ROMmem_lput (uaecptr, uae_u32) REGPARAM;
                    301: static void  ROMmem_wput (uaecptr, uae_u32) REGPARAM;
                    302: static void  ROMmem_bput (uaecptr, uae_u32) REGPARAM;
                    303: static int  ROMmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    304: static uae_u8 *ROMmem_xlate (uaecptr addr) REGPARAM;
                    305: 
                    306: uae_u32 REGPARAM2 ROMmem_lget (uaecptr addr)
                    307: {
                    308:     uae_u32 *m;
                    309:     addr -= ROMmem_start & ROMmem_mask;
                    310:     addr &= ROMmem_mask;
                    311:     m = (uae_u32 *)(ROMmemory + addr);
                    312:     return do_get_mem_long (m);
                    313: }
                    314: 
                    315: uae_u32 REGPARAM2 ROMmem_wget (uaecptr addr)
                    316: {
                    317:     uae_u16 *m;
                    318:     addr -= ROMmem_start & ROMmem_mask;
                    319:     addr &= ROMmem_mask;
                    320:     m = (uae_u16 *)(ROMmemory + addr);
                    321:     return do_get_mem_word (m);
                    322: }
                    323: 
                    324: uae_u32 REGPARAM2 ROMmem_bget (uaecptr addr)
                    325: {
                    326:     addr -= ROMmem_start & ROMmem_mask;
                    327:     addr &= ROMmem_mask;
                    328:     return ROMmemory[addr];
                    329: }
                    330: 
                    331: void REGPARAM2 ROMmem_lput (uaecptr addr, uae_u32 b)
                    332: {
                    333:     if (illegal_mem)
                    334:        write_log ("Illegal ROMmem lput at %08lx\n", addr);
                    335: }
                    336: 
                    337: void REGPARAM2 ROMmem_wput (uaecptr addr, uae_u32 b)
                    338: {
                    339:     if (illegal_mem)
                    340:        write_log ("Illegal ROMmem wput at %08lx\n", addr);
                    341: }
                    342: 
                    343: void REGPARAM2 ROMmem_bput (uaecptr addr, uae_u32 b)
                    344: {
                    345:     if (illegal_mem)
                    346:        write_log ("Illegal ROMmem lput at %08lx\n", addr);
                    347: }
                    348: 
                    349: int REGPARAM2 ROMmem_check (uaecptr addr, uae_u32 size)
                    350: {
                    351:     addr -= ROMmem_start & ROMmem_mask;
                    352:     addr &= ROMmem_mask;
                    353:     return (addr + size) <= ROMmem_size;
                    354: }
                    355: 
                    356: uae_u8 REGPARAM2 *ROMmem_xlate (uaecptr addr)
                    357: {
                    358:     addr -= ROMmem_start & ROMmem_mask;
                    359:     addr &= ROMmem_mask;
                    360:     return ROMmemory + addr;
                    361: }
                    362: 
                    363: 
                    364: /* Hardware IO memory */
                    365: /* see also intercept.c */
                    366: 
                    367: uae_u8 *IOmemory;
                    368: 
                    369: static int  IOmem_check (uaecptr addr, uae_u32 size) REGPARAM;
                    370: static uae_u8 *IOmem_xlate (uaecptr addr) REGPARAM;
                    371: 
                    372: int REGPARAM2 IOmem_check (uaecptr addr, uae_u32 size)
                    373: {
                    374:     addr -= IOmem_start & IOmem_mask;
                    375:     addr &= IOmem_mask;
                    376:     return (addr + size) <= IOmem_size;
                    377: }
                    378: 
                    379: uae_u8 REGPARAM2 *IOmem_xlate (uaecptr addr)
                    380: {
                    381:     addr -= IOmem_start & IOmem_mask;
                    382:     addr &= IOmem_mask;
                    383:     return IOmemory + addr;
                    384: }
                    385: 
                    386: 
                    387: 
                    388: /* Default memory access functions */
                    389: 
                    390: int REGPARAM2 default_check (uaecptr a, uae_u32 b)
                    391: {
                    392:     return 0;
                    393: }
                    394: 
                    395: uae_u8 REGPARAM2 *default_xlate (uaecptr a)
                    396: {
                    397:     write_log ("Your Atari program just did something terribly stupid\n");
                    398:     Reset_Warm();
                    399:     return ROMmem_xlate (get_long (0xFC0000)); /* So we don't crash. */
                    400: }
                    401: 
                    402: 
                    403: /* Address banks */
                    404: 
                    405: addrbank dummy_bank = {
                    406:     dummy_lget, dummy_wget, dummy_bget,
                    407:     dummy_lput, dummy_wput, dummy_bput,
                    408:     default_xlate, dummy_check
                    409: };
                    410: 
                    411: addrbank STmem_bank = {
                    412:     STmem_lget, STmem_wget, STmem_bget,
                    413:     STmem_lput, STmem_wput, STmem_bput,
                    414:     STmem_xlate, STmem_check
                    415: };
                    416: 
                    417: addrbank TTmem_bank = {
                    418:     TTmem_lget, TTmem_wget, TTmem_bget,
                    419:     TTmem_lput, TTmem_wput, TTmem_bput,
                    420:     TTmem_xlate, TTmem_check
                    421: };
                    422: 
                    423: addrbank ROMmem_bank = {
                    424:     ROMmem_lget, ROMmem_wget, ROMmem_bget,
                    425:     ROMmem_lput, ROMmem_wput, ROMmem_bput,
                    426:     ROMmem_xlate, ROMmem_check
                    427: };
                    428: 
                    429: addrbank IOmem_bank = {
                    430:     Intercept_ReadLong, Intercept_ReadWord, Intercept_ReadByte,
                    431:     Intercept_WriteLong, Intercept_WriteWord, Intercept_WriteByte,
                    432:     IOmem_xlate, IOmem_check
                    433: };
                    434: 
                    435: 
                    436: char *address_space, *good_address_map;
                    437: int good_address_fd;
                    438: 
                    439: static void init_mem_banks (void)
                    440: {
                    441:     int i;
                    442:     for (i = 0; i < 65536; i++)
                    443:        put_mem_bank (i<<16, &dummy_bank);
                    444: }
                    445: 
                    446: #define MAKE_USER_PROGRAMS_BEHAVE 1
                    447: void memory_init (void)
                    448: {
                    449:     char buffer[4096];
                    450:     char *nam;
                    451:     int i, fd;
                    452: 
                    453:     allocated_STmem = STmem_size;
                    454:     allocated_TTmem = TTmem_size;
                    455: 
                    456: #ifdef USE_MAPPED_MEMORY
                    457: #error So nicht
                    458:     fd = open ("/dev/zero", O_RDWR);
                    459:     good_address_map = mmap (NULL, 1 << 24, PROT_READ, MAP_PRIVATE, fd, 0);
                    460:     /* Don't believe USER_PROGRAMS_BEHAVE. Otherwise, we'd segfault as soon
                    461:      * as a decrunch routine tries to do color register hacks. */
                    462:     address_space = mmap (NULL, 1 << 24, PROT_READ | (USER_PROGRAMS_BEHAVE || MAKE_USER_PROGRAMS_BEHAVE? PROT_WRITE : 0), MAP_PRIVATE, fd, 0);
                    463:     if ((int)address_space < 0 || (int)good_address_map < 0) {
                    464:        write_log ("Your system does not have enough virtual memory - increase swap.\n");
                    465:        abort ();
                    466:     }
                    467: #ifdef MAKE_USER_PROGRAMS_BEHAVE
                    468:     memset (address_space + 0xDFF180, 0xFF, 32*2);
                    469: #else
                    470:     /* Likewise. This is mostly for mouse button checks. */
                    471:     if (USER_PROGRAMS_BEHAVE)
                    472:        memset (address_space + 0xA00000, 0xFF, 0xF00000 - 0xA00000);
                    473: #endif
                    474:     STmemory = mmap (address_space, 0x200000, PROT_READ|PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0);
1.1.1.2 ! root      475:     ROMmemory = mmap (address_space + ROMmem_start, ROMmem_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, fd, 0);
1.1       root      476: 
                    477:     close(fd);
                    478: 
                    479:     good_address_fd = open (nam = tmpnam (NULL), O_CREAT|O_RDWR, 0600);
                    480:     memset (buffer, 1, sizeof(buffer));
                    481:     write (good_address_fd, buffer, sizeof buffer);
                    482:     unlink (nam);
                    483: 
                    484:     for (i = 0; i < allocated_STmem; i += 4096)
                    485:        mmap (good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE,
                    486:              good_address_fd, 0);
                    487:     for (i = 0; i < ROMmem_size; i += 4096)
                    488:        mmap (good_address_map + i + 0x1000000 - ROMmem_size, 4096, PROT_READ,
                    489:              MAP_FIXED | MAP_PRIVATE, good_address_fd, 0);
                    490: #else
1.1.1.2 ! root      491:     ROMmemory = STRam+ROMmem_start;  /*(uae_u8 *)malloc (ROMmem_size)*/;
1.1       root      492:     STmemory = STRam; /*(uae_u8 *)malloc (allocated_STmem);*/
                    493: /*
                    494:     while (! STmemory && allocated_STmem > 512*1024) {
                    495:        allocated_STmem >>= 1;
                    496:        STmemory = (uae_u8 *)malloc (allocated_STmem);
                    497:        if (STmemory)
                    498:            fprintf (stderr, "Reducing STmem size to %dkb\n", allocated_STmem >> 10);
                    499:     }
                    500:     if (! STmemory) {
                    501:        write_log ("virtual memory exhausted (STmemory)!\n");
                    502:        abort ();
                    503:     }
                    504: */
                    505: #endif
                    506: 
                    507:     init_mem_banks ();
                    508: 
                    509:     /* Map the STmem into all of the lower 16MB */
                    510:     map_banks (&STmem_bank, 0x00, 256);
                    511: 
                    512:     if (allocated_TTmem > 0)
                    513:        TTmemory = (uae_u8 *)malloc (allocated_TTmem);
                    514:     if (TTmemory != 0)
                    515:        map_banks (&TTmem_bank, TTmem_start >> 16, allocated_TTmem >> 16);
                    516:     else
                    517:        allocated_TTmem = 0;
                    518: 
                    519:     map_banks(&ROMmem_bank, ROMmem_start >> 16, ROMmem_size/65536);
                    520: /*    map_banks(&ROMmem_bank, 0xFFFC, 4);*/
                    521: 
                    522:     map_banks(&IOmem_bank, IOmem_start>>16, 1);
                    523: 
1.1.1.2 ! root      524:     STmem_mask = 0x00ffffff;
        !           525:     ROMmem_mask = 0x00ffffff;
1.1       root      526:     TTmem_mask = allocated_TTmem - 1;
                    527:     IOmem_mask = IOmem_size - 1;
                    528: }
                    529: 
                    530: void map_banks (addrbank *bank, int start, int size)
                    531: {
                    532:     int bnr;
                    533:     unsigned long int hioffs = 0, endhioffs = 0x100;
                    534: 
                    535:     if (start >= 0x100) {
                    536:        for (bnr = start; bnr < start + size; bnr++)
                    537:            put_mem_bank (bnr << 16, bank);
                    538:        return;
                    539:     }
                    540:     /* Some ROMs apparently require a 24 bit address space... */
                    541:     if (address_space_24)
                    542:        endhioffs = 0x10000;
                    543:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
                    544:        for (bnr = start; bnr < start+size; bnr++)
                    545:            put_mem_bank ((bnr + hioffs) << 16, bank);
                    546: }

unix.superglobalmegacorp.com

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