diff -Nur qemu-cvs/hw/i8259.c qemu-local/hw/i8259.c --- qemu-cvs/hw/i8259.c 2005-06-15 20:09:28.000000000 +0200 +++ qemu-local/hw/i8259.c 2005-06-17 19:12:53.000000000 +0200 @@ -79,20 +79,21 @@ s->irr |= mask; s->last_irr |= mask; } else { + s->irr &= ~mask; s->last_irr &= ~mask; } } } /* return the highest priority found in mask (highest = smallest - number). Return 8 if no irq */ + number). Return 16 if no irq */ static inline int get_priority(PicState *s, int mask) { int priority; if (mask == 0) - return 8; - priority = 0; - while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0) + return 16; + priority = s->priority_add; + while ((mask & (1 << (priority & 7))) == 0) priority++; return priority; } @@ -104,7 +105,7 @@ mask = s->irr & ~s->imr; priority = get_priority(s, mask); - if (priority == 8) + if (priority == 16) return -1; /* compute current priority. If special fully nested mode on the master, the IRQ coming from the slave is not taken into account @@ -115,7 +116,7 @@ cur_priority = get_priority(s, mask); if (priority < cur_priority) { /* higher priority found: an irq should be generated */ - return (priority + s->priority_add) & 7; + return priority & 7; } else { return -1; } @@ -132,8 +133,10 @@ if (irq2 >= 0) { /* if irq request by slave pic, signal master PIC */ pic_set_irq1(&pics[0], 2, 1); + } else { pic_set_irq1(&pics[0], 2, 0); } + /* look at requested irq */ irq = pic_get_irq(&pics[0]); if (irq >= 0) { @@ -149,6 +152,8 @@ printf("pic: cpu_interrupt\n"); #endif cpu_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); + } else { + cpu_reset_interrupt(cpu_single_env, CPU_INTERRUPT_HARD); } } @@ -297,8 +304,8 @@ case 1: /* end of interrupt */ case 5: priority = get_priority(s, s->isr); - if (priority != 8) { - irq = (priority + s->priority_add) & 7; + if (priority != 16) { + irq = priority & 7; s->isr &= ~(1 << irq); if (cmd == 5) s->priority_add = (irq + 1) & 7;