swc.c 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358
  1. /*
  2. swc.c - Super Wild Card support for uCON64
  3. Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
  4. Copyright (c) 2001 - 2004 dbjh
  5. Copyright (c) 2001 Caz
  6. Copyright (c) 2003 John Weidman
  7. Copyright (c) 2004 JohnDie
  8. This program is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12. This program is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16. You should have received a copy of the GNU General Public License
  17. along with this program; if not, write to the Free Software
  18. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19. */
  20. #ifdef HAVE_CONFIG_H
  21. #include "config.h"
  22. #endif
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <time.h>
  26. #include <string.h>
  27. #include "misc/misc.h"
  28. #include "misc/itypes.h"
  29. #ifdef USE_ZLIB
  30. #include "misc/archive.h"
  31. #endif
  32. #include "misc/getopt2.h" // st_getopt2_t
  33. #include "misc/file.h"
  34. #include "misc/parallel.h"
  35. #include "ucon64.h"
  36. #include "ucon64_misc.h"
  37. #include "ffe.h"
  38. #include "swc.h"
  39. #include "console/snes.h" // for snes_get_file_type ()
  40. const st_getopt2_t swc_usage[] =
  41. {
  42. {
  43. NULL, 0, 0, 0,
  44. NULL, "Super Com Pro/Super Magicom/SMC/Super Wild Card (1.6XC/2.7CC/2.8CC/DX/DX2)/SWC"
  45. /*"1993/1994/1995/19XX Front Far East/FFE http://www.front.com.tw"*/,
  46. NULL
  47. },
  48. #ifdef USE_PARALLEL
  49. {
  50. "xswc", 0, 0, UCON64_XSWC,
  51. NULL, "send/receive ROM to/from Super Wild Card*/SWC; " OPTION_LONG_S "port=PORT\n"
  52. "receives automatically when ROM does not exist",
  53. &ucon64_wf[WF_OBJ_SNES_DEFAULT_STOP_NO_SPLIT_NO_ROM]
  54. },
  55. {
  56. "xswc2", 0, 0, UCON64_XSWC2,
  57. NULL, "same as " OPTION_LONG_S "xswc, but enables Real Time Save mode (SWC only)",
  58. &ucon64_wf[WF_OBJ_SNES_DEFAULT_STOP_NO_SPLIT_NO_ROM]
  59. },
  60. #if 1
  61. /*
  62. The following help text used to be hidden, because we wanted to avoid people
  63. to "accidentally" create overdumps, bad dumps or report bugs that aren't bugs
  64. (SA-1). However, now that ucon64.io_mode is useful for -xswcc I guess the
  65. help should be complete. - dbjh
  66. */
  67. {
  68. "xswc-io", 1, 0, UCON64_XSWC_IO,
  69. "MODE", "specify SWC I/O mode; use with -xswc or -xswcc\n"
  70. "MODE=0x001 force 32 Mbit dump\n"
  71. "MODE=0x002 use alternative method for determining ROM size\n"
  72. "MODE=0x004 Super FX\n"
  73. "MODE=0x008 S-DD1\n"
  74. "MODE=0x010 SA-1\n"
  75. "MODE=0x020 SPC7110\n"
  76. "MODE=0x040 DX2 trick (might work with other SWC models)\n"
  77. "MODE=0x080 Mega Man X 2\n"
  78. "MODE=0x100 dump BIOS\n"
  79. "It is possible to combine flags. MODE=0x44 makes it possible\n"
  80. "to dump for example Yoshi's Island",
  81. &ucon64_wf[WF_OBJ_SNES_SWITCH]
  82. },
  83. #endif
  84. {
  85. "xswcs", 0, 0, UCON64_XSWCS,
  86. NULL,
  87. "send/receive SRAM to/from Super Wild Card*/SWC; " OPTION_LONG_S "port=PORT\n"
  88. "receives automatically when SRAM does not exist",
  89. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  90. },
  91. {
  92. "xswcc", 0, 0, UCON64_XSWCC,
  93. NULL, "send/receive SRAM to/from cartridge in Super Wild Card*/SWC;\n"
  94. OPTION_LONG_S "port=PORT\n" "receives automatically when SRAM does not exist",
  95. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  96. },
  97. {
  98. "xswcr", 0, 0, UCON64_XSWCR,
  99. NULL, "send/receive RTS data to/from Super Wild Card*/SWC; " OPTION_LONG_S "port=PORT\n"
  100. "receives automatically when RTS file does not exist",
  101. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  102. },
  103. #endif // USE_PARALLEL
  104. {NULL, 0, 0, 0, NULL, NULL, NULL}
  105. };
  106. #ifdef USE_PARALLEL
  107. #define BUFFERSIZE 8192 // don't change, only 8192 works!
  108. /*
  109. Some notes about dumping special chip cartridges (JohnDie):
  110. The following defines enable code to dump cartridges containing special chips
  111. like the SA-1, the S-DD1, the SPC7110 and the C4. However, enabling these
  112. options is not all there is to successfully dump these cartridges.
  113. The SPC7110 and SA-1 need several attempts to "boot up" in the copier. This
  114. involves powering off and on until the chip comes out of reset and allows
  115. access to the cartridge. And you need to make sure that pin 1 of the SNES
  116. adapter of the SWC is not cut! The standard SWC DX2 adapter has this trace
  117. cut, so you have to reconnect it somehow.
  118. Dumping Super FX 2 cartridges is only possible when enabling the DX2 trick.
  119. Otherwise uCON64 will not detect the cartridge. This is because of the way the
  120. Super FX 2 cartridges have their ROM mapped into the SNES address space.
  121. */
  122. #define DUMP_MMX2
  123. #define DUMP_SA1
  124. #define DUMP_SDD1
  125. #define DUMP_SPC7110
  126. static int receive_rom_info (unsigned char *buffer, int io_mode);
  127. static int get_rom_size (unsigned char *info_block);
  128. static int check1 (unsigned char *info_block, int index);
  129. static int check2 (unsigned char *info_block, int index, unsigned char value);
  130. static int check3 (unsigned char *info_block, int index1, int index2, int size);
  131. static unsigned char get_emu_mode_select (unsigned char byte, int size);
  132. static void handle_fig_header (unsigned char *header);
  133. static void set_bank_and_page (unsigned char bank, unsigned char page);
  134. static void read_cartridge (unsigned int address, unsigned char *buffer,
  135. unsigned int length);
  136. static unsigned char read_cartridge1 (unsigned int address);
  137. static void write_cartridge (unsigned int address, unsigned char *buffer,
  138. unsigned int length);
  139. static void write_cartridge1 (unsigned int address, unsigned char byte);
  140. static void dump_rom (FILE *file, int size, int numblocks, unsigned int mask1,
  141. unsigned int mask2, unsigned int address);
  142. static void dump_bios (FILE *file);
  143. static int sub (void);
  144. static int mram_helper (int x);
  145. static int mram (void);
  146. static int hirom; // `hirom' was `special'
  147. static int dx2_trick = 0;
  148. #ifdef DUMP_SA1
  149. static void set_sa1_map (unsigned short chunk);
  150. static int snes_sa1 = 0;
  151. #endif
  152. #ifdef DUMP_SDD1
  153. static void set_sdd1_map (unsigned short chunk);
  154. static int snes_sdd1 = 0;
  155. #endif
  156. #ifdef DUMP_SPC7110
  157. static void set_spc7110_map (unsigned short chunk);
  158. static int snes_spc7110 = 0;
  159. #endif
  160. #if BUFFERSIZE < 512
  161. #error receive_rom_info() and swc_read_sram() expect BUFFERSIZE to be at least \
  162. 512 bytes.
  163. #endif
  164. int
  165. receive_rom_info (unsigned char *buffer, int io_mode)
  166. /*
  167. - returns size of ROM in Mb (128 kB) units
  168. - returns ROM header in buffer (index 2 (emulation mode select) is not yet
  169. filled in)
  170. - sets global `hirom'
  171. */
  172. {
  173. int n, size;
  174. volatile int m;
  175. unsigned char byte;
  176. #ifdef DUMP_MMX2
  177. if (io_mode & SWC_IO_MMX2)
  178. {
  179. /*
  180. MMX2 can be dumped after writing a 0 to SNES register 0x7f52. Before we can
  181. write to that register we have to enable cartridge page mapping. That is
  182. done by writing to SWC register 0xe00c. When cartridge page mapping is
  183. enabled we can access SNES registers by reading or writing to the SWC
  184. address range 0x2000-0x3fff. Before reading or writing to an address in that
  185. range we have to "announce" the address to the SWC (via command 5). Because
  186. we access a SNES register we only set the page number bits (0-1).
  187. */
  188. unsigned short address = 0x7f52;
  189. ffe_send_command0 (0xe00c, 0);
  190. ffe_send_command (5, (unsigned short) (address / 0x2000), 0);
  191. ffe_receive_block ((unsigned short) ((address & 0x1fff) + 0x2000), buffer, 8);
  192. dumper (stdout, buffer, 8, address, DUMPER_HEX);
  193. ffe_send_command (5, (unsigned short) (address / 0x2000), 0);
  194. ffe_send_command0 ((unsigned short) ((address & 0x1fff) + 0x2000), 0);
  195. ffe_send_command (5, (unsigned short) (address / 0x2000), 0);
  196. ffe_receive_block ((unsigned short) ((address & 0x1fff) + 0x2000), buffer, 8);
  197. dumper (stdout, buffer, 8, address, DUMPER_HEX);
  198. }
  199. #endif
  200. ffe_send_command0 (0xe00c, 0);
  201. if (UCON64_ISSET (ucon64.snes_hirom))
  202. hirom = ucon64.snes_hirom ? 1 : 0;
  203. else
  204. {
  205. byte = read_cartridge1 (0x00ffd5);
  206. hirom = ((byte & 1 && byte != 0x23) || byte == 0x3a) ? 1 : 0; // & 1 => 0x21, 0x31, 0x35
  207. }
  208. for (n = 0; n < (int) SWC_HEADER_LEN; n++)
  209. {
  210. for (m = 0; m < 65536; m++) // a delay is necessary here
  211. ;
  212. ffe_send_command (5, (unsigned short) (0x200 + n), 0);
  213. buffer[n] = ffe_send_command1 (0xa0a0);
  214. }
  215. if (io_mode & SWC_IO_FORCE_32MBIT)
  216. {
  217. if (!UCON64_ISSET (ucon64.snes_hirom))
  218. hirom = 1; // default to super HiROM dump
  219. size = 32; // dump 32 Mbit
  220. }
  221. else
  222. {
  223. size = get_rom_size (buffer);
  224. #ifdef DUMP_SA1
  225. if (!snes_sa1)
  226. #endif
  227. if (hirom)
  228. size <<= 1;
  229. }
  230. // Fix up ROM size for Super FX 2 cartridge, because get_rom_size() fails for
  231. // Super FX 2 cartridges and returns 0.
  232. if (io_mode & SWC_IO_SUPER_FX)
  233. // 00:303b returns the GSU revision and is non-zero if there is a GSU
  234. if (size == 0 && read_cartridge1 (0x00303b) != 0)
  235. size = 16;
  236. #ifdef DUMP_SDD1
  237. // Adjust size to 48 Mbit for Star Ocean
  238. if (snes_sdd1 && size == 32)
  239. {
  240. byte = read_cartridge1 (0x00ffd7);
  241. if (byte == 0x0d)
  242. size = 48;
  243. }
  244. #endif
  245. #ifdef DUMP_SA1
  246. // Fix up size for SA-1 chips
  247. if (snes_sa1)
  248. {
  249. byte = read_cartridge1 (0x00ffd7);
  250. switch (byte)
  251. {
  252. case 0x09:
  253. size = 4;
  254. break;
  255. case 0x0a:
  256. size = 8;
  257. break;
  258. case 0x0b:
  259. size = 16;
  260. break;
  261. case 0x0c:
  262. size = 32;
  263. break;
  264. default:
  265. break;
  266. }
  267. }
  268. #endif
  269. #ifdef DUMP_SPC7110
  270. // Fix up size for SPC7110 chips
  271. if (snes_spc7110)
  272. {
  273. byte = read_cartridge1 (0x00ffd7);
  274. switch (byte)
  275. {
  276. case 0x0c:
  277. size = 24;
  278. break;
  279. case 0x0d:
  280. size = 40;
  281. break;
  282. default:
  283. break;
  284. }
  285. }
  286. #endif
  287. memset (buffer, 0, SWC_HEADER_LEN);
  288. buffer[0] = size << 4; // *16 for 8 kB units; low byte
  289. buffer[1] = size >> 4; // *16 for 8 kB units /256 for high byte
  290. buffer[8] = 0xaa;
  291. buffer[9] = 0xbb;
  292. buffer[10] = 4;
  293. return size;
  294. }
  295. int
  296. get_rom_size (unsigned char *info_block)
  297. // returns size of ROM in Mb units
  298. {
  299. if (check1 (info_block, 0))
  300. return 0;
  301. if (check2 (info_block, 0x10, 0x84))
  302. return 0;
  303. if (check3 (info_block, 0, 0x20, 0x20))
  304. return 2;
  305. if (check3 (info_block, 0, 0x40, 0x20))
  306. return 4;
  307. if (check3 (info_block, 0x40, 0x60, 0x20))
  308. return 6;
  309. if (check3 (info_block, 0, 0x80, 0x10))
  310. return 8;
  311. if (check1 (info_block, 0x80))
  312. return 8;
  313. if (check3 (info_block, 0x80, 0x90, 0x10))
  314. return 8;
  315. if (check2 (info_block, 0x80, 0xa0))
  316. return 8;
  317. if (check3 (info_block, 0x80, 0xa0, 0x20))
  318. return 10;
  319. if (check1 (info_block, 0xc0))
  320. return 12;
  321. if (check2 (info_block, 0xc0, 0xb0))
  322. return 12;
  323. if (check3 (info_block, 0x80, 0xc0, 0x20))
  324. return 12;
  325. if (check3 (info_block, 0x100, 0, 0x10))
  326. return 16;
  327. if (check2 (info_block, 0x100, 0xc0))
  328. return 16;
  329. if (check3 (info_block, 0x100, 0x120, 0x10))
  330. return 18;
  331. if (check3 (info_block, 0x100, 0x140, 0x10))
  332. return 20;
  333. if (check2 (info_block, 0x140, 0xd0))
  334. return 20;
  335. if (check3 (info_block, 0x100, 0x180, 0x10))
  336. return 24;
  337. if (check2 (info_block, 0x180, 0xe0))
  338. return 24;
  339. if (check3 (info_block, 0x180, 0x1c0, 0x10))
  340. return 28;
  341. if (check3 (info_block, 0x1f0, 0x1f0, 0x10))
  342. return 32;
  343. return 0;
  344. }
  345. int
  346. check1 (unsigned char *info_block, int index)
  347. {
  348. int n;
  349. for (n = 0; n < 16; n++)
  350. if (info_block[n + index] != info_block[index])
  351. return 0;
  352. return 1;
  353. }
  354. int
  355. check2 (unsigned char *info_block, int index, unsigned char value)
  356. {
  357. int n;
  358. for (n = 0; n < 4; n++)
  359. if (info_block[n + index] != value)
  360. return 0;
  361. return 1;
  362. }
  363. int
  364. check3 (unsigned char *info_block, int index1, int index2, int size)
  365. {
  366. int n;
  367. for (n = 0; n < size; n++)
  368. if (info_block[n + index1] != info_block[n + index2])
  369. return 0;
  370. return 1;
  371. }
  372. unsigned char
  373. get_emu_mode_select (unsigned char byte, int size)
  374. {
  375. int x;
  376. unsigned char ems;
  377. if (byte == 0)
  378. x = 0xc;
  379. else if (byte == 1)
  380. x = 8;
  381. else if (byte == 3)
  382. x = 4;
  383. else
  384. x = 0;
  385. if (hirom)
  386. {
  387. if (x == 0xc && size <= 0x1c)
  388. ems = 0x1c;
  389. else
  390. ems = x + 0x30;
  391. }
  392. else
  393. {
  394. if (x == 0xc)
  395. ems = 0x2c;
  396. else
  397. ems = x;
  398. // if (size <= 8) // This bit should always be 0 - JohnDie
  399. // ems++;
  400. }
  401. return ems;
  402. }
  403. void
  404. handle_fig_header (unsigned char *header)
  405. {
  406. if ((header[4] == 0x77 && header[5] == 0x83) ||
  407. (header[4] == 0xf7 && header[5] == 0x83) ||
  408. (header[4] == 0x47 && header[5] == 0x83))
  409. header[2] = 0x0c; // 0 kB
  410. else if (header[4] == 0xfd && header[5] == 0x82)
  411. header[2] = 0x08; // 2 kB
  412. else if ((header[4] == 0xdd && header[5] == 0x82) ||
  413. (header[4] == 0x00 && header[5] == 0x80))
  414. /*
  415. 8 kB *or* 2 kB (shortcoming of FIG header format). We give the emu mode
  416. select byte a value as if the game uses 8 kB. At least this makes games
  417. that use 8 kB work.
  418. Users should not complain if the game doesn't work because of a SRAM
  419. protection, because they should have converted the ROM to SWC format in
  420. the first place.
  421. */
  422. header[2] = 0x04;
  423. else // if ((header[4] == 0xdd && header[5] == 0x02) ||
  424. // (header[4] == 0x00 && header[5] == 0x00) ||
  425. // (header[4] == 0x11 && header[5] == 0x02))
  426. header[2] = 0; // 32 kB
  427. if (header[3] & 0x80) // Pro Fighter (FIG) HiROM dump
  428. header[2] |= 0x30; // set bit 5&4 (SRAM & DRAM mem map mode 21)
  429. }
  430. void
  431. swc_unlock (unsigned int parport)
  432. /*
  433. "Unlock" the SWC. However, just starting to send, then stopping with ^C,
  434. gives the same result.
  435. */
  436. {
  437. ffe_init_io (parport);
  438. ffe_send_command (6, 0, 0);
  439. ffe_deinit_io ();
  440. }
  441. #ifdef DUMP_SA1
  442. void
  443. set_sa1_map (unsigned short chunk)
  444. {
  445. volatile int m;
  446. // map the 8 Mbit ROM chunk specified by chunk into the F0 bank
  447. write_cartridge1 (0x002223, (unsigned char) ((chunk & 0x07) | 0x80));
  448. for (m = 0; m < 65536; m++)
  449. ;
  450. }
  451. #endif
  452. #ifdef DUMP_SDD1
  453. void
  454. set_sdd1_map (unsigned short chunk)
  455. {
  456. volatile int m;
  457. // map the 8 Mbit ROM chunk specified by chunk into the F0 bank
  458. write_cartridge1 (0x004807, (unsigned char) (chunk & 0x07));
  459. for (m = 0; m < 65536; m++)
  460. ;
  461. }
  462. #endif
  463. #ifdef DUMP_SPC7110
  464. void
  465. set_spc7110_map (unsigned short chunk)
  466. {
  467. volatile int m;
  468. // map the 8 Mbit ROM chunk specified by chunk into the F0 bank
  469. write_cartridge1 (0x004834, 0xff);
  470. write_cartridge1 (0x004833, (unsigned char) (chunk & 0x07));
  471. for (m = 0; m < 65536; m++)
  472. ;
  473. }
  474. #endif
  475. void
  476. set_bank_and_page (unsigned char bank, unsigned char page)
  477. {
  478. static unsigned char currentbank = 0, currentpage = 4; // Force update on first call
  479. page &= 3;
  480. #if 0
  481. // We only send a command to the SWC if the bank or page differs.
  482. /*
  483. In order to avoid problems with that no other code should change the bank or
  484. page number. So, no calls to ffe_send_command(5, ...). I prefer to be able
  485. to call ffe_send_command(5, ...) without breaking this function. Besides,
  486. the benefit of this optimisation is rather small. - dbjh
  487. */
  488. if (bank != currentbank || page != currentpage)
  489. #endif
  490. {
  491. currentbank = bank;
  492. currentpage = page;
  493. if (dx2_trick)
  494. {
  495. /*
  496. The SWC DX2 does not allow to access banks 00-7f. But this is needed
  497. to dump some cartridges (ToP, DKJM2 and Super FX 2). This trick
  498. avoids using ffe_send_command(5, ...) to set the bank value and
  499. writes the bank value directly into the SNES RAM where the DX2 BIOS
  500. would store it. Note that this hack is specific to the SWC DX2 and
  501. will probably not work with other copiers. - JohnDie
  502. */
  503. ffe_send_command (5, currentpage, 0);
  504. ffe_send_command0 (0x0007, currentbank);
  505. }
  506. else
  507. ffe_send_command (5, (unsigned short) ((currentbank << 2) | currentpage), 0);
  508. }
  509. }
  510. void
  511. read_cartridge (unsigned int address, unsigned char *buffer, unsigned int length)
  512. {
  513. address &= 0xffffff;
  514. set_bank_and_page ((unsigned char) (address >> 16),
  515. (unsigned char) ((address & 0x7fff) / 0x2000));
  516. if ((address & 0x00ffff) < 0x8000)
  517. ffe_receive_block ((unsigned short) (((address & 0x7fffff) < 0x400000 ?
  518. 0x6000 : 0x2000) + (address & 0x001fff)), buffer, length);
  519. else
  520. ffe_receive_block ((unsigned short) (0xa000 + (address & 0x001fff)),
  521. buffer, length);
  522. }
  523. unsigned char
  524. read_cartridge1 (unsigned int address)
  525. {
  526. unsigned char byte;
  527. read_cartridge (address, &byte, 1);
  528. return byte;
  529. }
  530. void
  531. write_cartridge (unsigned int address, unsigned char *buffer, unsigned int length)
  532. {
  533. address &= 0xffffff;
  534. set_bank_and_page ((unsigned char) (address >> 16),
  535. (unsigned char) ((address & 0x7fff) / 0x2000));
  536. if ((address & 0x00ffff) < 0x8000)
  537. ffe_send_block ((unsigned short) (((address & 0x7fffff) < 0x400000 ?
  538. 0x6000 : 0x2000) + (address & 0x001fff)), buffer, length);
  539. else
  540. ffe_send_block ((unsigned short) (0xa000 + (address & 0x001fff)),
  541. buffer, length);
  542. }
  543. void
  544. write_cartridge1 (unsigned int address, unsigned char byte)
  545. {
  546. write_cartridge (address, &byte, 1);
  547. }
  548. void
  549. dump_rom (FILE *file, int size, int numblocks, unsigned int mask1,
  550. unsigned int mask2, unsigned int address)
  551. {
  552. int i, bytesreceived = 0;
  553. unsigned char *buffer;
  554. time_t starttime;
  555. #if defined DUMP_SA1 || defined DUMP_SDD1 || defined DUMP_SPC7110
  556. unsigned short chunk_num = 0; // 0 = 1st 8 Mb ROM chunk, 1 = 2nd 8 Mb, ...
  557. #endif
  558. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  559. {
  560. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  561. exit (1);
  562. }
  563. starttime = time (NULL);
  564. for (i = 0; i < numblocks; i++)
  565. {
  566. address |= mask1; // make sure to stay in ROM areas
  567. address &= mask2;
  568. #ifdef DUMP_SA1
  569. if (snes_sa1 && address == 0xf00000)
  570. set_sa1_map (chunk_num++);
  571. #endif
  572. #ifdef DUMP_SDD1
  573. if (snes_sdd1 && address == 0xf00000)
  574. set_sdd1_map (chunk_num++);
  575. #endif
  576. #ifdef DUMP_SPC7110
  577. if (snes_spc7110 && address == 0xf00000)
  578. set_spc7110_map (chunk_num++);
  579. #endif
  580. read_cartridge (address, buffer, BUFFERSIZE);
  581. fwrite (buffer, 1, BUFFERSIZE, file);
  582. address += BUFFERSIZE;
  583. bytesreceived += BUFFERSIZE;
  584. ucon64_gauge (starttime, bytesreceived, size);
  585. ffe_checkabort (2);
  586. }
  587. ffe_send_command (5, 0, 0);
  588. free (buffer);
  589. }
  590. void
  591. dump_bios (FILE *file)
  592. {
  593. unsigned short int address;
  594. int bytesreceived = 0;
  595. unsigned char *buffer;
  596. time_t starttime;
  597. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  598. {
  599. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  600. exit (1);
  601. }
  602. starttime = time (NULL);
  603. for (address = 0; address < 0x080; address += 4) // banks 00-1f
  604. {
  605. ffe_send_command (5, address, 0);
  606. ffe_receive_block (0xe000, buffer, BUFFERSIZE);
  607. fwrite (buffer, 1, BUFFERSIZE, file);
  608. bytesreceived += BUFFERSIZE;
  609. ucon64_gauge (starttime, bytesreceived, 0x20 * 0x2000);
  610. ffe_checkabort (2);
  611. }
  612. free (buffer);
  613. }
  614. int
  615. swc_read_rom (const char *filename, unsigned int parport, int io_mode)
  616. {
  617. FILE *file;
  618. unsigned char buffer[SWC_HEADER_LEN], byte;
  619. int size, blocksleft;
  620. ffe_init_io (parport);
  621. #ifdef DUMP_SA1
  622. if (io_mode & SWC_IO_SA1)
  623. snes_sa1 = 1;
  624. #endif
  625. #ifdef DUMP_SDD1
  626. if (io_mode & SWC_IO_SDD1)
  627. snes_sdd1 = 1;
  628. #endif
  629. #ifdef DUMP_SPC7110
  630. if (io_mode & SWC_IO_SPC7110)
  631. snes_spc7110 = 1;
  632. #endif
  633. if (io_mode & SWC_IO_DX2_TRICK)
  634. dx2_trick = 1;
  635. if ((file = fopen (filename, "wb")) == NULL)
  636. {
  637. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  638. exit (1);
  639. }
  640. if (io_mode & SWC_IO_DUMP_BIOS)
  641. {
  642. puts ("Press q to abort\n");
  643. dump_bios (file);
  644. ffe_deinit_io ();
  645. fclose (file);
  646. return 0; // skip the other code in this function
  647. }
  648. size = receive_rom_info (buffer, io_mode);
  649. if (size == 0)
  650. {
  651. fputs ("ERROR: There is no cartridge present in the Super Wild Card\n", stderr);
  652. fclose (file);
  653. remove (filename);
  654. exit (1);
  655. }
  656. blocksleft = size * 16; // 1 Mb (128 kB) unit == 16 8 kB units
  657. printf ("Receive: %d Bytes (%.4f Mb)\n", size * MBIT, (float) size);
  658. #ifdef DUMP_SA1
  659. if (snes_sa1)
  660. puts ("NOTE: Dumping SA-1 cartridge");
  661. #endif
  662. #ifdef DUMP_SDD1
  663. if (snes_sdd1)
  664. puts ("NOTE: Dumping S-DD1 cartridge");
  665. #endif
  666. #ifdef DUMP_SPC7110
  667. if (snes_spc7110)
  668. puts ("NOTE: Dumping SPC7110 cartridge");
  669. #endif
  670. size *= MBIT; // size in bytes for ucon64_gauge() below
  671. ffe_send_command (5, 0, 0);
  672. ffe_send_command0 (0xe00c, 0);
  673. byte = ffe_send_command1 (0xbfd8);
  674. buffer[2] = get_emu_mode_select (byte, blocksleft / 16);
  675. fwrite (buffer, 1, SWC_HEADER_LEN, file); // write header (other necessary fields are
  676. // filled in by receive_rom_info())
  677. puts ("Press q to abort\n"); // print here, NOT before first SWC I/O,
  678. // because if we get here q works ;-)
  679. #ifdef DUMP_SA1
  680. if (snes_sa1)
  681. dump_rom (file, size, blocksleft, 0xf00000, 0xffffff, 0xf00000);
  682. else
  683. #endif
  684. #ifdef DUMP_SDD1
  685. if (snes_sdd1)
  686. dump_rom (file, size, blocksleft, 0xf00000, 0xffffff, 0xf00000);
  687. else
  688. #endif
  689. #ifdef DUMP_SPC7110
  690. if (snes_spc7110)
  691. {
  692. // First dump the 8 MBit P-ROM (program ROM)
  693. dump_rom (file, 8 * MBIT, 8 * 16, 0xc00000, 0xcfffff, 0xc00000);
  694. // Then dump the remaining amount of D-ROM (data ROM)
  695. dump_rom (file, size - 8 * MBIT, blocksleft - 8 * 16, 0xf00000, 0xffffff,
  696. 0xf00000);
  697. }
  698. else
  699. #endif
  700. if (io_mode & SWC_IO_SUPER_FX)
  701. dump_rom (file, size, blocksleft, 0x008000, 0x7fffff, 0x008000);
  702. else if (hirom)
  703. dump_rom (file, size, blocksleft, 0x400000, 0xffffff, 0xc00000);
  704. else
  705. dump_rom (file, size, blocksleft, 0x008000, 0xffffff, 0x808000);
  706. #ifdef DUMP_SA1
  707. if (snes_sa1)
  708. set_sa1_map (3);
  709. #endif
  710. #ifdef DUMP_SDD1
  711. if (snes_sdd1)
  712. set_sdd1_map (3);
  713. #endif
  714. ffe_send_command (5, 0, 0);
  715. fclose (file);
  716. ffe_deinit_io ();
  717. return 0;
  718. }
  719. int
  720. swc_write_rom (const char *filename, unsigned int parport, int enableRTS)
  721. {
  722. FILE *file;
  723. unsigned char *buffer;
  724. int bytesread, bytessend, totalblocks, blocksdone = 0, emu_mode_select, fsize;
  725. unsigned short address;
  726. time_t starttime;
  727. ffe_init_io (parport);
  728. if ((file = fopen (filename, "rb")) == NULL)
  729. {
  730. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  731. exit (1);
  732. }
  733. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  734. {
  735. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  736. exit (1);
  737. }
  738. fsize = fsizeof (filename);
  739. printf ("Send: %d Bytes (%.4f Mb)\n", fsize, (float) fsize / MBIT);
  740. ffe_send_command0 (0xc008, 0);
  741. fread (buffer, 1, SWC_HEADER_LEN, file);
  742. if (snes_get_file_type () == FIG)
  743. handle_fig_header (buffer);
  744. #if 1
  745. /*
  746. 0x0c == no SRAM & LoROM; we use the header, so that the user can override this
  747. bit 4 == 0 => DRAM mode 20 (LoROM); disable SRAM by setting SRAM mem map mode 2
  748. */
  749. if ((buffer[2] & 0x1c) == 0x0c)
  750. buffer[2] |= 0x20;
  751. #else
  752. // The code below doesn't work for some HiROM games that don't use SRAM.
  753. if ((buffer[2] & 0x0c) == 0x0c) // 0x0c == no SRAM; we use the header, so
  754. { // that the user can override this
  755. if (buffer[2] & 0x10) // bit 4 == 1 => DRAM mode 21 (HiROM)
  756. buffer[2] &= ~0x20; // disable SRAM by setting SRAM mem map mode 1
  757. else // bit 4 == 0 => DRAM mode 20 (LoROM)
  758. buffer[2] |= 0x20; // disable SRAM by setting SRAM mem map mode 2
  759. }
  760. #endif
  761. emu_mode_select = buffer[2]; // this byte is needed later
  762. #if 1 // sending the header is not required
  763. ffe_send_command (5, 0, 0);
  764. ffe_send_block (0x400, buffer, SWC_HEADER_LEN); // send header
  765. #endif
  766. bytessend = SWC_HEADER_LEN;
  767. puts ("Press q to abort\n"); // print here, NOT before first SWC I/O,
  768. // because if we get here q works ;-)
  769. address = 0x200; // VGS '00 uses 0x200, VGS '96 uses 0,
  770. starttime = time (NULL); // but then some ROMs don't work
  771. while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
  772. {
  773. ffe_send_command0 ((unsigned short) 0xc010, (unsigned char) (blocksdone >> 9));
  774. ffe_send_command (5, address, 0);
  775. ffe_send_block (0x8000, buffer, bytesread);
  776. address++;
  777. blocksdone++;
  778. bytessend += bytesread;
  779. ucon64_gauge (starttime, bytessend, fsize);
  780. ffe_checkabort (2);
  781. }
  782. if (blocksdone > 0x200) // ROM dump > 512 8 kB blocks (=32 Mb (=4 MB))
  783. ffe_send_command0 (0xc010, 2);
  784. ffe_send_command (5, 0, 0);
  785. totalblocks = (fsize - SWC_HEADER_LEN + BUFFERSIZE - 1) / BUFFERSIZE; // round up
  786. ffe_send_command (6, (unsigned short) (5 | (totalblocks << 8)), (unsigned short) (totalblocks >> 8)); // bytes: 6, 5, #8 K L, #8 K H, 0
  787. ffe_send_command (6, (unsigned short) (1 | (emu_mode_select << 8)), (unsigned short) enableRTS); // last arg = 1 enables RTS
  788. // mode, 0 disables it
  789. ffe_wait_for_ready ();
  790. outportb ((unsigned short) (parport + PARPORT_DATA), 0);
  791. outportb ((unsigned short) (parport + PARPORT_CONTROL),
  792. (unsigned char) (inportb ((unsigned short) // invert strobe
  793. (parport + PARPORT_CONTROL)) ^ PARPORT_STROBE));
  794. free (buffer);
  795. fclose (file);
  796. ffe_deinit_io ();
  797. return 0;
  798. }
  799. int
  800. swc_read_sram (const char *filename, unsigned int parport)
  801. {
  802. FILE *file;
  803. unsigned char *buffer;
  804. int blocksleft, bytesreceived = 0;
  805. unsigned short address;
  806. time_t starttime;
  807. ffe_init_io (parport);
  808. if ((file = fopen (filename, "wb")) == NULL)
  809. {
  810. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  811. exit (1);
  812. }
  813. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  814. {
  815. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  816. exit (1);
  817. }
  818. printf ("Receive: %d Bytes\n", 32 * 1024);
  819. memset (buffer, 0, SWC_HEADER_LEN);
  820. buffer[8] = 0xaa;
  821. buffer[9] = 0xbb;
  822. buffer[10] = 5;
  823. fwrite (buffer, 1, SWC_HEADER_LEN, file);
  824. ffe_send_command (5, 0, 0);
  825. ffe_send_command0 (0xe00d, 0);
  826. ffe_send_command0 (0xc008, 0);
  827. puts ("Press q to abort\n"); // print here, NOT before first SWC I/O,
  828. // because if we get here q works ;-)
  829. blocksleft = 4; // SRAM is 4*8 kB
  830. address = 0x100;
  831. starttime = time (NULL);
  832. while (blocksleft > 0)
  833. {
  834. ffe_send_command (5, address, 0);
  835. ffe_receive_block (0x2000, buffer, BUFFERSIZE);
  836. blocksleft--;
  837. address++;
  838. fwrite (buffer, 1, BUFFERSIZE, file);
  839. bytesreceived += BUFFERSIZE;
  840. ucon64_gauge (starttime, bytesreceived, 32 * 1024);
  841. ffe_checkabort (2);
  842. }
  843. free (buffer);
  844. fclose (file);
  845. ffe_deinit_io ();
  846. return 0;
  847. }
  848. int
  849. swc_write_sram (const char *filename, unsigned int parport)
  850. {
  851. FILE *file;
  852. unsigned char *buffer;
  853. int bytesread, bytessend = 0, size;
  854. unsigned short address;
  855. time_t starttime;
  856. ffe_init_io (parport);
  857. if ((file = fopen (filename, "rb")) == NULL)
  858. {
  859. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  860. exit (1);
  861. }
  862. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  863. {
  864. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  865. exit (1);
  866. }
  867. size = fsizeof (filename) - SWC_HEADER_LEN; // SWC SRAM is 4*8 kB, emu SRAM often not
  868. printf ("Send: %d Bytes\n", size);
  869. fseek (file, SWC_HEADER_LEN, SEEK_SET); // skip the header
  870. ffe_send_command (5, 0, 0);
  871. ffe_send_command0 (0xe00d, 0);
  872. ffe_send_command0 (0xc008, 0);
  873. puts ("Press q to abort\n"); // print here, NOT before first SWC I/O,
  874. // because if we get here q works ;-)
  875. address = 0x100;
  876. starttime = time (NULL);
  877. while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
  878. {
  879. ffe_send_command (5, address, 0);
  880. ffe_send_block (0x2000, buffer, bytesread);
  881. address++;
  882. bytessend += bytesread;
  883. ucon64_gauge (starttime, bytessend, size);
  884. ffe_checkabort (2);
  885. }
  886. free (buffer);
  887. fclose (file);
  888. ffe_deinit_io ();
  889. return 0;
  890. }
  891. int
  892. sub (void)
  893. {
  894. ffe_send_command (5, 7 * 4, 0);
  895. ffe_send_command0 (0xe00d, 0);
  896. ffe_send_command0 (0xe003, 0);
  897. if (ffe_send_command1 (0xb080) != 'S')
  898. return 0;
  899. if (ffe_send_command1 (0xb081) != 'U')
  900. return 0;
  901. if (ffe_send_command1 (0xb082) != 'B')
  902. return 0;
  903. return 1;
  904. }
  905. int
  906. mram_helper (int x)
  907. {
  908. ffe_send_command (5, (unsigned short) x, 0);
  909. x = ffe_send_command1 (0x8000);
  910. ffe_send_command0 (0x8000, (unsigned char) (x ^ 0xff));
  911. if (ffe_send_command1 (0x8000) != (unsigned char) (x ^ 0xff))
  912. return 0;
  913. ffe_send_command0 (0x8000, (unsigned char) x);
  914. return 1;
  915. }
  916. int
  917. mram (void)
  918. {
  919. if (mram_helper (0x76 * 4))
  920. return 0x76 * 4;
  921. if (mram_helper (0x56 * 4))
  922. return 0x56 * 4;
  923. if (mram_helper (0x36 * 4))
  924. return 0x36 * 4;
  925. return 0x16 * 4;
  926. }
  927. int
  928. swc_read_rts (const char *filename, unsigned int parport)
  929. {
  930. FILE *file;
  931. unsigned char *buffer;
  932. int blocksleft, bytesreceived = 0;
  933. unsigned short address1, address2;
  934. time_t starttime;
  935. ffe_init_io (parport);
  936. if ((file = fopen (filename, "wb")) == NULL)
  937. {
  938. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  939. exit (1);
  940. }
  941. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  942. {
  943. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  944. exit (1);
  945. }
  946. printf ("Receive: %d Bytes\n", 256 * 1024);
  947. memset (buffer, 0, SWC_HEADER_LEN);
  948. buffer[8] = 0xaa;
  949. buffer[9] = 0xbb;
  950. buffer[10] = 8;
  951. fwrite (buffer, 1, SWC_HEADER_LEN, file);
  952. puts ("Press q to abort\n");
  953. blocksleft = 32; // RTS data is 32*8 kB
  954. if (sub ())
  955. {
  956. address1 = 0;
  957. address2 = 0xa000;
  958. }
  959. else
  960. {
  961. address1 = mram ();
  962. address2 = 0x8000;
  963. }
  964. starttime = time (NULL);
  965. while (blocksleft > 0)
  966. {
  967. ffe_send_command (5, address1, 0);
  968. if (address2 == 0x8000)
  969. ffe_send_command0 (0xc010, 1);
  970. ffe_receive_block (address2, buffer, BUFFERSIZE);
  971. blocksleft--;
  972. address1++;
  973. fwrite (buffer, 1, BUFFERSIZE, file);
  974. bytesreceived += BUFFERSIZE;
  975. ucon64_gauge (starttime, bytesreceived, 256 * 1024);
  976. ffe_checkabort (2);
  977. }
  978. ffe_send_command (6, 3, 0);
  979. free (buffer);
  980. fclose (file);
  981. ffe_deinit_io ();
  982. return 0;
  983. }
  984. int
  985. swc_write_rts (const char *filename, unsigned int parport)
  986. {
  987. FILE *file;
  988. unsigned char *buffer;
  989. int bytesread, bytessend = 0, size;
  990. unsigned short address1, address2;
  991. time_t starttime;
  992. ffe_init_io (parport);
  993. if ((file = fopen (filename, "rb")) == NULL)
  994. {
  995. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  996. exit (1);
  997. }
  998. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  999. {
  1000. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  1001. exit (1);
  1002. }
  1003. size = fsizeof (filename) - SWC_HEADER_LEN;
  1004. printf ("Send: %d Bytes\n", size);
  1005. fseek (file, SWC_HEADER_LEN, SEEK_SET); // skip the header
  1006. puts ("Press q to abort\n");
  1007. if (sub ())
  1008. {
  1009. address1 = 0;
  1010. address2 = 0xa000;
  1011. }
  1012. else
  1013. {
  1014. address1 = mram ();
  1015. address2 = 0x8000;
  1016. }
  1017. starttime = time (NULL);
  1018. while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
  1019. {
  1020. ffe_send_command (5, address1, 0);
  1021. if (address2 == 0x8000)
  1022. ffe_send_command0 (0xc010, 1);
  1023. ffe_send_block (address2, buffer, bytesread);
  1024. address1++;
  1025. bytessend += bytesread;
  1026. ucon64_gauge (starttime, bytessend, size);
  1027. ffe_checkabort (2);
  1028. }
  1029. ffe_send_command (6, 3, 0);
  1030. free (buffer);
  1031. fclose (file);
  1032. ffe_deinit_io ();
  1033. return 0;
  1034. }
  1035. int
  1036. swc_read_cart_sram (const char *filename, unsigned int parport, int io_mode)
  1037. {
  1038. FILE *file;
  1039. unsigned char *buffer, byte;
  1040. int bytesreceived = 0, size;
  1041. unsigned short address;
  1042. time_t starttime;
  1043. ffe_init_io (parport);
  1044. if (io_mode & SWC_IO_DX2_TRICK)
  1045. dx2_trick = 1;
  1046. if ((file = fopen (filename, "wb")) == NULL)
  1047. {
  1048. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  1049. exit (1);
  1050. }
  1051. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  1052. {
  1053. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  1054. exit (1);
  1055. }
  1056. size = receive_rom_info (buffer, io_mode);
  1057. if (size == 0)
  1058. {
  1059. fputs ("ERROR: There is no cartridge present in the Super Wild Card\n", stderr);
  1060. fclose (file);
  1061. remove (filename);
  1062. exit (1);
  1063. }
  1064. ffe_send_command (5, 3, 0); // detect cartridge SRAM size because
  1065. ffe_send_command0 (0xe00c, 0); // we don't want to read too few data
  1066. byte = read_cartridge1 (io_mode & SWC_IO_SUPER_FX ? 0x00ffbd : 0x00ffd8);
  1067. size = MAX ((byte ? 1 << (byte + 10) : 0), 32 * 1024);
  1068. printf ("Receive: %d Bytes\n", size);
  1069. memset (buffer, 0, SWC_HEADER_LEN);
  1070. buffer[8] = 0xaa;
  1071. buffer[9] = 0xbb;
  1072. buffer[10] = 5;
  1073. fwrite (buffer, 1, SWC_HEADER_LEN, file);
  1074. ffe_send_command (5, 0, 0);
  1075. ffe_send_command0 (0xe00c, 0);
  1076. // ffe_send_command0 (0xc008, 0);
  1077. puts ("Press q to abort\n"); // print here, NOT before first SWC I/O,
  1078. // because if we get here q works ;-)
  1079. address = hirom ? 0x2c3 : 0x1c0;
  1080. starttime = time (NULL);
  1081. while (bytesreceived < size)
  1082. {
  1083. set_bank_and_page ((unsigned char) (address >> 2), (unsigned char) (address & 3));
  1084. ffe_receive_block ((unsigned short) (hirom ? 0x6000 : 0x2000), buffer, BUFFERSIZE);
  1085. fwrite (buffer, 1, BUFFERSIZE, file);
  1086. address += hirom ? 4 : 1;
  1087. bytesreceived += BUFFERSIZE;
  1088. ucon64_gauge (starttime, bytesreceived, size);
  1089. ffe_checkabort (2);
  1090. }
  1091. free (buffer);
  1092. fclose (file);
  1093. ffe_deinit_io ();
  1094. return 0;
  1095. }
  1096. int
  1097. swc_write_cart_sram (const char *filename, unsigned int parport, int io_mode)
  1098. {
  1099. FILE *file;
  1100. unsigned char *buffer, byte;
  1101. int bytesread, bytessend = 0, size;
  1102. unsigned short address;
  1103. time_t starttime;
  1104. ffe_init_io (parport);
  1105. if (io_mode & SWC_IO_DX2_TRICK)
  1106. dx2_trick = 1;
  1107. if ((file = fopen (filename, "rb")) == NULL)
  1108. {
  1109. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  1110. exit (1);
  1111. }
  1112. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  1113. {
  1114. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  1115. exit (1);
  1116. }
  1117. size = receive_rom_info (buffer, io_mode);
  1118. if (size == 0)
  1119. {
  1120. fputs ("ERROR: There is no cartridge present in the Super Wild Card\n", stderr);
  1121. fclose (file);
  1122. exit (1);
  1123. }
  1124. ffe_send_command (5, 3, 0); // detect cartridge SRAM size because we don't
  1125. ffe_send_command0 (0xe00c, 0); // want to write more data than necessary
  1126. byte = read_cartridge1 (io_mode & SWC_IO_SUPER_FX ? 0x00ffbd : 0x00ffd8);
  1127. size = fsizeof (filename) - SWC_HEADER_LEN; // SWC SRAM is 4*8 kB, emu SRAM often not
  1128. size = MIN ((byte ? 1 << (byte + 10) : 0), size);
  1129. printf ("Send: %d Bytes\n", size);
  1130. fseek (file, SWC_HEADER_LEN, SEEK_SET); // skip the header
  1131. ffe_send_command (5, 0, 0);
  1132. ffe_send_command0 (0xe00c, 0);
  1133. // ffe_send_command0 (0xc008, 0);
  1134. puts ("Press q to abort\n"); // print here, NOT before first SWC I/O,
  1135. // because if we get here q works ;-)
  1136. address = hirom ? 0x2c3 : 0x1c0;
  1137. starttime = time (NULL);
  1138. while ((bytessend < size) && (bytesread = fread (buffer, 1, MIN (size, BUFFERSIZE), file)))
  1139. {
  1140. set_bank_and_page ((unsigned char) (address >> 2), (unsigned char) (address & 3));
  1141. ffe_send_block ((unsigned short) (hirom ? 0x6000 : 0x2000), buffer, bytesread);
  1142. address += hirom ? 4 : 1;
  1143. bytessend += bytesread;
  1144. ucon64_gauge (starttime, bytessend, size);
  1145. ffe_checkabort (2);
  1146. }
  1147. free (buffer);
  1148. fclose (file);
  1149. ffe_deinit_io ();
  1150. return 0;
  1151. }
  1152. #endif // USE_PARALLEL