Vintage PC pages
Home -> Vintage PCs -> Philips :YES

The Philips :YES

Note: This document is a work in progress.

The :YES (a name that certainly wasn't chosen for being easily findable in a search engine) is one of those early PC clones that runs MSDOS but isn't compatible at a hardware level with the original IBM PC. Instead, the hardware differences are handled by the ROM BIOS and IO.SYS.

At a hardware level, the specification is roughly:

I don't have a :YES, so all my information comes from the manuals, the BIOS ROM, and the system software.

Hardware

A :YES can have either 128k, 256k or 640k of memory. The BIOS detects this at boot time, and uses the 80186's memory mapping ability to place the video framebuffer at the end of memory, writing to the MMCS register (port 0FFA6h):

Memory sizeVideo segmentMMCS
128k1000h01F8h
256k3000h21F8h
640k9000h81F8h

I/O ports used are:

0400-041E: Serial / parallel ports (I8256AH MUART):

0400	MUART Command Register 0:
		Bits 6-7: Data bits 
				00 => 8
				01 => 7
				10 => 6
				11 => 5
		Bits 5-4: Stop bits
				00 => 1
				01 => 1.5
				10 => 2
				11 => 0.75
		Bit 3: Break-in Detect Enable
		Bit 2: Interrupt on bit change
		Bit 1: 8086 mode
		Bit 0: Timer frequency select

0402	MUART Command Register 2
		Bit 7: Parity enable
		Bit 6: Even Parity
		Bits 5-4: System clock prescaler
		Bits 0-3: Data rate

0404	MUART Command Register 3
0406	MUART mode register
0408	MUART Port 1 Control register
040A	MUART interrupt enable
040C	MUART interrupt address
040E	MUART transmit / receive buffer
0410	MUART Port 1: Serial / parallel port control (r/w)
		Bit 6: Normally 1, set to 0 to reset serial port
		Bit 4: Parallel port busy?
		Bit 1: Parallel port strobe
		Bit 0: Parallel port busy?
0412	MUART Port 2: Parallel port write character
0414	MUART Timer 1
0416	MUART Timer 2
0418	MUART Timer 3
041A	MUART Timer 4
041C	MUART Timer 5
041E	Serial port status
		Bit 7: Interrupt pending
		Bit 6: Receive data ready
		Bit 5: Transmit holding register empty
		Bit 4: Transmit shift register empty
		Bit 3: Break
		Bit 2: Parity error
		Bit 1: Overrun
		Bit 0: Framing error	

0480	WD2797 command / status register
0482	WD2797 track register
0484	WD2797 sector register
0486	WD2797 data register

0500	CRTC register select
0502	CRTC register value

0580	Floppy drive select (low 4 bits - bit 0 for first drive, 1 for second
	drive etc.) Bit 6 may be motor enable.

05A0	Last scancode from keyboard

05C0	Palette (16 entries at even-numbered addresses. Each entry holds
....	a 4-bit IRGB value for the corresponding colour.
05DE

05E0	System / display control.
	On read:
		Bits 6-7 give monitor type.
				0: ?Colour TTL
				1: Mono TTL
				2: ?Colour composite
				3: ?Colour SCART
		Bit    0 set if Professional Expansion Board is present.
		(I don't know which colour monitor option is which; I'm 
		simply guessing based on the initial video mode).
	On write:
		Bits 0-4 are the video mode control register.
			Bit 0 set for 40×25 text, 640×252 graphics
				and 160×252 graphics.
			Bit 1 set for text mode, clear for graphics modes
			Bit 2 set for the 640-pixel graphics modes
			Bit 3 set for the 320-pixel graphics mode
			Bit 4 always set (enable display?)
		Bit 5 is the beeper.
		Bit 7 is used in the floppy disk I/O functions.

066A	Real-time clock

067A	SASI data register
067C	SASI status / control register

FF00	80186 onboard peripherals. DMA0 is used for the hard drive, DMA1 for
....	the floppy. Timers 0 and 1 are used as system timers.
FFFF

Video modes

The BIOS contains timings for the following video modes. There are two sets of timings for most of the modes — presumably one for TTL monitors, the other for SCART / composite output.

ModeHorizontal totalHorizontal displayed Horizontal syncSync widthsVertical total Vertical adjustVertical displayedVertical syncInterleaveCharacter height Cursor shapeDisplay address Cursor address
First set
40×2554 40 44 67 27 3 25 26 2 9 0 0 0x39 0xD8 0 0
80×2554 40 44 67 27 3 25 26 2 9 0 0 0x39 0xD8 0 0
80×25 mono48 40 42 84 2516 25 26 2 13 0 0 0x39 0xD8 0 0
320×25254 40 44 67 69 0 63 64 2 3 0 0 0x00 0x00 0 0
640×25254 40 44 67 69 0 63 64 2 3 0 0 0x00 0x00 0 0
640×35248 40 42 84 94 2 88 88 2 3 0 0 0x00 0x00 0 0
160×25254 50 44 67 69 0 63 64 2 3 0 0 0x00 0x00 0 0
Second set
40×2556 40 44 68 30 2 25 27 2 9 0 0 0x39 0xD8 0 0
80×2556 40 44 68 30 2 25 27 2 9 0 0 0x39 0xD8 0 0
80 ×25 mono48 40 42 84 2516 25 26 2 13 0 0 0x39 0xD8 0 0
320×25256 40 44 68 77 0 63 68 2 3 0 0 0x00 0x00 0 0
640×25256 40 44 68 77 0 63 68 2 3 0 0 0x00 0x00 0 0
640×35248 40 42 84 94 2 88 88 2 3 0 0 0x00 0x00 0 0
160×25256 50 44 68 77 0 63 68 2 3 0 0 0x00 0x00 0 0
40-column mode for mono monitor
40×25 mono48 40 42 84 2516 25 25 2 13 0 0 0x39 0xD8 0 0

Terminal Emulation

Escape codes supported by the two built-in terminal emulations:

VT52

ESC ACursor up
ESC BCursor down
ESC CCursor left
ESC DCursor right
ESC EClear screen
ESC HHome cursor
ESC ICursor up (scroll down if on top row)
ESC JErase from cursor to bottom of screen
ESC KErase from cursor to end of line
ESC LInsert a line
ESC MDelete current line
ESC NDelete character under cursor
ESC Y row colSet cursor position
ESC aEnable cursor
ESC b colourSet foreground colour
ESC c colourSet background colour
ESC dDelete from start of screen to cursor
ESC eEnable cursor
ESC fDisable cursor
ESC jSave cursor position
ESC kRestore cursor position
ESC lErase characters on current line
ESC oErase from start of line to cursor
ESC pInverse video
ESC qNormal video
ESC rBold text on
ESC sBlinking text on
ESC tBlinking text off
ESC uBold text off
ESC vEnable wrapping at the end of the line.
ESC wDisable wrapping at the end of the line.
ESC <Switch to VT100 emulation
ESC ?Switch to dumb terminal emulation
ESC 0Underlined text on
ESC 1Underlined text off

VT100

ESC [ count ACursor up by count lines
ESC [ count BCursor down by count lines
ESC [ count CCursor left by count lines
ESC [ count DCursor right by count lines
ESC [ count E Cursor to beginning of row, count lines up
ESC [ count F Cursor to beginning of row, count lines down
ESC [ col G Move cursor to column col
ESC [ row ; col H Move cursor to row row, column col
ESC [ n JClear part of the screen
ESC [ n KClear part of the line
ESC [ n LScroll down the area of the screen below the cursor by n lines
ESC [ n MScroll up the area of the screen below the cursor by n lines
ESC [ n PDelete n characters to the right of the cursor
ESC [ n SScroll the screen up by n lines.
ESC [ n TScroll the screen down by n lines.
ESC [ col ` Move cursor to column col
ESC [ d
ESC [ row ; col f Move cursor to row row, column col
ESC [ n hTurn on option
ESC [ n lTurn off option

Options are:

0Select 40×25 black/white mode
1Select 40×25 colour mode
2Select 80×25 black/white mode
3Select 80×25 colour mode
4Select 320×252 mode
5Select 320×252 mode
6Select 640×252 mode
7Enable / disable wrap at end of line
8Select 80×25 mono mode
9Select 640×352 mode
10Enable / disable cursor
11Alters cursor positioning behaviour - relative to the screen or the window.
12Select dumb terminal [h] or VT52 emulation [l]
13Select 160×252 mode
ESC [ n mSelect colours / attributes
ESC [ 6nGet cursor position
ESC [ x ; y { Plot a pixel
ESC [ x ; y | Draw a line and update the last pixel position plotted
ESC [ x ; y } Draw a line and don't update the last pixel position plotted
ESC [ n ~Set cursor blink rate to n
ESC [ n ^Set beeper pitch to n
ESC [ n _Set cursor row relative to character
ESC [ sSave cursor position
ESC [ uRestore cursor position
ESC [ n r
ESC [ n \Set line bitmap to n

BIOS

The top 64k of memory contains the DOS Plus kernel, a boot menu, and a BIOS that attempts to be compatible with the IBM 5150, its heirs and successors.

The BIOS version can be found as a little-endian word at 00415h (0040:0015):

Bits 15-12: Gate array version
Bits 11- 8: BIOS version major
Bits  7- 0: BIOS version minor

The following services are provided:

INT 5Dh

INT 5Dh is used to control the extra features of the :YES. In general it is used with AH = device class (10h for video, 13h for disk, 14h for serial etc) and AL = subfunction.

Video functions (AH=10h)

AX = 1001h

Load character mapping table. Sets one of three DWORD address values.

DH = 0 for main set, 1 for secondary set.
DL = 0-2 for table within set.
ES:CX = value, 0000:0000 for default.

Each table is a list of words terminated by 0000h. The low byte of each word is the character to match, the high byte is the character to replace it with.

When a character is substituted, its attribute is also altered. The first table resets bit 6 of the attribute; the second sets bit 6. The third table seems to match only on the top 4 bits of the character, and substitutes the top 4 bits. It also sets bit 6 of the attribute.

AX = 1002h
Copy the secondary set of character mapping tables to the main set.
AX = 1003h
Apply the mapping tables to character CL. Returns AL = resulting character, AH = 0-3 (top 2 bits of resulting attribute).
AX = 1010h

Set video mode in CL:

	Mode	Resolution
	=======================================================
	0	40×25 text (BW40)
	1	40×25 text (CO40)
	2	80×25 text (BW40)
	3	80×25 text (CO40)
	4	320×252 graphics
	5	320×252 graphics
	6	640×252 graphics
	7	80×25 text (MONO)
	8	640×352 graphics
	9	160×252 graphics
	=======================================================
	
AX = 1011h
Get current video mode and monitor type. Returns mode in low 4 bits of AL, monitor type in AH (top 2 bits of port 05E0h). Bit 4 of AL is set for modes 8 or 9.
AX = 1012h
Set colour / monochrome output: CL = 0 for mono, 1 for colour. Changing video mode will reset this to the default value for the selected mode.
AX = 1013h
Get colour / monochrome setting in AL.
AX = 1020h
Set beep pitch in CX.
AX = 1021h
Sound the beeper.
AX = 1022h
Set cursor flash rate in AL.
AX = 1030h
Select terminal emulation. AL = terminal: 0 for none, 1 for VT100, 2 for VT52.
AX = 1031h
Return terminal emulation in AL.
AX = 1040h
As INT 10h/AH=9, but bypassing the mapping tables set by INT 5Dh/AH=1001h.
AX = 1041h
Write a block of text to screen. BX gives width, CX gives height, ES:DX gives address.
AX = 1042h
Read a block of text from screen to memory. BX gives width, CX gives height, ES:DX gives address.
AX = 1043h
Set text output window. CL = left, BL = right, BH = top, CH = bottom
AX = 1050h

Enable / disable graphics modes. CL = 0 to disable, 0FFh to enable.

Disabling graphics modes increases available program memory by 57k.

AX = 1051h
Get graphics mode availability. Returns AL = 0 (disabled) or 0FFh (avilable).
AX = 1052h
Get address of font for graphics modes in ES:BX, or 0 if graphics are not enabled. Unlike on a true blue PC, there is no graphics font in the BIOS so this would have to be provided by a utility like GRAFTABL.
AX = 1053h
Set graphics font address in ES:BX, 0000:0000 for none.
AX = 1054h
Get address of palette in ES:BX. Palette is 16 bytes long.
AX = 1055h
Change palette. BH = register, BL = value (both 0-0Fh).
AX = 1060h
Draw a line from the last plotted pixel to the given position. BH=bitmap pattern, BL=attribute, CX / DX are coordinates.

Disk functions (AH=13h)

AX = 1301h
Set INT13h hook function 1 in ES:BX (0000:0000 for none).
AX = 1302h
Set INT13h hook function 2 in ES:BX (0000:0000 for none).

Serial functions (AH=14h)

AX = 1401h
Set serial port callback in ES:BX.
AX = 1402h
Unknown.
AX = 1403h
Unknown.
AX = 1404h
Set a 32-bit value in BXCX.
AX = 1405h
Return serial port status (as INT 14h/AH=3).

Keyboard functions (AH=16h)

AX = 1601h
Set keyboard configuration table. DH = data set (0 for secondary, 1 for primary). DL = table to set, 0-6. ES:CX = table address, 0000:0000 to use default.
AX = 1602h
Copy secondary keyboard configuration addresses to primary.
AX = 1603h
Set keyboard callback in ES:BX. 0000:0000 for none.

Printer functions (AH=17h)

AX = 1701h
Enable / disable printer buffering. ES:BX = callback address, 0000:0000 to disable.
AX = 1702h
Set print spool timer as a 32-bit value in BXCX.

Special functions (AH=80h) and miscellany

AX = 388Ch
Cancel a one-shot timer. DL = timer number.
AX = 8001h
Get system memory size in paragraphs. Returns size in BX. If graphics modes are enabled, the system memory size will be reduced to make room for the graphical framebuffer.
AX = 8002h

Set a one-shot timer. Pass DL = timer number, CX = countdown, ES:BX = function to call when the timer reaches zero.

Timer 4 is used by the serial port.

Timer 7 is used internally for print spooling. In this case countdown is 32 bits (high word in BP).

AX = 8003h
Returns last keypress in AL.
AX = 8004h
Set a callback when the INT 8 timer fires. ES:BX = callback, 0000:0000 for none.
AX = 8005h
Unknown, parameter in DX.
AX = 8101h

Set / cancel mouse callback (implemented by the mouse driver, not the BIOS.

ES:BX = callback address (0 to cancel mouse callback).

Returns ES:BX = address of 3-byte mouse packet. On mouse move, callback code will be called, and the mouse packet will contain:

	DB buttons
	DB delta_x
	DB delta_y

Mouse

A loadable mouse driver is provided. In BIOS versions later than 1.02, the mouse support is present in the BIOS and does not need to be loaded manually.

The mouse driver hooks two interrupts: INT 0Ch and INT 5Dh.

INT 0Ch: Mouse hardware interrupt. When triggered, the handler reads port 066Eh, bit 1. If it is nonzero, a byte is read from port 0676h and interpreted (presumably this is the input from the mouse).

(All values are speculative; I may well have transposed the buttons, the
X and Y axes, or the directions).

Bit 0: Button 2 
Bit 1: X movement direction: 1=left 0=right
Bit 2: 0 -> 1 transition indicates X movement, direction given by bit 1. 
Bit 3: Y movement direction: 1=up 0=down
Bit 4: 0 -> 1 transition indicates Y movement, direction given by bit 3. 
Bit 5: Button 1

INT 5Dh: API. If called with AX=8101h, this is handled by the mouse driver:

When mouse interrupts are enabled, the callback code checks if mouse coordinates have changed. If so it calls the user callback passed to INT 5Dh/AX=8101h in ES:BX.

Real-Time Clock

The real-time clock is provided by the Professional Expansion Board.

XCLOCK.EXE detects the presence of the Professional Expansion Board by reading port 05E0h. If the bottom bit is zero, the clock is considered to be present.

The RTC is accessed using a serial protocol, controlled through ports 066Eh and 067Ch. The latter appears to be shared with the SASI controller.

Port	Bit	Meaning
066Eh	0	Data received from RTC
067Ch	0	Data to write to RTC
067Ch	6	}
067Ch	7	} Purpose unknown, but probably govern data direction.

The last value written to port 067Ch is saved in memory at 004E4h, and should be kept up to date.

Depending whether the register select is big- or little- endian, RTC registers are either:

Register (if big-endian) 	(if little-endian)	Meaning		
0				0			Month
2				2			Day
4				1			Hour
6				3			Minute

XCLOCK doesn't access the hardware when manipulating the year, so possibly the RTC only supports month, day, hour and minute. Instead, when the clock is set, the date (as the number of days since 1 January 1980) is written to offset 6Dh of the first sector of the boot drive. This is then used to initialise the DOS date at next boot.


John Elliott 7 April 2019