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;
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;
blizzardf0_slow(1);
+ addr &= blizzardf0_bank.mask;
if (is_csmk3(&currprefs) || is_blizzardppc(&currprefs)) {
if (flash_unlocked) {
return flash_read(flashrom, addr);
return flash_read(flashrom, addr);
}
}
- addr &= blizzardf0_bank.mask;
v = blizzardf0_bank.baseaddr[addr];
return v;
}
{
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;
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);
}
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;
}
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;
}
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;
}
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;
};
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;
}
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);
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) {
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;
}
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)
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());
_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;
#include "ncr9x_scsi.h"
#include "autoconf.h"
#include "devices.h"
+#include "flashrom.h"
+
#define DEBUG_IDE 0
#define DEBUG_IDE_GVP 0
}
if (ide->self_ptr)
*ide->self_ptr = NULL;
+ flash_free(ide->flashrom);
+ zfile_fclose(ide->romfile);
xfree(ide->rom);
xfree(ide);
}
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;
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) {
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;
} 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) {
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);
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) {
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);
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);
}
#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);
struct ide_board
{
uae_u8 *rom;
+ void *flashrom;
+ struct zfile *romfile;
uae_u8 acmemory[128];
int rom_size;
int rom_start;
bool intena;
bool enabled;
bool intlev6;
+ bool flashenabled;
int state;
uae_u8 state2[8];
int type;
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);
#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
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;
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) {
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);
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);
}
}
-struct zfile *read_rom(struct romdata *prd)
+struct zfile *read_rom(struct romdata *prd, bool rw)
{
struct romdata *rd2 = prd;
struct romdata *rd = 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);
} 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];
}
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)
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)
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)
return f;
}
-struct zfile *read_rom_name (const TCHAR *filename)
+struct zfile *read_rom_name(const TCHAR *filename, bool rw)
{
struct zfile *f;
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);
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;
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) {
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), '.');
}
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;
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;