home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD1.iso / Emulatoren / UAE061.LZH / uae-0.6.1 / memory.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-28  |  9.6 KB  |  422 lines

  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"
  14. #include "memory.h"
  15. #include "custom.h"
  16. #include "cia.h"
  17. #include "ersatz.h"
  18. #include "zfile.h"
  19.  
  20. int ersatzkickfile = 0;
  21.  
  22. int buserr;
  23. addrbank membanks[65536];
  24.  
  25. /* Default memory access functions */
  26.  
  27. int default_check(CPTR a, ULONG b)
  28. {
  29.     return 0;
  30. }
  31.  
  32. UWORD *default_xlate(CPTR a)
  33. {
  34.     fprintf(stderr, "Your Amiga program just did something terribly stupid\n");
  35.     return 0;
  36. }
  37.  
  38. /* A dummy bank that only contains zeros */
  39.  
  40. static ULONG dummy_lget(CPTR) REGPARAM;
  41. static UWORD dummy_wget(CPTR) REGPARAM;
  42. static UBYTE dummy_bget(CPTR) REGPARAM;
  43. static void  dummy_lput(CPTR, ULONG) REGPARAM;
  44. static void  dummy_wput(CPTR, UWORD) REGPARAM;
  45. static void  dummy_bput(CPTR, UBYTE) REGPARAM;
  46. static int   dummy_check(CPTR addr, ULONG size) REGPARAM;
  47. static UWORD *dummy_xlate(CPTR addr) REGPARAM;
  48.  
  49. ULONG dummy_lget(CPTR addr)
  50. {
  51.     return 0;
  52. }
  53.  
  54. UWORD dummy_wget(CPTR addr)
  55. {
  56.     return 0;
  57. }
  58.  
  59. UBYTE dummy_bget(CPTR addr)
  60. {
  61.     return 0;
  62. }
  63.  
  64. void dummy_lput(CPTR addr, ULONG l) { }
  65. void dummy_wput(CPTR addr, UWORD w) { }
  66. void dummy_bput(CPTR addr, UBYTE b) { }
  67.  
  68. int dummy_check(CPTR addr, ULONG size)
  69. {
  70.     return 0;
  71. }
  72.  
  73. UWORD *dummy_xlate(CPTR addr)
  74. {
  75.     return NULL;
  76. }
  77.  
  78. /* Chip memory */
  79.  
  80. UWORD *chipmemory;
  81.  
  82. static ULONG chipmem_lget(CPTR) REGPARAM;
  83. static UWORD chipmem_wget(CPTR) REGPARAM;
  84. static UBYTE chipmem_bget(CPTR) REGPARAM;
  85. static void  chipmem_lput(CPTR, ULONG) REGPARAM;
  86. static void  chipmem_wput(CPTR, UWORD) REGPARAM;
  87. static void  chipmem_bput(CPTR, UBYTE) REGPARAM;
  88. static int   chipmem_check(CPTR addr, ULONG size) REGPARAM;
  89. static UWORD *chipmem_xlate(CPTR addr) REGPARAM;
  90.  
  91. ULONG chipmem_lget(CPTR addr)
  92. {
  93.     addr -= chipmem_start & (chipmem_size-1);
  94.     addr &= chipmem_size-1;
  95.     return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
  96. }
  97.  
  98. UWORD chipmem_wget(CPTR addr)
  99. {
  100.     addr -= chipmem_start & (chipmem_size-1);
  101.     addr &= chipmem_size-1;
  102.     return chipmemory[addr >> 1];
  103. }
  104.  
  105. UBYTE chipmem_bget(CPTR addr)
  106. {
  107.     addr -= chipmem_start & (chipmem_size-1);
  108.     addr &= chipmem_size-1;
  109.     if (addr & 1) 
  110.     return chipmemory[addr >> 1];
  111.     else
  112.     return chipmemory[addr >> 1] >> 8;
  113. }
  114.  
  115. void chipmem_lput(CPTR addr, ULONG l)
  116. {
  117.     addr -= chipmem_start & (chipmem_size-1);
  118.     addr &= chipmem_size-1;
  119.     chipmemory[addr >> 1] = l >> 16;
  120.     chipmemory[(addr >> 1)+1] = (UWORD)l;
  121. }
  122.  
  123. void chipmem_wput(CPTR addr, UWORD w)
  124. {
  125.     addr -= chipmem_start & (chipmem_size-1);
  126.     addr &= chipmem_size-1;
  127.     chipmemory[addr >> 1] = w;
  128. }
  129.  
  130. void chipmem_bput(CPTR addr, UBYTE b)
  131. {
  132.     addr -= chipmem_start & (chipmem_size-1);
  133.     addr &= chipmem_size-1;
  134.     if (!(addr & 1)) {
  135.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  136.     } else {
  137.     chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
  138.     }
  139. }
  140.  
  141. int chipmem_check(CPTR addr, ULONG size)
  142. {
  143.     addr -= chipmem_start & (chipmem_size-1);
  144.     addr &= chipmem_size-1;
  145.     return (addr + size) < chipmem_size;
  146. }
  147.  
  148. UWORD *chipmem_xlate(CPTR addr)
  149. {
  150.     addr -= chipmem_start & (chipmem_size-1);
  151.     addr &= chipmem_size-1;
  152.     return chipmemory + (addr >> 1);
  153. }
  154.  
  155. /* Slow memory */
  156.  
  157. static UWORD *bogomemory;
  158.  
  159. static ULONG bogomem_lget(CPTR) REGPARAM;
  160. static UWORD bogomem_wget(CPTR) REGPARAM;
  161. static UBYTE bogomem_bget(CPTR) REGPARAM;
  162. static void  bogomem_lput(CPTR, ULONG) REGPARAM;
  163. static void  bogomem_wput(CPTR, UWORD) REGPARAM;
  164. static void  bogomem_bput(CPTR, UBYTE) REGPARAM;
  165. static int  bogomem_check(CPTR addr, ULONG size) REGPARAM;
  166. static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
  167.  
  168. ULONG bogomem_lget(CPTR addr)
  169. {
  170.     addr -= bogomem_start & (bogomem_size-1);
  171.     addr &= bogomem_size-1;
  172.     return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
  173. }
  174.  
  175. UWORD bogomem_wget(CPTR addr)
  176. {
  177.     addr -= bogomem_start & (bogomem_size-1);
  178.     addr &= bogomem_size-1;
  179.     return bogomemory[addr >> 1];
  180. }
  181.  
  182. UBYTE bogomem_bget(CPTR addr)
  183. {
  184.     addr -= bogomem_start & (bogomem_size-1);
  185.     addr &= bogomem_size-1;
  186.     if (addr & 1)
  187.     return bogomemory[addr >> 1];
  188.     else
  189.     return bogomemory[addr >> 1] >> 8;
  190. }
  191.  
  192. void bogomem_lput(CPTR addr, ULONG l)
  193. {
  194.     addr -= bogomem_start & (bogomem_size-1);
  195.     addr &= bogomem_size-1;
  196.     bogomemory[addr >> 1] = l >> 16;
  197.     bogomemory[(addr >> 1)+1] = (UWORD)l;
  198. }
  199.  
  200. void bogomem_wput(CPTR addr, UWORD w)
  201. {
  202.     addr -= bogomem_start & (bogomem_size-1);
  203.     addr &= bogomem_size-1;
  204.     bogomemory[addr >> 1] = w;
  205. }
  206.  
  207. void bogomem_bput(CPTR addr, UBYTE b)
  208. {
  209.     addr -= bogomem_start & (bogomem_size-1);
  210.     addr &= bogomem_size-1;
  211.     if (!(addr & 1)) {
  212.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
  213.     } else {
  214.     bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
  215.     }
  216. }
  217.  
  218. int bogomem_check(CPTR addr, ULONG size)
  219. {
  220.     addr -= bogomem_start & (bogomem_size-1);
  221.     addr &= bogomem_size-1;
  222.     return (addr + size) < bogomem_size;
  223. }
  224.  
  225. UWORD *bogomem_xlate(CPTR addr)
  226. {
  227.     addr -= bogomem_start & (bogomem_size-1);
  228.     addr &= bogomem_size-1;
  229.     return bogomemory + (addr >> 1);
  230. }
  231.  
  232. /* Kick memory */
  233.  
  234. static int zkickfile = 0;
  235. static UWORD kickmemory[kickmem_size/2];
  236.  
  237. static ULONG kickmem_lget(CPTR) REGPARAM;
  238. static UWORD kickmem_wget(CPTR) REGPARAM;
  239. static UBYTE kickmem_bget(CPTR) REGPARAM;
  240. static void  kickmem_lput(CPTR, ULONG) REGPARAM;
  241. static void  kickmem_wput(CPTR, UWORD) REGPARAM;
  242. static void  kickmem_bput(CPTR, UBYTE) REGPARAM;
  243. static int  kickmem_check(CPTR addr, ULONG size) REGPARAM;
  244. static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
  245.  
  246. ULONG kickmem_lget(CPTR addr)
  247. {
  248.     addr -= kickmem_start & (kickmem_size-1);
  249.     addr &= kickmem_size-1;
  250.     return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
  251. }
  252.  
  253. UWORD kickmem_wget(CPTR addr)
  254. {
  255.     addr -= kickmem_start & (kickmem_size-1);
  256.     addr &= kickmem_size-1;
  257.     return kickmemory[addr >> 1];
  258. }
  259.  
  260. UBYTE kickmem_bget(CPTR addr)
  261. {
  262.     addr -= kickmem_start & (kickmem_size-1);
  263.     addr &= kickmem_size-1;
  264.     return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
  265. }
  266.  
  267. void kickmem_lput(CPTR a, ULONG b)
  268. {
  269. }
  270.  
  271. void kickmem_wput(CPTR a, UWORD b)
  272. {
  273. }
  274.  
  275. void kickmem_bput(CPTR a, UBYTE b)
  276. {
  277. }
  278.  
  279. int kickmem_check(CPTR addr, ULONG size)
  280. {
  281.     addr -= kickmem_start & (kickmem_size-1);
  282.     addr &= kickmem_size-1;
  283.     return (addr + size) < kickmem_size;
  284. }
  285.  
  286. UWORD *kickmem_xlate(CPTR addr)
  287. {
  288.     addr -= kickmem_start & (kickmem_size-1);
  289.     addr &= kickmem_size-1;
  290.     return kickmemory + (addr >> 1);
  291. }
  292.  
  293. static int load_kickstart(void)
  294. {
  295.     int i;
  296.     ULONG cksum = 0, prevck = 0;
  297.     unsigned char buffer[8];
  298.     
  299.     FILE *f = zfile_open(romfile, "rb");
  300.     
  301.     if (f == NULL) {    
  302.         fprintf(stderr, "No Kickstart ROM found.\n");
  303.     return 0;
  304.     }
  305.     
  306.     fread(buffer, 1, 8, f);
  307.     if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
  308.     fprintf(stderr, "You seem to have a ZKick file there... You probably lose.\n");
  309.     zkickfile = 1;
  310.     } else 
  311.     fseek(f, 0, SEEK_SET);
  312.     
  313.     i = fread(kickmemory, 1, kickmem_size, f);
  314.     if (i == kickmem_size/2) {
  315.     fprintf(stderr, "Warning: Kickstart is only 256K.\n");
  316.     memcpy (kickmemory + kickmem_size/4, kickmemory, kickmem_size/2);
  317.     } else if (i != kickmem_size) {
  318.     fprintf(stderr, "Error while reading Kickstart.\n");
  319.     return 0;
  320.     }
  321.     zfile_close (f);
  322.     
  323.     for (i = 0; i < kickmem_size/2; i++) {
  324.     UWORD *p = kickmemory + i;
  325.     UBYTE *bp = (UBYTE *)p;
  326.     *p = (*bp << 8) | *(bp+1);
  327.     }
  328.  
  329.     for (i = 0; i < kickmem_size/4; i++) {
  330.     ULONG data = kickmemory[i*2]*65536 + kickmemory[i*2+1];
  331.     cksum += data;
  332.     if (cksum < prevck)
  333.         cksum++;
  334.     prevck = cksum;
  335.     }
  336.     if (cksum != 0xFFFFFFFF) {
  337.     fprintf(stderr, "Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
  338.     }
  339.     return 1;
  340. }
  341.  
  342. /* Address banks */
  343.  
  344. addrbank dummy_bank = {
  345.     dummy_lget, dummy_wget, dummy_bget,
  346.     dummy_lput, dummy_wput, dummy_bput,
  347.     dummy_xlate, dummy_check
  348. };
  349.  
  350. addrbank chipmem_bank = {
  351.     chipmem_lget, chipmem_wget, chipmem_bget,
  352.     chipmem_lput, chipmem_wput, chipmem_bput,
  353.     chipmem_xlate, chipmem_check
  354. };
  355.  
  356. addrbank bogomem_bank = {
  357.     bogomem_lget, bogomem_wget, bogomem_bget,
  358.     bogomem_lput, bogomem_wput, bogomem_bput,
  359.     bogomem_xlate, bogomem_check
  360. };
  361.  
  362. addrbank kickmem_bank = {
  363.     kickmem_lget, kickmem_wget, kickmem_bget,
  364.     kickmem_lput, kickmem_wput, kickmem_bput,
  365.     kickmem_xlate, kickmem_check
  366. };
  367.  
  368. void memory_init(void)
  369. {
  370.     int i;
  371.     buserr = 0;
  372.  
  373.     chipmemory = (UWORD *)malloc(chipmem_size);
  374.     if(!chipmemory) {
  375.        fprintf(stderr,"virtual memory exhausted !\n");
  376.        abort();
  377.     }
  378.     memset(chipmemory, 0, sizeof chipmemory);
  379.     
  380.     for(i = 0; i < 65536; i++)
  381.     membanks[i] = dummy_bank;
  382.     
  383.     /* Map the chipmem into all of the lower 16MB */
  384.     map_banks(chipmem_bank, 0x00, 256);
  385.     map_banks(custom_bank, 0xC0, 0x20);
  386.     map_banks(cia_bank, 0xA0, 32);
  387.     map_banks(clock_bank, 0xDC, 1);
  388.     
  389.     if (bogomem_size > 0) {
  390.     bogomemory = (UWORD *)malloc (bogomem_size);
  391.         if(!bogomemory) {
  392.            fprintf(stderr,"virtual memory exhausted !\n");
  393.            abort();
  394.         }
  395.         map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
  396.     }
  397.  
  398.     map_banks(rtarea_bank, 0xF0, 1); 
  399.     rtarea_init ();
  400.     if (!load_kickstart()) {
  401.     init_ersatz_rom(kickmemory);
  402.     ersatzkickfile = 1;
  403.     }
  404.     if (zkickfile)
  405.     map_banks(kickmem_bank, 0x20, 8);
  406.     
  407.     map_banks(kickmem_bank, 0xF8, 8);
  408.     if (!zkickfile)
  409.     map_banks(expamem_bank, 0xE8, 1);
  410. }
  411.  
  412. void map_banks(addrbank bank, int start, int size)
  413. {
  414.     int bnr;
  415.     int hioffs = 0;
  416. #if CPU_LEVEL < 2
  417.     for (hioffs = 0; hioffs < 256; hioffs++)
  418. #endif
  419.     for (bnr = start; bnr < start+size; bnr++) 
  420.         membanks[bnr + hioffs * 256] = bank;
  421. }
  422.