Mapping something beyond its own accessible address isn't so bad. You have to approach it from a hardware address line perspective.

Let's say you have a 16 byte space, and you have 11 bytes worth of unique data. How would you make such a board for real? Keeping in mind that virtually every ROM is a power of two ...
8 + 2 + 1 = 11

Now think about how you'd wire up such a board.
A3 == 0 ? ROM0 { A2, A1, A0 }
Else A1 == 0 ? ROM1 { A0 }
Else ROM2 { }

That would give you an interesting pattern:
0123456789AA89AA

0-7 = ROM0
8-9 = ROM1
A = ROM2

Of course, virtually all our sizes can be done with only one or two ROMs, so it's usually just very simple mirroring.

But we can make a simple algorithm to transform an address with the above mirroring.

Code:
unsigned Bus::mirror(unsigned addr, unsigned size) {
  unsigned base = 0;
  if(size) {
    unsigned mask = 1 << 23;
    while(addr >= size) {
      while(!(addr & mask)) mask >>= 1;
      addr -= mask;
      if(size > mask) {
        size -= mask;
        base += mask;
      }
      mask >>= 1;
    }
    base += addr;
  }
  return base;
}


It's a bit prettier in recursive form; but it's slower that way and some of my maps are dynamically modified through MMCs, so smile