The MASM Forum Archive 2004 to 2012
Welcome, Guest. Please login or register.
April 17, 2021, 11:27:18 PM

Login with username, password and session length
Search:     Advanced search
128553 Posts in 15254 Topics by 684 Members
Latest Member: mottt
* Home Help Search Login Register
+  The MASM Forum Archive 2004 to 2012
|-+  Miscellaneous Forums
| |-+  16 bit DOS Programming
| | |-+  Animation with int 21h ah=2ch
« previous next »
Pages: [1] 2 Print
Author Topic: Animation with int 21h ah=2ch  (Read 14941 times)
amrac
Guest


Email
Animation with int 21h ah=2ch
« on: December 29, 2009, 04:33:21 PM »

I have a little program that paints a little pixel on the screen and each time the user presses a key the pixel moves down. I want to move the pixel down but I want to do it within a certain interval of time, say 500 milliseconds. How can I do that? I know that I have to use int 21h that puts milliseconds in ah, but I dont know how to start. Here goes my code:
STACK SEGMENT PARA STACK
   DB   64 DUP ('MYSTACK ')
STACK ENDS

MYCODE SEGMENT PARA 'CODE'
MYPROC PROC FAR
   ASSUME CS:MYCODE,SS:STACK
      PUSH DS
      SUB AX,AX
      PUSH AX
      
      MOV AH, 00h
      MOV AL, 04h
      INT 10h
      
      ; MOV AH, 11
      ; MOV BH, 00
      ; MOV BL, 01
      ; INT 10h
      
      MOV AH, 11
      MOV BH, 01
      MOV BL, 00
      INT 10h
      
      MOV DX, 64h
      MOV CX,20
      
Game:
      PUSH CX
      MOV AL, 02      ;pixel cor vermelha
      MOV AH, 12
      MOV CX, 9Eh
      INT 10h
      
      MOV ah, 01
      INT 21h      ;espera por uma tecla
      
      MOV AL, 00      ;pixel cor preto
      MOV AH, 12
      MOV CX, 9Eh
      INT 10h
      
      INC DX
      POP CX
      Loop Game
      
      MOV ah, 01
      INT 21h
      
      MOV AH, 00h
      MOV AL, 02h
      INT 10h
      
      RET
MYPROC ENDP
MYCODE ENDS

   END
Logged
dedndave
Member
*****
Posts: 12523


Re: Animation with int 21h ah=2ch
« Reply #1 on: December 29, 2009, 04:41:47 PM »

i would use BIOS INT 1Ah, function 0

;===================================================================

DELAY   PROC    NEAR
;
;time delay
;
;AX = tick count to wait, 0 to 255 (0 to 14 seconds)
;
;----------------------------------------

        OR      AX,AX
        JNZ     EXECUTE_DELAY

        RET                       ;if AX = 0, exit immediately

EXECUTE_DELAY:
        PUSH    CX
        PUSH    DX
        PUSH    BX
        PUSH    AX
        OR      AH,AH
        JZ      UNDER_LIMIT

        MOV     AX,0FFh           ;max limit = 255 ticks (~14 seconds)

UNDER_LIMIT:
        PUSH    AX
        INT     1Ah               ;CX:DX = tick count
        POP     AX
        SUB     BX,BX             ;BX:AX = wait tick count

        ADD     AX,DX
        ADC     BX,CX             ;BX:AX = timeout value

        MOV     DX,0B0h
        MOV     CX,18h            ;CX:DX = midnight rollover value

        SUB     AX,DX
        SBB     BX,CX             ;subtract rollover
        JS      OVERFLOW_ADJUST

        PUSH    BX
        PUSH    AX

ROLLOVER_LOOP:
        MOV     AH,0
        INT     1Ah
        JCXZ    ROLLOVER_ENTRY

        JMP     ROLLOVER_LOOP

OVERFLOW_ADJUST:
        ADD     AX,DX
        ADC     BX,CX

WAIT_LOOP:
        PUSH    BX
        PUSH    AX
        MOV     AH,0
        INT     1Ah

ROLLOVER_ENTRY:
        POP     AX
        POP     BX
        CMP     BX,CX
        JB      DELAY_EXIT

        JA      WAIT_LOOP

        CMP     AX,DX
        JA      WAIT_LOOP

DELAY_EXIT:
        POP     AX
        POP     BX
        POP     DX
        POP     CX
        RET

DELAY   ENDP

;===================================================================
Logged
amrac
Guest


Email
Re: Animation with int 21h ah=2ch
« Reply #2 on: December 29, 2009, 04:56:03 PM »

What I dont understand is how can I interoperate this routine with my code.
Logged
dedndave
Member
*****
Posts: 12523


Re: Animation with int 21h ah=2ch
« Reply #3 on: December 29, 2009, 05:32:13 PM »

each clock tick is ~55 ms
500 ms is about 9 ticks, so...

        mov     ax,9
        call    DELAY

EDIT there are better ways to get a more repeatable delay
that involves revectoring one of the timer interrupts
this is a simple delay - it won't be exactly 500 ms everytime you call it
Logged
amrac
Guest


Email
Re: Animation with int 21h ah=2ch
« Reply #4 on: December 29, 2009, 07:49:03 PM »

Well I discovered that it has to be faster but it works just fine. Thanks!!
Logged
amrac
Guest


Email
Re: Animation with int 21h ah=2ch
« Reply #5 on: December 29, 2009, 08:28:14 PM »

Ive putten the smallest delay. Is there some code in the procedure that I can change to make the delay smaller? Here goes "my" code:
STACK SEGMENT PARA STACK
   DB   64 DUP ('MYSTACK ')
STACK ENDS

MYCODE SEGMENT PARA 'CODE'
MYPROC PROC FAR
   ASSUME CS:MYCODE,SS:STACK
   
      PUSH DS
      SUB AX,AX
      PUSH AX
      
      MOV AH, 00h
      MOV AL, 04h
      INT 10h
      
      ; MOV AH, 11
      ; MOV BH, 00
      ; MOV BL, 01
      ; INT 10h
      
      MOV AH, 11
      MOV BH, 01
      MOV BL, 00
      INT 10h
      
      mov dx,10h      ;selecciona a linha 100
      mov cx,9eh       ; seleciona a coluna 158
   
      
      ;MOV DX, 64h
      MOV CX,180
      
Game:
      PUSH CX
      MOV AL, 02      ;pixel cor vermelha
      MOV AH, 12
      MOV CX, 9Eh
      INT 10h
      
      ;MOV ah, 01
      ;INT 21h      ;espera por uma tecla

      mov     ax, 1      ;-------------------------------------------------------------------------------------------------<<<<<HERE IS THE SMALLER DELAY THAT I COULD MAKE
                call    DELAY
      
      MOV AL, 00      ;pixel cor preto
      MOV AH, 12
      MOV CX, 9Eh
      INT 10h
      
      INC DX
      POP CX
      Loop Game
      
      MOV ah, 01
      INT 21h
      
      MOV AH, 00h
      MOV AL, 02h
      INT 10h
      
      RET
MYPROC ENDP
DELAY   PROC    NEAR
;
;time delay
;
;AX = tick count to wait, 0 to 255 (0 to 14 seconds)
;
;----------------------------------------

        OR      AX,AX
        JNZ     EXECUTE_DELAY

        RET                       ;if AX = 0, exit immediately

EXECUTE_DELAY:
        PUSH    CX
        PUSH    DX
        PUSH    BX
        PUSH    AX
        OR      AH,AH
        JZ      UNDER_LIMIT

        MOV     AX,0FFh           ;max limit = 255 ticks (~14 seconds)

UNDER_LIMIT:
        PUSH    AX
        INT     1Ah               ;CX:DX = tick count
        POP     AX
        SUB     BX,BX             ;BX:AX = wait tick count

        ADD     AX,DX
        ADC     BX,CX             ;BX:AX = timeout value

        MOV     DX,0B0h
        MOV     CX,18h            ;CX:DX = midnight rollover value

        SUB     AX,DX
        SBB     BX,CX             ;subtract rollover
        JS      OVERFLOW_ADJUST

        PUSH    BX
        PUSH    AX

ROLLOVER_LOOP:
        MOV     AH,0
        INT     1Ah
        JCXZ    ROLLOVER_ENTRY

        JMP     ROLLOVER_LOOP

OVERFLOW_ADJUST:
        ADD     AX,DX
        ADC     BX,CX

WAIT_LOOP:
        PUSH    BX
        PUSH    AX
        MOV     AH,0
        INT     1Ah

ROLLOVER_ENTRY:
        POP     AX
        POP     BX
        CMP     BX,CX
        JB      DELAY_EXIT

        JA      WAIT_LOOP

        CMP     AX,DX
        JA      WAIT_LOOP

DELAY_EXIT:
        POP     AX
        POP     BX
        POP     DX
        POP     CX
        RET

DELAY   ENDP
MYCODE ENDS

   END
Logged
dedndave
Member
*****
Posts: 12523


Re: Animation with int 21h ah=2ch
« Reply #6 on: December 29, 2009, 09:18:40 PM »

for very small delays, you can just use a loop
the value you place into CX will deteremine how long the loop takes

        mov     cx,DelayCount       ;this can be a constant

Delay0: loop    Delay0

here is another example where i place a loop inside another loop
it can create somewhat longer delays

        mov     cx,DelayCount       ;this can be a constant

Delay0: push    cx
        xor     cx,cx

Delay1: loop    Delay1

        pop     cx
        loop    Delay0

the problem with these kinds of delay loops is - they run at different speeds on different machines

a more complicated approach is to use one of the counter/timers
it takes a bit more programming, but will yield the same results on most machines
Logged
FORTRANS
Member
*****
Gender: Male
Posts: 1147


Imagine


Re: Animation with int 21h ah=2ch
« Reply #7 on: December 29, 2009, 09:56:06 PM »

Hi,

   Depending on your system, INT 15H function 86H in a
wait function.  See Ralf Brown's Interrupt List (RBIL).

Code:
AH = 86H
CX:DX = 32 bit count in microseconds (resolution is 976 us)
INT 15H

   It did not work on my Windows 2000 system, but someone
mentioned a service pack may have changed that.  Instead
of the 18.2 times a second the INT 1CH gives you (55
millisecond wait), you get about a millisecond wait.

   You should be able to read the timer counting down as well
as it generates the 18.2 per second interrupts.  That could
give you very short delays.  That is the ports from 40H to
43H.  Again see RIBL.

Code:
Port  (data from "Undocumented DOS")

40H = Timer 0, system ticks
41H = Timer 1, DRAM refresh
42H = Timer 2, general use
43H = Tomers 0 - 2 mode control

Regards,

Steve N.
Logged
amrac
Guest


Email
Re: Animation with int 21h ah=2ch
« Reply #8 on: December 29, 2009, 11:10:54 PM »

Thanks once again for your reply. Is there a way in which I can freeze the process of making the little pixel fall? I need to have that functionality in my game. I mean the pixel is falling but when the user presses a key the pixel stops.
Logged
MichaelW
Global Moderator
Member
*****
Gender: Male
Posts: 5161


Re: Animation with int 21h ah=2ch
« Reply #9 on: December 30, 2009, 07:35:30 AM »

Here is another delay procedure.
Code:
; -----------------------------------------------------------
; This proc delays for the specified number of milliseconds.
; It does this by counting memory refresh requests, which
; for AT-class systems are generated by system timer 1,
; normally programmed by the BIOS to generate an output once
; every 18/1193182 = 15.09 microseconds. Each request toggles
; bit 4 of I/O port 61h. We are counting full cycles of the
; bit, with two toggles per cycle, so each cycle takes 30.18
; microseconds and we count 34 cycles for each millisecond.
;
; Call with the number of milliseconds in AX.
;
; Preserves all registers other than AX.
;
; Note that the delay will be much shorter when running
; under the NT versions of Windows.
; -----------------------------------------------------------

MsDelay proc
push cx

mov cx, ax ; load msLoop count
msLoop:
push cx ; preserve msLoop counter
mov cx, 34 ; load repeat count
wait1:
in al, 61h ; read byte from port
test al, 10h ; test bit 4
jz wait1 ; jump if bit clear
wait2:
in al, 61h ; read byte from port
test al, 10h ; test bit 4
jnz wait2 ; jump if bit not clear
dec cx ; decrement repeat count
jnz wait1 ; jump if count not zero
pop cx ; recover msLoop counter
dec cx ; decrement msLoop count
jnz msLoop ; jump if count not zero

pop cx
ret
MsDelay endp
Logged

eschew obfuscation
dedndave
Member
*****
Posts: 12523


Re: Animation with int 21h ah=2ch
« Reply #10 on: December 30, 2009, 10:10:48 AM »

lol - that is some old-timie stuff, Michael
how old are you, anyways ?
Logged
amrac
Guest


Email
Re: Animation with int 21h ah=2ch
« Reply #11 on: December 30, 2009, 10:29:35 AM »

I dont understand. Does this mean that the second procedure permits me to stop at any moment the pixel from falling and the first procedure doesn't?
Logged
amrac
Guest


Email
Re: Animation with int 21h ah=2ch
« Reply #12 on: December 30, 2009, 10:42:14 AM »

I tried the second procedure and it runs much faster. But can I stop the pixel from moving. I tried putting the value in ax to zero but it still moves from times to times.
Logged
dedndave
Member
*****
Posts: 12523


Re: Animation with int 21h ah=2ch
« Reply #13 on: December 30, 2009, 10:52:43 AM »

well - stopping the pixel should not be dependant on a delay routine
that is more of a program flow issue
Logged
FORTRANS
Member
*****
Gender: Male
Posts: 1147


Imagine


Re: Animation with int 21h ah=2ch
« Reply #14 on: December 30, 2009, 02:25:18 PM »

Hi,

   Looks good Michael.  Will check it out on some different
systems.  Do you have a correction for the "NT versions"?

Regards,

Steve N.
Logged
Pages: [1] 2 Print 
« previous next »
Jump to:  

Powered by MySQL Powered by PHP The MASM Forum Archive 2004 to 2012 | Powered by SMF 1.0.12.
© 2001-2005, Lewis Media. All Rights Reserved.
Valid XHTML 1.0! Valid CSS!