Читайте данную работу прямо на сайте или скачайте
Программа - резидент переключателя альтернативной кодировки (русификатор)
Институт Переподготовки Кадров
Уральского Государственного Технического ниверситета
Кафедра микропроцессорной техники
Оценка работы
Члены комиссии
ПРОГРАММА - РЕЗИДЕНТ
Курсовая работа
Пояснительная записка
Руководитель
к.т.н. доцент В. П. Кулюкин
Слушатель
Группа СП-913 А. А. Соколов
ЕКАТЕРИНБУРГ
1997
Содержание
ПОСТАНОВКА ЗАДАЧИ...................-
ВВЕДЕНИЕ............................3
1. ОПИСАНИЕ ПРОГРАММЫ...............4
1.1 ОБРАБОТКА 09 h. ................. .7
1.2 ОБРАБОТКА 1 0 h. ................. .9
ЗАКЛЮЧЕНИЕ..........................10
БИБЛИОГРАФИЧЕСКИЙ СПИСОК ...........11
ПРИЛОЖЕНИЕ 1 ТЕКСТ ПРОГРАММЫ........12
ВВЕДЕНИЕ
С самого начала существования IBM совместимых компьютеров встала проблема вывода на экран и ввода с клавиатуры символов кириллицы. Только начиная с версии MS DOS 6.0 появилась поддержка национальной 866 страницы. До появления версии MS DOS 6.0 проблему решали так называемые программы русификаторы. Эти программы замещали символы дополнительного кодового набора. Делалось это путем подстановки шрифта прошитого в ПЗУ видеодаптера своим. Эти программы были практически на каждом компьютере. Самыми известными из них являлись ENHFONT, KEYRUSS, LMSCR&LMKEY, KYRILLIC. Был еще один способ решить проблему русификации - перепрограммировать ПЗУ видеодаптера, но он не нашел большого применения.
1. ОПИСАНИЕ ПРОГРАММЫ
Поскольку данная программа относиться к типу программ, которые меняют шрифт загружающийся из ПЗУ видеодаптера, то сначала она открывает файл находящийся в этом же каталоге в котором находиться шрифт 8х16. После этого программа читает 4096 байт и помещает их в буфер. Затем загружаются полученные данные в видеобуфер, другими словами меняется текущий шрифт на новый. Следующий шаг программы это получение, сохранение и становка своих обработчиков 10 h и 09h прерываний. После данных операций программа завершает работу и остается резидентной используя 27 h прерывание, причем в регистре 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 10 h
Обработка 10 h программой представлена на рис. 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>
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 :
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 ;а 825А
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
;┌────────────────────────────────────────┐
;│ 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
movа di,0Ah ;смещение на начало видеобуфера
movа es,di ;будет адресоваться через сегмент доп. данных
xorа ah,ah ; чистка
imul di,ax,20h а ; ?????????????
push ds
push si
movа si,cs ;
movа ds,si ; для адресации данных станавливаем DS
leaа si,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
movа ax,di
movа cx,dx
shrа cx,1 ; cx /= 2
repа movsw
movа di,ax
addа di,20h
popа cx
loop @@All_symbols
leaа si,WRITE_OFF
call SetMode
pop es
pop di
pop si
pop dx
pop cx
pop ax
popf
ret
WRITE_ONа db 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
DispTypeа db 0Eh ; 0Eh - CGA/EGA/VGA 0Ah - MDA/HDA
LoadFont endp
SetMode proc
xor cx,cx
movа cl,2
movа dx,3C4hа ; делаем доступным
call @@Outport ; знакогенератор пользователя в памяти EGA
movа cl,3
movа dl,0CEh
@@Outport:
rep outsw
retn
SetMode endp
SetDisplayType proc
push ax
push es
xorа ax,ax
movа al,es:[0487h] ; а а какой у тебя адаптер ?
test al,2 ; EGA ?
jz @@Exit
movа al,0Ah ; MDA / HDA - значит
movа [DispType],al ; придется с ним работать
@@Exit:
pop es
pop ax
ret
SetDisplayType endp
NewFont db 16*256 dup(0)
END_TSR:
FileNameа db '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
jcа errorExit ; 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