ORG 100h

    Jmp        not_loaded

Jmp Ok

Ok:
   Mov AX,12h
   Int 10h
   Mov [MOUSEX],100
Ok2:

   Call  get_pos
   Mov   AH,0Ch
   Mov   CX,CX
   Mov   DX,DX
   Mov   AL,15
   Int   10h

   Xor   AX,AX
   Mov   AH,11h
   Int   16h
   Jnz   Sair
   Jmp Ok2

Sair:
Int 27h
        mov     ax,0x4C00 
        int        21h 

not_loaded:

        mov     ax,0x2574
        mov     dx,new_isr
        int         21h 
        cli 
        mov     bl,0a8h 
        call      keyboard_cmd 
        mov     bl,20h 
        call       keyboard_cmd 
        call       keyboard_read 
        or          al,2 
        mov      bl,60h 
        push    ax 
        call       keyboard_cmd 
        pop     ax 
        call      keyboard_write 
        mov     bl,0d4h 
        call       keyboard_cmd 
        mov     al,0f4h 
        call       keyboard_write 
        sti

Jmp Ok


new_isr: 
        pushf 
        cli 
        push    ax 
        push    bx 
        push    cx 
        push    dx 
        push    di 
        push    si 
        push    es 
        push    ds 
        push    cs 
        pop      ds
Atalho:
        mov     bl,0adh 
        call       keyboard_cmd 
        cmp     byte [first_time],0 
        je          not_first_time 
        mov     byte [first_time],0 
        call       keyboard_read 
        call       keyboard_read 
        call       keyboard_read 
        jmp       no_show 

not_first_time: 
        mov     word [temp_mask],0 
        mov     cx,word [pos_x] 
        mov     dx,word [pos_y] 
        call       keyboard_read 
        and      al,3                   ;I changed it from a 7 
                                               ;Why it was a 7 I do not know.
        mov     ah,byte [buttons]
        mov     byte [buttons],al 
        cmp     al,ah 
        je          no_button_change 
        and      al,3 
        and      ah,3 
        xor       al,ah 
        xor       bx,bx 
        push   ax 
        test      al,2 
        jz          no_right_button_change 
        and      ah,2 
        jz          right_button_pressed 
        or          bx,16 
        jmp       no_right_button_change 

right_button_pressed: 
        or         bx,8 

no_right_button_change: 
        pop     ax 
        test      al,1 
        jz         no_left_button_change 
        and     ah,1 
        jz         left_button_pressed 
        or         bx,4 
        jmp     no_left_button_change 

left_button_pressed: 
        or         bx,2 

no_left_button_change: 
        mov     word [temp_mask],bx 

no_button_change: 
        call       keyboard_read 
        cbw 
        add      word [pos_x],ax 
        add      word [x_move],ax 
        mov     ax,word [x_min] 
        cmp     word [pos_x],ax 
       jg           good_hor1 
        mov     word [pos_x],ax 

good_hor1: 
        mov     ax,word [x_max] 
        cmp     word [pos_x],ax 
        jle         good_hor2 
        mov     word [pos_x],ax 

good_hor2: 
        call      keyboard_read 
        neg     al 
        cbw 
        add      word [pos_y],ax 
        add      word [y_move],ax 
        mov     ax,[y_min] 
        cmp     word [pos_y],ax 
        jg         good_ver1 
        mov     word [pos_y],ax 

good_ver1: 
        mov     ax,word [y_max] 
        cmp     word [pos_y],ax 
        jle         good_ver2 
        mov     word [pos_y],ax 

good_ver2: 
        mov     ax,word [x_move] 
        or         ax,word [y_move] 
        or         ax,ax 
        jz          no_change_position 
        or         word [temp_mask],1 

no_change_position:
        mov     ax,word [temp_mask] 
        and      ax,word [user_mask] 
        jz          no_call_user

        db        60h

        mov     cx,word [pos_x] 
        mov     dx,word [pos_y] 

        mov     di,0                      ;[cs:x_move] 
        mov     si,0                      ;[cs:y_move] 

        mov     word [x_move],0 
        mov     word [y_move],0 

        mov     bl,byte [cs:buttons] 
        xor       bh,bh 
        call       word [cs:user_subroutine] 
        db         61h 

no_call_user:
        cmp      word [sm_flag],1 
        jne         no_show 
        shr        cx,3 
        shr        dx,3 
        mov      ax,80 
        mul       dl 
        add       ax,cx 
        shl        ax,1 
        mov     di,ax 
        mov     ax,0b800h 
        mov     es,ax 
        mov     ax,word [save_char] 
        stosw 
        mov     cx,word [pos_x] 
        mov     dx,word [pos_y] 
        shr       cx,3 
        shr       dx,3 
        mov     ax,80 
        mul      dl 
        add      ax,cx 
        shl       ax,1 
        mov     di,ax 
        mov     ax,0b800h 
        mov     es,ax 
        mov     ax,word [es:di] 
        mov     word [save_char],ax 
        not       ah 
        and      ah,7fh 
        stosw 

no_show:
        mov     bl,0aeh 
        call       keyboard_cmd 
        mov     al,20h 
        out       0a0h,al 
        out       20h,al 
        pop     ds 
        pop     es 
        pop     si 
        pop     di 
        pop     dx 
        pop     cx 
        pop     bx 
        pop     ax 
        popf
        iret


first_time               db      1 
buttons                  db      0 
pos_x                     dw      0 
pos_y                     dw      0 
sm_flag                  dw      0 
save_char             dw      0 
x_move                  dw      0 
y_move                  dw      0 
x_max                     dw      639 
x_min                      dw      0 
y_max                     dw      479 
y_min                      dw      0 
user_subroutine  dw      0,0 
user_mask             dw      0 
temp_mask            dw      0
MOUSEX  DW 0

keyboard_read: 
        push    cx 
        push    dx 
        xor        cx,cx 

key_read_loop: 
        in           al,64h 
        test        al,1 
        jnz         key_read_ready 
        loop       key_read_loop 
        mov       ah,1 
        jmp        key_read_exit 

key_read_ready: 
        push    cx 
        mov     cx,32 

key_read_delay: 
        loop    key_read_delay 
        pop     cx 
        in         al,60h 
        xor       ah,ah 

key_read_exit: 
        pop     dx 
        pop     cx 
        ret 

keyboard_write: 
        push     cx 
        push     dx 
        mov      dl,al 
        xor        cx,cx 

kbd_wrt_loop1: 
        in         al,64h 
        test      al,20h 
        jz          kbd_wrt_ok1 
        loop     kbd_wrt_loop1 
        mov     ah,1 
       jmp        kbd_wrt_exit 

kbd_wrt_ok1: 
        in        al,60h 
        xor     cx,cx 

kbd_wrt_loop: 
        in        al,64h 
        test     al,2 
        jz         kbd_wrt_ok 
        loop    kbd_wrt_loop 
        mov    ah,1 
        jmp     kbd_wrt_exit 

kbd_wrt_ok: 
        mov     al,dl 
        out       60h,al 
        xor       cx,cx 

kbd_wrt_loop3: 
        in         al,64h 
        test     al,2 
        jz         kbd_wrt_ok3 
        loop    kbd_wrt_loop3 
        mov     ah,1 
        jmp      kbd_wrt_exit 

kbd_wrt_ok3: 
        mov     ah,8 

kbd_wrt_loop4: 
        xor     cx,cx 

kbd_wrt_loop5: 
        in         al,64h 
        test     al,1 
        jnz      kbd_wrt_ok4 
        loop    kbd_wrt_loop5 
        dec     ah 
        jnz      kbd_wrt_loop4 

kbd_wrt_ok4: 
        xor     ah,ah 

kbd_wrt_exit: 
        pop     dx 
        pop     cx 
        ret 

keyboard_cmd: 
        xor     cx,cx 

cmd_wait: 
        in         al,64h 
        test     al,2 
        jz         cmd_send 
        loop    cmd_wait 
        jmp      cmd_error 

cmd_send: 
        mov     al,bl 
        out       64h,al 
        xor       cx,cx 

cmd_accept: 
        in         al,64h 
        test     al,2 
        jz         cmd_ok 
        loop    cmd_accept 

cmd_error: 
        mov     ah,1 
        jmp      cmd_exit 

cmd_ok: 
        xor     ah,ah 

cmd_exit: 
        ret 

get_pos: 
        mov     cx,word [pos_x] 
        mov     dx,word [pos_y] 
        mov     bl,byte [buttons] 
        xor       bh,bh 
        ret 
