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[] = {
83 {FLASH_COMMAND_END, 0}
86 static const struct flash_task PP[] = {
93 {FLASH_COMMAND_END, 0}
96 static void command_set(const struct flash_order *d, const struct flash_task *t)
98 while(t->address != FLASH_COMMAND_END){
99 long logical_address = 0;
101 case ADDRESS_0000: //bank ¤Ë¤è¤Ã¤Æ¤ÏÀßÄê¤Ç¤¤Ê¤¤¤«¤â?
102 logical_address = d->command_0000;
105 logical_address = d->command_2aaa;
108 logical_address = d->command_5555;
111 assert(0); //unknown task address
113 d->flash_write(logical_address, t->data);
119 ---- product ID check ----
121 static int productid_check(const struct flash_order *d, const struct flash_driver *f)
124 command_set(d, PRODUCTID_ENTRY);
125 d->read(d->command_0000, 3, data);
126 command_set(d, PRODUCTID_EXIT);
127 if(f->id_manufacurer != data[0]){
130 if(f->id_device != data[1]){
136 static int productid_sram(const struct flash_order *d, const struct flash_driver *f)
141 ---- toggle check ----
144 const int CHECK_RETRY_MAX = 0x10000;
145 static int toggle_check(const struct flash_order *d, long address)
149 d->read(address, 1, &predata); //read DQ6
151 while(retry < CHECK_RETRY_MAX){
153 d->read(address, 1, &data); //read DQ6 again
165 ---- polling check ----
168 static int polling_check(const struct flash_order *d, long address, u8 truedata)
173 while(retry < CHECK_RETRY_MAX){
175 d->read(address, 1, &data);
177 if(truedata == data){
185 static void bootblock_lockout(const struct flash_order *d)
189 d->read(0x8000 ,3, dummy);
190 printf("%02x %02x %02x \n", dummy[0], dummy[1], dummy[2]);
191 d->read(0xfff2 ,1, dummy);
192 command_set(d, PRODUCTID_EXIT);
197 static void flash_erase(const struct flash_order *d)
199 if(0) bootblock_lockout(d);
200 command_set(d, ERASE);
201 toggle_check(d, d->command_2aaa);
202 Sleep(200); //Tec 0.2 sec
205 static void sram_erase(const struct flash_order *d)
207 //bank ÀÚ¤êÂؤ¨¤¬È¼¤¦¤Î¤Ç¼ÂÁõ¤Ç¤¤Ê¤¤
213 static int program_byte(const struct flash_order *d, long address, const u8 *data, long length)
219 command_set(d, PROTECT_DISABLE);
220 d->flash_write(address, *data);
221 if(toggle_check(d, address) == NG){
223 printf("%s NG\n", __FUNCTION__);
229 d->read(address, 1, &dummy);
236 printf("%s %06x error\n", __FUNCTION__, (int) address);
248 static int program_pagewrite(const struct flash_order *d, long address, const u8 *data, long length)
250 const long toggle_address = address ;
251 command_set(d, PROTECT_DISABLE);
253 d->flash_write(address, *data);
259 int ret = toggle_check(d, toggle_address);
263 polling_check(d, address - 1, *data);
266 //command_set(d, PROTECT_ENABLE);
272 ---- block compare ----
274 static void compare(const struct flash_order *d, long address, const u8 *data, long length)
278 romdata = malloc(length);
279 d->read(address, length, romdata);
284 if((count & 7) == 7){
288 printf("%06x%c", (int)address, safix);
301 static void w49f002_init(const struct flash_order *d)
304 byte program mode ¤Ç¤Ï 1->0 ¤Ë¤¹¤ë¤À¤±¡£ 0->1 ¤Ï erase ¤Î¤ß¡£
305 ¤è¤Ã¤Æ½é´ü²½»þ¤Ë¤Ï erase ¤ò¼Â¹Ô¤¹¤ë
310 static void w49f002_write(const struct flash_order *d, long address, long length, const struct memory *m)
312 program_byte(d, address, m->data, length);
316 static void init_nop(const struct flash_order *d)
319 page write mode ¤Ç¤Ï¤È¤¯¤Ë¤Ê¤·
323 static void w29c020_write(const struct flash_order *d, long address, long length, const struct memory *m)
326 assert(d->pagesize != 0);
334 cmp = malloc(d->pagesize);
336 int result = program_pagewrite(d, a, dd, d->pagesize);
338 printf("%s: write error\n", __FUNCTION__);
342 d->read(a, d->pagesize, cmp);
343 if(memcmp(cmp, dd, d->pagesize) == 0){
357 printf("write ok. retry %d\n", retry);
358 compare(d, address, m->data, length);
362 static void w29c040_write(const struct flash_order *d, long address, long length, const struct memory *m)
367 assert(d->pagesize != 0);
368 cmp = malloc(d->pagesize);
372 long offset = m->offset;
378 d->read(a, d->pagesize, cmp);
379 if(memcmp(cmp, dd, d->pagesize) != 0){
381 printf("write %s 0x%06x\n", m->name, (int) offset);
382 int result = program_pagewrite(d, a, dd, d->pagesize);
384 printf("%s: write error\n", __FUNCTION__);
391 offset += d->pagesize;
394 printf("%s 0x%06x, ngblock %d\n", m->name, (int) offset, ngblock);
395 if(retry >= 3 && ngblock >= 16){
405 }while(ngblock != 0);
408 // compare(d, address, data, length);
412 static void sram_write(const struct flash_order *d, long address, long length, const struct memory *m)
417 d->flash_write(address, *data);
430 static const struct flash_driver DRIVER_SRAM256K = {
434 .id_manufacurer = ID_SRAM,
435 .id_device = ID_SRAM,
436 .productid_check = productid_sram,
444 static const struct flash_driver DRIVER_W29C020 = {
448 .id_manufacurer = 0xda,
450 .productid_check = productid_check,
452 .erase = flash_erase,
455 .write = w29c020_write
458 static const struct flash_driver DRIVER_W29C040 = {
462 .id_manufacurer = 0xda,
464 .productid_check = productid_check,
466 .erase = flash_erase,
469 .write = w29c040_write
472 static const struct flash_driver DRIVER_W49F002 = {
476 .id_manufacurer = 0xda,
478 .productid_check = productid_check,
480 .erase = flash_erase,
482 .init = w49f002_init,
483 .write = w49f002_write
486 static const struct flash_driver *DRIVER_LIST[] = {
487 &DRIVER_W29C020, &DRIVER_W29C040, &DRIVER_W49F002,
492 const struct flash_driver *flash_driver_get(const char *name)
494 const struct flash_driver **d;
497 if(strcmp(name, (*d)->name) == 0){