File: mirq.c

package info (click to toggle)
bb 1.2-9
  • links: PTS
  • area: main
  • in suites: potato
  • size: 4,152 kB
  • ctags: 3,357
  • sloc: ansic: 43,440; sh: 152; makefile: 64; asm: 36
file content (105 lines) | stat: -rw-r--r-- 2,378 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

/*

   Name:
   MDMA.C

   Description:
   Some general purpose IRQ routines

   Portability:

   MSDOS:       BC(y)   Watcom(y)       DJGPP(y)
   Win95:       n
   Os2: n
   Linux:       n

   (y) - yes
   (n) - no (not possible or not useful)
   (?) - may be possible, but not tested

 */
#include <dos.h>
#include <conio.h>
#include "mirq.h"

#define OCR1	0x20		/* 8259-1 Operation control register */
#define IMR1	0x21		/* 8259-1 Mask register */

#define OCR2	0xA0		/* 8259-2 Operation control register */
#define IMR2	0xA1		/* 8259-2 Mask register */


BOOL MIrq_IsEnabled(UBYTE irqno)
/*
   Returns true if the specified hardware irq is enabled.
 */
{
    UBYTE imr = (irqno > 7) ? IMR2 : IMR1;	/* interrupt mask register */
    UBYTE msk = 1 << (irqno & 7);	/* interrupt mask */
    return ((inportb(imr) & msk) == 0);
}


BOOL MIrq_OnOff(UBYTE irqno, UBYTE onoff)
/*
   Use to enable or disable the specified irq.
 */
{
    UBYTE imr = (irqno > 7) ? IMR2 : IMR1;	/* interrupt mask register */
    UBYTE ocr = (irqno > 7) ? OCR2 : OCR1;	/* ocr */
    UBYTE msk = 1 << (irqno & 7);	/* interrupt mask */
    UBYTE eoi = 0x60 | (irqno & 7);	/* specific end-of-interrupt */
    BOOL oldstate;

    /* save current setting of this irq */
    oldstate = ((inportb(imr) & msk) == 0);

    if (onoff) {
	outportb(imr, inportb(imr) & ~msk);
	outportb(ocr, eoi);
	if (irqno > 7)
	    MIrq_OnOff(2, 1);
    }
    else {
	outportb(imr, inportb(imr) | msk);
    }

    return oldstate;
}


void MIrq_EOI(UBYTE irqno)
/*
   Clears the specified interrupt request at the interrupt controller.
 */
{
    UBYTE ocr = (irqno > 7) ? OCR2 : OCR1;	/* ocr */
    UBYTE eoi = 0x60 | (irqno & 7);	/* specific end-of-interrupt */

    outportb(ocr, eoi);
    if (irqno > 7)
	outportb(OCR1, 0x20);
}


PVI MIrq_SetHandler(UBYTE irqno, PVI handler)
{
#ifdef __DJGPP__
    _go32_dpmi_seginfo seginfo;
#endif
    PVI oldvect;
    int vecno = (irqno > 7) ? irqno + 0x68 : irqno + 0x8;
#ifdef __DJGPP__
    _go32_dpmi_get_protected_mode_interrupt_vector(vecno, &seginfo);
    oldvect = seginfo.pm_offset;
    seginfo.pm_offset = handler;
    seginfo.pm_selector = _go32_my_cs();
    _go32_dpmi_allocate_iret_wrapper(&seginfo);
    _go32_dpmi_set_protected_mode_interrupt_vector(vecno, &seginfo);
#else
    oldvect = _dos_getvect(vecno);
    _dos_setvect(vecno, handler);
#endif
    return oldvect;
}