psxpblib.c 23 KB

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