Pages: [1] 2
|
 |
|
Author
|
Topic: Animation with int 21h ah=2ch (Read 14941 times)
|
amrac
Guest
|
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 don´t 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
|
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
|
What I don´t understand is how can I interoperate this routine with my code.
|
|
|
Logged
|
|
|
|
dedndave
|
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
|
Well I discovered that it has to be faster but it works just fine. Thanks!!
|
|
|
Logged
|
|
|
|
amrac
Guest
|
I´ve 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
|
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: 
Posts: 1147
Imagine
|
Hi, Depending on your system, INT 15H function 86H in a wait function. See Ralf Brown's Interrupt List (RBIL). 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. 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
|
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: 
Posts: 5161
|
Here is another delay procedure. ; ----------------------------------------------------------- ; 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
|
lol - that is some old-timie stuff, Michael how old are you, anyways ?
|
|
|
Logged
|
|
|
|
amrac
Guest
|
I don´t 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
|
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
|
well - stopping the pixel should not be dependant on a delay routine that is more of a program flow issue
|
|
|
Logged
|
|
|
|
FORTRANS
Member
    
Gender: 
Posts: 1147
Imagine
|
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
|
|
|
 |