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 <20>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();
|
|||
|
}
|
|||
|
|
|||
|
|