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.

198 lines
4.0 KiB

  1. //
  2. // MODULE : IRQ.C
  3. // PURPOSE : PIC programming
  4. // AUTHOR : JBS Yadawa
  5. // CREATED : 7/20/96
  6. //
  7. //
  8. // Copyright (C) 1996 SGS-THOMSON Microelectronics
  9. //
  10. //
  11. // REVISION HISTORY :
  12. //
  13. // DATE :
  14. //
  15. // COMMENTS :
  16. //
  17. #include "stdefs.h"
  18. #include <conio.h>
  19. #include "irq.h"
  20. #include "debug.h"
  21. #define MASK1 0x21 // PIC 1 mask register
  22. #define MASK2 0xA1 // PIC 2 mask register
  23. #define EOI1 0x20 // PIC 1 eoi register
  24. #define EOI2 0xA0 // PIC 2 eoi register
  25. #define EOI 0x20 // Value to write in EOI1 or EOI2
  26. //---- Interrupt number constants
  27. #define IRQ0INT 0x08 // IRQ 0 is mapped on INT 0x08
  28. #define IRQ8INT 0x70 // IRQ 8 is mapped on INT 0x70
  29. #define SWITCH 8 // 1st PIC manages IRQ0-7, 2nd PIC manages IRQ8-15
  30. //---- Processor Flag mask constant
  31. #define IFFLAG 0x0200 // i80x86 Interrupt Flag mask
  32. static BOOL ITAlreadyDisabled = FALSE; // Holds current �P state of IT masking
  33. static WORD Count = 0;
  34. static BYTE NEARAPI HostGetITMask(BYTE IRQ);
  35. static void NEARAPI HostSetITMask(BYTE IRQ, BYTE Mask);
  36. void FARAPI HostDisableIT(void)
  37. {
  38. _asm {
  39. push ax // saves ax
  40. pushf // push the flag register on the stack
  41. pop ax // pop it in ax
  42. test ax, IFFLAG // Test the Interrupt Flag (IF) bit
  43. pop ax // restore ax
  44. jz Disabled // if not set goto Disabled
  45. cli // disable interrupts
  46. }
  47. ITAlreadyDisabled = FALSE; // Interrupts were not already disable
  48. return ;
  49. Disabled :
  50. ITAlreadyDisabled = TRUE; // Interrupts were already disable
  51. }
  52. void FARAPI HostEnableIT(void)
  53. {
  54. if (!ITAlreadyDisabled)
  55. _enable(); // enable interrupts (i80x86 sti instruction)
  56. }
  57. static void NEARAPI HostSetVect(BYTE SWInt, INTRFNPTR ISR)
  58. {
  59. WORD FnSeg;
  60. WORD FnOff;
  61. FnSeg = FP_SEG(ISR);
  62. FnOff = FP_OFF(ISR);
  63. _asm {
  64. push ds
  65. mov dx, FnOff
  66. mov ds, FnSeg
  67. mov al, SWInt
  68. mov ah, 0x25
  69. int 0x21
  70. pop ds
  71. }
  72. }
  73. static INTRFNPTR NEARAPI HostGetVect(BYTE SWInt)
  74. {
  75. WORD FnSeg;
  76. WORD FnOff;
  77. _asm {
  78. push es
  79. mov al, SWInt
  80. mov ah, 0x35
  81. int 0x21
  82. mov FnSeg, es
  83. mov FnOff, bx
  84. pop es
  85. }
  86. return (INTRFNPTR)(MK_FP(FnSeg, FnOff));
  87. }
  88. INTRFNPTR FARAPI HostSaveAndSetITVector(BYTE IRQ, INTRFNPTR ISR)
  89. {
  90. BYTE SWInt;
  91. INTRFNPTR OldISR;
  92. //---- If IRQ is managed by PIC2, Converts the IRQ to a SWInt (vector) nbr
  93. if (IRQ >= SWITCH)
  94. SWInt = IRQ8INT + (IRQ - SWITCH);
  95. else
  96. SWInt = IRQ0INT + IRQ;
  97. //---- Keep the old handler / set the new one
  98. HostDisableIT();
  99. OldISR = HostGetVect(SWInt);
  100. HostSetVect(SWInt, ISR);
  101. HostEnableIT();
  102. return OldISR;
  103. }
  104. void FARAPI HostRestoreITVector(BYTE IRQ, INTRFNPTR OldISR)
  105. {
  106. BYTE INT;
  107. //---- If IRQ is managed by PIC2, Converts the IRQ to an INT (vector) nbr
  108. if (IRQ >= SWITCH)
  109. INT = IRQ8INT - SWITCH + IRQ;
  110. else
  111. INT = IRQ0INT + IRQ;
  112. //---- Set the old vector
  113. HostDisableIT();
  114. HostSetVect(INT, OldISR);
  115. HostEnableIT();
  116. }
  117. void FARAPI HostAcknowledgeIT(BYTE IRQ)
  118. {
  119. //---- If the IRQ is managed by PIC2
  120. if (IRQ >= SWITCH)
  121. _outp(EOI2, EOI);
  122. //---- For PIC1 and PIC2
  123. _outp(EOI1, EOI);
  124. }
  125. static BYTE NEARAPI HostGetITMask(BYTE IRQ)
  126. {
  127. BYTE Mask;
  128. HostDisableIT();
  129. if (IRQ >= SWITCH)
  130. Mask = _inp(MASK2); // PIC2
  131. else
  132. Mask = _inp(MASK1); // PIC1
  133. HostEnableIT();
  134. return Mask;
  135. }
  136. static void NEARAPI HostSetITMask(BYTE IRQ, BYTE Mask)
  137. {
  138. HostDisableIT();
  139. if (IRQ >= SWITCH)
  140. _outp(MASK2, Mask); // PIC2
  141. else
  142. _outp(MASK1, Mask); // PIC1
  143. HostEnableIT();
  144. }
  145. void FARAPI HostMaskIT(BYTE IRQ)
  146. {
  147. //---- If the IRQ is managed by PIC2
  148. HostDisableIT();
  149. if (IRQ >= SWITCH)
  150. _outp(MASK2, (BYTE)(_inp(MASK2) | (1 << (IRQ - SWITCH)))) ; // PIC2
  151. else
  152. _outp(MASK1, (BYTE)(_inp(MASK1) | (1 << IRQ))) ; // PIC1
  153. HostEnableIT();
  154. }
  155. void FARAPI HostUnmaskIT(BYTE IRQ)
  156. {
  157. //---- If the IRQ is managed by PIC2
  158. HostDisableIT();
  159. if (IRQ >= SWITCH)
  160. _outp(MASK2, (BYTE)(_inp(MASK2) & ~(1 << (IRQ - SWITCH)))) ; // PIC2
  161. else
  162. _outp(MASK1, (BYTE)(_inp(MASK1) & ~(1 << IRQ))) ; // PIC1
  163. HostEnableIT();
  164. }
  165.