PDA

Просмотр полной версии : статус клавиш num, caps и scroll lock



Alex_Burn
17.04.2008, 19:45
Здравствуйте, уважаемые участники форума!
Подскажите, пожалуйста, как изменять статус клавиш num lock, caps lock и scroll lock
(ну и лампочки заодно).

airyashov
18.04.2008, 00:13
----------

Alex_Burn
18.04.2008, 19:49
К сожалению не все понял изсказанного вами.

1. Какое отношение к программе будет иметь адрес 0040:0017

2. Что значит


ждать ACK (FAh)


3.



послать данные байт в 64h, три младших бита это скрол(0), нан(1), капс (2), 1-вкл, 0-выкл


Это что-то вроде




mov ax,1b
out 64,ax ;scroll

mov ax,10b
out 64,ax ;num

mov ax,100b
out 64,ax ;caps

?

Или нет?

airyashov
19.04.2008, 00:13
.model small
.stack 100h
.data
flag db 111b

.code
.startup

wait1:
; ожидание возможности посылки команды
in al,64h ; прочитать слово состояния
test al,10b ; бит 1 установлен?
jnz wait1; если нет ждем

mov al,0EDh
out 60h,al ; команда клавиатуры EDh

wait2:
; ожидание возможности посылки команды
in al,64h ; прочитать слово состояния
test al,10b ; бит 1 установлен?
jnz wait2; если нет ждем,

mov al,flag
out 60h,al ; новое состояние светодиодов

not flag
and flag,111b

mov ax,0700h ; ожидаем нажатие на клавишу
int 21h
cmp al,27;Esc
jne wait1

mov ax,4c00h
int 21h
end
запуск чистый дос

Alex_Burn
19.04.2008, 17:59
airyashov, что-то прога ничего не делает...
Что значит


ожидание возможности посылки команды
?

airyashov
20.04.2008, 22:53
Под чистый дос, под винду не пашет!
1 бит в 64h порте - проверка готовности клавы принять данные.

BBB
21.04.2008, 12:23
Вообще-то, как это ни может показаться невероятным, для "зажигания"/"тушения" клавиш достаточно изменить соответсвующие биты в в соответствующем байте в области данных BIOS (40h:17h)

Например, следующий код "тушит" NumLock:

.model tiny
.Code
Org 100h
Start:
Xor Ax,Ax
Mov Es,Ax
And byte ptr Es:[0417h],(not 20h)
Ret
End Start


Биты, сответсвующие клавишам:

Bit Val Meaning
7 $80 Insert on
6 $40 Caps Lock on
5 $20 Num Lock on
4 $10 Scroll Lock on
3 $08 <Alt> depressed
2 $04 <Ctrl> depressed
1 $02 <LeftShift> depressed
0 $01 <RightShift> depressed

airyashov
21.04.2008, 12:39
Весело, Я всегда считал что они отражают состояние клавиш, но не управляют.

BBB
21.04.2008, 14:05
Весело, Я всегда считал что они отражают состояние клавиш, но не управляют. Я тоже когда-то так считал. Потом вдруг опытным путем ообнаружил, что и на смену значения бита клавиша (и "огонек") тоже реагируют.
Возможно, эта "фигня" началась с AT-шек. Т.е., возможно, на XT такой фокус не проходил. Но наверняка уже не скажу. Дааавно здесь сидим (c) :)

Alex_Burn
21.04.2008, 17:46
Хм...
BBB, а ваш код тоже под винду не пашет?
А то созданная программа никак не влияет на индикаторы клавы. :(

BBB
22.04.2008, 09:41
Хм...
а ваш код тоже под винду не пашет?
А то созданная программа никак не влияет на индикаторы клавы. :( Попробовал под Win2000 - не "зажигает". Под Win98 - нормально отрабатывает.

Может, под виндами в таком случае через WinAPI, через SetKeyboardState? (Не знаю, насколько необходимо сделать это все через ассемблер).

BBB
22.04.2008, 09:47
В MSDN-е в описании ф-ии keybd_event наткнулся на пример, который как раз переключает NUM LOCK.

Example Code
The following sample program toggles the NUM LOCK light by using keybd_event()
with a virtual key of VK_NUMLOCK. It takes a Boolean value that indicates whether the
light should be turned off (FALSE) or on (TRUE). The same technique can be used for
the CAPS LOCK key (VK_CAPITAL) and the SCROLL LOCK key (VK_SCROLL).

#include <windows.h>

void SetNumLock( BOOL bState )
{
BYTE keyState[256];

GetKeyboardState((LPBYTE)&keyState);
if( (bState && !(keyState[VK_NUMLOCK] & 1)) ||
(!bState && (keyState[VK_NUMLOCK] & 1)) )
{
// Simulate a key press
keybd_event( VK_NUMLOCK,
0x45,
KEYEVENTF_EXTENDEDKEY | 0,
0 );

// Simulate a key release
keybd_event( VK_NUMLOCK,
0x45,
KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP,
0);
}
}

void main()
{
SetNumLock( TRUE );
}

А, вот еще примечание для keybd_event:
Windows NT/2000/XP: This function has been superseded. Use SendInput instead.

Alex_Burn
22.04.2008, 13:39
Не знаю, насколько необходимо сделать это все через ассемблер


Ну желательно конечн в АСМе


Под Win98 - нормально отрабатывает.

Где же я 98-ю Винду-то возьму?.. :(

Пардон за тупой вопрос, но как проги из под DOS запускать? (Просто я этого никогда не делал)

BBB
22.04.2008, 14:17
Пардон за тупой вопрос, но как проги из под DOS запускать? (Просто я этого никогда не делал) Вопрос не совсем ясен. Уточните.

Alex_Burn
22.04.2008, 14:43
Ну, г-н airyashov писал что прога пашет под чистый DOS.

Вот я и подумал, возможно ли не запускать винду, а заходить через DOS (в смысле, через загрузочную дискету, если, конечно данное действие возможно)

Я пытался решить данную проблему следующим путем:

Скачал эмулятор DOS. Но он почему-то не работает. Можно работать только на виртуальной дискете, а на HDD заходить не хочет, говорит что-то типа 'Invalid Drive C:'. Правда я пытался эмулировать DOS на ноуте, где у меня гибкого дисковода нет, может в этм проблема. Хотя, виртуалбно он есть.

В общем, мне хочется увидеть работоспособность проги, но пока не выходит... :-(

somewhere
22.04.2008, 16:55
DOS Box 0.72 в помощь...

Alex_Burn
22.04.2008, 17:22
DOS Box 0.72 в помощь...
Пробовал, прога из поста 4 данной темы на индикаторы не влияет

Alex_Burn
22.04.2008, 19:57
Пробовал запускать через DOSBox и код любезно предоставленный airyashov, и код уважаемого BBB, но, к сожалению, никакого эффекта программы на индикаторы клавы. :(
Может быть, у кого-нибудь будут еще мысли по данному вопросу? :confused:
Я пока пошел вешаться... :(

airyashov
23.04.2008, 08:56
чистый DOS - это загрузочная дискете, либо какой-нить реанимационный диск, либо NERO создайте загрузочный CD с DOS. Загружаете компутер с такого носителя и проверяйте программы.

Alex_Burn
23.04.2008, 09:03
чистый DOS - это загрузочная дискете, либо какой-нить реанимационный диск, либо NERO создайте загрузочный CD с DOS. Загружаете компутер с такого носителя и проверяйте программы.


Нельзя ли по подробней как это осуществить.
Ну, загрузочную дискету я уже создал.
Можно ли описать мне мои дальнейшие действия?

airyashov
23.04.2008, 10:30
скопировать на неё так же программу, дискету в дисковод, в биосе первое загрузка с дискеты (или F8/Esc/F12/F11 для выбора бут меню если есть, для разных матерей по разному) и затем запустить программу.
если подробнее надо можно и подробнее написать

Alex_Burn
26.04.2008, 18:06
Спасибо большое всем за помощь!!! Разобрался.

Оставляю потомкам следующий код. Циклическое переключение светодиодов клавиатуры.



.model tiny
.code
org 100h ; COM-программа

start proc near
mov ah,2 ; функция 02 прерывания 1Ah
int 1Ah ; получить текущее время
mov ch,dh ; сохранить текущую секунду в CH
mov cl,0100b ; CL = состояние светодиодов клавиатуры

main_loop:
call change_LEDs ; установить светодиоды в соответствии с CL

shl cl,1 ; следующий светодиод,
test cl,1000b ; если единица вышла в бит 3,
jz continue
mov cl,0001b ; вернуть ее в бит 0,
continue:
mov ah,1 ; проверить, не была ли нажата клавиша,
int 16h
jnz exit_loop ; если да - выйти из программы
push cx
mov ah,2 ; функция 02 прерывания 1Ah
int 1Ah ; получить текущее время
pop cx
cmp ch,dh ; сравнить текущую секунду в DH с CH
mov ch,dh ; скопировать ее в любом случае,
je continue ; если это была та же самая секунда - не
; переключать светодиоды,
jmp short main_loop ; иначе - переключить светодиоды

exit_loop:
mov ah,0 ; выход из цикла - была нажата клавиша
int 16h ; считать ее
ret ; и завершить программу
start endp

; процедура change_LEDs
; устанавливает состояние светодиодов клавиатуры в соответствии с числом в CL
change_LEDs proc near
call wait_KBin ; ожидание возможности посылки команды
mov al,0EDh
out 60h,al ; команда клавиатуры EDh
call wait_KBin ; ожидание возможности посылки команды
mov al,cl
out 60h,al ; новое состояние светодиодов
ret
change_LEDs endp

; процедура wait_KBin
; ожидание возможности ввода команды для клавиатуры
wait_KBin proc near
in al,64h ; прочитать слово состояния
test al,0010b ; бит 1 равен 1?
jnz wait_KBin ; если нет - ждать,
ret ; если да - выйти
wait_KBin endp
end start



Под ХР не работает, но с загрузочной дискетки работает замечательно. По слухам под 98-ю Винду тоже работает. Может кому проигодится.

Еще раз всем спасибо!