Программа-переключатель кодировки
Вопросы - Компьютеры, программирование
Другие вопросы по предмету Компьютеры, программирование
ПРОГРАММА РЕЗИДЕНТ ПЕРЕКЛЮЧАТЕЛЯ АЛЬТЕРНАТИВНОЙ КОДИРОВКИ
ВВЕДЕНИЕ
С самого начала существования 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
Неоспоримое достоинство программы - занимаемое место резидентом в памяти.
ПРИЛОЖЕНИЕ 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 ; голова на хвосте ?
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