Scali
Veteran Member
I have recently been toying around with the auto-EOI mode of the 8259A, to try and save a few bytes/cycles for time-critical timer interrupt stuff.
I got it working on my IBM 5160.
But then I got a 286 machine, and well... the plot thickened.
Namely, I wanted to reset the PIC back to its original state when my program exited. So I took the code from the IBM PC BIOS and put that in my application.
Since an AT-class machine has two PICs, it would need to be restored to the cascaded setup instead (one of those rare occasions where you have to know exactly what hardware you're running on, because you cannot assume backward compatibility).
So I added some code to detect the second PIC, and use the code from the AT BIOS in that case.
So far so good, the detection worked, and I got it working on both my 5160 and my 486 clone.
But when I tried to run it on my 286, it didn't work. I found that if I keep sending manual EOIs, the system appears to work correctly, but for some reason it didn't switch into auto-EOI mode.
So instead of just setting the first PIC up in a PC/XT configuration and ignoring the second PIC, I instead took the full AT BIOS setup, and just changed the auto-EOI bit there. Then it magically started working on my 286.
After some troubleshooting I found out that running a single PIC was not the issue. The problem was that the PC/XT sets ICW4 to a value of 9, where the AT sets it to a value of 1. The difference here is in the 'buffered mode'.
For some reason, auto-EOI doesn't work on my 286 if I set buffered mode.
So, perhaps someone here can shed some light on this, eg:
- Why does the AT initialize the 8259As with a different setting for ICW4? Is this because of changes in the circuit when adding the second PIC?
- What exactly is the effect of enabling/disabling buffered mode?
- How can auto-EOI be affected by the buffered mode setting? It doesn't seem to make sense to me. Auto-EOI is something that the 8259A should do internally, right? So how could it be affected by the buffered mode setting, which controls a signal to the outside world?
My 286 is a late model, which has an integrated chipset, so there are no physical 8259As present (and they probably integrated the whole two-PIC circuit in a single chip). It is possible that the implementation of the 8259A circuit is slightly bugged here, and the behavior is different from a real IBM AT (in which case my 486 appears to have a more accurate integrated chipset design, as far as the 8259A goes).
Does anyone have a real IBM AT to test this?
I have some simple test-code in a Turbo C++ project here anyway, contains both source and binary: https://www.dropbox.com/s/4d31o2aeti3hx0x/AUTOEOI_286.zip?dl=0
I got it working on my IBM 5160.
But then I got a 286 machine, and well... the plot thickened.
Namely, I wanted to reset the PIC back to its original state when my program exited. So I took the code from the IBM PC BIOS and put that in my application.
Since an AT-class machine has two PICs, it would need to be restored to the cascaded setup instead (one of those rare occasions where you have to know exactly what hardware you're running on, because you cannot assume backward compatibility).
So I added some code to detect the second PIC, and use the code from the AT BIOS in that case.
So far so good, the detection worked, and I got it working on both my 5160 and my 486 clone.
But when I tried to run it on my 286, it didn't work. I found that if I keep sending manual EOIs, the system appears to work correctly, but for some reason it didn't switch into auto-EOI mode.
So instead of just setting the first PIC up in a PC/XT configuration and ignoring the second PIC, I instead took the full AT BIOS setup, and just changed the auto-EOI bit there. Then it magically started working on my 286.
After some troubleshooting I found out that running a single PIC was not the issue. The problem was that the PC/XT sets ICW4 to a value of 9, where the AT sets it to a value of 1. The difference here is in the 'buffered mode'.
For some reason, auto-EOI doesn't work on my 286 if I set buffered mode.
So, perhaps someone here can shed some light on this, eg:
- Why does the AT initialize the 8259As with a different setting for ICW4? Is this because of changes in the circuit when adding the second PIC?
- What exactly is the effect of enabling/disabling buffered mode?
- How can auto-EOI be affected by the buffered mode setting? It doesn't seem to make sense to me. Auto-EOI is something that the 8259A should do internally, right? So how could it be affected by the buffered mode setting, which controls a signal to the outside world?
My 286 is a late model, which has an integrated chipset, so there are no physical 8259As present (and they probably integrated the whole two-PIC circuit in a single chip). It is possible that the implementation of the 8259A circuit is slightly bugged here, and the behavior is different from a real IBM AT (in which case my 486 appears to have a more accurate integrated chipset design, as far as the 8259A goes).
Does anyone have a real IBM AT to test this?
I have some simple test-code in a Turbo C++ project here anyway, contains both source and binary: https://www.dropbox.com/s/4d31o2aeti3hx0x/AUTOEOI_286.zip?dl=0