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 ¤¬Å¬ÍѤµ¤ì¡¢³ºÅö²Õ½ê¤Î¥½¡¼¥¹¤ò¸ø³«¤¹¤ëɬÍפ¬¤¢¤ë¡£
30 #include "driver_master.h"
31 #include "flashmemory.h"
33 driver for Winbond W29C020, W49F002
38 cpu address|rom address |page|task
39 $8000-$bfff|0x00000-0x03fff|0 |write (0x2aaa & 0x3fff) + 0x8000
40 $c000-$dfff|0x04000-0x05fff|2 |write (0x5555 & 0x1fff) + 0xc000
41 $e000-$efff|0x3e000-0x3ffff|fix |boot area
44 cpu address|rom address |page|task
45 $8000-$9fff|0x02000-0x03fff|1 |write (0x2aaa & 0x1fff) + 0x8000
46 $a000-$bfff|0x04000-0x05fff|2 |write (0x5555 & 0x1fff) + 0xa000
47 $c000-$efff|ËöÈø |fix |boot area
49 generic CPU memory bank
50 cpu address|rom address |page|task
51 $8000-$9fff|0x02000-0x03fff|1 |write (0x2aaa & 0x1fff) + 0x8000
52 $a000-$bfff|0x04000-0x05fff|2 |write (0x5555 & 0x1fff) + 0xa000
53 $c000-$dfff|n * 0x2000 |n |write area
54 $e000-$efff|ËöÈø |fix |boot area, ̤»ÈÍÑ
56 generic PPU memory bank
57 ppu address|rom address |page|task
58 $0000-$03ff|0x02800-0x02bff|0x0a|write (0x2aaa & 0x03ff) + 0
59 $0400-$07ff|0x05400-0x057ff|0x15|write (0x5555 & 0x03ff) + 0x400
61 $1000-$1fff|n * 0x0400 |n |write area
64 JEDEC flash memory command
65 http://www.sst.com/downloads/software_driver/SST49LF002A.txt
71 flash_task_end = 0x46494649
73 static const struct flash_task PRODUCTID_ENTRY[] = {
79 static const struct flash_task PRODUCTID_EXIT[] = {
85 static const struct flash_task PROTECT_DISABLE[] = {
91 static const struct flash_task PROTECT_ENABLE[] = {
100 static const struct flash_task ERASE[] = {
110 static void task_set(const struct flash_order *d, const struct flash_task *t)
112 while(t->address != flash_task_end){
113 long cpu_address = 0;
116 cpu_address = d->task_2aaa;
119 cpu_address = d->task_5555;
124 d->flash_write(cpu_address, t->data);
130 ---- product ID check ----
132 static int productid_check(const struct flash_order *d, const struct flash_driver *f)
135 task_set(d, PRODUCTID_ENTRY);
136 d->read(d->task_0000, 3, data);
137 task_set(d, PRODUCTID_EXIT);
138 if(f->id_manufacurer != data[0]){
141 if(f->id_device != data[1]){
148 ---- toggle check ----
151 const int CHECK_RETRY_MAX = 0x10000;
152 static int toggle_check(const struct flash_order *d, long address)
156 d->read(address, 1, &predata); //read DQ6
158 while(retry < CHECK_RETRY_MAX){
160 d->read(address, 1, &data); //read DQ6 again
172 ---- polling check ----
175 static int polling_check(const struct flash_order *d, long address, u8 truedata)
180 while(retry < CHECK_RETRY_MAX){
182 d->read(address, 1, &data);
184 if(truedata == data){
195 static void flash_erase(const struct flash_order *d)
198 toggle_check(d, d->task_2aaa);
199 //Sleep(200); //Tec 0.2 sec
205 static int program_byte(const struct flash_order *d, long address, const u8 *data, long length)
209 task_set(d, PROTECT_DISABLE);
210 d->flash_write(address, *data);
211 if(toggle_check(d, address) == NG){
213 printf("%s NG\n", __FUNCTION__);
219 d->read(address, 1, &putdata);
220 if(putdata != *data){
221 printf("%s %06x retry\n", __FUNCTION__, (int) address);
226 if((DEBUG == 1) && (address & 0x1f) == 0){
227 printf("%s %06x\n", __FUNCTION__, (int) address);
237 static int program_pagewrite(const struct flash_order *d, long address, const u8 *data, long length)
239 task_set(d, PROTECT_DISABLE);
241 d->flash_write(address, *data);
247 return toggle_check(d, d->address);
251 ---- block compare ----
253 static void compare(const struct flash_order *d, long address, const u8 *data, long length)
256 romdata = malloc(length);
257 d->read(address, length, romdata);
261 printf("%06x\n", (int)address);
274 static void w49f002_write(const struct flash_order *d)
276 program_byte(d, d->address, d->data, d->length);
277 compare(d, d->address, d->data, d->length);
280 static void w29c020_write(const struct flash_order *d)
283 const long pagesize = 0x80;
289 int result = program_pagewrite(d, a, dd, d->length);
298 compare(d, d->address, d->data, d->length);
304 static const struct flash_driver DRIVER_W29C020 = {
307 id_manufacurer: 0xda,
309 productid_check: productid_check,
314 static const struct flash_driver DRIVER_W49F002 = {
317 id_manufacurer: 0xda,
319 productid_check: productid_check,
324 static const struct flash_driver *DRIVER_LIST[] = {
325 &DRIVER_W29C020, &DRIVER_W49F002,
329 const struct flash_driver *flash_driver_get(const char *name)
331 const struct flash_driver **d;
334 if(strcmp(name, (*d)->name) == 0){