From: Toni Wilen Date: Sat, 4 Nov 2023 13:53:53 +0000 (+0200) Subject: Flash/EEPROM support updates. X-Git-Tag: 5.1.0~66 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=5af528df3188d3ecd6fd0b0c1ca77b8f440f4b87;p=francis%2Fwinuae.git Flash/EEPROM support updates. --- diff --git a/ar.cpp b/ar.cpp index b867fe7b..6affae9c 100644 --- a/ar.cpp +++ b/ar.cpp @@ -1659,7 +1659,7 @@ int action_replay_load (void) if (rd->type & ROMTYPE_CD32CART) return 0; } - f = read_rom_name (currprefs.cartfile); + f = read_rom_name(currprefs.cartfile, false); if (!f) { write_log (_T("failed to load '%s' cartridge ROM\n"), currprefs.cartfile); return 0; @@ -1812,7 +1812,7 @@ int hrtmon_load (void) if (!isinternal) { if (currprefs.cartfile[0] == '\0') return 0; - f = read_rom_name (currprefs.cartfile); + f = read_rom_name(currprefs.cartfile, false); if(!f) { write_log (_T("failed to load '%s' cartridge ROM\n"), currprefs.cartfile); return 0; diff --git a/cpuboard.cpp b/cpuboard.cpp index f1e6fabc..a73baa64 100644 --- a/cpuboard.cpp +++ b/cpuboard.cpp @@ -662,6 +662,7 @@ static uae_u32 REGPARAM2 blizzardf0_bget(uaecptr addr) blizzardf0_slow(1); + addr &= blizzardf0_bank.mask; if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) { if (flash_unlocked) { return flash_read(flashrom, addr); @@ -678,7 +679,6 @@ static uae_u32 REGPARAM2 blizzardf0_bget(uaecptr addr) return flash_read(flashrom, addr); } } - addr &= blizzardf0_bank.mask; v = blizzardf0_bank.baseaddr[addr]; return v; } @@ -714,12 +714,12 @@ static void REGPARAM2 blizzardf0_bput(uaecptr addr, uae_u32 b) { blizzardf0_slow(1); + addr &= blizzardf0_bank.mask; if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) { if (flash_unlocked) { flash_write(flashrom, addr, b); } } else if (is_csmk2(&currprefs)) { - addr &= 65535; addr += 65536; addr &= ~3; addr |= csmk2_flashaddressing; @@ -854,6 +854,7 @@ static void REGPARAM2 blizzardea_bput(uaecptr addr, uae_u32 b) if (addr >= CYBERSTORM_MK2_SCSI_OFFSET) { cpuboard_ncr9x_scsi_put(addr, b); } else { + addr &= 65535; addr &= ~3; addr |= csmk2_flashaddressing; flash_write(flashrom, addr, b); diff --git a/flashrom.cpp b/flashrom.cpp index 298df379..220e8ecb 100644 --- a/flashrom.cpp +++ b/flashrom.cpp @@ -246,14 +246,16 @@ void *eeprom93xx_new(const uae_u8 *memory, int nwords, struct zfile *zf) } eeprom = (eeprom93xx_eeprom_t *)xcalloc(eeprom93xx_eeprom_t, 1); - eeprom->size = nwords; - eeprom->addrbits = addrbits; - for (int i = 0; i < nwords; i++) { - eeprom->contents[i] = (memory[i * 2 + 0] << 8) | memory[i * 2 + 1]; - } - /* Output DO is tristate, read results in 1. */ - eeprom->eedo = 1; -// write_log("eeprom = 0x%p, nwords = %u\n", eeprom, nwords); + if (eeprom) { + eeprom->size = nwords; + eeprom->addrbits = addrbits; + for (int i = 0; i < nwords; i++) { + eeprom->contents[i] = (memory[i * 2 + 0] << 8) | memory[i * 2 + 1]; + } + /* Output DO is tristate, read results in 1. */ + eeprom->eedo = 1; + // write_log("eeprom = 0x%p, nwords = %u\n", eeprom, nwords); + } return eeprom; } @@ -542,16 +544,16 @@ void *eeprom_new(uae_u8 *memory, int size, struct zfile *zf) bitbang_i2c_interface *s; s = xcalloc(bitbang_i2c_interface, 1); - - eeprom_reset(s); - - s->memory = memory; - s->size = size; - s->zf = zf; - s->addressbitmask = (size / 256) - 1; - s->device_address = 0xa0; - s->device_address_mask = 0xf0; - + if (s) { + eeprom_reset(s); + + s->memory = memory; + s->size = size; + s->zf = zf; + s->addressbitmask = (size / 256) - 1; + s->device_address = 0xa0; + s->device_address_mask = 0xf0; + } return s; } @@ -560,18 +562,19 @@ void *i2c_new(uae_u8 device_address, int size, uae_u8 (*read_func)(uae_u8 addr), bitbang_i2c_interface *s; s = xcalloc(bitbang_i2c_interface, 1); - - eeprom_reset(s); - - s->memory = NULL; - s->size = size; - s->zf = NULL; - s->addressbitmask = 0; - s->device_address = 0xa2; - s->device_address_mask = 0xff; - - s->read_func = read_func; - s->write_func = write_func; + if (s) { + eeprom_reset(s); + + s->memory = NULL; + s->size = size; + s->zf = NULL; + s->addressbitmask = 0; + s->device_address = 0xa2; + s->device_address_mask = 0xff; + + s->read_func = read_func; + s->write_func = write_func; + } return s; } @@ -603,10 +606,16 @@ struct flashrom_data int state; int modified; int sectorsize; + int pagesize; uae_u8 devicecode, mfgcode; int flags; + int writeprot; + int lastpagewrite; int firstwriteoffset; int lastwriteoffset; + uae_u8 page[128]; + bool mpage[128]; + bool pagemodified; struct zfile *zf; }; @@ -624,17 +633,22 @@ static void setmodified(struct flashrom_data *fd, int offset) void *flash_new(uae_u8 *rom, int flashsize, int allocsize, uae_u8 mfgcode, uae_u8 devcode, struct zfile *zf, int flags) { struct flashrom_data *fd = xcalloc(struct flashrom_data, 1); - fd->flashsize = flashsize; - fd->allocsize = allocsize; - fd->mask = fd->flashsize - 1; - fd->zf = zf; - fd->rom = rom; - fd->flags = flags; - fd->devicecode = devcode; - fd->mfgcode = mfgcode; - fd->sectorsize = devcode == 0x20 ? 16384 : 65536; - fd->lastwriteoffset = 0; - fd->firstwriteoffset = allocsize; + if (fd) { + fd->flashsize = flashsize; + fd->allocsize = allocsize; + fd->mask = fd->flashsize - 1; + fd->zf = zf; + fd->rom = rom; + fd->flags = flags; + fd->devicecode = devcode; + fd->pagesize = mfgcode == 0xbf ? 128 : 64; + fd->mfgcode = mfgcode; + fd->sectorsize = devcode == 0x20 ? 16384 : 65536; + fd->lastwriteoffset = 0; + fd->firstwriteoffset = allocsize; + fd->writeprot = (flags & FLASHROM_DATA_PROTECT) ? 1 : 0; + fd->lastpagewrite = -1; + } return fd; } @@ -646,13 +660,36 @@ void flash_free(void *fdv) if (fd->zf && fd->modified) { if (fd->flags & FLASHROM_EVERY_OTHER_BYTE) { zfile_fseek(fd->zf, (fd->flags & FLASHROM_EVERY_OTHER_BYTE_ODD) ? 1 : 0, SEEK_SET); - for (int i = 0; i < fd->allocsize; i++) { + int last = fd->lastwriteoffset + 1; + last += 511; + last &= ~511; + if (last > fd->allocsize) { + last = fd->allocsize; + } + for (int i = 0; i < last; i++) { zfile_fwrite(&fd->rom[i * 2], 1, 1, fd->zf); zfile_fseek(fd->zf, 1, SEEK_CUR); } + } else if (fd->flags & FLASHROM_SKIP_EVERY_OTHER_BYTE) { + zfile_fseek(fd->zf, 0, SEEK_SET); + int last = fd->lastwriteoffset + 1; + last += 511; + last &= ~511; + if (last > fd->allocsize) { + last = fd->allocsize; + } + for (int i = 0; i < last / 2; i++) { + zfile_fwrite(&fd->rom[i * 2], 1, 1, fd->zf); + } } else { - zfile_fseek(fd->zf, fd->firstwriteoffset, SEEK_SET); - zfile_fwrite(fd->rom + fd->firstwriteoffset, fd->lastwriteoffset - fd->firstwriteoffset + 1, 1, fd->zf); + uae_s32 msize = zfile_ftell32(fd->zf); + if (msize > fd->lastwriteoffset) { + zfile_fseek(fd->zf, fd->firstwriteoffset, SEEK_SET); + zfile_fwrite(fd->rom + fd->firstwriteoffset, fd->lastwriteoffset - fd->firstwriteoffset + 1, 1, fd->zf); + } else { + zfile_fseek(fd->zf, 0, SEEK_SET); + zfile_fwrite(fd->rom, fd->lastwriteoffset + 1, 1, fd->zf); + } } } xfree(fdv); @@ -674,76 +711,126 @@ bool flash_active(void *fdv, uaecptr addr) return fd->state != 0; } +static void writeflash(struct flashrom_data *fd, int addr, uae_u8 v) +{ + if (!(fd->flags & FLASHROM_PARALLEL_EEPROM)) { + fd->state = 100; + if (fd->writeprot <= 0) { + if (fd->rom[addr] != v) { + fd->rom[addr] = v; + fd->modified = 1; + } + if (fd->modified) { + setmodified(fd, addr); + } + gui_flicker_led(LED_MD, 0, 2); + } + } else { + int page = addr & ~(fd->pagesize - 1); + int mpage = addr & (fd->pagesize - 1); + if (fd->lastpagewrite != page) { + memset(fd->mpage, 0, sizeof(fd->mpage)); + fd->pagemodified = false; + fd->lastpagewrite = page; + } + if (fd->writeprot <= 0) { + fd->page[mpage] = v; + fd->mpage[mpage] = true; + fd->pagemodified = true; + gui_flicker_led(LED_MD, 0, 2); + } + fd->state = 7 + 1; + } +} + bool flash_write(void *fdv, uaecptr addr, uae_u8 v) { struct flashrom_data *fd = (struct flashrom_data*)fdv; - int oldstate; - uae_u32 addr2; int other_byte_mult = 1; if (!fd) return false; - if (fd->flags & FLASHROM_EVERY_OTHER_BYTE) { + if (fd->flags & (FLASHROM_SKIP_EVERY_OTHER_BYTE | FLASHROM_EVERY_OTHER_BYTE)) { addr >>= 1; other_byte_mult = 2; } - oldstate = fd->state; + if (addr * other_byte_mult >= fd->allocsize) { + return false; + } + + int oldstate = fd->state; + bool det = false; #if FLASH_LOG > 1 write_log(_T("flash write %08x %02x (%d) PC=%08x\n"), addr, v, fd->state, m68k_getpc()); #endif addr &= fd->mask; - addr2 = addr & 0xffff; - if (fd->state >= 7 && fd->state < 7 + 64) { - if (!(fd->flags & FLASHROM_PARALLEL_EEPROM)) { - fd->state = 100; - } else { - fd->state++; - if (fd->state >= 7 + 64) - fd->state = 100; - } - if (addr >= fd->allocsize) - return false; + if (fd->state == 7 || fd->state == 8) { int a = addr * other_byte_mult; - if (fd->rom[a] != v) { - fd->rom[a] = v; - setmodified(fd, a); - } - gui_flicker_led (LED_MD, 0, 2); + writeflash(fd, a, v); return true; } - if (v == 0xf0) { + if (v == 0xf0 && fd->state > 0 && fd->state < 7) { fd->state = 0; return false; } // unlock - if (addr2 == 0x5555 && fd->state <= 2 && v == 0xaa) + if (addr == 0x5555 && fd->state <= 2 && v == 0xaa) { fd->state = 1; - if (addr2 == 0x2aaa && fd->state == 1 && v == 0x55) + det = true; + } + if (addr == 0x2aaa && fd->state == 1 && v == 0x55) { fd->state = 2; + det = true; + } + + // software id exit and reset first byte + if (addr == 0x5555 && fd->state == 3 && v == 0xaa) { + fd->state = 1; + det = true; + } // autoselect - if (addr2 == 0x5555 && fd->state == 2 && v == 0x90) + if (addr == 0x5555 && fd->state == 2 && v == 0x90) { fd->state = 3; + det = true; + } - // program - if (addr2 == 0x5555 && fd->state == 2 && v == 0xa0) + // data protect enable + if (addr == 0x5555 && fd->state == 2 && v == 0xa0) { fd->state = 7; + det = true; + fd->writeprot = -1; + return false; + } + + // data protect disable + if (addr == 0x5555 && fd->state == 6 && v == 0x20) { + fd->state = 0; + fd->writeprot = 0; + return false; + } - // chip/sector erase - if (addr2 == 0x5555 && fd->state == 2 && v == 0x80) + // chip/sector erase/protect disable + if (addr == 0x5555 && fd->state == 2 && v == 0x80) { fd->state = 4; - if (addr2 == 0x5555 && fd->state == 4 && v == 0xaa) + det = true; + } + if (addr == 0x5555 && fd->state == 4 && v == 0xaa) { fd->state = 5; - if (addr2 == 0x2aaa && fd->state == 5 && v == 0x55) + det = true; + } + if (addr == 0x2aaa && fd->state == 5 && v == 0x55) { fd->state = 6; - if (addr2 == 0x5555 && fd->state == 6 && v == 0x10) { + det = true; + } + if (addr == 0x5555 && fd->state == 6 && v == 0x10) { for (int i = 0; i < fd->allocsize; i++) { int a = i * other_byte_mult; if (fd->rom[a] != 0xff) { @@ -776,8 +863,15 @@ bool flash_write(void *fdv, uaecptr addr, uae_u8 v) return true; } - if (fd->state == oldstate) + if (fd->state == oldstate || !det) { fd->state = 0; + } + + if (!det && (fd->flags & FLASHROM_PARALLEL_EEPROM)) { + int a = addr * other_byte_mult; + writeflash(fd, a, v); + return true; + } return false; } @@ -793,12 +887,32 @@ uae_u32 flash_read(void *fdv, uaecptr addr) if (!fd) return 0; - if (fd->flags & FLASHROM_EVERY_OTHER_BYTE) { + if (fd->flags & (FLASHROM_EVERY_OTHER_BYTE | FLASHROM_SKIP_EVERY_OTHER_BYTE)) { addr >>= 1; other_byte_mult = 2; } + if (addr * other_byte_mult >= fd->allocsize) { + return 0xff; + } + addr &= fd->mask; + + // write data in pagebuffer when any read is done + if ((fd->flags & FLASHROM_PARALLEL_EEPROM) && fd->pagemodified) { + fd->pagemodified = false; + for (int i = 0; i < fd->pagesize; i++) { + int offset = fd->lastpagewrite + i; + if (fd->mpage[i]) { + if (fd->rom[offset] != fd->page[i]) { + fd->rom[offset] = fd->page[i]; + setmodified(fd, offset); + } + fd->mpage[i] = false; + } + } + } + if (fd->state == 3) { uae_u8 a = addr & 0xff; if (a == 0) @@ -821,14 +935,12 @@ uae_u32 flash_read(void *fdv, uaecptr addr) if (fd->state & 1) v ^= 0x40; fd->state++; - if (fd->state >= 110) + if (fd->state >= 110) { fd->state = 0; + } } else { fd->state = 0; - if (addr >= fd->allocsize) - v = 0xff; - else - v = fd->rom[addr * other_byte_mult]; + v = fd->rom[addr * other_byte_mult]; } #if FLASH_LOG > 1 write_log(_T("flash read %08x = %02X (%d) PC=%08x\n"), oaddr, v, fd->state, m68k_getpc()); diff --git a/gfxboard.cpp b/gfxboard.cpp index 5f7d507a..c3e57c19 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -4494,7 +4494,7 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) _tcscat(path, _T("voodoo3.rom")); else _tcscat(path, _T("s3virge.rom")); - struct zfile *zf = read_rom_name(path); + struct zfile *zf = read_rom_name(path, false); if (zf) { gb->bios = xcalloc(uae_u8, 65536); gb->bios_mask = 65535; diff --git a/idecontrollers.cpp b/idecontrollers.cpp index c84311ac..a578349b 100644 --- a/idecontrollers.cpp +++ b/idecontrollers.cpp @@ -28,6 +28,8 @@ #include "ncr9x_scsi.h" #include "autoconf.h" #include "devices.h" +#include "flashrom.h" + #define DEBUG_IDE 0 #define DEBUG_IDE_GVP 0 @@ -148,6 +150,8 @@ static void freencrunit(struct ide_board *ide) } if (ide->self_ptr) *ide->self_ptr = NULL; + flash_free(ide->flashrom); + zfile_fclose(ide->romfile); xfree(ide->rom); xfree(ide); } @@ -478,9 +482,18 @@ static int get_adide_reg(uaecptr addr, struct ide_board *board) return reg; } -static int get_buddha_reg(uaecptr addr, struct ide_board *board, int *portnum) +static int get_buddha_reg(uaecptr addr, struct ide_board *board, int *portnum, int *flashoffset) { int reg = -1; + if (flashoffset) { + *flashoffset = -1; + } + if (board->flashenabled) { + if (flashoffset && !(addr & 1)) { + *flashoffset = ((board->userdata & 0x100) ? 32768 : 0) + (addr >> 1); + } + return -1; + } if (addr < 0x800 || addr >= 0xe00) return reg; *portnum = (addr - 0x800) / 0x200; @@ -648,14 +661,18 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) write_log(_T("IDE IO BYTE READ %08x %08x\n"), addr, M68K_GETPC); #endif - if (addr < 0x40 && (!board->configured || board->keepautoconfig)) + if (addr < 0x40 && !board->flashenabled && (!board->configured || board->keepautoconfig)) return board->acmemory[addr]; if (board->type == BUDDHA_IDE) { int portnum; - int regnum = get_buddha_reg(addr, board, &portnum); - if (regnum >= 0) { + int flashoffset = -1; + bool p1 = (board->aci->rc->device_settings & 3) == 1; + int regnum = get_buddha_reg(addr, board, &portnum, &flashoffset); + if (flashoffset >= 0) { + v = flash_read(board->flashrom, flashoffset); + } else if (regnum >= 0) { if (board->ide[portnum]) v = get_ide_reg_multi(board, regnum, portnum, 1); } else if (addr >= 0xf00 && addr < 0x1000) { @@ -663,7 +680,7 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) v = ide_irq_check(board->ide[0], false) ? 0x80 : 0x00; } else if ((addr & ~3) == 0xf40) { v = ide_irq_check(board->ide[1], false) ? 0x80 : 0x00; - } else if ((addr & ~3) == 0xf80 && (board->aci->rc->device_settings & 3) != 1) { + } else if ((addr & ~3) == 0xf80 && !p1) { v = ide_irq_check(board->ide[2], false) ? 0x80 : 0x00; } else { v = 0; @@ -671,7 +688,11 @@ static uae_u32 ide_read_byte(struct ide_board *board, uaecptr addr) } else if (addr >= 0x7fc && addr <= 0x7ff) { v = board->userdata; } else { - v = board->rom[addr & board->rom_mask]; + int offset = (addr >> 1) & board->rom_mask; + if (p1 && (board->userdata & 0x100)) { + offset += 0x8000; + } + v = board->rom[offset]; } } else if (board->type == ALF_IDE || board->type == TANDEM_IDE) { @@ -1083,7 +1104,7 @@ static uae_u32 ide_read_word(struct ide_board *board, uaecptr addr) if (board->type == BUDDHA_IDE) { int portnum; - int regnum = get_buddha_reg(addr, board, &portnum); + int regnum = get_buddha_reg(addr, board, &portnum, NULL); if (regnum == IDE_DATA) { if (board->ide[portnum]) v = get_ide_reg_multi(board, IDE_DATA, portnum, 1); @@ -1393,15 +1414,65 @@ static void ide_write_byte(struct ide_board *board, uaecptr addr, uae_u8 v) if (board->type == BUDDHA_IDE) { int portnum; - int regnum = get_buddha_reg(addr, board, &portnum); - if (regnum >= 0) { + int flashoffset = -1; + bool p1 = (board->aci->rc->device_settings & 3) == 1; + int regnum = get_buddha_reg(addr, board, &portnum, &flashoffset); + if (flashoffset >= 0) { + flash_write(board->flashrom, flashoffset, v); + } else if (regnum >= 0) { if (board->ide[portnum]) { put_ide_reg_multi(board, regnum, v, portnum, 1); } } else if (addr >= 0xfc0 && addr < 0xfc4) { board->intena = true; + if (addr == 0xfc2 && p1) { + uae_u8 v2 = v & 0xf0; + int cnt = (board->userdata >> 16) & 15; + if (v2 == 0xa0 && cnt == 0) { + cnt++; + } else if (v2 == 0x50 && cnt == 1) { + cnt++; + } else if (v2 == 0xa0 && cnt == 2) { + cnt++; + } else if (v2 == 0x70 && cnt == 3) { + board->userdata |= 0x100000; + write_log("RAM expansion OFF\n"); + } else if (v2 == 0xc0 && cnt == 3) { + board->userdata |= 0x200000; + } else if (v2 == 0xe0 && cnt == 3) { + write_log("Lockdown EEPROM\n"); + } else if (v2 == 0xb0 && cnt == 3) { + write_log("Fast-Z2 ON\n"); + } else if (v2 == 0x30 && cnt == 3) { + write_log("Fast-Z2 OFF\n"); + } else if (v2 == 0x90 && cnt == 3) { + write_log("Early write ON\n"); + } else if (v2 == 0x80 && cnt == 3) { + write_log("Early write OFF\n"); + } else if (v2 == 0x60 && (board->userdata & 0x100000)) { + write_log("$a00000 ON\n"); + } else if (v2 == 0x60 && (board->userdata & 0x200000)) { + write_log("$c00000 ON\n"); + } else if (v2 == 0xf0 && cnt == 3) { + board->flashenabled = true; + } else { + cnt = 0; + } + board->userdata &= 0xfff0ffff; + board->userdata |= cnt << 16; + } } else if (addr >= 0x7fc && addr <= 0x7ff) { - board->userdata = v; + board->userdata &= ~0xff; + board->userdata |= v; + } else if (addr == 0xc3) { + if (p1) { + board->userdata |= 0x100; + } + } else if (addr == 0xc1) { + board->userdata &= ~0x100; + } else if (addr == 1) { + board->userdata = 0; + board->flashenabled = false; } } else if (board->type == ALF_IDE || board->type == TANDEM_IDE) { @@ -1670,7 +1741,7 @@ static void ide_write_word(struct ide_board *board, uaecptr addr, uae_u16 v) if (board->type == BUDDHA_IDE) { int portnum; - int regnum = get_buddha_reg(addr, board, &portnum); + int regnum = get_buddha_reg(addr, board, &portnum, NULL); if (regnum == IDE_DATA) { if (board->ide[portnum]) put_ide_reg_multi(board, IDE_DATA, v, portnum, 1); @@ -2479,21 +2550,26 @@ bool buddha_init(struct autoconfig_info *aci) return true; } struct ide_board *ide = getide(aci); + bool p1 = (aci->rc->device_settings & 3) == 1; ide->configured = 0; ide->bank = &ide_bank_generic; ide->rom_size = 65536; ide->mask = 65536 - 1; - ide->rom = xcalloc(uae_u8, ide->rom_size); - memset(ide->rom, 0xff, ide->rom_size); + ide->rom = xcalloc(uae_u8, ide->rom_size * 2); + memset(ide->rom, 0xff, ide->rom_size * 2); ide->rom_mask = ide->rom_size - 1; - load_rom_rc(aci->rc, ROMTYPE_BUDDHA, 32768, 0, ide->rom, 65536, LOADROM_EVENONLY_ODDONE | LOADROM_FILL); + ide->romfile = load_rom_rc_zfile(aci->rc, ROMTYPE_BUDDHA, 65536, 0, ide->rom, 65536, LOADROM_FILL); + if (p1) { + ide->flashrom = flash_new(ide->rom, 65536, 65536, 0xbf, 0x5d, ide->romfile, FLASHROM_PARALLEL_EEPROM | FLASHROM_DATA_PROTECT); + } + for (int i = 0; i < 16; i++) { uae_u8 b = ert->autoconfig[i]; if (i == 1 && (aci->rc->device_settings & 3) == 2) b = 42; - if (i == 9 && (aci->rc->device_settings & 3) == 1) + if (i == 9 && p1) b = 6; ew(ide, i * 4, b); } diff --git a/include/flashrom.h b/include/flashrom.h index 2f12bad4..0f355118 100644 --- a/include/flashrom.h +++ b/include/flashrom.h @@ -26,6 +26,8 @@ int eeprom_i2c_set(void *i2c, int line, int level); #define FLASHROM_EVERY_OTHER_BYTE 1 #define FLASHROM_EVERY_OTHER_BYTE_ODD 2 #define FLASHROM_PARALLEL_EEPROM 4 +#define FLASHROM_SKIP_EVERY_OTHER_BYTE 8 +#define FLASHROM_DATA_PROTECT 16 void *i2c_new(uae_u8 device_address, int size, uae_u8(*read_func)(uae_u8 addr), void(*write_func)(uae_u8 addr, uae_u8 v)); void i2c_free(void *i2c); diff --git a/include/ide.h b/include/ide.h index a2d0c5a0..c9992aa5 100644 --- a/include/ide.h +++ b/include/ide.h @@ -33,6 +33,8 @@ typedef void (*hsync_func)(struct ide_board*); struct ide_board { uae_u8 *rom; + void *flashrom; + struct zfile *romfile; uae_u8 acmemory[128]; int rom_size; int rom_start; @@ -47,6 +49,7 @@ struct ide_board bool intena; bool enabled; bool intlev6; + bool flashenabled; int state; uae_u8 state2[8]; int type; diff --git a/include/rommgr.h b/include/rommgr.h index ca34b6dd..52c39857 100644 --- a/include/rommgr.h +++ b/include/rommgr.h @@ -274,9 +274,9 @@ extern struct romlist *getromlistbyromdata (const struct romdata *rd); extern void romlist_add (const TCHAR *path, struct romdata *rd); extern TCHAR *romlist_get (const struct romdata *rd); extern void romlist_clear (void); -extern struct zfile *read_rom (struct romdata *rd); -extern struct zfile *read_rom_name (const TCHAR *filename); -extern struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype); +extern struct zfile *read_rom(struct romdata *rd, bool rw = false); +extern struct zfile *read_rom_name(const TCHAR *filename, bool rw = false); +extern struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype, bool rw = false); extern int load_keyring (struct uae_prefs *p, const TCHAR *path); extern uae_u8 *target_load_keyfile (struct uae_prefs *p, const TCHAR *path, int *size, TCHAR *name); @@ -314,6 +314,7 @@ void board_prefs_changed(int romtype, int devnum); #define LOADROM_ZEROFILL 8 #define LOADROM_ODDFILL(x) ((x << 16) | LOADROM_EVENONLY) bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags); +struct zfile *load_rom_rc_zfile(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags); struct zfile *flashromfile_open(const TCHAR *name); #define EXPANSION_ORDER_MAX 10000 diff --git a/memory.cpp b/memory.cpp index 678bd0ac..52676825 100644 --- a/memory.cpp +++ b/memory.cpp @@ -1674,7 +1674,7 @@ static bool load_extendedkickstart (const TCHAR *romextfile, int type) extendedkickmem_type = EXTENDED_ROM_ARCADIA; return false; } - f = read_rom_name (romextfile); + f = read_rom_name (romextfile, false); if (!f) { notify_user (NUMSG_NOEXTROM); return false; @@ -1871,7 +1871,7 @@ static struct zfile *get_kickstart_filehandle(struct uae_prefs *p) struct zfile *f; TCHAR tmprom[MAX_DPATH], tmprom2[MAX_DPATH]; - f = read_rom_name(p->romfile); + f = read_rom_name(p->romfile, false); _tcscpy(tmprom, p->romfile); _tcscpy(tmprom2, p->romfile); if (f == NULL) { diff --git a/rommgr.cpp b/rommgr.cpp index e2ed0232..3472761d 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -1921,7 +1921,7 @@ static void descramble (const struct romdata *rd, uae_u8 *data, int size, int od descramble_nordicpro (data, size, odd); } -static int read_rom_file (uae_u8 *buf, const struct romdata *rd) +static int read_rom_file(uae_u8 *buf, const struct romdata *rd, bool rw) { struct zfile *zf; struct romlist *rl = romlist_getrl (rd); @@ -1929,7 +1929,7 @@ static int read_rom_file (uae_u8 *buf, const struct romdata *rd) if (!rl || rl->path[0] == '\0') return 0; - zf = zfile_fopen (rl->path, _T("rb"), ZFD_NORMAL); + zf = zfile_fopen (rl->path, rw ? _T("rb+") : _T("rb"), ZFD_NORMAL); if (!zf) return 0; addkeydir (rl->path); @@ -2005,7 +2005,7 @@ static void alg_descramble(struct romdata *rd, uae_u8 *buf, int size) } } -struct zfile *read_rom(struct romdata *prd) +struct zfile *read_rom(struct romdata *prd, bool rw) { struct romdata *rd2 = prd; struct romdata *rd = prd; @@ -2043,7 +2043,7 @@ struct zfile *read_rom(struct romdata *prd) for (i = 0; i < 2; i++) { memset (buf, 0, size); if (!(flags & (ROMTYPE_EVEN | ROMTYPE_ODD))) { - read_rom_file (buf, rd); + read_rom_file(buf, rd, rw); if (flags & ROMTYPE_CD32) { memcpy (buf2, buf, size); mergecd32 (buf, buf2, size); @@ -2053,14 +2053,14 @@ struct zfile *read_rom(struct romdata *prd) } else if (flags & ROMTYPE_QUAD) { if (i == 0) { for (int k = 0; k < 4; k++) { - read_rom_file (buf2, rd2 + k + 1); + read_rom_file(buf2, rd2 + k + 1, rw); for (j = 0; j < size; j += 4) buf[j + k] = buf2[j / 4]; } } else { for (int kk = 0; kk < 2; kk++) { for (int k = 0; k < 2; k++) { - read_rom_file (buf2, rd2 + k + kk * 2 + 1); + read_rom_file(buf2, rd2 + k + kk * 2 + 1, rw); for (j = 0; j < size / 2; j += 2) { buf[j + k + kk * (rd2->size / 2)] = buf2[j / 2]; } @@ -2079,14 +2079,14 @@ struct zfile *read_rom(struct romdata *prd) else rdpair = rd; if (flags & ROMTYPE_8BIT) { - read_rom_file (buf2, rd); + read_rom_file(buf2, rd, rw); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) descramble (rd, buf2, romsize, odd); for (j = 0; j < size; j += 2) buf[j + odd] = buf2[j / 2]; - read_rom_file (buf2, rdpair); + read_rom_file(buf2, rdpair, rw); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) @@ -2094,7 +2094,7 @@ struct zfile *read_rom(struct romdata *prd) for (j = 0; j < size; j += 2) buf[j + (1 - odd)] = buf2[j / 2]; } else { - read_rom_file (buf2, rd); + read_rom_file(buf2, rd, rw); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) @@ -2103,7 +2103,7 @@ struct zfile *read_rom(struct romdata *prd) buf[j + 2 * odd + 0] = buf2[j / 2 + 0]; buf[j + 2 * odd + 1] = buf2[j / 2 + 1]; } - read_rom_file (buf2, rdpair); + read_rom_file(buf2, rdpair, rw); if (flags & ROMTYPE_BYTESWAP) byteswap (buf2, romsize); if (flags & ROMTYPE_SCRAMBLED) @@ -2233,7 +2233,7 @@ static struct zfile *rom_fopen2(const TCHAR *name, const TCHAR *mode, int mask) return f; } -struct zfile *read_rom_name (const TCHAR *filename) +struct zfile *read_rom_name(const TCHAR *filename, bool rw) { struct zfile *f; @@ -2245,7 +2245,7 @@ struct zfile *read_rom_name (const TCHAR *filename) return f; } } - f = rom_fopen2(filename, _T("rb"), ZFD_NORMAL); + f = rom_fopen2(filename, rw ? _T("rb+") : _T("rb"), ZFD_NORMAL); if (f) { uae_u8 tmp[11] = { 0 }; zfile_fread(tmp, sizeof tmp, 1, f); @@ -2598,19 +2598,19 @@ static bool isspecialrom(const TCHAR *name) return false; } -struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype) +struct zfile *read_device_from_romconfig(struct romconfig *rc, uae_u32 romtype, bool rw) { struct zfile *z = NULL; if (isspecialrom(rc->romfile)) return z; - z = read_rom_name (rc->romfile); + z = read_rom_name(rc->romfile, rw); if (z) return z; if (romtype) { struct romlist *rl = getromlistbyromtype(romtype, NULL); if (rl) { struct romdata *rd = rl->rd; - z = read_rom(rd); + z = read_rom(rd, rw); } } return z; @@ -2624,7 +2624,7 @@ struct zfile *read_device_rom(struct uae_prefs *p, int romtype, int devnum, int const TCHAR *romname = brc->roms[idx].romfile; if (isspecialrom(romname)) return NULL; - struct zfile *z = read_rom_name (romname); + struct zfile *z = read_rom_name (romname, false); if (!z && roms) { struct romlist *rl = getromlistbyids(roms, romname); if (rl) { @@ -2725,13 +2725,16 @@ static struct zfile *parse_trumpcard_driver(struct zfile *z) return zd; } -bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags) +static bool load_rom_rc1(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags, struct zfile **zf) { + if (zf) { + *zf = NULL; + } if (flags & LOADROM_ONEFILL) memset(rom, 0xff, maxromsize); if (flags & LOADROM_ZEROFILL) memset(rom, 0x00, maxromsize); - struct zfile *f = read_device_from_romconfig(rc, romtype); + struct zfile *f = read_device_from_romconfig(rc, romtype, zf != NULL); if (!f) return false; TCHAR *ext = _tcsrchr(zfile_getname(f), '.'); @@ -2772,7 +2775,11 @@ bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fil } if (f) write_log(_T("ROM '%s' loaded, %d bytes.\n"), zfile_getname(f), bytes); - zfile_fclose(f); + if (!zf) { + zfile_fclose(f); + } else { + *zf = f; + } int posend = pos; if (!(flags & LOADROM_FILL)) return true; @@ -2787,6 +2794,19 @@ bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fil return true; } +bool load_rom_rc(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags) +{ + return load_rom_rc1(rc, romtype, maxfilesize, fileoffset, rom, maxromsize, flags, NULL); +} +struct zfile *load_rom_rc_zfile(struct romconfig *rc, uae_u32 romtype, int maxfilesize, int fileoffset, uae_u8 *rom, int maxromsize, int flags) +{ + struct zfile *zf = NULL; + if (!load_rom_rc1(rc, romtype, maxfilesize, fileoffset, rom, maxromsize, flags, &zf)) { + return NULL; + } + return zf; +} + struct zfile *flashromfile_open(const TCHAR *name) { struct zfile *f;