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
klaar:
inc si
dec cx
jnz volgendepixel
;; ...SHORT DELAY...
mov ah,1 ;Check for a key
int 16h
jz claudia ;Loop back
Thanks Tedd.
I need a shorter delay than 1/18 of a second.
I will search for something with a finer granularity.
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
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
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 ;)
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.
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.
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.
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!!