cartlib.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767
  1. /*
  2. cartlib.c - Flash Linker Advance support for uCON64
  3. Copyright (c) 2001 Jeff Frohwein
  4. Copyright (c) 2002 - 2004 dbjh
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #ifdef USE_PARALLEL
  21. // *** GBA flash cart support routines in GCC ***
  22. // This library allows programming FA/Visoly (both Turbo
  23. // and non-Turbo) and official Nintendo flash carts. They
  24. // can be used with the Flash Linker or can be called
  25. // from GBA code to allow in-system flash cart programming.
  26. // NOTE: ALL OF THESE ROUTINES MUST BE LOCATED IN GBA RAM
  27. // IF THIS LIBRARY IS USED FOR IN-SYSTEM PROGRAMMING.
  28. //
  29. // by Jeff Frohwein, Started 2001-Aug-29
  30. //
  31. // v1.0 - 2001-Sept-25 - Original release
  32. // v1.1 - 2001-Nov-13 - Slightly modified SetVisolyBackupRWMode by removing >>1.
  33. //
  34. // Routines -
  35. //
  36. // void SetFAFlashRWMode (void)
  37. //
  38. // Used to enable modifications of FA/Visoly cart flash chip(s)
  39. // and also used for CartTypeDetect routine. YOU MUST CALL THIS
  40. // ROUTINE BEFORE USING ANY OF THE OTHER FA/VISOLY ROUTINES.
  41. //
  42. // u8 CartTypeDetect (void)
  43. // Return a value indicating type of cart installed:
  44. // 0x00 = Hudson Cart, 0x2e = Standard ROM
  45. // 0xe2 = N Flash Cart, 0xff = Unknown
  46. // 0x17 = FA 64M, 0x96 = Turbo FA 64M
  47. // 0x18 = FA 128M, 0x97 = Turbo FA 128M
  48. //
  49. // u32 EraseNintendoFlashBlocks (u32 StartAddr, u32 BlockCount)
  50. //
  51. // Erase official Nintendo flash cart blocks.
  52. // Ex: EraseNintendoFlashBlocks (0x8000000, 1); // erase block 1
  53. // EraseNintendoFlashBlocks (0x8010000, 2); // erase blocks 2 & 3
  54. //
  55. // u32 EraseNonTurboFABlocks (u32 StartAddr, u32 BlockCount)
  56. //
  57. // Erase older (non-Turbo) Visoly flash cart blocks.
  58. // Ex: EraseNonTurboFABlocks (0x8000000, 1); // erase block 1
  59. // EraseNonTurboFABlocks (0x8020000, 2); // erase blocks 2 & 3
  60. //
  61. // u32 EraseTurboFABlocks (u32 StartAddr, u32 BlockCount)
  62. //
  63. // Erase newer (Turbo) Visoly flash cart blocks.
  64. // Ex: EraseTurboFABlocks (0x8000000, 1); // erase block 1
  65. // EraseTurboFABlocks (0x8040000, 2); // erase blocks 2 & 3
  66. //
  67. // u32 WriteNintendoFlashCart (u32 SrcAddr, u32 FlashAddr, u32 Length)
  68. //
  69. // Write 2 x Length bytes to official Nintendo flash cart.
  70. // Ex: WriteNintendoFlashCart (SrcAddr, 0x8000000, 2) // write 4 bytes
  71. //
  72. // u32 WriteNonTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
  73. //
  74. // Write 32 x Length bytes to older (non-Turbo) Visoly flash cart.
  75. // Ex: WriteNonTurboFACart (SrcAddr, 0x8000000, 2) // write 64 bytes
  76. //
  77. // u32 WriteTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
  78. //
  79. // Write 64 x Length bytes to newer (Turbo) Visoly flash cart.
  80. // Ex: WriteTurboFACart (SrcAddr, 0x8000000, 2) // write 128 bytes
  81. //
  82. // To reduce the library size and remove support for any
  83. // of the following types, comment out one or more of
  84. // the following lines using //
  85. #define NONTURBO_FA_SUPPORT 1 // Visoly Non-Turbo flash carts
  86. #define TURBO_FA_SUPPORT 1 // Visoly Turbo flash carts
  87. #define NOA_FLASH_CART_SUPPORT 1 // Official Nintendo flash carts
  88. //#define SET_CL_SECTION 1 // Enable setting code section for cartlib
  89. //
  90. //
  91. //
  92. #ifdef TURBO_FA_SUPPORT
  93. #define COMMON_FA_SUPPORT 1
  94. #endif
  95. #ifdef NONTURBO_FA_SUPPORT
  96. #define COMMON_FA_SUPPORT 1
  97. #endif
  98. #ifdef FLINKER
  99. // FLinker programming defines
  100. #define _MEM_INC 1
  101. #define FP_TIMEOUT1 0x4000
  102. #define FP_TIMEOUT2 0x8000
  103. #define FP_TIMEOUT3 0x80000
  104. #define _CART_START 0
  105. #define FLINKER_SET l40226c ()
  106. #define READ_NTURBO_SR(a,b) WriteFlash (a, INTEL28F_READSR); \
  107. outpb (SPPCtrlPort, 0); \
  108. b = (PPReadWord() & 0xff)
  109. #define READ_NTURBO_S(a) outpb (SPPCtrlPort, 0); \
  110. a = (PPReadWord() & 0xff)
  111. #define READ_TURBO_SR(a) WriteFlash (0, INTEL28F_READSR); \
  112. PPWriteWord (INTEL28F_READSR); \
  113. outpb (SPPCtrlPort, 0); \
  114. a = PPReadWord() & 0xff; \
  115. a += (PPReadWord() & 0xff) << 8
  116. #define READ_TURBO_S(a) outpb (SPPCtrlPort, 0); \
  117. a = PPReadWord() & 0xff; \
  118. a += (PPReadWord() & 0xff) << 8
  119. #define READ_TURBO_S2(a,b,c) outpb (SPPCtrlPort, 0); \
  120. b = PPReadWord () & 0x80; \
  121. c = PPReadWord () & 0x80
  122. #define WRITE_FLASH_NEXT(a,b) PPWriteWord (b)
  123. #define SET_CART_ADDR(a) SetCartAddr (a); \
  124. l4021d0 (3)
  125. #define CTRL_PORT_0 outpb (SPPCtrlPort, 0)
  126. #define CTRL_PORT_1 outpb (SPPCtrlPort, 1)
  127. void
  128. WriteRepeat (int addr, int data, int count)
  129. {
  130. int i;
  131. for (i = 0; i < count; i++)
  132. WriteFlash (addr, data);
  133. }
  134. #else
  135. // GBA in-system programming defines
  136. #define _MEM_INC 2
  137. #define FP_TIMEOUT1 0x4000 // Probably could be MUCH smaller
  138. #define FP_TIMEOUT2 0x8000 // Probably could be MUCH smaller
  139. #define FP_TIMEOUT3 0x80000 // Probably could be MUCH smaller
  140. #define INTEL28F_BLOCKERASE 0x20
  141. #define INTEL28F_CLEARSR 0x50
  142. #define INTEL28F_CONFIRM 0xD0
  143. #define INTEL28F_QUIRY 0x98
  144. #define INTEL28F_READARRAY 0xff
  145. #define INTEL28F_READSR 0x70
  146. #define INTEL28F_RIC 0x90
  147. #define INTEL28F_WRTOBUF 0xe8
  148. #define SHARP28F_BLOCKERASE 0x20
  149. #define SHARP28F_CONFIRM 0xD0
  150. #define SHARP28F_WORDWRITE 0x10
  151. #define SHARP28F_READARRAY 0xff
  152. // typedef volatile unsigned char vu8;
  153. // typedef volatile unsigned short int vu16;
  154. // typedef volatile unsigned int vu32;
  155. // typedef volatile unsigned long long int vu64;
  156. // typedef unsigned char u8;
  157. // typedef unsigned short int u16;
  158. // typedef unsigned int u32;
  159. // typedef unsigned long long int u64;
  160. #define _CART_START 0x8000000
  161. #define _BACKUP_START 0xe000000
  162. #define FLINKER_SET {}
  163. #define READ_NTURBO_SR(a,b) *(vu16 *)a = INTEL28F_READSR; \
  164. b = *(vu16 *)a
  165. #define READ_NTURBO_S(a) a = *(vu16 *)_CART_START
  166. #define READ_TURBO_SR(a) *(vu16 *)_CART_START = INTEL28F_READSR; \
  167. *(vu16 *)(_CART_START+2) = INTEL28F_READSR; \
  168. a = *(vu16 *)_CART_START & 0xff; \
  169. a += (*(vu16 *)(_CART_START+2) & 0xff) << 8
  170. #define READ_TURBO_S(a) a = *(vu16 *)_CART_START & 0xff; \
  171. a += (*(vu16 *)(_CART_START+2) & 0xff) << 8
  172. #define READ_TURBO_S2(a,b,c) b = *(vu16 *)a & 0x80; \
  173. c = *(vu16 *)(a+2) & 0x80
  174. #define WRITE_FLASH_NEXT(a,b) WriteFlash (a, b)
  175. #define SET_CART_ADDR(a) {}
  176. #define CTRL_PORT_0 {}
  177. #define CTRL_PORT_1 {}
  178. #define CL_SECTION __attribute__ ((section (".iwram")))
  179. #ifdef SET_CL_SECTION
  180. // Prototypes to allow placing routines in any section
  181. void
  182. WriteFlash (u32 addr, u16 data)
  183. CL_SECTION;
  184. u16 ReadFlash (u32 addr) CL_SECTION;
  185. void WriteRepeat (u32 addr, u16 data, u16 count) CL_SECTION;
  186. void VisolyModePreamble (void) CL_SECTION;
  187. void SetVisolyFlashRWMode (void) CL_SECTION;
  188. void SetVisolyBackupRWMode (int i) CL_SECTION;
  189. u8 CartTypeDetect (void) CL_SECTION;
  190. u32 EraseNintendoFlashBlocks (u32 StartAddr, u32 BlockCount) CL_SECTION;
  191. u32 EraseNonTurboFABlocks (u32 StartAddr, u32 BlockCount) CL_SECTION;
  192. u32 EraseTurboFABlocks (u32 StartAddr, u32 BlockCount) CL_SECTION;
  193. u32 WriteNintendoFlashCart (u32 SrcAddr, u32 FlashAddr,
  194. u32 Length) CL_SECTION;
  195. u32 WriteNonTurboFACart (u32 SrcAddr, u32 FlashAddr,
  196. u32 Length) CL_SECTION;
  197. u32 WriteTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length) CL_SECTION;
  198. #endif
  199. void WriteFlash (u32 addr, u16 data)
  200. {
  201. *(vu16 *) addr = data;
  202. }
  203. u16
  204. ReadFlash (u32 addr)
  205. {
  206. return (*(vu16 *) addr);
  207. }
  208. void
  209. WriteRepeat (u32 addr, u16 data, u16 count)
  210. {
  211. u16 i;
  212. for (i = 0; i < count; i++)
  213. *(vu16 *) (_CART_START + (addr << 1)) = data;
  214. }
  215. #endif
  216. #ifdef COMMON_FA_SUPPORT
  217. void
  218. VisolyModePreamble (void) // 402438
  219. {
  220. FLINKER_SET;
  221. WriteRepeat (0x987654, 0x5354, 1);
  222. WriteRepeat (0x12345, 0x1234, 500);
  223. WriteRepeat (0x7654, 0x5354, 1);
  224. WriteRepeat (0x12345, 0x5354, 1);
  225. WriteRepeat (0x12345, 0x5678, 500);
  226. WriteRepeat (0x987654, 0x5354, 1);
  227. WriteRepeat (0x12345, 0x5354, 1);
  228. WriteRepeat (0x765400, 0x5678, 1);
  229. WriteRepeat (0x13450, 0x1234, 1);
  230. WriteRepeat (0x12345, 0xabcd, 500);
  231. WriteRepeat (0x987654, 0x5354, 1);
  232. }
  233. void
  234. SetVisolyFlashRWMode (void)
  235. {
  236. VisolyModePreamble ();
  237. WriteRepeat (0xf12345, 0x9413, 1);
  238. }
  239. void
  240. SetVisolyBackupRWMode (int i) // 402550
  241. {
  242. VisolyModePreamble ();
  243. WriteRepeat (0xa12345, i, 1);
  244. }
  245. #endif
  246. // Cart Type Detect
  247. // Return a value indicating type of cart installed:
  248. // 0xdc = Hudson Cart, 0x2e = Standard ROM Cart
  249. // 0xe2 = N Flash Cart, 0xff = Unknown
  250. // 0x17 = FA 64M, 0x96 = Turbo FA 64M
  251. // 0x18 = FA 128M, 0x97 = Turbo FA 128M
  252. u8
  253. CartTypeDetect (void)
  254. {
  255. u8 type = 0xff;
  256. u16 Manuf, Device;
  257. WriteFlash (_CART_START, INTEL28F_RIC); // Read Identifier codes from flash.
  258. // Works for intel 28F640J3A & Sharp LH28F320BJE.
  259. Manuf = (unsigned short) ReadFlash (_CART_START);
  260. Device = (unsigned short) ReadFlash (_CART_START + _MEM_INC);
  261. switch (Manuf)
  262. {
  263. case 0: // Hudson Cart
  264. type = 0xdc;
  265. break;
  266. case 0x2e: // Standard ROM
  267. type = (u8) Manuf;
  268. break;
  269. case 0x89: // Intel chips
  270. switch (Device)
  271. {
  272. case 0x16: // i28F320J3A
  273. case 0x17: // i28F640J3A
  274. case 0x18: // i28F128J3A
  275. type = (u8) Device;
  276. break;
  277. default:
  278. // Check to see if this is a Visoly "Turbo" cart
  279. Device = (unsigned short) ReadFlash (_CART_START + _MEM_INC + _MEM_INC);
  280. switch (Device)
  281. {
  282. case 0x16: // 2 x i28F320J3A
  283. case 0x17: // 2 x i28F640J3A
  284. case 0x18: // 2 x i28F128J3A
  285. type = (unsigned char) (Device + 0x80);
  286. break;
  287. }
  288. }
  289. break;
  290. case 0xb0: // Sharp chips
  291. switch (Device)
  292. {
  293. case 0xe2:
  294. type = (u8) Device;
  295. break;
  296. }
  297. break;
  298. }
  299. WriteFlash (_CART_START, INTEL28F_READARRAY); // Set flash to normal read mode
  300. return type;
  301. }
  302. #ifdef NOA_FLASH_CART_SUPPORT
  303. // Erase official Nintendo flash cart blocks
  304. // Function returns true if erase was successful.
  305. // Each block represents 64k bytes.
  306. u32
  307. EraseNintendoFlashBlocks (u32 StartAddr, u32 BlockCount)
  308. {
  309. int i = 0;
  310. int j, k;
  311. time_t starttime = time (NULL);
  312. for (k = 0; k < (int) BlockCount; k++)
  313. {
  314. i = StartAddr + (k * 32768 * _MEM_INC);
  315. do
  316. {
  317. READ_NTURBO_SR (i, j);
  318. }
  319. while ((j & 0x80) == 0);
  320. WriteFlash (i, SHARP28F_BLOCKERASE); // Erase a 64k byte block
  321. WriteFlash (i, SHARP28F_CONFIRM); // Comfirm block erase
  322. ucon64_gauge (starttime, (k + 1) * 64 * 1024, BlockCount * 64 * 1024);
  323. }
  324. do
  325. {
  326. READ_NTURBO_SR (i, j);
  327. }
  328. while ((j & 0x80) == 0);
  329. WriteFlash (i, SHARP28F_READARRAY); // Set normal read mode
  330. return 1;
  331. }
  332. #endif
  333. #ifdef NONTURBO_FA_SUPPORT
  334. // Erase older (non-Turbo) FA/Visoly flash cart blocks
  335. // (Single flash chip)
  336. // Function returns true if erase was successful.
  337. // Each block represents 128k bytes.
  338. u32
  339. EraseNonTurboFABlocks (u32 StartAddr, u32 BlockCount)
  340. {
  341. u16 k;
  342. u16 Ready = 1;
  343. u32 i = 0;
  344. u32 Timeout;
  345. time_t starttime = time (NULL);
  346. for (k = 0; k < BlockCount; k++)
  347. {
  348. i = StartAddr + (k * 65536 * _MEM_INC);
  349. Ready = 0;
  350. Timeout = FP_TIMEOUT2;
  351. while ((Ready == 0) && (Timeout != 0))
  352. {
  353. READ_NTURBO_SR (_CART_START, Ready);
  354. Ready &= 0x80;
  355. Timeout--;
  356. }
  357. if (Ready)
  358. {
  359. WriteFlash (i, INTEL28F_BLOCKERASE); // Erase a 128k byte block
  360. Ready = 0;
  361. Timeout = FP_TIMEOUT3;
  362. while ((!Ready) && (Timeout != 0))
  363. {
  364. READ_NTURBO_S (Ready);
  365. Ready = (Ready == 0x80);
  366. Timeout--;
  367. }
  368. if (Ready)
  369. {
  370. WriteFlash (i, INTEL28F_CONFIRM); // Comfirm block erase
  371. Ready = 0;
  372. Timeout = FP_TIMEOUT3;
  373. while ((!Ready) && (Timeout != 0))
  374. {
  375. READ_NTURBO_S (Ready);
  376. Ready = (Ready == 0x80);
  377. Timeout--;
  378. }
  379. if (Ready)
  380. {
  381. READ_NTURBO_SR (_CART_START, Ready);
  382. Ready = (Ready == 0x80);
  383. if (!Ready)
  384. break;
  385. }
  386. else
  387. break;
  388. }
  389. else
  390. break;
  391. }
  392. else
  393. break;
  394. ucon64_gauge (starttime, (k + 1) * 128 * 1024,
  395. BlockCount * 128 * 1024);
  396. }
  397. if (!Ready)
  398. {
  399. WriteFlash (i, INTEL28F_CLEARSR); // Clear flash status register
  400. }
  401. WriteFlash (i, INTEL28F_READARRAY); // Set flash to normal read mode
  402. WriteFlash (i, INTEL28F_READARRAY); // Set flash to normal read mode
  403. return Ready != 0;
  404. }
  405. #endif
  406. #ifdef TURBO_FA_SUPPORT
  407. // Erase newer (Turbo) FA/Visoly flash cart blocks
  408. // (Dual chip / Interleave)
  409. // Function returns true if erase was successful.
  410. // Each block represents 256k bytes.
  411. u32
  412. EraseTurboFABlocks (u32 StartAddr, u32 BlockCount)
  413. {
  414. u16 j, k;
  415. u16 done1, done2;
  416. u16 Ready = 1;
  417. u32 i = 0;
  418. u32 Timeout;
  419. time_t starttime = time (NULL);
  420. for (k = 0; k < BlockCount; k++)
  421. {
  422. i = StartAddr + (k * 131072 * _MEM_INC);
  423. Ready = 0;
  424. Timeout = FP_TIMEOUT2;
  425. while ((!Ready) && (Timeout != 0))
  426. {
  427. READ_TURBO_SR (j);
  428. Ready = (j == 0x8080);
  429. Timeout--;
  430. }
  431. if (Ready)
  432. {
  433. done1 = 0;
  434. done2 = 0;
  435. Ready = 0;
  436. Timeout = FP_TIMEOUT3;
  437. while ((!Ready) && (Timeout != 0))
  438. {
  439. if (done1 == 0)
  440. WriteFlash (i, INTEL28F_BLOCKERASE); // Erase a 128k byte block in flash #1
  441. if (done2 == 0)
  442. WriteFlash (i + _MEM_INC, INTEL28F_BLOCKERASE); // Erase a 128k byte block in flash #2
  443. READ_TURBO_S2 (_CART_START, done1, done2);
  444. Ready = ((done1 + done2) == 0x100);
  445. Timeout--;
  446. }
  447. if (Ready)
  448. {
  449. WriteFlash (i, INTEL28F_CONFIRM); // Comfirm block erase in flash #1
  450. WriteFlash (i + _MEM_INC, INTEL28F_CONFIRM); // Comfirm block erase in flash #2
  451. Ready = 0;
  452. Timeout = FP_TIMEOUT3;
  453. j = 0;
  454. while (((j & 0x8080) != 0x8080) && (Timeout != 0))
  455. {
  456. READ_TURBO_S (j);
  457. Ready = (j == 0x8080);
  458. Timeout--;
  459. }
  460. if (!Ready)
  461. break;
  462. }
  463. else
  464. break;
  465. }
  466. else
  467. break;
  468. ucon64_gauge (starttime, (k + 1) * 256 * 1024,
  469. BlockCount * 256 * 1024);
  470. }
  471. if (!Ready)
  472. {
  473. WriteFlash (i, INTEL28F_CLEARSR);
  474. WriteFlash (i + _MEM_INC, INTEL28F_CLEARSR);
  475. }
  476. WriteFlash (_CART_START, INTEL28F_READARRAY);
  477. WriteFlash (_CART_START + _MEM_INC, INTEL28F_READARRAY);
  478. WriteFlash (_CART_START, INTEL28F_READARRAY);
  479. WriteFlash (_CART_START + _MEM_INC, INTEL28F_READARRAY);
  480. return Ready != 0;
  481. }
  482. #endif
  483. #ifdef NOA_FLASH_CART_SUPPORT
  484. // Write 2 x Length bytes to official Nintendo flash cart.
  485. // Function returns true if write was successful.
  486. u32
  487. WriteNintendoFlashCart (u32 SrcAddr, u32 FlashAddr, u32 Length)
  488. {
  489. int j;
  490. int LoopCount = 0;
  491. u16 *SrcAddr2 = (u16 *)
  492. #ifdef __LP64__
  493. (u64)
  494. #endif
  495. SrcAddr;
  496. while (LoopCount < (int) Length)
  497. {
  498. do
  499. {
  500. READ_NTURBO_SR (FlashAddr, j);
  501. }
  502. while ((j & 0x80) == 0);
  503. WriteFlash (FlashAddr, SHARP28F_WORDWRITE);
  504. WriteFlash (FlashAddr, *SrcAddr2);
  505. SrcAddr2 += 2;
  506. FlashAddr += _MEM_INC;
  507. LoopCount++;
  508. }
  509. do
  510. {
  511. READ_NTURBO_SR (FlashAddr, j);
  512. }
  513. while ((j & 0x80) == 0);
  514. WriteFlash (_CART_START, SHARP28F_READARRAY);
  515. // CTRL_PORT_0;
  516. return 1;
  517. }
  518. #endif
  519. #ifdef NONTURBO_FA_SUPPORT
  520. // Write 32 x Length bytes to older (non-Turbo) FA/Visoly flash cart.
  521. // Function returns true if write was successful.
  522. u32
  523. WriteNonTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
  524. {
  525. int Ready = 0;
  526. int Timeout = 0;
  527. int LoopCount = 0;
  528. u16 *SrcAddr2 = (u16 *)
  529. #ifdef __LP64__
  530. (u64)
  531. #endif
  532. SrcAddr;
  533. while (LoopCount < (int) Length)
  534. {
  535. Ready = 0;
  536. Timeout = FP_TIMEOUT1;
  537. while ((Ready == 0) && (Timeout != 0))
  538. {
  539. WriteFlash (FlashAddr, INTEL28F_WRTOBUF);
  540. READ_NTURBO_S (Ready);
  541. Ready &= 0x80;
  542. Timeout--;
  543. }
  544. if (Ready)
  545. {
  546. int i;
  547. WriteFlash (FlashAddr, 15); // Write 15+1 16bit words
  548. SET_CART_ADDR (FlashAddr);
  549. for (i = 0; i < 16; i++)
  550. {
  551. WRITE_FLASH_NEXT (FlashAddr, *SrcAddr2);
  552. SrcAddr2 += 2;
  553. FlashAddr += _MEM_INC;
  554. }
  555. WRITE_FLASH_NEXT (FlashAddr, INTEL28F_CONFIRM);
  556. Ready = 0;
  557. Timeout = FP_TIMEOUT1;
  558. while ((Ready == 0) && (Timeout != 0))
  559. {
  560. READ_NTURBO_SR (_CART_START, i);
  561. Ready = i & 0x80;
  562. Timeout--;
  563. }
  564. if (Ready)
  565. {
  566. if (i & 0x7f)
  567. {
  568. // One or more status register error bits are set
  569. CTRL_PORT_1;
  570. WriteFlash (0, INTEL28F_CLEARSR);
  571. Ready = 0;
  572. break;
  573. }
  574. }
  575. else
  576. {
  577. CTRL_PORT_1;
  578. WriteFlash (0, INTEL28F_CLEARSR);
  579. break;
  580. }
  581. }
  582. else
  583. {
  584. break;
  585. }
  586. LoopCount++;
  587. }
  588. WriteFlash (_CART_START, INTEL28F_READARRAY); // Set flash to normal read mode
  589. WriteFlash (_CART_START, INTEL28F_READARRAY); // Set flash to normal read mode
  590. return Ready != 0;
  591. }
  592. #endif
  593. #ifdef TURBO_FA_SUPPORT
  594. // Write 64 x Length bytes to newer (Turbo) FA/Visoly flash cart.
  595. // Function returns true if write was successful.
  596. u32
  597. WriteTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
  598. {
  599. int i, k;
  600. int done1, done2;
  601. int Timeout;
  602. int Ready = 0;
  603. int LoopCount = 0;
  604. u16 *SrcAddr2 = (u16 *)
  605. #ifdef __LP64__
  606. (u64)
  607. #endif
  608. SrcAddr;
  609. while (LoopCount < (int) Length)
  610. {
  611. done1 = 0;
  612. done2 = 0;
  613. Ready = 0;
  614. Timeout = 0x4000;
  615. while ((!Ready) && (Timeout != 0))
  616. {
  617. if (done1 == 0)
  618. WriteFlash (FlashAddr, INTEL28F_WRTOBUF);
  619. if (done2 == 0)
  620. WriteFlash (FlashAddr + _MEM_INC, INTEL28F_WRTOBUF);
  621. SET_CART_ADDR (FlashAddr);
  622. READ_TURBO_S2 (FlashAddr, done1, done2);
  623. Ready = ((done1 + done2) == 0x100);
  624. Timeout--;
  625. }
  626. if (Ready)
  627. {
  628. WriteFlash (FlashAddr, 15); // Write 15+1 16bit words
  629. WRITE_FLASH_NEXT (FlashAddr + _MEM_INC, 15); // Write 15+1 16bit words
  630. SET_CART_ADDR (FlashAddr);
  631. for (i = 0; i < 32; i++)
  632. {
  633. WRITE_FLASH_NEXT (FlashAddr, *SrcAddr2);
  634. SrcAddr2 += 2;
  635. FlashAddr += _MEM_INC;
  636. }
  637. WRITE_FLASH_NEXT (FlashAddr, INTEL28F_CONFIRM);
  638. WRITE_FLASH_NEXT (FlashAddr + _MEM_INC, INTEL28F_CONFIRM);
  639. Ready = 0;
  640. Timeout = 0x4000;
  641. k = 0;
  642. while (((k & 0x8080) != 0x8080) && (Timeout != 0))
  643. {
  644. READ_TURBO_S (k);
  645. Ready = (k == 0x8080);
  646. Timeout--;
  647. }
  648. if (!Ready)
  649. break;
  650. }
  651. else
  652. break;
  653. LoopCount++;
  654. }
  655. WriteFlash (_CART_START, INTEL28F_READARRAY);
  656. CTRL_PORT_0;
  657. WriteFlash (_CART_START + _MEM_INC, INTEL28F_READARRAY);
  658. CTRL_PORT_0;
  659. if (!Ready)
  660. {
  661. WriteFlash (_CART_START, INTEL28F_CLEARSR);
  662. WriteFlash (_CART_START + _MEM_INC, INTEL28F_CLEARSR);
  663. }
  664. return Ready != 0;
  665. }
  666. #endif
  667. #endif // USE_PARALLEL