private static int runToNextInputFrameHiLoR(Gameboy gbL, Gameboy gbR, DualState initial, int limit) {
    int joypadInputFirst = Math.min(gbR.rom.readJoypadInputHi, gbR.rom.readJoypadInputLo);
    int joypadInputLast = Math.max(gbR.rom.readJoypadInputHi, gbR.rom.readJoypadInputLo);

    if (!gbR.onFrameBoundaries)
      dualStep(gbL, gbR, 0, 0); // end unfinished frame

    int initialSteps = gbR.stepCount;
    int lastVframe;
    int ret;

    int add = runToAddressR(limit, gbL, gbR, joypadInputFirst);
    while (true) {
      if (add == 0 || gbR.stepCount - initialSteps > limit)
        return 0;
      lastVframe = gbR.stepCount - 1; // subtract started frame
      if (dualStepUntilR(gbL, gbR, 0, 0, joypadInputLast) == 0) { // Assumption: joypadInputLast will come before curGb.rom.readJoypadAddress
        System.out.println("WARNING: joypadInputFirst not is same frame as joypadInputLast! Need two-frame press.");
        ret = 2;
      } else {
        ret = 1;
        add = dualStepUntilR(gbL, gbR, 0, 0, gbR.rom.readJoypadAddress);
        if (add != 0)
          break;
      }
      add = runToAddressR(limit, gbL, gbR, joypadInputFirst, gbR.rom.readJoypadAddress);
      if (add == gbR.rom.readJoypadAddress)
        break;
    }

    load(gbL, gbR, initial);
    runFor(gbL, gbR, lastVframe - initialSteps);
    return ret;
  }