#include #include "ibm.h" #include "device.h" #include "mem.h" enum { CMD_READ_ARRAY = 0xff, CMD_IID = 0x90, CMD_READ_STATUS = 0x70, CMD_CLEAR_STATUS = 0x50, CMD_ERASE_SETUP = 0x20, CMD_ERASE_CONFIRM = 0xd0, CMD_ERASE_SUSPEND = 0xb0, CMD_PROGRAM_SETUP = 0x40 }; typedef struct flash_t { uint8_t command, status; mem_mapping_t read_mapping, write_mapping; } flash_t; static flash_t flash; static uint8_t flash_read(uint32_t addr, void *p) { flash_t *flash = (flash_t *)p; // pclog("flash_read : addr=%08x command=%02x %04x:%08x\n", addr, flash->command, CS, pc); switch (flash->command) { case CMD_IID: if (addr & 1) return 0x94; return 0x89; default: return flash->status; } } static void flash_write(uint32_t addr, uint8_t val, void *p) { flash_t *flash = (flash_t *)p; // pclog("flash_write : addr=%08x val=%02x command=%02x %04x:%08x\n", addr, val, flash->command, CS, pc); switch (flash->command) { case CMD_ERASE_SETUP: if (val == CMD_ERASE_CONFIRM) { // pclog("flash_write: erase %05x\n", addr & 0x1ffff); if ((addr & 0x1f000) == 0x0d000) memset(&rom[0x0d000], 0xff, 0x1000); if ((addr & 0x1f000) == 0x0c000) memset(&rom[0x0c000], 0xff, 0x1000); if ((addr & 0x1f000) < 0x0c000 || (addr & 0x1f000) >= 0x10000) { memset(rom, 0xff, 0xc000); memset(&rom[0x10000], 0xff, 0x10000); } flash->status = 0x80; } flash->command = CMD_READ_STATUS; break; case CMD_PROGRAM_SETUP: // pclog("flash_write: program %05x %02x\n", addr & 0x1ffff, val); if ((addr & 0x1e000) != 0x0e000) rom[addr & 0x1ffff] = val; flash->command = CMD_READ_STATUS; flash->status = 0x80; break; default: flash->command = val; switch (val) { case CMD_CLEAR_STATUS: flash->status = 0; break; case CMD_IID: case CMD_READ_STATUS: mem_mapping_disable(&bios_mapping[0]); mem_mapping_disable(&bios_mapping[1]); mem_mapping_disable(&bios_mapping[2]); mem_mapping_disable(&bios_mapping[3]); mem_mapping_disable(&bios_mapping[4]); mem_mapping_disable(&bios_mapping[5]); mem_mapping_disable(&bios_mapping[6]); mem_mapping_disable(&bios_mapping[7]); mem_mapping_enable(&flash->read_mapping); break; case CMD_READ_ARRAY: mem_mapping_enable(&bios_mapping[0]); mem_mapping_enable(&bios_mapping[1]); mem_mapping_enable(&bios_mapping[2]); mem_mapping_enable(&bios_mapping[3]); mem_mapping_enable(&bios_mapping[4]); mem_mapping_enable(&bios_mapping[5]); mem_mapping_enable(&bios_mapping[6]); mem_mapping_enable(&bios_mapping[7]); mem_mapping_disable(&flash->read_mapping); break; } } } void *intel_flash_init() { FILE *f; flash_t *flash = malloc(sizeof(flash_t)); memset(flash, 0, sizeof(flash_t)); mem_mapping_add(&flash->read_mapping, 0xe0000, 0x20000, flash_read, NULL, NULL, NULL, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, (void *)flash); mem_mapping_add(&flash->write_mapping, 0xe0000, 0x20000, NULL, NULL, NULL, flash_write, NULL, NULL, NULL, MEM_MAPPING_EXTERNAL, (void *)flash); mem_mapping_disable(&flash->read_mapping); flash->command = CMD_READ_ARRAY; flash->status = 0; memset(&rom[0xc000], 0, 0x2000); f = romfopen("roms/endeavor/oemlogo.bin", "rb"); if (f) { fread(&rom[0xc000], 0x1000, 1, f); fclose(f); } f = romfopen("roms/endeavor/ecsd.bin", "rb"); if (f) { fread(&rom[0xd000], 0x1000, 1, f); fclose(f); } return flash; } void intel_flash_close(void *p) { FILE *f; flash_t *flash = (flash_t *)p; f = romfopen("roms/endeavor/oemlogo.bin", "wb"); fwrite(&rom[0xc000], 0x1000, 1, f); fclose(f); f = romfopen("roms/endeavor/ecsd.bin", "wb"); fwrite(&rom[0xd000], 0x1000, 1, f); fclose(f); free(flash); } device_t intel_flash_device = { "Intel 28F001BXT Flash BIOS", 0, intel_flash_init, intel_flash_close, NULL, NULL, NULL, NULL, NULL };