Первый уровень навороченности - физический идентификатор, в котором номер порта и номер бита в порте. Отдельная функция вычисляет номер порта и опрашивает номер бита в порте.
Второй уровень навороченности - абстрактный идентификатор кнопки, и переключаемая таблица, отображающая абстрактные идентификаторы в физические.
Третий уровень навороченности - единообразная обработка дребезга, знающая про все порты и маски всех кнопок в портах, но не про конкретные кнопки, и потом отдельное отображение битов в портах в абстрактные идентификаторы по фиксированной таблице, потом трансляция идентификаторов кнопок в команды одельным диспетчером с возможно хуками в виде коллбэков и потом диспетчеризаия команд.