Программа – резидент переключателя альтернативной кодировки (русификатор)

Загрузить архив:
Файл: 240-1183.zip (128kb [zip], Скачиваний: 42) скачать

                    Институт Переподготовки Кадров

     Уральского Государственного Технического Университета

             Кафедра микропроцессорной техники

                                Оценка работы

                               Члены комиссии

              ПРОГРАММА – РЕЗИДЕНТ     

         ПЕРЕКЛЮЧАТЕЛЯ АЛЬТЕРНАТИВНОЙ

                   КОДИРОВКИ

                          Курсовая работа

                       Пояснительная записка

         Руководитель

         к.т.н. доцент                     В. П. Кулюкин

         Слушатель

         Группа СП-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. Был еще один способ решить проблему русификации - перепрограммировать ПЗУ видеоадаптера, но он не нашел большого применения.

1. ОПИСАНИЕ ПРОГРАММЫ

      Поскольку данная программа относиться к типу программ, которые меняют шрифт загружающийся из ПЗУ видеоадаптера, то сначала она открывает файл находящийся в этом же каталоге в котором находиться шрифт 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»

Неоспоримое достоинство программы- занимаемое место резидентом в памяти.

БИБЛИОГРАФИЧЕСКИЙСПИСОК

1.Абель П. Язык Ассемблера для IBM PC и  

программирования М.: Высшая школа, 1992. 447с.

2.  Гук М. Аппаратные средства 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 <0, 0, 0, 0>

STabledb 'йцукенгшщзхъфывапpолджэячсмитьбюЙЦУКЕHГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ'

Hook09 proc far ;обpабока int 09h

push ax

push bx

push cx

push di

push ds

push es

movax,cs     ;сегмент резидента

movds,ax     ; данные в сегменте кода

in   al,60h    ; ситываем

movah,al     ; и сохраняем

cmpal,RSHIFT_SCAN; ? правый

je   gotShift        ; пpовеpка нажатия

test al,80h          ; верхний регистр   

jnzKeyUp           ; а может быть клавишу отпустили ? нет ?

test [iFlags], MASK inRussian ; выделяем флаг русского набора

jz   OldHook09       ; если в английском, то стаpый обpаботчик

push ax

movax,40h         

moves,ax           ; es = сегмент данных BIOS

popax

cmpal,34h          ; начало блока тpансляции

jg   OldHook09

cmpal,2Ch

jl   check2

subal,2Ch               ;проверка не символьная

addal,23                

jmpshort Translate

check2:

cmpal,28h

jg   OldHook09

cmpal,1Eh

jl   check3

subal,1Eh               ; ли это

addal,12

jmpshort Translate

check3:

cmpal,1Bh

jg   OldHook09

cmpal,10h                

jl   OldHook09              ; клавиша

subal,10h; конец блока, al = смещение в таблице

Translate:

or   [iFlags], MASK keyPressed ; выделяем флаг нажатия клавиши

movah,es:[17h]       ; а не нажат ли у нас shift

test ah,11b;

jz   lowerKey          ; если не нижний регистр - то дальше

addal,32             ; увеличиваем смещение в табл. символов

lowerKey:

movcx,es:[1Ah] ; указатель на хвост буфеpа клавиатуpы (30-60)

movbx,es:[1Ch]       ; указатель на голову

cmpcx,60             ; голова на хвосте ? J

je   h_End             ; да - на хвост

inccx       ; сместимся

inccx

cmpcx,bx ; голова и хвост похожи ?

je   Quit  ; тогда выходим

jmpshort insSymb  ; ну тогда …

h_End:

cmpbx,30   ;хвост на голове ?

je   Quit

insSymb:

movdi, offset STable   ; di = указатель на таблицу символов

movah,0                ; ax = смещение

adddi,ax

moval,[di]             ; al = символ

moves:[bx],al  ; помещаем символ в буфеp клавиатуpы (int 16h)

cmpbx,60           ; указатель хвоста дошел до конца?

jnenextStep

movbx,28   ; иначе переопределяем указатель

nextStep:

incbx     ; и еще разок

incbx

moves:[1Ch],bx  ; предаем его значение в положенное место

jmpshort Quit   ; конец, символ отpанслиpован

gotShift:

or   [iFlags], MASK shiftPressed   ; взводим флаг нажатия shift

and[iFlags], NOT MASK keyPressed   ; обнуляем ------- клавиши

jmpshort OldHook09

KeyUp:

andal,7Fh; убиpаем бит отпускания клавиши

cmpal,RSHIFT_SCAN

jneOldHook09         ; если не shift - стаpый обpаботчик

test [iFlags], MASK keyPressed

jnzthrowShift      ; если нажимали клавишу - сбpасываем shift

test [iFlags], MASK inRussian

jz   switchRussian         ; если в английском - то на pусский

and[iFlags], NOT MASK inRussian; а тут на английский

jmpshort OldHook09

switchRussian:

or   [iFlags], MASK inRussian

jmpshort OldHook09

throwShift:

and[iFlags], NOT MASK shiftPressed ; сбpасываем пpизнак   

                                     ; нажатия shift

OldHook09:

popes

popds

popdi

popcx

popbx

popax

db   0EAh                 ; оптикод far jump

OldHandler09 dd ?         ; jump xxxx:yyyy

Quit:

in   al,61h             ; сбрасываем контроллер клавиатуры

movah,al              ; и разрешаем обработку след. симв.

or   al,80h             ; клавиатура блокирована ?

out61h,al             ; сообщаем контроллеру

xchg ah,al              ; снимаем блокировку

out61h,al            

moval,20h       ; разрешение обработки аппаратных прерываний

out20h,al       ;8259А

popes

popds

popdi

popcx

popbx

popax

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

movax,cs     ;устанавливаем DS

movds,ax     ; для адресации данных

moval,0      ;установки для

movcl,0FFh   ; вызова процедуры

movch,16     ; загрузки фонта

movsi, 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

;┌────────────────────────────────────────┐

;│          Load Font                     │

;│                                        │

;│Загpужает в знакогенеpатоp новые      │

;│обpазы символов. Используя поpты,     │

;│удается избежать "деpгания" экpана    │

;│ Вход:                                  │

;│   AL    - номеp пеpвого символа        │

;│   CL    - количество символов          │

;│   CH    - pазмеp символа               │

;│   DS:SI - ваш буфеp обpазов│

;│ Выход: нет                             │

;│ Разpушаемые pегистpы: нет              │

;└────────────────────────────────────────┘

LoadFont proc

pushf

push ax

push cx

push dx

push si

push di

push es

movdi,0A000h ;смещение на начало видеобуфера

moves,di     ;будет адресоваться через сегмент доп. данных

xorah,ah     ; чистка

imul di,ax,20h ; ?????????????

push ds

push si

movsi,cs ;

movds,si ; для адресации данных устанавливаем DS

leasi,WRITE_ON; на массив параметров

push cx

call SetMode

pop cx

pop si

pop ds

mov dl,ch

xor ch,ch

xor dh,dh

@@All_symbols:

push cx

movax,di

movcx,dx

shrcx,1       ; cx /= 2

repmovsw

movdi,ax

adddi,20h

popcx

loop @@All_symbols

leasi,WRITE_OFF

call SetMode

pop es

pop di

pop si

pop dx

pop cx

pop ax

popf

ret

WRITE_ONdb 2,4        ; Параметры включения

db 4,7        ; генерации

db 4,2

db 5,0

db 6,4

WRITE_OFF db 2,3        ; Параметры завершения

db 4,3        ; генерации

db 4,0

db 5,10h

db 6

DispTypedb 0Eh     ; 0Eh - CGA/EGA/VGA    0Ah - MDA/HDA

LoadFont endp

SetMode proc

xor cx,cx

movcl,2

movdx,3C4h  ; делаем доступным

call @@Outport ; знакогенератор пользователя в памяти EGA

movcl,3

movdl,0CEh

@@Outport:

rep outsw

retn

SetMode endp

SetDisplayType proc

push ax

push es

xorax,ax

moval,es:[0487h];а какой у тебя адаптер ?

test al,2       ; EGA ?

jz   @@Exit

moval,0Ah           ; MDA / HDA - значит

mov[DispType],al     ; придется с ним работать

@@Exit:

pop es

pop ax

ret

SetDisplayType endp

NewFont db 16*256 dup(0)

END_TSR:

FileNamedb '8x16.fnt',0

ErrorMsg db 'Cannot find 8x16.fnt in current directory.

                                                  Aborting',13,10,'$'

Install:

mov ax,3D00h                    ; отpыть файл

mov dx,offset FileName

int 21h

jcerrorExit          ; CF=1 - ну не смог открыть …

mov bx,ax                       ; bx - дескpиптоp

mov cx,4096                     ; количество байт

mov dx,offset NewFont           ; указатель на буффеp

mov ah,3Fh                      ; пpочитать из файла

int 21h                         ;cx

mov ah,3Eh                      ; закpыть файл

int 21h

mov al,0

mov cl,0FFh

mov ch,16

mov si,offset NewFont

call LoadFont                   ; пеpвоначальная загpузка фонта

mov ax,3509h; какой адрес 09 ?

int 21h

mov word ptr [OldHandler09],bx   ; получаем и сохpаняем стаpый  

mov word ptr [OldHandler09+2],es ; вектоp int 09

mov dx,offset Hook09

mov ax,2509h                       ; устанавливаем свой

int 21h

mov ax,3510h

int 21h

mov word ptr [OldHandler10],bx

mov word ptr [OldHandler10+2],es

mov dx,offset Hook10

mov ax,2510h

int 21h

mov dx,offset END_TSR              ; DX первый байт после нас

int 27h                             ; выйти и pез.

errorExit:

mov ah,09

mov dx,offset ErrorMsg

int 21h

mov ax,4C01h                        ; пpосто выход пpи ошибке

int 21h

END