#include <stdio.h>
#include <conio.h>
#include "sysp.h"

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

	long ver, rc, handle;
	static char testmsg[] = "Тестовое сообщение";
	char buf[80];
	char far *ptr;
	int i;
	struct XMM_Move move_d;

// Проверяем, установлен ли драйвер HIMEM.SYS,
// если установлен, выводим его версию.

	if (XMM_Installed()) {
		printf("\nДрайвер HIMEM.SYS установлен.");
		ver = XMM_Version();
		printf("\nВерсия XMM: %4X, изменения: %4x",
			(short)ver, (short)(ver >> 16));
	}

	else {
		printf("\nДрайвер HIMEM.SYS не установлен.");
		exit(-1);
	}

// Запрашиваем управление областью HMA.

	rc = XMM_RequestHMA(0xffff);
	if(rc) error("Ошибка при запросе области HMA",rc);

	else {

// Открываем линию A20.

		rc = XMM_GlobalEnableA20();
		if(rc) error("Ошибка при разрешении линии A20",rc);

// Копируем тестовое сообщение сначала из
// стандартной памяти в область HMA,
// затем обратно в стандартную память.

		ptr = FP_MAKE(0xffff,0x0010);

		for(i=0; testmsg[i] != 0; i++)
			ptr[i] = testmsg[i];

		for(i=0; ptr[i] != 0; i++)
			buf[i] = ptr[i];
		buf[i] = 0;

// Выводим сообщение для проверки.

		printf("\n%s",buf);

// Закрываем линию A20 и отдаем системе область HMA.

		rc = XMM_GlobalDisableA20();
		if(rc) error("Ошибка при запрещении линии A20",rc);

		rc = XMM_ReleaseHMA();
		if(rc) error("Ошибка при освобождении области HMA",rc);
	}

// Получаем блок EMB размером в 1 килобайт.

	handle = XMM_AllocateExtended(1);
	if(handle < 0) error("Ошибка при запросе XMB",handle);

// Копируем тестовое сообщение сначала из
// стандартной памяти в блок EMB,
// затем обратно в стандартную память.

	move_d.Length = strlen(testmsg) + 1;
	move_d.SourceHandle = 0;
	(char far*)move_d.SourceOffset = (char far*)testmsg;
	move_d.DestHandle = handle;
	move_d.DestOffset = 0L;

	rc = XMM_MoveExtended(&move_d);
	if(rc < 0) error("Ошибка при копировании в EMB",rc);

	move_d.Length = strlen(testmsg) + 1;
	move_d.DestHandle = 0;
	(char far*)move_d.DestOffset = (char far*)buf;
	move_d.SourceHandle = handle;
	move_d.SourceOffset = 0L;

	rc = XMM_MoveExtended(&move_d);
	if(rc < 0) error("Ошибка при копировании из EMB",rc);

// Выводим сообщение для проверки.

	printf("\n%s",buf);

// Освобождаем блок EMB.

	rc = XMM_FreeExtended(handle);
	if(rc) error("Ошибка при освобождении XMB",rc);

	exit(0);
}

// Функция для вывода сообщения об ошибке
// и кода ошибки.

int error(char *msg, long rc) {

	rc = (unsigned char)(rc >> 24) ;
	printf("\n%s, код ошибки: %02.2X\n",
		msg, (unsigned char)rc);

}
