[英]how can I turn on caps lock's light in keyboard with assembly emu8086
如何使用组件emu8086打开键盘上的大写锁定指示灯
这是真的吗? 你能说出任何其他解决方案吗?
data segment
; add your data here!
pkey db "press any key...$"
ends
stack segment
dw 128 dup(0)
ends
code segment
start:
; set segment registers:
mov ax, data
mov ds, ax
mov es, ax
mov ax,0040h
mov es,ax
mov ax,0017h
mov di,ax
or byte [es:di],40h ; why are there erors -> ES:Dİ
mov ax, 4c00h ; exit to operating system.
int 21h
ends
end start ; set entry point and stop the assembler.
打开或关闭一个或多个键盘LED并不是在一个BIOS变量中写入单个值的简单问题!
它涉及输出到几个键盘的端口以及更新几个BIOS变量,以便BIOS和DOS仍然可以知道这些指示器的状态。
下一个程序可以完成设置CapsLock指标所需的全部工作。
该程序经过测试,在DOS 6.20等真正的DOS下完美运行。
如果程序输出“0”一切顺利,如果你看到“1”则指示器无法设置。
在仿效下会发生什么还有待观察。 DOSBox例如。 更改CapsLock条件但拒绝点亮相关的led。
ORG 256 ;Create .COM program
push ds
mov ax, 0040h ;BIOS data segment
mov ds, ax
mov dl, 00000100b ;Set CapsLock
call SetIndicators ; -> CF
pop ds
mov dl, "0"
adc dl, 0
mov ah, 02h ;Display character
int 21h
mov ah, 01h ;Wait for a key
int 21h
int 20h ;Terminate
; - - - - - - - - - - - - - - - - - - - - - - -
; IN (dl) OUT (CF)
SetIndicators:
test byte ptr [0097h], 01000000b
stc
jnz SetIndicators_3 ;Update in progress -> CF=1
push ax
push cx
push dx
and dl, 00000111b
mov al, dl
mov cl, 4
shl al, cl
and byte ptr [0017h], 10001111b
or [0017h], al
and byte ptr [0097h], 11111000b
or [0097h], dl
mov al, 0EDh ;Command to set KB leds
call SendToPort60
test byte ptr [0097h], 10000000b ;Was command acknowledged ?
jnz SetIndicators_1 ;No
mov al, dl
call SendToPort60
test byte ptr [0097h], 10000000b ;Was command acknowledged ?
jz SetIndicators_2 ;Yes
SetIndicators_1:
mov al, 0F4h ;Command to enable KB
call SendToPort60
SetIndicators_2:
and byte ptr [0097h], 00111111b ;OK -> CF=0
pop dx
pop cx
pop ax
SetIndicators_3:
ret
; - - - - - - - - - - - - - - - - - - - - - - -
; IN (IF=0) OUT ()
WaitForEmptyInbuffer:
push ax
push cx
mov cx, 03E3h
WaitForEmptyInbuffer_1:
in al, 61h
and al, 00010000b ;Toggles each refresh request
cmp al, ah
je WaitForEmptyInbuffer_1
mov ah, al
in al, 64h
test al, 00000010b ;Input buffer is full
loopnz WaitForEmptyInbuffer_1
pop cx
pop ax
ret
; - - - - - - - - - - - - - - - - - - - - - - -
; IN (al,ds=0040h) OUT ()
SendToPort60:
push ax
push bx
push cx
mov bh, al
mov bl, 3
SendToPort60_1:
cli
and byte ptr [0097h], 01001111b
call WaitForEmptyInbuffer
mov al, bh
out 60h, al ;This also enables KB !!!
sti ;STI is essential because FAh/
mov cx, 03E3h ; FEh arrive thru interrupt 9
SendToPort60_2:
test byte ptr [0097h], 00010000b ;Was aknowledged ?
jnz SendToPort60_4 ;Yes
test byte ptr [0097h], 00100000b ;Needs resending ?
jnz SendToPort60_3 ;Yes
in al, 61h
and al, 00010000b ;Toggles each refresh request
cmp al, ah
je SendToPort60_2
mov ah, al
loop SendToPort60_2
SendToPort60_3:
dec bl
jnz SendToPort60_1
or byte ptr [0097h], 10000000b ;Command was NOT aknowledged or
SendToPort60_4:
pop cx ; ... KB kept asking to resend!
pop bx
pop ax
cli
ret
; - - - - - - - - - - - - - - - - - - - - - - -
我使用了几个模拟器。 对于msdos,我使用dosbox和pcem。 我的问题是有时大写和虚拟机之间的大写锁定不同步。 我需要的是一个仅在虚拟机内更改大写锁定的程序。 从问题代码和tasm汇编程序我写道:
.286
.MODEL TINY
.CODE
ORG 100H
ENTRADA:
MOV AX, 0040H
MOV DS, AX
XOR BYTE PTR DS:[0017H], 40H
MOV AX, 4C00H
INT 21H
END ENTRADA
如果我编译这段代码,我得到一个15字节长的.com文件,它适用于dosbox和pcem。
谢谢阅读。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.