Не совсем так. Общаться напрямую с устройствами может как виртуальная программа (через системные вызовы .PEEK/.POKE или пользуясь тем, что PSW в XM/ZM для такой программы 140000) так и полновиртуальная (она просто может быть отмаплена на i/O page установкой соответствующего бита по смещению 4). Ограничение есть на использование векторов - вот к ним доступа у такой программы нет.
Соответственно без переделок все будет работать если использовать VBGEXE/V/VRUN, но по смещению 4 надо указать, что нужен IOPAGE (на память бит не помню, надо в описании утилиты LINK смотреть) если не нужны вектора.