Кафедра МОП ЭВМ Драйвер управления расширенной памятью HIMEM,SYS, страница 17

printf("5.25\"");

else

printf("3.5\"");

printf(" имеет емкость ");

if (capacity < 1024)

printf("%g Кб.\n", float(capacity));

else

printf("%g Мб.\n", float(capacity) / 1000);

printf("Наибольший свободный блок расширенной памяти "

"имеет размер ");

if (maxblk < 1024)

printf("%g Кб.\n", float(maxblk));

else

printf("%g Мб.\n", float(maxblk) / 1000);

if (capacity > maxblk)

fail("Копирование невозможно.");

// выделение памяти

dinfo.buffer = (void far *)malloc(tr_size);

if (!dinfo.buffer)

fail("Недостаточно стандартной памяти");

CMA_allocated = true;

ret = XMM_EnableA20();

if (!ret)  ErrMsg("Ошибка при включении линии A20: ");

A20_enabled = true;

ret = XMM_AllocMem(capacity, &handle);

if (!ret)  ErrMsg("Ошибка при выделении XMS-памяти: ");

XMA_allocated = true;

// чтение дискеты

printf("Идет чтение дискеты... ");

xpos = wherex(), ypos = wherey();

count = 0;

dinfo.sector = 1;  dinfo.nsectors = sectors;

for (word head = 0; head < heads; head++)

{

dinfo.head = head;

for (word track = 0; track < tracks; track++)

{

dinfo.track = track;

ret = _bios_disk(_DISK_READ, &dinfo);

if (HIBYTE(ret))

fail("\nОшибка чтения");

gotoxy(xpos, ypos);

printf("%d%%", int(count * 100 / (tracks * heads - 1)));

ret = XMM_MoveToXMA((void near *)dinfo.buffer, handle,

tr_size * count, tr_size);

if (!ret)  ErrMsg("\nОшибка при записи в XMS-память: ");

count++;

}

}

puts("");

// запись дискеты

do

{

printf("Вставьте вторую дискету в дисковод %c: "

"и нажмите любую клавишу...\n", disk);

bioskey(0);

err = abswrite(dinfo.drive, 1, 0, (void *)BPB);

if (err)

if (LOBYTE(errno) == 2)

puts("Устройство не готово.");

else if (LOBYTE(errno) == 0)

puts("Дискета защищена от записи.");

else

fail("Неизвестная ошибка");

} while (err);

printf("Идет запись дискеты... ");

xpos = wherex(), ypos = wherey();

count = 0;

dinfo.sector = 1;  dinfo.nsectors = sectors;

for (word head = 0; head < heads; head++)

{

dinfo.head = head;

for (word track = 0; track < tracks; track++)

{

dinfo.track = track;

ret = XMM_MoveToCMA((void near *)dinfo.buffer, handle,

tr_size * count, tr_size);

if (!ret)  ErrMsg("\nОшибка при чтении из XMS-памяти: ");

ret = _bios_disk(_DISK_WRITE, &dinfo);

if (HIBYTE(ret))

fail("\nОшибка записи");

gotoxy(xpos, ypos);

printf("%d%%", int(count * 100 / (tracks * heads - 1)));

count++;

}

}

puts("\nДискета скопирована");

// освобождение памяти

FreeMemory();

}

void ErrMsg(const char *msg)

{

printf(msg);

switch (err_code)

{

case 0x80:

fail("данная служба не поддерживается");

break;

case 0x82:

fail("сбой линии A20");

break;

case 0xA0:

fail("вся расширенная память использована");

break;

case 0xA1:

fail("свободные дескрипторы отсутствуют");

break;

case 0xA2:

fail("неверный дескриптор блока");

break;

case 0xA3:

fail("неверный дескриптор источника");

break;

case 0xA4:

fail("неверное смещение источника");

break;

case 0xA5:

fail("неверный дескриптор адреса назначения");

break;

case 0xA6:

fail("неверное смещение адреса назначения");

break;

case 0xA7:

fail("неверная длина блока");

break;

default:

printf("Ошибка номер %02xh", int(err_code));

fail("");

}

}

void fail(const char *s)

{

puts(s);

FreeMemory();

exit(1);

}

void FreeMemory()

{

if (CMA_allocated)

{

CMA_allocated = false;

free((void near *)dinfo.buffer);

}

if (XMA_allocated)

{

XMA_allocated = false;

ret = XMM_FreeMem(handle);

if (!ret)  ErrMsg("Ошибка при освобождении XMS-памяти: ");

}

if (A20_enabled)

{

A20_enabled = false;

ret = XMM_DisableA20();