VOGONS


First post, by Battler

User metadata
Rank Member
Rank
Member

My question is, how did that work since both of these models only had one PIC, with IRQ's 0 to 7, so what IRQ was the mouse on? Was on it IRQ 1 together with the keyboard? The technical reference only talks about the keyboard, and doesn't even mention the mouse.

Reply 3 of 11, by mkarcher

User metadata
Rank l33t
Rank
l33t
Battler wrote on 2020-10-01, 02:35:

My question is, how did that work since both of these models only had one PIC, with IRQ's 0 to 7, so what IRQ was the mouse on? Was on it IRQ 1 together with the keyboard? The technical reference only talks about the keyboard, and doesn't even mention the mouse.

It seems like one should not make the mistake of assuming the PS/2 model 30 behaves like an XT, e.g. that its IRQ system is completely like the XT one. There is no 8259 on the PS/2 model 30 mainboard, but the functionality has been reimplemented by IBM in their custom mask-programmed gate arrays. I just reversed a lot of the PS/2 model 30 BIOS, and it seems like all extended PS/2 interrupt sources are routed to processor interrupt 0x71 (which is used by IRQ9 on AT-like systems). The handler for interrupt 0x71 then dispatches according to proprietary port addresses to interrupt 0x70 (for RTC alarm, emulates IRQ8), to 0x73 (for PS/2 mouse data, don't ask me why they didn't use 0x74 here...) or to the current PIC base interrupt + 1 (for keyboard data). The current PIC base interrupt can be read from port 63, bits 3 to 7.

Also, port 60 seems to be a software thing. As the PS/2 model 30 doesn't have a keyboard controller (just like any other XT-class computer), the multiplexing of mouse and keyboard data to port 60 is done in software. The BIOS code looks like port 60 is just an 8-bit "scratch register" which is set up with a byte from port 67 or 68 (the actual data ports for the two PS/2 interfaces) before invoking IRQ1 or INT 73. Int 71 does not do scancode translation (a function of the AT keyboard controller), so the Model 30 computer needs to operate the keyboard in scancode set 1 (without translation), not in scancode set 2 (with translation to scancode set 1 in the KBC, as is common on AT-class computers). This might fail on some el-cheapo PS/2 keyboards of today. It definitely works on the Model M keyboards, though.

Reply 4 of 11, by Battler

User metadata
Rank Member
Rank
Member

I just checked the PS/2 Model 25-8086 technical reference, and it looks like I missed some parts before - it actually explicitly says both the keyboard and the pointing device are on IRQ 1, and says that is handled by INT 71h, no idea how that works.

Reply 5 of 11, by rmay635703

User metadata
Rank Oldbie
Rank
Oldbie
Battler wrote on 2020-10-04, 14:37:

I just checked the PS/2 Model 25-8086 technical reference, and it looks like I missed some parts before - it actually explicitly says both the keyboard and the pointing device are on IRQ 1, and says that is handled by INT 71h, no idea how that works.

Tandy 1000RL and RLX both are XT and PS/2, on those windows can’t find the ps/2 mouse because it’s on the wrong irq

Would be neat if they had A form of 16 bit. ISA on there

Reply 6 of 11, by mkarcher

User metadata
Rank l33t
Rank
l33t
Battler wrote on 2020-10-04, 14:37:

I just checked the PS/2 Model 25-8086 technical reference, and it looks like I missed some parts before - it actually explicitly says both the keyboard and the pointing device are on IRQ 1, and says that is handled by INT 71h, no idea how that works.

It works by not using the Intel 8259A chip, but a custom interrupt controller that always invokes INT 71h if IRQ1 is signalled, no matter what the base IRQ number is. INT 71h demultiplexes keyboard, pointing device and alarm (to INT 70h, IRQ1 as programmed by the 8259A setup sequence and INT 73h). So as long as no one revectors INT 71h, keyboard data still appears on the expected IRQ1 vector, whereas mouse data does not.

Reply 7 of 11, by Cloudschatze

User metadata
Rank Oldbie
Rank
Oldbie
rmay635703 wrote on 2020-10-04, 14:59:

Tandy 1000RL and RLX both are XT and PS/2, on those windows can’t find the ps/2 mouse because it’s on the wrong irq

The PS/2 keyboard and mouse in the Tandy 1000 TL/3, RL, and RLX share the use of IRQ 1, similar to the IBM PS/2 Model 25/30 behavior described in this thread.

I came up with a one-byte fix for the Windows mouse driver issue with these systems, if you're interested:
http://www.vcfed.org/forum/showthread.php?692 … 1092#post621092

Reply 8 of 11, by Battler

User metadata
Rank Member
Rank
Member

So, if I understand correctly, on PS/2 Model 25-8086 and 30-8086, keyboard, mouse, and RTC alarm are all on IRQ 1, and IRQ 1 always issues INT 71h, whose BIOS handler then demultiplexes it to INT 70h, IRQ 1 INT (with base read from port 63h), and INT 73h. Looks like I'll need to add this special behavior when I add those two machines to my emulator some day, so thanks for the information. :p

Reply 9 of 11, by mkarcher

User metadata
Rank l33t
Rank
l33t
Battler wrote on 2020-10-05, 19:18:

So, if I understand correctly, on PS/2 Model 25-8086 and 30-8086, keyboard, mouse, and RTC alarm are all on IRQ 1, and IRQ 1 always issues INT 71h, whose BIOS handler then demultiplexes it to INT 70h, IRQ 1 INT (with base read from port 63h), and INT 73h. Looks like I'll need to add this special behavior when I add those two machines to my emulator some day, so thanks for the information. :p

That's my understanding from disassembling the PS/2 Model 30 (non-286). The complete keyboard interface is non-standard on that machine. It describes some of the PS/2 Model 30 specific stuff on the mainboard. Together with reverse engineering of BIOS code, I gathered the following information about the "standard" keyboard ports:

  • Port 60h is a simple 8-bit latch - no hardware function associated. (Reference page 24: "The output port 60h is used by BIOS to store keystrokes")
  • Port 61h behaves as usual (Reference page 24, only bits 0/1 (speaker control) and 4/5 (NMI control) seem to be used)
  • Port 62h behaves XT-like (Reference page 25, I don't know whether timer 2 output on pin 5 is PS/2 specific, though)

The actual communication witht the keyboard happens on ports 66 to 6A, though

  • Port 66h
    • Bit 0: 1=Some error happened on Port 1 (likely parity error)
    • Bit 1: 1=Some error happened on Port 2 (likely parity error)
    • Bit 2: 0=Keyboard is locked (implementation in software: IRQ1 drops all bytes if this bit is clear)
    • Bit 3: software-controlled, no HW function. If set, keyboard on port 1, mouse on port 2; if clear; mouse on port 1, keyboard on port 2.
    • Bit 4: must be set for a short time after reading or writing the data byte for port 1 (most likely: releases clock low after RX; maybe allows releasing clock after last TX bit, too?)
    • Bit 5: will be cleared for some time before sending to port 1 (most likely: force clock low on port 1)
    • Bit 6: must be set for a short time after reading or writing the data byte for port 2
    • Bit 7: will be cleared for some time before sending to port 2 (most likely: force clock low on port 2)
  • Port 67h: Data buffer (in or out) for Port 1
  • Port 68h: Data buffer (in or out) for Port 2
  • Port 69h:
    • Bit 2: (guessed) 1=allow NMIs
    • Bit 3: pulsed high during clock low on TX start on port 1 (most likey: start TX state machine - generate start bit)
    • Bit 4: pulsed high during clock low on TX start on port 2 (most likey: start TX state machine - generate start bit)
  • Port 6Ah:
    • Bit 0: Seems to be some feedback of the density select line from the floppy drive. Possibly due to a bridge between pins 2 and 4 on a drive (HD only?)
    • Bit 2: 1 = byte from PS/2 port 1 available on port 67
    • Bit 5: 1 = byte from PS/2 port 2 available on port 68
  • Port A0h: PS/2 interrupt status
    • Bit 2: 1= IRQ1 due to PS/2 port 1
    • Bit 3: 1 = IRQ1 due to PS/2 port 2
  • Port A1h: Further interrupt controller extension
    • Bit 0: 0 = IRQ1 from Real-Time clock enabled. (1 = masked)

Furthermore, the system gate array implements two more ports, that are not keyboard/mouse related:

  • Port 65h: Reference page 21: it enables on-board components and controls the direction of the parallel port.
  • Port 6Bh: Reference page 35: Controls memory mapping and pinpoints parity errors to either on-board RAM (128K) or SIP/SIMM sockets (512K)

The real-time clock of the PS/2 model 30-8086 is a MM58167B RTC chip. That chip has 32 registers that are directly mapped into I/O space:

  • Port E0-EF: Registers 0-15 of the
  • Port B0-BF: Registers 16-31 of the MM58167B RTC chip

That chip has some RAM that is used to store the alarm time, but it is implemented in a creative way by IBM to alleviate some shortcomings. One main principle of abusing the alarm time RAM for general purpose data storage is understanding that nibble values C, D,E and F all mean "don't care". The chip works with nibbles due to its BCD nature. Each nibble thus allows to store two general-purpose bits that don't affect the operation of the RTC. The shortcomings of that RTC and the associated solutions are:

  • As the AT BIOS (which is compatible regarding RTC alarms) only supports seconds, minutes, hours and day-of-week for alarms, only registers 0Ah (seconds), 0Bh (minutes), 0Ch (hours) and 0Dh (day-of-week) are used for alarm time. This leaves registers 8 (milliseconds), 9 (centiseconds), 0Eh (day-of-month) and 0Fh (month) open for general-purpos use.
  • The chip has no year support at all. The current year (two digits, BCD) is stored (directly, not "hidden" in C-F) in the alarm centiseconds byte, register 9. Also, a century bit is stored in the low nibble of the alarm day-of-month (register 0Eh). Bit 1 in that register is unused and always zero. If the century bit is set, the century is "odd", i.e. 19xx. If the century bit is clear, the century is "even", i.e. 20xx.
  • Because the year is stored in RAM, it is not automatically updated when the date wraps from Dec 31st to Jan 1st. IBM introduces the concept of "RTC maintainance" to fix up the RTC in different circumstances. Maintainance happens (during POST) once per month at maximum. The mont number of the last RTC maintainance is hidden in the alarm milliseconds nibble (register 8, upper nibble) and day-of-week nibble (register number 0Dh, lower-nibble), by putting C-to-F-encoding the two low bits of the month number in the low nibble of register 0Dh and C-to-F-encoding the high to bits of the month number into the high nibble of register 8. If the last maintainance month is not equal to the current month, clock maintainance is performed and the last maintainance month is updated inside the RTC chip. If during maintainance the current month is lower than the last maintainance month, the year is incremented.
  • As the RTC doesn't know about years, it doesn't handle leap years. If during clock maintaince, it is detected that a leap day happened since the last maintaince, the RTC date is moved back one day. In case the maintainance happens on supposed Mar 1st (i.e. Feb 29th), the date is encoded as Mar, 0th. This enables "last maintaince March" to work as intended and prevent multiple adjustment of the RTC on multiple boots, and I don't know whether the RTC correctly jumps to Mar 1st after Feb 29th, as it does for Feb 28th.
  • There is no way to find out whether the battery is still good and the time/date is valid. A nibble-wise checksum is calculated over register 8 (high nibble only), registers 9 to 0Ch and the low nibble of register 0Eh. The checksum (which is cut to 6 bits, which is still wider than a nibble) is XORed with 0x15, and hidden in the alarm day-of-month register (0Eh, high nibble) and the alarm month register (0Fh). The high two bits of the xorred checksum is stored in register 0Eh, high nibble. The central two bits (of the xorred 6-bit checksum) is stored in register 0Fh, high nibble and the low two bits are stored into register 0Fh, low nibble. All three two-bit pieces are encoded as 0Ch to 0Fh.

Setting the alarm works through INT 1Ah,AL=06 and the alarm callback is on INT 4Ah, just as on the IBM AT.

Ignore the IBM specification suggestion about IRQ sharing. I never saw any hardware implementing that scheme.

Reply 10 of 11, by jakethompson1

User metadata
Rank Oldbie
Rank
Oldbie

Hey mkarcher, I've also done some bios analysis, but not of this particular bios or in this detail; always a good read. Does the model 30 bi0s execute in place or did you have to figure out how it's decompressed? And with these being 8086 I assume there is no ABIOS for OS/2 to worry about?

Reply 11 of 11, by mkarcher

User metadata
Rank l33t
Rank
l33t
jakethompson1 wrote on 2020-10-09, 23:38:

Hey mkarcher, I've also done some bios analysis, but not of this particular bios or in this detail; always a good read. Does the model 30 bi0s execute in place or did you have to figure out how it's decompressed? And with these being 8086 I assume there is no ABIOS for OS/2 to worry about?

It's a 64KB BIOS that executes in place. Actually, it's a map like this:

  • F000:0000-F000:5FFF 24KB BIOS code
  • F600:0000-F600:8000 32KB IBM ROM BASIC (based on Microsoft Basic)
  • F000:E000-F000:FFFF 8KB BIOS code

The odd split of the main BIOS is most likely due to the requirement to keep IBM BASIC at the location it already had on the IBM XT.

You are correct that there is no ABIOS code in the PS/2 model 30 BIOS. This is true for both the basic model 30 (obviously) and the 30/286.