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 wink

Code
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.