к содержанию

9.8. Утилита MEMOSCOP

Для определения активных интерфейсов с защищённым режимом можно использовать предлагаемую утилиту MEMOSCOP. Эта утилита проверяет присутствие всех уровней поддержки программ, работающих в защищённом режиме или с расширенной памятью - от BIOS до DPMI.

*MEMOSCOP*, © Frolov A.V., 1992
--------------------------------------------------------
Файл memoscop.c

#include <stdio.h>
#include <stdlib.h>
#include <dos.h>

void main(void) {

        extern int getcpu(void);
        unsigned cpu_type, ver;
        unsigned err;
        char ver_hi, ver_lo, verems;
        unsigned hostdata_seg, hostdata_size, dpmi_flags;
        void (far *pm_entry)();

        union REGS regs;
        struct SREGS segregs;


        printf("\n*MemoScop* v 1.0, © Frolov A.V., 1992\n"
                 "---------------------------------------\n");

// Определяем тип центрального процессора. Если программа
// работает на процессоре i8086, завершаем выполнение,
// так как в этом случае интерфейсы с защищенным режимом
// недоступны.

        printf("Тип процессора: 80%d\n", (cpu_type = getcpu()));
        if(cpu_type == 86) {
                printf("\nНа этом процессоре нам работать не интересно...");
                exit(0);
        }

// Определяем размер доступной через прерывание INT 15h
// расширенной памяти.

        printf("\n------------------------ Уровень BIOS -------------------------\n");

        regs.h.ah = 0x88;
        int86(0x15, &regs, &regs);
        printf("Размер расширенной памяти, доступной через INT 15:"
        " \t%d Кбайт\n", regs.x.ax);

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

        printf("\n------------------------ Уровень XMM --------------------------\n");


        if (XMM_Installed()) {
                printf("Установлен драйвер HIMEM.SYS");
                ver = XMM_Version();
                printf(", версия: %4X, изменения: %4X\n",
                        (short)ver, (short)(ver >> 16));
                printf("Размер свободной расширенной памяти, доступной через XMM:"
                                         " %ld Кбайт\n", (long)XMM_QueryLargestFree());
                printf("Общий размер расширенной памяти, доступной через XMM:"
                                         " \t  %ld Кбайт\n", (long)XMM_QueryTotalFree());

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


        printf("\n------------------------ Уровень EMS/VCPI ----------------------\n");

// Проверяем наличие драйвера EMS/VCPI

        if(ems_init()) printf("Драйвер EMS/VCPI не загружен\n");
        else {
                printf("Драйвер EMS/VCPI загружен, ");

// Выводим номер версии драйвера

                if((err = ems_ver(&verems)) != 0) {
                        printf("\nОшибка %02.2X при определении версии EMM", err);
                        exit(-1);
                }
                printf("версия EMM: %02.2X", verems);

// Определяем присутствие VCPI и его версию

                if(vcpi_ver(&ver_hi, &ver_lo) != 0) {
                        printf("\nДрайвер EMM не поддерживает VCPI\n");
                        exit(-1);
                }
                printf("\nВерсия VCPI: %02.2X.%02.2X\n", ver_hi, ver_lo);
        }


        printf("\n------------------------ Уровень DPMI --------------------------");


// Проверяем доступность и параметры сервера DPMI

        regs.x.ax = 0x1687;
        int86x(0x2F, &regs, &regs, &segregs);
        if(regs.x.ax != 0) {
                printf("\nСервер DPMI не активен"); exit(-1);
        }

// Определяем версию сервера DPMI

        printf("\nВерсия сервера DPMI: \t\t\t%d.%d\n",
                regs.h.dh, regs.h.dl);

// Определяем тип процессора

        printf("Тип процессора:\t\t\t\t");
        if(regs.h.cl == 2) printf("80286");
        else if(regs.h.cl == 3) printf("80386");
        else if(regs.h.cl == 4) printf("80486");

// Определяем возможность работы с 32-разрядными
// программами

        dpmi_flags = regs.x.bx;
        printf("\nПоддержка 32-разрядных программ:\t");
        if(dpmi_flags && 1) printf("ПРИСУТСТВУЕТ");
        else printf("ОТСУТСТВУЕТ");

// Определяем размер области памяти для сервера DPMI

        hostdata_size = regs.x.si;
        printf("\nРазмер памяти для сервера DPMI:\t\t%d байт",
                hostdata_size * 16);

// Определяем адрес точки входа в защищённый режим

        FP_SEG(pm_entry) = segregs.es;
        FP_OFF(pm_entry) = regs.x.di;
        printf("\nАдрес точки входа в защищённый режим: \t%Fp\n",
                pm_entry);

        getch();

}

/**
*.Name         ems_init
*.Title        Функция проверяет установку драйвера EMS
*
*.Descr        Эта функция проверяет наличие драйвера EMS
*
*.Proto        int ems_init(void);
*
*.Params       Не используются
*
*.Return       0 - драйвер EMS установлен;
*              1 - драйвер EMS не установлен.
*
*.Sample       ems_test.c
**/

int ems_init(void) {

        void (_interrupt _far *EMS_driver_adr)(void);
        char _far *EMS_driver_name;
        char test_name[8];
        int i;

        EMS_driver_adr = _dos_getvect(0x67);

        FP_SEG(EMS_driver_name) = FP_SEG (EMS_driver_adr);
        FP_OFF(EMS_driver_name) = 10;

        for(i=0; i<8; i++) test_name[i] = EMS_driver_name[i];

        if(strncmp(test_name, "EMMXXXX0", 8) == 0) return(0);
        else return(1);

}

/**
*.Name         ems_ver
*.Title        Определение версии драйвера EMS
*
*.Descr        Эта функция возвращает номер версии
*              драйвера EMS в двоично-десятичном формате.
*
*.Proto        int ems_ver(char *ver);
*
*.Params       char *ver - указатель на байт, в который
*                 будет записан номер версии.
*
*.Return       Номер версии драйвера EMS в формате BCD
*
*.Sample       ems_test.c
**/

int ems_ver(char *ver) {

        union REGS reg;

        reg.x.ax = 0x4600;
        int86(0x67, &reg, &reg);

        *ver = reg.h.al;
        return(reg.h.ah);
}

int vcpi_ver(char *ver_hi, char *ver_lo) {

        union REGS reg;

        reg.x.ax = 0xDE00;
        int86(0x67, &reg, &reg);

        *ver_hi = reg.h.bh;
        *ver_lo = reg.h.bl;
        return(reg.h.ah);
}




Исходные тексты функций, вызываемых утилитой MEMOSCOP приведены ниже:

*MEMOSCOP*, © Frolov A.V., 1992
--------------------------------------------------------
Файл cpu.asm


DEAL

MODEL SMALL

P386

PUBLIC  _getcpu

CODESEG

PROC    _getcpu  NEAR

; --------------------------------------------------------
; Пытаемся установить старшую тетраду регистра флагов в 0.
; Если программа работает на процессоре 8086, в этом
; байте все биты будут установлены в 1
; --------------------------------------------------------

        mov     dx, 86      ; Тип процессора - 8086

        pushf
        pop     bx
        and     bh,0Fh
        push    bx
        popf
        pushf
        pop     ax
        and     ah,0F0h
        cmp     ah,0F0h
        je      cpu_end

; --------------------------------------------------------
; Для теста на процессор 80286 пытаемся установить старшую
; тетраду регистра флагов в единицы. Если программа
; выполняется на процессоре 80286, эти биты останутся
; равными нулю
; --------------------------------------------------------

        mov     dx, 286             ; Тип процессора - 80286

        or      bh,0F0h
        push    bx
        popf
        pushf
        pop     ax
        test    ah,0F0h
        jz      cpu_end

; --------------------------------------------------------
; Для того, чтобы отличить процессор 80386 от процессора
; 80486, используем бит 18 регистра флагов EFLAGS.
; Если программа может изменить состояние этого бита,
; она выполняется на процессоре 80486. В противном случае
; используется процессор 80386.
; --------------------------------------------------------

; Созраняем указатель стека

        mov     edx,esp

; Выравниваем указатель стека для предотвращения
; исключения при установке флага AC

        and     esp,not 3

; Копируем регистр EFLAGS в регистр EAX

        pushfd
        pop     eax

; Сохраняем начальное значение регистра EFLAGS

        mov     ecx,eax

; Переключаем флаг AC

        xor     eax,40000H

; Пытаемся записать измененное значение обратно в регистр
; EFLAGS

        push     eax
        popfd

; Копируем регистр EFLAGS в регисрр EAX

        pushfd
        pop     eax

; Сравниваем старое и новое значения бита AC

        xor     eax,ecx
        shr     eax,18
        and     eax,1
        push    ecx

; Восстанавливаем регситр EFLAGS

        popfd

; Восстанавливаем указатель стека

        mov     esp,edx

; Теперь если программа выполняется на процессоре 80386,
; регистр AX содержит значение 0, а если на процессоре
; 80486 - значение 1.

        mov     dx,386              ; Тип процессора - 80386

        test    ax,ax
        jz      cpu_end

        mov     ax,486              ; Тип процессора - 80486

cpu_end:
        mov     ax, dx
        ret
ENDP    _getcpu

END




Для работы с функциями драйвера HIMEM.SYS используется интерфейс, описанный нами в томе 2 "Библиотеки системного программсита":

*MEMOSCOP*, © Frolov A.V., 1992
--------------------------------------------------------
Файл xmmc.asm


; Это интерфейсный модуль для вызова функций
; XMS из Си. Текст программы рассчитан на
; модель памяти Small.

          .model small,c
          .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 установлен.
;
;.Sample       xms_test.c
;**

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 битах
;              возвращаемого значения
;
;.Sample       xms_test.c
;**

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 назначена программе.
;
;.Sample       xms_test.c
;**

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 освобождена.
;
;.Sample       xms_test.c
;**

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 включена.
;
;.Sample       xms_test.c
;**

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 выключена.
;
;.Sample       xms_test.c
;**

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 включена.
;
;.Sample       xms_test.c
;**

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 выключена.
;
;.Sample       xms_test.c
;**

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 включена.
;
;.Sample       xms_test.c
;**

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 - размер блока.
;
;.Sample       xms_test.c
;**

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 - размер расширенной памяти.
;
;.Sample       xms_test.c
;**

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  - младший байт содержит индекс
;                      полученного блока памяти.
;
;.Sample       xms_test.c
;**


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  - блок освобожден.
;
;.Sample       xms_test.c
;**

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  - блок скопирован успешно.
;
;.Sample       xms_test.c
;**

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  - блок заблокирован, функция
;                      возвращает физический адрес блока
;                      памяти.
;
;.Sample       xms_test.c
;**

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  - блок разблокирован.
;
;.Sample       xms_test.c
;**

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  - длина блока в килобайтах.
;
;.Sample       xms_test.c
;**

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  - младший байт - общее количество
;                      индексов в системе;
;                      старший байт - счетчик блокирования.
;
;.Sample       xms_test.c
;**

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  - младший байт содержит индекс
;                      полученного блока памяти.
;
;.Sample       xms_test.c
;**

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.
;
;.Sample       xms_test.c
;**

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 освобождена.
;
;.Sample       xms_test.c
;**

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




к содержанию
Hosted by uCoz