#include <dos.h>
#include <stdio.h>
#include <malloc.h>
#include <errno.h>
#include "sysp.h"

void main(void);
void main(void) {

	 union REGS reg;
	 struct SREGS segreg;
	 DPB _far *dbp;
	 DPB_FORMAT _far *dbp_f;

	 int sectors, i;

	 printf("\nПрограмма уничтожит содержимое"
			  "\n20-й дорожки диска А:."
			  "\nЖелаете продолжить? (Y,N)\n");

// Ожидаем ответ оператора и анализируем его

	 i = getch();
	 if((i != 'y') && (i != 'Y')) exit(-1);

// Заказываем память для блока параметров устройства

	 dbp = _fmalloc(sizeof(DPB));

// Заказываем память для блока параметров устройства,
// который будет использован для форматирования

	 dbp_f = _fmalloc(sizeof(DPB_FORMAT));

	 if(dbp == NULL || dbp_f == NULL) {
		printf("\nМало оперативной памяти!");
		exit(-1);
	 }

// Получаем текущие параметры диска А:

	 dbp->spec = 0;

// Вызываем подфункцию 0Dh для выполнения
// операции чтения текущих параметров диска А:

	 reg.x.ax = 0x440d;
	 reg.h.bl = 1;
	 reg.x.cx = 0x0860;
	 reg.x.dx =  FP_OFF(dbp);
	 segreg.ds = FP_SEG(dbp);

	 intdosx(&reg, &reg, &segreg);

// Проверяем флаг переноса

	 if(reg.x.cflag != 0) {
		printf("\nОшибка: %d",reg.x.ax);
		exit(-1);
	 }

// Заполняем блок парметров для форматирования.
// Байт специальных функций содержит значение,
// равное 5. Это означает, что:
//    - используется текущий блок параметров BIOS BPB;
//    - используются все поля в блоке парметров устройства;
//    - все сектора на дорожке имеют одинаковый размер

	 dbp->spec = 5;

// Считываем из BPB количество секторов на дорожке

	 sectors = dbp->bpb.seccnt;

// Подготавливаем таблицу, описывающую формат дорожки

// Записываем количество секторов на дорожке

	 dbp->trkcnt = sectors;

// Для каждого сектора на дорожке в таблицу
// записываем его номер и размер.
// Заметьте, что записывается размер сектора
// в байтах, а не код размера, как это делается
// при форматировании с помощью функции 05h прерывания INT13h

	 for(i = 0; i < sectors; i++) {
		dbp->trk[i].no   = i+1;
		dbp->trk[i].size = 512;
	 }

// Устанавливаем новые параметры для диска А:

	 reg.x.ax = 0x440d;
	 reg.h.bl = 1;
	 reg.x.cx = 0x0840;
	 reg.x.dx =  FP_OFF(dbp);
	 segreg.ds = FP_SEG(dbp);

	 intdosx(&reg, &reg, &segreg);

// Проверяем флаг переноса

	 if(reg.x.cflag != 0) {
		printf("\nОшибка: %d",reg.x.ax);
		exit(-1);
	 }

// Подготавливаем блок параметров устройства,
// который будет использован при вызове
// операции проверки возможности форматирования
// дорожки

// В поле специальных функций записываем 1,
// это означает, что будет выполняться проверка
// возможности использования указанного формата дорожки

	 dbp_f->spec = 1;
	 dbp_f->head = 0;
	 dbp_f->track = 20;

	 reg.x.ax = 0x440d;
	 reg.h.bl = 1;
	 reg.x.cx = 0x0842;
	 reg.x.dx =  FP_OFF(dbp_f);
	 segreg.ds = FP_SEG(dbp_f);

	 intdosx(&reg, &reg, &segreg);

// Проверяем флаг переноса

	 if(reg.x.cflag != 0) {
		printf("\nОшибка: %d",reg.x.ax);
		exit(-1);
	 }

// Если указанный формат дорожки поддерживается,
// поле специальных функций будет содержать 0.
// Проверяем это.

	 if(dbp_f->spec != 0) {
		printf("\nФормат дорожки не поддерживается!");
		exit(-1);
	 }

// Заполняем блок параметров для выполнения
// операции форматирования

	 dbp_f->spec = 0;
	 dbp_f->head = 0;
	 dbp_f->track = 20;

// Форматируем дорожку с номером 20, головка 0

	 reg.x.ax = 0x440d;
	 reg.h.bl = 1;
	 reg.x.cx = 0x0842;
	 reg.x.dx =  FP_OFF(dbp_f);
	 segreg.ds = FP_SEG(dbp_f);

	 intdosx(&reg, &reg, &segreg);

// Проверяем флаг переноса

	 if(reg.x.cflag != 0) {
		printf("\nОшибка: %d",reg.x.ax);
		exit(-1);
	 }

// Освобождаем буфера

	 _ffree(dbp);
	 _ffree(dbp_f);

	 exit(0);
}

