Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Отчёт мой.doc
Скачиваний:
4
Добавлен:
11.12.2018
Размер:
6.37 Mб
Скачать

Лабораторная работа контроллер нжмд

Цель работы: Изучить принцип работы контроллеров накопителей на жестком магнитном диске (НЖМД); разобраться, как происходит работа с жесткими дисками по стандарту АТА; научиться писать программы, выполняющие заданные действия в системе НЖМД-ОП.

Работа с накопителями на низком уровне

Если возникает потребность в выполнении низкоуровневых операций, то в случае с гибкими дисками удобнее и безопаснее работать через функции BIOS (они более стандартны, чем контроллеры дисководов, разработанные разными фирмами), а с жесткими дисками, наоборот, гораздо проще взаимодействовать напрямую (по стандарту АТА).

С регистрами контроллера жёсткого дис­ка необходимость работать напрямую возникает в следующих случаях:

- при переключении процессора в защищенный режим (прерыва­ния DOS и BIOS становятся недоступными);

- при работе с дисками большого (свыше 8 Гбайт) объема или не­стандартного (не DOS) формата;

- в измерительных системах и системах управления в реальном вре­мени (для ускорения операций ввода-вывода);

- в системах с повышенными требованиями к защи­те информации (для предотвращения перехвата управления на уровне прерываний, например, компьютерным вирусом).

Стандарт АТА позволяет подключать к каждому каналу (то есть к одному кабелю) по два устройства. Наличие на материнской плате двух каналов для подключения АТА – устройств, фактически, стало стандартом. Для этих каналов жестко закреплен диапазон адресов ввода-вывода и номера используемых прерываний.

Для адресации данных на диске с интерфейсом АТА можно использовать либо режим LBA, либо режим CHS, причем назначение регистров контроллера зависит от используемого режима адресации. Все регистры, за исключением регистра данных, 8-разрядные, а регистр данных — 16-разрядный.

Рассмотрим основные регистры контроллера НЖМД.

Регистр данных (DR - 1F0h) используется при выполнении операции чтения или записи секто­ра в программном режиме ввода-вывода. Этот регистр недо­ступен, пока не начнется операция чтения или записи. Нельзя обра­щаться к регистру, когда происходит обмен информацией между диском и памятью в режиме прямого доступа (DMA). Передача данных через регистр осуществляется 16-разрядными сло­вами. Этот 16-разрядный регистр и его адресное пространство перекрывают следующий за ним регистр ошибок.

Регистр ошибок (ER – 1F1h) доступен только для чтения. Он определяет состояние адаптера после выполнения операции. Содержимое это­го регистра нужно проверять в двух случаях:

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

- после выполнения команды «диагностика» или после выполне­ния внутренней диагностики адаптера по системному сбросу.

Если при выполнении команды ошибок не было, то все разряды ре­гистра ошибок содержат нули. Если при выполнении команды про­исходит какая-либо ошибка, то соответствующий разряд регистра устанавливается в “1”.

В регистр счетчика секторов (SC – 1F2h) заносится количество секторов, которое должно быть считано или записано (при записи 0 в этот ре­гистр происходит обработка 256 секторов) на носитель. Значение этого регистра уменьшается на единицу после обработки каждого сектора. При вы­полнении мультисекторной операции секторы должны располагать­ся на диске последовательно, друг за другом (то есть область данных должна быть непрерывной). Регистр SC доступен не только для записи, но и для считывания. В случае возникновения ошибки при выполнении операции чтения или записи в этом регистре будет находиться число секторов, оставшихся необработанными.

В регистр номера сектора (SN – 1F3h) в режиме CHS загружается старто­вый номер сектора при операциях чтения/записи. После обработки каждого сектора в этот регистр автоматически заносится номер сле­дующего сектора, подлежащего обработке. Регистр доступен для чтения и для записи. После выполнения команды он содержит номер по­следнего обработанного сектора. В режиме LBА регистр номера секто­ра содержит младший байт линейного адреса сектора (разряды 0-7).

Регистры младшего (CL – 1F4h) и старшего (СН – 1F5h) байтов номера цилиндра в режиме CHS определяют стартовый цилиндр для выполнения команды. Регистры доступны для чтения и для записи. После выполнения команды они содержат текущий адрес цилиндра. В режиме LBA регистр CL содержит разряды 8-15, а регистр СН — разряды 16-23 линейного адреса сектора.

Регистр состояния (SR – 1F7h) отображает состояние устройства и доступен только для чтения.

Регистр команд (CR – 1F7h) используется для загрузки кода выполняемой команды. Запись кода команды должна проводиться в последнюю очередь, т.е. только после того, как в остальные регистры занесены все необходимые для ее выполнения данные. Выполнение команды на­чинается сразу после записи кода в этот регистр.

Регистр выбора НЖМД /номера головки (1F6h) содержит биты D3-D0 для выбора головки, бит D4 для выбора НЖМД и биты D6 и D5, задающие размер сектора (01-512 байт).

Команды АТА

В соответствии со стандартом команды интерфейса АТА делятся на три основные группы:

- обязательные команды;

- дополнительные команды;

- специфические команды.

В [1] (Глава “Работа с дисками”) дано описание команд, необходимых для работы с со­временными дисководами, и, потому, обязательных для всех выпус­каемых устройств.

Команда контроллера НЖМД (КНЖМД) состоит из одного байта и выполняется сразу после занесения в регистр команд (1F7h). Вследствие этого, необходимо предварительно загрузить параметры в соответствующие порты КНЖМД, если он находится в состоянии “не занят” (бит D7 регистра состояния равен нулю). Перечень команд КНЖМД приведен в таблице 1.

Таблица 1

Команда

Биты

D7

D6

D5

D4

D3

D2

D1

D0

Поиск

0

1

1

1

R3

R2

R1

R0

Чтение секторов

0

0

1

0

0

0

L

T

Запись секторов

0

0

1

1

0

0

L

T

Верификация секторов

0

1

0

0

0

0

0

T

Инициализация параметров НЖМД

1

0

0

1

0

0

0

1

Диагностика

1

0

0

1

0

0

0

0

Обозначение:

L = 0 – нормальный режим; L = 1 – длинный режим; T = 0 – разрешение повтора; T = 1 – запрет повтора; R3-R0 – скорость позиционирования: 0000 – 35 мкс/шаг…. 1111 – 16 мкс/шаг.

Режимы и протоколы передачи информации

Обмен информацией между жестким диском, обозначенным в стан­дарте термином Device (устройство), и компьютером, обозначенным как Host (хост), должен выполняться по строго определенным пра­вилам.

Для обмена данными между диском и контроллером используются 16-разрядные слова в пакетах по 256 штук. При работе с современ­ными жесткими дисками может применяться один из двух основ­ных режимов передачи данных: режим программного ввода-вывода (PIO) через процессор или режим прямого доступа к памяти (DMA). Оба режима постоянно совершенствуются и в настоящее время имеют несколько вариантов реализации, отличающихся все более высокой скоростью передачи данных между контроллером и устройством. Сравнительный анализ режимов приведён в [1].

В программах, предназначенных для работы в MS-DOS, можно ограничиться простыми протоколами ввода-вывода РIO, посколь­ку значительно более сложный для реализации протокол DMA да­ет выигрыш по скорости только в многозадачном режиме.

Лабораторное задание

1. Ознакомиться с литературой и разобраться с работой программ.

2. Ознакомиться с внутренним устройством и общими принципами функционирования жестких дисков.

3. Изучить функциональное назначение регистров контроллера жесткого диска и режимы адресации данных.

4. Ознакомиться с обязательными командами интерфейса АТА.

5. Запустить демонстрационный пример , разобраться в его работе.

6. Написать на Ассемблере программу, которая бы выполняла чтение определенного сектора или верификацию сектора; чтение состояния НЖМД или внутреннюю диагностику; чтение регистра ошибок или чтение регистра состояния НЖМД, т.е. программную реализацию соответствующих функций BIOS.

Листинг программы 1:

;Поиск подключённых жёстких дисков по каналам

;1 и 2

; Автор текста программ Кулаков Владимир ;Геннадьевич.

IDEAL

P386

LOCALS

MODEL MEDIUM

; подключить файл мнемонических обозначений

; кодов управляющих клавиш

include "lst_2_03.inc"

include "lst_2_05.inc"

DATASEG

; текстовое сообщение

Txt1 DB LIGHTCYAN,0,26,"ИДЕНТИФИКАЦИЯ ЖЕСТКИХ ДИСКОВ",0

DB YELLOW,24,35,"Ждите ...",0

Txt2 DB 2,27,"На канале найден диск .",0

DB 4,25,"Параметры обнаруженного диска:",0

DB 6,22,"общая информация:",0

DB 7,12,"число логических цилиндров:",0

DB 8,14," число логических головок:",0

DB 9,13," число логических секторов:",0

DB 10,24,"серийный номер:",0

DB 11,32,"модель:",0

DB 12,8,"макс.кол-во секторор за сеанс:",0

DB 13,27, "возможности:",0

DB 14,10,"текущее число лог.цилиндров:",0

DB 15,12," текущее число лог.головок:",0

DB 16,11," текущее число лог.секторов:",0

DB 17,13,"текущая ёмкость секторов:",0

DB 18,11,"число секторов в режиме LBA:",0

DB 19,13,"поддерживаемые режимы DMA:",0

DB 20,17,"улучшенные режимы PIO:",0

Txt3 DB LIGHTGREEN

DB 12,24,"Поиск завершён, больше нет дисков",0

AnyK DB YELLOW,24,29,"Нажмите любую клавишу",0

ENDS

SEGMENT sseg para stack 'STACK'

DB 400h DUP(?)

ENDS

CODESEG

;*****************************

;* основной модуль программы *

;*****************************

PROC IdentifyDevices

mov AX,DGROUP

mov DS,AX

; установить текстовый режим и очистить экран

mov AX,3

int 10h

; Скрыть курсор 

mov [ScreenString],25

mov [ScreenColumn],0

call SetCursorPosition

; Вывести текстовые сообщения на экран

mov SI,offset Txt1

call ShowColorString

call ShowColorString

; Цикл опроса каналов

mov [ChannelNumber],1

; Опросить Master-диск

@@AskMaster:

call ClearPrevInfo

mov [HDDNumber],0

call ReadHDD_ID

cmp [HDDErrorCode],0

jne @@AskSlave

call ShowHDD_ID

; опросить Slave-диск

@@AskSlave:

call ClearPrevInfo

mov [HDDNumber],1

call ReadHDD_ID

cmp [HDDErrorCode],0

jne @@NextCannel

call ShowHDD_ID

@@NextCannel:

inc [ChannelNumber]

cmp [ChannelNumber],3

jb @@AskMaster

@@End: ; выдать сообщение о завершении поиска 

call ClearPrevInfo

mov SI,offset Txt3

call ShowColorString

call ShowColorString

call GetChar

; переустановить текстовый режим

mov ax,3

int 10h

; выход в DOS

mov AH,4Ch

int 21h

ENDP IdentifyDevices

;************************************

; РАСШИФРОВКА ИДЕНТИФИКАТОРА ДИСКА*

;************************************

PROC ShowHDD_ID near

pushad

mov [TextColorAndBackground],LIGHTGREEN

mov CX,17

mov SI,offset Txt2

@@NextStr:

call ShowString

loop @@NextStr

mov SI,offset AnyK

call ShowColorString

; “бв ­®ўЁвм ЎҐ«л© 梥⠨ зҐа­л© д®­

mov [TextColorAndBackground],WHITE

; вывести номер канала и номер диска 

mov [ScreenString],2

mov [ScreenColumn],37

mov AX,[ChannelNumber]

call ShowDecWord

mov [ScreenColumn],51

mov AL,[HDDNumber]

call ShowDecByte

; вывести отдельные поля идентификатора 

mov [ScreenString],6

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer]

call ShowBinWord

; — число лог.цилиндров

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+1*2]

call ShowDecWord

; число лог.головок

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+3*2]

call ShowDecWord

; число логюсекторов

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+6*2]

call ShowDecWord

;серийный номер

mov AX,0B800h

mov ES,AX

mov SI,offset SectorDataBuffer

add SI,10*2

mov DI,(10*80+40)*2

mov AH,[TextColorAndBackground]

mov CX,10

@@NextWord1:

mov DX,[SI]

mov AL,DH

stosw

mov AL,DL

stosw

add SI,2

loop @@NextWord1

; Ќ®¬Ґа ¬®¤Ґ«Ё

mov SI,offset SectorDataBuffer

add SI,27*2

mov DI,(11*80+40)*2

mov AH,[TextColorAndBackground]

mov CX,20

@@NextWord2:

mov DX,[SI]

mov AL,DH

stosw

mov AL,DL

stosw

add SI,2

loop @@NextWord2

; Њ Єб. Є®«-ў® ᥪв®а®ў §  ᥠ­б

add [ScreenString],3

mov [ScreenColumn],40

mov AL,[SectorDataBuffer+47*2]

call ShowDecByte

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+49*2]

call ShowBinWord

test [word ptr SectorDataBuffer+53*2],1

jz @@NotValid5458

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+54*2]

call ShowDecWord

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+55*2]

call ShowDecWord

; ’ҐЄг饥 зЁб«® «®ЈЁзҐбЄЁе ᥪв®а®ў

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[word ptr SectorDataBuffer+56*2]

call ShowDecWord

; ’ҐЄгй п Ґ¬Є®бвм, ᥪв®а®ў

inc [ScreenString]

mov [ScreenColumn],40

mov EAX,[dword ptr SectorDataBuffer+57*2]

call ShowDecDWord

@@NotValid5458:

; —Ёб«® ᥪв®а®ў ў ०Ё¬Ґ LBA

mov [ScreenString],18

mov [ScreenColumn],40

mov EAX,[dword ptr SectorDataBuffer+60*2]

call ShowDecDWord

inc [ScreenString]

mov [ScreenColumn],40

mov AL,[SectorDataBuffer+63*2]

call ShowByteBinCode

test [word ptr SectorDataBuffer+53*2],10b

jz @@NotValid6470

inc [ScreenString]

mov [ScreenColumn],40

mov AL,[SectorDataBuffer+64*2]

call ShowByteBinCode

@@NotValid6470:

; ожидать нажатия клавиши

call GetChar

popad

ret

ENDP ShowHDD_ID

;**************************************

;* ОЧИСТИТЬ ЭКРАН И ВЫВЕСТИ ЗАГОЛОВКИ*

;**************************************

PROC ClearPrevInfo near

pushad

call ClearScreen

; ВЫВЕСТИ ТЕКСТОВОЕ СООБЩЕНИЕ

mov SI,offset Txt1

call ShowColorString

call ShowColorString

popad

ret

ENDP ClearPrevInfo

ENDS

include "lst_2_02.inc"

include "lst_3_05.inc"

include "lst_7_07.inc"

END

Результат программы:

Вывод: данная программа организует поиск подключённых жёстких дисков по каналам 1 и 2. На экран выводятся обнаруженного диска.

Листинг программы 2:

; Просмотр секторов «ведущего» жёсткого диска 

; канала 1 в режиме LBA

;

IDEAL

P386

LOCALS

MODEL MEDIUM

include "lst_2_03.inc"

include "lst_2_05.inc"

DATASEG

; Тукстовые сообщения

Txt1 DB LIGHTCYAN,0,16,"Просмотр секторов "

DB "жесткого диска в ASCII-кодах",0

DB LIGHTGREEN,5,8,"сектор N :",0

DB LIGHTCYAN,17,8,"управляющие клавиши:",0

DB YELLOW,24,27,"Нажмите управляющую клавишу",0

Txt2 DB 19,8,"стрелка вниз-следующий сектор",0

DB 20,8,"стрелка вверх-предыдущий сектор",0

DB 21,8,"Esc - выход.",0

Err1 DB LIGHTRED,12,21

DB "Master-диск ­ на канале 1 не обнаружен.",0

Err2 DB LIGHTRED,12,24

DB "Диск не поддерживает режим LBA.",0

PBut DB YELLOW,24,29,"Нажмите любую клавишу",0

ENDS

SEGMENT sseg para stack 'STACK'

DB 400h DUP(?)

ENDS

CODESEG

;*****************************

;* Основной модуль программы*

;*****************************

PROC ShowHDDSector

mov AX,DGROUP

mov DS,AX

; установить текстовый режим и очистить экран

mov AX,3

int 10h

; скрыть курсор 

mov [ScreenString],25

mov [ScreenColumn],0

call SetCursorPosition

; опросить Master-диск канала  1

mov [ChannelNumber],1

mov [HDDNumber],0

call ReadHDD_ID

; диск подключен­?

cmp [HDDErrorCode],0

jne @@DiskNotFound

; режим LBA поддерживается?

cmp [dword ptr SectorDataBuffer+60*2],0

je @@LBANotSupported

; вывести текстовые сообщения на экран

mov CX,4

mov SI,offset Txt1

@@Txt1: call ShowColorString

loop @@Txt1

; установить зеленый цвет и черный цвет фона

mov [TextColorAndBackground],LIGHTGREEN

mov SI,offset Txt2

call ShowString

call ShowString

call ShowString

; инициализируем переменные

mov [HDDNumber],0

mov [dword ptr SectorAddress],0

mov AX,0B800h

mov ES,AX

; ВНЕШНИЙ ЦИКЛ

@@ReadSector:

mov [ScreenString],5

mov [ScreenColumn],17

mov EAX,[SectorAddress]

call ShowHexDword

call ReadHDDSector

mov DI,7*160+8*2

mov SI,offset SectorDataBuffer

mov AH,LIGHTCYAN+BLUE*16

mov DX,8 ;бзҐвзЁЄ бва®Є

@@OutNextString:

mov CX,64 ;бзҐвзЁЄ бЁ¬ў®«®ў ў бва®ЄҐ

@@OutNextChar:

lodsb

stosw

loop @@OutNextChar

add DI,16*2

dec DX

jnz @@OutNextString

@@GetCommand:

; ОЖИДАЕМ ВВОДА СЛЕДУЮЩЕЙ команды

call GetChar

cmp AL,0

je @@TestCommandByte

call Beep

jmp short @@GetCommand

@@TestCommandByte:

cmp AH,B_Esc ;"Выход"

je @@End

@@TestDn:

cmp AH,B_DN ;"Стрелка вниз"

jne @@TestUp

; Увеличить на 1 номер сектора 

inc [dword ptr SectorAddress]

jmp @@ReadSector

@@TestUp:

cmp AH,B_UP

jne @@CommandError

cmp [dword ptr SectorAddress],0

je @@CommandError

; Уменьшить на 1 номер счектора

dec [dword ptr SectorAddress]

jmp @@ReadSector

@@CommandError:

call Beep

jmp @@GetCommand

@@DiskNotFound:

mov SI,offset Err1

call ShowColorString

mov SI,offset PBut

call ShowColorString

call GetChar

jmp short @@End

@@LBANotSupported:

; Сообщение»Диск не поддерживает» LBA"

mov SI,offset Err2

call ShowColorString

mov SI,offset PBut

call ShowColorString

call GetChar

@@End: ; переустановить текстовый режим

mov ax,3

int 10h

; ‚л室 ў DOS

mov AH,4Ch

int 21h

ENDP ShowHDDSector

ENDS

include "lst_2_02.inc"

include "lst_7_07.inc"

END

Результат программы:

Вывод: данная программа обеспечивает просмотр секторов «ведущего» жёсткого диска канала 1 в режиме LBA. Просмотр секторов жесткого диска происходит в ASCII-кодах. На экране отображаются управляющие клавиши.

Листинг программы 3:

; Просмотр в режиме LBA параметроа логических дисков

; на «ведущем» жестком диске канала 1.

IDEAL

P386

LOCALS

MODEL MEDIUM

include "lst_2_03.inc"

include "lst_2_05.inc"

DATASEG

; Текстовые сообщения

Txt00 DB YELLOW,24,29,"Нажмите любую клавишу",0

Txt01 DB YELLOW,0,30

DB "MASTER-диск канала 1

DB YELLOW,1,22

DB "ТАБЛИЦА РАЗДЕЛОВ ЛОГИЧЕСКОГО ДИСКА

Txt02 DB 8,1,"N",0

DB 8,4,"Тип

DB 8,9,"Призн9,9,"Акт.

DB 8,16," Начало раздела ",0

DB 9,17,"Цил.",0,9,24, "Сект",0,9,31,"‘ҐЄв.",0

DB 8,37," Конец раздела  ",0

DB 9,38,"Гол..",0,9,45,"Цил.",0,9,52,"Сект.",0

DB 8,58,"Номер нач.",0

DB 9,58,"сектора ",0

DB 8,70,"размер",0

DB 9,70,"секторов",0

Txt11 DB YELLOW,0,19

DB "ЗАГРУЗОЧНАЯ ЗАПИСЬ ЛОГИЧЕСКОГО ДИСКА N",0

Txt12 DB 2,12,"ид.изгот:",0

DB 3,22,"Байтов на сектор:",0

DB 4,19,"Секторов в кластере:",0

DB 5,14,"Число резервных секторов:",0

DB 6,23,"Число копий FAT:",0

DB 7,6,"„Дескрипторов в корневом каталоге:",0

DB 8,14,"Число секторов в ращзделе:",0

DB 9,15,"Тип носителя инф:",0

DB 10,1,"Число секторов, занимаемы копией FAT:",0

DB 11,13,"число секторов на дорожке:",0

DB 12,1,"Количество рабочих поверхностей  диска:",0

DB 13,16,"Число скрытых секторов:",0

Txt13 DB 14,23,"№дисковола :",0

DB 15,15,"№ лог диска :",0

DB 16,27,"Метка диска :",0

DB 17,9,"Аббревиатура файловой системы:",0

Txt14 DB 14,20,"№ активной FAT:",0

DB 15,22,"Номер версии FAT:",0

DB 16,0

DB "Номер на.кластера :",0

DB 17,8," FSINFO:",0

DB 18,4," Boot:",0

DB 19,23,"Номер дисковода:",0

DB 20,15,"номер лог д :",0

DB 21,27,"ЊҐвЄ  ¤ЁбЄ :",0

DB 22,9," Аббревиатура файловой системы:",:",0

Err1 DB LIGHTRED,12,22

DB "Master-диск на канале ",0 не обнаружен

Err2 DB LIGHTRED,12,25

ENDS

SEGMENT sseg para stack 'STACK'

DB 400h DUP(?)

ENDS

CODESEG

;*****************************

;* ОСНОВНОЙ МОДУЛЬ ПРОГРАММЫ *

;*****************************

PROC SearchLogicalDisks

mov AX,DGROUP

mov DS,AX

; УСТАНОВКА ТЕКСТОВОГО РЕЖИМА

mov AX,3

int 10h

; скрыть курсор 

mov [ScreenString],25

mov [ScreenColumn],0

call SetCursorPosition

mov [ChannelNumber],1

mov [HDDNumber],0

call ReadHDD_ID

cmp [HDDErrorCode],0

cmp [dword ptr SectorDataBuffer+60*2],0

je @@LBANotSupported

mov [LogicalDriveNumber],0

mov [CurrentDrive_StartSector],0

mov [dword ptr SectorAddress],0

call ReadHDDSector

;Отобразить таблицу разделов

call ShowPartitionTable

;найти и записать номера нач.секторов;

mov [NextDrivePresent],0

mov SI,offset SectorDataBuffer

add SI,1BEh ;смещение первойзаписи

mov AL,[SI+4]  

;проверить код основного раздела

cmp AL,01h

je @@PrimPartFound

cmp AL,04h

je @@PrimPartFound

cmp AL,06h

je @@PrimPartFound

cmp AL,0Bh

je @@PrimPartFound

cmp AL,0Eh

jne @@PrimPartNotFound

@@PrimPartFound:

; найден основной раздел

mov EAX,[SI+8] ;извлечь адрес сектора 

mov [PriDOS_StartSector],EAX

add SI,10h ;смещение второй записи

mov AL,[SI+4] ;извлечь тип раздела 

cmp AL,05h

je @@ExtPartFound

cmp AL,0Ch

je @@ExtPartFound

cmp AL,0Fh

jne @@NextDriveNotPresent0

@@ExtPartFound:

;имеется расширенный раздел

mov EAX,[SI+8]

mov [ExtDOS_StartSector],EAX

mov [NextDrivePresent],1

@@NextDriveNotPresent0:

; прочитать BOOT-сектор основного раздела 

mov EAX,[PriDOS_StartSector]

mov [SectorAddress],EAX

call ReadHDDSector

; отобразить данные BOOT-сектора 

call DecodeBootSector

;имеетмся след.диск?

cmp [NextDrivePresent],0

je @@End

mov EAX,[ExtDOS_StartSector]

mov [CurrentDrive_StartSector],EAX

;ЦИКЛ ОПРОСА ЛОГИЧЕСКИХ ДИСКОВ РАСШИРЕННОГО РАЗДЕЛА

@@ReadSMBR:

inc [LogicalDriveNumber]

mov EAX,[CurrentDrive_StartSector]

mov [BootSector],EAX

mov [SectorAddress],EAX

call ReadHDDSector

call ShowPartitionTable

mov [NextDrivePresent],0

mov SI,offset SectorDataBuffer

add SI,1BEh

mov EAX,[SI+8]

add [BootSector],EAX

add SI,10h

mov EAX,[SI+8]

cmp EAX,0

je @@NextDriveNotPresent1

add EAX,[ExtDOS_StartSector]

mov [CurrentDrive_StartSector],EAX

; УСТАНОВИТЬ ПРИЗНАК НАЛИЧИЯ СЛЕД.ДИСКА 

mov [NextDrivePresent],1

@@NextDriveNotPresent1:

mov EAX,[BootSector]

mov [SectorAddress],EAX

call ReadHDDSector

; Ћв®Ўа §Ёвм ¤ ­­лҐ BOOT-ᥪв®а 

call DecodeBootSector

cmp [NextDrivePresent],0

je @@End

jmp @@ReadSMBR

; обработка ошибок

@@DiskNotFound:

; сообщение «диск не найден»

mov SI,offset Err1

jmp short @@AllErr

@@LBANotSupported:

mov SI,offset Err2

jmp short @@AllErr

@@PrimPartNotFound:

mov SI,offset Err3

@@AllErr:

;общая часть обр.ошибок

call ShowColorString

mov SI,offset PBut

call ShowColorString

call GetChar

@@End:

mov ax,3

int 10h

; выход в DOS

mov AH,4Ch

int 21h

ENDP SearchLogicalDisks

;*****************************************

;* ПРОЧИТАТЬ НУЛЕВОЙ СЕКТОР И ОТОБРАЗИТЬ НА ЭКРАН ТУБЛИЦУ РАЗДЕЛОВ *

;*****************************************

PROC ShowPartitionTable near

pushad

push ES

call ClearScreen

mov SI,offset Txt00

call ShowColorString

mov SI,offset Txt01

call ShowColorString

call ShowColorString

mov [ScreenString],1

mov [ScreenColumn],57

mov [TextColorAndBackground],YELLOW

mov AL,[LogicalDriveNumber]

call ShowByteHexCode

mov AX,0B800h

mov ES,AX

mov DI,8*80*2

mov AH,LIGHTBLUE

mov AL,0B3h

mov DX,7

push DI

add DI,3*2

mov [ES:DI],AX

add DI,5*2

mov CX,8

@@ac1: mov [ES:DI],AX

add DI,7*2

loop @@ac1

add DI,4*2

mov [ES:DI],AX

pop DI

add DI,80*2

dec DX

jnz @@ac0

; Уст.зеленый цвет

mov [TextColorAndBackground],LIGHTGREEN

mov CX,16

mov SI,offset Txt02

@@NextStr1:

call ShowString

loop @@NextStr1

; ЦИКЛ ВВОДА ДВННЫХ

mov [TextColorAndBackground],WHITE

mov [PartitionNumber],1

mov SI,offset SectorDataBuffer

add SI,1BEh

mov [ScreenString],11

@@ShS0: mov AL,[PartitionNumber]

mov [ScreenColumn],0

call ShowByteHexCode

lodsb

mov [ScreenColumn],11

call ShowByteHexCode

; НОМЕР НАЧ. ПОВЕРХНОСТИ

lodsb

mov [ScreenColumn],18

call ShowByteHexCode

lodsw

mov BL,AL

shr AL,6

xchg AL,AH

mov [ScreenColumn],24

call ShowHexWord

mov AL,BL

and AL,0111111b

mov [ScreenColumn],32

call ShowByteHexCode

mov [ScreenColumn],5

lodsb

call ShowByteHexCode

mov [ScreenColumn],39

lodsb

call ShowByteHexCode

lodsw

mov BL,AL

shr AL,6

xchg AL,AH

mov [ScreenColumn],45

call ShowHexWord

mov AL,BL

and AL,0111111b

mov [ScreenColumn],53

call ShowByteHexCode

; отобразить код признака активного разжела 

mov [ScreenColumn],59

mov EAX,[SI]

add SI,4

call ShowHexDWord

mov [ScreenColumn],70

mov EAX,[SI]

add SI,4

call ShowHexDWord

inc [ScreenString]

inc [PartitionNumber]

cmp [PartitionNumber],5

jb @@ShS0

call GetChar

pop ES

popad

ret

ENDP ShowPartitionTable

;**********************************************

;* ОТОБРАЗИТЬ ИНФОРМАЦИЮ ЗАГРУЗОЧНОГО СЕКТОРА*

;**********************************************

PROC DecodeBootSector near

pushad

push ES

call ClearScreen

mov SI,offset Txt00

call ShowColorString

mov SI,offset Txt11

call ShowColorString

mov [ScreenString],0

mov [ScreenColumn],58

mov [TextColorAndBackground],YELLOW

mov AL,[LogicalDriveNumber]

call ShowByteHexCode

mov [TextColorAndBackground],LIGHTGREEN

mov CX,12

mov SI,offset Txt12

@@NextStr1:

call ShowString

loop @@NextStr1

BPB_TotSec32

call ShowHexWord

@@UseTotSec32:

inc [ScreenString]

mov [ScreenColumn],40

mov AL,[SI+15h]

call ShowByteHexCode

; ЧИСЛО СЕКТОРОВ

mov [ScreenString],8

mov [ScreenColumn],40

mov EAX,[SI+20h]

cmp EAX,0

je @@UseTotSec16 ;ЁбЇ®«м§®ў вм BPB_TotSec16

call ShowHexDWord

@@UseTotSec16:

mov CX,9

mov SI,offset Txt14

@@NextStr3:

call ShowString

loop @@NextStr3

mov SI,offset SectorDataBuffer

; число секторов FAT32

mov [ScreenString],10

mov [ScreenColumn],40

mov EAX,[SI+24h]

call ShowHexDWord

mov [ScreenString],14

mov [ScreenColumn],40

mov AX,[SI+28h]

call ShowHexWord

; число секторов FAT

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[SI+2Ah]

call ShowHexWord

inc [ScreenString]

mov [ScreenColumn],40

mov EAX,[SI+2Ch]

call ShowHexDWord

; FSINFO

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[SI+30h]

call ShowHexWord

inc [ScreenString]

mov [ScreenColumn],40

mov AX,[SI+32h]

call ShowHexWord

; отобр.№дисковода

inc [ScreenString]

mov [ScreenColumn],40

mov AL,[SI+40h]

call ShowByteHexCode

; от.№ ЛОГ.ДИСКА 

inc [ScreenString]

mov [ScreenColumn],40

mov EAX,[SI+43h]

call ShowHexDWord

; от.метку диска 

inc [ScreenString]

mov [ScreenColumn],40

mov BX,47h

mov CX,11

call ShowASCIIField

; ОТОБР.АБ.

inc [ScreenString]

mov [ScreenColumn],40

mov BX,52h

mov CX,8

call ShowASCIIField

@@End: call GetChar

pop ES

popad

ret

ENDP DecodeBootSector

;**********************************************

;ВЫВОД НА ЭКРАН ТЕКСТОВОГО ПОЛЯ ДАННЫХ

;**********************************************

PROC ShowASCIIField near

pusha

push ES

mov AX,0B800h

add SI,BX

; вычислить начальную позицию

mov AX,[ScreenString]

mov DI,160

mul DI

add AX,[ScreenColumn]

add AX,[ScreenColumn]

mov DI,AX

mov AH,[TextColorAndBackground]

@@NextChar:

lodsb

stosw

loop @@NextChar

pop ES

popa

ret

ENDP ShowASCIIField

ENDS

include "lst_7_07.inc"

END

Результат программы:

Вывод: данная программа обеспечивает просмотр в режиме LBA параметров логических дисков на «ведущем» жестком диске канала 1.На экран выводятся и начало раздела, и конец раздела, а также номер начального сектора и размер секторов.

Листинг программы 4:

;Программа, которая ищет в корневом каталоге

; «ведущего» диска канала 1 файл AUTOEXEC.BAT,

; считывает его и отображает на экране

IDEAL

P386

LOCALS

MODEL MEDIUM

include "lst_2_03.inc"

include "lst_2_05.inc"

;размер RootDirSize equ 32

FATAreaAddress equ 110000h

DATASEG

; Текстовые сообщения

Txt00 DB YELLOW,24,29,"Нажмите ",0

Txt20 DB YELLOW,0,25," FAT:",0

Txt30 DB YELLOW,0,23

DB "Сп ф корневого каталога :",0

Txt40 DB YELLOW,0,16,"Просмотр нач "

DB "гз бвЄ  д ©«  AUTOEXEC.BAT:",0

Err1 DB LIGHTRED,12,21

DB "Master-диск ­ на канале 1 не обнаружен.",0

Err2 DB LIGHTRED,12,24

DB "Диск не поддерживает режим LBA.",0

PBut DB YELLOW,24,29,"Нажмите люб кл",0

; Номер раздела

PartitionNumber DB ?

PriDOS_StartSector DD ?

BootSector DD ?

FATType DB ?

NextDrivePresent DB ?

SectorsInCluster DW ?

RSects DD ?

FATsOnDisk DW ?

FATSize DW ?

HiddenSectors DD ?

ENDS

SEGMENT sseg para stack 'STACK'

DB 400h DUP(?)

ENDS

CODESEG

;*****************************

;* Основной МОДУЛЬ *

;*****************************

PROC SearchAutoexecBat

mov AX,DGROUP

mov DS,AX

; текстовый режим

mov AX,3

int 10h

call Initialization

mov [ScreenString],25

mov [ScreenColumn],0

call SetCursorPosition

; опросить Master-диск

mov [ChannelNumber],1

mov [HDDNumber],0

call ReadHDD_ID

cmp [HDDErrorCode],0

jne @@DiskNotFound

cmp [dword ptr SectorDataBuffer+60*2],0

je @@LBANotSupported

mov [dword ptr SectorAddress],0

call ReadHDDSector

; зап номер нач сектора 

mov SI,offset SectorDataBuffer

add SI,1BEh

mov EAX,[SI+8]

mov [PriDOS_StartSector],EAX

; определить тип FAT

mov [FATType],1

mov EAX,[PriDOS_StartSector]

mov [SectorAddress],EAX

call ReadHDDSector

mov SI, offset SectorDataBuffer

movzx AX,[byte ptr SI+0Dh]

mov [SectorsInCluster],AX

movzx EAX,[word ptr SI+0Eh]

mov [RSects],EAX

movzx AX,[byte ptr SI+10h]

mov [FATsOnDisk],AX

mov AX,[SI+16h]

mov [FATSize],AX

; число скрытых секторов

mov EAX,[SI+1Ch]

mov [HiddenSectors],EAX

; ПРОЧИТАТЬ И ПОКАЗАТЬ FAT

call ClearScreen

mov SI,offset Txt20

call ShowColorString

mov SI,offset Txt00

call ShowColorString

mov EAX,[PriDOS_StartSector]

add EAX,[RSects]

mov [FATStartSect],EAX

mov [SectorAddress],EAX

mov EDI,FATAreaAddress

mov DX,[FATSize] ;бзҐвзЁЄ ᥪв®а®ў FAT

@@NextFATSector:

call ReadHDDSector

inc [dword ptr SectorAddress]

mov SI, offset SectorDataBuffer

mov CX,512

@@NextFATSectByte:

lodsb

mov [GS:EDI],AL

inc EDI

loop @@NextFATSectByte

dec DX

mov [ScreenString],2

mov [ScreenColumn],0

mov EDI,FATAreaAddress

mov CX,256

@@FAT: mov AX,[GS:EDI]

call ShowHexWord

inc [ScreenColumn]

add EDI,2

loop @@FAT

call GetChar

movzx EAX,[FATSize]

movzx EDX,[FATsOnDisk]

mul EDX

add EAX,[FATStartSect]

mov [RootDirStartSect],EAX

mov [SectorAddress],EAX

mov EDI,RootDirAddress

mov DX,RootDirSize

@@NextRootSector:

@@NextRootByte:

lodsb

mov [GS:EDI],AL

inc EDI

loop @@NextRootByte

dec DX

jnz @@NextRootSector

mov AX,0B800h

mov ES,AX

mov DI,160*2

mov ESI,RootDirAddress

mov AH,WHITE

mov DX,100 ;бзҐвзЁЄ § ЇЁбҐ©

@@NextFileName:

mov CX,11

@@NextNameByte:

mov AL,[GS:ESI]

stosw

inc [ScreenColumn]

inc ESI

loop @@NextNameByte

add DI,(16-11)*2

add ESI,32-11

dec DX

jnz @@NextFileName

call GetChar

call ClearScreen

mov SI,offset Txt40

call ShowColorString

mov SI,offset Txt00

call ShowColorString

; найти в корневом каталоге AUTOEXEC.BAT

mov ESI,RootDirAddress

mov CX,512 @@NextElement:

cmp [dword ptr GS:ESI],'OTUA'

jne @@NotAutoexec

cmp [dword ptr GS:ESI+4],'CEXE'

jne @@NotAutoexec

cmp [word ptr GS:ESI+8],'AB'

jne @@NotAutoexec

cmp [byte ptr GS:ESI+10],'T'

je @@AutoexecFileFound

@@NotAutoexec:

add ESI,32

loop @@NextElement

add EAX,[RootDirStartSect]

add EAX,RootDirSize

mov [FileStartSect],EAX

mov [SectorAddress],EAX

mov EDI,FileBufferAddress

mov DX,[SectorsInCluster]

@@NextFileSector:

call ReadHDDSector

inc [dword ptr SectorAddress]

mov SI, offset SectorDataBuffer

mov CX,512

@@NextFileByte:

lodsb

mov [GS:EDI],AL

inc EDI

loop @@NextFileByte

dec DX

jnz @@NextFileSector

mov AX,0B800h

mov ES,AX

mov DI,160*2

mov ESI,FileBufferAddress mov ECX,[FileSize mov DX,0 ;счетчик строк  

mov BX,0 ; счетчик колонок 

mov AH,LIGHTGREEN

@@Out1:

mov AL,[GS:ESI]

inc ESI

cmp AL,0Dh

jz @@Out2

; проверка символа

cmp AL,0Ah

jz @@Out3

; вывести символ на экран

stosw

inc BX

cmp BX,80

jb @@Out3

@@Out2: add DI,160

sub DI,BX

sub DI,BX

mov BX,0

inc DX

cmp DX,22

ja @@OutEnd

@@Out3: dec ECX

jnz @@Out1

@@OutEnd:

call GetChar

jmp short @@End

@@DiskNotFound:

mov SI,offset Err1

call ShowColorString

mov SI,offset PBut

call ShowColorString

call GetChar

jmp short @@End

@@LBANotSupported:

mov SI,offset Err1

call ShowColorString

mov SI,offset PBut

call ShowColorString

call GetChar

mov ax,3

int 10h

mov AH,4Ch

int 21h

ENDP SearchAutoexecBat

ENDS

include "lst_7_07.inc"

END

Результат программы:

Вывод: данная программа обеспечивает поиск в корневом каталоге «ведущего» диска канала 1 файл AUTOEXEC.BAТ,считывает его и отображает на экране. На экран выводится начальная область первой FAT, список файлов корневого каталога, просмотр начального участка файла AUTOEXEC.BAТ.

Листинг программы 5:

; Программа, выполняющая считывание загрузочного

; сектора Master-диска канала 1 в режиме DMA

IDEAL

P386

LOCALS

MODEL MEDIUM

include "lst_2_05.inc"

DATASEG

; Текстовые сообщения

Txt0 DB LIGHTCYAN,0,17

DB "ТЕСТИРОВАНИЕ РЕЖИМА DMA MASTER-ДИСКА КАНАЛА1",0

DB YELLOW,5,8,"Содержимое загрузочного сектора "

DB "Master-диск канала  1:",0

AnyK DB YELLOW,24,29,"нажмите клавишу",0

NoPCI DB LIGHTRED,12,18

DB "не поддерживается PCI BIOS",0

NoIDEC DB LIGHTRED,12,26

DB "Контроллер PCI IDE не найден,0

BadReg DB LIGHTRED,12,28,"неверный номер регистра ",0

NoHDD DB LIGHTRED,12,21

DB "Master-диск на канаое 1 не обнаружен",0

NoLBA DB LIGHTRED,12,24

DB "Диск не поддердивает LBA.",0

DErr1 DB LIGHTRED,12,8,"Тайм-аут "

DErr4 DB LIGHTRED,12,27,"неправильный номер канала.",0

DErr5 DB LIGHTRED,12,26," неправильный номер диска.",0

DErr6 DB LIGHTRED,12,17," неправильный номер головки"

DB "Ошибка при выполнении.",0

ENDS

; буфер для работы с диском в режиме DMA

SEGMENT DMA_BUF para public 'DATA'

DB 8000h DUP(?)

ENDS

; буфер для таблицы PRD

SEGMENT PRD_Table para public 'DATA'

DB 1024 DUP(?)

ENDS

SEGMENT sseg para stack 'STACK'

DB 400h DUP(?)

ENDS

CODESEG

;*****************************

;* ОСНОВНОЙ МОДУЛЬ ПРОГРАММЫ*

;*****************************

PROC IDE_DMA_Test

mov AX,DGROUP

mov DS,AX

; ТЕКС.РЕЖИМ

mov AX,3

int 10h

; скрыть курсор

mov [ScreenString],25

mov [ScreenColumn],0

call SetCursorPosition

; вывести заголовок на экран

mov SI,offset Txt0

call ShowColorString

call ShowColorString

; задать номер канала и номер диска 

mov [ChannelNumber],1

mov [HDDNumber],0

call HDD_Presence_Test

call SearchBusMasterIDEContr

mov AX,PRD_Table

mov ES,AX

xor EAX,EAX

mov AX,DMA_BUF

shl EAX,4

mov [ES:0],EA ; записать кол-во передаваемых байтов

mov [word ptr ES:4],512

mov [word ptr ES:6],8000h

xor EAX,EAX

mov AX,PRD_Table

shl EAX,4

; вычислить адрес регистра контроллера 

mov DX,[IDEContrRegsBaseAddr]

add DX,04h

out DX,EAX

call ReadBootSector

; окончание работы

@@End: mov AX,3

int 10h

; ‚л室 ў DOS

mov AH,4Ch

int 21h

ENDP IDE_DMA_Test

;**********************************************

;НАЙТИ КОНТРОЛЛЕР PCI И ОТОБРАЗИТЬ НА ЭКРАН

; СОДЕРЖИМОЕ РЕГИСТРОВ КОНФИГУРАЦИОННОГО ПРОСТРАНСТВА

;*********************************************

PROC SearchBusMasterIDEContr near

pushad

; проверить наличие PCI BIOS

mov AX,0B101h

int 1Ah

jc @@PCIBIOSNotFound

cmp EDX,20494350h

jne @@PCIBIOSNotFound

;найти контроллер Bus Master IDE по Клоду класса 

mov AX,0B103h

mov ECX,010180h ;первый вариант кода 

mov SI,0

int 1Ah

jnc @@ReadPCIRegisters

mov AX,0B103h

mov ECX,010185h ; второй вариант  

mov SI,0

int 1Ah

jnc @@ReadPCIRegisters

mov AX,0B103h

mov ECX,01018Ah ; третий 

mov SI,0

int 1Ah

jc @@DeviceNotFound

; устройство обнаружено, его координаты на PCI

mov AX,0B10Ah ;читать двойное слово

mov DI,20h ;смещение слова

int 1Ah

jc @@BadRegisterNumber

and CX,0FFF0h

mov [IDEContrRegsBaseAddr],CX

popad

ret

; неверный номер регистра

@@BadRegisterNumber:

mov SI,offset BadReg

call FatalError

@@DeviceNotFound:

mov SI,offset NoIDEC

call FatalError

@@PCIBIOSNotFound:

; не поддерживается PCI BIOS

mov SI,offset NoPCI

call FatalError

ENDP SearchBusMasterIDEContr

;**********************************************

;ПРВЕРИТЬ ПРИСУТСТВИЕ ДИСКА И НАЛИЧИК ПОДДЕРЖКИ LBA

;**********************************************

PROC HDD_Presence_Test near

pusha

cmp [HDDErrorCode],0

jne @@DiskNotFound

cmp [dword ptr SectorDataBuffer+60*2],0

je @@LBANotSupported

popa

ret

; обработка ошибок

@@DiskNotFound:

mov SI,offset NoHDD

call FatalError

@@LBANotSupported:

mov SI,offset NoLBA

call FatalError

ENDP HDD_Presence_Test

;*********************************************

;ПРОЧИТАТЬ ЗАГРУЗОЧНЫЙ СЕКТОР В РЕЖИМЕ DMA ;*********************************************

PROC ReadBootSector near

pushad

mov DX,[IDEContrRegsBaseAddr]

add DX,02h

mov AL,110b

out DX,AL

mov DX,[IDEContrRegsBaseAddr]

mov AL,0

out DX,AL

mov AL,1000b

out DX,AL

mov [ATAAddressMode],1

mov [dword ptr SectorAddress],0

mov [dword ptr ATASectorNumber],0

mov [ATAFeatures],0

mov [ATASectorCount],1

mov EAX,[SectorAddress]

; ПОСЛАТЬ КОМАНДУ ДИСКУ

mov [ATACommand],0C8h

call SendCommandToHDD

cmp [HDDErrorCode],0

jne @@

mov DX,[IDEContrRegsBaseAddr]

mov AL,1001b

out DX,AL

; ОЖИДАТЬ ГОТОВНОСТЬ ДАННЫХ HDD

mov AX,0

mov ES,AX

mov DX,[HDDBasePortAddr]

add DX,7

@@WaitCompleet:

; проверить время выполнения команды

mov EAX,[ES:046Ch]

sub EAX,[HDDTime]

cmp EAX,MaxHDDWaitTime

ja @@Err1

in AL,DX

test AL,88h

jnz @@WaitCompleet

; ожидать конца цикла  DMA

mov DX,[IDEContrRegsBaseAddr]

add DX,02h

@@WaitDMAOperationEnd:

in AL,DX

test AL,1

jnz @@WaitDMAOperationEnd

; сбросить упр.регистр канала 1 DMA

mov DX,[IDEContrRegsBaseAddr]

mov AL,0

out DX,AL

; отобразить на экран содержимое прочитанного сектора

; в ASCII-кодах

push DS

mov AX,DMA_BUF

mov DS,AX

mov AX,0B800h

mov ES,AX

mov DI,7*160+8*2

xor SI,SI

mov DX,8 ;бзҐвзЁЄ бва®Є

@@OutNextString:

mov CX,64 ; счетчик символов в строке

@@OutNextChar:

lodsb

stosw

loop @@OutNextChar

add DI,16*2

dec DX

jnz @@OutNextString

pop DS

mov SI,offset AnyK

call ShowColorString

call GetChar

popad

ret

; обработка ошибок

@@Error:

cmp [HDDErrorCode],1

je @@Err1

cmp [HDDErrorCode],2

je @@Err2

cmp [HDDErrorCode],3

je @@Err3

cmp [HDDErrorCode],4

je @@Err4

cmp [HDDErrorCode],5

je @@Err5

cmp [HDDErrorCode],6

je @@Err6

@@Err1: mov SI,offset DErr1

call FatalError

@@Err2: mov SI,offset DErr2

call FatalError

@@Err3: mov SI,offset DErr3

call FatalError

@@Err4: mov SI,offset DErr4

call FatalError

@@Err5: mov SI,offset DErr5

call FatalError

@@Err6: mov SI,offset DErr6

call FatalError

ENDP ReadBootSector

;**********************************************

; ФАТАЛЬНАЯ ОШИБКА

; ВЫДАТЬ СООБЩЕНИЕ И ВЫЙТИ ИЗ ПРОГРАММЫ

;**********************************************

PROC FatalError near

; вывести сообщение об ошибке

call ClearScreen

call ShowColorString

mov SI,offset AnyK

call ShowColorString

call GetChar

; аварийный выход

mov AH,4Ch

int 21h

ENDP FatalError

ENDS

include "lst_2_02.inc"

include "lst_7_07.inc"

END

Результат программы:

Вывод: данная программа выполняет считывание загрузочного сектора Master-диска канала 1 в режиме DMA. Но контроллер PCI не найден.

Листинг программы 6:

; Выполняем верификацию сектора (0-0-1)

; и диагностику с последующим анализом регистра ошибок

Ideal

Model Small

CodeSeg

StartUpCode ; основной модуль

mov dx, offset message0

call str_out ; вывод строки message0

call verify ; вызов процедуры верификации

call delay ; подождем немного

call diags ; вызов процедуры диагностики

call delay ; подождем немного

call read_status ; вызов процедуры чтения кода ошибки

call error_out ; вызов процедуры вывода на экран

; информации об ошибке

ExitCode ; конец основного модуля

;------------------------пауза--------------------------

proc delay

push cx bx

mov cx, 0ffffh

m1:

mov bx, 1000

m2:

dec bx

jnz m2

loop m1

pop bx cx

ret

endp

;----------------------команда запуска диагностики-------------

proc diags

mov dx, 1F7h ; регистр команд

mov al, 90h ; код команды диагностики

out dx, al ; передаем в порт

ret

endp

;---------------------верификация сектора 1 головки 0 цилиндра 0-------

proc verify

mov dx, 1F2h ; регистр кол-ва секторов

mov al, 1 ; проверяем сектор 1

out dx, al ; передаем в порт

mov dx, 1F3h ; регистр номера сектора

mov al, 1 ; сектор 1

out dx, al ; передаем в порт

mov dx, 1F4h ; регистр номера цилиндра старшая часть

xor al, al ; al = 0

out dx, al ; передаем в порт

mov dx, 1F5h ; регистр номера цилиндра младшая часть

xor al, al ; al = 0

out dx, al ; передаем в порт

mov dx, 1F6h ; регистр устройства и номера головки

xor al, al ; al = 0

out dx, al ; передаем в порт

mov dx, 1F7h ; регистр команд

mov al, 40h ; команда верификации с разрешением повтора

out dx, al ; передаем в порт

ret

endp

;-------------------чтение состояния КНЖМД--------------------------

;вход:

;выход: al - код ошибки

proc read_status

mov dx, 1F1h ; регистр ошибок

in al, dx ; al = код ошибки

ret

endp

;-----------------вывод ошибки на экран-----------------

;вход - al - код ошибки

proc error_out

mov dx, offset message1 ; смещение сообщения

call str_out ; вывод на экран

cmp al, 6 ; если код ошибки больше 6

ja m3 ; переходим на m3

dec al ; код ошибки уменьшили на 1,

; теперь al - индекс строк

mov dl, 32 ; длина текстового сообщения

mul dl ; получаем смещение нужной строки

; относительно первой

mov dx, offset err01 ; начало текстовых строк

add dx, ax ; получаем смещение нужной строки

; относительно начала сегмента данных

call str_out ; выводим на экран

jmp end_out

m3:

mov dx, offset err06 ; в dx - смещение строки err06

call str_out ; вывод строки на экран

end_out: ret

endp

;---------------вывод строки на экран--------------------

; вход - ds:dx - адрес строки для вывода

proc str_out

push ax

mov ah, 09h ; функция вывода строки на экран

int 21h ; вызываем

pop ax

ret

endp

DataSeg

message0 db "Идет диагностика КНЖМД...", 10, 13, '$'

message1 db "После операции диагностики регистр ошибок :",10, 13, '$'

;размер каждой строки - 32 байта

;это для правильной индексации при выводе строки об ошибке

err01 db "01h - нет ошибки ", 13, 10, '$'

err02 db "02h - ошибка КНЖМД ", 13, 10, '$'

err03 db "03h - ошибка буфферной памяти", 13, 10, '$'

err04 db "04h - ошибка схемы ECC ",13, 10, '$'

err05 db "05h - ошибка П ",13, 10, '$'

err06 db "??h - неизвестная ошибка (возможно запущен Windows)", 13, 10, '$'

END

Результат программы:

Вывод:данная программа Выполняет верификацию сектора (0-0-1) и диагностику с последующим анализом регистра ошибок. (01h – нет ошибки).