timer(IRQ 0)

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.
hanoi

timer(IRQ 0)

Post by hanoi »

Hey!
I have some problems with the timer..
I've looked in a few sources, but they did exactly like me.
My IDT&PIC-Remap are working(i know from keyboard).
So i am wondering why it doesn't work...

-Code-
void timer_set(unsigned int frequency)
{
unsigned short foo = 1193182 / frequency;
outp(0x43, 0x36);   
outp(0x40, (unsigned char) foo);   
outp(0x40, (unsigned char)(foo >> 8));
return;
}

void main()
{
...
timer_set( 100 ); //set frequency of timer 0(which is connected to IRQ 0) to 100
setVector(0x20, (void *)(tim));
...
}

asm (
".globl _tim \n"
"_tim: \n"
"cli \n"
"pusha \n"
"pushf \n"
"call _timer \n"
"popf \n"
"popa \n"
"sti \n"
"iret \n"
);

void timer()
{
outp(0x20,0x20);
k_printf("timer\n");
counter++;
return;
}
-Code-
I would be glad toget it working, because without it'd be difficult to make a multi-tasking somehow.
jrfritz

Re:timer(IRQ 0)

Post by jrfritz »

You need a ASM stub and here:

in asm:
GLOBAL IRQ0
EXTERN PIT

IRQ0:
pusha
call PIT
mov al, 0x20
out 0x20, al
popa
IRET

in your C code:

extern void IRQ0(); // Your IDT calles THIS function

void PIT()
{
k_printf( "timer " );
counter++;
}
hanoi

Re:timer(IRQ 0)

Post by hanoi »

asm (
".globl _tim \n"
"_tim: \n"
"cli \n"
"pusha \n"
"pushf \n"
"call _timer \n"
"popf \n"
"popa \n"
"sti \n"
"iret \n"
);


setVector(0x20, (void *)(tim));
hanoi

Re:timer(IRQ 0)

Post by hanoi »

this should work as the other
jrfritz

Re:timer(IRQ 0)

Post by jrfritz »

Opps didn't read that.

Must be your timer_set.

Try without it.
hanoi

Re:timer(IRQ 0)

Post by hanoi »

:(
unfourtanetly not.
I dunno what to do :(
richie

Re:timer(IRQ 0)

Post by richie »

It would be possible that you forgot to enable IRQ 0 at the PIC. This would explain why you get no timer-int but you get a keyboard-int.
If your timer-interrupt-routine is never called it has something to do with enabling the interrupts: The interrupt-flag must be set (sti), your IDT must be set right and the PIC must be set right. If your keyboard-interrupt-handler works the only possible fault can be the PIC.
If I understand your right you copied the code from some other OS-Source. To understand how the PIc is programmed you can go to the following page where you find some useful links to PIC-related topics:
http://www.nondot.org/sabre/os/articles/MiscellaneousDevices/
jrfritz

Re:timer(IRQ 0)

Post by jrfritz »

Maybe your RemapIRQs doesn't remap IRQ0 ???
hanoi

Re:timer(IRQ 0)

Post by hanoi »

i've put outp(0x20,0); outp(0xA0, 0);
at the end of the PIC_remap function....
hanoi

Re:timer(IRQ 0)

Post by hanoi »

this enables all IRQs , doesn't it?
jrfritz

Re:timer(IRQ 0)

Post by jrfritz »

Maybe your out of memory...where did you load your OS into?

When you run out of memory...your IDT won't work properly.
hanoi

Re:timer(IRQ 0)

Post by hanoi »

My OS is loaded from my bootloader to 0x100000
richie

Re:timer(IRQ 0)

Post by richie »

I have the following function to remap all IRQs to ints and enable them:

Code: Select all

//The following code is not my idea,
//it is the mixture of different OS-sources
 #define   PIC1_COMMAND   0x20 
 #define   PIC1_DATA   0x21 
 #define   PIC2_COMMAND   0xA0 
 #define   PIC2_DATA   0xA1 

 #define   ICW1_ICW4   0x01
 #define   ICW1_INIT   0x10
 #define   ICW4_8086   0x01

 void remap_pics(int pic1, int pic2) 
 { 
  unsigned char a1, a2; 

  a1=inportb(PIC1_DATA); 
  a2=inportb(PIC2_DATA); 
 
  outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4); 
  outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4); 
  outportb(PIC1_DATA, pic1); 
  outportb(PIC2_DATA, pic2); 
  outportb(PIC1_DATA, 4); 
  outportb(PIC2_DATA, 2); 
  outportb(PIC1_DATA, ICW4_8086); 
  outportb(PIC2_DATA, ICW4_8086); 
    
  outportb(PIC1_DATA, a1); 
  outportb(PIC2_DATA, a2); 
 }; 

To remap:
IRQ 0 - IRQ 7 => INT 0x20 - INT 0x27
IRQ 8 - IRQ 15 => INT 0x28 - INT 0x2F

You can use the following code:

Code: Select all

//in your init_kernel_function

//...

 remap_pics(0x20, 0x28);   // irq 0 20h irq 8 28h 
 sti(); //enable interrupts 

//...
Of course you need a handler for every int from 0x20 to 0x2F even if these handlers are only dummy handlers.
jrfritz

Re:timer(IRQ 0)

Post by jrfritz »

May I see your bootloader code? I can't get mine to load at 1 meg.

You can post it in the Text Truncated thread...

as for your PIT...I can't see the problem...
hanoi

Re:timer(IRQ 0)

Post by hanoi »

I can explain how i did this:
i loaded the kernel to 0x10000 with bios.
then i switched to pmode.
(i've made two big segments(4Gb)(1 data, 1 code)
Then i've copied the kernel from 0x10000 to 0x100000
with movsb:
mov ecx, Kernelsize
mov esi, 0x10000
mov edi, 0x100000
rep movsb
that's it
Post Reply