Чтобы сформировать цикл записи адреса
Чтобы сформировать цикл записи адреса EPP, нужно воспользоваться кодом IOCTL_PAR_SET_WRITE_ADDRESS.
const IOCTL_PAR_SET_WRITE_ADDRESS = $16001C;
var Address: byte;
Address := $AA; DeviceIoControl(hLpt, IOCTL_PAR_SET_WRITE_ADDRESS, @Address, 1, nil, 0, ret, lpOverlapped);
Новый цикл будет сформирован лишь при условии, что в очередном запросе драйверу будет передан новый адрес. Драйвер пытается устранять избыточные операции - благая цель, которая усложняет систему и как следствие влечет ошибки. Я полагаю, что программист Майкрософт не правильно понял смысл чтения адреса EPP, поэтому такая операция отсутствует, зато есть команда IOCTL_PAR_SET_READ_ADDRESS, которая не формирует физических циклов, но настраивает драйвер таким образом, что он создает цикл записи адреса непосредственно перед циклом чтения данных. При этом драйвер, оптимизируя циклы адреса, не всегда работает разумно. Поэтому, не вдаваясь в подробности, я не рекомендую вообще использовать IOCTL_PAR_SET_READ_ADDRESS, тем более что он не дает ничего дополнительно по сравнению с IOCTL_PAR_SET_WRITE_ADDRESS.
Для записи данных в устройство используется функция WriteFile, а для чтения ReadFile. Обе функции обрабатывают поток данных, а не отдельный байт. Это означает, что для режима EPP будет последовательно сформировано столько циклов записи (чтения) данных, сколько необходимо, чтобы передать весь массив байт за байтом. Естественно, что все данные при этом уйдут по одному адресу. Ниже приводится пример кода, в котором производится запись $55 по адресу $AA, а затем чтение по адресам $AA и $BB.
uses Windows;
var hLpt: THandle; ret: DWORD; Address: byte; Data: byte;
// Открыть порт для синхронного доступа hLpt := CreateFile('LPT1', GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, 0, 0);
// Запись $55 по адресу $AA Address := $AA; DeviceIoControl(hLpt, IOCTL_PAR_SET_WRITE_ADDRESS, @Address, 1, nil, 0, ret, nil); WriteFile(hLpt, [$55], 1, ret, nil);
// Чтение по адресу $AA ReadFile(hLPT, Data, 1, ret, nil);
// Чтение по адресу $BB Address := $BB; DeviceIoControl(hLpt, IOCTL_PAR_SET_WRITE_ADDRESS, @Address, 1, nil, 0, ret, nil); ReadFile(hLPT, Data, 1, ret, nil);
// Закрыть устройство CloseHandle(hLpt);