- int mode = ssp->pmac_write[reg]&0xffff;
- int addr = ssp->pmac_write[reg]>>16;
- switch (mode) {
- case 0x0018: elprintf(EL_SVP, "ssp DRAM w [%06x] %04x", addr<<1, d);
- ((unsigned short *)svp->dram)[addr] = d;
- break;
- case 0x0818: elprintf(EL_SVP, "ssp DRAM w [%06x] %04x (inc 1)", addr<<1, d);
- ((unsigned short *)svp->dram)[addr] = d;
- ssp->pmac_write[reg] += 1<<16;
- break;
- case 0x081c: iram_write(addr, d, reg, 1); break; // checked: used by code @ 0902
- case 0x101c: iram_write(addr, d, reg, 2); break; // checked: used by code @ 3b7c
- default: elprintf(EL_SVP|EL_ANOMALY, "ssp PM%i unhandled write mode %04x, [%06x] %04x @ %04x",
- reg, mode, addr<<1, d, GET_PPC_OFFS()); break;
+ int mode = ssp->pmac_write[reg]>>16;
+ int addr = ssp->pmac_write[reg]&0xffff;
+ if ((mode & 0xb800) == 0xb800)
+ elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: mode %04x", mode);
+ if ((mode & 0x43ff) == 0x0018) // DRAM
+ {
+ int inc = get_inc(mode);
+ elprintf(EL_SVP, "ssp PM%i DRAM w [%06x] %04x (inc %i, ovrw %i)",
+ reg, CADDR, d, inc, (mode>>10)&1);
+ if (mode & 0x0400) {
+ overwrite_write(dram[addr], d);
+ } else dram[addr] = d;
+ ssp->pmac_write[reg] += inc;
+ }
+ else if ((mode & 0xfbff) == 0x4018) // DRAM, cell inc
+ {
+ elprintf(EL_SVP, "ssp PM%i DRAM w [%06x] %04x (cell inc, ovrw %i) @ %04x",
+ reg, CADDR, d, (mode>>10)&1, GET_PPC_OFFS());
+ if (mode & 0x0400) {
+ overwrite_write(dram[addr], d);
+ } else dram[addr] = d;
+ ssp->pmac_write[reg] += (addr&1) ? 31 : 1;
+ }
+ else if ((mode & 0x47ff) == 0x001c) // IRAM
+ {
+ int inc = get_inc(mode);
+ if ((addr&0xfc00) != 0x8000)
+ elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: invalid IRAM addr: %04x", addr<<1);
+ elprintf(EL_SVP, "ssp IRAM w [%06x] %04x (inc %i)", (addr<<1)&0x7ff, d, inc);
+ ((unsigned short *)svp->iram_rom)[addr&0x3ff] = d;
+ ssp->pmac_write[reg] += inc;
+ }
+ else
+ {
+ elprintf(EL_SVP|EL_ANOMALY, "ssp FIXME: PM%i unhandled write mode %04x, [%06x] %04x @ %04x",
+ reg, mode, CADDR, d, GET_PPC_OFFS());