ref: 6d4887cafd1a3f7f84f8df23974a0e9b6673603f
parent: d3b174f82102c6fb3ee9c540ebc5879e6bedb3f6
author: Jacob Moody <moody@posixcafe.org>
date: Fri Mar 13 23:26:12 EDT 2026
games/md: SRAMEN is only technically needed for roms > 2MB (thanks qwx) Turns out that what SRAMEN controlls is a mapping that swaps between the upper 2MB of the rom and SRAM (if in the cart). If the ROM is only 2MB the mega drive will permit writes to SRAM through addresses >2MB regardless of SRAMEN. This fixes shadowrun.
--- a/sys/src/games/md/mem.c
+++ b/sys/src/games/md/mem.c
@@ -121,12 +121,16 @@
switch(a >> 21 & 7){case 0: case 1:
- if((sramctl & SRAMEN) != 0 && a >= sram0 && a <= sram1)
- switch(sramctl & ADDRMASK){- case ADDREVEN: return sram[(a - sram0) >> 1] << 8;
- case ADDRODD: return sram[(a - sram0) >> 1];
- case ADDRBOTH: return sram[a - sram0] << 8 | sram[a - sram0 + 1];
- }
+ if(a < sram0 || a > sram1)
+ goto rom;
+ if((sramctl & SRAMEN) == 0 && nprg > 2*1024*1024)
+ goto rom;
+ switch(sramctl & ADDRMASK){+ case ADDREVEN: return sram[(a - sram0) >> 1] << 8;
+ case ADDRODD: return sram[(a - sram0) >> 1];
+ case ADDRBOTH: return sram[a - sram0] << 8 | sram[a - sram0 + 1];
+ }
+ rom:
return prg[(a % nprg) / 2];
case 5:
switch(a >> 16 & 0xff){@@ -203,22 +207,23 @@
print("%x %x %x\n", curpc, v, m); switch((a >> 21) & 7){case 0: case 1:
- if((sramctl & SRAMEN) != 0 && a >= sram0 && a <= sram1){- switch(sramctl & ADDRMASK){- case ADDREVEN: sram[(a - sram0) >> 1] = v >> 8; break;
- case ADDRODD: sram[(a - sram0) >> 1] = v; break;
- case ADDRBOTH:
- if((m & 0xff00) == 0xff00)
- sram[a - sram0] = v >> 8;
- if((m & 0xff) == 0xff)
- sram[a + 1 - sram0] = v;
- break;
- }
- if(saveclock == 0)
- saveclock = SAVEFREQ;
- return;
+ if(a < sram0 || a > sram1)
+ goto invalid;
+ if((sramctl & SRAMEN) == 0 && nprg > 2*1024*1024)
+ goto invalid;
+ switch(sramctl & ADDRMASK){+ case ADDREVEN: sram[(a - sram0) >> 1] = v >> 8; break;
+ case ADDRODD: sram[(a - sram0) >> 1] = v; break;
+ case ADDRBOTH:
+ if((m & 0xff00) == 0xff00)
+ sram[a - sram0] = v >> 8;
+ if((m & 0xff) == 0xff)
+ sram[a + 1 - sram0] = v;
+ break;
}
- goto invalid;
+ if(saveclock == 0)
+ saveclock = SAVEFREQ;
+ return;
case 5:
switch(a >> 16 & 0xff){case 0xa0:
--
⑨