2 famicom ROM cartridge utility - unagi
5 Copyright (C) 2008 sato_tiff
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 driver for Winbond W29C020, W49F002
37 JEDEC flash memory command
38 http://www.sst.com/downloads/software_driver/SST49LF002A.txt
45 ADDRESS_2AAA = 0x2aaa,
46 ADDRESS_5555 = 0x5555,
49 static const struct flash_task PRODUCTID_ENTRY[] = {
53 {FLASH_COMMAND_END, 0}
55 static const struct flash_task PRODUCTID_EXIT[] = {
59 {FLASH_COMMAND_END, 0}
61 static const struct flash_task PROTECT_DISABLE[] = {
65 {FLASH_COMMAND_END, 0}
67 static const struct flash_task PROTECT_ENABLE[] = {
74 {FLASH_COMMAND_END, 0}
76 static const struct flash_task ERASE_CHIP[] = {
83 {FLASH_COMMAND_END, 0}
86 static const struct flash_task ERASE_SECTOR[] = {
92 //¤³¤Î¤¢¤È sectoraddress ¤Ë 0x30 ¤ò write
93 {FLASH_COMMAND_END, 0}
96 static const struct flash_task PP[] = {
100 {ADDRESS_5555, 0xaa},
101 {ADDRESS_2AAA, 0x55},
102 {ADDRESS_5555, 0x60},
103 {FLASH_COMMAND_END, 0}
106 static void command_set(const struct flash_order *d, const struct flash_task *t)
108 while(t->address != FLASH_COMMAND_END){
109 long logical_address = 0;
111 case ADDRESS_0000: //bank ¤Ë¤è¤Ã¤Æ¤ÏÀßÄê¤Ç¤¤Ê¤¤¤«¤â?
112 logical_address = d->command_0000;
115 logical_address = d->command_2aaa;
118 logical_address = d->command_5555;
121 assert(0); //unknown task address
123 d->flash_write(logical_address, t->data);
129 ---- product ID check ----
131 static int productid_check(const struct flash_order *d, const struct flash_driver *f)
134 command_set(d, PRODUCTID_ENTRY);
135 d->read(d->command_0000, 3, data);
136 command_set(d, PRODUCTID_EXIT);
137 if(f->id_manufacurer != data[0]){
140 if(f->id_device != data[1]){
146 static int productid_sram(const struct flash_order *d, const struct flash_driver *f)
151 ---- toggle check ----
154 const int CHECK_RETRY_MAX = 0x10000;
155 static int toggle_check(const struct flash_order *d, long address)
159 d->read(address, 1, &predata); //read DQ6
161 while(retry < CHECK_RETRY_MAX){
163 d->read(address, 1, &data); //read DQ6 again
175 ---- polling check ----
178 static int polling_check(const struct flash_order *d, long address, u8 truedata)
183 while(retry < CHECK_RETRY_MAX){
185 d->read(address, 1, &data);
187 if(truedata == data){
195 static void bootblock_lockout(const struct flash_order *d)
199 d->read(0x8000 ,3, dummy);
200 printf("%02x %02x %02x \n", dummy[0], dummy[1], dummy[2]);
201 d->read(0xfff2 ,1, dummy);
202 command_set(d, PRODUCTID_EXIT);
207 static void flash_erase_chip(const struct flash_order *d)
209 if(0) bootblock_lockout(d);
210 command_set(d, ERASE_CHIP);
211 toggle_check(d, d->command_2aaa);
212 Sleep(200); //Tec 0.2 sec
215 static void sram_erase(const struct flash_order *d)
217 //bank ÀÚ¤êÂؤ¨¤¬È¼¤¦¤Î¤Ç¼ÂÁõ¤Ç¤¤Ê¤¤
223 static int program_byte(const struct flash_order *d, long address, const u8 *data, long length)
229 command_set(d, PROTECT_DISABLE);
230 d->flash_write(address, *data);
231 if(toggle_check(d, address) == NG){
233 printf("%s NG\n", __FUNCTION__);
239 d->read(address, 1, &dummy);
246 printf("%s %06x error\n", __FUNCTION__, (int) address);
258 static int program_pagewrite(const struct flash_order *d, long address, const u8 *data, long length)
260 const long toggle_address = address ;
261 command_set(d, PROTECT_DISABLE);
263 d->flash_write(address, *data);
269 int ret = toggle_check(d, toggle_address);
273 polling_check(d, address - 1, *data);
276 //command_set(d, PROTECT_ENABLE);
282 ---- block compare ----
284 static void compare(const struct flash_order *d, long address, const u8 *data, long length)
288 romdata = malloc(length);
289 d->read(address, length, romdata);
294 if((count & 7) == 7){
298 printf("%06x%c", (int)address, safix);
311 static void w49f002_init(const struct flash_order *d)
314 byte program mode ¤Ç¤Ï 1->0 ¤Ë¤¹¤ë¤À¤±¡£ 0->1 ¤Ï erase ¤Î¤ß¡£
315 ¤è¤Ã¤Æ½é´ü²½»þ¤Ë¤Ï erase ¤ò¼Â¹Ô¤¹¤ë
320 static void w49f002_write(const struct flash_order *d, long address, long length, const struct memory *m)
322 program_byte(d, address, m->data, length);
326 static void init_nop(const struct flash_order *d)
329 page write mode ¤Ç¤Ï¤È¤¯¤Ë¤Ê¤·
333 static void w29c020_write(const struct flash_order *d, long address, long length, const struct memory *m)
336 assert(d->pagesize != 0);
344 cmp = malloc(d->pagesize);
346 int result = program_pagewrite(d, a, dd, d->pagesize);
348 printf("%s: write error\n", __FUNCTION__);
352 d->read(a, d->pagesize, cmp);
353 if(memcmp(cmp, dd, d->pagesize) == 0){
367 printf("write ok. retry %d\n", retry);
368 compare(d, address, m->data, length);
372 static void w29c040_write(const struct flash_order *d, long address, long length, const struct memory *m)
377 assert(d->pagesize != 0);
378 cmp = malloc(d->pagesize);
382 long offset = m->offset;
388 d->read(a, d->pagesize, cmp);
389 if(memcmp(cmp, dd, d->pagesize) != 0){
391 printf("write %s 0x%06x\n", m->name, (int) offset);
392 int result = program_pagewrite(d, a, dd, d->pagesize);
394 printf("%s: write error\n", __FUNCTION__);
401 offset += d->pagesize;
404 printf("%s 0x%06x, ngblock %d\n", m->name, (int) offset, ngblock);
405 if(retry >= 3 && ngblock >= 16){
415 }while(ngblock != 0);
418 // compare(d, address, data, length);
422 static void sram_write(const struct flash_order *d, long address, long length, const struct memory *m)
427 d->flash_write(address, *data);
440 static const struct flash_driver DRIVER_SRAM256K = {
444 .id_manufacurer = ID_SRAM,
445 .id_device = ID_SRAM,
446 .productid_check = productid_sram,
454 static const struct flash_driver DRIVER_W29C020 = {
458 .id_manufacurer = 0xda,
460 .productid_check = productid_check,
462 .erase = flash_erase_chip,
465 .write = w29c020_write
468 static const struct flash_driver DRIVER_W29C040 = {
472 .id_manufacurer = 0xda,
474 .productid_check = productid_check,
476 .erase = flash_erase_chip,
479 .write = w29c040_write
482 static const struct flash_driver DRIVER_W49F002 = {
486 .id_manufacurer = 0xda,
488 .productid_check = productid_check,
490 .erase = flash_erase_chip,
492 .init = w49f002_init,
493 .write = w49f002_write
497 MANUFATUTER ID 0x7f1c
498 EN29F002T DEVICE ID 0x7f92
499 EN29F002B DEVICE ID 0x7f97
501 command address ¤¬ 0x00555, 0x00aaa ¤Ë¤Ê¤Ã¤Æ¤ë
503 static const struct flash_driver DRIVER_EN29F002T = {
507 .id_manufacurer = 0x1c,
509 .productid_check = productid_check,
511 .erase = flash_erase_chip,
513 .init = w49f002_init,
514 .write = w49f002_write
517 static const struct flash_driver DRIVER_AM29F040B = {
521 .id_manufacurer = 0x01,
523 .productid_check = productid_check,
525 .erase = flash_erase_chip,
527 .init = w49f002_init,
528 .write = w49f002_write
531 static const struct flash_driver *DRIVER_LIST[] = {
532 &DRIVER_W29C020, &DRIVER_W29C040, &DRIVER_W49F002,
537 const struct flash_driver *flash_driver_get(const char *name)
539 const struct flash_driver **d;
542 if(strcmp(name, (*d)->name) == 0){