function like Delay(ms); in Pascal

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

function like Delay(ms); in Pascal

Post by Cmaranec »

I am really beginer in OSDev.

Can you help me with function like Delay(ms); in Pascal or Sleep(ms); in Win API ? I have timer, but i don't know how to make "slowing function". Can you help me please?
uglyoldbob
Member
Member
Posts: 62
Joined: Tue Feb 13, 2007 10:46 am

Post by uglyoldbob »

For this I programmed the timer (IRQ 0) to fire ~1000 times a second.
Delay(unsigned int milliseconds) is called from C code
hope this helps

timer dd 0
irqM0:

push ax

inc dword [timer]

;manual EOI before the interrupt has ended

mov al, 0x20

out 0x20, al

pop ax

iret

[global Delay]
Delay: ;delays for some number of irq0 firings (each of which are about 1 millisecond)
push eax
push ebx
mov eax, [timer]
add eax, [esp + 12] ;eax = delay + time
.wait
mov ebx, [timer]
cmp eax, ebx
jg .wait
pop ebx
pop eax
ret
I have an 80386SX 20MHz 2MB RAM.
It is my testbed platform. Only has the 3.5" and 5.25" floppy drives.
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

ehh..

Post by Cmaranec »

Can I do it in C++ ?
Sorry for my bad English...
uglyoldbob
Member
Member
Posts: 62
Joined: Tue Feb 13, 2007 10:46 am

Post by uglyoldbob »

Yes it will work with C++ code, but you will want to change the declarator in the C++ code to:

extern "C" void Delay(unsigned int milliseconds);

This should avoid name mangling.
I have an 80386SX 20MHz 2MB RAM.
It is my testbed platform. Only has the 3.5" and 5.25" floppy drives.
Tyler
Member
Member
Posts: 514
Joined: Tue Nov 07, 2006 7:37 am
Location: York, England

Post by Tyler »

How would this be done if the Scheduler was relying on the PIT?
uglyoldbob
Member
Member
Posts: 62
Joined: Tue Feb 13, 2007 10:46 am

Post by uglyoldbob »

BogoMips? Take a quick spin around google for it. It is a calculation of how fast your computer can do "nothing" and can ppossibly be used for timing loops.
I have an 80386SX 20MHz 2MB RAM.
It is my testbed platform. Only has the 3.5" and 5.25" floppy drives.
Tyler
Member
Member
Posts: 514
Joined: Tue Nov 07, 2006 7:37 am
Location: York, England

Post by Tyler »

uglyoldbob wrote:BogoMips? Take a quick spin around google for it. It is a calculation of how fast your computer can do "nothing" and can ppossibly be used for timing loops.
No i mean.. what does the timing for a delay function if it cant get access to a PIT? For example in user mode code where the kernel cant provide the service because the kernel uses the PIT for sceduling...
uglyoldbob
Member
Member
Posts: 62
Joined: Tue Feb 13, 2007 10:46 am

Post by uglyoldbob »

You would probably have to use the RTC clock for that (which isn't supported on all hardware, can't seem to remember what doesn't support it, probably old stuff). Or you could introduce a method into your scheduler that delays a process/thread for a minimum of x timer ticks.

//add an item for each process that says (earliest time to execute)
//pretend earlyTime is the variable for the process/thread
earlyTime dd 0

Delay
mov eax, [ticks]
mov [earlyTime], eax
(switch to another task)
ret

EXAMPLE
ticks dd 0
irq0:
inc dword [ticks]
//bla bla scheduler code
//found a process/thread to switch to maybe?
mov eax, earlyTime
cmp eax, [ticks]
if (eax < [ticks])
DONT do this thread/process

This might be the easiest, but you'll probably have to use software task switching instead of hardware switching becuase of the added information for each task.
I have an 80386SX 20MHz 2MB RAM.
It is my testbed platform. Only has the 3.5" and 5.25" floppy drives.
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

Thaks

Post by Cmaranec »

Thank you.
Sorry for my bad English...
Cmaranec
Member
Member
Posts: 45
Joined: Sat Oct 21, 2006 1:07 pm
Location: Czech Republic

hm...

Post by Cmaranec »

Now, the linker giving this:

main.o(.text+0x1ff):main.c: undefined reference to `_Delay'

i wrote "extern void Delay(unsigned int cas);" into system.h included from all .C files of my OS.
i wrote "Delay(2000);" into main.c (for wait 2 seconds)
i wrote your code for Delay: into start.asm when i setting up all IRQ's.
i wrote your code for irqM0: into start.asm into setting of IRQ0
Sorry for my bad English...
User avatar
AJ
Member
Member
Posts: 2646
Joined: Sun Oct 22, 2006 7:01 am
Location: Devon, UK
Contact:

Post by AJ »

Hi - a couple of things:

1) If you want to access your assembly routine from C, you need to prefix the assembly label with an underscore (ie _Delay, rather than Delay).

2) Can the linker see all of your object files and are they all in a supported format?

3) Have you put a 'global _Delay' somewhere in your assembly code?

HTH,
Adam
User avatar
inflater
Member
Member
Posts: 1309
Joined: Thu Sep 28, 2006 10:32 am
Location: Slovakia
Contact:

Post by inflater »

If you have GDT.INC (or something) accessible by your OS kernel, you can switch to real mode -

Code: Select all

XOR EAX,EAX
MOV CR0,EAX
and use INT15,AH=86h function Wait.
CX*65535 and DX is the number of microseconds to wait.
The precision for this function is 977 microseconds.

Then you can switch to protected mode by loading GDT, IDT and other necessary data to stack and setting the first bit of CR0 to 1. :)

But beware - if this function is used very frequently in your OS - your minimal system requirements may be higher than a regular 80386 - switching to real mode from PMode just for delay function and hopping back to PM can be on older machines slow. But it is a delay procedure, so who cares? :D
My web site: http://inflater.wz.cz (Slovak)
Derrick operating system: http://derrick.xf.cz (Slovak and English :P)
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Post by Brendan »

Hi,
inflater wrote:But beware - if this function is used very frequently in your OS - your minimal system requirements may be higher than a regular 80386 - switching to real mode from PMode just for delay function and hopping back to PM can be on older machines slow. But it is a delay procedure, so who cares? :D
I'd guess anyone trying to write protected mode IRQ handlers would be deeply disturbed by this - worst case IRQ latency measured in days.... ;)


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.
Tyler
Member
Member
Posts: 514
Joined: Tue Nov 07, 2006 7:37 am
Location: York, England

Post by Tyler »

Hey

I recently implemented a delay function in my native library... for the sake of it. But it causes serious problems the way i am doing it. Does anyone know how it is done by an operatin system like linux? Do they use the PIT and time the system with APIC or do they simply check the RTC during kernel mode access?
frank
Member
Member
Posts: 729
Joined: Sat Dec 30, 2006 2:31 pm
Location: East Coast, USA

Post by frank »

Tyler wrote:Hey

I recently implemented a delay function in my native library... for the sake of it. But it causes serious problems the way i am doing it. Does anyone know how it is done by an operatin system like linux? Do they use the PIT and time the system with APIC or do they simply check the RTC during kernel mode access?
I don't know how linux does it however, I can tell you how my delay function works. When you call the delay function it passes on the delay count to the scheduler and tells the scheduler not to wake the task up before this delay has passed. Of course that is how I do it, and I'm sure that this is not the only way.
Post Reply