/ MCUME_teensy / teensyuae / memory.c
memory.c
  1   /*
  2    * UAE - The Un*x Amiga Emulator
  3    *
  4    * Memory management
  5    *
  6    * (c) 1995 Bernd Schmidt
  7    */
  8  
  9  #include "shared.h"
 10  
 11  #include "memory.h"
 12  #include "custom.h"
 13  #include "cia.h"
 14  #ifdef HAS_ERSATZ  
 15  #include "ersatz.h"
 16  int ersatzkickfile = 0;
 17  #endif
 18  
 19  #define HALF_CHIPMEM   1
 20  
 21  #define HALF_KICKIMAGE 1
 22  
 23  int buserr;
 24  addrbank membanks[256];
 25  
 26  
 27  /* Default memory access functions */
 28  
 29  int default_check(CPTR a, ULONG b)
 30  {
 31      return 0;
 32  }
 33  
 34  UWORD *default_xlate(CPTR a)
 35  {
 36      emu_printf("Your Amiga program just did something terribly stupid\n");
 37      return 0;
 38  }
 39  
 40  /* A dummy bank that only contains zeros */
 41  
 42  ULONG dummy_lget(CPTR addr)
 43  {
 44      return 0;
 45  }
 46  
 47  UWORD dummy_wget(CPTR addr)
 48  {
 49      return 0;
 50  }
 51  
 52  UBYTE dummy_bget(CPTR addr)
 53  {
 54      return 0;
 55  }
 56  
 57  void dummy_lput(CPTR addr, ULONG l)
 58  {
 59  }
 60  
 61  void dummy_wput(CPTR addr, UWORD w)
 62  {
 63  }
 64  
 65  void dummy_bput(CPTR addr, UBYTE b)
 66  {
 67  }
 68  
 69  int dummy_check(CPTR addr, ULONG size)
 70  {
 71      return 0;
 72  }
 73  
 74  UWORD *dummy_xlate(CPTR addr)
 75  {
 76      return NULL;
 77  }
 78  
 79  /* Chip memory */
 80  
 81  UWORD *chipmemory=NULL;
 82  void *chipmemory_end=NULL;
 83  #ifdef HALF_CHIPMEM
 84  static UBYTE chipmemextra[chipmem_size/2];
 85  UWORD *chipmemory2=(UWORD*)&chipmemextra[0];
 86  #else
 87  UWORD *chipmemory2=NULL;
 88  #endif
 89  
 90  extern UWORD *chipmemoryadd;
 91  
 92  ULONG chipmem_lget(CPTR addr)
 93  {
 94      if (chipmemory != chipmemoryadd) {
 95        emu_printf("aaaaaa");
 96        //delay(100);
 97        chipmemory = chipmemoryadd;
 98      }  
 99      
100      addr -= chipmem_start;
101      addr &= chipmem_size-1;
102  #ifdef HALF_CHIPMEM
103      if (addr >= 0x040000) {
104          addr -= 0x040000;
105          return ((ULONG)chipmemory2[addr >> 1] << 16) | chipmemory2[(addr >> 1)+1];
106      }
107  #endif    
108      return ((ULONG)chipmemory[addr >> 1] << 16) | chipmemory[(addr >> 1)+1];
109  }
110  
111  UWORD chipmem_wget(CPTR addr)
112  {
113      /*
114      if (chipmemory != chipmemoryadd) {
115        emu_printf("aaaaaa");
116        delay(100);
117        chipmemory = chipmemoryadd;
118      }
119      */ 
120      addr -= chipmem_start;
121      addr &= chipmem_size-1;
122  #ifdef HALF_CHIPMEM
123      if (addr >= 0x040000) {
124          addr -= 0x040000;
125          return chipmemory2[addr >> 1];
126      }
127  #endif    
128      return chipmemory[addr >> 1];
129  }
130  
131  UBYTE chipmem_bget(CPTR addr)
132  {
133      /*
134      if (chipmemory != chipmemoryadd) {
135        emu_printf("aaaaaa");
136        delay(100);
137        chipmemory = chipmemoryadd;
138      }
139      */  
140      addr -= chipmem_start;
141      addr &= chipmem_size-1;
142  #ifdef HALF_CHIPMEM
143      if (addr >= 0x040000) {
144          addr -= 0x040000;
145          if (addr & 1) 
146             return chipmemory2[addr >> 1];
147          else
148             return chipmemory2[addr >> 1] >> 8;
149      }
150  #endif    
151      if (addr & 1) 
152  	   return chipmemory[addr >> 1];
153      else
154  	   return chipmemory[addr >> 1] >> 8;
155  }
156  
157  void chipmem_lput(CPTR addr, ULONG l)
158  {
159      addr -= chipmem_start;
160      addr &= chipmem_size-1;
161  #ifdef HALF_CHIPMEM
162      if (addr >= 0x040000) {
163          addr -= 0x040000;
164          chipmemory2[addr >> 1] = l >> 16;
165          chipmemory2[(addr >> 1)+1] = (UWORD)l;
166          return;
167      }
168  #endif    
169      chipmemory[addr >> 1] = l >> 16;
170      chipmemory[(addr >> 1)+1] = (UWORD)l;
171  }
172  
173  void chipmem_wput(CPTR addr, UWORD w)
174  {
175      addr -= chipmem_start;
176      addr &= chipmem_size-1;
177  #ifdef HALF_CHIPMEM
178      if (addr >= 0x040000) {
179          addr -= 0x040000;
180          chipmemory2[addr >> 1] = w;
181          return;
182      }
183  #endif    
184      chipmemory[addr >> 1] = w;
185  }
186  
187  void chipmem_bput(CPTR addr, UBYTE b)
188  {
189      addr -= chipmem_start;
190      addr &= chipmem_size-1;
191  #ifdef HALF_CHIPMEM
192      if (addr >= 0x040000) {
193          addr -= 0x040000;
194          if (!(addr & 1)) {
195            chipmemory2[addr>>1] = (chipmemory2[addr>>1] & 0xff) | (((UWORD)b) << 8);
196          } else {
197            chipmemory2[addr>>1] = (chipmemory2[addr>>1] & 0xff00) | b;
198          }    
199          return;
200      }
201  #endif    
202      if (!(addr & 1)) {
203        chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
204      } else {
205        chipmemory[addr>>1] = (chipmemory[addr>>1] & 0xff00) | b;
206      }    
207  }
208  
209  int chipmem_check(CPTR addr, ULONG size)
210  {
211      addr -= chipmem_start;
212      addr &= chipmem_size-1;
213      return (addr + size) < chipmem_size;
214  }
215  
216  UWORD *chipmem_xlate(CPTR addr)
217  {
218      addr -= chipmem_start;
219      addr &= chipmem_size-1;
220  #ifdef HALF_CHIPMEM
221      if (addr >= 0x040000) {
222          addr -= 0x040000;
223          return chipmemory2 + (addr >> 1);
224      }
225  #endif
226      return chipmemory + (addr >> 1);
227  }
228  
229  
230  /* Kick memory */
231  
232  static int zkickfile = 0;
233  
234  #ifdef HAS_KICKFILE   
235  static UWORD kick[kickmem_size/2];
236  #else
237  #ifdef HALF_KICKIMAGE
238  #include "kick13_swapped.h"
239  #else
240  #include "kickfull_swapped.h"
241  #endif
242  #endif
243  static UWORD *kickmemory=(UWORD*)&kick[0];
244  
245  
246  static ULONG kickmem_lget(CPTR) REGPARAM;
247  static UWORD kickmem_wget(CPTR) REGPARAM;
248  static UBYTE kickmem_bget(CPTR) REGPARAM;
249  static void  kickmem_lput(CPTR, ULONG) REGPARAM;
250  static void  kickmem_wput(CPTR, UWORD) REGPARAM;
251  static void  kickmem_bput(CPTR, UBYTE) REGPARAM;
252  static int  kickmem_check(CPTR addr, ULONG size) REGPARAM;
253  static UWORD *kickmem_xlate(CPTR addr) REGPARAM;
254  
255  
256  ULONG kickmem_lget(CPTR addr)
257  {
258      addr -= kickmem_start;
259      addr &= kickmem_size-1;
260  #ifdef HALF_KICKIMAGE
261      if (addr >= 0x040000) {addr -= 0x040000;}
262  #endif    
263      return ((ULONG)kickmemory[addr >> 1] << 16) | kickmemory[(addr >> 1)+1];
264  }
265  
266  UWORD kickmem_wget(CPTR addr)
267  {
268      addr -= kickmem_start;
269      addr &= kickmem_size-1;
270  #ifdef HALF_KICKIMAGE
271      if (addr >= 0x040000) {addr -= 0x040000;}
272  #endif    
273      return kickmemory[addr >> 1];
274  }
275  
276  UBYTE kickmem_bget(CPTR addr)
277  {
278      addr -= kickmem_start;
279      addr &= kickmem_size-1;
280  #ifdef HALF_KICKIMAGE
281      if (addr >= 0x040000) {addr -= 0x040000;}
282  #endif    
283      return kickmemory[addr >> 1] >> (addr & 1 ? 0 : 8);
284  }
285  
286  void kickmem_lput(CPTR a, ULONG b)
287  {
288  }
289  
290  void kickmem_wput(CPTR a, UWORD b)
291  {
292  }
293  
294  void kickmem_bput(CPTR a, UBYTE b)
295  {
296  }
297  
298  int kickmem_check(CPTR addr, ULONG size)
299  {
300      addr -= kickmem_start;
301      addr &= kickmem_size-1;
302      return (addr + size) < kickmem_size;
303  }
304  
305  UWORD *kickmem_xlate(CPTR addr)
306  {
307      addr -= kickmem_start;
308      addr &= kickmem_size-1;
309   #ifdef HALF_KICKIMAGE
310      if (addr >= 0x040000) {addr -= 0x040000;}
311  #endif    
312      return kickmemory + (addr >> 1);
313  }
314  
315  
316  
317  #ifdef HAS_BOGOMEM 
318  
319  /* Slow memory */
320  
321  static UWORD *bogomemory;
322  
323  static ULONG bogomem_lget(CPTR) REGPARAM;
324  static UWORD bogomem_wget(CPTR) REGPARAM;
325  static UBYTE bogomem_bget(CPTR) REGPARAM;
326  static void  bogomem_lput(CPTR, ULONG) REGPARAM;
327  static void  bogomem_wput(CPTR, UWORD) REGPARAM;
328  static void  bogomem_bput(CPTR, UBYTE) REGPARAM;
329  static int  bogomem_check(CPTR addr, ULONG size) REGPARAM;
330  static UWORD *bogomem_xlate(CPTR addr) REGPARAM;
331  
332  ULONG bogomem_lget(CPTR addr)
333  {
334      addr -= bogomem_start & (bogomem_size-1);
335      addr &= bogomem_size-1;
336      return ((ULONG)bogomemory[addr >> 1] << 16) | bogomemory[(addr >> 1)+1];
337  }
338  
339  UWORD bogomem_wget(CPTR addr)
340  {
341      addr -= bogomem_start & (bogomem_size-1);
342      addr &= bogomem_size-1;
343      return bogomemory[addr >> 1];
344  }
345  
346  UBYTE bogomem_bget(CPTR addr)
347  {
348      addr -= bogomem_start & (bogomem_size-1);
349      addr &= bogomem_size-1;
350      if (addr & 1)
351      return bogomemory[addr >> 1];
352      else
353      return bogomemory[addr >> 1] >> 8;
354  }
355  
356  void bogomem_lput(CPTR addr, ULONG l)
357  {
358      addr -= bogomem_start & (bogomem_size-1);
359      addr &= bogomem_size-1;
360      bogomemory[addr >> 1] = l >> 16;
361      bogomemory[(addr >> 1)+1] = (UWORD)l;
362  }
363  
364  void bogomem_wput(CPTR addr, UWORD w)
365  {
366      addr -= bogomem_start & (bogomem_size-1);
367      addr &= bogomem_size-1;
368      bogomemory[addr >> 1] = w;
369  }
370  
371  void bogomem_bput(CPTR addr, UBYTE b)
372  {
373      addr -= bogomem_start & (bogomem_size-1);
374      addr &= bogomem_size-1;
375      if (!(addr & 1)) {
376      bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff) | (((UWORD)b) << 8);
377      } else {
378      bogomemory[addr>>1] = (bogomemory[addr>>1] & 0xff00) | b;
379      }
380  }
381  
382  int bogomem_check(CPTR addr, ULONG size)
383  {
384      addr -= bogomem_start & (bogomem_size-1);
385      addr &= bogomem_size-1;
386      return (addr + size) < bogomem_size;
387  }
388  
389  UWORD *bogomem_xlate(CPTR addr)
390  {
391      addr -= bogomem_start & (bogomem_size-1);
392      addr &= bogomem_size-1;
393      return bogomemory + (addr >> 1);
394  }
395  #endif
396  
397  #ifdef HAS_KICKFILE
398  int processFileInMem(char * infile, char * outfile, char * arrname, unsigned char * data, int size) {
399  
400    FILE *fp_wr = stdout;
401    if ((fp_wr = fopen (outfile, "wb")) == NULL)
402    {
403      fprintf (stderr, "Error:  can not create file %s\n", outfile);    
404    }
405  
406    int cnt=0;
407    fprintf(fp_wr, "const unsigned char %s[%d] = {\n", arrname, size);
408  
409    cnt = 0;
410    for (int i = 0; i < size; i++) {
411      cnt++;
412      if (cnt == 16) {
413        fprintf(fp_wr, "0x%02X,\n",data[i]);
414      }  
415      else {
416        fprintf(fp_wr, "0x%02X,",data[i]);
417      }  
418      cnt &= 15;
419    }  
420    fprintf(fp_wr, "};\n");
421  
422    fclose (fp_wr);
423    return 1;  
424  }
425  
426  static int load_kickstart(void)
427  {
428      int i;
429      ULONG cksum = 0, prevck = 0;
430      unsigned char buffer[8];
431      
432      FILE *f = fopen(romfile, "rb");
433      
434      if (f == NULL) {	
435          emu_printf("No Kickstart ROM found.\n");
436          return 0;
437      }
438      
439      fread(buffer, 1, 8, f);
440      if (buffer[4] == 0 && buffer[5] == 8 && buffer[6] == 0 && buffer[7] == 0) {
441  	   emu_printf("You seem to have a ZKick file there... You probably lose.\n");
442  	   zkickfile = 1;
443      } else 
444  	fseek(f, 0, SEEK_SET);
445      
446      i = fread(kick, 1, kickmem_size, f);
447      if (i == kickmem_size/2) {
448  	   emu_printf("Warning: Kickstart is only 256K.\n");
449  	   memcpy (kick + kickmem_size/4, kick, kickmem_size/2);
450      } else if (i != kickmem_size) {
451  	   emu_printf("Error while reading Kickstart.\n");
452  	   return 0;
453      }
454      fclose (f);
455      
456      for (i = 0; i < kickmem_size/2; i++) {
457  	   UWORD *p = kick + i;
458  	   UBYTE *bp = (UBYTE *)p;
459  	   *p = (*bp << 8) | *(bp+1);
460      }
461  
462      
463      for (i = 0; i < kickmem_size/4; i++) {
464  	   ULONG data = kick[i*2]*65536 + kick[i*2+1];
465  	   cksum += data;
466  	   if (cksum < prevck)
467  	       cksum++;
468  	   prevck = cksum;
469      }
470      if (cksum != 0xFFFFFFFF) {
471  	   emu_printf("Warning: Kickstart checksum incorrect. You probably have a corrupted ROM image.\n");
472      }
473  
474      return 1;
475  }
476  #endif
477  
478  
479  /* Address banks */
480  
481  addrbank dummy_bank = {
482      dummy_lget, dummy_wget, dummy_bget,
483      dummy_lput, dummy_wput, dummy_bput,
484      dummy_xlate, dummy_check
485  };
486  
487  addrbank chipmem_bank = {
488      chipmem_lget, chipmem_wget, chipmem_bget,
489      chipmem_lput, chipmem_wput, chipmem_bput,
490      chipmem_xlate, chipmem_check
491  };
492  
493  addrbank kickmem_bank = {
494      kickmem_lget, kickmem_wget, kickmem_bget,
495      kickmem_lput, kickmem_wput, kickmem_bput,
496      kickmem_xlate, kickmem_check
497  };
498  
499  #ifdef HAS_BOGOMEM   
500  addrbank bogomem_bank = {
501      bogomem_lget, bogomem_wget, bogomem_bget,
502      bogomem_lput, bogomem_wput, bogomem_bput,
503      bogomem_xlate, bogomem_check
504  };
505  #endif
506  
507  
508  void memory_init(void)
509  {
510      int i;
511      buserr = 0;
512  
513  #ifdef HALF_CHIPMEM
514      chipmemory = (WORD*)emu_Malloc(chipmem_size/2);
515      chipmemoryadd = chipmemory;
516      memset(chipmemory, 0, chipmem_size/2);
517      memset(chipmemory2, 0, chipmem_size/2);
518      chipmemory_end = chipmemory;
519      chipmemory_end += chipmem_size/2;    
520  #else
521      chipmemory = (WORD*)emu_Malloc(chipmem_size);
522      memset(chipmemory, 0, chipmem_size);
523      chipmemory_end = chipmemory;
524      chipmemory_end += chipmem_size;    
525  #endif
526  
527      for(i = 0; i < 256; i++)
528  	   membanks[i] = dummy_bank;
529      
530      /* Map the chipmem into all of the lower 16MB */
531      map_banks(chipmem_bank, 0x00, 256); //chipmem_size>>16??
532      map_banks(custom_bank, 0xC0, 0x20);
533      map_banks(cia_bank, 0xA0, 0x20);
534      
535      //0x000000 - 0x080000 
536      //0xA00000 - 0xBFFFFF
537      //0xC00000 - 0xDFFFFF
538      //0xF80000 - 0xFFFFFF
539  
540  
541      //map_banks(clock_bank, 0xDC, 1);
542      //map_banks(rtarea_bank, 0xF0, 1); 
543      //rtarea_init ();
544      
545  #ifdef HAS_KICKFILE       
546      if (!load_kickstart()) {
547  #ifdef HAS_ERSATZ          
548  	   init_ersatz_rom(kickmemory);
549  	   ersatzkickfile = 1;
550  #endif       
551      }
552      //processFileInMem("kick13.rom","kickbig.h","kick",kick,kickmem_size);    
553  #endif
554  
555      if (zkickfile)
556  	   map_banks(kickmem_bank, 0x20, 8);
557      
558      map_banks(kickmem_bank, 0xF8, 8);
559  
560  #ifdef HAS_BOGOMEM   
561      if (bogomem_size > 0) {
562          bogomemory = (UWORD *)emu_malloc (bogomem_size);
563          map_banks(bogomem_bank, 0xC0, bogomem_size >> 16);
564      }
565  #endif
566  
567  #ifdef HAS_EXPANMEM   
568      fastmem_size = 0x200000;    
569      if (!zkickfile)
570  	   map_banks(expamem_bank, 0xE8, 1);
571  #endif    
572  }
573  
574  void map_banks(addrbank bank, int start, int size)
575  {
576      int bnr;
577  //    int hioffs = 0;
578  //#if CPU_LEVEL < 2
579  //    for (hioffs = 0; hioffs < 256; hioffs++)
580  //#endif
581  	for (bnr = start; bnr < start+size; bnr++) 
582  	    membanks[bnr /*+ hioffs * 256*/] = bank;
583  }