6 * 1) Second PIC is not implemented.
7 * 2) Interrupt priority management is not implemented.
8 * 3) What should be read from port 0x20?
10 * "within interrupt processing" means the following is true:
11 * 1) Hardware interrupt <irql> is delivered by hardint().
12 * 2) Next interrupt <irql> is not possible yet by either:
18 * int isinhardint(int irql)
19 * void set_eoir(int irql, void (*eoir)(void *), void *arg);
21 * $FreeBSD: src/usr.bin/doscmd/int.c,v 1.3.2.2 2002/04/25 11:04:51 tg Exp $
22 * $DragonFly: src/usr.bin/doscmd/int.c,v 1.2 2003/06/17 04:29:26 dillon Exp $
31 void (*eoir)(void *arg);
35 static unsigned char IM;
37 static struct IRQ Irqs[8];
39 #define int_allowed(n) ((IM & 1 << (n)) == 0 && Irql > (n))
42 set_eoir(int irql, void (*eoir)(void *), void *arg)
44 Irqs [irql].eoir = eoir;
45 Irqs [irql].arg = arg;
51 return Irqs[irql].within;
57 regcontext_t *REGS = saved_regcontext;
60 if (R_EFLAGS & PSL_VIF) {
65 for (irql = 0; irql < 8; irql++)
66 if (int_allowed(irql) && (Irqs[irql].within || Irqs[irql].pending)) {
75 resume_interrupt(void)
77 regcontext_t *REGS = saved_regcontext;
80 if (R_EFLAGS & PSL_VIF) {
81 for (irql = 0; irql < 8; irql++)
82 if (Irqs[irql].within && int_allowed(irql)) {
83 Irqs[irql].within = 0;
85 Irqs[irql].eoir(Irqs[irql].arg);
88 for (irql = 0; irql < 8; irql++)
89 if (Irqs[irql].pending && int_allowed(irql)) {
90 Irqs[irql].pending = 0;
107 if (Irqs [Irql].busy)
114 ** Cause a hardware interrupt to happen immediately after
115 ** we return to vm86 mode
120 regcontext_t *REGS = saved_regcontext;
121 u_long vec = ivec[8 + irql];
124 ** if we're dead, or there's no vector, or the saved registers
127 if (dead || !saved_valid || vec == 0)
131 ** if the vector points into the BIOS, or the handler at the
132 ** other end is just an IRET, don't bother
134 if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
137 if (!int_allowed(irql)) {
138 Irqs[irql].pending = 1;
142 if ((R_EFLAGS & PSL_VIF) == 0) {
143 Irqs[irql].pending = 1;
148 debug(D_TRAPS | (8 + irql), "Int%02x [%04lx:%04lx]\n",
149 8 + irql, vec >> 16, vec & 0xffff);
154 Irqs[Irql].within = 1;
156 PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
159 R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts */
160 PUTVEC(R_CS, R_IP, vec);
166 if (!Irqs[irql].pending)
168 Irqs[irql].pending = 0;
173 irqc_in(int port __unused)
175 return 0x60; /* What should be here? */
179 irqc_out(int port __unused, unsigned char val)
186 imr_in(int port __unused)
192 imr_out(int port __unused, unsigned char val)
199 ** Cause a software interrupt to happen immediately after we
200 ** return to vm86 mode
205 regcontext_t *REGS = saved_regcontext;
206 u_long vec = ivec[intnum];
209 ** if we're dead, or there's no vector or the saved registers are
212 if (dead || !saved_valid || vec == 0)
216 ** if the vector points into the BIOS, or the handler at the other
217 ** end is just an IRET, don't bother.
219 if ((vec >> 16) == 0xf000 || *(u_char *)VECPTR(vec) == 0xcf)
222 debug(D_TRAPS | intnum, "INT %02x [%04lx:%04lx]\n",
223 intnum, vec >> 16, vec & 0xffff);
225 PUSH((R_FLAGS & ~PSL_I) | (R_EFLAGS & PSL_VIF ? PSL_I : 0), REGS);
228 R_EFLAGS &= ~PSL_VIF; /* XXX disable interrupts? */
229 PUTVEC(R_CS, R_IP, vec);
237 for (i = 0; i < 8; i++) {
246 define_input_port_handler(0x20, irqc_in);
247 define_output_port_handler(0x20, irqc_out);
248 define_input_port_handler(0x21, imr_in);
249 define_output_port_handler(0x21, imr_out);