OSDev.org

The Place to Start for Operating System Developers
It is currently Tue Apr 23, 2024 6:21 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 3 posts ] 
Author Message
 Post subject: Sleeping certain amount of time in real mode
PostPosted: Sun Sep 30, 2018 2:56 pm 
Offline
Member
Member

Joined: Thu Sep 27, 2018 5:10 pm
Posts: 28
Location: Turkey
Hi,

I am developing a simple snake game in real mode (for fun and educational purposes). I need to run main game loop periodically. I am using following code to set timer frequency to 1000hz.

Code:
    # setup timer freq (once per milliseconds)
    mov $1193,%bx
    mov $0x36,%al
    out %al,$0x43
    mov %bl,%al
    out %al,$0x40
    mov %bh,%al
    out %al,$0x40


I am using this function to sleep certain amount of time.

Code:
/* put milliseconds to sleep in %ax, %ax trashed */
sleep:
    push %bx
    mov timer_ticks,%bx
    add %bx,%ax
sleep0:
    mov timer_ticks,%bx
    cmp %bx,%ax
    jle sleep1
    hlt
    jmp sleep0
sleep1:
    pop %bx
    ret


I am testing this code using Virtualbox. sleep function seems to take more time than I intend. Am I doing everything properly here?

Complete code is accessible here: https://github.com/yasar11732/snakeos/b ... 54/snake.s

Edit:
My interrupt handler:

Code:
irq_return:
    mov $0x20,%al
    out %al,$0x20
    popa
    iret

timer_handler:
    pusha
    incw timer_ticks
    jmp irq_return


Top
 Profile  
 
 Post subject: Re: Sleeping certain amount of time in real mode
PostPosted: Sun Sep 30, 2018 5:03 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5143
Virtual machines have trouble keeping time accurately. Does it also run at the wrong speed on bare metal?

If it runs at the correct speed on bare metal, you may need to reconfigure your virtual machine or use a different one.


Top
 Profile  
 
 Post subject: Re: Sleeping certain amount of time in real mode
PostPosted: Sun Sep 30, 2018 5:43 pm 
Offline
Member
Member
User avatar

Joined: Sat Jan 15, 2005 12:00 am
Posts: 8561
Location: At his keyboard!
Hi,

I can't find a bug in the code that would explain the symptoms; but...

yasar11732 wrote:
Am I doing everything properly here?


A signed 16-bit integer has a range from -32768 to +32768 (a total of 65536 values). If it's incremented 1000 times per second it'll overflow every 65536/1000 = 65.536 seconds.

Now let's see what happens when the "timer_ticks" contains +32767 and you call this code with "milliseconds to sleep = 10":

Code:
/* put milliseconds to sleep in %ax, %ax trashed */
sleep:
    push %bx
    mov timer_ticks,%bx          ;bx = +32767
    add %bx,%ax                  ;ax = +32767 + 10 = -32759 due to overflow
sleep0:
    mov timer_ticks,%bx          ;bx = +32767 still
    cmp %bx,%ax
    jle sleep1                   ;if(-32759 <= +32767) exit the loop
    hlt
    jmp sleep0
sleep1:
    pop %bx
    ret


What this means is that sometimes it will return immediately with no delay at all.

Note: It's more common to use unsigned integers (e.g. "jbe sleep1"), but you'd have the same bug in that case (e.g. "65535 + 10 = 9 due to overflow").

To fix both of these, try something like:

Code:
/* put milliseconds to sleep in %ax, %ax trashed */
sleep:
    push %cx
    push %bx
    mov timer_ticks,%cx          ;cx = starting tick
sleep0:
    mov timer_ticks,%bx          ;bx = current tick
    sub %cx,%bx                  ;bx = current tick - starting tick = time passed

    cmp %ax,%bx
    jae sleep1                   ;If time passed >= delay exit the loop
    hlt
    jmp sleep0
sleep1:
    pop %bx
    pop %cx
    ret


This code should be immune to overflows.

Also note that if you ask for a 1 ms delay immediately before the timer IRQ occurs you could delay for almost no time at all. Essentially the code waits for between (AX-1) and AX milliseconds (and doesn't wait for at least AX milliseconds). To fix that you can change the the branch to "ja sleep1".


Cheers,

Brendan

_________________
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 3 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 107 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group