linux-assembly.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: read key from keyboard
@ 2004-12-21  7:29 Richard Cooper
  2005-08-02 17:12 ` HIToC
  0 siblings, 1 reply; 4+ messages in thread
From: Richard Cooper @ 2004-12-21  7:29 UTC (permalink / raw)
  To: linux-assembly

I just found this in the archive.  No one else answered it, so I guess I  
will.  It's quite the pain to figure out really.  I remember spending  
hours if not days trying to learn enough C that I could figure it out from  
the kernel source.  I really hate C.


> How can I read a key from the keyboard when the key is available?

You have to call TCSETSW, which sadly is like the most undocumented IOCTL  
ever...

This code is copy & pasted out of my program Softer.  The assembly syntax  
is different, but I'm sure you can figure it out.  It also makes the I/O  
completely raw, meaning you'll receive 127 instead of 8 for backspace, and  
you'll receive 13 instead of 10 for enter.  This is more than you want if  
you're just looking to read the characters as they are typed, but I don't  
remember how I ever figured out the correct values to get it to do what I  
wanted.  However, if you also want scancodes, then this is exactly what  
you want.

First you need to save the current settings which are creating the line  
buffering and other nonsense so that you can put them back when your  
program is done.

sys sys_ioctl, 0, TCGETS, old_termios

This requires a little structure to save into...

   old_termios
     .c_iflag resd 1
     .c_oflag resd 1
     .c_cflag resd 1
     .c_lflag resd 1
     .c_cc resb 19

Then you call another function to set the new mode...

   sys sys_ioctl, 0, TCSETSW, new_termios

And of course this requires another structure...

   new_termios
     .c_iflag dd 0
     .c_oflag dd ONLCR | OPOST
     .c_cflag dd B38400 | CS8 | CREAD | HUPCL
     .c_lflag dd 0
     .c_cc db $0, $3, $1c, $7f, $15, $4, $0, $1
           db $0, $11, $13, $1a, $0, $12, $f, $17
           db $16, $0, $0

And finally when your program is finished you need to put things back like  
they were...

   sys sys_ioctl, 0, TCSETSW, old_termios

And those nice constants are:

sys_ioctl = 54
TCGETS = 0x5401
TCSETSW = 0x5403
ONLCR | OPOST = 5
B38400 | CS8 | CREAD | HUPCL = 0x4BF

It looks like I got all of that from from the kernel source code file  
include/asm/termbits.h


> I wish also to know the keyboard scan code...

For scan codes you need the following, but you also need the above.   
Otherwise when scan code 13 comes along, linux will turn it into a 10, and  
it'll also not give you any scan codes until scancode 13 comes along.

First you have to save the old mode...

   sys sys_ioctl, 0, KDGKBMODE, oldmode

This just requires a place to store it.

   oldmode resd 1

Then you set the new mode...

   sys sys_ioctl, 0, KDSKBMODE, K_RAW

And when you're done you set it back...

   sys sys_ioctl, 0, KDSKBMODE, [oldmode]; systrap "calling KDSKBMODE."

And the constants are:

KDGKBMODE = 0x4B44
KDSKBMODE = 0x4B45
K_RAW = 0


I'll warn you that this is all a real pain in the backside.  If you  
program crashes before setting this stuff back like it was, then there's  
usually not much that can be done besides hitting the reset button.   
Scancode mode disable's linux's switching of consoles on Alt-Fn, and you  
can't type anything into your shell since it doesn't understand scancodes.

If you're just looking for better keyboard access, you might think about  
using my program Softer.  It already does all of this stuff and more  
simply so that programs can be written to run under it and not have to do  
it themselves.  It's basically an emulator for a non-existant terminal I  
made up that does everything the way that I want.  Interfacing with it is  
done simply by using your stdin and stdout, and when the user types you  
get the codes immediatly, both the ASCII character that was typed and a  
scan code so that you know which key was pressed, plus the scan codes are  
way easier to interpret than standard keyboard scan codes.  It's the  
easiest keyboard access one could ask for.

The website is
http://www.xersedefixion.com/softer/
and there is more information on it's keyboard I/O at
http://www.xersedefixion.com/softer/orange.html

It's especially nice for assembly language because all of the keyboard  
codes are the same fixed length, so there's none of that "if it began with  
an escape character then keep reading until you see one of these, then  
take the digits and convert them from text into a number, then if it's  
this" nonsense, and the display codes are all binary, so if you want to  
move to column 57 on the screen, you don't have to first convert the  
number 57 into a text string.  It also supports 320x240x256 and 640x480x16  
graphics modes to a limited extent, again, used by simply writing to  
stdout.

^ permalink raw reply	[flat|nested] 4+ messages in thread
* Re: read key from keyboard
@ 2005-08-02 18:02 TheReader06
  0 siblings, 0 replies; 4+ messages in thread
From: TheReader06 @ 2005-08-02 18:02 UTC (permalink / raw)
  To: HIToC, Richard Cooper; +Cc: Linux Assembly

http://www.unet.univie.ac.at/aix/files/aixfiles/termios.h.htm  explains many of the ioctl constants..  I just figured most of them out last week when I wrote the below program to turn off terminal echo in asm, in case anyone needs an example..  Yes, I over-comment assembly, otherwise I spend forever trying to figure out what I did later ;p   And on a related keyboard note, the A20 gate sucks..

test6.asm:
; for vim syntax highlighting, asmsyntax=nasm
BITS 32

%define TCGETA  0x5405                  ; <asm/ioctls.h>
%define TCSETA  0x5406

%define ICANON  0000002q                ; <bits/termios.h>
%define ECHO    0000010q
%define ECHOE   0000020q
%define ECHOK   0000040q
%define ECHONL  0000100q

%define STDIN_FILENO    0               ; <unistd.h>

%define BUFSIZE 1024

section .bss
buf     resb    BUFSIZE
old     resb    2                       ; save the old flags
tty     resb    17                      ; struct termio tty

section .text
        global _start

_start:
        xor     eax, eax                ; eax = 0
        mov     al, 54                  ; sys_ioctl
        xor     ebx, ebx                ; ebx = 0
        mov     ecx, TCGETA
        lea     edx, [tty]              ; &tty
        int     80h                     ; syscall

        mov     ax, [tty + 6]
        mov     [old], ax               ; save value
;       and     ax, ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL)
        and     ax, ~(ECHO | ECHOE | ECHOK | ECHONL)
        mov     [tty + 6], ax

        xor     eax, eax                ; eax = 0
        mov     al, 54                  ; sys_ioctl
        xor     ebx, ebx                ; ebx = 0
        mov     ecx, TCSETA             ; int request
        lea     edx, [tty]              ; &tty
        int     80h

        xor     eax, eax                ; eax = 0
        mov     al, 3                   ; sys_read
        xor     ebx, ebx                ; ebx = 0
        mov     bl, STDIN_FILENO        ; int fd
        mov     ecx, buf                ; void *buf
        mov     edx, BUFSIZE            ; size_t count
        int     80h                     ; syscall

        mov     ax, [old]               ; retrieve old value
        mov     [tty + 6], ax           ; restore it

        xor     eax, eax                ; eax = 0
        mov     al, 54                  ; sys_ioctl
        xor     ebx, ebx                ; ebx = 0
        mov     ecx, TCSETA             ; int request
        lea     edx, [tty]              ; &tty
        int     80h                     ; syscall

        xor     eax, eax                ; eax = 0
        mov     al, 1                   ; sys_exit
        xor     ebx, ebx                ; ebx = 0
        int     80h                     ; syscall

Hope it helps,

Joshua Roys


> On Tuesday 21 December 2004 08:29, Richard Cooper wrote:
> > I just found this in the archive.  No one else answered it, so I guess I
> > will.  It's quite the pain to figure out really.  I remember spending
> > hours if not days trying to learn enough C that I could figure it out from
> > the kernel source.  I really hate C.
> >
> > > How can I read a key from the keyboard when the key is available?
> >
> > You have to call TCSETSW, which sadly is like the most undocumented IOCTL
> > ever...
> >
> > This code is copy & pasted out of my program Softer.  The assembly syntax
> > is different, but I'm sure you can figure it out.  It also makes the I/O
> > completely raw, meaning you'll receive 127 instead of 8 for backspace, and
> > you'll receive 13 instead of 10 for enter.  This is more than you want if
> > you're just looking to read the characters as they are typed, but I don't
> > remember how I ever figured out the correct values to get it to do what I
> > wanted.  However, if you also want scancodes, then this is exactly what
> > you want.
> >
> > First you need to save the current settings which are creating the line
> > buffering and other nonsense so that you can put them back when your
> > program is done.
> >
> > sys sys_ioctl, 0, TCGETS, old_termios
> >
> > This requires a little structure to save into...
> >
> >    old_termios
> >      .c_iflag resd 1
> >      .c_oflag resd 1
> >      .c_cflag resd 1
> >      .c_lflag resd 1
> >      .c_cc resb 19
> >
> > Then you call another function to set the new mode...
> >
> >    sys sys_ioctl, 0, TCSETSW, new_termios
> >
> > And of course this requires another structure...
> >
> >    new_termios
> >      .c_iflag dd 0
> >      .c_oflag dd ONLCR | OPOST
> >      .c_cflag dd B38400 | CS8 | CREAD | HUPCL
> >      .c_lflag dd 0
> >      .c_cc db $0, $3, $1c, $7f, $15, $4, $0, $1
> >            db $0, $11, $13, $1a, $0, $12, $f, $17
> >            db $16, $0, $0
> 
> Ok. What are the meaning of this constants?
> I suppose that with this type of ioctl function, I can have more
> control over the keyboard.. Where I can find the documentation of
> this constants?
> 
> 
> >
> > And finally when your program is finished you need to put things back like
> > they were...
> >
> >    sys sys_ioctl, 0, TCSETSW, old_termios
> >
> > And those nice constants are:
> >
> > sys_ioctl = 54
> > TCGETS = 0x5401
> > TCSETSW = 0x5403
> > ONLCR | OPOST = 5
> > B38400 | CS8 | CREAD | HUPCL = 0x4BF
> 
> Yes, very nice! Why have you choosen B38400 | CS8 | CREAD | HUPCL ?
> In an aonther example I found this: ICANON | ECHO | ISIG
> 
> Thanks,
> HIToC
> 
> -- 
> With regards,
> 
> 
> 					HIToC
> 					hitoc_mail@yahoo.it
> -
> To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread
* read key from keyboard
@ 2004-11-01 16:55 HIToC
  0 siblings, 0 replies; 4+ messages in thread
From: HIToC @ 2004-11-01 16:55 UTC (permalink / raw)
  To: linux-assembly

Hi all

How can I read a key from the keyboard when the key is
available?
I wish also to know the keyboard scan code... Do you
remember the
funtion 0 of interrupt 16h of BIOS??

	xor	ah, ah
	int	16h
returns:
	AH = BIOS scan code
	AL = ASCII character


I have seen that on Linux we can read from the stdin:

	mov	eax, 0x03	; sys_read
	xor	ebx, ebx	; stdin = 0
	mov	ebx, buffer	; buffer
	mov	ecx, 0x01	; count
	int	0x80		; Linux kernel

but this code does not return the key when it is
immediatelly
available... It prints the key on stdout and waits
that the
user presses enter!

Thanks!!


=====
HIToC


		
___________________________________ 
Nuovo Yahoo! Messenger: E' molto più divertente: Audibles, Avatar, Webcam, Giochi, Rubrica… Scaricalo ora! 
http://it.messenger.yahoo.it
-
To unsubscribe from this list: send the line "unsubscribe linux-assembly" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-08-02 18:02 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-12-21  7:29 read key from keyboard Richard Cooper
2005-08-02 17:12 ` HIToC
  -- strict thread matches above, loose matches on Subject: below --
2005-08-02 18:02 TheReader06
2004-11-01 16:55 HIToC

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).