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.
Remapping the PIC
Re: Remapping the PIC
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
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
Re: Remapping the PIC
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.
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.
Re: Remapping the PIC
Well, if you try to transmit the data too fast, you may get strange errors ...
Re: Remapping the PIC
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 --
Re: Remapping the PIC
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.
#define PIC1 0x20
#define PIC2 0xA0
remap_pics(PIC1, PIC2);
And, how can I tell if my code really remaps the PIC?
K.J.
Re: Remapping the PIC
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.
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.