Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

199 lines
4.0 KiB

//
// MODULE : IRQ.C
// PURPOSE : PIC programming
// AUTHOR : JBS Yadawa
// CREATED : 7/20/96
//
//
// Copyright (C) 1996 SGS-THOMSON Microelectronics
//
//
// REVISION HISTORY :
//
// DATE :
//
// COMMENTS :
//
#include "stdefs.h"
#include <conio.h>
#include "irq.h"
#include "debug.h"
#define MASK1 0x21 // PIC 1 mask register
#define MASK2 0xA1 // PIC 2 mask register
#define EOI1 0x20 // PIC 1 eoi register
#define EOI2 0xA0 // PIC 2 eoi register
#define EOI 0x20 // Value to write in EOI1 or EOI2
//---- Interrupt number constants
#define IRQ0INT 0x08 // IRQ 0 is mapped on INT 0x08
#define IRQ8INT 0x70 // IRQ 8 is mapped on INT 0x70
#define SWITCH 8 // 1st PIC manages IRQ0-7, 2nd PIC manages IRQ8-15
//---- Processor Flag mask constant
#define IFFLAG 0x0200 // i80x86 Interrupt Flag mask
static BOOL ITAlreadyDisabled = FALSE; // Holds current æP state of IT masking
static WORD Count = 0;
static BYTE NEARAPI HostGetITMask(BYTE IRQ);
static void NEARAPI HostSetITMask(BYTE IRQ, BYTE Mask);
void FARAPI HostDisableIT(void)
{
_asm {
push ax // saves ax
pushf // push the flag register on the stack
pop ax // pop it in ax
test ax, IFFLAG // Test the Interrupt Flag (IF) bit
pop ax // restore ax
jz Disabled // if not set goto Disabled
cli // disable interrupts
}
ITAlreadyDisabled = FALSE; // Interrupts were not already disable
return ;
Disabled :
ITAlreadyDisabled = TRUE; // Interrupts were already disable
}
void FARAPI HostEnableIT(void)
{
if (!ITAlreadyDisabled)
_enable(); // enable interrupts (i80x86 sti instruction)
}
static void NEARAPI HostSetVect(BYTE SWInt, INTRFNPTR ISR)
{
WORD FnSeg;
WORD FnOff;
FnSeg = FP_SEG(ISR);
FnOff = FP_OFF(ISR);
_asm {
push ds
mov dx, FnOff
mov ds, FnSeg
mov al, SWInt
mov ah, 0x25
int 0x21
pop ds
}
}
static INTRFNPTR NEARAPI HostGetVect(BYTE SWInt)
{
WORD FnSeg;
WORD FnOff;
_asm {
push es
mov al, SWInt
mov ah, 0x35
int 0x21
mov FnSeg, es
mov FnOff, bx
pop es
}
return (INTRFNPTR)(MK_FP(FnSeg, FnOff));
}
INTRFNPTR FARAPI HostSaveAndSetITVector(BYTE IRQ, INTRFNPTR ISR)
{
BYTE SWInt;
INTRFNPTR OldISR;
//---- If IRQ is managed by PIC2, Converts the IRQ to a SWInt (vector) nbr
if (IRQ >= SWITCH)
SWInt = IRQ8INT + (IRQ - SWITCH);
else
SWInt = IRQ0INT + IRQ;
//---- Keep the old handler / set the new one
HostDisableIT();
OldISR = HostGetVect(SWInt);
HostSetVect(SWInt, ISR);
HostEnableIT();
return OldISR;
}
void FARAPI HostRestoreITVector(BYTE IRQ, INTRFNPTR OldISR)
{
BYTE INT;
//---- If IRQ is managed by PIC2, Converts the IRQ to an INT (vector) nbr
if (IRQ >= SWITCH)
INT = IRQ8INT - SWITCH + IRQ;
else
INT = IRQ0INT + IRQ;
//---- Set the old vector
HostDisableIT();
HostSetVect(INT, OldISR);
HostEnableIT();
}
void FARAPI HostAcknowledgeIT(BYTE IRQ)
{
//---- If the IRQ is managed by PIC2
if (IRQ >= SWITCH)
_outp(EOI2, EOI);
//---- For PIC1 and PIC2
_outp(EOI1, EOI);
}
static BYTE NEARAPI HostGetITMask(BYTE IRQ)
{
BYTE Mask;
HostDisableIT();
if (IRQ >= SWITCH)
Mask = _inp(MASK2); // PIC2
else
Mask = _inp(MASK1); // PIC1
HostEnableIT();
return Mask;
}
static void NEARAPI HostSetITMask(BYTE IRQ, BYTE Mask)
{
HostDisableIT();
if (IRQ >= SWITCH)
_outp(MASK2, Mask); // PIC2
else
_outp(MASK1, Mask); // PIC1
HostEnableIT();
}
void FARAPI HostMaskIT(BYTE IRQ)
{
//---- If the IRQ is managed by PIC2
HostDisableIT();
if (IRQ >= SWITCH)
_outp(MASK2, (BYTE)(_inp(MASK2) | (1 << (IRQ - SWITCH)))) ; // PIC2
else
_outp(MASK1, (BYTE)(_inp(MASK1) | (1 << IRQ))) ; // PIC1
HostEnableIT();
}
void FARAPI HostUnmaskIT(BYTE IRQ)
{
//---- If the IRQ is managed by PIC2
HostDisableIT();
if (IRQ >= SWITCH)
_outp(MASK2, (BYTE)(_inp(MASK2) & ~(1 << (IRQ - SWITCH)))) ; // PIC2
else
_outp(MASK1, (BYTE)(_inp(MASK1) & ~(1 << IRQ))) ; // PIC1
HostEnableIT();
}