cart_loader.cpp 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #ifdef CART_CPP
  2. //================
  3. //Normal cartridge
  4. //================
  5. bool Cartridge::load_normal(const char *base) {
  6. uint8_t *data;
  7. unsigned size;
  8. bool patch_applied;
  9. cart.filename = base;
  10. load_begin(ModeNormal);
  11. if(load_image(base, data, size, patch_applied) == false) return false;
  12. snes.config.path.current = basepath(cart.filename);
  13. if(patch_applied) set(patched, true);
  14. cartinfo_t cartinfo;
  15. read_header(cartinfo, cart.rom = data, cart.rom_size = size);
  16. set_cartinfo(cartinfo);
  17. if(cartinfo.ram_size > 0) {
  18. load_ram(get_filename(base, "srm", snes.config.path.save), cart.ram, cart.ram_size = cartinfo.ram_size, 0xff);
  19. }
  20. if(cartinfo.srtc || cartinfo.spc7110rtc) {
  21. load_ram(get_filename(base, "rtc", snes.config.path.save), cart.rtc, cart.rtc_size = 20, 0x00);
  22. }
  23. load_end();
  24. set(name, basename(base));
  25. return true;
  26. }
  27. void Cartridge::unload_normal() {
  28. if(cart.ram) save_file(get_filename(cart.filename, "srm", snes.config.path.save), cart.ram, cart.ram_size);
  29. if(cart.rtc) save_file(get_filename(cart.filename, "rtc", snes.config.path.save), cart.rtc, cart.rtc_size);
  30. }
  31. //======================
  32. //BS-X slotted cartridge
  33. //======================
  34. bool Cartridge::load_bsx_slotted(const char *base, const char *slot) {
  35. uint8_t *data;
  36. unsigned size;
  37. bool patch_applied;
  38. cart.filename = base;
  39. bs.filename = slot;
  40. load_begin(ModeBsxSlotted);
  41. if(load_image(base, data, size, patch_applied) == false) return false;
  42. snes.config.path.current = basepath(cart.filename);
  43. if(patch_applied) set(patched, true);
  44. cartinfo_t cartinfo;
  45. read_header(cartinfo, cart.rom = data, cart.rom_size = size);
  46. set_cartinfo(cartinfo);
  47. if(load_image(slot, data, size, patch_applied) == true) {
  48. set(bsx_flash_loaded, true);
  49. if(patch_applied) set(patched, true);
  50. bs.ram = data;
  51. bs.ram_size = size;
  52. }
  53. if(cartinfo.ram_size > 0) {
  54. load_ram(get_filename(base, "srm", snes.config.path.save), cart.ram, cart.ram_size = cartinfo.ram_size, 0xff);
  55. }
  56. load_end();
  57. string filename = basename(base);
  58. if(*slot) filename << " + " << basename(slot);
  59. set(name, filename);
  60. return true;
  61. }
  62. void Cartridge::unload_bsx_slotted() {
  63. if(cart.ram) save_file(get_filename(cart.filename, "srm", snes.config.path.save), cart.ram, cart.ram_size);
  64. }
  65. //====================
  66. //BS-X flash cartridge
  67. //====================
  68. bool Cartridge::load_bsx(const char *base, const char *slot) {
  69. uint8_t *data;
  70. unsigned size;
  71. bool patch_applied;
  72. cart.filename = base;
  73. bs.filename = slot;
  74. load_begin(ModeBsx);
  75. if(load_image(base, data, size, patch_applied) == false) return false;
  76. snes.config.path.current = basepath(cart.filename);
  77. if(patch_applied) set(patched, true);
  78. cartinfo_t cartinfo;
  79. read_header(cartinfo, cart.rom = data, cart.rom_size = size);
  80. set_cartinfo(cartinfo);
  81. cart.ram = 0;
  82. cart.ram_size = 0;
  83. memset(bsxcart.sram.handle (), 0x00, bsxcart.sram.size ());
  84. memset(bsxcart.psram.handle(), 0x00, bsxcart.psram.size());
  85. if(load_file(get_filename(base, "srm", snes.config.path.save), data, size, CompressionNone) == true) {
  86. memcpy(bsxcart.sram.handle (), data, min(bsxcart.sram.size (), size));
  87. delete[] data;
  88. }
  89. if(load_file(get_filename(base, "psr", snes.config.path.save), data, size, CompressionNone) == true) {
  90. memcpy(bsxcart.psram.handle(), data, min(bsxcart.psram.size(), size));
  91. delete[] data;
  92. }
  93. if(load_image(slot, data, size, patch_applied) == true) {
  94. set(bsx_flash_loaded, true);
  95. if(patch_applied) set(patched, true);
  96. bs.ram = data;
  97. bs.ram_size = size;
  98. }
  99. load_end();
  100. set(name, !*slot ? basename(base) : basename(slot));
  101. return true;
  102. }
  103. void Cartridge::unload_bsx() {
  104. save_file(get_filename(cart.filename, "srm", snes.config.path.save), bsxcart.sram.handle (), bsxcart.sram.size ());
  105. save_file(get_filename(cart.filename, "psr", snes.config.path.save), bsxcart.psram.handle(), bsxcart.psram.size());
  106. }
  107. //============================
  108. //Sufami Turbo flash cartridge
  109. //============================
  110. bool Cartridge::load_sufami_turbo(const char *base, const char *slotA, const char *slotB) {
  111. uint8_t *data;
  112. unsigned size;
  113. bool patch_applied;
  114. cart.filename = base;
  115. stA.filename = slotA;
  116. stB.filename = slotB;
  117. load_begin(ModeSufamiTurbo);
  118. if(load_image(base, data, size, patch_applied) == false) return false;
  119. snes.config.path.current = basepath(cart.filename);
  120. if(patch_applied) set(patched, true);
  121. cartinfo_t cartinfo;
  122. read_header(cartinfo, cart.rom = data, cart.rom_size = size);
  123. set_cartinfo(cartinfo);
  124. if(load_image(slotA, data, size, patch_applied) == true) {
  125. if(patch_applied) set(patched, true);
  126. stA.rom = new(zeromemory) uint8_t[stA.rom_size = 0x100000];
  127. memcpy(stA.rom, data, min(size, stA.rom_size));
  128. delete[] data;
  129. load_ram(get_filename(slotA, "srm", snes.config.path.save), stA.ram, stA.ram_size = 0x020000, 0xff);
  130. }
  131. if(load_image(slotB, data, size, patch_applied) == true) {
  132. if(patch_applied) set(patched, true);
  133. stB.rom = new(zeromemory) uint8_t[stB.rom_size = 0x100000];
  134. memcpy(stB.rom, data, min(size, stB.rom_size));
  135. delete[] data;
  136. load_ram(get_filename(slotB, "srm", snes.config.path.save), stB.ram, stB.ram_size = 0x020000, 0xff);
  137. }
  138. load_end();
  139. string filename;
  140. if(!*slotA && !*slotB) filename << basename(base);
  141. else if( *slotA && !*slotB) filename << basename(slotA);
  142. else if(!*slotA && *slotB) filename << basename(slotB);
  143. else filename << basename(slotA) << " + " << basename(slotB);
  144. set(name, filename);
  145. return true;
  146. }
  147. void Cartridge::unload_sufami_turbo() {
  148. if(stA.ram) save_file(get_filename(stA.filename, "srm", snes.config.path.save), stA.ram, stA.ram_size);
  149. if(stB.ram) save_file(get_filename(stB.filename, "srm", snes.config.path.save), stB.ram, stB.ram_size);
  150. }
  151. //=================
  152. //utility functions
  153. //=================
  154. Cartridge::Type Cartridge::detect_image_type(const char *filename) const {
  155. uint8_t *data;
  156. unsigned size;
  157. bool patch_applied;
  158. if(!load_image(filename, data, size, patch_applied)) return TypeUnknown;
  159. cartinfo_t info;
  160. read_header(info, data, size);
  161. delete[] data;
  162. return info.type;
  163. }
  164. bool Cartridge::load_image(const char *filename, uint8_t *&data, unsigned &size, bool &patched) const {
  165. if(!filename || !*filename) return false;
  166. if(!load_file(filename, data, size, CompressionAuto)) return false;
  167. if((size & 0x7fff) == 512) {
  168. //remove 512-byte header
  169. memmove(data, data + 512, size -= 512);
  170. }
  171. uint8_t *pdata;
  172. unsigned psize;
  173. if(load_file(get_filename(filename, "ups", snes.config.path.patch), pdata, psize, CompressionInspect) == true) {
  174. apply_patch(pdata, psize, data, size);
  175. delete[] pdata;
  176. patched = true;
  177. } else {
  178. patched = false;
  179. }
  180. return true;
  181. }
  182. bool Cartridge::load_ram(const char *filename, uint8_t *&data, unsigned size, uint8_t init) const {
  183. data = new uint8_t[size];
  184. memset(data, init, size);
  185. uint8_t *savedata;
  186. unsigned savesize;
  187. if(load_file(filename, savedata, savesize, CompressionNone) == false) return false;
  188. memcpy(data, savedata, min(size, savesize));
  189. delete[] savedata;
  190. return true;
  191. }
  192. #endif