54#define PORT0_ICW1 0x10
55#define PORT0_OCW3 0x08
59#define STATE_READY 0x00
60#define STATE_WAITING_ICW2 0X01
61#define STATE_WAITING_ICW3 0X02
62#define STATE_WAITING_ICW4 0X04
67 m_state = STATE_READY;
74 m_pendingInterrupt =
false;
79void PIC8259::write(
int addr, uint8_t value)
84 if (value & PORT0_ICW1) {
88 m_state = STATE_WAITING_ICW2;
89 m_state |= value & ICW1_IC4 ? STATE_WAITING_ICW4 : 0;
90 m_state |= value & ICW1_SNGL ? 0 : STATE_WAITING_ICW3;
91 }
else if (value & PORT0_OCW3) {
96 m_readISR = value & OCW3_RIS;
101 if (value & OCW2_EOI) {
109 if (m_state & STATE_WAITING_ICW2) {
112 m_baseVector = value & 0xf8;
113 m_state &= ~STATE_WAITING_ICW2;
114 }
else if (m_state & STATE_WAITING_ICW3) {
118 m_state &= ~STATE_WAITING_ICW3;
119 }
else if (m_state & STATE_WAITING_ICW4) {
123 m_autoEOI = value & ICW4_AEOI;
124 m_state &= ~STATE_WAITING_ICW4;
135uint8_t PIC8259::read(
int addr)
141 return m_readISR ? m_ISR : m_IRR;
156int PIC8259::getHighestPriorityBitNum(uint8_t value)
159 for (
int i = 0; i < 8; ++i)
160 if ((value >> i) & 1)
168void PIC8259::setPendingInterrupt()
170 int highestInt = getHighestPriorityBitNum(m_IRR & ~m_IMR);
171 int servicingInt = getHighestPriorityBitNum(m_ISR);
173 if (highestInt < servicingInt) {
175 m_pendingInterrupt =
true;
176 m_pendingIR = highestInt;
182bool PIC8259::signalInterrupt(
int intnum)
185 bool success =
false;
188 if ((m_ISR & (1 << intnum)) == 0) {
190 m_IRR |= 1 << intnum;
191 setPendingInterrupt();
199void PIC8259::ackPendingInterrupt()
202 int pendmsk = 1 << m_pendingIR;
205 m_pendingInterrupt =
false;
211void PIC8259::performEOI()
215 int servicingInt = getHighestPriorityBitNum(m_ISR);
216 m_ISR &= ~(1 << servicingInt);
218 setPendingInterrupt();