auto V30MZ::opInString(Size size) {
  wait(5);
  if(!repeat() || r.cx) {
    auto data = in(size, r.dx);
    write(size, r.es, r.di, data);
    r.di += r.f.d ? -size : size;

    if(!repeat() || !--r.cx) return;

    state.prefix = true;
    r.ip--;
  }
}

auto V30MZ::opOutString(Size size) {
  wait(6);
  if(!repeat() || r.cx) {
    auto data = read(size, segment(r.ds), r.si);
    out(size, r.dx, data);
    r.si += r.f.d ? -size : size;

    if(!repeat() || !--r.cx) return;

    state.prefix = true;
    r.ip--;
  }
}

auto V30MZ::opMoveString(Size size) {
  wait(4);
  if(!repeat() || r.cx) {
    auto data = read(size, segment(r.ds), r.si);
    write(size, r.es, r.di, data);
    r.si += r.f.d ? -size : size;
    r.di += r.f.d ? -size : size;

    if(!repeat() || !--r.cx) return;

    state.prefix = true;
    r.ip--;
  }
}

auto V30MZ::opCompareString(Size size) {
  wait(5);
  if(!repeat() || r.cx) {
    auto x = read(size, segment(r.ds), r.si);
    auto y = read(size, r.es, r.di);
    r.si += r.f.d ? -size : size;
    r.di += r.f.d ? -size : size;
    alSub(size, x, y);

    if(!repeat() || !--r.cx) return;
    if(repeat() == RepeatWhileZero && r.f.z == 0) return;
    if(repeat() == RepeatWhileNotZero && r.f.z == 1) return;

    state.prefix = true;
    r.ip--;
  }
}

auto V30MZ::opStoreString(Size size) {
  wait(2);
  if(!repeat() || r.cx) {
    write(size, r.es, r.di, getAcc(size));
    r.di += r.f.d ? -size : size;

    if(!repeat() || !--r.cx) return;

    state.prefix = true;
    r.ip--;
  }
}

//ac  lodsb
//ad  lodsw
auto V30MZ::opLoadString(Size size) {
  wait(2);
  if(!repeat() || r.cx) {
    setAcc(size, read(size, segment(r.ds), r.si));
    r.si += r.f.d ? -size : size;

    if(!repeat() || !--r.cx) return;

    state.prefix = true;
    r.ip--;
  }
}

//ae  scasb
//af  scasw
auto V30MZ::opScanString(Size size) {
  wait(3);
  if(!repeat() || r.cx) {
    auto x = getAcc(size);
    auto y = read(size, r.es, r.di);
    r.di += r.f.d ? -size : size;
    alSub(size, x, y);

    if(!repeat() || !--r.cx) return;
    if(repeat() == RepeatWhileZero && r.f.z == 0) return;
    if(repeat() == RepeatWhileNotZero && r.f.z == 1) return;

    state.prefix = true;
    r.ip--;
  }
}
