From: carlos on
Hello, I'm trying to make a little program that do the following:

Check if a key was pressed. If so, return the ascii value of the key.
Otherwise, returns 0.

I made this code, but I'm can't capturing the ascii value of the
arrows.

org 100h

mov ah, 11h
int 16h
je pre_quit

mov ah,8h
int 21h
cmp al,0 ; if not extended key
jnz quit
int 21h
jmp quit

pre_quit:
mov al,0
quit:
mov ah,4ch
int 21h


From: Rod Pemberton on
"carlos" <cmontiers(a)gmail.com> wrote in message
news:77a6ea74-9e1e-4144-bcd4-5a074aad2bc4(a)m3g2000yqf.googlegroups.com...
> Hello, I'm trying to make a little program that do the following:
>
> Check if a key was pressed. If so, return the ascii value of the key.
> Otherwise, returns 0.
>
> I made this code, but I'm can't capturing the ascii value of the
> arrows.
>
> org 100h
>
> mov ah, 11h
> int 16h
> je pre_quit
>

Those lines seems to have no effect on my machine. So, I commented them
out:

; mov ah, 11h
; int 16h
; je pre_quit

> mov ah,8h

After trying to figure out why your code didn't work for a while, I realized
that you probably confused ah=8h with ah=6h. It seems that ah=8h doesn't
check for extended keys. I think what you want is:

kbwait:
mov ah,6h
mov dl,0ffh ; needed to select input

> int 21h

It seems you are missing a wait loop. The function returns ZF set for no
key available. It sets AL=0, if not an extended key. But, you must wait
until a key is available (ZF clear) to check for AL=0... So:

int21h
jz kbwait ; wait for key

> cmp al,0 ; if not extended key
> jnz quit
> int 21h
> jmp quit
>
> pre_quit:
> mov al,0
> quit:
> mov ah,4ch
> int 21h
>

In total, I get this:

org 100h

; mov ah, 11h
; int 16h
; je pre_quit

kbdwait:
; mov ah,8h
mov ah,6h ; read w/extended
mov dl,0ffh ; input
int 21h
jz kbdwait ; wait for key
cmp al,0 ; if not extended key
jnz quit
int 21h
jmp quit

pre_quit:
mov al,0
quit:
mov ah,4ch
int 21h

HTH,


Rod Pemberton
PS. Threw on comp.os.msdos.programmer in case someone there knows how to do
it with ah=8h, or has a better method.


From: Frank Kotler on
carlos wrote:
> Hello, I'm trying to make a little program that do the following:
>
> Check if a key was pressed. If so, return the ascii value of the key.
> Otherwise, returns 0.
>
> I made this code, but I'm can't capturing the ascii value of the
> arrows.

I don't think arrow keys... or function keys, "editing keys" (home, end,
etc.) actually *have* an "ascii code" (it's a "bios scan code", which
looks the same). Been a while since I've done this, so I may misremember
(my current install of dosemu is gefukt, and I don't feel like rebooting
right now... I may have to...)

> org 100h
>
> mov ah, 11h
> int 16h
> je pre_quit

Rod says this does nothing on his machine. As I remember it, this should
"check for" (not remove from keyboard buffer) a key. It should return
immediately, with the zero-flag set if no key is available... so your
program would end before it's begun! I must misremember this...

One way to get "extended" keys is...

mov ah, 10h
int 16h
cmp al, 0
jnz not_extended

cmp ah, 48h
je up_arrow
cmp ah, 50h
je down_arrow
; etc...

not_extended:
; it's a "regular" key

Note that we check ah, if al is zero. I'm pretty sure I remember this
correctly...

> mov ah,8h
> int 21h
> cmp al,0 ; if not extended key
> jnz quit
> int 21h
> jmp quit

But I thought I remembered that this should work, too - if it returns
zero in al, call it again to get the "extended" key (in al). You *might*
have to reload ah with 8 before the second int 21h. I don't think you
should have to, but... easy to check, anyway. :)

> pre_quit:
> mov al,0
> quit:
> mov ah,4ch
> int 21h

As I recall, if you do get the "extended key" on the second call, it'll
look like 'M', 'H', 'P', ??? So you may not be able to distinguish the
return value from a "regular" key. You might want to return 0FFh or
something if it's an extended key... depending on what you intend to do
with this.

Rod's idea of using ah=6 (instead of 1, 7, or 8) may work out better for
you, but I think int 16h is easier (just check ah, instead of calling it
again).

Your description of the program indicates that you want to return zero
if no key is pressed. Generally, there won't be one - unless you're a
*really* fast typist (or do myprog<sometext). Is this really what you want?

Best,
Frank
From: Alex Russell on
Rod Pemberton wrote:
> "carlos" <cmontiers(a)gmail.com> wrote in message
> news:77a6ea74-9e1e-4144-bcd4-5a074aad2bc4(a)m3g2000yqf.googlegroups.com...
>> Hello, I'm trying to make a little program that do the following:
>>
>> Check if a key was pressed. If so, return the ascii value of the key.
>> Otherwise, returns 0.
>>
>> I made this code, but I'm can't capturing the ascii value of the
>> arrows.
>>
>> org 100h
>>
>> mov ah, 11h
>> int 16h
>> je pre_quit
>>
>
> Those lines seems to have no effect on my machine. So, I commented them
> out:
>
> ; mov ah, 11h
> ; int 16h
> ; je pre_quit
>
>> mov ah,8h
>
> After trying to figure out why your code didn't work for a while, I realized
> that you probably confused ah=8h with ah=6h. It seems that ah=8h doesn't
> check for extended keys. I think what you want is:
>
> kbwait:
> mov ah,6h
> mov dl,0ffh ; needed to select input
>
>> int 21h
>
> It seems you are missing a wait loop. The function returns ZF set for no
> key available. It sets AL=0, if not an extended key. But, you must wait
> until a key is available (ZF clear) to check for AL=0... So:
>
> int21h
> jz kbwait ; wait for key
>
>> cmp al,0 ; if not extended key
>> jnz quit
>> int 21h
>> jmp quit
>>
>> pre_quit:
>> mov al,0
>> quit:
>> mov ah,4ch
>> int 21h
>>
>
> In total, I get this:
>
> org 100h
>
> ; mov ah, 11h
> ; int 16h
> ; je pre_quit
>
> kbdwait:
> ; mov ah,8h
> mov ah,6h ; read w/extended
> mov dl,0ffh ; input
> int 21h
> jz kbdwait ; wait for key
> cmp al,0 ; if not extended key
> jnz quit
> int 21h
> jmp quit
>
> pre_quit:
> mov al,0
> quit:
> mov ah,4ch
> int 21h
>
> HTH,
>
>
> Rod Pemberton
> PS. Threw on comp.os.msdos.programmer in case someone there knows how to do
> it with ah=8h, or has a better method.
>
>

According to my docs the jz kbdwait should not be required as int 21
func 08h is supposed to wait for the next key press or return the last
key pressed. My dos machine is lent out so I can't test.

The cmp al, 0 is required to check for extended keys.

int 16h, func 00h also waits.
This func returns scan codes in ah and ascii in al. al will be zero if a
non-ascii key was pressed. This func doesn't require a second call to
get the extended keys


int21 and int16 both have funcs to check for a key being ready to
prevent waits.


Alex
From: s_dubrovich on
On Nov 26, 6:28 am, Frank Kotler <fbkot...(a)myfairpoint.net> wrote:
> carlos wrote:
> > Hello, I'm trying to make a little program that do the following:
>
> > Check if a key was pressed. If so, return the ascii value of the key.
> > Otherwise, returns 0.
>
> > I made this code, but I'm can't capturing the ascii value of the
> > arrows.
>
> I don't think arrow keys... or function keys, "editing keys" (home, end,
> etc.) actually *have* an "ascii code" (it's a "bios scan code", which
> looks the same). Been a while since I've done this, so I may misremember
> (my current install of dosemu is gefukt, and I don't feel like rebooting
> right now... I may have to...)
>
Yeah, F11, F12, ScrollLock, Pause|Break, PrintScreen|SysRq, don't
return on an AH`0, Int 16h call, they're ignored.

The arrow keys, F1..F10, home, end, delete, pgup, pgdn and insert do
return unique AH values (scan codes) but no ascii codes in AL, for
example...

Here's the main loop of my program..

;;--------------------------------------------------------60
[SECTION .cseg vstart=0100h] ;; for .com
Key_Scan:
mov ax, 0000h ;; waits for keypress
Int 16h ;; ZF is none awaits.
;; jz Key_Scan_Lp ;; .else. AH`scan code, AL`ascii chr

;; -= ck Xit chr; Q, q =-
cmp ax, 1071h ;; q
je Key_Scan_Xit
cmp ax, 1051h ;; Q
je Key_Scan_Xit

;; -= .else. conout AX =-
call conout_AX
nop
nop ;; space for trap
nop

Key_Scan_Lp:
jmp Key_Scan

Key_Scan_Xit:
call conout_AX ;; emit Q,q vals

mov ah, 0 ;; pause for keypress..
int 16h
int 19h ;; done

;;--------------------------------------------------------60
;; S U B R O U T I N E S
;;--------------------------------------------------------60

My notes say Function 11h is a keyboard Check function, which does not
remove the word from the keyboard buffer, you still need to 'remove'
it by a 'read' Function 0h. I dunno, this might require
experimentation. There were 3 keyboard base types. PC, XT, and AT
class.

For example: up arrow is AX=4800h, F10 is AX=4400h,'a' is AX=1E61h,
shift+'a' is AX=1E41h (A). -on this Dell I'm banging on..

hth.

Steve

> > org 100h
>
> > mov ah, 11h
> > int 16h
> > je pre_quit
>
> Rod says this does nothing on his machine. As I remember it, this should
> "check for" (not remove from keyboard buffer) a key. It should return
> immediately, with the zero-flag set if no key is available... so your
> program would end before it's begun! I must misremember this...
>

Yeah, _Check Keyboard_

>
> Rod's idea of using ah=6 (instead of 1, 7, or 8) may work out better for
> you, but I think int 16h is easier (just check ah, instead of calling it
> again).
>
> Your description of the program indicates that you want to return zero
> if no key is pressed. Generally, there won't be one - unless you're a
> *really* fast typist (or do myprog<sometext). Is this really what you want?
>
> Best,
> Frank