Annotation of frontvm/cpu/memory.c, revision 1.1

1.1     ! root        1:  /*
        !             2:   * UAE - The Un*x Amiga Emulator - CPU core
        !             3:   *
        !             4:   * Memory management
        !             5:   *
        !             6:   * (c) 1995 Bernd Schmidt
        !             7:   *
        !             8:   * Adaptation to Hatari by Thomas Huth
        !             9:   *
        !            10:   * This file is distributed under the GNU Public License, version 2 or at
        !            11:   * your option any later version. Read the file gpl.txt for details.
        !            12:   */
        !            13: static char rcsid[] = "Hatari $Id: memory.c,v 1.12 2003/04/05 22:25:03 thothy Exp $";
        !            14: 
        !            15: #include "sysdeps.h"
        !            16: #include "hatari-glue.h"
        !            17: #include "maccess.h"
        !            18: #include "memory.h"
        !            19: #include "../hardware/main.h"
        !            20: #include "../hardware/reset.h"
        !            21: #include "../hardware/decode.h"
        !            22: #include "../hardware/m68000.h"
        !            23: #include "newcpu.h"
        !            24: 
        !            25: 
        !            26: uae_u32 STmem_size;
        !            27: 
        !            28: #define STmem_start  0x00000000
        !            29: 
        !            30: #define STmem_mask  0x00ffffff
        !            31: 
        !            32: 
        !            33: #ifdef SAVE_MEMORY_BANKS
        !            34: addrbank *mem_banks[65536];
        !            35: #else
        !            36: addrbank mem_banks[65536];
        !            37: #endif
        !            38: 
        !            39: #ifdef NO_INLINE_MEMORY_ACCESS
        !            40: __inline__ uae_u32 longget (uaecptr addr)
        !            41: {
        !            42:     return call_mem_get_func (get_mem_bank (addr).lget, addr);
        !            43: }
        !            44: __inline__ uae_u32 wordget (uaecptr addr)
        !            45: {
        !            46:     return call_mem_get_func (get_mem_bank (addr).wget, addr);
        !            47: }
        !            48: __inline__ uae_u32 byteget (uaecptr addr)
        !            49: {
        !            50:     return call_mem_get_func (get_mem_bank (addr).bget, addr);
        !            51: }
        !            52: __inline__ void longput (uaecptr addr, uae_u32 l)
        !            53: {
        !            54:     call_mem_put_func (get_mem_bank (addr).lput, addr, l);
        !            55: }
        !            56: __inline__ void wordput (uaecptr addr, uae_u32 w)
        !            57: {
        !            58:     call_mem_put_func (get_mem_bank (addr).wput, addr, w);
        !            59: }
        !            60: __inline__ void byteput (uaecptr addr, uae_u32 b)
        !            61: {
        !            62:     call_mem_put_func (get_mem_bank (addr).bput, addr, b);
        !            63: }
        !            64: #endif
        !            65: 
        !            66: 
        !            67: /* Some prototypes: */
        !            68: static int STmem_check (uaecptr addr, uae_u32 size) REGPARAM;
        !            69: static uae_u8 *STmem_xlate (uaecptr addr) REGPARAM;
        !            70: 
        !            71: 
        !            72: /* A dummy bank that only contains zeros */
        !            73: 
        !            74: static uae_u32 dummy_lget (uaecptr) REGPARAM;
        !            75: static uae_u32 dummy_wget (uaecptr) REGPARAM;
        !            76: static uae_u32 dummy_bget (uaecptr) REGPARAM;
        !            77: static void dummy_lput (uaecptr, uae_u32) REGPARAM;
        !            78: static void dummy_wput (uaecptr, uae_u32) REGPARAM;
        !            79: static void dummy_bput (uaecptr, uae_u32) REGPARAM;
        !            80: static int dummy_check (uaecptr addr, uae_u32 size) REGPARAM;
        !            81: 
        !            82: uae_u32 REGPARAM2 dummy_lget (uaecptr addr)
        !            83: {
        !            84:     if (illegal_mem)
        !            85:        write_log ("Illegal lget at %08lx\n", (long)addr);
        !            86: 
        !            87:     return 0;
        !            88: }
        !            89: 
        !            90: uae_u32 REGPARAM2 dummy_wget (uaecptr addr)
        !            91: {
        !            92:     if (illegal_mem)
        !            93:        write_log ("Illegal wget at %08lx\n", (long)addr);
        !            94: 
        !            95:     return 0;
        !            96: }
        !            97: 
        !            98: uae_u32 REGPARAM2 dummy_bget (uaecptr addr)
        !            99: {
        !           100:     if (illegal_mem)
        !           101:        write_log ("Illegal bget at %08lx\n", (long)addr);
        !           102: 
        !           103:     return 0;
        !           104: }
        !           105: 
        !           106: void REGPARAM2 dummy_lput (uaecptr addr, uae_u32 l)
        !           107: {
        !           108:     if (illegal_mem)
        !           109:        write_log ("Illegal lput at %08lx\n", (long)addr);
        !           110: }
        !           111: 
        !           112: void REGPARAM2 dummy_wput (uaecptr addr, uae_u32 w)
        !           113: {
        !           114:     if (illegal_mem)
        !           115:        write_log ("Illegal wput at %08lx\n", (long)addr);
        !           116: }
        !           117: 
        !           118: void REGPARAM2 dummy_bput (uaecptr addr, uae_u32 b)
        !           119: {
        !           120:     if (illegal_mem)
        !           121:        write_log ("Illegal bput at %08lx\n", (long)addr);
        !           122: }
        !           123: 
        !           124: int REGPARAM2 dummy_check (uaecptr addr, uae_u32 size)
        !           125: {
        !           126:     if (illegal_mem)
        !           127:        write_log ("Illegal check at %08lx\n", (long)addr);
        !           128: 
        !           129:     return 0;
        !           130: }
        !           131: 
        !           132: uae_u8 REGPARAM2 *dummy_xlate (uaecptr addr)
        !           133: {
        !           134:     write_log("Your Atari program just did something terribly stupid:"
        !           135:               " dummy_xlate($%x)\n", addr);
        !           136:     /*Reset_Warm();*/
        !           137:     return STmem_xlate(addr);  /* So we don't crash. */
        !           138: }
        !           139: 
        !           140: 
        !           141: /* **** This memory bank only generates bus errors **** */
        !           142: 
        !           143: uae_u32 REGPARAM2 BusErrMem_lget(uaecptr addr)
        !           144: {
        !           145:     if (illegal_mem)
        !           146:        write_log ("Bus error lget at %08lx\n", (long)addr);
        !           147: 
        !           148:     M68000_Crash (2);
        !           149:     return 0;
        !           150: }
        !           151: 
        !           152: uae_u32 REGPARAM2 BusErrMem_wget(uaecptr addr)
        !           153: {
        !           154:     if (illegal_mem)
        !           155:        write_log ("Bus error wget at %08lx\n", (long)addr);
        !           156: 
        !           157:     M68000_Crash (2);
        !           158:     return 0;
        !           159: }
        !           160: 
        !           161: uae_u32 REGPARAM2 BusErrMem_bget(uaecptr addr)
        !           162: {
        !           163:     if (illegal_mem)
        !           164:        write_log ("Bus error bget at %08lx\n", (long)addr);
        !           165: 
        !           166:     M68000_Crash (2);
        !           167:     return 0;
        !           168: }
        !           169: 
        !           170: void REGPARAM2 BusErrMem_lput(uaecptr addr, uae_u32 l)
        !           171: {
        !           172:     if (illegal_mem)
        !           173:        write_log ("Bus error lput at %08lx\n", (long)addr);
        !           174: 
        !           175:     M68000_Crash (2);
        !           176: }
        !           177: 
        !           178: void REGPARAM2 BusErrMem_wput(uaecptr addr, uae_u32 w)
        !           179: {
        !           180:     if (illegal_mem)
        !           181:        write_log ("Bus error wput at %08lx\n", (long)addr);
        !           182: 
        !           183:     M68000_Crash (2);
        !           184: }
        !           185: 
        !           186: void REGPARAM2 BusErrMem_bput(uaecptr addr, uae_u32 b)
        !           187: {
        !           188:     if (illegal_mem)
        !           189:        write_log ("Bus error bput at %08lx\n", (long)addr);
        !           190: 
        !           191:     M68000_Crash (2);
        !           192: }
        !           193: 
        !           194: int REGPARAM2 BusErrMem_check(uaecptr addr, uae_u32 size)
        !           195: {
        !           196:     if (illegal_mem)
        !           197:        write_log ("Bus error check at %08lx\n", (long)addr);
        !           198: 
        !           199:     return 0;
        !           200: }
        !           201: 
        !           202: uae_u8 REGPARAM2 *BusErrMem_xlate (uaecptr addr)
        !           203: {
        !           204:     write_log("Your Atari program just did something terribly stupid:"
        !           205:               " BusErrMem_xlate($%x)\n", addr);
        !           206: 
        !           207:     /*M68000_Crash (2);*/
        !           208:     return STmem_xlate(addr);  /* So we don't crash. */
        !           209: }
        !           210: 
        !           211: 
        !           212: /* **** ST RAM memory **** */
        !           213: 
        !           214: uae_u8 *STmemory;
        !           215: 
        !           216: uae_u32 REGPARAM2 STmem_lget (uaecptr addr)
        !           217: {
        !           218:     uae_u32 *m;
        !           219: 
        !           220:     addr -= STmem_start & STmem_mask;
        !           221:     addr &= STmem_mask;
        !           222:     m = (uae_u32 *)(STmemory + addr);
        !           223:     return do_get_mem_long (m);
        !           224: }
        !           225: 
        !           226: uae_u32 REGPARAM2 STmem_wget (uaecptr addr)
        !           227: {
        !           228:     uae_u16 *m;
        !           229: 
        !           230:     addr -= STmem_start & STmem_mask;
        !           231:     addr &= STmem_mask;
        !           232:     m = (uae_u16 *)(STmemory + addr);
        !           233:     return do_get_mem_word (m);
        !           234: }
        !           235: 
        !           236: uae_u32 REGPARAM2 STmem_bget (uaecptr addr)
        !           237: {
        !           238:     addr -= STmem_start & STmem_mask;
        !           239:     addr &= STmem_mask;
        !           240:     return STmemory[addr];
        !           241: }
        !           242: 
        !           243: void REGPARAM2 STmem_lput (uaecptr addr, uae_u32 l)
        !           244: {
        !           245:     uae_u32 *m;
        !           246: 
        !           247:     addr -= STmem_start & STmem_mask;
        !           248:     addr &= STmem_mask;
        !           249:     m = (uae_u32 *)(STmemory + addr);
        !           250:     do_put_mem_long (m, l);
        !           251: }
        !           252: 
        !           253: void REGPARAM2 STmem_wput (uaecptr addr, uae_u32 w)
        !           254: {
        !           255:     uae_u16 *m;
        !           256: 
        !           257:     addr -= STmem_start & STmem_mask;
        !           258:     addr &= STmem_mask;
        !           259:     m = (uae_u16 *)(STmemory + addr);
        !           260:     do_put_mem_word (m, w);
        !           261: }
        !           262: 
        !           263: void REGPARAM2 STmem_bput (uaecptr addr, uae_u32 b)
        !           264: {
        !           265:     addr -= STmem_start & STmem_mask;
        !           266:     addr &= STmem_mask;
        !           267:     STmemory[addr] = b;
        !           268: }
        !           269: 
        !           270: int REGPARAM2 STmem_check (uaecptr addr, uae_u32 size)
        !           271: {
        !           272:     addr -= STmem_start & STmem_mask;
        !           273:     addr &= STmem_mask;
        !           274:     return (addr + size) <= STmem_size;
        !           275: }
        !           276: 
        !           277: uae_u8 REGPARAM2 *STmem_xlate (uaecptr addr)
        !           278: {
        !           279:     addr -= STmem_start & STmem_mask;
        !           280:     addr &= STmem_mask;
        !           281:     return STmemory + addr;
        !           282: }
        !           283: 
        !           284: 
        !           285: /*
        !           286:  * **** ST RAM system memory ****
        !           287:  * We need a separate mem bank for this region since the first 0x800 bytes on
        !           288:  * the ST can only be accessed in supervisor mode. Note that the very first
        !           289:  * 8 bytes of the ST memory are also a mirror of the TOS ROM, so they are write
        !           290:  * protected!
        !           291:  */
        !           292: uae_u32 REGPARAM2 SysMem_lget(uaecptr addr)
        !           293: {
        !           294:     uae_u32 *m;
        !           295: 
        !           296:     addr -= STmem_start & STmem_mask;
        !           297:     addr &= STmem_mask;
        !           298:     m = (uae_u32 *)(STmemory + addr);
        !           299:     return do_get_mem_long (m);
        !           300: }
        !           301: 
        !           302: uae_u32 REGPARAM2 SysMem_wget(uaecptr addr)
        !           303: {
        !           304:     uae_u16 *m;
        !           305: 
        !           306:     addr -= STmem_start & STmem_mask;
        !           307:     addr &= STmem_mask;
        !           308:     m = (uae_u16 *)(STmemory + addr);
        !           309:     return do_get_mem_word (m);
        !           310: }
        !           311: 
        !           312: uae_u32 REGPARAM2 SysMem_bget(uaecptr addr)
        !           313: {
        !           314:     addr -= STmem_start & STmem_mask;
        !           315:     addr &= STmem_mask;
        !           316:     return STmemory[addr];
        !           317: }
        !           318: 
        !           319: void REGPARAM2 SysMem_lput(uaecptr addr, uae_u32 l)
        !           320: {
        !           321:     uae_u32 *m;
        !           322: 
        !           323:     addr -= STmem_start & STmem_mask;
        !           324:     addr &= STmem_mask;
        !           325:     m = (uae_u32 *)(STmemory + addr);
        !           326:     do_put_mem_long (m, l);
        !           327: }
        !           328: 
        !           329: void REGPARAM2 SysMem_wput(uaecptr addr, uae_u32 w)
        !           330: {
        !           331:     uae_u16 *m;
        !           332: 
        !           333:     addr -= STmem_start & STmem_mask;
        !           334:     addr &= STmem_mask;
        !           335:     m = (uae_u16 *)(STmemory + addr);
        !           336:     do_put_mem_word (m, w);
        !           337: }
        !           338: 
        !           339: void REGPARAM2 SysMem_bput(uaecptr addr, uae_u32 b)
        !           340: {
        !           341:     addr -= STmem_start & STmem_mask;
        !           342:     addr &= STmem_mask;
        !           343:     STmemory[addr] = b;
        !           344: }
        !           345: 
        !           346: 
        !           347: /*
        !           348:  * **** Void memory ****
        !           349:  * Between the ST-RAM end and the 4 MB barrier, there is a void memory space:
        !           350:  * Reading always returns the same value and writing does nothing at all.
        !           351:  */
        !           352: 
        !           353: uae_u32 REGPARAM2 VoidMem_lget(uaecptr addr)
        !           354: {
        !           355:     return 0;
        !           356: }
        !           357: 
        !           358: uae_u32 REGPARAM2 VoidMem_wget(uaecptr addr)
        !           359: {
        !           360:     return 0;
        !           361: }
        !           362: 
        !           363: uae_u32 REGPARAM2 VoidMem_bget(uaecptr addr)
        !           364: {
        !           365:     return 0;
        !           366: }
        !           367: 
        !           368: void REGPARAM2 VoidMem_lput(uaecptr addr, uae_u32 l)
        !           369: {
        !           370: }
        !           371: 
        !           372: void REGPARAM2 VoidMem_wput(uaecptr addr, uae_u32 w)
        !           373: {
        !           374: }
        !           375: 
        !           376: void REGPARAM2 VoidMem_bput (uaecptr addr, uae_u32 b)
        !           377: {
        !           378: }
        !           379: 
        !           380: int REGPARAM2 VoidMem_check(uaecptr addr, uae_u32 size)
        !           381: {
        !           382:     if (illegal_mem)
        !           383:        write_log ("Void memory check at %08lx\n", (long)addr);
        !           384: 
        !           385:     return 0;
        !           386: }
        !           387: 
        !           388: uae_u8 REGPARAM2 *VoidMem_xlate (uaecptr addr)
        !           389: {
        !           390:     write_log("Your Atari program just did something terribly stupid:"
        !           391:               " VoidMem_xlate($%x)\n", addr);
        !           392: 
        !           393:     return STmem_xlate(addr);  /* So we don't crash. */
        !           394: }
        !           395: 
        !           396: 
        !           397: /* **** Address banks **** */
        !           398: 
        !           399: addrbank dummy_bank = {
        !           400:     dummy_lget, dummy_wget, dummy_bget,
        !           401:     dummy_lput, dummy_wput, dummy_bput,
        !           402:     dummy_xlate, dummy_check
        !           403: };
        !           404: 
        !           405: addrbank BusErrMem_bank = {
        !           406:     BusErrMem_lget, BusErrMem_wget, BusErrMem_bget,
        !           407:     BusErrMem_lput, BusErrMem_wput, BusErrMem_bput,
        !           408:     BusErrMem_xlate, BusErrMem_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 SysMem_bank = {
        !           418:     SysMem_lget, SysMem_wget, SysMem_bget,
        !           419:     SysMem_lput, SysMem_wput, SysMem_bput,
        !           420:     STmem_xlate, STmem_check
        !           421: };
        !           422: 
        !           423: addrbank VoidMem_bank = {
        !           424:     VoidMem_lget, VoidMem_wget, VoidMem_bget,
        !           425:     VoidMem_lput, VoidMem_wput, VoidMem_bput,
        !           426:     VoidMem_xlate, VoidMem_check
        !           427: };
        !           428: 
        !           429: 
        !           430: char *address_space, *good_address_map;
        !           431: int good_address_fd;
        !           432: 
        !           433: 
        !           434: static void init_mem_banks (void)
        !           435: {
        !           436:     int i;
        !           437:     for (i = 0; i < 65536; i++)
        !           438:        put_mem_bank (i<<16, &dummy_bank);
        !           439: }
        !           440: 
        !           441: 
        !           442: /*
        !           443:  * Initialize the memory banks
        !           444:  */
        !           445: void memory_init(uae_u32 f_STMemSize, uae_u32 f_TTMemSize, uae_u32 f_RomMemStart)
        !           446: {
        !           447:     STmem_size = (f_STMemSize + 65535) & 0xFFFF0000;
        !           448: 
        !           449:     /*write_log("memory_init: STmem_size=$%x, TTmem_size=$%x, ROM-Start=$%x,\n",
        !           450:               STmem_size, TTmem_size, f_RomMemStart);*/
        !           451: 
        !           452:     STmemory = STRam;
        !           453: /*
        !           454:     while (! STmemory && STmem_size > 512*1024) {
        !           455:        STmem_size >>= 1;
        !           456:        STmemory = (uae_u8 *)malloc (STmem_size);
        !           457:        if (STmemory)
        !           458:            fprintf (stderr, "Reducing STmem size to %dkb\n", STmem_size >> 10);
        !           459:     }
        !           460:     if (! STmemory) {
        !           461:        write_log ("virtual memory exhausted (STmemory)!\n");
        !           462:        abort ();
        !           463:     }
        !           464: */
        !           465: 
        !           466:     init_mem_banks();
        !           467: 
        !           468:     /* Map the ST RAM: */
        !           469:     map_banks(&SysMem_bank, 0x00, 1);
        !           470:     map_banks(&VoidMem_bank, 0x08, 0x38);  /* Between STRamEnd and 4MB barrier, there is void space! */
        !           471:     map_banks(&STmem_bank, 0x01, (STmem_size >> 16) - 1);
        !           472: 
        !           473:     /* Illegal memory regions cause a bus error on the ST: */
        !           474:     map_banks(&BusErrMem_bank, 0x200000 >> 16, 0xbf); /* Everything above 2mb */
        !           475: }
        !           476: 
        !           477: 
        !           478: /*
        !           479:  * Uninitialize the memory banks.
        !           480:  */
        !           481: void memory_uninit (void)
        !           482: {
        !           483:     /* Here, we free allocated memory from memory_init */
        !           484: }
        !           485: 
        !           486: 
        !           487: void map_banks (addrbank *bank, int start, int size)
        !           488: {
        !           489:     int bnr;
        !           490:     unsigned long int hioffs = 0, endhioffs = 0x100;
        !           491: 
        !           492:     if (start >= 0x100) {
        !           493:        for (bnr = start; bnr < start + size; bnr++)
        !           494:            put_mem_bank (bnr << 16, bank);
        !           495:        return;
        !           496:     }
        !           497:     /* Some ROMs apparently require a 24 bit address space... */
        !           498:     if (address_space_24)
        !           499:        endhioffs = 0x10000;
        !           500:     for (hioffs = 0; hioffs < endhioffs; hioffs += 0x100)
        !           501:        for (bnr = start; bnr < start+size; bnr++)
        !           502:            put_mem_bank ((bnr + hioffs) << 16, bank);
        !           503: }

unix.superglobalmegacorp.com