News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Delay needed

Started by Magnum, December 30, 2012, 06:35:56 AM

Previous topic - Next topic

Magnum

The snow falls too fast and I would like to slow it down.

I have some code for a CPU independent delay but don't know where to put the delay.



; snow.asm
;
.model tiny
.386

.code

org 100h

start:
jmp begin

eoh db '* SOPHIE *'



begin:

mov ax,13h ; video mode
int 10h
mov bl,2 ; foreground color, bright red = 4
push 0a000h
pop es
mov bh,10d ;this contains count of chars to be

; (this matches what is in eoh)
mov di,30508
mov si,offset eoh

nogeenchar:

mov cl,ds:[si]
inc si
push si
push di
push bx
push ds
push 0f000h
pop ds
mov si,0fa6eh
shl cx,3
add si,cx
mov cx,08

nogeenrow:

lodsb
mov ah,al
mov dl,10000000b

nogeenpixel:

mov al,ah
and al,dl
jz nietneerzetten
mov al,bl
stosb
dec di

nietneerzetten:

inc di
shr dl,1
jnz nogeenpixel
add di,312
dec cx
jnz nogeenrow
pop ds
pop bx
pop di
pop si
add di,8
dec bh
jnz nogeenchar
xor ax,ax
push ax

claudia:
pop ax
inc ax
push ax
sub di,bx
add di,ax
add di,cx
and di,0000001000000000b
shr di,9
push di
mov si,319 ;<---- ; Hier wordt de

mov cl,3 ; eax = n

sneeuwvlokje: ; ebx = n
add ax,bp ; ecx = n
add ax,bx ; edx = n
sub ax,di ; esi = n <- die moet

mov bx,di ; edi = n
or bx,ax ; ebp = n
not ax ; fs add bx,dx ; gs
xor ax,bx ; ds add al,ah ; es mov
;bp,ax
test bp,1
jnz pleuris
not bp
shr bp,1
pleuris:
cmp ax,319
jna gassen
sub ax,319
jmp pleuris
gassen:
add ax,63680
mov di,ax
mov ax,0a000h
mov es,ax
mov al,15
stosb
dec cl
jnz sneeuwvlokje

mov cx,64000-319
push 0a000h
pop es
push es
pop ds
mov ax,15
pop di

volgendepixel:
mov dl,ds:[si] ;bx was si
mov bx,-319
add bx,di
cmp dl,15
jne klaar

nogeenrandommer:
add dx,cx
xor dx,di
add dl,dh
and dl,00000011b
cmp dl,3
je drie
cmp dl,2
je twee
cmp dl,1
jne nogeenrandommer
een:
call piaf
witte1:
dec bx
call piaf
witte2:
dec bx
call paf
jne klaar
jmp plop
twee:
dec bx
call piaf
witte3:
inc bx
call piaf
witte4:
dec bx
dec bx
call paf
jne klaar
jmp plop
drie:
dec bx
dec bx
call piaf
witte5:
inc bx
call piaf
witte6:
inc bx
call paf
jne klaar
jmp plop

ploep:
pop bp

plop:
mov ds:[si],ah
mov ds:[si-bx],al
klaar:
inc si
dec cx
jnz volgendepixel

mov ah,1 ;Check for a key
int 16h

jz claudia ;Loop back

xor ah,ah ;Eat the key
int 16h

mov ax,03h
int 10h
pop ax
push cs
pop ds
ret

piaf proc
call paf
je ploep
ret
endp

paf proc
mov dl,ds:[si-bx]
cmp dl,00
ret
endp

end start

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Tedd


klaar:
inc si
dec cx
jnz volgendepixel

;; ...SHORT DELAY...

mov ah,1 ;Check for a key
int 16h
jz claudia ;Loop back
Potato2

Magnum

Thanks Tedd.

I need a shorter delay than 1/18 of a second.

I will search for something with a finer granularity.

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

that's a tough one in 16-bit mode
i have been looking around for a good way to delay, without hogging the cpu
no luck, yet

Magnum

Two ways to delay which are CPU independent.

I ran the snow code and did an Alt Tab to open up Task Manager.


; cx:dx registerpair holds value to wait for in microseconds
; 000f4240 (hex) is 1000000 = 1 second
;
;     mov cx,2h
;     mov dx,07c0h
;     mov ah,86h
;     int 15h

  mov       ah,0     ; function no. for read
               int          1ah      ; get the time of day count
               add          dx,2     ; add « second delay to low word 18 = 1 second
               mov          bx,dx    ; store end of delay value in bx
  again:                           
               int          1ah
               cmp          dx,bx
               jne          again


mov ah,1 ;Check for a key
int 16h




; snow.asm
;
.model tiny
.386

.code

org 100h

start:
jmp begin

eoh db '* SOPHIE *'



begin:

mov ax,13h ; video mode
int 10h
mov bl,2 ; foreground color, bright red = 4
push 0a000h
pop es
mov bh,10d ;this contains count of chars to be

; (this matches what is in eoh)
mov di,30508
mov si,offset eoh

nogeenchar:

mov cl,ds:[si]
inc si
push si
push di
push bx
push ds
push 0f000h
pop ds
mov si,0fa6eh
shl cx,3
add si,cx
mov cx,08

nogeenrow:

lodsb
mov ah,al
mov dl,10000000b

nogeenpixel:

mov al,ah
and al,dl
jz nietneerzetten
mov al,bl
stosb
dec di

nietneerzetten:

inc di
shr dl,1
jnz nogeenpixel
add di,312
dec cx
jnz nogeenrow
pop ds
pop bx
pop di
pop si
add di,8
dec bh
jnz nogeenchar
xor ax,ax
push ax

claudia:
pop ax
inc ax
push ax
sub di,bx
add di,ax
add di,cx
and di,0000001000000000b
shr di,9
push di
mov si,319 ;<---- ; Hier wordt de

mov cl,3 ; eax = n

sneeuwvlokje: ; ebx = n
add ax,bp ; ecx = n
add ax,bx ; edx = n
sub ax,di ; esi = n <- die moet

mov bx,di ; edi = n
or bx,ax ; ebp = n
not ax ; fs add bx,dx ; gs
xor ax,bx ; ds add al,ah ; es mov
;bp,ax
test bp,1
jnz pleuris
not bp
shr bp,1
pleuris:
cmp ax,319
jna gassen
sub ax,319
jmp pleuris
gassen:
add ax,63680
mov di,ax
mov ax,0a000h
mov es,ax
mov al,15
stosb
dec cl
jnz sneeuwvlokje

mov cx,64000-319
push 0a000h
pop es
push es
pop ds
mov ax,15
pop di

volgendepixel:
mov dl,ds:[si] ;bx was si
mov bx,-319
add bx,di
cmp dl,15
jne klaar

nogeenrandommer:
add dx,cx
xor dx,di
add dl,dh
and dl,00000011b
cmp dl,3
je drie
cmp dl,2
je twee
cmp dl,1
jne nogeenrandommer
een:
call piaf
witte1:
dec bx
call piaf
witte2:
dec bx
call paf
jne klaar
jmp plop
twee:
dec bx
call piaf
witte3:
inc bx
call piaf
witte4:
dec bx
dec bx
call paf
jne klaar
jmp plop
drie:
dec bx
dec bx
call piaf
witte5:
inc bx
call piaf
witte6:
inc bx
call paf
jne klaar
jmp plop

ploep:
pop bp

plop:
mov ds:[si],ah
mov ds:[si-bx],al
klaar:
inc si
dec cx
jnz volgendepixel

; cx:dx registerpair holds value to wait for in microseconds
; 000f4240 (hex) is 1000000 = 1 second
;
;     mov cx,2h
;     mov dx,07c0h
;     mov ah,86h
;     int 15h

  mov          ah,0     ; function no. for read
               int          1ah      ; get the time of day count
               add          dx,2     ; add « second delay to low word 18 = 1 second
               mov          bx,dx    ; store end of delay value in bx
  again:                           
               int          1ah
               cmp          dx,bx
               jne          again


mov ah,1 ;Check for a key
int 16h

jz claudia ;Loop back

xor ah,ah ;Eat the key
int 16h

mov ax,03h
int 10h
pop ax
push cs
pop ds
ret

piaf proc
call paf
je ploep
ret
endp

paf proc
mov dl,ds:[si-bx]
cmp dl,00
ret
endp

end start

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

Tedd

Quote from: dedndave on December 30, 2012, 07:45:57 AM
that's a tough one in 16-bit mode
i have been looking around for a good way to delay, without hogging the cpu
no luck, yet

The PIT can be reprogrammed for a much higher frequency, but that would obviously throw off anything else relying on it. However, since the handlers are chained, you can reprogram the timer for 10x speed and call the previous interrupt handler only once every 10 interrupts ;)
Potato2

Tedd

The second method is a busy loop - it repeatedly checks the PIT ticks until the required value has been reached.

The first method (int 1Ah,86h) actually suspends execution, and with a much finer granularity.
Potato2

MichaelW

Under DOS and Windows 9x the BIOS Event Wait (Interrupt 15h, function 83h, requires polling a flag) and Wait (Interrupt 15h, function 86h) functions work well for short delays, but unfortunately (and IIRC) they are not supported under NTVDM.
Well Microsoft, here's another nice mess you've gotten us into.

MichaelW

The attachment contains a fairly recent version of some old code that uses system timer 0 and an IRQ0 (Int8) ISR to provide a millisecond resolution timer, a Sleep procedure based on that timer, and a simple test app. There are several methods of doing this that run fine under DOS, but I selected this method because it runs fine under NTVDM and has good long-term accuracy.
Well Microsoft, here's another nice mess you've gotten us into.

MichaelTripi68

Quote from: MichaelW on January 01, 2013, 07:26:19 PM
The attachment contains a fairly recent version of some old code that uses system timer 0 and an IRQ0 (Int8) ISR to provide a millisecond resolution timer, a Sleep procedure based on that timer, and a simple test app. There are several methods of doing this that run fine under DOS, but I selected this method because it runs fine under NTVDM and has good long-term accuracy.

Michael,  I was just browsing the forum posts for a similar function.  Thanks for the post!!  Not only does it provide what I needed but after studying your code (which was well documented :)), I now understand alot about ISR coding in assembler.  Awesome snippet!!