// Эту программу можно запускать только из командной
// строки. При запуске из интегрированной среды QC
// или PWB возможен конфликт с используемым в этих
// средах обработчиком критических ошибок.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <direct.h>
#include <string.h>
#include <dos.h>
#include <bios.h>

void main(void);
void _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr);
void _bios_str(char *p);

void main() {

// Устанавливаем обработчик критических ошибок

	 _harderr(hhandler);

// Моделируем критическую ошибку. Выполняем попытку создать
// каталог на диске А:. Если мы "забудем" вставить
// в дисковод дискету, будет вызван обработчик
// критической ошибки

	 printf("\nВставьте (или не вставляйте) дискету в дисковод A:"
			  "\nи нажмите любую клавишу..."
			  "\n");

	 getch();

// Создаем каталог

	 if(mkdir("a:\test_ctl")) {

		  printf("\nОшибка при создании каталога" );
		  exit(-1);

	 }
	 else {

		  printf("\nУспешное создание каталога");

// Удаляем только что созданный каталог

		  rmdir("a:test_ctl");
		  exit(0);

	 }
}


// Новый обработчик критических ошибок

void _far hhandler(unsigned deverr, unsigned doserr, unsigned _far *hdr) {

	 int ch;
	 static char buf[200], tmpbuf[10];

// Выводим сообщение о критической ошибке

	 sprintf(buf,"\n\r"
					 "\n\rКод ошибки устройтсва: %04.4X"
					 "\n\rКод ошибки DOS:        %d"
					 "\n\r\n\r"
					 "\n\rВыполняемые действия:"
					 "\n\r  0 - повторить"
					 "\n\r  1 - отменить"
					 "\n\r  2 - завершить"
					 "\n\r----> ?",
					 deverr,
					 doserr);

	 _bios_str(buf);

// Вводим ответ с клавиатуры

	 ch = _bios_keybrd(_KEYBRD_READ) & 0x00ff;
	 _bios_str("\n\r");

	 switch(ch) {

		  case '0':       // Пытаемся повторить операцию
		  default:

				_hardresume(_HARDERR_RETRY);

		  case '2':       // Завершаем работу программы

				_hardresume(_HARDERR_ABORT);

		  case '1':       // Возврат в DOS с кодом ошибки

				_hardretn(doserr);

	 }
}

// Программа для вывода строки символов на экран
// с помощью функции BIOS 0Eh

void _bios_str(char *ptr) {

	 union REGS inregs, outregs;
	 char *start = ptr;

	 inregs.h.ah = 0x0e;
	 for(; *ptr; ptr++) {

		  inregs.h.al = *ptr;
		  int86(0x10, &inregs, &outregs);

	 }
}

