Аппаратное обеспечение IBM PC

Примеры программ


Первая программа демонстрирует проверку подключения драйвера и использование его основных функций:

include sysp.inc

.MODEL tiny DOSSEG

.STACK 100h

.DATA

msg DB 13,10,"Работа с драйвером HIMEM.SYS", 13, 10 DB "Copyright ©Frolov A.,1991",13,10,13,10 DB "$"

noHMM DB 13,10 DB "Драйвер HIMEM.SYS не установлен",13,10,"$" yesHMM DB 13,10,"Драйвер HIMEM.SYS установлен, ", "$" ver1 DB "версия: ", "$" ver2 DB ", номер модификации: ", "$" errmsg DB 13,10,"Ошибка с кодом ", "$" okmsg DB 13,10,"Успех!!!", "$" hmareq DB 13,10,"Запрашиваем область HMA", "$" hmarel DB 13,10,"Освобождаем область HMA", "$" enA20 DB 13,10,"Открываем линию A20", "$" dsA20 DB 13,10,"Закрываем линию A20", "$" loc_enA20 DB 13,10,"Локальный доступ к линии A20","$" loc_dsA20 DB 13,10,"Закрываем локальный доступ" DB " к линии A20", "$" check_A20 DB 13,10,"Проверяем доступность " DB "линии A20", "$" free_ext_mem DB 13,10,"Всего расширенной " DB "памяти, Кбайт: ", "$" max_ext_block DB 13,10,"Максимальный участок " DB "свободной" DB " расширенной памяти, Кбайт: ", "$"

HMMEntry dd ?

.CODE .STARTUP

mov ah, 9h ; Выводим заголовок mov dx, OFFSET msg int 21h

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

mov ax, 4300h int 2fh cmp al, 80h je HMM_installed

; Если не установлен, выводим сообщение и завершаем ; работу программы



mov ah, 9h mov dx, OFFSET noHMM int 21h

jmp terminate

HMM_installed:

mov ah, 9h mov dx, OFFSET yesHMM int 21h

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

mov ax, 4310h int 2fh mov word ptr cs:[HMMEntry][0], bx mov word ptr cs:[HMMEntry][2], es

; Получаем номер версии

mov ah, 9h mov dx, OFFSET ver1 int 21h


mov ax,0 call cs:[HMMEntry]
; Выводим номер версии на экран
call Print_word
mov ah, 9h mov dx, OFFSET ver2 int 21h
mov ax, bx call Print_word
; Запрашиваем область HMA
mov ah, 9h mov dx, OFFSET hmareq int 21h
mov ax,0100h mov dx,0ffffh
call cs:[HMMEntry] or ax, ax jnz hmareq_ok jmp error
hmareq_ok: mov ah, 9h mov dx, OFFSET okmsg int 21h
; Открываем линию A20
mov ah, 9h mov dx, OFFSET enA20 int 21h
mov ax,0300h
call cs:[HMMEntry] or ax, ax jnz enA20_ok jmp error
enA20_ok: mov ah, 9h mov dx, OFFSET okmsg int 21h
; Закрываем линию A20
mov ah, 9h mov dx, OFFSET dsA20 int 21h
mov ax,0400h
call cs:[HMMEntry] or ax, ax jnz dsA20_ok jmp error
dsA20_ok:
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Освобождаем область HMA
mov ah, 9h mov dx, OFFSET hmarel int 21h
mov ax,0200h
call cs:[HMMEntry] or ax, ax jz error
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Получаем локальный доступ к линии A20
mov ah, 9h mov dx, OFFSET loc_enA20 int 21h
mov ax,0500h
call cs:[HMMEntry] or ax, ax jz error
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Проверяем линию A20
mov ah, 9h mov dx, OFFSET check_A20 int 21h
mov ax,0700h
call cs:[HMMEntry] or ax, ax jz error
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Определяем размер свободной расширенной памяти
mov ah, 9h mov dx, OFFSET free_ext_mem int 21h
mov ax,0800h
call cs:[HMMEntry]
push ax mov ax, dx call Print_word
mov ah, 9h mov dx, OFFSET max_ext_block int 21h
pop ax call Print_word
; Освобождаем линию A20
mov ah, 9h mov dx, OFFSET loc_dsA20 int 21h
mov ax,0600h
call cs:[HMMEntry] or ax, ax jz error
mov ah, 9h mov dx, OFFSET okmsg int 21h
jmp terminate
error: push bx
mov ah, 9h mov dx, OFFSET errmsg int 21h
pop ax call Print_word
terminate:
.EXIT 0
; Вывод на экран содержимого регистра AX
Print_word proc near ;-------------------- push ax push bx push dx ; push ax mov cl,8 rol ax,cl call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl ; pop ax call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl ; pop dx pop bx pop ax ret Print_word endp ; Byte_to_hex proc near ;-------------------- ; al - input byte ; dx - output hex ;-------------------- push ds push cx push bx ; lea bx,tabl mov dx,cs mov ds,dx ; push ax and al,0fh xlat mov dl,al ; pop ax mov cl,4 shr al,cl xlat mov dh,al ; pop bx pop cx pop ds ret ; tabl db '0123456789ABCDEF' Byte_to_hex endp ;


END
Теперь приведем пример программы, использующей область HMA для выполнения процедуры генерации звукового сигнала. Программа получает доступ к области HMA, копирует в нее процедуру генерации звукового сигнала и вызывает эту процедуру с помощью межсегментной команды call:
include sysp.inc
.MODEL tiny DOSSEG .STACK 100h
.DATA
msg DB 13,10,"Работа в области HMA", 13, 10 DB "Copyright ©Frolov A.,1991",13,10,13,10 DB "$"
noHMM DB 13,10,"Драйвер HIMEM.SYS " DB "не установлен", 13, 10, "$" yesHMM DB 13,10,"Драйвер HIMEM.SYS установлен, ","$" errmsg DB 13,10,"Ошибка с кодом ", "$" okmsg DB 13,10,"Успех!!!", "$" hmareq DB 13,10,"Запрашиваем область HMA", "$" hmarel DB 13,10,"Освобождаем область HMA", "$" enA20 DB 13,10,"Открываем линию A20", "$" dsA20 DB 13,10,"Закрываем линию A20", "$"
HMMEntry dd ?
HMAStart dd ?
.CODE .STARTUP
mov ah, 9h ; Выводим заголовок mov dx, OFFSET msg int 21h
; Проверяем, установлен ли драйвер HIMEM.SYS
mov ax, 4300h int 2fh cmp al, 80h je HMM_installed
; Если не установлен, выводим сообщение и завершаем ; работу программы
mov ah, 9h mov dx, OFFSET noHMM int 21h jmp terminate
HMM_installed:
mov ah, 9h mov dx, OFFSET yesHMM int 21h
; Получаем адрес управляющей функции драйвера
mov ax, 4310h int 2fh mov word ptr cs:[HMMEntry][0], bx mov word ptr cs:[HMMEntry][2], es
; Запрашиваем область HMA
mov ah, 9h mov dx, OFFSET hmareq int 21h
mov ax,0100h mov dx,0ffffh call cs:[HMMEntry] or ax, ax jnz hmareq_ok jmp error
hmareq_ok: mov ah, 9h mov dx, OFFSET okmsg int 21h
; Открываем линию A20
mov ah, 9h mov dx, OFFSET enA20 int 21h
mov ax,0300h call cs:[HMMEntry] or ax, ax jnz enA20_ok jmp error
enA20_ok: mov ah, 9h mov dx, OFFSET okmsg int 21h
; Записываем в двойное слово HMAStart ; адрес начала облсти HMA
mov word ptr cs:[HMAStart][0], 0010h mov word ptr cs:[HMAStart][2], 0ffffh


; Копируем в область HMA процедуру, которая ; будет там выполняться
cld lea si, begin_HMA_code mov di, 0010h
mov ax, cs mov ds, ax
mov ax, 0ffffh mov es, ax
mov cx, HMA_code_size rep movsb
; Вызываем процедуру, находящуюся в области HMA
call cs:[HMAStart]
; Закрываем линию A20
mov ah, 9h mov dx, OFFSET dsA20 int 21h
mov ax,0400h call cs:[HMMEntry] or ax, ax jnz dsA20_ok jmp error
dsA20_ok:
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Освобождаем область HMA
mov ah, 9h mov dx, OFFSET hmarel int 21h
mov ax,0200h call cs:[HMMEntry] or ax, ax jz error
mov ah, 9h mov dx, OFFSET okmsg int 21h
jmp terminate
error:
push bx mov ah, 9h mov dx, OFFSET errmsg int 21h
pop ax call Print_word
terminate:
.EXIT 0
; Вывод на экран содержимого регистра AX
Print_word proc near ;-------------------- push ax push bx push dx ; push ax mov cl,8 rol ax,cl call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl ; pop ax call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl ; pop dx pop bx pop ax ret Print_word endp ; Byte_to_hex proc near ;-------------------- ; al - input byte ; dx - output hex ;-------------------- push ds push cx push bx ; lea bx,tabl mov dx,cs mov ds,dx ; push ax and al,0fh xlat mov dl,al ; pop ax mov cl,4 shr al,cl xlat mov dh,al ; pop bx pop cx pop ds ret ; tabl db '0123456789ABCDEF' Byte_to_hex endp
; Эта процедура предназначена для ; выполнения в области HMA. ; Она просто три раза генерирует ; звуковой сигнал.
begin_HMA_code:
BEEP BEEP BEEP retf
end_HMA_code:
; Здесь записана длина процедуры, ; предназначенной для выполнения в ; области HMA
HMA_code_size dw $-begin_HMA_code
END
В программе использована макрокоманда BEEP, описанная в файле sysp.inc:
; Макро для выдачи звукового сигнала
BEEP MACRO mov bx,0 mov ax, 0E07h int 10h ENDM
Следующая программа демонстрирует использование функции копирования. Сообщение копируется из области основной памяти в область расширенной памяти, а затем обратно в область основной памяти, но в другое место:
include sysp.inc


ExtMemMoveStruct struc
@Length dd ? ; количество пересылаемых байтов SourceHandle dw ? ; индекс исходного блока SourceOffset dd ? ; смещение в исходном блоке DestHandle dw ? ; индекс блока-назначения DestOffset dd ? ; смещение в блокe
ExtMemMoveStruct ends
.MODEL tiny
DOSSEG .STACK 100h
.DATA
movestr ExtMemMoveStruct <0,0,0,0,0>
msg DB 13,10,"Использование блоков EMB", 13, 10 DB "Copyright ©Frolov A.,1991",13,10,13,10 DB "$"
noHMM DB 13,10,"Драйвер HIMEM.SYS не установлен",13,10,"$" yesHMM DB 13,10,"Драйвер HIMEM.SYS установлен, ","$" errmsg DB 13,10,"Ошибка с кодом ", "$" okmsg DB 13,10,"Успех!!!", "$" free_ext_mem DB 13,10,"Всего расширенной памяти, Кбайт: ","$" max_ext_block DB 13,10,"Максимальный участок свободной" DB " расширенной памяти, Кбайт: ", "$" getEMBmsg DB 13,10,"Получаем блок EMB","$" freeEMBmsg DB 13,10,"Освобождаем блок EMB","$"
copymsg DB 13,10,"Копируем блок данных в область EMB","$" copymsg1 DB 13,10,"Копируем блок данных обратно","$"
testmsg DB 13,10,13,10,"Сообщение для копирования" DB " в область EMB","$"
len_testmsg DW $-testmsg
; Буфер для копирования сообщения
testbuf DB 512 dup(?)
HMMEntry dd ?
EMBHandle dw ?
.CODE .STARTUP
mov ah, 9h ; Выводим заголовок mov dx, OFFSET msg int 21h
; Проверяем, установлен ли драйвер HIMEM.SYS
mov ax, 4300h int 2fh cmp al, 80h je HMM_installed
; Если не установлен, выводим сообщение и завершаем ; работу программы
mov ah, 9h mov dx, OFFSET noHMM int 21h
jmp terminate
HMM_installed:
mov ah, 9h mov dx, OFFSET yesHMM int 21h
; Получаем адрес управляющей функции драйвера
mov ax, 4310h int 2fh mov word ptr cs:[HMMEntry][0], bx mov word ptr cs:[HMMEntry][2], es
; Определяем размер свободной расширенной памяти
mov ah, 9h mov dx, OFFSET free_ext_mem int 21h


mov ax,0800h
call cs:[HMMEntry]
push ax mov ax, dx call Print_word
mov ah, 9h mov dx, OFFSET max_ext_block int 21h
pop ax call Print_word
; Получаем блок EMB
mov ah, 9h mov dx, OFFSET getEMBmsg int 21h
mov ax,0900h mov dx,1h
call cs:[HMMEntry] or ax, ax jnz getemb_ok jmp error
getemb_ok:
mov EMBHandle, dx
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Копируем строку testmsg в блок EMB
mov ah, 9h mov dx, OFFSET copymsg int 21h
; Заполняем управляющую структуру
; Длина копируемого массива памяти
mov ax, word ptr len_testmsg mov word ptr movestr.@Length, ax
; Индекс основной памяти, должен быть = 0
mov ax, 0 mov word ptr movestr.SourceHandle, ax
; Задаем сегмент:смещение копируемого сообщения
mov ax, OFFSET testmsg mov word ptr [movestr.SourceOffset][0], ax mov ax, cs mov word ptr [movestr.SourceOffset][2], ax
; Задаем индекс EMB, в который будем копировать ; сообщение из основной памяти
mov ax, EMBHandle mov movestr.DestHandle, ax
; Копируем в начало EMB, поэтому ; смещение = 0
mov ax, 0 mov word ptr [movestr.DestOffset][0], ax mov word ptr [movestr.DestOffset][2], ax
; Загружаем адрес управляющей структуры в DS:SI
mov ax, cs mov ds, ax mov ax, OFFSET movestr mov si, ax mov ax,0B00h
; Вызываем функцию копирования
call cs:[HMMEntry] or ax, ax jnz moveemb_ok jmp error
moveemb_ok:
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Копируем сообщение обратно из блока EMB ; в буфер testbuf, расположенный в основной ; памяти
mov ah, 9h mov dx, OFFSET copymsg1 int 21h
; Подготавливаем управляющую структуру
mov ax, word ptr len_testmsg mov word ptr movestr.@Length, ax
mov ax, 0 mov word ptr movestr.DestHandle, ax
mov ax, OFFSET testbuf mov word ptr [movestr.DestOffset][0], ax mov ax, cs mov word ptr [movestr.DestOffset][2], ax
mov ax, EMBHandle mov movestr.SourceHandle, ax
mov ax, 0 mov word ptr [movestr.SourceOffset][0], ax mov word ptr [movestr.SourceOffset][2], ax
; Выполняем копирование
mov ax, cs mov ds, ax mov ax, OFFSET movestr mov si, ax mov ax,0B00h


call cs:[HMMEntry] or ax, ax jnz move1emb_ok jmp error
move1emb_ok:
mov ah, 9h mov dx, OFFSET okmsg int 21h
; Выводим скопированное сообщение на экран ; для проверки
mov ah, 9h mov dx, OFFSET testbuf int 21h
; Освобождаем блок EMB
mov ah, 9h mov dx, OFFSET freeEMBmsg int 21h
mov ax,0A00h mov dx,EMBHandle
call cs:[HMMEntry] or ax, ax jnz freeemb_ok jmp error
freeemb_ok:
mov EMBHandle, dx
mov ah, 9h mov dx, OFFSET okmsg int 21h
jmp terminate
error: push bx
mov ah, 9h mov dx, OFFSET errmsg int 21h
pop ax call Print_word
terminate:
.EXIT 0
; Вывод на экран содержимого регистра AX
Print_word proc near ;-------------------- push ax push bx push dx ; push ax mov cl,8 rol ax,cl call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl ; pop ax call Byte_to_hex mov bx,dx @@out_ch bh @@out_ch bl ; pop dx pop bx pop ax ret Print_word endp ; Byte_to_hex proc near ;-------------------- ; al - input byte ; dx - output hex ;-------------------- push ds push cx push bx ; lea bx,tabl mov dx,cs mov ds,dx ; push ax and al,0fh xlat mov dl,al ; pop ax mov cl,4 shr al,cl xlat mov dh,al ; pop bx pop cx pop ds ret ; tabl db '0123456789ABCDEF' Byte_to_hex endp
END

Содержание раздела