assemblykeyboardmasmdosbox

Why MASM saves data when ctrl pressed?


This is my first question. The essence of the program is to read the line character by character and prohibit extraneous characters, such as F1, F2, Insert keys etc. or combinations with CTRL (Ctrl+c => heart symbol)

Part of my code below:

main:
    mov si, 0
    mov ax,@data
    mov ds, ax
    lea dx,message 
    mov ah, 09h     ;print message
    int 21h
    mov ax, 40h                     ; load segment into AX
    mov es, ax
read_loop:        
    mov ah, 00h
    test byte ptr es:[17h], 04h     ; is CTRL pressed?
    jnz read_loop
    int 16h
    cmp al, 0       ;check ASCII
    jne ASCII
    mov ah, 00h
    int 16h
    jmp read_loop
ASCII:
    cmp ah, 14
    je read_loop
    cmp al, 13      ; ENTER?
    je next
    test byte ptr es:[17h], 04h     ; is CTRL pressed?
    jnz read_loop
    mov str_record[si], al
    mov ah, 02h     ; display
    mov dl, al
    int 21h
    inc si
    cmp si, 40  ;check max_len
    je next
    jmp read_loop
    
next:
    cmp str_record[0], '$'
    je quit
    mov al, 3
    int 10h
    mov di, 0
    mov ax, 3
    int 10h
    
    mov ah, 02h
    mov dh, 2
    mov dl, 15
    int 10h

I am trying to check ctrl is pressed with Keyboard Shift Status Flags but when I release the key, then all the buttons that I pressed along with CTRL are printed


Solution

  • cmp al, 0       ;check ASCII
    jne ASCII
    mov ah, 00h
    int 16h
    

    Asking a second time after receiving 0 would be typical for how certain DOS keyboard related functions operate. The BIOS keyboard functions don't work that way!

    The more practical solution to not allow special keys disturb your results, is to only accept keys that have an ASCII code of 32 or more. The one exception being Enter of course.

    read_loop:        
        mov  ah, 00h
        int  16h
        cmp  al, 13      ; ENTER?
        je   next
        cmp  al, 32      ;check ASCII
        jb   read_loop
        mov  str_record[si], al
        mov  ah, 02h     ; display
        mov  dl, al
        int  21h
        inc  si
        cmp  si, 40      ;check max_len
        jne  read_loop
    next: