From 887b79e485fbe9b557509b32559e67de5d0848ed Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 9 Feb 2023 17:10:43 +0200 Subject: [PATCH] Picasso IV flash rom emulation --- flashrom.cpp | 43 +++++++++++++++++++++++------- gfxboard.cpp | 74 +++++++++++++++++++++++++++++----------------------- 2 files changed, 74 insertions(+), 43 deletions(-) diff --git a/flashrom.cpp b/flashrom.cpp index 3dcc1199..298df379 100644 --- a/flashrom.cpp +++ b/flashrom.cpp @@ -605,9 +605,22 @@ struct flashrom_data int sectorsize; uae_u8 devicecode, mfgcode; int flags; + int firstwriteoffset; + int lastwriteoffset; struct zfile *zf; }; +static void setmodified(struct flashrom_data *fd, int offset) +{ + fd->modified = 1; + if (offset < fd->firstwriteoffset) { + fd->firstwriteoffset = offset; + } + if (offset > fd->lastwriteoffset) { + fd->lastwriteoffset = 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); @@ -620,6 +633,8 @@ void *flash_new(uae_u8 *rom, int flashsize, int allocsize, uae_u8 mfgcode, uae_u fd->devicecode = devcode; fd->mfgcode = mfgcode; fd->sectorsize = devcode == 0x20 ? 16384 : 65536; + fd->lastwriteoffset = 0; + fd->firstwriteoffset = allocsize; return fd; } @@ -629,7 +644,6 @@ void flash_free(void *fdv) if (!fd) return; if (fd->zf && fd->modified) { - zfile_fseek(fd->zf, 0, SEEK_SET); 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++) { @@ -637,7 +651,8 @@ void flash_free(void *fdv) zfile_fseek(fd->zf, 1, SEEK_CUR); } } else { - zfile_fwrite(fd->rom, fd->allocsize, 1, fd->zf); + zfile_fseek(fd->zf, fd->firstwriteoffset, SEEK_SET); + zfile_fwrite(fd->rom + fd->firstwriteoffset, fd->lastwriteoffset - fd->firstwriteoffset + 1, 1, fd->zf); } } xfree(fdv); @@ -693,9 +708,11 @@ bool flash_write(void *fdv, uaecptr addr, uae_u8 v) } if (addr >= fd->allocsize) return false; - if (fd->rom[addr * other_byte_mult] != v) - fd->modified = 1; - fd->rom[addr * other_byte_mult] = v; + 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); return true; } @@ -727,11 +744,14 @@ bool flash_write(void *fdv, uaecptr addr, uae_u8 v) if (addr2 == 0x2aaa && fd->state == 5 && v == 0x55) fd->state = 6; if (addr2 == 0x5555 && fd->state == 6 && v == 0x10) { - for (int i = 0; i < fd->allocsize; i++) { - fd->rom[i * other_byte_mult] = 0xff; + for (int i = 0; i < fd->allocsize; i++) { + int a = i * other_byte_mult; + if (fd->rom[a] != 0xff) { + fd->rom[a] = 0xff; + setmodified(fd, a); + } } fd->state = 200; - fd->modified = 1; #if FLASH_LOG write_log(_T("flash chip erased\n"), addr); #endif @@ -741,11 +761,14 @@ bool flash_write(void *fdv, uaecptr addr, uae_u8 v) int saddr = addr & ~(fd->sectorsize - 1); if (saddr < fd->allocsize) { for (int i = 0; i < fd->sectorsize; i++) { - fd->rom[(saddr + i) * other_byte_mult] = 0xff; + int a = (saddr + i) * other_byte_mult; + if (fd->rom[a] != 0xff) { + fd->rom[a] = 0xff; + setmodified(fd, a); + } } } fd->state = 200; - fd->modified = 1; #if FLASH_LOG write_log(_T("flash sector %d erased (%08x)\n"), saddr / fd->sectorsize, addr); #endif diff --git a/gfxboard.cpp b/gfxboard.cpp index bc996d2f..c8fcf39f 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -45,6 +45,7 @@ static bool memlogw = true; #include "xwin.h" #include "devices.h" #include "gfxfilter.h" +#include "flashrom.h" #include "pcem/device.h" #include "pcem/vid_s3_virge.h" #include "pcem/vid_cl5429.h" @@ -304,6 +305,7 @@ struct rtggfxboard uae_u8 picassoiv_bank, picassoiv_flifi; uae_u8 p4autoconfig[256]; struct zfile *p4rom; + void *p4flashrom; bool p4z2; uae_u32 p4_mmiobase; uae_u32 p4_special_mask; @@ -3158,6 +3160,10 @@ static void gfxboard_free_board(struct rtggfxboard *gb) gb->gfxboard_intena = 0; gb->picassoiv_bank = 0; gb->active = false; + flash_free(gb->p4flashrom); + gb->p4flashrom = NULL; + zfile_fclose(gb->p4rom); + gb->p4rom = NULL; } void gfxboard_free(void) @@ -3379,13 +3385,9 @@ static uae_u32 REGPARAM2 gfxboards_bget_regs (uaecptr addr) write_log (_T("PicassoIV BGET %08x %02x\n"), addr, v); #endif } else { - if (addr < PICASSOIV_FLASH_OFFSET) { - v = gb->automemory[addr]; - return v; - } - addr -= PICASSOIV_FLASH_OFFSET; + addr += ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 * 2 : 0); addr /= 2; - v = gb->automemory[addr + PICASSOIV_FLASH_OFFSET + ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 : 0)]; + v = flash_read(gb->p4flashrom, addr); } return v; } @@ -3519,14 +3521,6 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v) } return; } - if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) { - if (addr == 0x404) { - gb->picassoiv_flifi = b; - picassoiv_checkswitch (gb); - } else if (addr == 0x406) { - gb->p4i2c = b; - } - } if (gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) { // memory mapped io if (addr >= gb->p4_mmiobase && addr < gb->p4_mmiobase + 0x8000) { @@ -3538,7 +3532,7 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v) return; } } - if (gb->p4z2 && addr >= 0x10000) { + if (gb->p4z2 && addr >= 0x10000 && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH)) { addr -= 0x10000; addr = mungeaddr (gb, addr, true); if (addr) { @@ -3548,6 +3542,16 @@ static void REGPARAM2 gfxboards_bput_regs (uaecptr addr, uae_u32 v) } return; } + + if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) { + if (addr == 0x404) { + gb->picassoiv_flifi = b; + picassoiv_checkswitch(gb); + } else if (addr == 0x406) { + gb->p4i2c = b; + } + } + #if PICASSOIV_DEBUG_IO write_log (_T("PicassoIV BPUT %08x %02X\n"), addr, b & 0xff); #endif @@ -4249,8 +4253,6 @@ static void gfxboard_init (struct autoconfig_info *aci, struct rtggfxboard *gb) gb->gfxmem_bank = gfxmem_banks[gb->rtg_index]; gb->gfxmem_bank->mask = gb->rbc->rtgmem_size - 1; gb->p4z2 = false; - zfile_fclose (gb->p4rom); - gb->p4rom = NULL; gb->banksize_mask = gb->board->banksize - 1; memset (gb->cirrus_pci, 0, sizeof gb->cirrus_pci); reset_pci (gb); @@ -4286,9 +4288,8 @@ static void loadp4rom (struct rtggfxboard *gb) } // main flash code zfile_fseek (gb->p4rom, 16384, SEEK_SET); - zfile_fread (&gb->automemory[PICASSOIV_FLASH_OFFSET], 1, PICASSOIV_MAX_FLASH, gb->p4rom); - zfile_fclose (gb->p4rom); - gb->p4rom = NULL; + zfile_fread (&gb->automemory[PICASSOIV_FLASH_OFFSET / 2], 1, PICASSOIV_MAX_FLASH, gb->p4rom); + gb->p4flashrom = flash_new(gb->automemory, 131072, 131072, 0x01, 0x20, gb->p4rom, 0); write_log (_T("PICASSOIV: flash rom loaded\n")); } @@ -4357,19 +4358,18 @@ bool gfxboard_init_memory (struct autoconfig_info *aci) TCHAR path[MAX_DPATH]; fetch_rompath (path, sizeof path / sizeof (TCHAR)); - gb->p4rom = read_device_rom(p, ROMTYPE_PICASSOIV, 0, roms); + if (rl) { + gb->p4rom = flashromfile_open(rl->path); + } if (!gb->p4rom && p->picassoivromfile[0] && zfile_exists(p->picassoivromfile)) - gb->p4rom = read_rom_name(p->picassoivromfile); - - if (!gb->p4rom && rl) - gb->p4rom = read_rom(rl->rd); + gb->p4rom = flashromfile_open(p->picassoivromfile); if (!gb->p4rom) { _tcscat (path, _T("picasso_iv_flash.rom")); - gb->p4rom = read_rom_name (path); + gb->p4rom = flashromfile_open(path); if (!gb->p4rom) - gb->p4rom = read_rom_name (_T("picasso_iv_flash.rom")); + gb->p4rom = flashromfile_open(_T("picasso_iv_flash.rom")); } if (gb->p4rom) { zfile_fread (gb->p4autoconfig, sizeof gb->p4autoconfig, 1, gb->p4rom); @@ -5616,7 +5616,7 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size) write_log(_T("PicassoIV CL REG PUT %08x %02x PC=%08x\n"), addr, v, M68K_GETPC); #endif - if (addr >= 0x400000 || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) { + if ((addr >= 0x400000 && addr < 0xa00000) || (gb->p4z2 && !(gb->picassoiv_bank & PICASSOIV_BANK_MAPRAM) && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) && ((addr >= 0x800 && addr < 0xc00) || (addr >= 0x1000 && addr < 0x2000)))) { uae_u32 addr2 = addr & 0xffff; if (addr2 >= 0x0800 && addr2 < 0x840) { addr2 -= 0x800; @@ -5646,7 +5646,7 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size) #endif } return; - } + } if (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH) { if (size == 0) { if (addr == 0x404) { @@ -5683,7 +5683,7 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size) goto end; } } - if (gb->p4z2 && addr >= 0x10000) { + if (gb->p4z2 && addr >= 0x10000 && (gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH)) { addr -= 0x10000; if (size == 2) { v = do_byteswap_32(v); @@ -5700,6 +5700,14 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size) // } goto end; } + if (!(gb->picassoiv_bank & PICASSOIV_BANK_UNMAPFLASH)) { + if (addr >= PICASSOIV_FLASH_OFFSET / 2) { + addr += ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 * 2 : 0); + addr /= 2; + flash_write(gb->p4flashrom, addr, v); + } + } + #if PICASSOIV_DEBUG_IO write_log(_T("PicassoIV BPUT %08x %08X %d\n"), addr, v, size); #endif @@ -5928,13 +5936,13 @@ static uae_u32 special_pcem_get(uaecptr addr, int size) write_log(_T("PicassoIV BGET %08x %02x\n"), addr, v); #endif } else { - if (addr < PICASSOIV_FLASH_OFFSET) { + if (addr < PICASSOIV_FLASH_OFFSET / 2) { v = gb->automemory[addr]; return v; } - addr -= PICASSOIV_FLASH_OFFSET; + addr += ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 * 2: 0); addr /= 2; - v = gb->automemory[addr + PICASSOIV_FLASH_OFFSET + ((gb->picassoiv_bank & PICASSOIV_BANK_FLASHBANK) ? 0x8000 : 0)]; + v = flash_read(gb->p4flashrom, addr); } } -- 2.47.3