1 /*
2 * flash040core.c - (AM)29F0[14]0(B) Flash emulation.
3 *
4 * Written by
5 * Hannu Nuotio <hannu.nuotio@tut.fi>
6 * Extended by
7 * Marko Makela <marko.makela@iki.fi>
8 *
9 * This file is part of VICE, the Versatile Commodore Emulator.
10 * See README for copyright notice.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA.
25 *
26 */
27
28 #include "vice.h"
29
30 #include <stdio.h>
31 #include <string.h>
32
33 #include "alarm.h"
34 #include "flash040.h"
35 #include "lib.h"
36 #include "log.h"
37 #include "maincpu.h"
38 #include "snapshot.h"
39 #include "types.h"
40
41 /* -------------------------------------------------------------------------- */
42
43 /* #define FLASH_DEBUG_ENABLED */
44
45 #ifdef FLASH_DEBUG_ENABLED
46 #define FLASH_DEBUG(x) log_debug x
47 #else
48 #define FLASH_DEBUG(x)
49 #endif
50
51 struct flash_types_s {
52 uint8_t manufacturer_ID;
53 uint8_t device_ID;
54 uint8_t device_ID_addr;
55 unsigned int size;
56 unsigned int sector_mask;
57 unsigned int sector_size;
58 unsigned int sector_shift;
59 unsigned int magic_1_addr;
60 unsigned int magic_2_addr;
61 unsigned int magic_1_mask;
62 unsigned int magic_2_mask;
63 uint8_t status_toggle_bits;
64 unsigned int erase_sector_timeout_cycles;
65 unsigned int erase_sector_cycles;
66 unsigned int erase_chip_cycles;
67 };
68 typedef struct flash_types_s flash_types_t;
69
70 static const flash_types_t flash_types[FLASH040_TYPE_NUM] = {
71 /* AM29F040 */
72 { 0x01, 0xa4, 1,
73 0x80000,
74 0x70000, 0x10000, 16,
75 0x5555, 0x2aaa, 0x7fff, 0x7fff,
76 0x40,
77 80, 2000000, 14000000}, /* may take up to 30s and 120s */
78 /* AM29F040B */
79 { 0x01, 0xa4, 1,
80 0x80000,
81 0x70000, 0x10000, 16,
82 0x555, 0x2aa, 0x7ff, 0x7ff,
83 0x40,
84 50, 1000000, 8000000}, /* may take up to 8s and 64s */
85 /* 29F010 */
86 { 0x01, 0x20, 1,
87 0x20000,
88 0x1c000, 0x04000, 14,
89 0x5555, 0x2aaa, 0x7fff, 0x7fff,
90 0x40,
91 80, 1000000, 1000000 }, /* may take up to 15s */
92 /* 29F032B with A0/1 swap */
93 { 0x01, 0x41, 1,
94 0x400000,
95 0x3f0000, 0x10000, 16,
96 0x556, 0x2a9, 0x7ff, 0x7ff,
97 0x44,
98 50, 1000000, 64000000 }, /* may take up to 8s */
99 /* Spansion S29GL064N */
100 { 0x01, 0x7e, 2,
101 0x800000,
102 /* FIXME: some models support non-uniform sector layout */
103 0x7f0000, 0x10000, 16,
104 0xaaa, 0x555, 0xfff, 0xfff,
105 0x40,
106 50, 500000, 64000000}, /* may take up to 3.5s and 128s */
107 };
108
109 /* -------------------------------------------------------------------------- */
110
flash_magic_1(flash040_context_t * flash040_context,unsigned int addr)111 inline static int flash_magic_1(flash040_context_t *flash040_context, unsigned int addr)
112 {
113 return ((addr & flash_types[flash040_context->flash_type].magic_1_mask) == flash_types[flash040_context->flash_type].magic_1_addr);
114 }
115
flash_magic_2(flash040_context_t * flash040_context,unsigned int addr)116 inline static int flash_magic_2(flash040_context_t *flash040_context, unsigned int addr)
117 {
118 return ((addr & flash_types[flash040_context->flash_type].magic_2_mask) == flash_types[flash040_context->flash_type].magic_2_addr);
119 }
120
flash_clear_erase_mask(flash040_context_t * flash040_context)121 inline static void flash_clear_erase_mask(flash040_context_t *flash040_context)
122 {
123 int i;
124
125 for (i = 0; i < FLASH040_ERASE_MASK_SIZE; ++i) {
126 flash040_context->erase_mask[i] = 0;
127 }
128 }
129
flash_sector_to_addr(flash040_context_t * flash040_context,unsigned int sector)130 inline static unsigned int flash_sector_to_addr(flash040_context_t *flash040_context, unsigned int sector)
131 {
132 unsigned int sector_size = flash_types[flash040_context->flash_type].sector_size;
133
134 return sector * sector_size;
135 }
136
flash_addr_to_sector_number(flash040_context_t * flash040_context,unsigned int addr)137 inline static unsigned int flash_addr_to_sector_number(flash040_context_t *flash040_context, unsigned int addr)
138 {
139 unsigned int sector_addr = flash_types[flash040_context->flash_type].sector_mask & addr;
140 unsigned int sector_shift = flash_types[flash040_context->flash_type].sector_shift;
141
142 return sector_addr >> sector_shift;
143 }
144
flash_add_sector_to_erase_mask(flash040_context_t * flash040_context,unsigned int addr)145 inline static void flash_add_sector_to_erase_mask(flash040_context_t *flash040_context, unsigned int addr)
146 {
147 unsigned int sector_num = flash_addr_to_sector_number(flash040_context, addr);
148
149 flash040_context->erase_mask[sector_num >> 3] |= (uint8_t)(1 << (sector_num & 0x7));
150 }
151
flash_erase_sector(flash040_context_t * flash040_context,unsigned int sector)152 inline static void flash_erase_sector(flash040_context_t *flash040_context, unsigned int sector)
153 {
154 unsigned int sector_size = flash_types[flash040_context->flash_type].sector_size;
155 unsigned int sector_addr;
156
157 sector_addr = flash_sector_to_addr(flash040_context, sector);
158
159 FLASH_DEBUG(("Erasing 0x%x - 0x%x", sector_addr, sector_addr + sector_size - 1));
160 memset(&(flash040_context->flash_data[sector_addr]), 0xff, sector_size);
161 flash040_context->flash_dirty = 1;
162 }
163
flash_erase_chip(flash040_context_t * flash040_context)164 inline static void flash_erase_chip(flash040_context_t *flash040_context)
165 {
166 FLASH_DEBUG(("Erasing chip"));
167 memset(flash040_context->flash_data, 0xff, flash_types[flash040_context->flash_type].size);
168 flash040_context->flash_dirty = 1;
169 }
170
flash_program_byte(flash040_context_t * flash040_context,unsigned int addr,uint8_t byte)171 inline static int flash_program_byte(flash040_context_t *flash040_context, unsigned int addr, uint8_t byte)
172 {
173 uint8_t old_data = flash040_context->flash_data[addr];
174 uint8_t new_data = old_data & byte;
175
176 FLASH_DEBUG(("Programming 0x%05x with 0x%02x (%02x->%02x)", addr, byte, old_data, old_data & byte));
177 flash040_context->program_byte = byte;
178 flash040_context->flash_data[addr] = new_data;
179 flash040_context->flash_dirty = 1;
180
181 return (new_data == byte) ? 1 : 0;
182 }
183
flash_write_operation_status(flash040_context_t * flash040_context)184 inline static int flash_write_operation_status(flash040_context_t *flash040_context)
185 {
186 return ((flash040_context->program_byte ^ 0x80) & 0x80) /* DQ7 = inverse of programmed data */
187 | ((maincpu_clk & 2) << 5) /* DQ6 = toggle bit (2 us) */
188 | (1 << 5) /* DQ5 = timeout */
189 ;
190 }
191
flash_erase_operation_status(flash040_context_t * flash040_context)192 inline static int flash_erase_operation_status(flash040_context_t *flash040_context)
193 {
194 int v;
195
196 /* DQ6 = toggle bit */
197 v = flash040_context->program_byte;
198
199 /* toggle the toggle bit(s) */
200 /* FIXME better toggle bit II emulation */
201 flash040_context->program_byte ^= flash_types[flash040_context->flash_type].status_toggle_bits;
202
203 /* DQ3 = sector erase timer */
204 if (flash040_context->flash_state != FLASH040_STATE_SECTOR_ERASE_TIMEOUT) {
205 v |= 0x08;
206 }
207
208 return v;
209 }
210
211 /* -------------------------------------------------------------------------- */
212
erase_alarm_handler(CLOCK offset,void * data)213 static void erase_alarm_handler(CLOCK offset, void *data)
214 {
215 unsigned int i, j;
216 uint8_t m;
217 flash040_context_t *flash040_context = (flash040_context_t *)data;
218
219 alarm_unset(flash040_context->erase_alarm);
220
221 FLASH_DEBUG(("Erase alarm, state %i", (int)flash040_context->flash_state));
222
223 switch (flash040_context->flash_state) {
224 case FLASH040_STATE_SECTOR_ERASE_TIMEOUT:
225 alarm_set(flash040_context->erase_alarm, maincpu_clk + flash_types[flash040_context->flash_type].erase_sector_cycles);
226 flash040_context->flash_state = FLASH040_STATE_SECTOR_ERASE;
227 break;
228 case FLASH040_STATE_SECTOR_ERASE:
229 for (i = 0; i < (8 * FLASH040_ERASE_MASK_SIZE); ++i) {
230 j = i >> 3;
231 m = (uint8_t)(1 << (i & 0x7));
232 if (flash040_context->erase_mask[j] & m) {
233 flash_erase_sector(flash040_context, i);
234 flash040_context->erase_mask[j] &= (uint8_t) ~m;
235 break;
236 }
237 }
238
239 for (i = 0, m = 0; i < FLASH040_ERASE_MASK_SIZE; ++i) {
240 m |= flash040_context->erase_mask[i];
241 }
242
243 if (m != 0) {
244 alarm_set(flash040_context->erase_alarm, maincpu_clk + flash_types[flash040_context->flash_type].erase_sector_cycles);
245 } else {
246 flash040_context->flash_state = flash040_context->flash_base_state;
247 }
248 break;
249
250 case FLASH040_STATE_CHIP_ERASE:
251 flash_erase_chip(flash040_context);
252 flash040_context->flash_state = flash040_context->flash_base_state;
253 break;
254
255 default:
256 FLASH_DEBUG(("Erase alarm - error, state %i unhandled!", (int)flash040_context->flash_state));
257 break;
258 }
259 }
260
261 /* -------------------------------------------------------------------------- */
262
flash040core_store_internal(flash040_context_t * flash040_context,unsigned int addr,uint8_t byte)263 static void flash040core_store_internal(flash040_context_t *flash040_context,
264 unsigned int addr, uint8_t byte)
265 {
266 #ifdef FLASH_DEBUG_ENABLED
267 flash040_state_t old_state = flash040_context->flash_state;
268 flash040_state_t old_base_state = flash040_context->flash_base_state;
269 #endif
270
271 switch (flash040_context->flash_state) {
272 case FLASH040_STATE_READ:
273 if (flash_magic_1(flash040_context, addr) && (byte == 0xaa)) {
274 flash040_context->flash_state = FLASH040_STATE_MAGIC_1;
275 }
276 break;
277
278 case FLASH040_STATE_MAGIC_1:
279 if (flash_magic_2(flash040_context, addr) && (byte == 0x55)) {
280 flash040_context->flash_state = FLASH040_STATE_MAGIC_2;
281 } else {
282 flash040_context->flash_state = flash040_context->flash_base_state;
283 }
284 break;
285
286 case FLASH040_STATE_MAGIC_2:
287 if (flash_magic_1(flash040_context, addr)) {
288 switch (byte) {
289 case 0x90:
290 flash040_context->flash_state = FLASH040_STATE_AUTOSELECT;
291 flash040_context->flash_base_state = FLASH040_STATE_AUTOSELECT;
292 break;
293 case 0xf0:
294 flash040_context->flash_state = FLASH040_STATE_READ;
295 flash040_context->flash_base_state = FLASH040_STATE_READ;
296 break;
297 case 0xa0:
298 flash040_context->flash_state = FLASH040_STATE_BYTE_PROGRAM;
299 break;
300 case 0x80:
301 flash040_context->flash_state = FLASH040_STATE_ERASE_MAGIC_1;
302 break;
303 default:
304 flash040_context->flash_state = flash040_context->flash_base_state;
305 break;
306 }
307 } else {
308 flash040_context->flash_state = flash040_context->flash_base_state;
309 }
310 break;
311
312 case FLASH040_STATE_BYTE_PROGRAM:
313 if (flash_program_byte(flash040_context, addr, byte)) {
314 /* The byte program time is short enough to ignore */
315 flash040_context->flash_state = flash040_context->flash_base_state;
316 } else {
317 flash040_context->flash_state = FLASH040_STATE_BYTE_PROGRAM_ERROR;
318 }
319 break;
320
321 case FLASH040_STATE_ERASE_MAGIC_1:
322 if (flash_magic_1(flash040_context, addr) && (byte == 0xaa)) {
323 flash040_context->flash_state = FLASH040_STATE_ERASE_MAGIC_2;
324 } else {
325 flash040_context->flash_state = flash040_context->flash_base_state;
326 }
327 break;
328
329 case FLASH040_STATE_ERASE_MAGIC_2:
330 if (flash_magic_2(flash040_context, addr) && (byte == 0x55)) {
331 flash040_context->flash_state = FLASH040_STATE_ERASE_SELECT;
332 } else {
333 flash040_context->flash_state = flash040_context->flash_base_state;
334 }
335 break;
336
337 case FLASH040_STATE_ERASE_SELECT:
338 if (flash_magic_1(flash040_context, addr) && (byte == 0x10)) {
339 flash040_context->flash_state = FLASH040_STATE_CHIP_ERASE;
340 flash040_context->program_byte = 0;
341 alarm_set(flash040_context->erase_alarm, maincpu_clk + flash_types[flash040_context->flash_type].erase_chip_cycles);
342 } else if (byte == 0x30) {
343 flash_add_sector_to_erase_mask(flash040_context, addr);
344 flash040_context->program_byte = 0;
345 flash040_context->flash_state = FLASH040_STATE_SECTOR_ERASE_TIMEOUT;
346 alarm_set(flash040_context->erase_alarm, maincpu_clk + flash_types[flash040_context->flash_type].erase_sector_timeout_cycles);
347 } else {
348 flash040_context->flash_state = flash040_context->flash_base_state;
349 }
350 break;
351
352 case FLASH040_STATE_SECTOR_ERASE_TIMEOUT:
353 if (byte == 0x30) {
354 flash_add_sector_to_erase_mask(flash040_context, addr);
355 } else {
356 flash040_context->flash_state = flash040_context->flash_base_state;
357 flash_clear_erase_mask(flash040_context);
358 alarm_unset(flash040_context->erase_alarm);
359 }
360 break;
361
362 case FLASH040_STATE_SECTOR_ERASE:
363 /* TODO not all models support suspending */
364 if (byte == 0xb0) {
365 flash040_context->flash_state = FLASH040_STATE_SECTOR_ERASE_SUSPEND;
366 alarm_unset(flash040_context->erase_alarm);
367 }
368 break;
369
370 case FLASH040_STATE_SECTOR_ERASE_SUSPEND:
371 if (byte == 0x30) {
372 flash040_context->flash_state = FLASH040_STATE_SECTOR_ERASE;
373 alarm_set(flash040_context->erase_alarm, maincpu_clk + flash_types[flash040_context->flash_type].erase_sector_cycles);
374 }
375 break;
376
377 case FLASH040_STATE_BYTE_PROGRAM_ERROR:
378 case FLASH040_STATE_AUTOSELECT:
379 if (flash_magic_1(flash040_context, addr) && (byte == 0xaa)) {
380 flash040_context->flash_state = FLASH040_STATE_MAGIC_1;
381 }
382 if (byte == 0xf0) {
383 flash040_context->flash_state = FLASH040_STATE_READ;
384 flash040_context->flash_base_state = FLASH040_STATE_READ;
385 }
386 break;
387
388 case FLASH040_STATE_CHIP_ERASE:
389 default:
390 break;
391 }
392
393 FLASH_DEBUG(("Write %02x to %05x, state %i->%i (base state %i->%i)", byte, addr, (int)old_state, (int)flash040_context->flash_state, (int)old_base_state, (int)flash040_context->flash_base_state));
394 }
395
396 /* -------------------------------------------------------------------------- */
397
flash040core_store(flash040_context_t * flash040_context,unsigned int addr,uint8_t byte)398 void flash040core_store(flash040_context_t *flash040_context, unsigned int addr, uint8_t byte)
399 {
400 if (maincpu_rmw_flag) {
401 maincpu_clk--;
402 flash040core_store_internal(flash040_context, addr, flash040_context->last_read);
403 maincpu_clk++;
404 }
405
406 flash040core_store_internal(flash040_context, addr, byte);
407 }
408
flash040core_read(flash040_context_t * flash040_context,unsigned int addr)409 uint8_t flash040core_read(flash040_context_t *flash040_context, unsigned int addr)
410 {
411 uint8_t value;
412 #ifdef FLASH_DEBUG_ENABLED
413 flash040_state_t old_state = flash040_context->flash_state;
414 #endif
415
416 switch (flash040_context->flash_state) {
417 case FLASH040_STATE_AUTOSELECT:
418 if (flash040_context->flash_type == FLASH040_TYPE_032B_A0_1_SWAP) {
419 if ((addr & 0xff) < 4) {
420 addr = "\0\2\1\3"[addr & 0x3];
421 }
422 }
423
424 if ((addr & 0xff) == 0) {
425 value = flash_types[flash040_context->flash_type].manufacturer_ID;
426 } else if ((addr & 0xff) == flash_types[flash040_context->flash_type].device_ID_addr) {
427 value = flash_types[flash040_context->flash_type].device_ID;
428 } else if ((addr & 0xff) == 2) {
429 value = 0;
430 } else {
431 value = flash040_context->flash_data[addr];
432 }
433 break;
434
435 case FLASH040_STATE_BYTE_PROGRAM_ERROR:
436 value = flash_write_operation_status(flash040_context);
437 break;
438
439 case FLASH040_STATE_SECTOR_ERASE_SUSPEND:
440 case FLASH040_STATE_CHIP_ERASE:
441 case FLASH040_STATE_SECTOR_ERASE:
442 case FLASH040_STATE_SECTOR_ERASE_TIMEOUT:
443 value = flash_erase_operation_status(flash040_context);
444 break;
445
446 default:
447 /* The state doesn't reset if a read occurs during a command sequence */
448 /* fall through */
449 case FLASH040_STATE_READ:
450 value = flash040_context->flash_data[addr];
451 break;
452 }
453
454 #ifdef FLASH_DEBUG_ENABLED
455 if (old_state != FLASH040_STATE_READ) {
456 FLASH_DEBUG(("Read %02x from %05x, state %i->%i", value, addr, (int)old_state, (int)flash040_context->flash_state));
457 }
458 #endif
459
460 flash040_context->last_read = value;
461 return value;
462 }
463
flash040core_peek(flash040_context_t * flash040_context,unsigned int addr)464 uint8_t flash040core_peek(flash040_context_t *flash040_context, unsigned int addr)
465 {
466 return flash040_context->flash_data[addr];
467 }
468
flash040core_reset(flash040_context_t * flash040_context)469 void flash040core_reset(flash040_context_t *flash040_context)
470 {
471 FLASH_DEBUG(("Reset"));
472 flash040_context->flash_state = FLASH040_STATE_READ;
473 flash040_context->flash_base_state = FLASH040_STATE_READ;
474 flash040_context->program_byte = 0;
475 flash_clear_erase_mask(flash040_context);
476 alarm_unset(flash040_context->erase_alarm);
477 }
478
flash040core_init(struct flash040_context_s * flash040_context,struct alarm_context_s * alarm_context,flash040_type_t type,uint8_t * data)479 void flash040core_init(struct flash040_context_s *flash040_context,
480 struct alarm_context_s *alarm_context,
481 flash040_type_t type, uint8_t *data)
482 {
483 FLASH_DEBUG(("Init"));
484 flash040_context->flash_data = data;
485 flash040_context->flash_type = type;
486 flash040_context->flash_state = FLASH040_STATE_READ;
487 flash040_context->flash_base_state = FLASH040_STATE_READ;
488 flash040_context->program_byte = 0;
489 flash_clear_erase_mask(flash040_context);
490 flash040_context->flash_dirty = 0;
491 flash040_context->erase_alarm = alarm_new(alarm_context, "Flash040Alarm", erase_alarm_handler, flash040_context);
492 }
493
flash040core_shutdown(flash040_context_t * flash040_context)494 void flash040core_shutdown(flash040_context_t *flash040_context)
495 {
496 FLASH_DEBUG(("Shutdown"));
497 }
498
499 /* -------------------------------------------------------------------------- */
500
501 #define FLASH040_DUMP_VER_MAJOR 2
502 #define FLASH040_DUMP_VER_MINOR 0
503
flash040core_snapshot_write_module(snapshot_t * s,flash040_context_t * flash040_context,const char * name)504 int flash040core_snapshot_write_module(snapshot_t *s, flash040_context_t *flash040_context, const char *name)
505 {
506 snapshot_module_t *m;
507 uint8_t state, base_state;
508
509 m = snapshot_module_create(s, name, FLASH040_DUMP_VER_MAJOR, FLASH040_DUMP_VER_MINOR);
510 if (m == NULL) {
511 return -1;
512 }
513
514 state = (uint8_t)(flash040_context->flash_state);
515 base_state = (uint8_t)(flash040_context->flash_base_state);
516
517 if (0
518 || (SMW_B(m, state) < 0)
519 || (SMW_B(m, base_state) < 0)
520 || (SMW_B(m, flash040_context->program_byte) < 0)
521 || (SMW_BA(m, flash040_context->erase_mask, FLASH040_ERASE_MASK_SIZE) < 0)
522 || (SMW_B(m, flash040_context->last_read) < 0)) {
523 snapshot_module_close(m);
524 return -1;
525 }
526
527 snapshot_module_close(m);
528 return 0;
529 }
530
flash040core_snapshot_read_module(snapshot_t * s,flash040_context_t * flash040_context,const char * name)531 int flash040core_snapshot_read_module(snapshot_t *s, flash040_context_t *flash040_context, const char *name)
532 {
533 uint8_t vmajor, vminor, state, base_state;
534 snapshot_module_t *m;
535
536 m = snapshot_module_open(s, name, &vmajor, &vminor);
537 if (m == NULL) {
538 return -1;
539 }
540
541 if (vmajor != FLASH040_DUMP_VER_MAJOR) {
542 snapshot_module_close(m);
543 return -1;
544 }
545
546 if (0
547 || (SMR_B(m, &state) < 0)
548 || (SMR_B(m, &base_state) < 0)
549 || (SMR_B(m, &(flash040_context->program_byte)) < 0)
550 || (SMR_BA(m, flash040_context->erase_mask, FLASH040_ERASE_MASK_SIZE) < 0)
551 || (SMR_B(m, &(flash040_context->last_read)) < 0)) {
552 snapshot_module_close(m);
553 return -1;
554 }
555
556 snapshot_module_close(m);
557
558 flash040_context->flash_state = (flash040_state_t)state;
559 flash040_context->flash_base_state = (flash040_state_t)base_state;
560
561 /* Restore alarm if needed */
562 switch (flash040_context->flash_state) {
563 case FLASH040_STATE_SECTOR_ERASE_TIMEOUT:
564 case FLASH040_STATE_SECTOR_ERASE:
565 case FLASH040_STATE_CHIP_ERASE:
566 /* the alarm timing is not saved, just use some value for now */
567 alarm_set(flash040_context->erase_alarm, maincpu_clk + flash_types[flash040_context->flash_type].erase_sector_cycles);
568 break;
569
570 default:
571 break;
572 }
573
574 return 0;
575 }
576