Vintage PC pages
Home -> Vintage PCs -> Olivetti PCS86

The Olivetti PCS86


The Olivetti PCS86 is a late-1980s XT clone. It's of similar spec to an IBM PS/2 Model 30 or an Amstrad 2086/3086.

The hardware includes:

The following connectors are on the back panel:

One curious feature of my PCS86 (and presumably of all single-drive models) is that it only has a single internal power connector - there's no way to power a second floppy drive or a hard drive.

Other sites suggest that the correct hard drive would be a Conner CP3026, a 21Mb drive about which the Internet has very little to say, except it's similar to the better-documented CP3024. Given that the BIOS seems to be expecting an XTA drive, I wonder if the difference between the two is that the CP3026 is XTA rather than ATA.


The PCS86's BIOS is in a 64k ROM. All functionality is included in the one BIOS at 0xF0000; there is no separate VGA BIOS at 0xC0000 or hard drive BIOS at 0xC8000. There are two sets of video BIOS code - one to support the onboard VGA, and another to support a secondary CGA or MDA.

The BIOS claims (if you interrogate it with INT 0x15/AH=0xC0) to be for a PS/2 Model 30, submodel 109 (i.e. BIOS 1.09), revision 1.01. Most of the BIOS quirks found in earlier Olivetti PCs have gone, but video mode 0x40 (640x400x16) is still present. When this mode is selected, the CGA BIOS is used rather than the main VGA BIOS.

There are still a few traces of the master data table in the BIOS. When the VGA BIOS has control, the bytes at 0040:0084 are standard VGA/EGA variables (rows on screen, pixels per character, and video options). When the CGA BIOS is in use (either when the main screen is in mode 0x40, or when a secondary CGA is in use), 0040:0084 may contain a DWORD pointer to the master data table, which is used to locate the 8x8 and 8x16 bitmap fonts. The BIOS does not set up a master table; this would have to be done by a transient utility. When using the table, the BIOS (sometimes) checks if the first word is 16h. If it is, then it treats the table as valid; if not, it uses hardcoded ROM fonts. At other times, particularly in mode 40h, it uses the table without checking.


The motherboard has various jumpers; here, I'm concerned with the bank of eight at the rear right-hand side of the case. They are read by reading port 100h; in the value returned, bit 0 corresponds to the jumper nearest the back of the PC, and bit 7 to the one nearest the front. If a jumper is present, the corresponding bit will be zero; otherwise, one.

The BIOS only appears to care about jumpers 0-3 and 7:

Bits 1, 0: Floppy drive 0 type
		Jumper on both       [:][:]   360k
		Jumper on low bit     : [:]   1.2M
		Jumper on high bit   [:] :    720k
                Jumper on neither     :  :    1.4M

Bits 3, 2: Floppy drive 1 type, as above.

Bit  7   : If jumper is fitted, a hard drive is present.

PS/2 Ports

Though the PCS86 is an XT, it uses the AT keyboard interface and protocol. However, the controller at the PC end doesn't use the same I/O ports as an AT keyboard controller. Instead, the two PS/2 ports use the I/O range 66h-6Ah. The labels on the case show Port 2 as the keyboard port, port 1 as the mouse port, but the two are, sensibly, interchangeable. The BIOS attempts to support either type of device on either port.

The BIOS keyboard detection code will detect PS/2 keyboard IDs AB 83 (full PS/2) and AB 84 (Spacesaver). The mouse detection requires the mouse ID to be zero, and so will not detect mice with wheels.

Port 66h: Read/write port.
	Bit 7	: Port 2 clock line. 1 to release it, 0 to hold it low.
	Bit 6	: Port 2 reset interrupt trigger? Writes 0, 1, 0 after
                  transmitting or receiving a byte.
	Bit 5	: Port 1 clock line. 1 to release it, 0 to hold it low.
	Bit 4	: Port 1 reset interrupt trigger? Writes 0, 1, 0 after
                  transmitting or receiving a byte.
	Bit 3   : Appears to select which port emulates the XT keyboard: 
                  1 for port 1, 0 for port 2. The selected port will raise
                  interrupts on IRQ1 and forward scancodes to port 60h.
	Bit 2	: Zero if the keylock is locked

Port 67h: Port 1 data register -- scancodes / commands are read and written
Port 68h: Port 2 data register.

Port 69h:
	Bit 4   : Port 2 data line? Before loading the data register,
                  BIOS holds the clock low and writes 1 then 0.
	Bit 3   : Port 1 data line? Before loading the data register,
                  BIOS holds the clock low and writes 1 then 0.

Port 6Ah:
	Bit 5   : Port 1 - set if byte received from keyboard
	Bit 2   : Port 2 - set if byte received from keyboard

Real Time Clock

The Real Time Clock function is provided by an MM58167. Its memory is mapped at I/O ports 0E0h-0EFh:

E0	Counter: BCD milliseconds
E1	Counter: BCD centiseconds
E2	Counter: BCD seconds
E3	Counter: BCD minutes
E4	Counter: BCD hours
E5	Counter: BCD day of week
E6	Counter: BCD day of month (29th Feb held as 0th March)
E7	Counter: BCD month

E8	RAM: Bits 7,6 should always be 1 (no alarm millisecond)
	     Bits 5,4 are bits 2,3 of last month read from RTC

E9	RAM: BCD Year 

EA	RAM: Alarm second (0FFh if no alarm set)

EB	RAM: Alarm minute (0FFh if no alarm set)

EC	RAM: Alarm hour   (0FFh if no alarm set)

ED	RAM: Only low 4 bits exist.
	     Bits 0,1 are bits 0,1 of last month read from RTC
             Bits 3,2 should always be 1 (no alarm weekday)
EE	RAM: Bit    0 gives century (0 => 21st, 1 => 20th)
             Bit    1 does not appear to be used; century rollover sets it to 0.
             Bits 5,4 are bits 5,4 of checksum (see below)
	     Bits 7,6,3,2 should always be 1 (no alarm day)

EF	RAM: Bits 1,0 are bits 1,0 of checksum (see below)
             Bits 5,4 are bits 3,2 of checksum (see below) 
             Bits 7,6,3,2 should always be 1 (no alarm month)

and its command registers at 0B0h-0B7h:

B0	Interrupt status register
B1	Interrupt control register
B2	Counters reset
B3	RAM reset
B4	Status Bit (bit 0 is set if RTC is updating)
B5	GO command
B6	~Standby interrupt
B7	Test mode

The 'last month read' value is used to detect year rollover. If the last month read is greater than the current month, the BIOS increments the year (and, if necessary, the century) since the MM58167 doesn't have a year counter of its own.

The RTC memory contains a 6-bit checksum, calculated as follows:

  (high 4 bits of port 0E8h) >> 4
+ (high 4 bits of port 0E9h) >> 4
+ (low  4 bits of port 0E9h) 
+ (high 4 bits of port 0EAh) >> 4
+ (low  4 bits of port 0EAh) 
+ (high 4 bits of port 0EBh) >> 4
+ (low  4 bits of port 0EBh) 
+ (high 4 bits of port 0ECh) >> 4
+ (low  4 bits of port 0ECh) 
+ (low  4 bits of port 0EDh) 
+ (low  4 bits of port 0EEh) 
AND with 03Fh
XOR with 015h

The resulting 6-bit value is then stored as follows:

Bits 5,4: Stored in bits 5,4 of port 0EEh
Bits 3,2: Stored in bits 5,4 of port 0EFh
Bits 1,0: Stored in bits 1,0 of port 0EFh

If the checksum is incorrect, the BIOS will return an error to INT 1Ah/AH=2 (read CMOS time) and INT 1Ah/AH=4 (read CMOS date).

Other Ports

Port 65h appears to enable / disable motherboard features.

Bit 0: Enable motherboard hard drive controller.
Bit 1: Enable motherboard parallel port
Bit 2: Enable motherboard video chipset?
Bit 5: Enable motherboard serial port
Bit 7: Set to 1 by cold boot and when testing printer port.

The parallel and serial port initialisation code checks these ports twice — once with the motherboard ports disabled, and once with them enabled. This allows add-on cards to override the built-in ones.

Port 102h appears to be associated with add-on VGA or 8514/A cards. It's frequently written at the same time as port 46E8h (enable / disable add-on VGA card), with the value 1 (enable add-on VGA?) or 0 (disable add-on VGA?).

John Elliott 6 December 2013