Cleanup in elf.c with .bss section clean; adm command mounts cdrom instead of floppy...
[ZeXOS.git] / kernel / lib / stdio / delay.c
blobf6c44a9eadc5f67d3bee620f73b7973bd6920d29
1 /*
2 * ZeX/OS
3 * Copyright (C) 2007 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
4 * Copyright (C) 2008 Tomas 'ZeXx86' Jedrzejek (zexx86@zexos.org)
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * Allright, let's review how we're going to do this.
24 * Goal:
25 * The goal is to create a reasonably accurate version of the delay()
26 * function, which creates a delay in multiples of one millisecond.
28 * Restrictions:
29 * We don't want to use the PIT for the delay. In your average
30 * bare-hardware system (ie OS) you'll be using the PIT for quite a few
31 * other things already (in my OS code, channel 0 and 1 are used by the
32 * scheduler, and channel 2 would probably be needed to control the
33 * speaker.)
35 * Method:
36 * A simple loop would delay the computer wonderfully. Ie, take something
37 * like:
39 * for(i=0;i<BIGNUMBER;i++); // Delay loop
41 * That kills time wonderfully. All we need to do is to find out what
42 * BIGNUMBER we need to use to delay one millisecond. Finding the correct
43 * BIGNUMBER for your machine is called *delay loop calibration*.
45 * We can calibrate the delay loop using the PIT. In the initialisation
46 * phase of the OS, when the PIT is not yet hooked to the scheduler, it
47 * can be freely used to do this. When the delay loop has been calibrated
48 * against the PIT, the PIT is free to be used for other purposes.
50 * There are many ways to calibrate a delay loop with the PIT. This is
51 * one way (used in Linux.) More documentation in the code.
54 /**************************************************************************/
57 * When I was testing the delay code, I notice that the calibration we use
58 * is very delicate. Originally, I had inlined the delay for() loops into
59 * the delay() and calibrateDelayLoop() functions, but this doesn't work.
60 * Due to different register allocation or something similar the compiler
61 * might have generated different code in the two situations (I didn't
62 * check this.) Or alignment differences might have caused the problems.
63 * Anyway, to solve the problem, we always use the __delay() function for
64 * the delay for() loop, because it always is the same code with the same
65 * alignment. __delay() is called from delay() as well as from
66 * calibrateDelayLoop(). By using __delay() we can fine-tune our
67 * calibration without it losing its finesse afterwards.
70 void __delay(unsigned long loops)
72 unsigned long c;
73 for (c = 0; c < loops; c ++);
76 extern unsigned long timer_swticks;
78 void delay (unsigned long milliseconds)
80 __delay (milliseconds * timer_swticks); /* Delay milliseconds ms */
83 /* The end */