flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Low level keyboard detection

Author
Thread Post new topic Reply to topic
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 28 Jan 2007, 20:42
Note:

http://board.flatassembler.net/topic.php?t=6585

This ^^^ is NOT what I am searching for ... Rolling Eyes

Is there a good way to detect keypresses without BIOS ? Found out that
after CLI the thing no longer reacts to CTL-ALT-DEL ... but reboots as soon
as STI occurs Shocked

How to detect keypresses after CLI ? And is there a good way to deactivate
the collecting/buffering of keypresses ? I am interested only in a keypress
at the moment of detection, not all the garbage that might have
been typed before ...

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 28 Jan 2007, 20:42
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8356
Location: Kraków, Poland
Tomasz Grysztar 28 Jan 2007, 21:11
Most probably all the information you need may be found in Ralph Brown's interrupt list (PORTS.LST for ports 60h-64h description, INTERRUPT.LST for list of scan codes in Table 00006).

For a very quick and dirty sample, this should wait for an Esc key:
Code:
        cli
clear_input_buffer:
        in      al,64h
        test    al,1
        jz      wait_for_key
        in      al,60h
        jmp     clear_input_buffer
wait_for_key:
        in      al,64h
        test    al,1
        jz      wait_for_key
        in      al,60h
        cmp     al,1 ; scan code of Esc
        jne     wait_for_key    
Post 28 Jan 2007, 21:11
View user's profile Send private message Visit poster's website Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u 28 Jan 2007, 22:53
If your making a game and need multi keypress, let me know as i have code for that.
Post 28 Jan 2007, 22:53
View user's profile Send private message Reply with quote
Japheth



Joined: 26 Oct 2004
Posts: 151
Japheth 29 Jan 2007, 16:23
PS/2 mouse data will also be send thru port 60h, something which is often forgotten when polling ports 60h/64h. Bit 5 of port 64h should tell if data at 60h is from the mouse.
Post 29 Jan 2007, 16:23
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 31 Jan 2007, 20:07
Note : post edited , example updated , old confusing junk kicked
Code:
;Code:
;        cli
;clear_input_buffer:
;        in      al,64h
;        test    al,1
;        jz      wait_for_key
;        in      al,60h
;        jmp     clear_input_buffer
;wait_for_key:
;        in      al,64h
;        test    al,1
;        jz      wait_for_key
;        in      al,60h
;        cmp     al,1 ; scan code of Esc
;        jne     wait_for_key;
;
; PS/2 mouse data will also be send thru port 60h,
; something which is often forgotten when polling ports 60h/64h.
; Bit 5 of port 64h should tell if data at 60h is from the mouse.
;
; F3h    double  set typematic rate/delay
;                format of the second byte:
;                bit7=0 : reserved
;                bit6-5 : typemativ delay
;                         00b=250ms     10b= 750ms
;                         01b=500ms     11b=1000ms
;                bit4-0 : typematic rate (see #P0391)
; F4h    sngl    enable keyboard
; F5h    sngl    disable keyboard. set default parameters (no keyboard scanning)
; F6h    sngl    set default parameters
; F7h    sngl    [MCA] set all keys to typematic (scancode set 3)
; F8h    sngl    [MCA] set all keys to make/release
; F9h    sngl    [MCA] set all keys to make only
; FAh    sngl    [MCA] set all keys to typematic/make/release
; FBh    sngl    [MCA] set al keys to typematic
; FCh    double  [MCA] set specific key to make/release
; FDh    double  [MCA] set specific key to make only
; FEh    sngl    resend last scancode
; FFh    sngl    perform internal power-on reset function
; Note: each command is acknowledged by FAh (ACK), if not mentioned otherwise.
;
; 00000b=30.0   10000b=7.5
; 00001b=26.7   10001b=6.7
; 01110b= 8.5   11110b=2.1
; 01111b= 8.0   11111b=2.0
;
; http://www.computer-engineering.org/ps2keyboard/
;

   format binary as "COM"
   use16
   org $0100

     push $B800
     pop ds           ; !!!

     cli

@@:  in   al,$64
     test al,2
     jnz  @b
     nop
     mov  al,$F3
     out  $60,al
     nop
@@:  in   al,$64
     test al,2
     jnz  @b
     nop
     mov  al,$7F
     out  $60,al
     nop

     mov ch,10      ; After 10 <ESC>'s abort
     mov bx,0
     mov al,0
@@:  mov [bx],al
     inc bx
     inc bx
     cmp bx,4000
     jne @b         ; Clear screen
     mov bx,0

xloop: in al,$64
       test al,1
       jz xloop     ; Is there something ???? NO -> looping

       and al,$20   ; Isolate bit 5 (mouse)
       shr al,5
       add al,$30
       mov dl,al    ; Save bit in dl

       in al,$60    ; Pick key or mouse code
       mov dh,al    ; Save code in dh

       mov ah,al
       and al,$0F   ; Low nibble
       shr ah,4     ; High nibble
       add ax,$3030
       cmp al,$3A
       jb @f
       add al,7
@@:    cmp ah,$3A
       jb @f
       add ah,7
@@:
       mov [bx],dl    ; Output mouse bit
       mov [bx+2],ah  ; Output keycode
       mov [bx+4],al  ; Output keycode
       add bx,8
       cmp bx,4000    ; 2*2000, 25*80=2000
       jnz @f
       mov bx,0
@@:    cmp dh,1       ; <ESC> aborts, but at 10th attempt !!!
       jne xloop      ; Not <ESC>
       dec ch
       jnz xloop      ; Not yet 10 <ESC>'s

       sti
       mov ax,$0003
       int $10        ; Set 25 lines mode and clear screen
       mov ax,$4C00
       int $21
;END.
    


Last edited by DOS386 on 18 Dec 2007, 02:15; edited 2 times in total
Post 31 Jan 2007, 20:07
View user's profile Send private message Reply with quote
Japheth



Joined: 26 Oct 2004
Posts: 151
Japheth 01 Feb 2007, 11:50
> But doesn't. Seems to work on some PC's only. For me the bit is
> always 1 and this is bad.

I haven't analyzed your code, but what is suspicious:

or al,$20 ; Isolate bit 5 (mouse)

with "or" you will not "isolate" a bit, this is done with

and al, $20
Post 01 Feb 2007, 11:50
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 01 Feb 2007, 19:47
Quote:
but what is suspicious:


Well, it's more than suspicious: it IS the bug. Shocked

Quote:
will not "isolate" a bit, this is done with


I know ... I must have had a blackout when coding the thing Sad

And the port docs gave me "right":

Code:
Bitfields for keyboard controller read status (MCA):
Bit(s)  Description     (Table P0399)
 7      parity error on transmission from keyboard
 6      general timeout
 5      mouse output buffer full
    


This is ^^^ good Smile

Code:
Bitfields for keyboard controller read status (ISA, EISA):
Bit(s)  Description     (Table P0398)
 7      parity error on transmission from keyboard
 6      receive timeout
 5      transmit timeout
    


But ^^^ this is bad Sad - do I have to bother ? Confused

Now it works on the one PC I tested so far Smile

Any comments on the remaining issues ?

Is the keypress buffering (+mouse buffering and messing it into same
buffer Sad ) hard-wired in the hardware, with no possibility to deactivate ?

What are the limitations of this method ? Down to pre-PS/2 80386 PC's ?
USB keyboards ?

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 01 Feb 2007, 19:47
View user's profile Send private message Reply with quote
Japheth



Joined: 26 Oct 2004
Posts: 151
Japheth 01 Feb 2007, 20:38
> Is the keypress buffering (+mouse buffering and messing it into same
> buffer Sad ) hard-wired in the hardware, with no possibility to deactivate ?

both keyboard and ps/2 mouse can be deactivated (RBIL, ports.A).

But why polling the keyboard anyway? Disabling interrupts while waiting for a keystroke will almost certainly loose timer interrupts, which is rather bad.

The two devices use different IRQs (kbd IRQ 1, mouse IRQ 12), so if you want to poll the keyboard only, you can selectively disable IRQ 1 (PIC port 21h, bit 1). I'm not sure, however, if this works reliably, should be tried out first.
Post 01 Feb 2007, 20:38
View user's profile Send private message Reply with quote
MCD



Joined: 21 Aug 2004
Posts: 602
Location: Germany
MCD 01 Feb 2007, 20:42
if you have USB mouse/keyboard, things get much more complecated. I'm not so into USB programming, but how much USB databases/lists does one need to access simple mouse/keyboard?
Post 01 Feb 2007, 20:42
View user's profile Send private message Reply with quote
DOS386



Joined: 08 Dec 2006
Posts: 1903
DOS386 01 Feb 2007, 21:52
Thanks.

Quote:
both keyboard and ps/2 mouse can be deactivated (RBIL, ports.A).


OK, it is sort of documented ... but not really obvious how to use, and
maybe even dangerous:

Code:
Note:   Attention: Never write anything other than 99h to this port
          (better: never write anything to this port, only during BIOS
          init), as other values may connect multiple output drivers
          and will cause hardware damage in PC/XTs!  By setting command
          word to 99h, PPI will be set in input/output modes as it is
          necessary to support the commonly known IO-ports 60, 61, 62
          as desired.
    


But now seems I have not really the need to deactivate the buffering or
the kbd or mouse completely Very Happy

Remains the USB issue: I had a look at source of DKRNL32.DLL and did
not understand really much but it seems that DKRNL32 picks keypresses
from port $60 in IRQ1 - does this mean that DKRNL32 does NOT
work with USB kbd's either ? Confused Confused I now have no USB kbd's to test Sad

BIOS will (mostly) copy keypresses from USB somewhere - to INT $16
maybe, rather than into port $60 ?

Quote:
But why polling the keyboard anyway? Disabling interrupts while waiting for a keystroke


Tomasz's example was waiting, my issue is not waiting, but possibility to
abort a running process: exit if <ESC>, otherwise continue.

Quote:
will almost certainly loose timer interrupts, which is rather bad.


What is the damage ? Anyway, timers was an issue I wanted to ask next:
can I use the timers (OK, they hang on ports $40...$5F as "documented"
in the same text Confused ) without interrupts (after CLI) to generate a delay
of cca 50us - start the timer, execute some code (should take <50us),
and then wait for "completing" the 50us ?

OK, I retested the "loose timer" problem: the CLOCK is FROZEN while
CLI and it remains delayed Sad Unreproductable: if the PC is off, the
clock runs also, although no interrupts occur either Confused Confused Any good way
to prevent this problem, except not to use CLI ?

_________________
Bug Nr.: 12345

Title: Hello World program compiles to 100 KB !!!

Status: Closed: NOT a Bug
Post 01 Feb 2007, 21:52
View user's profile Send private message Reply with quote
Japheth



Joined: 26 Oct 2004
Posts: 151
Japheth 02 Feb 2007, 08:10
> if the PC is off, the clock runs also, although no interrupts occur either

yes, the RTC runs always. But the RTC and the PIT are 2 different devices, and DOS synchronizes with the RTC "not very often".

Simplest way to detect a keypress (not one of the status keys, however) without calling the BIOS is to check variables [41Ah] and [41Ch]. If they are equal, the keyboard buffer is "empty".
Post 02 Feb 2007, 08:10
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.