Hey guys. I am trying to print different messages in dependency of what char you press. In my case i use, F1,F2,F3, escape.

The problem is that the first message is printed again after a char input is read, which it shouldn't!

This is my code, please tell me where i'm wrong:

TITLE	ep2_5
	.MODEL    SMALL
        .STACK    10h
        .DATA
        	msg	DB 'Apasati o tasta F*:'
		msg_l	equ	$-msg
        	f1	DB 'Ati apasat tasta F1',13,10
		f1_l	equ	$-f1

        	f2	DB 'Ati apasat tasta F2',13,10
		f2_l	equ	$-f2

        	f3	DB 'Ati apasat tasta F3',13,10
		f3_l	equ	$-f3

        	error	 DB 'Nu ati apasat o tasta valida! Incercati din nou',13,10
		error_l	equ	$-error
	.CODE
        	begin:   mov	ax,@DATA
                mov	ds,ax
	loop1:	;Print msg
		mov  bx, 1
		mov  cx, msg_l
		mov  dx, offset msg
		mov  ah, 40h
		int  21h
				;looping to get caracters
	waitk:	;getChar
		mov ah, 06h ;
		mov dx, 0ffh
		int 21h ;
		jz waitk
		cmp al,59
		je	_f1
		cmp al,60
		je	_f2
		cmp al,61
		je	_f3
		cmp al, 27
		je	bail		
		
		jmp loop1
	_f1:	;Print f1
		mov  bx, 1
		mov  cx, f1_l
		mov  dx, offset f1
		mov  ah, 40h
		int  21h
		jmp loop1
	_f2:	;Print f2
		mov  bx, 1
		mov  cx, f2_l
		mov  dx, offset f2
		mov  ah, 40h
		int  21h
 	        jmp loop1
	_f3:	;Print f3
		mov  bx, 1
		mov  cx, f3_l
		mov  dx, offset f3
		mov  ah, 40h
		int  21h
		jmp loop1

        
	bail:	;bail out
		mov	ax,4c00h	
	        int	21h	
                END	begin

I'm using tasm. Screenshot included.

Dani AI

Generated

The symptom and fix are already shown in the thread: extended keys (F1–F12, arrows, etc.) are reported by DOS as a two-step result when you use the DOS character services. The first call returns 0 in AL to signal “extended key,” so you must call the keyboard routine a second time and use the second return. That is what implemented after ’s pointer — check AL for zero and, if zero, call the routine again before doing the comparisons.

A more robust approach is to use the BIOS keyboard service (INT 16h, AH=00). It returns the ASCII code in AL and the scan code in AH in a single call, so you can test AH for F1–F3 and AL for ESC without the two-call dance. Example:

mov ah, 00h
int 16h     ; on return: AH = scan code, AL = ASCII (AL=0 for extended)
cmp ah, 3Bh ; F1 (0x3B)
je  F1_label
cmp ah, 3Ch ; F2 (0x3C)
je  F2_label
cmp ah, 3Dh ; F3 (0x3D)
je  F3_label
cmp al, 1Bh ; ESC (0x1B)
je  bail

Practical tips: print your prompt once (outside the input loop) unless you deliberately want it shown every iteration; when using INT 21h/AH=06 read-with-DX=0FFh, do not jump back to the prompt when the first AL==0 — read the second byte first. Also be aware that scan codes are BIOS-level values (0x3B–0x3D for F1–F3); keyboard layouts or unusual BIOSes can differ, so validate on your target environment.

Recommended Answers

All 2 Replies

See if this helps:

commented: Helpful link +2

Evrika! You helped me.

i wrote (modified to)

waitk:	;getChar
		mov ah, 06h ;
		mov dx, 0ffh
		int 21h ;
		jz waitk
		cmp al,0
		jne not_extended
		mov ah, 06h ;
		mov dx, 0ffh
		int 21h ;

	not_extended:
		cmp al,59
		je	_f1

And now it works.
What was the problem/solution:

If you press a key that has an extended code rather than an ASCII code, MS-DOS returns two keycodes. On the first call MS-DOS returns a zero value. This tells you that you must call the get character routine again. The code MS-DOS returns on the second call is the extended key code.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.