atpic
struct atpic atpic[2];
#define ATPIC_PIN_FOREACH(pinvar, atpic, tmpvar) \
for (tmpvar = 0, pinvar = (atpic->lowprio + 1) & 0x7; \
master_atpic(struct vatpic *vatpic, struct atpic *atpic)
if (atpic == &vatpic->atpic[0])
vatpic_get_highest_isrpin(struct atpic *atpic)
ATPIC_PIN_FOREACH(pin, atpic, i) {
if (atpic->reg_isr & bit) {
if (atpic->special_mask_mode &&
(atpic->reg_imr & bit) != 0) {
vatpic_get_highest_irrpin(struct atpic *atpic)
serviced = atpic->reg_isr;
if (atpic->special_full_nested)
if (atpic->special_mask_mode)
ATPIC_PIN_FOREACH(pin, atpic, tmp) {
if ((atpic->reg_irr & bit) != 0 && (atpic->reg_imr & bit) == 0)
struct atpic *atpic;
atpic = &vatpic->atpic[1];
if (!atpic->intr_raised &&
(pin = vatpic_get_highest_irrpin(atpic)) != -1) {
atpic->intr_raised = true;
atpic = &vatpic->atpic[0];
if (!atpic->intr_raised &&
(pin = vatpic_get_highest_irrpin(atpic)) != -1) {
atpic->intr_raised = true;
vatpic_icw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->ready = false;
atpic->icw_state = IS_ICW1;
atpic->reg_irr = 0;
atpic->reg_imr = 0;
atpic->lowprio = 7;
atpic->read_isr_next = false;
atpic->poll = false;
atpic->special_mask_mode = false;
atpic->icw_state = IS_ICW2;
vatpic_icw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->irq_base = val & IRQ_BASE_MASK;
atpic->icw_state = IS_ICW3;
vatpic_icw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->icw_state = IS_ICW4;
vatpic_icw4(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->auto_eoi = (val & ICW4_AEOI) != 0;
if (master_atpic(vatpic, atpic)) {
atpic->special_full_nested = (val & ICW4_SFNM) != 0;
atpic->icw_state = IS_ICW1;
atpic->ready = true;
vatpic_ocw1(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->reg_imr = val;
vatpic_ocw2(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->rotate = (val & OCW2_R) != 0;
isr_bit = vatpic_get_highest_isrpin(atpic);
atpic->reg_isr &= ~(1 << isr_bit);
if (atpic->rotate)
atpic->lowprio = isr_bit;
} else if ((val & OCW2_SL) != 0 && atpic->rotate) {
atpic->lowprio = val & 0x7;
vatpic_ocw3(struct vatpic *vatpic, struct atpic *atpic, uint8_t val)
atpic->special_mask_mode = (val & OCW3_SMM) != 0;
atpic->read_isr_next = (val & OCW3_RIS) != 0;
atpic->poll = true;
struct atpic *atpic;
atpic = &vatpic->atpic[pin >> 3];
oldcnt = newcnt = atpic->acnt[lpin];
atpic->acnt[lpin] = newcnt;
const bool level = ((atpic->elc & (1 << (lpin))) != 0);
atpic->reg_irr |= (1 << lpin);
atpic->reg_irr &= ~(1 << lpin);
struct atpic *atpic;
atpic = &vatpic->atpic[irq >> 3];
if (!atpic->ready)
struct atpic *atpic = &vatpic->atpic[irq >> 3];
atpic->elc |= (1 << pin);
atpic->elc &= ~(1 << pin);
struct atpic *atpic;
atpic = &vatpic->atpic[0];
pin = vatpic_get_highest_irrpin(atpic);
atpic = &vatpic->atpic[1];
pin = vatpic_get_highest_irrpin(atpic);
*vecptr = atpic->irq_base + pin;
vatpic_pin_accepted(struct atpic *atpic, int pin)
atpic->intr_raised = false;
if (atpic->acnt[pin] == 0)
atpic->reg_irr &= ~(1 << pin);
if (atpic->auto_eoi) {
if (atpic->rotate)
atpic->lowprio = pin;
atpic->reg_isr |= (1 << pin);
if ((vector & IRQ_BASE_MASK) == vatpic->atpic[1].irq_base) {
vatpic_pin_accepted(&vatpic->atpic[1], pin);
vatpic_pin_accepted(&vatpic->atpic[0], 2);
vatpic_pin_accepted(&vatpic->atpic[0], pin);
vatpic_read(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
if (atpic->poll) {
atpic->poll = false;
pin = vatpic_get_highest_irrpin(atpic);
vatpic_pin_accepted(atpic, pin);
*eax = atpic->reg_imr;
if (atpic->read_isr_next) {
*eax = atpic->reg_isr;
*eax = atpic->reg_irr;
vatpic_write(struct vatpic *vatpic, struct atpic *atpic, bool in, int port,
switch (atpic->icw_state) {
error = vatpic_icw2(vatpic, atpic, val);
error = vatpic_icw3(vatpic, atpic, val);
error = vatpic_icw4(vatpic, atpic, val);
error = vatpic_ocw1(vatpic, atpic, val);
error = vatpic_icw1(vatpic, atpic, val);
if (atpic->ready) {
error = vatpic_ocw3(vatpic, atpic, val);
error = vatpic_ocw2(vatpic, atpic, val);
if (atpic->ready)
struct atpic *atpic = &vatpic->atpic[0];
return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
struct atpic *atpic = &vatpic->atpic[1];
return (vatpic_read(vatpic, atpic, in, port, bytes, eax));
return (vatpic_write(vatpic, atpic, in, port, bytes, eax));
struct atpic *atpic = NULL;
atpic = &vatpic->atpic[0];
atpic = &vatpic->atpic[1];
*eax = atpic->elc;
atpic->elc = *eax & elc_mask;
const struct atpic *src = &vatpic->atpic[i];
struct atpic *out = &vatpic->atpic[i];