199 lines
4 KiB
C
199 lines
4 KiB
C
//
|
||
// 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();
|
||
}
|
||
|
||
|