fig.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. /*
  2. fig.c - Super PRO Fighter support for uCON64
  3. Copyright (c) 1999 - 2002 NoisyB
  4. Copyright (c) 2001 - 2004 dbjh
  5. Copyright (c) 2003 - 2004 JohnDie
  6. This program is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program; if not, write to the Free Software
  16. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include "misc/archive.h"
  24. #include "misc/file.h"
  25. #include "ucon64_misc.h"
  26. #include "console/snes.h" // for snes_get_snes_hirom()
  27. #include "backup/ffe.h"
  28. #include "backup/fig.h"
  29. #ifdef USE_PARALLEL
  30. static st_ucon64_obj_t fig_obj[] =
  31. {
  32. {UCON64_SNES, WF_DEFAULT | WF_STOP | WF_NO_SPLIT | WF_NO_ROM},
  33. {UCON64_SNES, WF_STOP | WF_NO_ROM}
  34. };
  35. #endif
  36. const st_getopt2_t fig_usage[] =
  37. {
  38. {
  39. NULL, 0, 0, 0,
  40. NULL, "Super Pro Fighter (Q/Q+)/Pro Fighter X (Turbo 2)/Double Pro Fighter (X Turbo)"
  41. /*"1993/1994/19XX China Coach Limited/CCL http://www.ccltw.com.tw"*/,
  42. NULL
  43. },
  44. #ifdef USE_PARALLEL
  45. {
  46. "xfig", 0, 0, UCON64_XFIG,
  47. NULL, "send/receive ROM to/from *Pro Fighter*/FIG; " OPTION_LONG_S "port=PORT\n"
  48. "receives automatically when ROM does not exist",
  49. &fig_obj[0]
  50. },
  51. {
  52. "xfigs", 0, 0, UCON64_XFIGS,
  53. NULL, "send/receive SRAM to/from *Pro Fighter*/FIG; " OPTION_LONG_S "port=PORT\n"
  54. "receives automatically when SRAM does not exist",
  55. &fig_obj[1]
  56. },
  57. {
  58. "xfigc", 0, 0, UCON64_XFIGC, NULL,
  59. "send/receive SRAM to/from cartridge in *Pro Fighter*/FIG;\n" OPTION_LONG_S "port=PORT\n"
  60. "receives automatically when SRAM does not exist",
  61. // "Press q to abort; ^C might cause invalid state of backup unit"
  62. &fig_obj[1]
  63. },
  64. #endif
  65. {NULL, 0, 0, 0, NULL, NULL, NULL}
  66. };
  67. #ifdef USE_PARALLEL
  68. #define BUFFERSIZE 8192 // don't change, only 8192 works!
  69. static int receive_rom_info (unsigned char *buffer);
  70. static unsigned char get_rom_size (unsigned char *info_block);
  71. static int check1 (unsigned char *info_block, int index);
  72. static int check2 (unsigned char *info_block, int index, unsigned char value);
  73. static int check3 (unsigned char *info_block, int index1, int index2, int size);
  74. static void handle_swc_header (unsigned char *header);
  75. static int hirom;
  76. #if BUFFERSIZE < 512
  77. #error receive_rom_info() and fig_read_sram() expect BUFFERSIZE to be at least \
  78. 512 bytes.
  79. #endif
  80. static int
  81. receive_rom_info (unsigned char *buffer)
  82. /*
  83. - returns size of ROM in Mb (128 kB) units
  84. - sets global `hirom'
  85. */
  86. {
  87. unsigned short n;
  88. volatile int m;
  89. unsigned char byte, size;
  90. ffe_send_command0 (0xe00c, 0);
  91. if (UCON64_ISSET (ucon64.snes_hirom))
  92. hirom = ucon64.snes_hirom ? 1 : 0;
  93. else
  94. {
  95. ffe_send_command (5, 3, 0);
  96. byte = ffe_send_command1 (0xbfd5);
  97. if ((byte & 1 && byte != 0x23) || byte == 0x3a) // & 1 => 0x21, 0x31, 0x35
  98. hirom = 1;
  99. }
  100. for (n = 0; n < FIG_HEADER_LEN; n++)
  101. {
  102. for (m = 0; m < 65536; m++) // a delay is necessary here
  103. ;
  104. ffe_send_command (5, 0x200 + n, 0);
  105. buffer[n] = ffe_send_command1 (0xa0a0);
  106. }
  107. size = get_rom_size (buffer);
  108. if (hirom)
  109. size <<= 1;
  110. return size;
  111. }
  112. static unsigned char
  113. get_rom_size (unsigned char *info_block)
  114. // returns size of ROM in Mb units
  115. {
  116. if (check1 (info_block, 0))
  117. return 0;
  118. if (check2 (info_block, 0x10, 0x84))
  119. return 0;
  120. if (check3 (info_block, 0, 0x20, 0x20))
  121. return 2;
  122. if (check3 (info_block, 0, 0x40, 0x20))
  123. return 4;
  124. if (check3 (info_block, 0x40, 0x60, 0x20))
  125. return 6;
  126. if (check3 (info_block, 0, 0x80, 0x10))
  127. return 8;
  128. if (check1 (info_block, 0x80))
  129. return 8;
  130. if (check3 (info_block, 0x80, 0x90, 0x10))
  131. return 8;
  132. if (check2 (info_block, 0x80, 0xa0))
  133. return 8;
  134. if (check3 (info_block, 0x80, 0xa0, 0x20))
  135. return 0xa;
  136. if (check1 (info_block, 0xc0))
  137. return 0xc;
  138. if (check2 (info_block, 0xc0, 0xb0))
  139. return 0xc;
  140. if (check3 (info_block, 0x80, 0xc0, 0x20))
  141. return 0xc;
  142. if (check3 (info_block, 0x100, 0, 0x10))
  143. return 0x10;
  144. if (check2 (info_block, 0x100, 0xc0))
  145. return 0x10;
  146. if (check3 (info_block, 0x100, 0x120, 0x10))
  147. return 0x12;
  148. if (check3 (info_block, 0x100, 0x140, 0x10))
  149. return 0x14;
  150. if (check2 (info_block, 0x140, 0xd0))
  151. return 0x14;
  152. if (check3 (info_block, 0x100, 0x180, 0x10))
  153. return 0x18;
  154. if (check2 (info_block, 0x180, 0xe0))
  155. return 0x18;
  156. if (check3 (info_block, 0x180, 0x1c0, 0x10))
  157. return 0x1c;
  158. if (check3 (info_block, 0x1f0, 0x1f0, 0x10))
  159. return 0x20;
  160. return 0;
  161. }
  162. static int
  163. check1 (unsigned char *info_block, int index)
  164. {
  165. int n;
  166. for (n = 0; n < 16; n++)
  167. if (info_block[n + index] != info_block[index])
  168. return 0;
  169. return 1;
  170. }
  171. static int
  172. check2 (unsigned char *info_block, int index, unsigned char value)
  173. {
  174. int n;
  175. for (n = 0; n < 4; n++)
  176. if (info_block[n + index] != value)
  177. return 0;
  178. return 1;
  179. }
  180. static int
  181. check3 (unsigned char *info_block, int index1, int index2, int size)
  182. {
  183. int n;
  184. for (n = 0; n < size; n++)
  185. if (info_block[n + index1] != info_block[n + index2])
  186. return 0;
  187. return 1;
  188. }
  189. static void
  190. handle_swc_header (unsigned char *header)
  191. {
  192. if ((header[2] & 0x10) == 0x10)
  193. { // HiROM
  194. header[3] |= 0x80;
  195. if ((header[2] & 0x0c) == 0x0c) // 0 Kbit SRAM
  196. {
  197. header[4] = 0x77;
  198. header[5] = 0x83;
  199. }
  200. else if (((header[2] & 0x0c) == 0x08) || // 16 *or* 64 Kbit SRAM
  201. ((header[2] & 0x0c) == 0x04))
  202. {
  203. header[4] = 0xdd;
  204. header[5] = 0x82;
  205. }
  206. else // 256 Kbit SRAM
  207. {
  208. header[4] = 0xdd;
  209. header[5] = 0x02;
  210. }
  211. }
  212. else
  213. { // LoROM
  214. header[3] &= 0x7f;
  215. if ((header[2] & 0x0c) == 0x0c) // 0 Kbit SRAM
  216. {
  217. header[4] = 0x77;
  218. header[5] = 0x83;
  219. }
  220. else if (((header[2] & 0x0c) == 0x08) || // 16 *or* 64 Kbit SRAM
  221. ((header[2] & 0x0c) == 0x04))
  222. {
  223. header[4] = 0x00;
  224. header[5] = 0x80;
  225. }
  226. else // 256 Kbit SRAM
  227. {
  228. header[4] = 0x00;
  229. header[5] = 0x00;
  230. }
  231. }
  232. }
  233. int
  234. fig_read_rom (const char *filename, unsigned short parport)
  235. {
  236. FILE *file;
  237. unsigned char *buffer;
  238. int n, size, blocksleft, bytesreceived = 0;
  239. unsigned short address1, address2;
  240. time_t starttime;
  241. st_ucon64_nfo_t rominfo;
  242. ffe_init_io (parport);
  243. if ((file = fopen (filename, "wb")) == NULL)
  244. {
  245. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  246. exit (1);
  247. }
  248. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  249. {
  250. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  251. exit (1);
  252. }
  253. size = receive_rom_info (buffer);
  254. if (size == 0)
  255. {
  256. fputs ("ERROR: There is no cartridge present in the Pro Fighter\n", stderr);
  257. fclose (file);
  258. remove (filename);
  259. exit (1);
  260. }
  261. blocksleft = size * 16; // 1 Mb (128 kB) unit == 16 8 kB units
  262. printf ("Receive: %d Bytes (%.4f Mb)\n", size * MBIT, (float) size);
  263. size *= MBIT; // size in bytes for ucon64_gauge() below
  264. ffe_send_command (5, 0, 0);
  265. ffe_send_command0 (0xe00c, 0);
  266. ffe_send_command0 (0xe003, 0);
  267. // byte = ffe_send_command1 (0xbfd8);
  268. memset (buffer, 0, FIG_HEADER_LEN);
  269. fwrite (buffer, 1, FIG_HEADER_LEN, file); // write temporary empty header
  270. if (hirom)
  271. blocksleft >>= 1;
  272. puts ("Press q to abort\n"); // print here, NOT before first FIG I/O,
  273. // because if we get here q works ;-)
  274. address1 = 0x300; // address1 = 0x100, address2 = 0 should
  275. address2 = 0x200; // also work
  276. starttime = time (NULL);
  277. while (blocksleft > 0)
  278. {
  279. if (hirom)
  280. for (n = 0; n < 4; n++)
  281. {
  282. ffe_send_command (5, address1, 0);
  283. ffe_receive_block (0x2000, buffer, BUFFERSIZE);
  284. address1++;
  285. fwrite (buffer, 1, BUFFERSIZE, file);
  286. bytesreceived += BUFFERSIZE;
  287. ucon64_gauge (starttime, bytesreceived, size);
  288. ffe_checkabort (2);
  289. }
  290. for (n = 0; n < 4; n++)
  291. {
  292. ffe_send_command (5, address2, 0);
  293. ffe_receive_block (0xa000, buffer, BUFFERSIZE);
  294. blocksleft--;
  295. address2++;
  296. fwrite (buffer, 1, BUFFERSIZE, file);
  297. bytesreceived += BUFFERSIZE;
  298. ucon64_gauge (starttime, bytesreceived, size);
  299. ffe_checkabort (2);
  300. }
  301. }
  302. ffe_send_command (5, 0, 0);
  303. // Create a correct header. We can't obtain the header from the Pro Fighter
  304. // unless a (the same) cartridge was just dumped to diskette...
  305. ucon64.fname = filename;
  306. ucon64.file_size = size + FIG_HEADER_LEN;
  307. // override everything we know for sure
  308. ucon64.console = UCON64_SNES;
  309. ucon64.backup_header_len = FIG_HEADER_LEN;
  310. ucon64.split = 0;
  311. ucon64.snes_hirom = hirom ? SNES_HIROM : 0;
  312. ucon64.interleaved = 0;
  313. memset (&rominfo, 0, sizeof (st_ucon64_nfo_t));
  314. fflush (file);
  315. snes_init (&rominfo);
  316. memset (buffer, 0, FIG_HEADER_LEN);
  317. snes_set_fig_header (&rominfo, (st_fig_header_t *) buffer);
  318. fseek (file, 0, SEEK_SET);
  319. fwrite (buffer, 1, FIG_HEADER_LEN, file); // write correct header
  320. free (buffer);
  321. fclose (file);
  322. return 0;
  323. }
  324. int
  325. fig_write_rom (const char *filename, unsigned short parport)
  326. {
  327. FILE *file;
  328. unsigned char *buffer, emu_mode_select;
  329. int bytesread = 0, bytessent, totalblocks, blocksdone = 0, blocksleft, fsize,
  330. n;
  331. unsigned short address1, address2;
  332. time_t starttime;
  333. ffe_init_io (parport);
  334. if ((file = fopen (filename, "rb")) == NULL)
  335. {
  336. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  337. exit (1);
  338. }
  339. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  340. {
  341. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  342. exit (1);
  343. }
  344. fsize = ucon64.file_size;
  345. printf ("Send: %d Bytes (%.4f Mb)\n", fsize, (float) fsize / MBIT);
  346. ffe_send_command0 (0xc008, 0);
  347. fread (buffer, 1, FIG_HEADER_LEN, file);
  348. if (snes_get_file_type () == SWC)
  349. handle_swc_header (buffer);
  350. emu_mode_select = buffer[2]; // this byte is needed later
  351. ffe_send_command (5, 0, 0);
  352. ffe_send_block (0x400, buffer, FIG_HEADER_LEN); // send header
  353. bytessent = FIG_HEADER_LEN;
  354. hirom = snes_get_snes_hirom ();
  355. if (hirom)
  356. ffe_send_command0 (0xe00f, 0); // seems to enable HiROM mode,
  357. // value doesn't seem to matter
  358. puts ("Press q to abort\n"); // print here, NOT before first FIG I/O,
  359. // because if we get here q works ;-)
  360. totalblocks = (fsize - FIG_HEADER_LEN + BUFFERSIZE - 1) / BUFFERSIZE; // round up
  361. blocksleft = totalblocks;
  362. address1 = 0x300;
  363. address2 = 0x200;
  364. starttime = time (NULL);
  365. while (blocksleft > 0)
  366. {
  367. if (hirom)
  368. for (n = 0; n < 4; n++)
  369. {
  370. bytesread = fread (buffer, 1, BUFFERSIZE, file);
  371. ffe_send_command0 (0xc010, (unsigned char) (blocksdone >> 9));
  372. ffe_send_command (5, address1, 0);
  373. ffe_send_block (0x0000, buffer, (unsigned short) bytesread);
  374. address1++;
  375. blocksleft--;
  376. blocksdone++;
  377. bytessent += bytesread;
  378. ucon64_gauge (starttime, bytessent, fsize);
  379. ffe_checkabort (2);
  380. }
  381. for (n = 0; n < 4; n++)
  382. {
  383. bytesread = fread (buffer, 1, BUFFERSIZE, file);
  384. ffe_send_command0 (0xc010, (unsigned char) (blocksdone >> 9));
  385. ffe_send_command (5, address2, 0);
  386. ffe_send_block (0x8000, buffer, (unsigned short) bytesread);
  387. address2++;
  388. blocksleft--;
  389. blocksdone++;
  390. bytessent += bytesread;
  391. ucon64_gauge (starttime, bytessent, fsize);
  392. ffe_checkabort (2);
  393. }
  394. }
  395. if (blocksdone > 0x200) // ROM dump > 512 8 kB blocks (=32 Mb (=4 MB))
  396. ffe_send_command0 (0xc010, 2);
  397. ffe_send_command (5, 0, 0);
  398. ffe_send_command (6, 1 | (emu_mode_select << 8), 0);
  399. #if 0
  400. ffe_wait_for_ready ();
  401. outportb (parport + PARPORT_DATA, 0);
  402. outportb (parport + PARPORT_CONTROL,
  403. inportb (parport + PARPORT_CONTROL) ^ PARPORT_STROBE); // invert strobe
  404. #endif
  405. free (buffer);
  406. fclose (file);
  407. return 0;
  408. }
  409. int
  410. fig_read_sram (const char *filename, unsigned short parport)
  411. {
  412. FILE *file;
  413. unsigned char *buffer;
  414. int blocksleft, bytesreceived = 0;
  415. unsigned short address;
  416. time_t starttime;
  417. ffe_init_io (parport);
  418. if ((file = fopen (filename, "wb")) == NULL)
  419. {
  420. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  421. exit (1);
  422. }
  423. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  424. {
  425. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  426. exit (1);
  427. }
  428. printf ("Receive: %d Bytes\n", 32 * 1024);
  429. memset (buffer, 0, FIG_HEADER_LEN);
  430. #if 0 // Not needed for FIG, as size is always 4 blocks
  431. buffer[0] = 4; // 32 kB == 4*8 kB, "size_high" is already 0
  432. #endif
  433. fwrite (buffer, 1, FIG_HEADER_LEN, file);
  434. ffe_send_command (5, 0, 0);
  435. ffe_send_command0 (0xe00d, 0);
  436. ffe_send_command0 (0xc008, 0);
  437. puts ("Press q to abort\n"); // print here, NOT before first FIG I/O,
  438. // because if we get here q works ;-)
  439. blocksleft = 4; // SRAM is 4*8 kB
  440. address = 0x100;
  441. starttime = time (NULL);
  442. while (blocksleft > 0)
  443. {
  444. ffe_send_command (5, address, 0);
  445. ffe_receive_block (0x2000, buffer, BUFFERSIZE);
  446. blocksleft--;
  447. address++;
  448. fwrite (buffer, 1, BUFFERSIZE, file);
  449. bytesreceived += BUFFERSIZE;
  450. ucon64_gauge (starttime, bytesreceived, 32 * 1024);
  451. ffe_checkabort (2);
  452. }
  453. free (buffer);
  454. fclose (file);
  455. return 0;
  456. }
  457. int
  458. fig_write_sram (const char *filename, unsigned short parport)
  459. {
  460. FILE *file;
  461. unsigned char *buffer;
  462. int bytesread, bytessent = 0, size;
  463. unsigned short address;
  464. time_t starttime;
  465. ffe_init_io (parport);
  466. if ((file = fopen (filename, "rb")) == NULL)
  467. {
  468. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  469. exit (1);
  470. }
  471. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  472. {
  473. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  474. exit (1);
  475. }
  476. size = ucon64.file_size - FIG_HEADER_LEN; // FIG SRAM is 4*8 kB, emu SRAM often not
  477. printf ("Send: %d Bytes\n", size);
  478. fseek (file, FIG_HEADER_LEN, SEEK_SET); // skip the header
  479. ffe_send_command (5, 0, 0);
  480. ffe_send_command0 (0xe00d, 0);
  481. ffe_send_command0 (0xc008, 0);
  482. puts ("Press q to abort\n"); // print here, NOT before first FIG I/O,
  483. // because if we get here q works ;-)
  484. address = 0x100;
  485. starttime = time (NULL);
  486. while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) != 0)
  487. {
  488. ffe_send_command (5, address, 0);
  489. ffe_send_block (0x2000, buffer, (unsigned short) bytesread);
  490. address++;
  491. bytessent += bytesread;
  492. ucon64_gauge (starttime, bytessent, size);
  493. ffe_checkabort (2);
  494. }
  495. free (buffer);
  496. fclose (file);
  497. return 0;
  498. }
  499. int
  500. fig_read_cart_sram (const char *filename, unsigned short parport)
  501. {
  502. FILE *file;
  503. unsigned char *buffer, byte;
  504. int bytesreceived = 0, size;
  505. unsigned short address;
  506. time_t starttime;
  507. ffe_init_io (parport);
  508. if ((file = fopen (filename, "wb")) == NULL)
  509. {
  510. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  511. exit (1);
  512. }
  513. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  514. {
  515. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  516. exit (1);
  517. }
  518. size = receive_rom_info (buffer);
  519. if (size == 0)
  520. {
  521. fputs ("ERROR: There is no cartridge present in the Pro Fighter\n", stderr);
  522. fclose (file);
  523. remove (filename);
  524. exit (1);
  525. }
  526. ffe_send_command (5, 3, 0); // detect cartridge SRAM size because
  527. ffe_send_command0 (0xe00c, 0); // we don't want to read too few data
  528. byte = ffe_send_command1 (0xbfd8);
  529. size = MAX ((byte ? 1 << (byte + 10) : 0), 32 * 1024);
  530. printf ("Receive: %d Bytes\n", size);
  531. memset (buffer, 0, FIG_HEADER_LEN);
  532. #if 0 // Not needed for FIG, as size is always 4 blocks
  533. buffer[0] = 4; // 32 kB == 4*8 kB, "size_high" is already 0
  534. #endif
  535. fwrite (buffer, 1, FIG_HEADER_LEN, file);
  536. ffe_send_command (5, 0, 0);
  537. ffe_send_command0 (0xe00c, 0);
  538. // ffe_send_command0 (0xc008, 0);
  539. puts ("Press q to abort\n"); // print here, NOT before first FIG I/O,
  540. // because if we get here q works ;-)
  541. address = hirom ? 0x2c3 : 0x1c0;
  542. starttime = time (NULL);
  543. while (bytesreceived < size)
  544. {
  545. ffe_send_command (5, address, 0);
  546. ffe_receive_block (hirom ? 0x6000 : 0x2000, buffer, BUFFERSIZE);
  547. fwrite (buffer, 1, BUFFERSIZE, file);
  548. address += hirom ? 4 : 1;
  549. bytesreceived += BUFFERSIZE;
  550. ucon64_gauge (starttime, bytesreceived, size);
  551. ffe_checkabort (2);
  552. }
  553. free (buffer);
  554. fclose (file);
  555. return 0;
  556. }
  557. int
  558. fig_write_cart_sram (const char *filename, unsigned short parport)
  559. {
  560. FILE *file;
  561. unsigned char *buffer, byte;
  562. int bytesread, bytessent = 0, size;
  563. unsigned short address;
  564. time_t starttime;
  565. ffe_init_io (parport);
  566. if ((file = fopen (filename, "rb")) == NULL)
  567. {
  568. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  569. exit (1);
  570. }
  571. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  572. {
  573. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  574. exit (1);
  575. }
  576. size = receive_rom_info (buffer);
  577. if (size == 0)
  578. {
  579. fputs ("ERROR: There is no cartridge present in the Pro Fighter\n", stderr);
  580. fclose (file);
  581. remove (filename);
  582. exit (1);
  583. }
  584. ffe_send_command (5, 3, 0); // detect cartridge SRAM size because we don't
  585. ffe_send_command0 (0xe00c, 0); // want to write more data than necessary
  586. byte = ffe_send_command1 (0xbfd8);
  587. size = ucon64.file_size - FIG_HEADER_LEN; // FIG SRAM is 4*8 kB, emu SRAM often not
  588. size = MIN ((byte ? 1 << (byte + 10) : 0), size);
  589. printf ("Send: %d Bytes\n", size);
  590. fseek (file, FIG_HEADER_LEN, SEEK_SET); // skip the header
  591. ffe_send_command (5, 0, 0);
  592. ffe_send_command0 (0xe00c, 0);
  593. // ffe_send_command0 (0xc008, 0);
  594. puts ("Press q to abort\n"); // print here, NOT before first FIG I/O,
  595. // because if we get here q works ;-)
  596. address = hirom ? 0x2c3 : 0x1c0;
  597. starttime = time (NULL);
  598. while (bytessent < size && (bytesread = fread (buffer, 1, MIN (size, BUFFERSIZE), file)) != 0)
  599. {
  600. ffe_send_command (5, address, 0);
  601. ffe_send_block (hirom ? 0x6000 : 0x2000, buffer, (unsigned short) bytesread);
  602. address += hirom ? 4 : 1;
  603. bytessent += bytesread;
  604. ucon64_gauge (starttime, bytessent, size);
  605. ffe_checkabort (2);
  606. }
  607. free (buffer);
  608. fclose (file);
  609. return 0;
  610. }
  611. #endif // USE_PARALLEL