Timerproblem - Programmers Heaven

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Timerproblem

I know the timer at meml[$0040:$006C].

But i have seen a timer-procedure which have a delay that is 256 times faster than this.

Does anyone know how this works?


Comments

  • : I know the timer at meml[$0040:$006C].

    : But i have seen a timer-procedure which have a delay that is 256 times faster than this.

    : Does anyone know how this works?

    :



    No, not how that one does specifically. I do know how you could accomplish it though.



    First off, you could always use the PIC. The Timer interrupt (which increments the BIOS timer) is on one of the channels of the PIC. It is set to the longest intervals that the PIC can support which is appoximately 18 ms. There is other channels of the PIC and you can program it to go much faster.



    Another scheme, would be to use the timestamp. I believe it is only on Pentiums and better, but I may be wrong. Anyways, the timestamp is incremented every clock cycle, which means millions of times per second. That is the most precise timer on the computer, however it is different depending on the speed of the CPU. However, once you get the speed of the CPU you can get very precise interval timers.



    Also, you can use the CMOS's clock which is supposed to be pretty precise as well.


  • : : I know the timer at meml[$0040:$006C].

    : : But i have seen a timer-procedure which have a delay that is 256 times faster than this.

    : : Does anyone know how this works?

    : :

    :

    : No, not how that one does specifically. I do know how you could accomplish it though.

    :

    : First off, you could always use the PIC. The Timer interrupt (which increments the BIOS timer) is on one of the channels of the PIC. It is set to the longest intervals that the PIC can support which is appoximately 18 ms. There is other channels of the PIC and you can program it to go much faster.

    :

    : Another scheme, would be to use the timestamp. I believe it is only on Pentiums and better, but I may be wrong. Anyways, the timestamp is incremented every clock cycle, which means millions of times per second. That is the most precise timer on the computer, however it is different depending on the speed of the CPU. However, once you get the speed of the CPU you can get very precise interval timers.

    :

    : Also, you can use the CMOS's clock which is supposed to be pretty precise as well.

    :



    Thanks!



    How does this PIC work? How can I program it? Do I have to create an iterrupthandler?




  • : How does this PIC work? How can I program it? Do I have to create an iterrupthandler?

    :

    :





    Uh, i have two typos, it should be 55 ms (18.2 times a second) also, I meant PIT wherever I said PIC. Not that it makes much of a difference... yet. PIC=Programmable Interrupt Controller (not something you typically want to mess with, though it can be fun) PIT = Programmable Interval Timer which I've never actually used it because I've never had need to.







    That doesn't mean I don't know how to use it though.



    anyways...



    There are three channels on the PIT. Channel 0 goes to the timer, channel 1 goes to DRAM refresh, and Channel 2 goes to the speaker.



    You DO NOT want to mess with the DRAM one (at least not much, and it's probably safer... much safer if you don't).



    The speaker one is only good for making crappy sounds on a PC speaker.



    So you're left with only the timer one. Unforunately, as I said, the timer one is being used. So, yes, you will have to mess with interrupt handlers (which I don't see why people have such a problem with, I find it stupidly simple). This is an especially sticky case because you can't just call the BIOS interrupt everytime because most likely your interrupt handler is being called more than normal, which would speed up the system clock (until reboot). So what you need to do is call the BIOS interrupt when it needs to be called. So let's say you get called every ms. Then simply call the BIOS handler every 55th time the interrupt handler is called. This can be implemented easily by simply using a counter. And there you have it, all you need to know now is how to change the interval on the PIT.



    To answer how the PIT works (which is what you mean to ask, only I had a typo). It is simply a chunk of hardware (probably a VERY small chunk) that has a counter that it decrements, and every time it hits 0 it does something depending on what mode it's set to. I won't go into any modes because it's not relevant. What it normally does when it hits 0 for channel 0, is call the timer interrupt by raising the first pin on the PIC (yes the PIC this time). That in turn starts the timer interrupt going.



    the basic code you'll need is this...



    Port[$43]:=$34;

    Port[$40]:=low_byte_of_counter;

    Port[$40]:=high_byte_of_counter;



    counter := $1234DD/number_of_times_per_second;



    and to reset it back to normal when you are done just use a counter of 0.


  • Thanks!



    From where do you know that all? (Especially the port-Numbers and -functions)

    Do you have a table of the port-functions?



    : : How does this PIC work? How can I program it? Do I have to create an iterrupthandler?

    : :

    : :

    :

    :

    : Uh, i have two typos, it should be 55 ms (18.2 times a second) also, I meant PIT wherever I said PIC. Not that it makes much of a difference... yet. PIC=Programmable Interrupt Controller (not something you typically want to mess with, though it can be fun) PIT = Programmable Interval Timer which I've never actually used it because I've never had need to.

    :

    :

    :

    : That doesn't mean I don't know how to use it though.

    :

    : anyways...

    :

    : There are three channels on the PIT. Channel 0 goes to the timer, channel 1 goes to DRAM refresh, and Channel 2 goes to the speaker.

    :

    : You DO NOT want to mess with the DRAM one (at least not much, and it's probably safer... much safer if you don't).

    :

    : The speaker one is only good for making crappy sounds on a PC speaker.

    :

    : So you're left with only the timer one. Unforunately, as I said, the timer one is being used. So, yes, you will have to mess with interrupt handlers (which I don't see why people have such a problem with, I find it stupidly simple). This is an especially sticky case because you can't just call the BIOS interrupt everytime because most likely your interrupt handler is being called more than normal, which would speed up the system clock (until reboot). So what you need to do is call the BIOS interrupt when it needs to be called. So let's say you get called every ms. Then simply call the BIOS handler every 55th time the interrupt handler is called. This can be implemented easily by simply using a counter. And there you have it, all you need to know now is how to change the interval on the PIT.

    :

    : To answer how the PIT works (which is what you mean to ask, only I had a typo). It is simply a chunk of hardware (probably a VERY small chunk) that has a counter that it decrements, and every time it hits 0 it does something depending on what mode it's set to. I won't go into any modes because it's not relevant. What it normally does when it hits 0 for channel 0, is call the timer interrupt by raising the first pin on the PIC (yes the PIC this time). That in turn starts the timer interrupt going.

    :

    : the basic code you'll need is this...

    :

    : Port[$43]:=$34;

    : Port[$40]:=low_byte_of_counter;

    : Port[$40]:=high_byte_of_counter;

    :

    : counter := $1234DD/number_of_times_per_second;

    :

    : and to reset it back to normal when you are done just use a counter of 0.

    :






Sign In or Register to comment.