static void start_programming_byte(device *me, hw_eeprom_device *eeprom, unsigned_word address, unsigned8 new_byte) { unsigned8 old_byte = eeprom->memory[address]; DTRACE(eeprom, ("start-programing-byte - address 0x%lx, new 0x%lx, old 0x%lx\n", (unsigned long)address, (unsigned long)new_byte, (unsigned long)old_byte)); eeprom->byte_program_address = address; /* : old new : ~old : new&~old : 0 0 : 1 : 0 : 0 1 : 1 : 1 -- can not set a bit : 1 0 : 0 : 0 : 1 1 : 0 : 0 */ if (~old_byte & new_byte) invalid_write(me, eeprom->state, address, new_byte, "setting cleared bit"); /* : old new : old&new : 0 0 : 0 : 0 1 : 0 : 1 0 : 0 : 1 1 : 1 */ eeprom->byte_program_byte = new_byte & old_byte; eeprom->memory[address] = ~new_byte & ~0x24; /* LE-bits 5:3 zero */ eeprom->program_start_time = device_event_queue_time(me); eeprom->program_finish_time = (eeprom->program_start_time + eeprom->byte_write_delay); }
static void sh7750_mmct_write(void *opaque, target_phys_addr_t addr, uint64_t mem_value, unsigned size) { SH7750State *s = opaque; if (size != 4) { invalid_write(opaque, addr, mem_value); } switch (MM_REGION_TYPE(addr)) { case MM_ICACHE_ADDR: case MM_ICACHE_DATA: /* do nothing */ break; case MM_ITLB_ADDR: cpu_sh4_write_mmaped_itlb_addr(s->cpu, addr, mem_value); break; case MM_ITLB_DATA: cpu_sh4_write_mmaped_itlb_data(s->cpu, addr, mem_value); abort(); break; case MM_OCACHE_ADDR: case MM_OCACHE_DATA: /* do nothing */ break; case MM_UTLB_ADDR: cpu_sh4_write_mmaped_utlb_addr(s->cpu, addr, mem_value); break; case MM_UTLB_DATA: cpu_sh4_write_mmaped_utlb_data(s->cpu, addr, mem_value); break; default: abort(); break; } }
static void write_byte(device *me, hw_eeprom_device *eeprom, unsigned_word address, unsigned8 data) { /* may need multiple transitions to process a write */ while (1) { switch (eeprom->state) { case read_reset: if (address == 0x5555 && data == 0xaa) eeprom->state = write_nr_2; else if (data == 0xf0) eeprom->state = read_reset; else { invalid_write(me, eeprom->state, address, data, "unexpected"); eeprom->state = read_reset; } return; case write_nr_2: if (address == 0x2aaa && data == 0x55) eeprom->state = write_nr_3; else { invalid_write(me, eeprom->state, address, data, "unexpected"); eeprom->state = read_reset; } return; case write_nr_3: if (address == 0x5555 && data == 0xf0) eeprom->state = read_reset; else if (address == 0x5555 && data == 0x90) eeprom->state = autoselect; else if (address == 0x5555 && data == 0xa0) { eeprom->state = byte_program; } else if (address == 0x5555 && data == 0x80) eeprom->state = write_nr_4; else { invalid_write(me, eeprom->state, address, data, "unexpected"); eeprom->state = read_reset; } return; case write_nr_4: if (address == 0x5555 && data == 0xaa) eeprom->state = write_nr_5; else { invalid_write(me, eeprom->state, address, data, "unexpected"); eeprom->state = read_reset; } return; case write_nr_5: if (address == 0x2aaa && data == 0x55) eeprom->state = write_nr_6; else { invalid_write(me, eeprom->state, address, data, "unexpected"); eeprom->state = read_reset; } return; case write_nr_6: if (address == 0x5555 && data == 0x10) { start_erasing_chip(me, eeprom); eeprom->state = chip_erase; } else { start_erasing_sector(me, eeprom, address); eeprom->sector_state = read_reset; eeprom->state = sector_erase; } return; case autoselect: if (data == 0xf0) eeprom->state = read_reset; else if (address == 0x5555 && data == 0xaa) eeprom->state = write_nr_2; else { invalid_write(me, eeprom->state, address, data, "unsupported address"); eeprom->state = read_reset; } return; case byte_program: start_programming_byte(me, eeprom, address, data); eeprom->state = byte_programming; return; case byte_programming: if (device_event_queue_time(me) > eeprom->program_finish_time) { finish_programming_byte(me, eeprom); eeprom->state = read_reset; continue; } /* ignore it */ return; case chip_erase: if (device_event_queue_time(me) > eeprom->program_finish_time) { finish_erasing_chip(me, eeprom); eeprom->state = read_reset; continue; } /* ignore it */ return; case sector_erase: if (device_event_queue_time(me) > eeprom->program_finish_time) { finish_erasing_sector(me, eeprom); eeprom->state = eeprom->sector_state; continue; } else if (device_event_queue_time(me) > eeprom->sector_start_time && data == 0xb0) { eeprom->sector_state = read_reset; eeprom->state = sector_erase_suspend; } else { if (eeprom->sector_state == read_reset && address == 0x5555 && data == 0xaa) eeprom->sector_state = write_nr_2; else if (eeprom->sector_state == write_nr_2 && address == 0x2aaa && data == 0x55) eeprom->sector_state = write_nr_3; else if (eeprom->sector_state == write_nr_3 && address == 0x5555 && data == 0x80) eeprom->sector_state = write_nr_4; else if (eeprom->sector_state == write_nr_4 && address == 0x5555 && data == 0xaa) eeprom->sector_state = write_nr_5; else if (eeprom->sector_state == write_nr_5 && address == 0x2aaa && data == 0x55) eeprom->sector_state = write_nr_6; else if (eeprom->sector_state == write_nr_6 && address != 0x5555 && data == 0x30) { if (device_event_queue_time(me) > eeprom->sector_start_time) { DTRACE(eeprom, ("sector erase command after window closed\n")); eeprom->sector_state = read_reset; } else { start_erasing_sector(me, eeprom, address); eeprom->sector_state = read_reset; } } else { invalid_write(me, eeprom->state, address, data, state2a(eeprom->sector_state)); eeprom->state = read_reset; } } return; case sector_erase_suspend: if (data == 0x30) eeprom->state = sector_erase; else { invalid_write(me, eeprom->state, address, data, "not resume command"); eeprom->state = read_reset; } return; } } }