2 famicom ROM cartridge utility - unagi
5 Copyright (C) 2008-2009 ±·³«È¯¶¨Æ±Áȹç
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 flashmemory.c ¤À¤±¤Î·Ù¹ð
22 ¤³¤Î¥½¡¼¥¹¥³¡¼¥É¤ò»²¹Í¡¢Å¾ÍѤ·¤Æ¥·¥§¥¢¥¦¥§¥¢¤Ê¤É¤ÇÍø±×¤òÆÀ¤Ê¤¤¤³¤È¡£
23 ȽÌÀ¤·¤¿¾ì¹ç¤Ï LGPL ¤¬Å¬ÍѤµ¤ì¡¢³ºÅö²Õ½ê¤Î¥½¡¼¥¹¤ò¸ø³«¤¹¤ëɬÍפ¬¤¢¤ë¡£
32 #include "flashmemory.h"
34 JEDEC flash memory command
35 http://www.sst.com/downloads/software_driver/SST49LF002A.txt
42 ADDRESS_2AAA = 0x2aaa,
43 ADDRESS_5555 = 0x5555,
46 static const struct flash_task PRODUCTID_ENTRY[] = {
50 {FLASH_COMMAND_END, 0}
52 static const struct flash_task PRODUCTID_EXIT[] = {
56 {FLASH_COMMAND_END, 0}
58 static const struct flash_task PROTECT_DISABLE[] = {
62 {FLASH_COMMAND_END, 0}
64 static const struct flash_task PROTECT_ENABLE[] = {
71 {FLASH_COMMAND_END, 0}
73 static const struct flash_task ERASE_CHIP[] = {
80 {FLASH_COMMAND_END, 0}
83 static const struct flash_task ERASE_SECTOR[] = {
89 //¤³¤Î¤¢¤È sectoraddress ¤Ë 0x30 ¤ò write
90 {FLASH_COMMAND_END, 0}
93 static const struct flash_task PP[] = {
100 {FLASH_COMMAND_END, 0}
103 static void command_set(const struct flash_order *d, const struct flash_task *t)
105 while(t->address != FLASH_COMMAND_END){
106 long logical_address = 0;
108 case ADDRESS_0000: //bank ¤Ë¤è¤Ã¤Æ¤ÏÀßÄê¤Ç¤¤Ê¤¤¤«¤â?
109 logical_address = d->command_0000;
112 logical_address = d->command_2aaa;
115 logical_address = d->command_5555;
118 assert(0); //unknown task address
120 d->flash_write(logical_address, t->data);
126 ---- product ID check ----
128 #define dprintf if(DEBUG==1) printf
129 static int productid_check(const struct flash_order *d, const struct flash_driver *f)
132 command_set(d, PRODUCTID_ENTRY);
133 d->read(d->command_0000, 3, data);
134 command_set(d, PRODUCTID_EXIT);
135 if(f->id_manufacurer != data[0]){
138 if(f->id_device != data[1]){
144 static int productid_sram(const struct flash_order *d, const struct flash_driver *f)
149 ---- toggle check ----
152 const int CHECK_RETRY_MAX = 0x10000;
153 static int toggle_check_d6(const struct flash_order *d, long address)
157 d->read(address, 1, &predata); //read DQ6
159 while(retry < CHECK_RETRY_MAX){
161 d->read(address, 1, &data); //read DQ6 again
172 static int toggle_check_d2d5d6(const struct flash_order *d, long address)
176 d->read(address, 1, &predata);
180 d->read(address, 1, &data);
182 if(predata == (data & 0x40)){
185 //DQ5 == 0 ¤Ê¤é¤ä¤ê¤Ê¤ª¤·
187 //recheck toggle bit, read twice
189 d->read(address, 1, &t[0]);
190 d->read(address, 1, &t[1]);
191 if((t[0] & 0x40) == (t[1] & 0x40)){
194 //Program/Erase operation not complete, write reset command.
197 if((retry & 0x0f) == 0){
198 dprintf("toggle out %06x \n", (int) address);
201 }while(retry < CHECK_RETRY_MAX);
206 ---- polling check ----
209 static int polling_check_d7(const struct flash_order *d, long address, u8 truedata)
214 while(retry < CHECK_RETRY_MAX){
216 d->read(address, 1, &data);
218 if(truedata == data){
226 static int polling_check_d5d7(const struct flash_order *d, long address, u8 truedata)
233 d->read(address, 1, &data);
234 if(truedata == (data & 0x80)){
238 d->read(address, 1, &data);
239 if(truedata == (data & 0x80)){
242 dprintf("%s error", __FUNCTION__);
246 }while(retry < CHECK_RETRY_MAX);
252 static void flash_erase_chip_2aaa(const struct flash_order *d)
254 command_set(d, ERASE_CHIP);
255 toggle_check_d6(d, d->command_2aaa);
256 Sleep(d->erase_wait);
259 static void flash_erase_chip_02aa(const struct flash_order *d)
262 d->read(d->command_2aaa, 1, &data);
263 command_set(d, ERASE_CHIP);
265 toggle_check_d2d5d6(d, d->command_2aaa);
268 polling_check_d5d7(d, d->command_2aaa, data);
270 Sleep(d->erase_wait);
274 static void sram_erase(const struct flash_order *d)
276 //bank ÀÚ¤êÂؤ¨¤¬È¼¤¦¤Î¤Ç¼ÂÁõ¤Ç¤¤Ê¤¤
283 static int program_byte(const struct flash_order *d, long address, const u8 *data, long length)
288 command_set(d, PROTECT_DISABLE);
289 d->flash_write(address, *data);
290 if(toggle_check_d6(d, address) == NG){
291 dprintf("%s NG\n", __FUNCTION__);
294 /*if(polling_check_d7(d, address, *data) == NG){
295 dprintf("%s NG\n", __FUNCTION__);
306 static int program_pagewrite(const struct flash_order *d, long address, const u8 *data, long length)
308 const long toggle_address = address ;
309 command_set(d, PROTECT_DISABLE);
311 d->flash_write(address, *data);
316 int ret = toggle_check_d6(d, toggle_address);
319 polling_check_d7(d, address - 1, *data);
328 static void w49f002_init(const struct flash_order *d)
331 byte program mode ¤Ç¤Ï 1->0 ¤Ë¤¹¤ë¤À¤±¡£ 0->1 ¤Ï erase ¤Î¤ß¡£
332 ¤è¤Ã¤Æ½é´ü²½»þ¤Ë¤Ï erase ¤ò¼Â¹Ô¤¹¤ë
334 flash_erase_chip_2aaa(d);
337 static void w49f002_write(const struct flash_order *d, long address, long length, const struct memory *m)
339 program_byte(d, address, m->data, length);
340 // dprintf("write %s 0x%06x done\n", m->name, (int) m->offset);
343 static void am29f040_init(const struct flash_order *d)
345 flash_erase_chip_02aa(d);
348 static void am29f040_write(const struct flash_order *d, long address, long length, const struct memory *m)
354 command_set(d, PROTECT_DISABLE);
355 d->flash_write(address, *data);
356 if(toggle_check_d2d5d6(d, address) == NG){
357 dprintf("%s NG\n", __FUNCTION__);
367 static void init_nop(const struct flash_order *d)
370 page write mode ¤Ç¤Ï¤È¤¯¤Ë¤Ê¤·
374 static void w29c040_write(const struct flash_order *d, long address, long length, const struct memory *m)
379 assert(d->pagesize != 0);
380 cmp = malloc(d->pagesize);
384 long offset = m->offset;
390 d->read(a, d->pagesize, cmp);
391 if(memcmp(cmp, dd, d->pagesize) != 0){
393 //dprintf("write %s 0x%06x\n", m->name, (int) offset);
394 int result = program_pagewrite(d, a, dd, d->pagesize);
396 printf("%s: write error\n", __FUNCTION__);
403 offset += d->pagesize;
406 dprintf("%s 0x%06x, ngblock %d\n", m->name, (int) m->offset, ngblock);
408 if(retry >= 3 && ngblock >= 16){
418 }while(ngblock != 0);
423 static void sram_write(const struct flash_order *d, long address, long length, const struct memory *m)
428 d->flash_write(address, *data);
435 static void dummy_write(const struct flash_order *d, long address, long length, const struct memory *m)
442 //0x80 °Ê¹ß¤ÏËÜÅö¤Î¥Ç¥Ð¥¤¥¹½ÅÊ£¤·¤Ê¤¤¤È»×¤¦. 狼 JEDEC ¤Î¤È¤³¤ò¤·¤é¤Ù¤Æ.
443 static const struct flash_driver DRIVER_SRAM256K = {
449 .id_manufacurer = FLASH_ID_DEVICE_SRAM,
450 .id_device = FLASH_ID_DEVICE_SRAM,
451 .productid_check = productid_sram,
459 static const struct flash_driver DRIVER_DUMMY = {
465 .id_manufacurer = FLASH_ID_DEVICE_DUMMY,
466 .id_device = FLASH_ID_DEVICE_DUMMY,
467 .productid_check = productid_sram,
475 static const struct flash_driver DRIVER_W29C020 = {
480 .command_mask = 0x7fff,
481 .id_manufacurer = 0xda,
483 .productid_check = productid_check,
485 .erase = flash_erase_chip_2aaa,
488 .write = w29c040_write
491 static const struct flash_driver DRIVER_W29C040 = {
496 .command_mask = 0x7fff,
497 .id_manufacurer = 0xda,
499 .productid_check = productid_check,
501 .erase = flash_erase_chip_2aaa,
504 .write = w29c040_write
507 static const struct flash_driver DRIVER_W49F002 = {
511 .erase_wait = 1000, //typ 0.1, max 0.2 sec
512 .command_mask = 0x7fff,
513 .id_manufacurer = 0xda,
515 .productid_check = productid_check,
517 .erase = flash_erase_chip_2aaa,
519 .init = w49f002_init,
520 .write = w49f002_write
524 MANUFATUTER ID 0x7f1c
525 EN29F002T DEVICE ID 0x7f92
526 EN29F002B DEVICE ID 0x7f97
528 command address ¤¬ 0x00555, 0x00aaa ¤Ë¤Ê¤Ã¤Æ¤ë
530 static const struct flash_driver DRIVER_EN29F002T = {
534 .erase_wait = 3000, //typ 2, max 5 sec
535 .command_mask = 0x07ff,
536 .id_manufacurer = 0x1c,
538 .productid_check = productid_check,
540 .erase = flash_erase_chip_02aa,
542 .init = am29f040_init,
543 .write = am29f040_write
546 static const struct flash_driver DRIVER_AM29F040B = {
550 .erase_wait = 8000, //typ 8, max 64 sec
551 .command_mask = 0x07ff,
552 .id_manufacurer = 0x01,
554 .productid_check = productid_check,
556 .erase = flash_erase_chip_02aa,
558 .init = am29f040_init,
559 .write = am29f040_write
562 static const struct flash_driver *DRIVER_LIST[] = {
563 &DRIVER_W29C020, &DRIVER_W29C040,
564 &DRIVER_W49F002, &DRIVER_EN29F002T, &DRIVER_AM29F040B,
570 const struct flash_driver *flash_driver_get(const char *name)
572 const struct flash_driver **d;
575 if(strcmp(name, (*d)->name) == 0){