cart.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. #include <../base.hpp>
  2. #include <../chip/chip.hpp>
  3. #include <../reader/reader.hpp>
  4. #define CART_CPP
  5. #include <nall/crc32.hpp>
  6. #include <nall/ups.hpp>
  7. #include "cart.hpp"
  8. #include "cart_file.cpp"
  9. #include "cart_header.cpp"
  10. #include "cart_loader.cpp"
  11. namespace memory {
  12. MappedRAM cartrom, cartram, cartrtc;
  13. MappedRAM bscram;
  14. MappedRAM stArom, stAram;
  15. MappedRAM stBrom, stBram;
  16. };
  17. Cartridge cartridge;
  18. void Cartridge::load_begin(Mode cartridge_mode) {
  19. cart.rom = cart.ram = cart.rtc = 0;
  20. bs.ram = 0;
  21. stA.rom = stA.ram = 0;
  22. stB.rom = stB.ram = 0;
  23. cart.rom_size = cart.ram_size = cart.rtc_size = 0;
  24. bs.ram_size = 0;
  25. stA.rom_size = stA.ram_size = 0;
  26. stB.rom_size = stB.ram_size = 0;
  27. set(loaded, false);
  28. set(bsx_flash_loaded, false);
  29. set(patched, false);
  30. set(mode, cartridge_mode);
  31. }
  32. void Cartridge::load_end() {
  33. memory::cartrom.map(cart.rom, cart.rom_size);
  34. memory::cartram.map(cart.ram, cart.ram_size);
  35. memory::cartrtc.map(cart.rtc, cart.rtc_size);
  36. memory::bscram.map(bs.ram, bs.ram_size);
  37. memory::stArom.map(stA.rom, stA.rom_size);
  38. memory::stAram.map(stA.ram, stA.ram_size);
  39. memory::stBrom.map(stB.rom, stB.rom_size);
  40. memory::stBram.map(stB.ram, stB.ram_size);
  41. memory::cartrom.write_protect(true);
  42. memory::cartram.write_protect(false);
  43. memory::bscram.write_protect(true);
  44. memory::stArom.write_protect(true);
  45. memory::stAram.write_protect(false);
  46. memory::stBrom.write_protect(true);
  47. memory::stBram.write_protect(false);
  48. string cheat_file = get_filename(cart.filename, "cht", snes.config.path.cheat);
  49. if(file::exists(cheat_file)) {
  50. cheat.clear();
  51. cheat.load(cheat_file);
  52. }
  53. bus.load_cart();
  54. set(loaded, true);
  55. }
  56. void Cartridge::unload() {
  57. if(loaded() == false) return;
  58. bus.unload_cart();
  59. switch(mode()) {
  60. case ModeNormal: unload_normal(); break;
  61. case ModeBsxSlotted: unload_bsx_slotted(); break;
  62. case ModeBsx: unload_bsx(); break;
  63. case ModeSufamiTurbo: unload_sufami_turbo(); break;
  64. }
  65. if(cart.rom) { delete[] cart.rom; cart.rom = 0; }
  66. if(cart.ram) { delete[] cart.ram; cart.ram = 0; }
  67. if(cart.rtc) { delete[] cart.rtc; cart.rtc = 0; }
  68. if(bs.ram) { delete[] bs.ram; bs.ram = 0; }
  69. if(stA.rom) { delete[] stA.rom; stA.rom = 0; }
  70. if(stA.ram) { delete[] stA.ram; stA.ram = 0; }
  71. if(stB.rom) { delete[] stB.rom; stB.rom = 0; }
  72. if(stB.ram) { delete[] stB.ram; stB.ram = 0; }
  73. string cheat_file = get_filename(cart.filename, "cht", snes.config.path.cheat);
  74. if(cheat.count() > 0 || file::exists(cheat_file)) {
  75. cheat.save(cheat_file);
  76. cheat.clear();
  77. }
  78. set(loaded, false);
  79. }
  80. Cartridge::Cartridge() {
  81. set(loaded, false);
  82. }
  83. Cartridge::~Cartridge() {
  84. if(loaded() == true) unload();
  85. }
  86. void Cartridge::set_cartinfo(const Cartridge::cartinfo_t &source) {
  87. set(region, source.region);
  88. set(mapper, source.mapper);
  89. set(dsp1_mapper, source.dsp1_mapper);
  90. set(has_bsx_slot, source.bsx_slot);
  91. set(has_superfx, source.superfx);
  92. set(has_sa1, source.sa1);
  93. set(has_srtc, source.srtc);
  94. set(has_sdd1, source.sdd1);
  95. set(has_spc7110, source.spc7110);
  96. set(has_spc7110rtc, source.spc7110rtc);
  97. set(has_cx4, source.cx4);
  98. set(has_dsp1, source.dsp1);
  99. set(has_dsp2, source.dsp2);
  100. set(has_dsp3, source.dsp3);
  101. set(has_dsp4, source.dsp4);
  102. set(has_obc1, source.obc1);
  103. set(has_st010, source.st010);
  104. set(has_st011, source.st011);
  105. set(has_st018, source.st018);
  106. }
  107. //==========
  108. //cartinfo_t
  109. //==========
  110. void Cartridge::cartinfo_t::reset() {
  111. type = TypeUnknown;
  112. mapper = LoROM;
  113. dsp1_mapper = DSP1Unmapped;
  114. region = NTSC;
  115. rom_size = 0;
  116. ram_size = 0;
  117. bsx_slot = false;
  118. superfx = false;
  119. sa1 = false;
  120. srtc = false;
  121. sdd1 = false;
  122. spc7110 = false;
  123. spc7110rtc = false;
  124. cx4 = false;
  125. dsp1 = false;
  126. dsp2 = false;
  127. dsp3 = false;
  128. dsp4 = false;
  129. obc1 = false;
  130. st010 = false;
  131. st011 = false;
  132. st018 = false;
  133. }
  134. Cartridge::cartinfo_t::cartinfo_t() {
  135. reset();
  136. }
  137. //=======
  138. //utility
  139. //=======
  140. //ensure file path is absolute (eg resolve relative paths)
  141. string Cartridge::filepath(const char *filename, const char *pathname) {
  142. //if no pathname, return filename as-is
  143. string file(filename);
  144. file.replace("\\", "/");
  145. string path = (!pathname || !*pathname) ? (const char*)snes.config.path.current : pathname;
  146. //ensure path ends with trailing '/'
  147. path.replace("\\", "/");
  148. if(!strend(path, "/")) path.append("/");
  149. //replace relative path with absolute path
  150. if(strbegin(path, "./")) {
  151. ltrim(path, "./");
  152. path = string() << snes.config.path.base << path;
  153. }
  154. //remove folder part of filename
  155. lstring part;
  156. part.split("/", file);
  157. return path << part[part.size() - 1];
  158. }
  159. //remove directory information and file extension ("/foo/bar.ext" -> "bar")
  160. string Cartridge::basename(const char *filename) {
  161. string name(filename);
  162. //remove extension
  163. for(signed i = strlen(name) - 1; i >= 0; i--) {
  164. if(name[i] == '.') {
  165. name[i] = 0;
  166. break;
  167. }
  168. }
  169. //remove directory information
  170. for(signed i = strlen(name) - 1; i >= 0; i--) {
  171. if(name[i] == '/' || name[i] == '\\') {
  172. i++;
  173. char *output = name();
  174. while(true) {
  175. *output++ = name[i];
  176. if(!name[i]) break;
  177. i++;
  178. }
  179. break;
  180. }
  181. }
  182. return name;
  183. }
  184. //remove filename and return path only ("/foo/bar.ext" -> "/foo/bar/")
  185. string Cartridge::basepath(const char *filename) {
  186. string path(filename);
  187. path.replace("\\", "/");
  188. //remove filename
  189. for(signed i = strlen(path) - 1; i >= 0; i--) {
  190. if(path[i] == '/') {
  191. path[i] = 0;
  192. break;
  193. }
  194. }
  195. if(!strend(path, "/")) path.append("/");
  196. return path;
  197. }