static const vector<string> registerNames = {
  "MI_INIT_MODE",
  "MI_VERSION",
  "MI_INTR",
  "MI_INTR_MASK",
};

auto MI::readWord(u32 address) -> u32 {
  address = (address & 0xfffff) >> 2;
  uint32 data;

  if(address == 0) {
    //MI_INIT_MODE
  }

  if(address == 1) {
    //MI_VERSION
    data.byte(0) = revision.io;
    data.byte(1) = revision.rac;
    data.byte(2) = revision.rdp;
    data.byte(3) = revision.rsp;
  }

  if(address == 2) {
    //MI_INTR
    data.bit(0) = irq.sp.line;
    data.bit(1) = irq.si.line;
    data.bit(2) = irq.ai.line;
    data.bit(3) = irq.vi.line;
    data.bit(4) = irq.pi.line;
    data.bit(5) = irq.dp.line;
  }

  if(address == 3) {
    //MI_INTR_MASK
    data.bit(0) = irq.sp.mask;
    data.bit(1) = irq.si.mask;
    data.bit(2) = irq.ai.mask;
    data.bit(3) = irq.vi.mask;
    data.bit(4) = irq.pi.mask;
    data.bit(5) = irq.dp.mask;
  }

  if(debugger.tracer.io->enabled()) {
    debugger.io({registerNames(address, "MI_UNKNOWN"), " => ", hex(data, 8L)});
  }
  return data;
}

auto MI::writeWord(u32 address, u32 data_) -> void {
  address = (address & 0xfffff) >> 2;
  uint32 data = data_;

  if(address == 0) {
    //MI_INIT_MODE
    if(data.bit(11)) mi.lower(MI::IRQ::DP);
  }

  if(address == 1) {
    //MI_VERSION (read-only)
  }

  if(address == 2) {
    //MI_INTR (read-only)
  }

  if(address == 3) {
    //MI_INTR_MASK
    if(data.bit( 0)) irq.sp.mask = 0;
    if(data.bit( 1)) irq.sp.mask = 1;
    if(data.bit( 2)) irq.si.mask = 0;
    if(data.bit( 3)) irq.si.mask = 1;
    if(data.bit( 4)) irq.ai.mask = 0;
    if(data.bit( 5)) irq.ai.mask = 1;
    if(data.bit( 6)) irq.vi.mask = 0;
    if(data.bit( 7)) irq.vi.mask = 1;
    if(data.bit( 8)) irq.pi.mask = 0;
    if(data.bit( 9)) irq.pi.mask = 1;
    if(data.bit(10)) irq.dp.mask = 0;
    if(data.bit(11)) irq.dp.mask = 1;
    poll();
  }

  if(debugger.tracer.io->enabled()) {
    debugger.io({registerNames(address, "MI_UNKNOWN"), " <= ", hex(data, 8L)});
  }
}
