VOGONS


First post, by superfury

User metadata
Rank l33t++
Rank
l33t++

UniPCemu has it assigned to IRQ5(shared on XT, not shared on AT and up), but somehow the Windows 95 hardware detection and boot-time auto mode thinks it's nonexistent(no IRQ logged to detlog.txt, while the hardware properties IRQ entry in auto mode has it weirdly set to IRQ3???).

Weirdly enough, the detlog.txt says about the UARTs for COM1 and COM2 IIR=1 and "assuming 3" or "assuming 4"? Anyone knows what that means? The UART should be raising/lowering the IR3/4 of the master PIC properly?
UART code: https://bitbucket.org/superfury/unipcemu/src/ … hardware/uart.c
See the lowerirq/raiseirq calls and their calling functions for their functionality.
Is there an issue with the IIR register?

As for the Sound Blaster:
https://bitbucket.org/superfury/unipcemu/src/ … /soundblaster.c
Also the lowerirq(by reading the status register at 22Eh, the case 0xE) and raiseirq(which also sets a flag in the soundblaster telling the 0xE read to lower the IRQ).

If required, the special PIC emulation(supporting parallel IR lines, mainly for the XT):
https://bitbucket.org/superfury/unipcemu/src/ … /hardware/pic.c

The parameter to raiseirq/lowerirq is a 2-nibble packed value. The low nibble is the IR line(0-15). The high nibble is the shared line number for that IR-line(e.g. Sound Blaster uses shared line 0x3, as far as I remember LPT3 uses shared line 0x2(currently unused by said hardware) and the ATA controller on the XT uses shared line 0x1 as far as I remember). So for the Sound Blaster that's 0x35 combined(three other devices use 0x25, 0x15 and 0x05).
It uses a special protocol(a simple handler messaging protocol: a acnowledgeirq and finishirq to tell the connected shared lines(if registered) that it's starting said shared IR line and sending it to the CPU as an interrupt) between the PIC and connected peripheral on said line. Perhaps you can compare it to my own version of some kind of special PCI-like bus signal being emulated. 🤣

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 1 of 6, by superfury

User metadata
Rank l33t++
Rank
l33t++

Just improved the shared IR line emulation a bit. Now, when starting an instruction, it updates the IRR register from the parallel IR lines. That way, even hardware that just checks the IRR register to check on the parallel IR lines will see the IR line being raised. Of course, when the interrupt is fired, this is remembered for the ISR register and on EOI the hardware can be notified of said fact(because the PIC controller remembers which line it had acnowledged).

In the case of multiple devices on the same IR line raising their lines, a simple lower priority is used. So if parallel lines 0 and 2 are raised, when an instruction starts first 0 is processed and raising the IRR bit(with interrupt handling clearing it and moving it to the ISR register and ISR2 status(to keep a record of the ISR's used parallel IR line for the finish handler).

When the interrupt is moved from the IRR register(clearing said bit) to the ISR register(setting said bit) (and the same shared IR line didn't raise another on parallel line #0), the very next instruction that's executing checks the shared line again. Said check(just like before) sees that the IRR bit is cleared and a shared request is set(in IRR3). So what it does it(like with parallel line #0), it then moves the parallel line #2(in this example) to the IRR, setting said bit and a flag that the IRR bit is for the parallel line #2. Then after the EOI is executed, said interrupt is fired, but for the parallel line #2 instead. Of course when more lines are raised (at the same time), said handling occurs as well. It's basically the plain IRR->ISR->EOI principle(with lower priority levels having higher priority) extended onto the IR lines themselves to archieve the parallel IR lines.

Software seeing the IRR register, ISR register etc. will just handle everything like it always does with non-shared IR lines. The hardware on the other hand will require some extra communication to know it's actually the one being handled by the IRR line at any said moment. For that reason, the moving from the IRR3(the raised edge sense) to IRR calls a hardware-registered handler to notify that it's moved to the IRR(so the hardware can report it's the one that raised the IRQ accordingly). Such a handler also exists for the ISR when the EOI is received for such an IRQ(so that it can be handled accordingly if it wishes).

As long as software handles the IRQs like other shared IRQs(like with COM1/3 and COM2/4), querying the hardware which might be responsible for whether or not it was the cause, the sharing should work without problems. And of course software that only use one of said devices at a time would have no problem at all(since it wouldn't activate hardware that uses the other parallel IR line). 😁

Edit: When you think about it, it's basically a kind of slave PIC that doesn't report it's IRQ(it let's the 'master' do that).

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 2 of 6, by superfury

User metadata
Rank l33t++
Rank
l33t++

What it now does is the following:
- Direct line output of shared lines are kept in irr2's line field.
- Raising irr2's field to high sets irr3's field. Clearing irr2's field clears irr3, irr3_a and (if none is left for said irq only) the irr register's irq as well.
- Before each cpu instruction, when irr's irq is cleared, the first active irr3's field is cleared and moved into irr(making it active), setting irr3_a(the flag for acnowledge of said line, which also notifies the hardware it's acnowledged by a registered acnowledge handler).

Then, during each cpu's irq check and delivery:
- It checks irr, irr3_a(for all shared lines), imr(not) and isr(not) anded together. If non-zero, said line will be handled(first come first serve, lower lines again having higher priority). The master-slave connection of the two PICs also can block from this point onwards(blocking against all below).
- When handling an irr, irr3_a for the shared line, irr and irr3 for the shared line are cleared. Then isr and isr2(for the shared line) is set, to indicate an active interrupt for the shared line(this is the acnowledge phase).
- The acnowledge phase is also done for irq 2 on the master pic if it's the slave pic.
- It starts said interrupt, giving the CPU the interrupt vector number for the irq.
- The interrupt runs normally.
- When a PIC receives an EOI, it sends a finish handler to the shared IR lines that have isr2 set, then clears isr2 and isr's bit together.

Both registered acnowledge and finish handlers are optional. Acnowledge is required for peripherals that share IR lines with other peripherals(see UniPCemu's interrupt line list on the wiki).
The hardware(e.g. Sound Blaster) with an acnowledge handler can use this to identify if it's started or finished an irq that's shared. The sound blaster in UniPCemu for example uses a flag to identify that it's raised the shared IR line(becomes 2), received an acnowledge(changes when set to 2 to become 3), lowers the IR line(clears the flag) and when reading port xEh(the status) it checks said line against being 3(the IR line's raised and acnowledged into the IRR register) to perform the DMA transaction resume and IR line lowering, doing nothing besides giving the output buffer status when it's not(no irq pending because of the raising of the IR line or not yet acnowledged into IRR because of another peripheral having priority to handle).

PIC emulation: https://bitbucket.org/superfury/unipcemu/src/ … /hardware/pic.c
Sound Blaster emulation: https://bitbucket.org/superfury/unipcemu/src/ … /soundblaster.c

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 3 of 6, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmmm.... The Sound Blaster emulation did add an 0xAA byte to the output buffer for the CPU read when issuing a IRQ request. Looking at the current Dosbox sources, this isn't supposed to happen? Guess I'll remove that little part and just make it raise the IRQ after 10us.

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 4 of 6, by superfury

User metadata
Rank l33t++
Rank
l33t++

Hmmmm.... Windows 95 hardware detection wizard still doesn't seem to detect the Sound Blaster IRQ? I see it executing command 0xF2 multiple times, but no IRQ seems to have been found?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 5 of 6, by superfury

User metadata
Rank l33t++
Rank
l33t++

Those are maybe 3 or 4 IRQ requests it makes during hardware detection.... Hmmmm.... Perhaps it's trying to enable all 4 interrupt vectors one by one, trying to detect which one is the Sound Blaster one?
But since the Interrupt flag isn't ever enabled at said point, perhaps it's never triggered by the PIT due to missing ACK from the CPU, thus failing detection?

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io

Reply 6 of 6, by superfury

User metadata
Rank l33t++
Rank
l33t++

This is what I see happening currently when Windows 95 is issuing IRQ requests to the Sound Blaster:
FA
E1
E1
E1
E7
E0
F2
F2
F2
F2
F2
F2
F2
PIC command: 0x0A->master PIC
0x0A->slave PIC
Read Slave IRR: 0x00
Read Master IRR: 0x21
Lower IRQ on the SB by reading the Status Register=0x2A
Write Master command: 0x0A
Write Slave command: 0x0A
Read Slave: 0x00
Read Master: 0x01
Read 22C: 0xFF
Delay some
Read 22C: 0xFF
Read 22C: 0xFF
Write Master Command: 0x0A
Write Slave Command: 0x0A
Read Slave: 0x00
Read Slave: 0x00
Read Master: 0x01
Read Master: 0x01
Read SB Status: 0x2A
"
Write Slave Command: 0x0B
Write Master Command: 0x0B
Write Slave IMR: 0x0D
Write Master IMR: 0xB8
Write Master IMR: 0xB9
EOI
Write Master IMR: 0xB8
Reset SB
Write Master IMR: 0xB9
EOI IRQ0
B8->Master IMR
B9->Master IMR
B8->Master IMR
(repeats for a while, then ends)

Author of the UniPCemu emulator.
UniPCemu Git repository
UniPCemu for Android, Windows, PSP, Vita and Switch on itch.io