---------------------------------------------------------------------
; ************ DRIVER.INC *******************************************
;
; Driver.Inc : Содержит определения и константы для использования при
; ассемблировании драйверов MS-DOS.
;
; ************ ОПРЕДЕЛЕНИЕ КОНСТАНТ, ИСПОЛЬЗУЕМЫХ В ДРАЙВЕРАХ *******
;
; Определение битов слова атрибутов драйвера :
AT_CHR EQU 1000000000000000b ; Символьное устройство
AT_IOCTL EQU 0100000000000000b ; Поддержка IOCTL
AT_BUSY EQU 0010000000000000b ; Поддержка OTB
AT_NOIBM EQU 0010000000000000b ; Не IBM устройство
AT_NET EQU 0001000000000000b ; Сетевое устройство
AT_OCRM EQU 0000100000000000b ; Поддержка OCRM
- 6-53 -
AT_GIOCTL EQU 0000000001000000b ; Поддержка GIOCTL
AT_LOGICL EQU 0000000001000000b ; Get/Set Logical Dev
AT_SPECL EQU 0000000000010000b ; Специальное устр-во
AT_CLOCK EQU 0000000000001000b ; Устройство "ЧАСЫ"
AT_NUL EQU 0000000000000100b ; Устройство NUL
AT_STDOUT EQU 0000000000000010b ; Стандартные устр-ва
AT_STDIN EQU 0000000000000001b ; ввода и вывода
ST_ERROR EQU 1000000000000000b
ST_BUSY EQU 0000001000000000b
ST_DONE EQU 0000000100000000b
; Определение кодов ошибок драйверов устройств :
WRITE_PROTECT EQU 0
UNKNOWN_UNIT EQU 1
NOT_READY EQU 2
UNKNOWN_UNIT EQU 3
CRC_ERROR EQU 4
BAD_REQUEST EQU 5
SEEK_ERROR EQU 6
UNKNOWN_MEDIA EQU 7
SECTOR_NOT_FOUND EQU 8
OUT_OF_PAPER EQU 9
WRITE_FAULT EQU 0Ah
READ_FAULT EQU 0Bh
GENERAL_FAILURE EQU 0Ch
INVALID_DISK_CHANGE EQU 0Fh
; Статус, возвращаемый командой MEDIA CHECK :
IsChanged EQU -1 ; носитель был заменен
DontKnow EQU 0 ; не известно была ли замена
NotChanged EQU 1 ; носитель был заменен
;
; ************ КОНЕЦ ФАЙЛА : DRIVER.INC *****************************
---------------------------------------------------------------------
Пример драйвера виртуального диска
В конце этой главы, в листинге 6-10, мы приводим пример весьма
упрощенного драйвера RAM-диска (т.е. драйвера виртуального диска,
размещаемого в ОЗУ). Несмотря на свою простоту, драйвер на 100%
работоспособен и может быть использован на любой MS-DOS системе
начиная с версии 2.0 и выше. Драйвер RAM-диска, показанный в лис-
тинге 6-10, использует 360 Kбайт системной памяти для эмуляции
стандартного пятидюймового дисковода. Если Вы намерены использо-
вать этот драйвер, то Ваша система должна иметь по крайней мере
512 Kбайт памяти. Если Вы имеете меньше памяти или просто желаете
иметь виртуальный диск меньших размеров, то Вы можете изменить
принимаемые по умолчанию параметры, которые описаны в секции
драйвера, помеченной как "Описание RAM-диска".
Более элегантным решением изменения размеров RAM-диска являет-
ся использование параметров командной строки. Вспомните, что при
входе в обработчик команды INIT параметры request.bpbtabo и
request.bpbtabs содержат длинный указатель на командную строку
драйвера. Эта строка может быть проверена на наличие переключате-
лей и опций, которые могут быть использованы для конфигурации
драйвера. При использовании этого метода процедура INIT должна
выполнить проверку, скорректировать параметры в BPB и сегментный
адрес завершения драйвера.
- 6-54 -
После того, как программа была обработана ассемблером и редак-
тором связей, переименуйте ее в RDISK.SYS. Теперь создайте файл
CONFIG.SYS (если, конечно, он еже не создан) и добавьте в него
командную строку :
DEVICE=RDISK.SYS
При первой же перезагрузке драйвер будет установлен как драй-
вер следующего по порядку дисковода (вероятно как драйвер диско-
вода C:, если у Вас нет жесткого диска). Ничего более для уста-
новки драйвера RDISK не требуется.
Доступ к RAM-диску возможен с помощью любых функций MS-DOS или
программ, за исключением команд DISKCOPY и DISKCOMP. Обе эти
программы ожидают определенные типы дисков и не работают с
RAM-дисками.
Драйвер RDISK, приведенный в листинге 6-10, содержит простой
код, который может быть использован для отладки или исследования
драйверов. Он написан с использованием функций ввода/вывода уров-
ня BIOS, приведенных в листинге 6-8. Для того, чтобы отладочный
код располагался до адреса завершения драйвера, RDISK включает в
себя исходный текст файла BIOSIO.ASM (см.листинг 6-9). Так как
библиотечные процедуры обычно добавляются редактором связей в ко-
нец программы, их использование в драйверах устройств представля-
ется проблематичным.
Отладочный код может быть задействован путем включения в файл
RDISK оператора DEBUG EQU 1 или, при использовании Microsoft MASM
версии 4 или более поздней, указанием в командной строке опции
/DDEBUG.
Во время выполнения отладочный код использует ряд команд драй-
вера в качестве индекса в таблице message_table. Элементами таб-
лицы message_table являются адреса строк, представляющих имена
команд, находящихся в области данных, предшествующей таблице
message_table.Эти текстовые строки отображаются с помощью аппара-
турозависимой процедуры _biosprt. В драйвере RDISK процедура
_biosprt использует адаптер EGA с цветным монитором, что позволя-
ет легко отличать отладочный текст от обычных сообщений MS-DOS.
Листинг 6-8. Файл BIOSIO.INC
----------------------------------------------------------------------
; ************ BIOSIO.INC ********************************************
;
; BiosIO.Inc содержит константы для использования процедур BIOS уровня
; находящихся в файле STDLIB.LIB
;
; Макрокоманда @Video для использования с видеопроцедурами
;
@Video MACRO function
mov ah,function
int 10h
ENDM
;
; ************ BIOS I/O Equates **************************************
;
; Эти определения поддерживают использование ввода/вывода уровня BIOS.
;
; Определения функций видеосервиса BIOS (INT 10H)
- 6-55 -
SET_CURSOR_POS EQU 02H ;; BH = страница, DH = строка, DL = колонка
GET_CURSOR_POS EQU 03H ;; BH = страница; строка => DH, колонка => DL
SET_PAGE EQU 05H ;; AL => страница
SCROLL_UP EQU 06H ;; AL = #строк, BH => атрибут, C(x) = верхняя
SCROLL_DOWN EQU 07H ;; левая, D(x) = нижняя правая,
;; (x)H = строка, (x)L = колонка
READ_CHR_ATR EQU 08H ;; BH = страница; атр. => AH, симв. => AL
WRITE_CHR_ATR EQU 09H ;; BH = страница, CX = 1, AL = симв., BL = атр.
WRITE_CHAR EQU 0AH ;; BH = страница, CX = 1, AL = симв., без атр.
WRITE_TEXT EQU 0EH ;; BH = страница, AL = символ
GET_MODE EQU 0FH ;; режим => AL, #колонок => AH, страница => BH
;
; Атрибуты символов при использовании адаптера EGA
BLINK EQU 10000000b
BRIGHT EQU 00001000b
BLACK_F EQU 00h
BLUE_F EQU 01h
GREEN_F EQU 02h
CYAN_F EQU 03h
RED_F EQU 04h
MAGENTA_F EQU 05h
YELLOW_F EQU 06h
WHITE_F EQU 07h
BLACK_B EQU 00h
BLUE_B EQU 10h
GREEN_B EQU 20h
CYAN_B EQU 30h
RED_B EQU 40h
MAGENTA_B EQU 50h
YELLOW_B EQU 60h
WHITE_B EQU 70h
;
; ************ КОНЕЦ ФАЙЛА BIOSIO.INC ********************************
Листинг 6-9. Файл BIOSIO.ASM
----------------------------------------------------------------------
PAGE 60,132
PUBLIC _biosprt
; ************ BIOSIO.ASM ********************************************
; BIOSIO: Содержит процедуры для выполнения ввода/вывода на
; уровне BIOS, используя стандартные вызовы BIOS. Эти процедуры
; предназначены для целей отладки.
;
IFNDEF DEBUG ; если не часть DEBUG, то должна быть часть
; от LIBRARY, и должна включать наши
; собственные определения
; ************ INCLUDES **********************************************
;
INCLUD biosio.inc ; BIOS I/O difinition
;
; ************ DGROUP (DATA) COMPONENT SEGMENTS **********************
_DATA SEGMENT BYTE PUBLIC 'DATA'
_DATA ENDS
;
DGROUP GROUP _DATA
;
- 6-56 -
;************* PROGRAM CODE STARTS HERE ******************************
;
_TEXT SEGMENT BYTE PUBLIC 'CODE'
ASSUME cs:_TEXT, ds:DGROUP, es:DGROUP, ss:DGROUP
ENDIF
;
; Шаблон структуры, описывающей состояние стека для _BIODPRT
bpframe STRUC
dw ? ; Старый BP
dw ? ; адрес возврата
p1 dw ? ; параметр #1
p2 dw ? ; параметр #2
p3 dw ? ; параметр #3
p4 dw ? ; параметр #4
bpframe ENDS
prtbase EQU [bp]
;
; _BIOSPRT
; Эта подпрограмма выполняет вывод на экран на уровне BIOS и
; используется для отладки драйвера. Подпрограмма использует
; видеорежим 03h : 80*25 цветной текст
;
; Эквивалентный языку Си синтаксис вызова : biosprt(string,color)
;
_biosprt PROC NEAR
push bp
mov bp,sp
push si
push cx
push bx
;
@Video GET_MODE ; Получить номер тек.страницы
mov si,word prt [prtbase.p1] ; адрес строки
mov bl,byte prt [prtbase.p2] ; атрибут
mov cx,1
;
biosprtloop:
lodsb ; Берем очередной символ
or al,al ; Строка завершается нулем
jz biosprtdone
cmp al,'$' ; или завершается "$"
jz biosprtdone
push ax
mov al,020h
@Video WRITE_CHR_ATR ; Пробел с атрибутом
pop ax
@Video WRITE_TEXT ; Символ в режиме TTY
jmp biosprtloop ; Следующий символ
;
biosprtdone
pop bx
pop cx
pop si
pop bp