* 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
2004-12-21 7:29 read key from keyboard Richard Cooper
@ 2005-08-02 17:12 ` HIToC
0 siblings, 0 replies; 4+ messages in thread
From: HIToC @ 2005-08-02 17:12 UTC (permalink / raw)
To: Richard Cooper; +Cc: Linux Assembly
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
^ 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).