Институт Переподготовки Кадров Уральского Государственного Технического Университета Кафедра микропроцессорной техники Оценка работы Члены комиссии ПРОГРАММА – РЕЗИДЕНТ ПЕРЕКЛЮЧАТЕЛЯ АЛЬТЕРНАТИВНОЙ КОДИРОВКИ Курсовая работа Пояснительная записка Руководитель к. т. н. доцент В. П. Кулюкин Слушатель Группа СП-913 А. А. Соколов ЕКАТЕРИНБУРГ 1997 Содержание ПОСТАНОВКА ЗАДАЧИ............................ ВВЕДЕНИЕ..........................................3 1. ОПИСАНИЕ ПРОГРАММЫ...................... 4 1. 1 ОБРАБОТКА 09h............................ 7 1. 2 ОБРАБОТКА 10h............................ 9 ЗАКЛЮЧЕНИЕ.......................................10 БИБЛИОГРАФИЧЕСКИЙ СПИСОК ................ 11 ПРИЛОЖЕНИЕ 1 ТЕКСТ ПРОГРАММЫ............12 ВВЕДЕНИЕ
С самого начала существования IBM совместимых компьютеров встала проблема вывода на экран и ввода с клавиатуры символов кириллицы. Только начиная с версии MS DOS 6. 0 появилась поддержка национальной 866 страницы. До появления версии MS DOS 6. 0 проблему решали так называемые программы русификаторы. Эти программы замещали символы дополнительного кодового набора. Делалось это путем подстановки шрифта прошитого в ПЗУ видеоадаптера своим. Эти программы были практически на каждом компьютере. Самыми известными из них являлись ENHFONT, KEYRUSS, LMSCR&LMKEY, KYRILLIC. Был еще один способ решить проблему русификации - перепрограммировать ПЗУ видеоадаптера, но он не нашел большого применения. ОПИСАНИЕ ПРОГРАММЫ
Поскольку данная программа относиться к типу программ, которые меняют шрифт загружающийся из ПЗУ видеоадаптера, то сначала она открывает файл находящийся в этом же каталоге в котором находиться шрифт 8х16. После этого программа читает 4096 байт и помещает их в буфер. Затем загружаются полученные данные в видеобуфер, другими словами меняется текущий шрифт на новый. Следующий шаг программы это получение, сохранение и установка своих обработчиков 10h и 09h прерываний. После данных операций программа завершает работу и остается резидентной используя 27h прерывание, причем в регистре DX находится первый байт памяти после резидентной части программы. Общая логика работы показана на рис. 1. 1 и 1. 2 Рис. 1. 1 Рис. 1. 2 1. 1 ОБРАБОТКА INT 09h Обработка 09h программой представлена на рис. 1. 3 и 1. 4 Рис. 1. 3 Рис. 1. 4 1. 2 ОБРАБОТКА INT 10h Обработка 10h программой представлена на рис. 1. 5 Рис. 1. 5 ЗАКЛЮЧЕНИЕ Данная программа имеет следующие недостатки: Может использоваться только в ДОС - режиме Клавиша переключающая раскладки неизменяемая
Во время работы программы файл со шрифтом должен находиться в том же каталоге, где находится русификатор Файл шрифта должен быть только с именем “8х16. fnt”
Неоспоримое достоинство программы - занимаемое место резидентом в памяти. БИБЛИОГРАФИЧЕСКИЙ СПИСОК Абель П. Язык Ассемблера для IBM PC и программирования М. : Высшая школа, 1992. 447с. Гук М. Аппаратные средства IBM PC СПб. : Питер, 1996. 224с. ПРИЛОЖЕНИЕ 1 ТЕКСТ ПРОГРАММЫ . MODEL TINY ; Все сегменты в одном . CODE ; Как ком файл . STARTUP . 286 LOCALS ; Близкие переходы JUMPS jmp Install RSHIFT_SCAN EQU 36h ; RSHIFT scan code
FLAGS record inRussian: 1, shiftPressed: 1, keyPressed: 1, reserved: 6 iFlags FLAGS
STable db 'йцукенгшщзхъфывапpолджэячсмитьбюЙЦУКЕHГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ' Hook09 proc far ; обpабока int 09h push ax push bx push cx push di push ds push es mov ax, cs ; сегмент резидента mov ds, ax ; данные в сегменте кода in al, 60h ; ситываем mov ah, al ; и сохраняем cmp al, RSHIFT_SCAN ; ? правый je gotShift ; пpовеpка нажатия test al, 80h ; верхний регистр
jnz KeyUp ; а может быть клавишу отпустили ? нет ? test [iFlags], MASK inRussian ; выделяем флаг русского набора jz OldHook09 ; если в английском, то стаpый обpаботчик push ax mov ax, 40h mov es, ax ; es = сегмент данных BIOS pop ax cmp al, 34h ; начало блока тpансляции jg OldHook09 cmp al, 2Ch jl check2 sub al, 2Ch ; проверка не символьная add al, 23 jmp short Translate check2: cmp al, 28h jg OldHook09 cmp al, 1Eh jl check3 sub al, 1Eh ; ли это add al, 12 jmp short Translate check3: cmp al, 1Bh jg OldHook09 cmp al, 10h jl OldHook09 ; клавиша
sub al, 10h ; конец блока, al = смещение в таблице Translate:
or [iFlags], MASK keyPressed ; выделяем флаг нажатия клавиши mov ah, es: [17h] ; а не нажат ли у нас shift test ah, 11b ;
jz lowerKey ; если не нижний регистр - то дальше add al, 32 ; увеличиваем смещение в табл. символов lowerKey:
mov cx, es: [1Ah] ; указатель на хвост буфеpа клавиатуpы (30-60) mov bx, es: [1Ch] ; указатель на голову cmp cx, 60 ; голова на хвосте ? J je h_End ; да - на хвост inc cx ; сместимся inc cx cmp cx, bx ; голова и хвост похожи ? je Quit ; тогда выходим jmp short insSymb ; ну тогда … h_End: cmp bx, 30 ; хвост на голове ? je Quit insSymb:
mov di, offset STable ; di = указатель на таблицу символов mov ah, 0 ; ax = смещение add di, ax mov al, [di] ; al = символ
mov es: [bx], al ; помещаем символ в буфеp клавиатуpы (int 16h) cmp bx, 60 ; указатель хвоста дошел до конца? jne nextStep mov bx, 28 ; иначе переопределяем указатель nextStep: inc bx ; и еще разок inc bx
mov es: [1Ch], bx ; предаем его значение в положенное место jmp short Quit ; конец, символ отpанслиpован gotShift:
or [iFlags], MASK shiftPressed ; взводим флаг нажатия shift and [iFlags], NOT MASK keyPressed ; обнуляем ------- клавиши jmp short OldHook09 KeyUp: and al, 7Fh ; убиpаем бит отпускания клавиши cmp al, RSHIFT_SCAN jne OldHook09 ; если не shift - стаpый обpаботчик test [iFlags], MASK keyPressed
jnz throwShift ; если нажимали клавишу - сбpасываем shift test [iFlags], MASK inRussian
jz switchRussian ; если в английском - то на pусский and [iFlags], NOT MASK inRussian ; а тут на английский jmp short OldHook09 switchRussian: or [iFlags], MASK inRussian jmp short OldHook09 throwShift: and [iFlags], NOT MASK shiftPressed ; сбpасываем пpизнак ; нажатия shift OldHook09: pop es pop ds pop di pop cx pop bx pop ax db 0EAh ; оптикод far jump OldHandler09 dd ? ; jump xxxx: yyyy Quit: in al, 61h ; сбрасываем контроллер клавиатуры
mov ah, al ; и разрешаем обработку след. симв. or al, 80h ; клавиатура блокирована ? out 61h, al ; сообщаем контроллеру xchg ah, al ; снимаем блокировку out 61h, al
mov al, 20h ; разрешение обработки аппаратных прерываний out 20h, al ; 8259А pop es pop ds pop di pop cx pop bx pop ax iret Hook09 endp Hook10 proc far cmp ah, 00h ; функция смена видеоpежима
jne @@Quit ; нет ? передаем управление старому обработчику cmp al, 2 ; видеорежим 2 или 3 ? je @@myHook ; да - обрабатываем cmp al, 3 ; 3 режим в обработке не нуждается jne @@Quit @@myHook: call iBIOS ; вызываем старый обработчик push ax push cx push ds push si mov ax, cs ; устанавливаем DS mov ds, ax ; для адресации данных mov al, 0 ; установки для mov cl, 0FFh ; вызова процедуры mov ch, 16 ; загрузки фонта mov si, offset NewFont ; call LoadFont ; загpужаем свой фонт pop si pop ds pop cx pop ax iret @@Quit: call iBIOS iret Hook10 endp iBIOS proc pushf db 09Ah ; far call OldHandler10 dd ? ret iBIOS endp ;