Feel free to use this as PD. Many people have tried to improve it (with lookup tables, ternary, only one return point, etc), but none have succeeded
unsigned sCPU::speed(unsigned addr) const {
if(addr & 0x408000) {
if(addr & 0x800000) return fastROM;
return 8;
}
if((addr + 0x6000) & 0x4000) return 8;
if((addr - 0x4000) & 0x7e00) return 6;
return 12;
}
Set (unsigned)fastROM to 8 on reset, and on $420d.d0 writes, set to (d0 ? 6 : 8);
If you stick this function inside the bus_read() and bus_write() functions, the core of your CPU won't ever need to manually specify eat_cycles() calls.