user3763588
user3763588

Reputation: 11

Assembly system time DOS

I wrote some code:

petla:
mov ah,2
int 1ah

mov[sekunda], dh
mov ah, [sekunda]
mov cl, 4
and ah, 11110000b 
shr ah, cl  
mov dl, ah
add dl, '0'
mov ah, 2
int 21h

mov ah, [sekunda]
and ah, 00001111b   
mov dl, ah
add dl, '0'
mov ah, 2
int 21h

jmp petla

sekunda db 0

When I run this program shows me lot of values (seconds) looks like this:

12
12
12
12
12
13
13

How modify code to show only one time one values ( one seconds one value)?

How I can modify code to show for example time every 5 sec?

I need this to my main code where after x seconds something will be changed.

Upvotes: 0

Views: 611

Answers (1)

lornix
lornix

Reputation: 2036

Remember that seconds are very long periods of time for a computer (Well, for the last 40-50 years at least!)

Your little program is grabbing the time value very quickly, so it can get the current time several thousand (million even!) times a second.

If you only want an output when it changes, try something like the following: (We're adding a comparison)

petla:
    mov ah,2
    int 1ah             ; get time

    mov ah, [sekunda]   ; retrieve last good value
    cmp ah, dh          ; is it same as last good value?
    jz  pet1a           ; yup, ignore it, loop again!

    mov [sekunda], dh   ; save seconds

    mov ah, [sekunda]   ; get seconds value
    mov cl, 4           ; ready to shift 4 bits
    and ah, 11110000b   ; isolate top nybble
    shr ah, cl          ; shift into low nybble
    mov dl, ah          ; move into proper register for output
    add dl, '0'         ; magically transform into ASCII digit
    mov ah, 2           ; Select 'write char'
    int 21h             ; uh... write char!

    mov ah, [sekunda]   ; hey, this seems familiar!
    and ah, 00001111b   ; isolate lower nybble!
    mov dl, ah          ; no, really.. deja vu!
    add dl, '0'         ; TaaDaa, it's a char!
    mov ah, 2           ; Select 'write char'
    int 21h             ; make it so!

    jmp petla           ; do it again!  (make this a 'ret', see below)

Now this little routine will constantly output a new value every second... perhaps not very valuable...

But wait! There's more!

If you change the LAST instruction (jmp pet1a) to a return (ret), we can use it as part of a 'wait_for_five_seconds' routine... like so:

wait_for_five_seconds:
    mov al,5              ; how many seconds to wait
wait_for_al_seconds:      ; explained below
wait_loop:
    push ax               ; save our counter (al)
    call pet1a            ; this will call pet1a, which will not return until it has displayed a new second value
    pop ax                ; retrieve our counter (pet1a changes value of ah/al/ax, remember?)
    dec al                ; decrease al by one (does not set flags!!)
    or al,al              ; set flags
    jnz wait_loop         ; al=0?  nope, around we go again!
    ret                   ; go back to whomever called us!

Now, if you wanted to pause for 5 seconds, you simple call wait_for_five_seconds and it'll work!

If you remove the part of pet1a that writes the characters out... you then have a silent delay of one second. Useful for pausing.

What if you wanted to pause for 17 seconds? Hmmm, our delay is based on the value of al when we enter the wait_loop section... so what if we preloaded al, then called the wait bit?

    mov al, 17                 ; delay for 17 seconds!
    call wait_for_al_seconds   ; delay for whatever number is in al

Be careful though, if al has a value of 0... it has to loop all the way around... 0, -1, -2, ... -127, -128, 127, 126... 2, 1, 0 ... you'd pause for 256 seconds! (4 minutes, 16 seconds!). (See Signed Number Representations for why it went weird around -128)

I hope this has helped and perhaps given you some ideas. It's not an idea 'pause' solution since it isn't an exact delay, if you called pet1a just before a new second ticked over, the delay would be teeny-tiny for the first click, then full seconds for the rest... so a desired delay of 5 seconds could be anywhere from 4.000001 seconds to 5 seconds long. But it's a start.

Upvotes: 1

Related Questions