logo search
несколько программ / bsp33

ПрограммаCallhma

Приведем текст программы, составленная на языке программирования Си, которая вызывает функции драйвера расширенной памяти. Эта программа будет работать только в моделях памяти Small и Compact. Для других моделей памяти требуется изменить строки интерфейсного модуля hma.asm, в которых передаваемые функциям параметры извлекаются из стека и тип процедур:

Аргументы

Small, Compact

Large, Huge

Первый аргумент

[bp+4]

[bp+6]

Второй аргумент

[bp+6]

[bp+8]

Текст программы CALLHMAвы найдете в листинге 11.2, а текст интерфейсного модуля - в листинге 11.3.

Листинг 11.2. Файлcallhma\callhma.c

// =====================================================

// Работа с драйвером HIMEM.SYS

//

// (C) Фролов А.В, 1997

//

// E-mail: frolov@glas.apc.org

// WWW: http://www.glasnet.ru/~frolov

// или

// http://www.dials.ccas.ru/frolov

// =====================================================

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <dos.h>

#include <string.h>

struct XMM_Move

{

unsigned long Length;

unsigned short SourceHandle;

unsigned long SourceOffset;

unsigned short DestHandle;

unsigned long DestOffset;

};

extern long XMM_Installed(void);

extern long XMM_Version(void);

extern long XMM_RequestHMA(unsigned);

extern long XMM_ReleaseHMA(void);

extern long XMM_GlobalEnableA20(void);

extern long XMM_GlobalDisableA20(void);

extern long XMM_EnableA20(void);

extern long XMM_DisableA20(void);

extern long XMM_QueryA20(void);

extern long XMM_QueryLargestFree(void);

extern long XMM_QueryTotalFree(void);

extern long XMM_AllocateExtended(unsigned);

extern long XMM_FreeExtended(unsigned);

extern long XMM_MoveExtended(struct XMM_Move *);

extern long XMM_LockExtended(unsigned);

extern long XMM_UnLockExtended(unsigned);

extern long XMM_GetHandleLength(unsigned);

extern long XMM_GetHandleInfo(unsigned);

extern long XMM_ReallocateExtended(unsigned, unsigned);

extern long XMM_RequestUMB(unsigned);

extern long XMM_ReleaseUMB(unsigned);

void error(char *msg, long rc);

int 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("\nHIMEM.SYS installed");

ver = XMM_Version();

printf("\nver XMM: %4X,%4x",

(short)ver, (short)(ver >> 16));

}

else

{

printf("\nHIMEM.SYS not found");

exit(-1);

}

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

rc = XMM_RequestHMA(0xffff);

if(rc)

error("Request HMA error",rc);

else

{

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

rc = XMM_GlobalEnableA20();

if(rc)

error("Open A20 error",rc);

// Копируем тестовое сообщение сначала из

// стандартной памяти в область HMA,

// затем обратно в стандартную память

FP_SEG(ptr) = 0xffff;

FP_OFF(ptr) = 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("Close A20 eror",rc);

rc = XMM_ReleaseHMA();

if(rc)

error("Free HMA error",rc);

}

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

handle = XMM_AllocateExtended(1);

if(handle < 0)

error("Request XMB error",handle);

// Копируем тестовое сообщение сначала из

// стандартной памяти в блок EMB,

// затем обратно в стандартную память

move_d.Length = strlen(testmsg) + 1;

move_d.SourceHandle = 0;

(char far*)move_d.SourceOffset = (char far*)testmsg;

move_d.DestHandle = (short)handle;

move_d.DestOffset = 0L;

rc = XMM_MoveExtended(&move_d);

if(rc < 0)

error("Copy in EMB error",rc);

move_d.Length = strlen(testmsg) + 1;

move_d.DestHandle = 0;

(char far*)move_d.DestOffset = (char far*)buf;

move_d.SourceHandle = (short)handle;

move_d.SourceOffset = 0L;

rc = XMM_MoveExtended(&move_d);

if(rc < 0)

error("Copy from EMB error",rc);

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

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

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

rc = XMM_FreeExtended((unsigned)handle);

if(rc)

error("Free XMB error",rc);

return 0;

}

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

// и кода ошибки

void error(char *msg, long rc)

{

rc = (unsigned char)(rc >> 24) ;

printf("\n%s, error: %02.2X\n",

msg, (unsigned char)rc);

exit(-1);

}

Листинг 11.3. Файлcallhma\hma.asm

; =====================================================

; Это интерфейсный модуль для вызова функций

; XMS из Си. Текст программы рассчитан на

; модель памяти Small

;

; (C) A. Frolov, 1997

;

; E-mail: frolov@glas.apc.org

; WWW: http://www.glasnet.ru/~frolov

; or

; http://www.dials.ccas.ru/frolov

; =====================================================

.model small

.DATA

; В этом месте будет храниться адрес

; управляющей функции XMM

XMM_Control dd ?

.CODE

; Макроопределения для выполнения соглашения об

; использовании регистров в процедурах Си

c_begin macro

push bp

mov bp,sp

push si

push di

endm

c_end macro

pop di

pop si

mov sp,bp

pop bp

ret

endm

; Все процедуры должны быть public

public _XMM_Installed

public _XMM_Version

public _XMM_RequestHMA

public _XMM_ReleaseHMA

public _XMM_GlobalEnableA20

public _XMM_GlobalDisableA20

public _XMM_EnableA20

public _XMM_DisableA20

public _XMM_QueryA20

public _XMM_QueryLargestFree

public _XMM_QueryTotalFree

public _XMM_AllocateExtended

public _XMM_FreeExtended

public _XMM_MoveExtended

public _XMM_LockExtended

public _XMM_UnLockExtended

public _XMM_GetHandleLength

public _XMM_GetHandleInfo

public _XMM_ReallocateExtended

public _XMM_RequestUMB

public _XMM_ReleaseUMB

;**

;.Name _XMM_Installed

;.Title Получение адреса управляющей функции

;

;.Descr Эта функция проверяет наличие драйвера

; HIMEM.SYS и в случае его присуствия

; запоминает адрес управляющей функции.

;

;.Proto unsigned XMM_Installed(void);

;

;.Params Не используются

;

;.Return 0 - драйвер HIMEM.SYS не установлен;

; 1 - драйвер HIMEM.SYS установлен.

;

;**

_XMM_Installed proc near

c_begin

mov ax, 4300h

int 2fh

cmp al, 80h

jne NotInstalled

mov ax, 4310h

int 2fh

mov word ptr [XMM_Control], bx

mov word ptr [XMM_Control+2], es

mov ax,1

jmp Installed

NotInstalled:

mov ax, 0

Installed:

c_end

_XMM_Installed endp

;**

;.Name _XMM_Version

;.Title Определение версии драйвера HIMEM.SYS

;

;.Descr Эта функция определяет версию драйвера

; HIMEM.SYS

;

;.Proto long XMM_Version(void);

;

;.Params Не используются

;

;.Return Номер версии в младших 16 битах,

; номер изменений - в старших 16 битах

; возвращаемого значения

;

;**

_XMM_Version proc near

push si

push di

xor ah, ah

call [XMM_Control]

mov dx, bx

pop di

pop si

ret

_XMM_Version endp

;**

;.Name _XMM_RequestHMA

;.Title Запросить область HMA

;

;.Descr Эта функция пытается зарезервировать для

; программы область HMA

;

;.Proto long XMM_RequestHMA(unsigned space);

;

;.Params space - размер требуемой области для

; TSR-программы или драйвера,

; 0xffff для прикладной программы;

;

;.Return < 0 - область HMA не назначена программе,

; код ошибки находится в старшем байте.

; 0L - область HMA назначена программе.

;

;**

_XMM_RequestHMA proc near

c_begin

mov ah, 1

mov dx, [bp+4]

call [XMM_Control]

xor dx, dx

dec ax

jz @success

mov dh, bl

@success:

c_end

_XMM_RequestHMA endp

;**

;.Name _XMM_ReleaseHMA

;.Title Освободить область HMA

;

;.Descr Эта функция пытается освободить

; область HMA

;

;.Proto long XMM_ReleaseHMA(void);

;

;.Params Не используются

;

;.Return < 0 - область HMA не освобождена,

; код ошибки находится в старшем байте.

; 0L - область HMA освобождена.

;

;**

_XMM_ReleaseHMA proc near

c_begin

mov ah, 2

call [XMM_Control]

xor dx, dx

dec ax

jz @success1

mov dh, bl

@success1:

c_end

_XMM_ReleaseHMA endp

;**

;.Name _XMM_GlobalEnableA20

;.Title Глобальное разрешение линии A20

;

;.Descr Эта функция разрешает программе, получившей

; доступ к области HMA использовать линию A20

;

;.Proto long XMM_GlobalEnableA20(void);

;

;.Params Не используются

;

;.Return < 0 - линия A20 не включена,

; код ошибки находится в старшем байте.

; 0L - линия A20 включена.

;

;**

_XMM_GlobalEnableA20 proc near

c_begin

mov ah, 3

call [XMM_Control]

xor dx, dx

dec ax

jz @success2

mov dh, bl

@success2:

c_end

_XMM_GlobalEnableA20 endp

;**

;.Name _XMM_GlobalDisableA20

;.Title Глобальное запрещение линии A20

;

;.Descr Эта функция запрещает программе, получившей

; доступ к области HMA использовать линию A20

;

;.Proto long XMM_GlobalDisableA20(void);

;

;.Params Не используются

;

;.Return < 0 - линия A20 не выключена,

; код ошибки находится в старшем байте.

; 0L - линия A20 выключена.

;

;**

_XMM_GlobalDisableA20 proc near

c_begin

mov ah, 4

call [XMM_Control]

xor dx, dx

dec ax

jz @success3

mov dh, bl

@success3:

c_end

_XMM_GlobalDisableA20 endp

;**

;.Name _XMM_EnableA20

;.Title Локальное разрешение линии A20

;

;.Descr Эта функция разрешает программе управлять

; областью расширенной памяти.

;

;.Proto long XMM_EnableA20(void);

;

;.Params Не используются

;

;.Return < 0 - линия A20 не включена,

; код ошибки находится в старшем байте.

; 0L - линия A20 включена.

;

;**

_XMM_EnableA20 proc near

c_begin

mov ah, 5

call [XMM_Control]

xor dx, dx

dec ax

jz @success4

mov dh, bl

@success4:

c_end

_XMM_EnableA20 endp

;**

;.Name _XMM_DisableA20

;.Title Локальное запрещение линии A20

;

;.Descr Эта функция запрещает программе управлять

; областью расширенной памяти.

;

;.Proto long XMM_DisableA20(void);

;

;.Params Не используются

;

;.Return < 0 - линия A20 не выключена,

; код ошибки находится в старшем байте.

; 0L - линия A20 выключена.

;

;**

_XMM_DisableA20 proc near

c_begin

mov ah, 6

call [XMM_Control]

xor dx, dx

dec ax

jz @success5

mov dh, bl

@success5:

c_end

_XMM_DisableA20 endp

;**

;.Name _XMM_QueryA20

;.Title Проверить состояние линии A20

;

;.Descr Эта функция проверяет доступность

; линии A20

;

;.Proto long XMM_QueryA20(void);

;

;.Params Не используются

;

;.Return < 0 - ошибка,

; код ошибки находится в старшем байте.

; 0L - линия A20 выключена,

; 1L - линия A20 включена.

;

;**

_XMM_QueryA20 proc near

c_begin

mov ah, 7

call [XMM_Control]

xor dx, dx

or ax, ax

jnz @success6

mov dh, bl

@success6:

c_end

_XMM_QueryA20 endp

;**

;.Name _XMM_QueryLargestFree

;.Title Определить максимальный размер блока

;

;.Descr Эта функция возвращает размер максимального

; непрерывного блока расширенной памяти,

; который доступен программе.

;

;.Proto long XMM_QueryLargestFree(void);

;

;.Params Не используются

;

;.Return < 0 - ошибка,

; код ошибки находится в старшем байте.

; >= 0 - размер блока.

;

;**

_XMM_QueryLargestFree proc near

c_begin

mov ah, 8

call [XMM_Control]

xor dx, dx

or ax, ax

jnz @success7

mov dh, bl

@success7:

c_end

_XMM_QueryLargestFree endp

;**

;.Name _XMM_QueryTotalFree

;.Title Определить размер расширенной памяти

;

;.Descr Эта функция возвращает размер

; всей имеющейся расширенной памяти.

;

;.Proto long XMM_QueryTotalFree(void);

;

;.Params Не используются

;

;.Return < 0 - ошибка,

; код ошибки находится в старшем байте.

; >= 0 - размер расширенной памяти.

;

;**

_XMM_QueryTotalFree proc near

c_begin

mov ah, 8

call [XMM_Control]

or ax, ax

mov ax, dx

mov dx, 0

jnz @success8

mov dh, bl

@success8:

c_end

_XMM_QueryTotalFree endp

;**

;.Name _XMM_AllocateExtended

;.Title Запросить блок расширенной памяти

;

;.Descr Эта функция выделяет программе блок

; расширенной памяти, в случае успеха

; возвращает индекс полученного блока.

;

;.Proto long XMM_AllocateExtended(unsigned space);

;

;.Params space - размер требуемого блока памяти

; в килобайтах;

;

;.Return < 0 - блок не распределен,

; код ошибки находится в старшем байте.

; > 0L - младший байт содержит индекс

; полученного блока памяти.

;

;**

_XMM_AllocateExtended proc near

c_begin

mov ah, 9

mov dx, [bp+4]

call [XMM_Control]

or ax, ax

mov ax, dx

mov dx, 0

jnz @success9

mov dh, bl

@success9:

c_end

_XMM_AllocateExtended endp

;**

;.Name _XMM_FreeExtended

;.Title Освободить блок расширенной памяти

;

;.Descr Эта функция освобождает блок

; расширенной памяти, полученный функцией

; XMM_AllocateExtended().

;

;.Proto long XMM_FreeExtended(unsigned handle);

;

;.Params handle - индекс освобождаемого блока памяти;

;

;.Return < 0 - блок не распределен,

; код ошибки находится в старшем байте.

; 0L - блок освобожден.

;

;**

_XMM_FreeExtended proc near

c_begin

mov ah, 0Ah

mov dx, [bp+4]

call [XMM_Control]

xor dx, dx

dec ax

jz @successA

mov dh, bl

@successA:

c_end

_XMM_FreeExtended endp

;**

;.Name _XMM_MoveExtended

;.Title Копировать блок расширенной памяти

;

;.Descr Эта функция копирует блок

; расширенной памяти, используя структуру

; struct XMM_Move:

;

; struct XMM_Move {

; unsigned long Length;

; unsigned short SourceHandle;

; unsigned long SourceOffset;

; unsigned short DestHandle;

; unsigned long DestOffset;

; };

;

;.Proto long XMM_MoveExtended(struct

; XMM_Move *move_descr);

;

;.Params struct XMM_Move *move_descr -

; указатель на структуру, описывающую

; что, откуда и куда надо копировать.

;

;.Return < 0 - ошибка при копировании,

; код ошибки находится в старшем байте.

; 0L - блок скопирован успешно.

;

;**

_XMM_MoveExtended proc near

c_begin

mov ah, 0Bh

mov si, [bp+4];

call [XMM_Control]

xor dx, dx

dec ax

jz @successB

mov dh, bl

@successB:

c_end

_XMM_MoveExtended endp

;**

;.Name _XMM_LockExtended

;.Title Заблокировать блок расширенной памяти

;

;.Descr Эта функция блокирует блок расширенной

; памяти и возвращает 31 разряд его

; физического адреса.

;

;.Proto long XMM_LockExtended(unsigned handle);

;

;.Params handle - индекс блокируемого блока памяти;

;

;.Return < 0 - блок не заблокирован,

; код ошибки находится в старшем байте.

; > 0L - блок заблокирован, функция

; возвращает физический адрес блока

; памяти.

;

;**

_XMM_LockExtended proc near

c_begin

mov ah, 0Ch

mov dx, [bp+4]

call [XMM_Control]

xchg ax, bx

dec bx

jz XMML_Success

mov dh, al

XMML_Success:

c_end

_XMM_LockExtended endp

;**

;.Name _XMM_UnLockExtended

;.Title Разблокировать блок расширенной памяти

;

;.Descr Эта функция разблокирует блок расширенной

; памяти.

;

;.Proto long XMM_UnLockExtended(unsigned handle);

;

;.Params handle - индекс блока памяти;

;

;.Return < 0 - блок не разблокирован,

; код ошибки находится в старшем байте.

; 0L - блок разблокирован.

;

;**

_XMM_UnLockExtended proc near

c_begin

mov ah, 0Dh

mov dx, [bp+4]

call [XMM_Control]

xor dx, dx

dec ax

jz @successC

mov dh, bl

@successC:

c_end

_XMM_UnLockExtended endp

;**

;.Name _XMM_GetHandleLength

;.Title Получить длину блока расширенной памяти

;

;.Descr Эта функция возвращает длину блока

; расширенной памяти по его индексу.

;

;.Proto long XMM_GetHandleLength(unsigned handle);

;

;.Params handle - индекс блока памяти;

;

;.Return < 0 - произошла ошибка,

; код ошибки находится в старшем байте.

; > 0L - длина блока в килобайтах.

;

;**

_XMM_GetHandleLength proc near

c_begin

mov ah, 0Eh

mov dx, [bp+4]

call [XMM_Control]

or ax, ax

mov ax, dx

mov dx, 0

jnz @successD

mov dh, bl

@successD:

c_end

_XMM_GetHandleLength endp

;**

;.Name _XMM_GetHandleInfo

;.Title Получить информацию о блоке расширенной памяти

;

;.Descr Эта функция возвращает общее

; количество индексов в системе и

; содержимое счетчика блокирования для

; заданного индекса.

;

;.Proto long XMM_GetHandleInfo(unsigned handle);

;

;.Params handle - индекс блока памяти;

;

;.Return < 0 - произошла ошибка,

; код ошибки находится в старшем байте.

; > 0L - младший байт - общее количество

; индексов в системе;

; старший байт - счетчик блокирования.

;

;**

_XMM_GetHandleInfo proc near

c_begin

mov ah, 0Eh

mov dx, [bp+4]

call [XMM_Control]

mov dx, bx

or ax, ax

mov ax, dx

mov dx, 0

jnz @successE

mov dh, bl

@successE:

c_end

_XMM_GetHandleInfo endp

;**

;.Name _XMM_ReallocateExtended

;.Title Изменить размер блока расширенной памяти

;

;.Descr Эта функция изменяет размер выделенного

; блока расширенной памяти.

;

;.Proto long XMM_ReallocateExtended(unsigned handle,

; unsigned new_size);

;

;.Params handle - индекс блока памяти;

; new_size - новый размер блока памяти

; в килобайтах;

;

;.Return < 0 - блок не распределен,

; код ошибки находится в старшем байте.

; > 0L - младший байт содержит индекс

; полученного блока памяти.

;

;**

_XMM_ReallocateExtended proc near

c_begin

mov ah, 0Fh

mov dx, [bp+4]

mov bx, [bp+6]

call [XMM_Control]

xor dx, dx

dec ax

jz @successF

mov dh, bl

@successF:

c_end

_XMM_ReallocateExtended endp

;**

;.Name _XMM_RequestUMB

;.Title Запросить область UMB

;

;.Descr Эта функция пытается зарезервировать для

; программы область UMB

;

;.Proto long XMM_RequestUMB(unsigned space);

;

;.Params space - размер требуемой области

; в параграфах;

;

;.Return < 0 - область UMB не назначена программе,

; код ошибки находится в старшем байте;

; максимальный размер доступного блока

; в младшем слове (16 разрядов);

; > 0L - область UMB назначена программе,

; младшее слово содержит сегмент блока

; UMB, старший - размер выделенного

; блока UMB.

;

;**

_XMM_RequestUMB proc near

c_begin

mov ah, 10h

mov dx, [bp+4]

call [XMM_Control]

xchg bx, ax

dec bx

jz RUMB_Success

xchg ax, dx

mov dh, dl

RUMB_Success:

c_end

_XMM_RequestUMB endp

;**

;.Name _XMM_ReleaseUMB

;.Title Освободить область UMB

;

;.Descr Эта функция пытается освободить

; область UMB

;

;.Proto long XMM_ReleaseUMB(unsigned segment);

;

;.Params segment - сегмент освобождаемого блока UMB*

;

;.Return < 0 - область UMB не освобождена,

; код ошибки находится в старшем байте.

; 0L - область UMB освобождена.

;

;**

_XMM_ReleaseUMB proc near

c_begin

mov ah, 11h

mov dx, [bp+4]

call [XMM_Control]

xor dx, dx

dec ax

jz @success10

mov dh, bl

@success10:

c_end

_XMM_ReleaseUMB endp

END