fig.c 20 KB

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