// Данная прорамма использует прерывание 80h,
// которое устанавливается демонстрационным
// драйвером. Для правлильной установки файл
// CONFIG.SYS должен содержать, например,
// такую строку для подключения драйвера:
//
// device=e:\sysprg\devdrv.sys  1 80 378 379 37a 37a
//
// Число 80 означает номер используемого прерывания.


#include <io.h>
#include <conio.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <malloc.h>
#include <errno.h>
#include <dos.h>

int main(void);

union  REGS  inregs, outregs;
struct SREGS segregs;

int main(void) {

	 char buf[100], ch;
	 int io_handle;
	 unsigned count;


	 // Открываем устройство с именем DEVDRIVR

	 if( (io_handle = open("DEVDRIVR", O_RDWR)) == - 1 ) {

		// Если открыть не удалось, выводим
		// код ошибки

		printf("Ошибка при открытии устройства %d",errno);
		return errno;
	 }

	 // Читаем 8 байт из устройства в буфер buf

	 printf("\nВведите 8 символов с клавиатуры\n");

	 if( (count = read(io_handle, buf, 8)) == -1 ) {

		 // Если при чтении произошла ошибка,
		 // выводим ее код

		 printf("Ошибка чтения %d",errno);
	    return errno;
	}

	// Закрываем прочитанную строку нулем
	// для последующего вывода функцией printf

	buf[8]=0;

	printf("\n▒▒▒ Введена строка: %s ▒▒▒",buf);

	// Выводим только что прочитанные данные
	// обратно на то же устройство

	if( (count = write(io_handle, buf, 8)) == -1 ) {

		 // Если при записи произошла ошибка,
		 // выводим ее код

		 printf("Ошибка записи %d",errno);
	    return errno;
	}

	// Вводим строку IOCTL из устройства

	printf("\nВведите строку IOCTL (8 символов): ");

	inregs.h.ah = 0x44;
	inregs.h.al = 2;
	inregs.x.bx = io_handle;
	inregs.x.dx = (unsigned)buf;
	inregs.x.cx = 8;
	intdos( &inregs, &outregs );
	if(outregs.x.cflag == 1) {

		// При ошибке выводим код ошибки

		printf("IOCTL error %x\n",&outregs.x.ax);
		exit(-1);
	}
	buf[8]=0;
	printf("\n▒▒▒ Введена строка IOCTL: %s ▒▒▒",buf);

	// Выводим строку IOCTL на устройства из buf

	printf("\nВыведена строка IOCTL: ");

	inregs.h.ah = 0x44;
	inregs.h.al = 3;
	inregs.x.bx = io_handle;
	inregs.x.dx = (unsigned)buf;
	inregs.x.cx = 8;
	intdos( &inregs, &outregs );
	if(outregs.x.cflag == 1) {

		// При ошибке выводим код ошибки

		printf("IOCTL error %x\n",&outregs.x.ax);
		exit(-1);
	}

	 printf("\n\n\nПроверяем вызов прерывания."
			  "\n"
			  "\nНажмите любую клавишу...\n\n");
	 getch();

	 printf("\nКоманда записи:\n");

	 inregs.h.ah = 0x0; /* WRITE */
	 inregs.h.bh = 0x777;
	 inregs.h.bl = 0x13;
	 int86( 0x80, &inregs, &outregs );

	 printf("\nКоманда чтения:\n");

	 inregs.h.ah = 0x1; /* READ */
	 inregs.h.bh = 0x776;
	 int86( 0x80, &inregs, &outregs );
	 ch=outregs.h.bl;

	 printf("Полученное значение: %x\n",ch);

	 printf("\nНеизвестная команда:\n");

	 inregs.h.ah = 0x2; /* ??? */
	 int86( 0x80, &inregs, &outregs );

	// Закрываем устройство

	close(io_handle);

	exit(0);
}

