'===========================================================================
' Subject: FIND IRQ                           Date: 06-16-98 (23:24)       
'  Author: Alec Skelly                        Code: QB, QBasic, PDS        
'  Origin: skellya@usa.net                  Packet: INTERRPT.ABC
'===========================================================================
'****************************************************************************
'** FindIRQ by Alec Skelly 03/98 (MS QuickBasic 4.5)                       **
'** Returns the IRQ in use by a serial or parallel port.                   **
'** --------------------------------------                                 **
'** DECLARE FUNCTION FindIRQ (port%, lpt%)                                 **
'** --------------------------------------                                 **
'** port% is the hex port number of a serial or parallel port.             **
'** lpt% is a flag indicating that port% is a parallel port (0 = false).   **
'** If IRQ can't be detected, 0 is returned.                               **
'** NOTES:                                                                 **
'**   1)  Parallel ports require a Norton Utilities type loopback plug or  **
'**       a bridge (paper clip) between pins 9 and 10.                     **
'**   2)  A port that shares an IRQ with another device (including another **
'**       port) will typically not respond or will respond only the first  **
'**       time the function is called.                                     **
'**   3)  Works best in DOS.  Detection often fails in WIN95/98.           **
'****************************************************************************
DEFINT A-Z
FUNCTION FindIRQ (port, lpt)
CONST PIC1 = &H20, PIC2 = &HA0
OldMask1 = INP(PIC1 + 1)                'save IRQ masks
OldMask2 = INP(PIC2 + 1)                '
OUT PIC1 + 1, 0                         'clear any pending IRQs
OUT PIC2 + 1, 0                         '
OUT PIC1, &H20                          '  EOI
OUT PIC2, &H20                          '  EOI
OUT PIC1 + 1, &HFC                      'disable all but TIMER, KB
OUT PIC2 + 1, &HFE                      'disable all but RTC
IF lpt THEN
  OUT port, &HFF                        'stuff high
  OUT port + 2, INP(port + 2) AND &HDF  'use output mode
  OUT port + 2, INP(port + 2) OR &H10   'enable IRQ
  OUT port, 0                           'generate IRQ (high to low)
  OUT port, &HFF                        '             (low to high)
ELSE
  OUT port + 1, 0                       'disable IRQ (UART)
  OUT port + 4, &HB                     'set DTR, RTS, OUT2 high
  OUT port + 2, &HC7                    'enable & clear FIFO
  OUT port + 1, 2                       'enable IRQ on TX empty (UART)
END IF
FOR i = PIC1 TO PIC2 STEP (PIC2 - PIC1)
  IF i = PIC2 THEN
    a = 8: y = 1
  ELSE
    a = 0: y = 2
  END IF
  OUT i, &HA                            'set next read = IRR
  p = INP(i)                            'read IRR
  FOR z = y TO 7                        'bypasses TIMER, KB, RTC
    IF 2 ^ z AND p THEN IRQFound = a + z
  NEXT
  IF IRQFound THEN EXIT FOR
NEXT
FindIRQ = IRQFound
IF lpt THEN
  OUT port + 2, INP(port + 2) AND &HEF  'disable port IRQs
ELSE                                    '
  OUT port + 1, 0                       '
END IF
OUT PIC1 + 1, 0                         'clear any pending IRQs
OUT PIC2 + 1, 0                         '
OUT PIC1, &H20                          '  EOI
OUT PIC2, &H20                          '  EOI
OUT PIC1 + 1, OldMask1                  'restore IRQ masks
OUT PIC2 + 1, OldMask2                  '
END FUNCTION
