Скачиваний:
28
Добавлен:
15.09.2014
Размер:
14.56 Кб
Скачать

ПРИМЕР Файл lst_6_02.inc Запись шрифта в файл и считывание шрифта из файла в двоичном формате.

; Файл lst_6_02.inc, 19.04.2000. ; Автор текста программы Кулаков Владимир Геннадьевич. DATASEG ; Текстовые сообщения WrtFontErr DB LIGHTRED,12,23 DB "Ошибка при записи файла font0.fnt",0 NoFontFile DB LIGHTRED,12,16,"Ошибка: не удается " DB "открыть файл шрифта font0.fnt",0 PrKbButton DB YELLOW,24,29,"Нажмите любую клавишу",0 ; Имя для двоичного файла, содержащего шрифт BinFileName DB 'font0.fnt',0 ENDS CODESEG ;*************************************** ;* ЗАПИСАТЬ ШРИФТ В ДВОИЧНЫЙ ФАЙЛ * ;* Параметры: * ;* DS:DX - указатель на массив шрифта. * ;*************************************** PROC WriteFontFile NEAR pusha ; Создать файл для записи push DX mov AH,3Ch mov CX,0 ;доступ без ограничений mov DX,offset BinFileName ;имя файла int 21h jc @@Err mov BX,AX ;запомнить Handle в BX pop DX ; Записать данные в файл mov CX,4096 ;размер файла в байтах mov AH,40h int 21h jc @@Err ; Закрыть файл mov AH,3Eh int 21H jc @@Err popa ret ; Аварийный выход - ошибка при записи файла @@Err: ; Установить текстовый режим mov AX,3 int 10h ; Скрыть курсор mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Выдать сообщение об ошибке mov SI,offset WrtFontErr call ShowColorString mov SI,offset PrKbButton call ShowColorString call GetChar ; Выход в DOS mov AH,4Ch int 21h ENDP WriteFontFile ;*************************************** ;* ПРОЧИТАТЬ ШРИФТ ИЗ ФАЙЛА * ;* Параметры: * ;* DS:DX - указатель на массив шрифта. * ;*************************************** PROC ReadFontFile NEAR pushad ; Открыть файл для чтения push DX mov AH,3Dh mov AL,0 ;доступ "только для чтения" mov DX,offset BinFileName ;имя файла int 21h jc @@Err mov BX,AX ;запомнить Handle в BX pop DX ; Прочитать данные из файла mov CX,4096 ;размер файла в байтах mov AH,3Fh int 21h jc @@Err ; Закрыть файл mov AH,3Eh int 21H jc @@Err popad ret ; Аварийный выход - ошибка при чтении файла @@Err: ; Установить текстовый режим mov AX,3 int 10h ; Скрыть курсор mov [ScreenString],25 mov [ScreenColumn],0 call SetCursorPosition ; Выдать сообщение об ошибке mov SI,offset NoFontFile call ShowColorString mov SI,offset PrKbButton call ShowColorString call GetChar ; Выход в DOS mov AH,4Ch int 21h ENDP ReadFontFile ENDS Файл lst_6_07.inc Процедуры для непосредственной работы с контроллером жестких дисков ATA.

; Файл lst_6_07.inc, 24.04.2000. ; Автор текста программы Кулаков Владимир Геннадьевич. ; Максимальное время ожидания завершения операции ; (в "тиках") MaxHDDWaitTime equ 10 DATASEG ; Стандартные базовые адреса каналов 1 - 4 StandardHDDBases DW 1F0h, 170h, 1E8h, 168h ; Номер канала ChannelNumber DW ? ; Базовый адрес группы портов контроллера HDD HDDBasePortAddr DW ? ; Номер диска HDDNumber DB ? ; Параметры ATA-команды ATAFeatures DB ? ;особенности ATASectorCount DB ? ;количество обрабатываемых секторов ATASectorNumber DB ? ;номер начального сектора ATACylinder DW ? ;номер начального цилиндра ATAHead DB ? ;номер начальной головки ATAAddressMode DB ? ;режим адресации (0 - CHS, 1 - LBA) ATACommand DB ? ;код команды, подлежащей выполнению ; Код ошибки (0 - нет ошибок, 1 - превышен допустимый ; интервал ожидания, 2 - неверный код режима адресации, ; 3 - неверный номер канала, 4 - неверный номер диска, ; 5 - неверный номер головки, 6 - ошибка при выполнении ; команды) HDDErrorCode DB ? ; Момент начала очередной операции с диском HDDTime DD ? ; Адрес считываемого сектора в режиме LBA SectorAddress DD 0 ; Область памяти для хранения прочитанного сектора SectorDataBuffer DB 512 DUP (?) ENDS CODESEG ;************************************************* ;* ЧТЕНИЕ СЕКТОРА ЖЕСТКОГО ДИСКА В РЕЖИМЕ LBA * ;* Входные параметры передаются через глобальные * ;* перменные: * ;* ChannelNumber - номер канала (1 - 4); * ;* HDDNumber - номер диска на канале (0 или 1); * ;* SectorAddress - номер считываемого сектора. * ;* Сектор считывается основной сегмент данных, * ;* в массив SectorDataBuffer. * ;************************************************* PROC ReadHDDSector NEAR pushad push ES ; Задать режим LBA mov [ATAAddressMode],1 ; Послать команду чтения сектора (с повторами) mov [ATAFeatures],0 mov [ATASectorCount],1 mov EAX,[SectorAddress] mov [dword ptr ATASectorNumber],EAX mov [ATACommand],20h call SendCommandToHDD cmp [HDDErrorCode],0 jne @@End ;закончить, сохранив код ошибки ; Ожидать готовность данных 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 @@Error1 ;ошибка тайм-аута ; Проверить готовность in AL,DX test AL,80h ;состояние сигнала BSY jnz @@WaitCompleet test AL,08h ;состояние сигнала DRQ jz @@WaitCompleet ; Принять сектор mov AX,DGROUP mov ES,AX mov DI,offset SectorDataBuffer mov DX,[HDDBasePortAddr] ;регистр данных mov CX,256 ;число считываемых слов rep insw ;принять блок данных ; Сбросить признак ошибки mov [HDDErrorCode],0 jmp short @@End ; Записать номер ошибки @@Error1: mov [HDDErrorCode],1 ;ошибка тайм-аута jmp short @@End @@End: pop ES popad ret ENDP ReadHDDSector ;**************************************************** ;* ПОСЛАТЬ КОМАНДУ ЗАДАННОМУ ДИСКУ * ;* Входные параметры передаются через глобальные * ;* перменные: * ;* ChannelNumber - номер канала (1 - 4); * ;* HDDNumber - номер диска (0 или 1); * ;* ATAFeatures - "особенности"; * ;* ATASectorCount - количество секторов; * ;* ATASectorNumber - номер начального сектора; * ;* ATACylinder - номер начального цилиндра; * ;* ATAHead - номер начальной головки; * ;* ATAAddressMode - режим адресации (0-CHS, 1-LBA); * ;* ATACommand - код команды. * ;* После успешного выполнения функции: * ;* в SectorDataBuffer - прочитанный сектор; * ;* в HDDBasePortAddr - базовый адрес HDD; * ;* в HDDTime - момент начала выполнения команды; * ;* в HDDErrorCode - ноль. * ;* При возникновении ошибки в HDDErrorCode будет * ;* возвращен код ошибки. * ;**************************************************** PROC SendCommandToHDD near pushad push ES ; Запомнить время начала операции с диском ; Загрузить в ES сегмент данных BIOS mov AX,0 mov ES,AX ; Запомнить текущее время mov EAX,[ES:046Ch] mov [HDDTime],EAX ; Проверить значение кода режима cmp [ATAAddressMode],1 ja @@Error2 ; Проверить корректность номера канала mov BX,[ChannelNumber] cmp BX,1 jb @@Error3 cmp BX,4 ja @@Error3 ; Установить базовый адрес dec BX shl BX,1 mov AX,[BX+StandardHDDBases] mov [HDDBasePortAddr],AX ; Запретить прерывания от контроллера HDD mov DX,[HDDBasePortAddr] add DX,206h mov AL,1010b out DX,AL ; Ожидать "освобождения" HDD mov DX,[HDDBasePortAddr] add DX,7 ;адрес регистра состояния @@WaitNotBSY: ; Проверить время выполнения команды mov EAX,[ES:046Ch] sub EAX,[HDDTime] cmp EAX,MaxHDDWaitTime ja @@Error1 ;ошибка тайм-аута ; Проверить состояние сигнала BSY in AL,DX test AL,80h ;состояние сигнала BSY jnz @@WaitNotBSY ; Ожидание готовности HDD к приему команды ; Выбрать нужный диск mov DX,[HDDBasePortAddr] add DX,6 ;адрес регистра головок mov AL,[HDDNumber] cmp AL,1 ;проверить номера диска ja @@Error4 shl AL,4 or AL,10100000b out DX,AL ; Ожидать, пока диск не будет готов inc DX @@WaitHDReady: ; Проверить время выполнения команды mov EAX,[ES:046Ch] sub EAX,[HDDTime] cmp EAX,MaxHDDWaitTime ja @@Error1 ;ошибка тайм-аута ; Проверить состояние BSY и DRDY in AL,DX test AL,80h ;состояние сигнала BSY jnz @@WaitHDReady test AL,40h ;состояние сигнала DRDY jz @@WaitHDReady ; Загрузить команду в регистры контроллера mov DX,[HDDBasePortAddr] inc DX ;регистр "особенностей" mov AL,[ATAFeatures] out DX,AL inc DX ;счетчик секторов mov AL,[ATASectorCount] out DX,AL inc DX ;регистр номера сектора mov AL,[ATASectorNumber] out DX,AL inc DX ;номер цилиндра (младший байт) mov AX,[ATACylinder] out DX,AL inc DX ;номер цилиндра (старший байт) mov AL,AH out DX,AL inc DX ;номер головки/номер диска mov AL,[HDDNumber] shl AL,4 cmp [ATAHead],0Fh ;проверить номер головки ja @@Error5 or AL,[ATAHead] or AL,10100000b mov AH,[ATAAddressMode] shl AH,6 or AL,AH out DX,AL ; Послать команду mov AL,[ATACommand] inc DX ;регистр команд out DX,AL ; Сбросить признак ошибки mov [HDDErrorCode],0 jmp short @@End ; Записать код ошибки @@Error1: mov [HDDErrorCode],1 jmp short @@End @@Error2: mov [HDDErrorCode],2 jmp short @@End @@Error3: mov [HDDErrorCode],3 jmp short @@End @@Error4: mov [HDDErrorCode],4 jmp short @@End @@Error5: mov [HDDErrorCode],5 jmp short @@End @@End: pop ES popad ret ENDP SendCommandToHDD ;************************************************* ;* ЧТЕНИЕ ИДЕНТИФИКАТОРА ЖЕСТКОГО ДИСКА * ;* Входные параметры передаются через глобальные * ;* перменные: * ;* ChannelNumber - номер канала (1 - 4); * ;* HDDNumber - номер диска на канале (0 или 1). * ;* Идентификационный блок данных считывается * ;* в массив SectorDataBuffer. * ;************************************************* PROC ReadHDD_ID near pushad push ES ; Задать режим CHS mov [ATAAddressMode],0 ; Послать команду идентификации устройства mov [ATAFeatures],0 mov [ATAHead],0 mov [ATACommand],0ECh call SendCommandToHDD cmp [HDDErrorCode],0 ;проверить код ошибки jne @@End ;закончить, сохранив код ошибки ; Ожидать готовность данных 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 @@Error1 ;ошибка тайм-аута ; Проверить готовность in AL,DX test AL,80h ;состояние сигнала BSY jnz @@WaitCompleet test AL,1 ;состояние сигнала ERR jnz @@Error6 test AL,08h ;состояние сигнала DRQ jz @@WaitCompleet ; Принять блок данных от контроллера mov AX,DGROUP mov ES,AX mov DI,offset SectorDataBuffer mov DX,[HDDBasePortAddr] ;регистр данных mov CX,256 ;число считываемых слов rep insw ;принять блок данных jmp short @@End ; Записать код ошибки @@Error1: mov [HDDErrorCode],1 jmp short @@End @@Error6: mov [HDDErrorCode],6 @@End: pop ES popad ret ENDP ReadHDD_ID ENDS

Соседние файлы в папке Учебник