home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 6 / AACD06.ISO / AACD / Emulation / Atari800 / mem.c < prev    next >
C/C++ Source or Header  |  1998-02-17  |  15KB  |  846 lines

  1. /*******************************************************
  2.  ** mem.h                                             **
  3.  ** Memory-Handler                                    **
  4.  ** Speicherzugriffe, RAM,ROM,Hardware                **
  5.  *******************************************************/
  6.  
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <unistd.h>
  12. #include <stdlib.h>
  13. #include "mem.h"
  14. #include "atari.h"
  15.  
  16. #ifndef O_BINARY
  17. #define O_MODE O_RDONLY
  18. #else
  19. #define O_MODE (O_RDONLY | O_BINARY)
  20. #endif
  21.  
  22. #ifdef VMS
  23. #include <unixio.h>
  24. #include <file.h>
  25. #else
  26. #include <fcntl.h>
  27. #endif
  28.  
  29. mtype memory[65536];
  30. mtype *XE_Banks[5];  /* #5 is a temporary buffer */
  31. MemGet mget[65536];
  32. MemPut mput[65536];
  33.  
  34. static struct Cart *current=NULL;  /* currently inserted LEFT cartridge */
  35. static struct Cart *basic=NULL;    /* XL,XE basic */
  36. static struct Cart *os=NULL;       /* main OS, 0xe000,0xffff */
  37. static struct Cart *mpack=NULL;    /* math pack, 0xd800,0xdfff */
  38. static struct Cart *os_x=NULL;     /* XL OS extension 0xc000,0xcfff */
  39. static struct Cart *selftest=NULL; /* XL selftest 0xd000,0xd7ff */
  40.  
  41. static int basic_on=FALSE;
  42.  
  43. static char *rcsid = "$Id: mem.c,v 1.00 1998/02/17 thor";
  44.  
  45. static struct Cart *ReadCart(char *filename, int fd,int addr, int nbytes);
  46.  
  47.  
  48.  
  49. mtype NoGet(void)
  50. {
  51.   return ~0;
  52. }
  53.  
  54. int NoPut(mtype byte)
  55. {
  56.   return 0;
  57. }
  58.  
  59. void SetRAM(int lower,int upper)
  60. {
  61. int i;
  62.  
  63.   for(i=lower;i<=upper;i++) {
  64.      mput[i] = NULL;
  65.      mget[i] = NULL;
  66.    }
  67. }
  68.  
  69. void SetROM(int lower,int upper)
  70. {
  71. int i;
  72.  
  73.    for(i=lower;i<=upper;i++) {
  74.      mput[i] = &NoPut;
  75.      mget[i] = NULL;
  76.    }
  77. }
  78.  
  79. void SetHW(int addr,int mask,MemGet read,MemPut write)
  80. {
  81. int i;
  82. int lo,hi;
  83.  
  84.   lo = addr & 0xff00;
  85.   hi = lo + 0x100;
  86.  
  87.   for(i=lo;i<hi;i++) {
  88.     if ((i & mask)==addr) {
  89.       if (read)  mget[i] = read;
  90.       else       mget[i] = &NoGet;
  91.  
  92.       if (write) mput[i] = write;
  93.       else       mput[i] = &NoPut;
  94.     }
  95.   }
  96. }
  97.  
  98.  
  99. void SetBlank(int lower,int upper)
  100. {
  101. int i;
  102.  
  103.    for(i=lower;i<=upper;i++) {
  104.      mget[i] = &NoGet;
  105.      mput[i] = &NoPut;
  106.    }
  107. }
  108.  
  109.  
  110. void EnablePILL (void)
  111. {
  112.   SetROM (0x8000, 0xbfff);
  113. }
  114.  
  115. void CopyFromMem(ATPtr from,UBYTE *to,int size)
  116. {
  117.   memcpy(to,from+memory,size);
  118. }
  119.  
  120.  
  121. void CopyToMem(UBYTE *from,ATPtr to,int size)
  122. {
  123. int i;
  124.  
  125.    for(i=0;i<size;i++) {
  126.      Poke(to,*from);
  127.      from++,to++;
  128.    }
  129. }
  130.  
  131. struct Cart *AllocCart(int size)
  132. {
  133. struct Cart *ct;
  134. int i;
  135.  
  136.   if ((ct=malloc(sizeof(struct Cart)))!=0) {
  137.     if ((ct->image=malloc(size*sizeof(mtype)))!=0) {
  138.       if ((ct->saveback=malloc(size*sizeof(mtype)))!=0) {
  139.     ct->type = 0;
  140.     ct->active = FALSE;
  141.     ct->num_secs = 1;  /* Defaults to one section */
  142.     for (i=0;i<0x4;i++) {
  143.       ct->secs[i].lo = ct->secs[i].hi = 0;
  144.       ct->secs[i].offset = 0;
  145.       ct->secs[i].active = FALSE;
  146.     }
  147.     ct->secs[0].active = TRUE;  /* section zero is active by default */
  148.  
  149.     return ct;
  150.       }
  151.       free(ct->image);
  152.     }
  153.     free(ct);
  154.   }
  155.  
  156.   return NULL;
  157. }
  158.  
  159. void FreeCart(struct Cart *ct)
  160. {
  161.   if (ct) {
  162.     if (ct->image)
  163.       free(ct->image);
  164.     if (ct->saveback)
  165.       free(ct->saveback);
  166.     free(ct);
  167.   }
  168. }
  169.  
  170. static int ReadImage(int fd,mtype *to,int nbytes)
  171. {
  172. UBYTE *buffer,*ptr;
  173. int i;
  174. int status=0;
  175.  
  176.   if ((buffer=malloc(nbytes*sizeof(UBYTE)))!=0) {
  177.     if (read(fd,buffer,nbytes)==nbytes) {
  178.       for(i=0,ptr=buffer;i<nbytes;i++,ptr++,to++)
  179.     *to=*ptr;
  180.       status = 1;
  181.     }
  182.     free(buffer);
  183.   }
  184.  
  185.   return status;
  186. }
  187.  
  188. int Read5200Rom(char *filename,int fd)
  189. {
  190. int fdo = -1;
  191. int status = 0;
  192.   
  193.   if ((os=AllocCart(0xffff-0xf800+1))!=0) {
  194.     if (filename) {
  195.       fd = fdo = open(filename, O_MODE, 0777);
  196.     }
  197.     if (fd >= 0) {
  198.       if (ReadImage(fd,os->image,0xffff-0xf800+1)) {
  199.     status = 1;
  200.       }
  201.     }
  202.   }
  203.  
  204.   if (fdo >= 0)
  205.     close(fdo);
  206.  
  207.   if (status) {
  208.     os->secs[0].lo=0xf800;
  209.     os->secs[0].hi=0xffff;
  210.     return TRUE;
  211.   }
  212.  
  213.   if (verbose)
  214.     perror(filename);
  215.  
  216.   FreeCart(os);
  217.  
  218.   os=NULL;
  219.  
  220.   return FALSE;
  221. }
  222.  
  223. int ReadOSABRom(char *filename,int fd)
  224. {
  225. int fdo = -1;
  226. int status = 0;
  227.   
  228.   if ((os=AllocCart(0xffff-0xe000+1))!=0) {
  229.     if ((mpack=AllocCart(0xdfff-0xd800+1))!=0) {
  230.       if (filename) {
  231.     fd = fdo = open(filename, O_MODE, 0777);
  232.       }
  233.       if (fd >= 0) {
  234.     if (ReadImage(fd,mpack->image,0xdfff-0xd800+1)) {
  235.       if (ReadImage(fd,os->image,0xffff-0xe000+1)) {
  236.         status = 1;
  237.       }
  238.     }
  239.       }
  240.     }
  241.   }
  242.  
  243.   if (fdo >= 0)
  244.     close(fdo);
  245.  
  246.   if (status) {
  247.     os->secs[0].lo=0xe000;
  248.     os->secs[0].hi=0xffff;
  249.     mpack->secs[0].lo=0xd800;
  250.     mpack->secs[0].hi=0xdfff;
  251.     return TRUE;
  252.   }
  253.  
  254.   if (verbose)
  255.     perror(filename);
  256.  
  257.   FreeCart(os);
  258.   FreeCart(mpack);
  259.  
  260.   os=mpack=NULL;
  261.  
  262.   return FALSE;
  263. }
  264.  
  265. int ReadXLRom(char *filename,int fd)
  266. {
  267. int fdo = -1;
  268. int status = 0;
  269.   
  270.   if ((os=AllocCart(0xffff-0xe000+1))!=0) {
  271.     if ((mpack=AllocCart(0xdfff-0xd800+1))!=0) {
  272.       if ((os_x=AllocCart(0xcfff-0xc000+1))!=0) {
  273.     if ((selftest=AllocCart(0xd7ff-0xd000+1))!=0) {
  274.       if (filename) {
  275.         fd = fdo = open(filename, O_MODE, 0777);
  276.       }
  277.       if (fd>=0) {
  278.         if (ReadImage(fd,os_x->image,0xcfff-0xc000+1)) {
  279.           if (ReadImage(fd,selftest->image,0xd7ff-0xd000+1)) {
  280.         if (ReadImage(fd,mpack->image,0xdfff-0xd800+1)) {
  281.           if (ReadImage(fd,os->image,0xffff-0xe000+1)) {
  282.             status = 1;
  283.           }
  284.         }
  285.           }
  286.         }
  287.       }
  288.     }
  289.       }
  290.     }
  291.   }
  292.  
  293.   if (fdo>=0)
  294.     close(fdo);
  295.  
  296.   if (status) {
  297.     os->secs[0].lo=0xe000;
  298.     os->secs[0].hi=0xffff;
  299.     mpack->secs[0].lo=0xd800;
  300.     mpack->secs[0].hi=0xdfff;
  301.     selftest->secs[0].lo=0x5000;
  302.     selftest->secs[0].hi=0x57ff;
  303.     os_x->secs[0].lo=0xc000;
  304.     os_x->secs[0].hi=0xcfff;
  305.     return TRUE;
  306.   }
  307.  
  308.   if (verbose)
  309.     perror(filename);
  310.  
  311.   FreeCart(os);
  312.   FreeCart(mpack);
  313.   FreeCart(os_x);
  314.   FreeCart(selftest);
  315.  
  316.   os=mpack=os_x=selftest=NULL;
  317.  
  318.   return FALSE;
  319. }
  320.  
  321. int ReadBasic(char *filename,int fd)
  322. {
  323. struct Cart *ct;
  324.  
  325.    if ((ct=ReadCart(filename,fd,0xa000,0xbfff-0xa000+1))!=0) {
  326.      basic=ct;
  327.      return TRUE;
  328.    }
  329.  
  330.    return FALSE;
  331. }
  332.  
  333. /*
  334.  * Load a standard 8K ROM from the specified file
  335.  */
  336. int Insert_8K_ROM (char *filename,int fd)
  337. {
  338. struct Cart *ct;
  339.  
  340.    if ((ct=ReadCart(filename,fd,0xa000,0xbfff-0xa000+1))!=0) {
  341.      ct->type = NORMAL8_CART;
  342.      RemoveCurrent();
  343.      InsertCart(ct);
  344.      return TRUE;
  345.    }
  346.  
  347.    return FALSE; 
  348. }
  349.  
  350. /*
  351.  * Load a standard 16K ROM from the specified file
  352.  */
  353. int Insert_16K_ROM (char *filename,int fd)
  354. {
  355. struct Cart *ct;
  356.  
  357.    if ((ct=ReadCart(filename,fd,0x8000,0xbfff-0x8000+1))!=0) {
  358.      ct->type = NORMAL16_CART;
  359.      RemoveCurrent();
  360.      InsertCart(ct);
  361.      return TRUE;
  362.    }
  363.  
  364.    return FALSE; 
  365. }
  366.  
  367.  /*
  368.  * Load an OSS Supercartridge from the specified file
  369.  * The OSS cartridge is a 16K bank switched cartridge
  370.  * that occupies 8K of address space between $a000
  371.  * and $bfff
  372.  */
  373.  
  374. int Insert_OSS_ROM (char *filename,int fd)
  375. {
  376. struct Cart *ct;
  377.  
  378.    if ((ct=ReadCart(filename,fd,0x8000,0xbfff-0x8000+1))!=0) {
  379.      ct->type = OSS_SUPERCART;
  380.      ct->secs[0].lo     = 0xa000;
  381.      ct->secs[0].hi     = 0xafff;
  382.      ct->secs[1].lo     = 0xa000;
  383.      ct->secs[1].hi     = 0xafff;
  384.      ct->secs[1].offset = 0x1000;
  385.      ct->secs[2].lo     = 0xa000;
  386.      ct->secs[2].hi     = 0xafff;
  387.      ct->secs[2].offset = 0x2000;
  388.      ct->secs[3].lo     = 0xb000;
  389.      ct->secs[3].hi     = 0xbfff;
  390.      ct->secs[3].offset = 0x3000;
  391.      ct->secs[3].active = TRUE;
  392.      RemoveCurrent();
  393.      InsertCart(ct);
  394.      return TRUE;
  395.    }
  396.  
  397.    return FALSE; 
  398. }
  399.  
  400.  
  401. /*
  402.  * Load a DB Supercartridge from the specified file
  403.  * The DB cartridge is a 32K bank switched cartridge
  404.  * that occupies 16K of address space between $8000
  405.  * and $bfff
  406.  */
  407. int Insert_DB_ROM (char *filename,int fd)
  408. {
  409. struct Cart *ct;
  410.  
  411.    if ((ct=ReadCart(filename,fd,0x2000,0xbfff-0x2000+1))!=0) {
  412.      ct->type = DB_SUPERCART;
  413.      ct->secs[0].lo     = 0x8000;
  414.      ct->secs[0].hi     = 0x9fff;
  415.      ct->secs[1].lo     = 0x8000;
  416.      ct->secs[1].hi     = 0x9fff;
  417.      ct->secs[1].offset = 0x2000;
  418.      ct->secs[2].lo     = 0x8000;
  419.      ct->secs[2].hi     = 0x9fff;
  420.      ct->secs[2].offset = 0x4000;
  421.      ct->secs[3].lo     = 0xa000;
  422.      ct->secs[3].hi     = 0xbfff;
  423.      ct->secs[3].offset = 0x6000;
  424.      ct->secs[3].active = TRUE;
  425.      RemoveCurrent();
  426.      InsertCart(ct);
  427.      return TRUE;
  428.    }
  429.  
  430.    return FALSE; 
  431. }
  432.  
  433.  
  434. /*
  435.  * Load a 32K 5200 ROM from the specified file
  436.  * 
  437.  * still to be checked
  438.  */
  439.  
  440. int Insert_32K_5200ROM (char *filename,int fd)
  441. {
  442. struct Cart *ct;
  443.  
  444.    if ((ct=ReadCart(filename,fd,0x4000,0xbfff-0x4000+1))!=0) {
  445.      ct->type = AGS32_CART;
  446.      RemoveCurrent();
  447.      InsertCart(ct);
  448.      return TRUE;
  449.    }
  450.  
  451.    return FALSE; 
  452. }
  453.  
  454. int Insert_16K_5200ROM (char *filename,int fd)
  455. {
  456. struct Cart *ct;
  457.  
  458.    if ((ct=ReadCart(filename,fd,0x4000,0x7fff-0x4000+1))!=0) {
  459.      ct->type = AGS16_CART;
  460.      /* setup the magic mirroring. Invalidates RAM saveback, but who cares...
  461.     the 5200 doesn't have RAM there anyways */
  462.      ct->secs[0].lo = 0x4000;
  463.      ct->secs[0].hi = 0x5fff;
  464.      ct->secs[0].offset = 0x0000;
  465.      ct->secs[0].active = TRUE;
  466.      ct->secs[1].lo = 0x8000;
  467.      ct->secs[1].hi = 0x9fff;
  468.      ct->secs[1].offset = 0x2000;
  469.      ct->secs[1].active = TRUE;
  470.      ct->secs[2].lo = 0xa000;
  471.      ct->secs[2].hi = 0xbfff;
  472.      ct->secs[2].offset = 0x2000;
  473.      ct->secs[2].active = TRUE;
  474.      ct->secs[3].lo = 0x6000;
  475.      ct->secs[3].hi = 0x7fff;
  476.      ct->secs[3].offset = 0x0000;
  477.      ct->secs[3].active = TRUE;
  478.      RemoveCurrent();
  479.      InsertCart(ct);
  480.      return TRUE;
  481.    }
  482.  
  483.    return FALSE; 
  484. }
  485.  
  486. static struct Cart *ReadCart(char *filename, int fd,int addr, int nbytes)
  487. {
  488. struct Cart *ct;
  489. int fdo = -1;
  490. int status=0;
  491.  
  492.   if ((ct=AllocCart(nbytes))!=0) {
  493.     if (filename) {
  494.       fd = fdo = open(filename, O_MODE,0777);
  495.     }
  496.     if (fd>=0) {
  497.       status = ReadImage(fd,ct->image,nbytes);
  498.     } 
  499.   }
  500.  
  501.   if (fdo>=0)
  502.     close(fdo);
  503.  
  504.   if (status)  {
  505.     ct->secs[0].lo = addr;
  506.     ct->secs[0].hi = addr+nbytes-1;
  507.     return ct;
  508.   }
  509.  
  510.   if (verbose)
  511.     perror(filename);
  512.  
  513.   FreeCart(ct);
  514.   return NULL;
  515. }
  516.   
  517.        
  518. int lof(char *filename)
  519. {
  520. struct stat buf;
  521.  
  522.   if (stat(filename,&buf)==0) {
  523.     return buf.st_size;
  524.   }
  525.  
  526.   if (verbose)
  527.     perror(filename);
  528.  
  529.   return -1;
  530. }
  531.  
  532.  
  533. static void DisableCart(struct Cart *ct)
  534. {
  535. int i;
  536.  
  537.   if (ct) {
  538.     if (ct->active) {
  539.       for(i=0;i<4;i++) {
  540.     if (ct->secs[i].active) {
  541.       memcpy(memory+ct->secs[i].lo,ct->saveback+ct->secs[i].offset,(ct->secs[i].hi-ct->secs[i].lo+1)*sizeof(mtype));
  542.       SetRAM(ct->secs[i].lo,ct->secs[i].hi);
  543. #ifdef DEBUG
  544.       printf("Disabling a cart between %x and %x\n",ct->secs[i].lo,ct->secs[i].hi);
  545. #endif
  546.     }
  547.       }
  548.       ct->active = FALSE;
  549.     }
  550.   }
  551. }
  552.  
  553. static void EnableCart(struct Cart *ct)
  554. {
  555. int i;
  556. int len;
  557.  
  558.   if (ct) {
  559.     if (!(ct->active)) {
  560.       for(i=0;i<4;i++) {
  561.     if (ct->secs[i].active) {
  562.       len = (ct->secs[i].hi-ct->secs[i].lo+1)*sizeof(mtype);
  563.       memcpy(ct->saveback+ct->secs[i].offset,memory+ct->secs[i].lo,len);
  564.       memcpy(memory+ct->secs[i].lo,ct->image+ct->secs[i].offset,len);
  565.       SetROM(ct->secs[i].lo,ct->secs[i].hi);
  566. #ifdef DEBUG
  567.       printf("Enabling a cart between %x and %x\n",ct->secs[i].lo,ct->secs[i].hi);
  568. #endif
  569.     }
  570.       }
  571.       ct->active=TRUE;
  572.     }
  573.   }
  574. }
  575.  
  576.  
  577. void ChangeMapping(int map0,int map1,int map2, int map3)
  578. {
  579. struct Cart *ct=current;
  580.  
  581.   if (ct) {
  582.     /* first, remove all images */
  583.     if (!(ct->active)) {
  584.       if (basic_on) {
  585.     DisableCart(basic);  /* if it wasn't active before, we've to turn the
  586.                 basic off */
  587.       }
  588.     } else DisableCart(ct);
  589.     ct->active = TRUE;   /* enables cartridge as well */
  590.     ct->secs[0].active = map0;
  591.     ct->secs[1].active = map1;
  592.     ct->secs[2].active = map2;
  593.     ct->secs[3].active = map3;
  594.     EnableCart(ct);
  595.   }
  596. }
  597.  
  598. void RemoveCart(void)
  599. {
  600.   
  601.   DisableCart(current);
  602.   current = NULL;
  603.   
  604.   if (basic_on)
  605.     EnableCart(basic);
  606. }
  607.     
  608. void RemoveCurrent(void)
  609. {
  610. struct Cart *old=current;
  611.  
  612.    if (old) {
  613.      RemoveCart();
  614.      FreeCart(old);
  615.    }
  616. }
  617.  
  618. void TurnOffCart(void)
  619. {
  620. struct Cart *ct=current;
  621.  
  622.   if (ct) {
  623.     if (ct->active) {
  624.       DisableCart(ct);
  625.     }
  626.     if (basic_on) {
  627.       EnableCart(basic);
  628.     }
  629.   }
  630. }
  631.  
  632. void TurnOnCart(void)
  633. {
  634. struct Cart *ct=current;
  635.  
  636.   if (ct) {
  637.     if (!(ct->active)) {
  638.       if (basic_on) {
  639.     DisableCart(basic);
  640.       }
  641.  
  642.       EnableCart(ct);
  643.     }
  644.   }
  645. }
  646.  
  647. void InsertCart(struct Cart *ct)
  648. {
  649.   if (ct) {
  650.     DisableCart(basic);    
  651.     if (current!=ct) {
  652.       DisableCart(current);
  653.       EnableCart(ct);
  654.       current=ct;
  655.     }
  656.   }
  657. }
  658.  
  659.   
  660. int CartInserted(void)
  661. {
  662.   if (current && current->active)
  663.     return TRUE;
  664.  
  665.   return FALSE;
  666. }
  667.  
  668. int CartType(void)
  669. {
  670.   if (current)
  671.     return current->type;
  672.   else return -1;
  673. }
  674.  
  675. void EnableBasic(void)
  676. {
  677.   basic_on=TRUE;
  678.  
  679.   if (!(CartInserted()))
  680.       EnableCart(basic);
  681. }
  682.   
  683. void DisableBasic(void)
  684. {
  685.   basic_on=FALSE;
  686.  
  687.   if (!(CartInserted()))
  688.     DisableCart(basic);
  689. }
  690.  
  691. void EnableOs(void)
  692. {
  693.   EnableCart(os);
  694.   EnableCart(mpack);
  695.   EnableCart(os_x);
  696. }
  697.  
  698. void DisableOs(void)
  699. {
  700.   DisableCart(os);
  701.   DisableCart(mpack);
  702.   DisableCart(os_x);
  703. }
  704.  
  705. void EnableSelftest(void)
  706. {
  707.   EnableCart(selftest);
  708. }
  709.  
  710. void DisableSelftest(void)
  711. {
  712.   DisableCart(selftest);
  713. }
  714.  
  715. void FreeCarts(void)
  716. {
  717.   FreeCart(basic);
  718.   FreeCart(os);
  719.   FreeCart(os_x);
  720.   FreeCart(selftest);
  721.   FreeCart(mpack);
  722.   FreeCart(current);
  723.   basic=os=os_x=selftest=mpack=current=NULL;
  724. }
  725.  
  726. void SelectXEBank(int byte)
  727. {      
  728. int cpu_flag = (byte & 0x10);
  729. #ifdef DEBUG
  730. int antic_flag = (byte & 0x20);
  731. #endif
  732. int bank = (byte & 0x0c) >> 2;
  733. static int xe_bank = -1;
  734.  
  735. #ifdef DEBUG
  736.    printf ("CPU = %d, ANTIC = %d, XE BANK = %d\n",
  737.           cpu_flag, antic_flag, bank);
  738. #endif
  739.  
  740. /*
  741.  * Possible Bank Transitions
  742.  *
  743.  * Main        -> Main
  744.  * Main        -> Bank1,2,3,4
  745.  * Bank1,2,3,4 -> Main
  746.  * Bank1,2,3,4 -> Bank1,2,3,4
  747.  */
  748.  
  749.   if (cpu_flag) {  /* turn off bank */
  750.      if (xe_bank != -1) {
  751.        memcpy (XE_Banks[xe_bank],memory + 0x4000,0x4000);
  752.        memcpy (memory + 0x4000,XE_Banks[5],0x4000);
  753.        xe_bank = -1;
  754.      }
  755.    } else if (bank != xe_bank) { /* turn on bank */
  756.      if (xe_bank == -1) {
  757.        memcpy (XE_Banks[5],memory + 0x4000,0x4000);  /* saveback mem */
  758.      } else {
  759.        memcpy (XE_Banks[xe_bank],memory + 0x4000,0x4000); /* saveback bank */
  760.      }
  761.      memcpy (memory+0x4000,XE_Banks[bank],0x4000); /* swap in bank */
  762.      xe_bank = bank;
  763.    }
  764. }
  765.  
  766.  
  767. int Free_XE_Banks(void)
  768. {
  769. int i;
  770.  
  771.    for(i=0;i<4;i++) {
  772.      if (XE_Banks[i])
  773.        free(XE_Banks[i]);
  774.    }
  775.  
  776.    return TRUE;
  777. }
  778.  
  779. int Build_XE_Banks(void)
  780. {
  781. int i;
  782.  
  783.   for(i=0;i<4;i++) {
  784.     if (!(XE_Banks[i] = malloc(0x4000*sizeof(mtype))))
  785.       return FALSE;
  786.   }
  787.  
  788.   return TRUE;
  789. }
  790.  
  791.  
  792. static int InCart(struct Cart *ct,ATPtr ad,mtype **where)
  793. {
  794. int i;
  795.  
  796.   if (ct) {
  797.     for (i=0;i<4;i++) {
  798.       if (ct->secs[i].active) {
  799.     if (ad>=ct->secs[i].lo && ad<=ct->secs[i].hi) {
  800.       *where=ct->image+ct->secs[i].offset+(ad-ct->secs[i].lo);
  801.       return TRUE;
  802.     }
  803.       }
  804.     }
  805.   }
  806.  
  807.   return FALSE;
  808. }
  809.       
  810. static mtype *LocationOf(ATPtr ad)
  811. {
  812. mtype *in;
  813.  
  814.   if (InCart(os_x,ad,&in))
  815.     return in;
  816.  
  817.   if (InCart(selftest,ad,&in))
  818.     return in;
  819.  
  820.   if (InCart(mpack,ad,&in))
  821.     return in;
  822.  
  823.   if (InCart(os,ad,&in))
  824.     return in;
  825.  
  826.   printf("Invalid ROM address %x while patching.\n",ad);
  827.   Atari800_Exit (FALSE,20);
  828.   return 0;
  829. }
  830.  
  831. int RomGet(ATPtr ad)
  832. {
  833.   return *LocationOf(ad);
  834. }
  835.  
  836. int RomDGet(ATPtr ad)
  837. {
  838.   return RomGet(ad)|(RomGet(ad+1)<<8);
  839. }
  840.  
  841. void RomSet(ATPtr ad,int v)
  842. {
  843.   *LocationOf(ad)=v;
  844. }
  845.  
  846.