psxpblib.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. /*
  2. *
  3. * PSX Peripheral Bus Library v1.4 17/01/00 Richard Davies
  4. * <mailto:richard@debaser.force9.co.uk>
  5. *
  6. * Revision History:
  7. * v1.4 - 17/01/00 Win32 / Win32 DLL support, rewrite and bug fixes
  8. * v1.3 - 21/12/99 Linux support and bug fixes
  9. * v1.1 - 26/09/99 Minor Controller detection improvements.
  10. * v1.0 - 17/07/99 Initial release (based on PSXTest v1.1 by me).
  11. *
  12. * see psxpblib.h for details.
  13. *
  14. */
  15. #ifdef HAVE_CONFIG_H
  16. #include "config.h"
  17. #endif
  18. #include <fcntl.h>
  19. #include <ctype.h>
  20. #ifdef HAVE_DIRENT_H
  21. #include <dirent.h>
  22. #endif
  23. #include <stddef.h>
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <time.h>
  28. #ifdef HAVE_UNISTD_H
  29. #include <unistd.h>
  30. #endif
  31. #include "misc/misc.h"
  32. #include "misc/itypes.h"
  33. #ifdef USE_ZLIB
  34. #include "misc/archive.h"
  35. #endif
  36. #include "misc/getopt2.h" // st_getopt2_t
  37. #include "ucon64.h"
  38. #include "ucon64_misc.h"
  39. #include "psxpblib.h"
  40. #include "misc/parallel.h"
  41. #ifdef USE_PARALLEL
  42. static unsigned char psx_parallel_out_0 = 0xff;
  43. static unsigned char psx_parallel_out_2 = 0x00;
  44. /*
  45. *
  46. * sets clock for conport connected to parallel port base
  47. *
  48. */
  49. void
  50. psx_clk (int base, int conport, int on)
  51. {
  52. if (conport == 8)
  53. {
  54. if (on)
  55. {
  56. /* set controller clock high */
  57. psx_parallel_out_2 |= LPT_STR;
  58. }
  59. else
  60. {
  61. /* set controller clock low */
  62. psx_parallel_out_2 &= ~LPT_STR;
  63. }
  64. psx_outportb (base + 2, psx_parallel_out_2);
  65. }
  66. else
  67. {
  68. if (on)
  69. {
  70. /* set controller clock high */
  71. psx_parallel_out_0 |= LPT_D2;
  72. }
  73. else
  74. {
  75. /* set controller clock low */
  76. psx_parallel_out_0 &= ~LPT_D2;
  77. }
  78. psx_outportb (base + 0, psx_parallel_out_0);
  79. }
  80. }
  81. /*
  82. *
  83. * sets att for conport connected to parallel port base
  84. *
  85. */
  86. void
  87. psx_att (int base, int conport, int on)
  88. {
  89. /* bits 3-7 base + 0 (pins 5 to 9 parallel port) */
  90. const int power = LPT_D3 | LPT_D4 | LPT_D5 | LPT_D6 | LPT_D7;
  91. /* bits 1-6 base + 0 (pins 3, 5, 6, 7 and 8 parallel port) */
  92. unsigned char att_array[] =
  93. { LPT_D1, LPT_D1, LPT_D3, LPT_D4, LPT_D5, LPT_D6, LPT_D7 };
  94. unsigned char att;
  95. if (conport == 8)
  96. {
  97. if (on)
  98. {
  99. /* set controller att high */
  100. psx_parallel_out_2 |= LPT_INI;
  101. }
  102. else
  103. {
  104. /* set controller att low */
  105. psx_parallel_out_2 &= ~LPT_INI;
  106. }
  107. psx_outportb (base + 2, psx_parallel_out_2);
  108. }
  109. else
  110. {
  111. /* powers up all parallel port driven conports */
  112. psx_parallel_out_0 |= power;
  113. att = att_array[conport - 1];
  114. if (on)
  115. {
  116. /* set controller att high */
  117. psx_parallel_out_0 |= att;
  118. }
  119. else
  120. {
  121. /* set controller att low */
  122. psx_parallel_out_0 &= ~att;
  123. }
  124. psx_outportb (base + 0, psx_parallel_out_0);
  125. }
  126. }
  127. /*
  128. *
  129. * sets command for conport connected to parallel port base
  130. *
  131. */
  132. void
  133. psx_cmd (int base, int conport, int on)
  134. {
  135. if (conport == 8)
  136. {
  137. if (on)
  138. {
  139. /* set controller cmd high */
  140. psx_parallel_out_2 |= LPT_AUT;
  141. }
  142. else
  143. {
  144. /* set controller cmd low */
  145. psx_parallel_out_2 &= ~LPT_AUT;
  146. }
  147. psx_outportb (base + 2, psx_parallel_out_2);
  148. }
  149. else
  150. {
  151. if (on)
  152. {
  153. /* set controller cmd high */
  154. psx_parallel_out_0 |= LPT_D0;
  155. }
  156. else
  157. {
  158. /* set controller cmd low */
  159. psx_parallel_out_0 &= ~LPT_D0;
  160. }
  161. psx_outportb (base + 0, psx_parallel_out_0);
  162. }
  163. }
  164. /*
  165. *
  166. * tests data for conport connected to parallel port base, returns 1 if high
  167. *
  168. */
  169. int
  170. psx_dat (int base, int conport)
  171. {
  172. if (conport == 2)
  173. {
  174. if (psx_inportb (base + 1) & LPT_SEL)
  175. {
  176. return 1;
  177. }
  178. else
  179. {
  180. return 0;
  181. }
  182. }
  183. else
  184. {
  185. if (psx_inportb (base + 1) & LPT_ACK)
  186. {
  187. return 1;
  188. }
  189. else
  190. {
  191. return 0;
  192. }
  193. }
  194. }
  195. /*
  196. *
  197. * tests ack for conport connected to parallel port base, returns 1 if high
  198. *
  199. */
  200. int
  201. psx_ack (int base, int conport)
  202. {
  203. if (conport == 2)
  204. {
  205. if (psx_inportb (base + 2) & LPT_ERR)
  206. {
  207. return 1;
  208. }
  209. else
  210. {
  211. return 0;
  212. }
  213. }
  214. else if (conport == 8)
  215. {
  216. if (psx_inportb (base + 1) & LPT_SEL)
  217. {
  218. return 1;
  219. }
  220. else
  221. {
  222. return 0;
  223. }
  224. }
  225. else
  226. {
  227. if (psx_inportb (base + 1) & LPT_PAP)
  228. {
  229. return 1;
  230. }
  231. else
  232. {
  233. return 0;
  234. }
  235. }
  236. }
  237. /*
  238. *
  239. * wait for delay * (psx_outportb() execution time)
  240. *
  241. */
  242. void
  243. psx_delay (int base, int delay)
  244. {
  245. int i;
  246. for (i = 0; i < delay; i++)
  247. {
  248. psx_outportb (base + 0, psx_parallel_out_0);
  249. }
  250. }
  251. /*
  252. *
  253. * send byte as a command to conport connected to parallel port base
  254. * assumes clock high and the attention for conport
  255. *
  256. */
  257. unsigned char
  258. psx_sendbyte (int base, int conport, int delay, unsigned char byte, int wait)
  259. {
  260. int i;
  261. unsigned char data;
  262. data = 0;
  263. /* for each bit in byte */
  264. for (i = 0; i < 8; i++)
  265. {
  266. psx_delay (base, delay);
  267. psx_cmd (base, conport, byte & (1 << i)); /* send the (i+1)th bit of byte to any listening controller */
  268. psx_clk (base, conport, 0); /* clock low */
  269. psx_delay (base, delay);
  270. data |= (psx_dat (base, conport) ? (1 << i) : 0); /* read the (i+1)th bit of data from conport */
  271. psx_clk (base, conport, 1); /* clock high */
  272. }
  273. /* wait for controller ack */
  274. for (i = 0; wait && i < 10240 && psx_ack (base, conport); i++)
  275. ;
  276. return data;
  277. }
  278. /*
  279. *
  280. * sets clock high and gets the attention of conport, use before psx_sendbyte()
  281. *
  282. */
  283. void
  284. psx_sendinit (int base, int conport, int delay)
  285. {
  286. // psx_obtain_io_permission (base);// uCON64 already enabled access to I/O ports
  287. psx_att (base, conport, 1); /* set att on for conport */
  288. psx_clk (base, conport, 1); /* clock high */
  289. psx_cmd (base, conport, 1); /* set command on for conport */
  290. psx_delay (base, delay);
  291. psx_delay (base, delay);
  292. psx_delay (base, delay);
  293. psx_delay (base, delay);
  294. psx_delay (base, delay);
  295. psx_att (base, conport, 0); /* set att off for conport */
  296. psx_delay (base, delay);
  297. psx_delay (base, delay);
  298. psx_delay (base, delay);
  299. psx_delay (base, delay);
  300. }
  301. /*
  302. *
  303. * use after psx_sendbyte()
  304. *
  305. */
  306. void
  307. psx_sendclose (int base, int conport, int delay)
  308. {
  309. psx_delay (base, delay);
  310. psx_delay (base, delay);
  311. psx_att (base, conport, 1); /* set att on for conport */
  312. psx_cmd (base, conport, 1); /* set command on for conport */
  313. psx_clk (base, conport, 1); /* clock high */
  314. psx_delay (base, delay);
  315. }
  316. /*
  317. *
  318. * send string as a series of commands to conport connected to parallel port base
  319. *
  320. */
  321. void
  322. psx_sendstring (int base, int conport, int delay, int string[])
  323. {
  324. int i;
  325. psx_sendinit (base, conport, delay);
  326. /* for each byte in string */
  327. for (i = 0; string[i + 1] != -1; i++)
  328. {
  329. /* send byte i and wait for conport ack */
  330. psx_sendbyte (base, conport, delay, (unsigned char) string[i], 0);
  331. psx_delay (base, delay);
  332. }
  333. /* send the last byte in string and don't wait for ack */
  334. psx_sendbyte (base, conport, delay, (unsigned char) string[i], 0);
  335. psx_sendclose (base, conport, delay);
  336. }
  337. /*
  338. *
  339. * tests for the presence of a controller on conport:tap connected to base
  340. * returns the type if present, otherwise -1
  341. *
  342. */
  343. int
  344. psx_controller_detect (int base, int conport, int tap, int delay)
  345. {
  346. unsigned char ack;
  347. int type, length;
  348. psx_sendinit (base, conport, delay);
  349. psx_sendbyte (base, conport, delay, (unsigned char) tap, 0);
  350. psx_delay (base, delay);
  351. psx_delay (base, delay);
  352. psx_delay (base, delay);
  353. psx_delay (base, delay);
  354. ack = psx_sendbyte (base, conport, delay, 0x42, 0);
  355. psx_delay (base, delay);
  356. psx_sendclose (base, conport, delay);
  357. type = (ack & 0xf0) >> 4;
  358. length = 2 * (ack & 0x0f);
  359. /* check the controller has a legal packet length */
  360. if (!((length > 0) && (length < PSX_MAX_DATA)))
  361. return -1;
  362. /* check the controller has a legal id */
  363. if (!((type > 0) && (type < 0x0f) && (type != 0x08)))
  364. return -1;
  365. return type;
  366. }
  367. /*
  368. *
  369. * reads a controller on conport:tap connected to base returns the data
  370. * if present, otherwise -1
  371. *
  372. */
  373. PSX_CON_BUF *
  374. psx_controller_read (int base, int conport, int tap, int delay)
  375. {
  376. unsigned char ack;
  377. int i;
  378. static PSX_CON_BUF psx_con_buf;
  379. psx_sendinit (base, conport, delay);
  380. psx_sendbyte (base, conport, delay, (unsigned char) tap, 0);
  381. psx_delay (base, delay);
  382. psx_delay (base, delay);
  383. psx_delay (base, delay);
  384. psx_delay (base, delay);
  385. ack = psx_sendbyte (base, conport, delay, 0x42, 0);
  386. psx_delay (base, delay);
  387. psx_con_buf.type = (ack & 0xf0) >> 4;
  388. psx_con_buf.length = 2 * (ack & 0x0f);
  389. /* check the controller has a legal packet length */
  390. if (!((psx_con_buf.length > 0) && (psx_con_buf.length < PSX_MAX_DATA)))
  391. {
  392. psx_sendclose (base, conport, delay);
  393. return NULL;
  394. }
  395. /* check the controller has a legal id */
  396. if (!
  397. ((psx_con_buf.type > 0) && (psx_con_buf.type < 0x0f)
  398. && (psx_con_buf.type != 0x08)))
  399. {
  400. psx_sendclose (base, conport, delay);
  401. return NULL;
  402. }
  403. psx_sendbyte (base, conport, delay, 0x00, 0);
  404. psx_delay (base, delay);
  405. for (i = 0; i < psx_con_buf.length; i++)
  406. {
  407. psx_con_buf.data[i] = psx_sendbyte (base, conport, delay, 0x00, 0);
  408. psx_delay (base, delay);
  409. }
  410. psx_sendclose (base, conport, delay);
  411. return &psx_con_buf;
  412. }
  413. /*
  414. *
  415. * sends force feedback/shock init command sequence to conport:tap on port base
  416. * (also initialises crash protection for some controllers)
  417. *
  418. */
  419. void
  420. psx_controller_vinit (int base, int conport, int tap, int delay)
  421. {
  422. int i, vibrate_init_string[3][11] =
  423. {
  424. {tap, 0x43, 0x00, 0x01, 0x00, 0x01, -1},
  425. {tap, 0x4d, 0x00, 0x00, 0x01, 0xff, 0xff, 0xff, 0xff, 0x01, -1},
  426. {tap, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -1},
  427. };
  428. for (i = 0; i < 3; i++)
  429. {
  430. psx_delay (base, delay);
  431. psx_delay (base, delay);
  432. psx_delay (base, delay);
  433. psx_sendstring (base, conport, delay, vibrate_init_string[i]);
  434. }
  435. }
  436. /*
  437. *
  438. * sends the dual shock command sequence to conport:tap on port base
  439. *
  440. */
  441. void
  442. psx_controller_vshock (int base, int conport, int tap, int delay, int shock,
  443. int rumble)
  444. {
  445. int dualshock_string[7] = { tap, 0x42, 0x00, shock, rumble, 0x01, -1 };
  446. psx_controller_vinit (base, conport, tap, delay);
  447. psx_delay (base, delay);
  448. psx_delay (base, delay);
  449. psx_delay (base, delay);
  450. psx_sendstring (base, conport, delay, dualshock_string);
  451. }
  452. /*
  453. *
  454. * Reads a single frame (128 bytes) from Memory Card on conport base:tap
  455. *
  456. */
  457. unsigned char *
  458. psx_memcard_read_frame (int base, int conport, int tap, int delay, int frame)
  459. {
  460. int i, xor_val;
  461. static unsigned char data[128], c_data;
  462. unsigned char cmd_rstring_hdr[4] = { (0x80 + (unsigned char) tap), 0x52, 0x00, 0x00 },
  463. chk_rstring_hdr[2] = { 0x5a, 0x5d },
  464. cmd_rstring_adr[2] = { (frame >> 8) & 0xff, frame & 0xff },
  465. chk_rstring_ack[1] = { 0x5c },
  466. chk_rstring_sfl[1] = { 0x5d },
  467. chk_rstring_efl[1] = { 0x47 };
  468. psx_sendinit (base, conport, delay);
  469. /* send header */
  470. for (i = 0; i < 2; i++)
  471. {
  472. psx_sendbyte (base, conport, delay, cmd_rstring_hdr[i], 0);
  473. psx_delay (base, delay);
  474. psx_delay (base, delay);
  475. }
  476. for (; i < 4; i++)
  477. {
  478. c_data = psx_sendbyte (base, conport, delay, cmd_rstring_hdr[i], 0);
  479. psx_delay (base, delay);
  480. psx_delay (base, delay);
  481. if (c_data != chk_rstring_hdr[i - 2])
  482. {
  483. psx_sendclose (base, conport, delay);
  484. return NULL;
  485. }
  486. }
  487. /* send read address */
  488. for (i = 0; i < 2; i++)
  489. {
  490. psx_sendbyte (base, conport, delay, cmd_rstring_adr[i], 0);
  491. psx_delay (base, delay);
  492. }
  493. /* receive command ack (have to wait for this) */
  494. c_data = psx_sendbyte (base, conport, delay, 0x00, 1);
  495. if (c_data != chk_rstring_ack[0])
  496. {
  497. psx_sendclose (base, conport, delay);
  498. return NULL;
  499. }
  500. /* receive start of data flag */
  501. i = 0;
  502. while (c_data != chk_rstring_sfl[0])
  503. {
  504. c_data = psx_sendbyte (base, conport, delay, 0x00, 0);
  505. psx_delay (base, delay);
  506. i++;
  507. if (i > 255)
  508. {
  509. psx_sendclose (base, conport, delay);
  510. return NULL;
  511. }
  512. }
  513. /* receive read address */
  514. for (i = 0; i < 2; i++)
  515. {
  516. c_data = psx_sendbyte (base, conport, delay, 0x00, 0);
  517. psx_delay (base, delay);
  518. if (c_data != cmd_rstring_adr[i])
  519. {
  520. psx_sendclose (base, conport, delay);
  521. return NULL;
  522. }
  523. }
  524. /* receive data */
  525. for (i = 0; i < 128; i++)
  526. {
  527. data[i] = psx_sendbyte (base, conport, delay, 0x00, 0);
  528. psx_delay (base, delay);
  529. }
  530. /* receive xor */
  531. c_data = psx_sendbyte (base, conport, delay, 0x00, 0);
  532. psx_delay (base, delay);
  533. /* test xor */
  534. xor_val = 0;
  535. xor_val ^= cmd_rstring_adr[0];
  536. xor_val ^= cmd_rstring_adr[1];
  537. for (i = 0; i < 128; i++)
  538. xor_val ^= data[i];
  539. if (xor_val != c_data)
  540. {
  541. psx_sendclose (base, conport, delay);
  542. return NULL;
  543. }
  544. /* receive end of data flag */
  545. c_data = psx_sendbyte (base, conport, delay, 0x00, 0);
  546. psx_delay (base, delay);
  547. if (c_data != chk_rstring_efl[0])
  548. {
  549. psx_sendclose (base, conport, delay);
  550. return NULL;
  551. }
  552. psx_sendclose (base, conport, delay);
  553. return data;
  554. }
  555. /*
  556. *
  557. * Writes a single frame (128 bytes) to Memory Card on conport base:tap
  558. *
  559. */
  560. int
  561. psx_memcard_write_frame (int base, int conport, int tap, int delay, int frame,
  562. unsigned char *data_f)
  563. {
  564. int i, xor_val;
  565. unsigned char c_data,
  566. cmd_wstring_hdr[4] = { (0x80 + (unsigned char) tap), 0x57, 0x00, 0x00 },
  567. chk_wstring_hdr[2] = { 0x5a, 0x5d },
  568. cmd_wstring_adr[2] = { (frame >> 8) & 0xff, frame & 0xff },
  569. chk_wstring_emk[2] = { 0x5c, 0x5d },
  570. chk_wstring_efl[1] = { 0x47 };
  571. psx_sendinit (base, conport, delay);
  572. /* send header (have to wait for this) */
  573. for (i = 0; i < 2; i++)
  574. {
  575. psx_sendbyte (base, conport, delay, cmd_wstring_hdr[i], 1);
  576. }
  577. for (; i < 4; i++)
  578. {
  579. c_data = psx_sendbyte (base, conport, delay, cmd_wstring_hdr[i], 1);
  580. if (c_data != chk_wstring_hdr[i - 2])
  581. {
  582. psx_sendclose (base, conport, delay);
  583. return -1;
  584. }
  585. }
  586. /* send write address */
  587. for (i = 0; i < 2; i++)
  588. {
  589. psx_sendbyte (base, conport, delay, cmd_wstring_adr[i], 0);
  590. psx_delay (base, delay);
  591. }
  592. /* send data */
  593. for (i = 0; i < 128; i++)
  594. {
  595. psx_sendbyte (base, conport, delay, data_f[i], 0);
  596. psx_delay (base, delay);
  597. }
  598. /* calculate xor */
  599. xor_val = 0;
  600. xor_val ^= cmd_wstring_adr[0];
  601. xor_val ^= cmd_wstring_adr[1];
  602. for (i = 0; i < 128; i++)
  603. xor_val ^= data_f[i];
  604. /* send xor */
  605. psx_sendbyte (base, conport, delay, (unsigned char) xor_val, 0);
  606. psx_delay (base, delay);
  607. /* receive end mark */
  608. for (i = 0; i < 2; i++)
  609. {
  610. c_data = psx_sendbyte (base, conport, delay, 0x00, 1);
  611. if (c_data != chk_wstring_emk[i])
  612. {
  613. psx_sendclose (base, conport, delay);
  614. return -1;
  615. }
  616. }
  617. /* receive end of data flag */
  618. c_data = psx_sendbyte (base, conport, delay, 0x00, 1);
  619. if (c_data != chk_wstring_efl[0])
  620. {
  621. psx_sendclose (base, conport, delay);
  622. return -1;
  623. }
  624. psx_sendclose (base, conport, delay);
  625. return (int) ((unsigned char) xor_val);
  626. }
  627. /*
  628. *
  629. * Reads a single block (64 frames) from Memory Card on conport base:tap
  630. *
  631. */
  632. unsigned char *
  633. psx_memcard_read_block (int base, int conport, int tap, int delay, int block)
  634. {
  635. int i, j;
  636. static unsigned char data_b[8192], *data_f;
  637. for (i = 0; i < 64; i++)
  638. {
  639. data_f =
  640. psx_memcard_read_frame (base, conport, tap, delay, (block * 64) + i);
  641. if (data_f != NULL)
  642. {
  643. for (j = 0; j < 128; j++)
  644. data_b[(i * 128) + j] = data_f[j];
  645. }
  646. else
  647. {
  648. return NULL;
  649. }
  650. }
  651. return data_b;
  652. }
  653. /*
  654. *
  655. * Writes a single block (64 frames) to Memory Card on conport base:tap
  656. *
  657. */
  658. int
  659. psx_memcard_write_block (int base, int conport, int tap, int delay, int block,
  660. unsigned char *data_b)
  661. {
  662. int i, xor_val;
  663. for (i = 0; i < 64; i++)
  664. {
  665. xor_val =
  666. psx_memcard_write_frame (base, conport, tap, delay, (block * 64) + i,
  667. &(data_b[128 * i]));
  668. if (xor_val == -1)
  669. {
  670. return -1;
  671. }
  672. }
  673. return 1;
  674. }
  675. /*
  676. *
  677. * Reads the info associated with block from the directory
  678. *
  679. */
  680. PSX_MCB_INFO_DIR *
  681. psx_mcb_read_dir (int base, int conport, int tap, int delay, int block)
  682. {
  683. int i, xor_val;
  684. unsigned char *data_f;
  685. static PSX_MCB_INFO_DIR mcb_info_dir;
  686. mcb_info_dir.read = 1;
  687. /* check memory card state */
  688. data_f = psx_memcard_read_frame (base, conport, tap, delay, 0);
  689. if (data_f == NULL)
  690. {
  691. mcb_info_dir.read = 0;
  692. return &mcb_info_dir;
  693. }
  694. if ((data_f[0] != 'M') && (data_f[1] != 'C'))
  695. {
  696. mcb_info_dir.read = 0;
  697. return &mcb_info_dir;
  698. }
  699. for (i = 2; i < 127; i++)
  700. {
  701. if (data_f[i] != 0x00)
  702. {
  703. mcb_info_dir.read = 0;
  704. return &mcb_info_dir;
  705. }
  706. }
  707. if (data_f[127] != 0x0e)
  708. {
  709. mcb_info_dir.read = 0;
  710. return &mcb_info_dir;
  711. }
  712. /* read block's directory */
  713. data_f = psx_memcard_read_frame (base, conport, tap, delay, block);
  714. if (data_f == NULL)
  715. {
  716. mcb_info_dir.read = 0;
  717. return &mcb_info_dir;
  718. }
  719. xor_val = 0;
  720. for (i = 0; i < 127; i++)
  721. xor_val ^= data_f[i];
  722. if (xor_val != data_f[127])
  723. {
  724. mcb_info_dir.read = 0;
  725. return &mcb_info_dir;
  726. }
  727. mcb_info_dir.linktype = data_f[0] & 0x0f;
  728. /* Only test if first link */
  729. if (mcb_info_dir.linktype == PSX_MCB_LTYPE_FIRST)
  730. {
  731. if (data_f[10] != 'B')
  732. {
  733. mcb_info_dir.read = 0;
  734. return &mcb_info_dir;
  735. }
  736. }
  737. mcb_info_dir.state = (data_f[0] >> 4) & 0x0f;
  738. mcb_info_dir.bytes = (data_f[4] << 16) + (data_f[5] << 8) + data_f[6];
  739. mcb_info_dir.next = data_f[8]; /* 0 to 14 */
  740. mcb_info_dir.territory = data_f[11]; /* E, A or I */
  741. for (i = 0; i < 10; i++)
  742. mcb_info_dir.code[i] = (char) data_f[12 + i];
  743. mcb_info_dir.code[i] = '\0';
  744. for (i = 0; i < 8; i++)
  745. mcb_info_dir.filename[i] = data_f[22 + i];
  746. mcb_info_dir.filename[i] = '\0';
  747. return &mcb_info_dir;
  748. }
  749. /*
  750. *
  751. * Reads the info associated with block from it's data
  752. *
  753. */
  754. PSX_MCB_INFO_DAT *
  755. psx_mcb_read_dat (int base, int conport, int tap, int delay, int block)
  756. {
  757. int i, j;
  758. unsigned char *data_f;
  759. static PSX_MCB_INFO_DAT mcb_info_dat;
  760. mcb_info_dat.read = 1;
  761. if ((block < 1) || (block > 15))
  762. {
  763. mcb_info_dat.read = 0;
  764. return &mcb_info_dat;
  765. }
  766. data_f =
  767. psx_memcard_read_frame (base, conport, tap, delay, (block * 64) + 0);
  768. if (!data_f)
  769. {
  770. mcb_info_dat.read = 0;
  771. return &mcb_info_dat;
  772. }
  773. if ((data_f[0] != 'S') || (data_f[1] != 'C'))
  774. {
  775. mcb_info_dat.read = 0;
  776. return &mcb_info_dat;
  777. }
  778. mcb_info_dat.icon_valid = (data_f[2] >> 4) & 0x0f;
  779. mcb_info_dat.icon_frames = data_f[2] & 0x0f;
  780. mcb_info_dat.blocks = data_f[3];
  781. /* bodged character set conversion */
  782. j = 0;
  783. for (i = 0; i < 91; i += 2)
  784. {
  785. if (data_f[4 + i] != 0x00)
  786. {
  787. if (data_f[4 + i] == 0x81)
  788. {
  789. if (data_f[5 + i] == 0x7c)
  790. mcb_info_dat.name[j] = '-';
  791. else if (data_f[5 + i] == 0x40)
  792. mcb_info_dat.name[j] = ' ';
  793. else if (data_f[5 + i] == 0x46)
  794. mcb_info_dat.name[j] = ':';
  795. else if (data_f[5 + i] == 0x5e)
  796. mcb_info_dat.name[j] = '/';
  797. else if (data_f[5 + i] == 0x49)
  798. mcb_info_dat.name[j] = '!';
  799. else if (data_f[5 + i] == 0x93)
  800. mcb_info_dat.name[j] = '%';
  801. else if (data_f[5 + i] == 0x68)
  802. mcb_info_dat.name[j] = '\"';
  803. else if (data_f[5 + i] == 0x44)
  804. mcb_info_dat.name[j] = '.';
  805. else if (data_f[5 + i] == 0x6d)
  806. mcb_info_dat.name[j] = '[';
  807. else if (data_f[5 + i] == 0x6e)
  808. mcb_info_dat.name[j] = ']';
  809. else if (data_f[5 + i] == 0x69)
  810. mcb_info_dat.name[j] = '(';
  811. else if (data_f[5 + i] == 0x6a)
  812. mcb_info_dat.name[j] = ')';
  813. else
  814. mcb_info_dat.name[j] = '?';
  815. }
  816. else if (data_f[4 + i] == 0x82)
  817. {
  818. if ((data_f[5 + i] > 0x4e) && (data_f[5 + i] < 0x80))
  819. mcb_info_dat.name[j] = data_f[5 + i] - 0x1f;
  820. else if ((data_f[4 + i] > 0x80) && (data_f[5 + i] < 0x9a))
  821. mcb_info_dat.name[j] = data_f[5 + i] - 0x20;
  822. else
  823. mcb_info_dat.name[j] = '?';
  824. }
  825. else
  826. {
  827. mcb_info_dat.name[j] = data_f[4 + i];
  828. j++;
  829. if (data_f[5 + i] != 0x00)
  830. mcb_info_dat.name[j] = data_f[5 + i];
  831. else
  832. {
  833. mcb_info_dat.name[j] = '\0';
  834. i = 91;
  835. }
  836. }
  837. }
  838. else
  839. {
  840. mcb_info_dat.name[j] = '\0';
  841. i = 91;
  842. }
  843. j++;
  844. }
  845. return &mcb_info_dat;
  846. }
  847. /*
  848. *
  849. * Merges the info associated with block from the directory and it's data
  850. *
  851. */
  852. PSX_MCB_INFO *
  853. psx_mcb_info_merge (PSX_MCB_INFO_DIR mcb_info_dir,
  854. PSX_MCB_INFO_DAT mcb_info_dat, PSX_MCB_INFO * mcb_info)
  855. {
  856. mcb_info->read = 1;
  857. if (!mcb_info_dir.read)
  858. {
  859. mcb_info->read = 0;
  860. return mcb_info;
  861. }
  862. if ((mcb_info_dir.linktype == PSX_MCB_LTYPE_FIRST) && (!mcb_info_dat.read))
  863. {
  864. mcb_info->read = 0;
  865. return mcb_info;
  866. }
  867. strcpy (mcb_info->filename, mcb_info_dir.filename);
  868. strcpy (mcb_info->code, mcb_info_dir.code);
  869. mcb_info->territory = mcb_info_dir.territory;
  870. mcb_info->bytes = mcb_info_dir.bytes;
  871. mcb_info->state = mcb_info_dir.state;
  872. mcb_info->linktype = mcb_info_dir.linktype;
  873. mcb_info->next = mcb_info_dir.next;
  874. if (mcb_info_dir.linktype == PSX_MCB_LTYPE_FIRST)
  875. {
  876. strcpy (mcb_info->name, mcb_info_dat.name);
  877. mcb_info->blocks = mcb_info_dat.blocks;
  878. mcb_info->icon_valid = mcb_info_dat.icon_valid;
  879. mcb_info->icon_frames = mcb_info_dat.icon_frames;
  880. }
  881. else
  882. {
  883. mcb_info->name[0] = '\0';
  884. mcb_info->blocks = 0;
  885. mcb_info->icon_valid = 0;
  886. mcb_info->icon_frames = 0;
  887. }
  888. return mcb_info;
  889. }
  890. /*
  891. *
  892. * Reads the info associated with block from the directory and it's data
  893. *
  894. */
  895. PSX_MCB_INFO *
  896. psx_mcb_read_info (int base, int conport, int tap, int delay, int block)
  897. {
  898. PSX_MCB_INFO_DIR *mcb_info_dir;
  899. PSX_MCB_INFO_DAT *mcb_info_dat;
  900. static PSX_MCB_INFO mcb_info;
  901. mcb_info_dir = psx_mcb_read_dir (base, conport, tap, delay, block);
  902. mcb_info_dat = psx_mcb_read_dat (base, conport, tap, delay, block);
  903. return psx_mcb_info_merge (*mcb_info_dir, *mcb_info_dat, &mcb_info);
  904. }
  905. #endif // USE_PARALLEL