]> git.unchartedbackwaters.co.uk Git - francis/winuae.git/commitdiff
Picasso IV flash rom emulation
authorToni Wilen <twilen@winuae.net>
Thu, 9 Feb 2023 15:10:43 +0000 (17:10 +0200)
committerToni Wilen <twilen@winuae.net>
Thu, 9 Feb 2023 15:10:43 +0000 (17:10 +0200)
flashrom.cpp
gfxboard.cpp

index 3dcc119962fbd6036c2758a1cd828afda9bb7dca..298df379bc016cebc3842e5a0c5685a56de4c9a2 100644 (file)
@@ -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
index bc996d2f3389701352c3d29590b706a42be2b0c5..c8fcf39f32d428ef20a2c2e01ea4de6b9af93cb7 100644 (file)
@@ -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);
                }
 
        }