Remapping the PIC

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.
Post Reply
K.J.

Remapping the PIC

Post by K.J. »

I just snagged DF's code for remapping the PIC. It looks like this:

#define      PIC1            0x20
#define      PIC2            0xA0
#define      PIC1_COMMAND      PIC1
#define      PIC1_DATA      (PIC1+1)
#define      PIC2_COMMAND      PIC2
#define      PIC2_DATA      (PIC2+1)
#define      PIC_EOI            0x20

#define      ICW1_ICW4      0x01            /* ICW4 (not) needed */
#define      ICW1_SINGLE      0x02            /* Single (cascade) mode */
#define      ICW1_INTERVAL4      0x04            /* Call address interval 4 (8) */
#define      ICW1_LEVEL      0x08            /* Level triggered (edge) mode */
#define      ICW1_INIT      0x10            /* Initialization - required! */

#define      ICW4_8086      0x01            /* 8086/88 (MCS-80/85) mode */
#define      ICW4_AUTO      0x02            /* Auto (normal) EOI */
#define      ICW4_BUF_SLAVE      0x08            /* Buffered mode/slave */
#define      ICW4_BUF_MASTER      0x0C            /* Buffered mode/master */
#define      ICW4_SFNM      0x10            /* Special fully nested (not) */

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

     a1=inportb(PIC1_DATA);
     a2=inportb(PIC2_DATA);

     outportb(PIC1_COMMAND, ICW1_INIT+ICW1_ICW4);
     io_wait();
     outportb(PIC2_COMMAND, ICW1_INIT+ICW1_ICW4);
     io_wait();
     outportb(PIC1_DATA, pic1);
     io_wait();
     outportb(PIC2_DATA, pic2);
     io_wait();
     outportb(PIC1_DATA, 4);
     io_wait();
     outportb(PIC2_DATA, 2);
     io_wait();

     outportb(PIC1_DATA, ICW4_8086);
     io_wait();
     outportb(PIC2_DATA, ICW4_8086);
     io_wait();

     outportb(PIC1_DATA, a1);
     outportb(PIC2_DATA, a2);
};


I don't know what is supposed to go in io_wait so I just have an empty function for it.

I then call the above function like this:
remap_pics(PIC1, PIC2)

Is this correct, and what goes in io_wait?

Thanks,
K.J.
roswell

Re: Remapping the PIC

Post by roswell »

Hi,

I don't remember exactly what is supposed to be done in the process of changing the PIC base, you'd better check directly in the Flux OS Kit.

But I know what io_wait is made for.

In fact access to a port on x86 is slower than access to the memory. So before you can admit than a value as been transmitted to a device, you must add a delay.

Usualy, this delay is done by accessing a non used port ( I don't remember which one ).

As I said at the beginning you will find everything in the OsKit

Roswell
K.J.

Re: Remapping the PIC

Post by K.J. »

I have seen the OSkit, but I would like to make my OS mostly from scratch.

In fact access to a port on x86 is slower than access to the memory. So before you can admit than a value as been transmitted to a device, you must add a delay.

Why do I need to wait? I'm only sending data one right after another and not reading anything in between.

K.J.
The Legend

Re: Remapping the PIC

Post by The Legend »

Well, if you try to transmit the data too fast, you may get strange errors ...
User avatar
df
Member
Member
Posts: 1076
Joined: Fri Oct 22, 2004 11:00 pm
Contact:

Re: Remapping the PIC

Post by df »

The PIC was one of those old original xt chips, and the IO wait was to the chip could catch up. newer chips dont require this IO wait routines, so you'd probably be safe removing it.
-- Stu --
K.J.

Re: Remapping the PIC

Post by K.J. »

Okay, but is this corect?

#define PIC1  0x20
#define PIC2  0xA0

remap_pics(PIC1, PIC2);


And, how can I tell if my code really remaps the PIC?

K.J.
Tim

Re: Remapping the PIC

Post by Tim »

The parameters pic1 and pic2 should be the interrupt numbers where each PIC's block of IRQs should starts.

In the code you've got, IRQ 0 will trigger interrupt 0x20, IRQ 1 will go to interrupt 0x21, and so on until IRQ 7; IRQ 8 will give interrupt 0xA0, IRQ 9 0xA1, etc.

You probably want to set it up so that all the IRQs are in a single block somewhere low down in the interrupt numbers, but not somewhere where it clashes with the Intel reserved interrupts. I put mine at 0x20 and 0x28, so that all IRQs trigger interrupts in a nice block from int 0x20 to int 0x30.

You will only know that your PIC reconfiguration works when you have an IDT set up with handlers for those interrupts. Most devices will interrupt only when you ask them to, although the timer will give IRQ 0 regularly, and the keyboard will give you an IRQ 1 for every scan code it gives you.
K.J.

Re: Remapping the PIC

Post by K.J. »

Thanks Tim, that was just what I needed to know.

K.J.
Post Reply