Difference between revisions of "Input"

From SizeCoding
Jump to: navigation, search
(DOS alternative, Int 16/AH=01h)
(adding mouse interaction and "point" snippet)
Line 42: Line 42:
  
 
See also : [http://www.ctyme.com/intr/rb-1755.htm Ralf Browns Interrupt List : Int 16/AH=01h]
 
See also : [http://www.ctyme.com/intr/rb-1755.htm Ralf Browns Interrupt List : Int 16/AH=01h]
 +
 +
== Reading the Mouse ==
 +
 +
For more sophisticated interaction with the mouse, there is <code>int 33h</code>. The most important interactions :
 +
 +
* [http://www.ctyme.com/intr/rb-5957.htm show mouse cursor - Int 33/AX=0001h]
 +
* [http://www.ctyme.com/intr/rb-5959.htm return position and button status - Int 33/AX=0003h]
 +
* [http://www.ctyme.com/intr/int-33.htm general overview]
 +
 +
It appears that a little "Paint" implementation is [http://www.pouet.net/prod.php?which=63826 possible in 16 bytes]
 +
<syntaxhighlight lang=nasm>
 +
org 100h        ; code starts at 0x100
 +
mov al,0x12    ; assume ah = 0 ; set graphics mode to 640*480
 +
inc bx          ; assume bx = 0 ; set to 1 (show cursor)
 +
mloop:
 +
int 0x10        ; first loop, switch to graphic mode
 +
                ; further loops, set pixel
 +
xchg bx,ax      ; first loop, set AX to 1 (show cursor)
 +
                ; further loops, restore old calling mode
 +
xor al,0x02    ; switch modes : show cursor <-> get mouse state
 +
                ; updating XY every second loop plus drawing
 +
                ; one pixel left results in thicker lines
 +
int 0x33        ; call the mouse interrupt
 +
xchg bx,ax      ; store the button state in AL for drawing
 +
                ; remember the current calling mode
 +
                ; for switching it later (in BX)
 +
mov ah,0x0C    ; set mode to "set pixel"
 +
loop mloop      ; dec CX -> draw one pixel left from cursor
 +
                ; basically enables drawing pixels
 +
                ; while the cursor is active
 +
                ; allows exit if the mouse is leftmost
 +
ret            ; assume [[FFEE]] = [0] = CD20 = int 20
 +
</syntaxhighlight>

Revision as of 08:33, 14 August 2016

Checking for ESCAPE

This is fairly easy: Monitor the keyboard scancode port for ESC which is #1, then deal with it:

        in      al,60h          ;read whatever is at keyboard port; looking for ESC which is #1
        dec     ax              ;if ESC, AX now 0
        jnz     mainloop        ;fall through if 0, do jump somewhere else if otherwise

Sometimes your AH register does not contain 00h at any given time. In that case dec ax will never trigger the zero flag, so you would have to spend the extra byte and use dec al. Alternatively you can redesign your codeflow as to have 00h in AH at least sometimes ;)

Checking for any keypress

If you need to shave a byte, it might be possible in some environments to check for any keypress instead of just escape using less code:

        in      al,60h          ;read whatever is at keyboard port
        das                     ;If non-zero, parity will be set
        jp      mainloop        ;Jump if parity

An alternative if not running DOSBox:

        in      al,60h          ;read whatever is at keyboard port
        aaa
        jz      mainloop        ;Jump if zero

The above are somewhat flaky due to different hardware, VMs, and emulators not honoring flags correctly.

The DOS alternative

In very small productions, it's sometimes impossible to use one of the above, since AL contains intermediate results or pixel values all the time. Luckily there is int 16h which checks for any key with the following code :

        mov      ah,1           ; subfunction AH = 1, check for key
        int      16h
        jz       mainloop       ; ZF set if no keystroke available

See also : Ralf Browns Interrupt List : Int 16/AH=01h

Reading the Mouse

For more sophisticated interaction with the mouse, there is int 33h. The most important interactions :

It appears that a little "Paint" implementation is possible in 16 bytes

org 100h        ; code starts at 0x100
mov al,0x12     ; assume ah = 0 ; set graphics mode to 640*480
inc bx          ; assume bx = 0 ; set to 1 (show cursor)
mloop:	
int 0x10        ; first loop, switch to graphic mode
                ; further loops, set pixel		
xchg bx,ax      ; first loop, set AX to 1 (show cursor)
                ; further loops, restore old calling mode		
xor al,0x02     ; switch modes : show cursor <-> get mouse state
                ; updating XY every second loop plus drawing
                ; one pixel left results in thicker lines		
int 0x33        ; call the mouse interrupt
xchg bx,ax      ; store the button state in AL for drawing
                ; remember the current calling mode
                ; for switching it later (in BX)			
mov ah,0x0C     ; set mode to "set pixel"
loop mloop      ; dec CX -> draw one pixel left from cursor
                ; basically enables drawing pixels
                ; while the cursor is active
                ; allows exit if the mouse is leftmost
ret             ; assume [[FFEE]] = [0] = CD20 = int 20