Page 1 of 1

(PIC&PIT) What it doesn't work in my source?

Posted: Sun Jul 19, 2009 2:49 pm
by Karlosoft
Hi! I wrote a simple pic driver based on the code of Bran's osdev tutorial. Well doesn't work.... Here there are four files, pic.cpp pic.h pit.cpp pit.h

Code: Select all

//Pic.cpp
#include "io.h"
#include "datatypes.h"
#include "idt.h"
#include "video.h"


void (*irq_routines[16])(struct regs *r) =
{
    0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0
};


void irq_handler(struct regs *r)
{

    void (*handler)(struct regs *r);


    handler = *(irq_routines+(r->int_no - 32));
    if (handler)
    {
        handler(r);
    }


    if (r->int_no >= 40)
    {
        outb(0xA0, 0x20);
    }

    outb(0x20, 0x20);
}



void irq0(){
     regs r;
     r.int_no=32;
     irq_handler(&r);
     };
     
void irq1(){
     regs r;
     r.int_no=33;
     irq_handler(&r);
     };
void irq2(){
     regs r;
     r.int_no=34;
     irq_handler(&r);
     };
void irq3(){
     regs r;
     r.int_no=35;
     irq_handler(&r);
     };
void irq4(){
     regs r;
     r.int_no=36;
     irq_handler(&r);
     };
void irq5(){
     regs r;
     r.int_no=37;
     irq_handler(&r);
     };
void irq6(){
     regs r;
     r.int_no=38;
     irq_handler(&r);
     };
void irq7(){
     regs r;
     r.int_no=39;
     irq_handler(&r);
     };
void irq8(){
     regs r;
     r.int_no=40;
     irq_handler(&r);
     };
void irq9(){
     regs r;
     r.int_no=41;
     irq_handler(&r);
     };
void irq10(){
     regs r;
     r.int_no=42;
     irq_handler(&r);
     };
void irq11(){
     regs r;
     r.int_no=43;
     irq_handler(&r);
     };
void irq12(){
     regs r;
     r.int_no=44;
     irq_handler(&r);
     };
void irq13(){
     regs r;
     r.int_no=45;
     irq_handler(&r);
     };
void irq14(){
     regs r;
     r.int_no=46;
     irq_handler(&r);
     };
void irq15(){
     regs r;
     r.int_no=47;
     irq_handler(&r);
     };



void irq_install_handler(int irq, void (*handler)(struct regs *r))
{
    irq_routines[irq] = handler;
}


void irq_uninstall_handler(int irq)
{
    irq_routines[irq] = 0;
}


void irq_remap()
{
    outb(0x20, 0x11);
    outb(0xA0, 0x11);
    outb(0x21, 0x20);
    outb(0xA1, 0x28);
    outb(0x21, 0x04);
    outb(0xA1, 0x02);
    outb(0x21, 0x01);
    outb(0xA1, 0x01);
    outb(0x21, 0x0);
    outb(0xA1, 0x0);
}


void irq_install()
{
    irq_remap();

    idt_set_gate(32, (unsigned)irq0, 0x08, 0x8E);
    idt_set_gate(33, (unsigned)irq1, 0x08, 0x8E);
    idt_set_gate(34, (unsigned)irq2, 0x08, 0x8E);
    idt_set_gate(35, (unsigned)irq3, 0x08, 0x8E);
    idt_set_gate(36, (unsigned)irq4, 0x08, 0x8E);
    idt_set_gate(37, (unsigned)irq5, 0x08, 0x8E);
    idt_set_gate(38, (unsigned)irq6, 0x08, 0x8E);
    idt_set_gate(39, (unsigned)irq7, 0x08, 0x8E);

    idt_set_gate(40, (unsigned)irq8, 0x08, 0x8E);
    idt_set_gate(41, (unsigned)irq9, 0x08, 0x8E);
    idt_set_gate(42, (unsigned)irq10, 0x08, 0x8E);
    idt_set_gate(43, (unsigned)irq11, 0x08, 0x8E);
    idt_set_gate(44, (unsigned)irq12, 0x08, 0x8E);
    idt_set_gate(45, (unsigned)irq13, 0x08, 0x8E);
    idt_set_gate(46, (unsigned)irq14, 0x08, 0x8E);
    idt_set_gate(47, (unsigned)irq15, 0x08, 0x8E);
}


Code: Select all

//Pic.h
#ifndef PIC_H
#define PIC_H

#include "datatypes.h"  

void irq0();
void irq1();
void irq2();
void irq3();
void irq4();
void irq5();
void irq6();
void irq7();
void irq8();
void irq9();
void irq10();
void irq11();
void irq12();
void irq13();
void irq14();
void irq15();

void irq_install_handler(int irq, void (*handler)(struct regs *r));
void irq_uninstall_handler(int irq);
void irq_remap();
void irq_install();
void irq_handler(struct regs *r);
        
#endif

Code: Select all

//Pit.cpp
#include "Video.h"
#include "io.h"
#include "datatypes.h"
#include "idt.h"
#include "isrs.h"  
#include "pic.h"  
#include "pit.h"
 
int timer_ticks = 0;

/* Handles the timer. In this case, it's very simple: We
*  increment the 'timer_ticks' variable every time the
*  timer fires. By default, the timer fires 18.222 times
*  per second. Why 18.222Hz? Some engineer at IBM must've
*  been smoking something funky */
void timer_handler(struct regs *r)
{
     Video vid;
    /* Increment our 'tick count' */
    timer_ticks++;

    /* Every 18 clocks (approximately 1 second), we will
    *  display a message on the screen */
    if (timer_ticks % 18 == 0)
    {
        vid.puts("One second has passed\n", ALERT);
    }
}
/* This will continuously loop until the given time has
*  been reached */
void timer_wait(int ticks)
{
    unsigned long eticks;

    eticks = timer_ticks + ticks;
    while(timer_ticks < eticks);
}

/* Sets up the system clock by installing the timer handler
*  into IRQ0 */
void timer_install()
{
    /* Installs 'timer_handler' to IRQ0 */
    irq_install_handler(0, timer_handler);
}

Code: Select all

//Pit.h
#ifndef PIT_H
#define PIT_H

#include "datatypes.h"  

void timer_handler(struct regs *r);
void timer_wait(int ticks);
void timer_install();
        
#endif

Can anyone help me? :) (forgive me for my bad English )

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Sun Jul 19, 2009 3:22 pm
by Combuster
Ever heard of calling conventions? How does processor call your code on interrupt?

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Tue Jul 21, 2009 12:46 pm
by Karlosoft
Do you mean something like extern "C"?

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Tue Jul 21, 2009 12:56 pm
by gzaloprgm
No, he means that you should write your Isr/Irq handlers in asm, because otherwise you don't know what your compiler does (prologue and epilogue of a function). If your compiler supports it, you should generate a "naked" function.

For more info, http://wiki.osdev.org/Interrupt_Service_Routines

Cheers,
gzaloprgm

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Tue Jul 21, 2009 5:07 pm
by neon
Karlosoft wrote:Do you mean something like extern "C"?
Calling conventions are the way that the compiler generates code for calling and returning from functions. That is, how it is called, returned from, and parameters passed to it. Examples include _cdecl, _stdcall, and _pascal. It is very different from extern "C".

ISRs are a little tricky writing in C do to it requiring using iretd. Anything the compiler pushes on the stack must be popped off before your iretd instruction, which is, of course, compiler dependent. Because of this, ISRs are usually written in assembly language rather then C.

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Wed Jul 22, 2009 3:20 am
by Karlosoft
Thank you :)... Now it works. An other question, when the sound channel of the pit makes beeps, the processor is busy or only the channel on the pit?

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Wed Jul 22, 2009 12:11 pm
by manonthemoon
Karlosoft wrote:when the sound channel of the pit makes beeps, the processor is busy or only the channel on the pit?
Only the channel on the PIT. The processor can continue to do other work once it activates the speaker.

Re: (PIC&PIT) What it doesn't work in my source?

Posted: Tue Jul 28, 2009 8:01 am
by Karlosoft
Thanks... now my os has a logon sound XD