DOS Plus v1.x eXtended Input/Output system

The XIOS is the machine-dependent part of DOSPLUS (or PCP/M-86), corresponding to the BIOS under CP/M. A number of different XIOSes exist, corresponding to different platforms. XIOSes are known to exist for:

I have released an enhanced version of the PC1512 XIOS as DOSPLUS 1.2-je4.

Internal Layout

Unlike a CP/M BIOS, the XIOS does not start with a big jumpblock. Instead there is a short header:

	jmp	BOOT	;Cold start routine
	jmp	DISP	;Function dispatcher
	dw	DATASEG				;Data segment address
						;in paragraphs

BOOT

This function is called by the BDOS as part of system startup. It is entered with DL = boot drive, and DS = data segment address. The standard implementation initialises all character devices and disc drives, sets up interrupt vectors, and prints a sign-on message.

DISP

The function dispatcher is entered with:

The following function numbers correspond to documented calls which can be accessed using BDOS function 50:

Note that the internal function numbers are not the same as the call numbers passed to BDOS function 50. The latter use the same order as in 8-bit CP/M.

The XIOS also provides the following calls, which are accessed either by the XDOS or by programs such as DISK. To make one of these calls, you have to find the XIOS entry point and call it directly, using code similar to this:

S_SYSDAT	EQU	154	;Get system data segment
RLR		EQU	4Eh	;Segment of current process table entry
XIOSE		EQU	28h	;Far pointer to XIOS entry

		PUSH	ES
		PUSH	DS
		MOV	CL,S_SYSDAT
		INT	0E0h	;ES:BX-> system data segment.
;
; ... Set up registers for your function ...
;
		MOV	AL,function_id		;Function selector
		PUSH	ES
		MOV	ES,WORD PTR .RLR	;Set ES -> current process
		POP	DS			;Set DS -> system data segment
		CALLF	DWORD PTR .XIOSE
		POP	DS
		POP	ES
		RET

Function numbers 0-13 are common to DOS Plus, Concurrent CP/M and Concurrent DOS. Higher numbers diverge.

Some (but not all) of these calls are also supported by CP/M-86 Plus and Personal CP/M-86. CP/M-86 Plus and Personal CP/M-86 v1.0 support calls up to number 17, AUXOST; PCP/M-86 version 2.0 supports calls up to number 42, though not all are implemented.

Unimplemented calls return AX=BX=0FFFFh.

Note that calls with AL greater than 80h are implementation-dependent; they differ between the PC versions (IBM, Amstrad, Jasmin) and the BBC Master version. They do not exist on any Personal CP/M-86 version.

16-bit addresses returned by XIOS calls will be in the system data segment.

The extra XIOS calls are:

7. SWITCH.
Under Concurrent CP/M / Concurrent DOS, this would be used to switch virtual consoles (DL = virtual console to use). But DOS Plus and PCP/M-86 don't support virtual consoles, so this function just returns AX=0.
8. STATLINE
Set the status line text. Enter with:
		AL = 8
		DX:CX = Address of message to display. 
			If CX = 0FFFFh then restore to normal status line. 
			Under Concurrent DOS, if CX=0 then update normal status
			line.
		BL = Pause flag. Nonzero to wait for a keypress after
			showing the message.
		SI = 0FFFFh.
	

Under Personal CP/M-86, this call does nothing and returns AX=0.

9. SELDSK
Try to log in a drive. Enter with AL=9, CL=drive number, 0-15 (DOS Plus supports only 13 drives, but the XIOS can still go up to 16). Returns BX=0 if failed, address of DPH if successful.
10. READ

Read sectors. All parameters are passed on the stack:

		SP+0: 	Far return address.
		SP+4:	Far pointer to read/write buffer.
		SP+8:	Sector number (word).
		SP+10:	Track number (word).
		SP+12:	Drive number (byte).
		SP+13:	Number of sectors to read (byte).
	

Returns AX=0 if OK, 1 if error.

11. WRITE

Write sectors. All parameters are passed on the stack:

		SP+0: 	Far return address.
		SP+4:	Far pointer to read/write buffer.
		SP+8:	Sector number (word).
		SP+10:	Track number (word).
		SP+12:	Drive number (byte).
		SP+13:	Number of sectors to write (byte).
	

Returns AX=0 if OK, 1 if error, 2 if drive read-only.

12. FLUSH
Write any pending disk buffers. Returns AX = 0 if OK, 1 if error.
13. POLL.
Corresponds to the Concurrent "Poll device" call (DL=device number). Always returns immediately with AX=0 (device ready).
16. AUXIST
Return status of current auxiliary input device. Returns AL=0 (not ready) or AL=0FFh (ready).
17. AUXOST
Return status of current auxiliary output device. Returns AL=0 (not ready) or AL=0FFh (ready).
18. Raw read.

Read sectors using absolute cylinder/head/sector addressing.

		SP+0: 	Far return address.
		SP+4:	Far pointer to read/write buffer.
		SP+8:	0-based sector number (byte).
		SP+10:	Cylinder number (byte).
		SP+11:	Head number (byte).
		SP+12:	Drive number (byte).
		SP+13:	Number of sectors to read (byte).
	

Returns registers as from an INT 13h call.

Under Personal CP/M-86, this call does nothing and returns AX=0.

19. Raw write.

Write sectors using absolute cylinder/head/sector addressing.

		SP+0: 	Far return address.
		SP+4:	Far pointer to read/write buffer.
		SP+8:	0-based sector number (byte).
		SP+10:	Cylinder number (byte).
		SP+11:	Head number (byte).
		SP+12:	Drive number (byte).
		SP+13:	Number of sectors to write (byte).
	

Returns registers as from an INT 13h call.

Under Personal CP/M-86, this call does nothing and returns AX=0.

29. Format floppy track

Enter with parameters pushed on the stack:

		SP+0:	Far return address
		SP+4:	Address of sector header buffer (far pointer)
		SP+8:	Magic number. In the PC versions, this is ignored. 
			On the BBC Master, it must be 4A57h or 574Ah 
			('JW' or 'WJ').
		SP+10:	Cylinder (bits 15-1) / Head (bit 0) to format (word)
		SP+12:	Drive number to format (byte)
		SP+13:	Number of sectors to format (byte)
		

Returns AX=0 if OK, 1 if error, 2 if disc read-only.

Under Personal CP/M-86 v2.0/4, the word at SP+12 can also have the following special values:

32. Status line control

Used to enable/disable the status line. CL=mode.

Under Personal CP/M-86 v2.0/4, this call does nothing and returns AX=0.

35. Absolute sector read

Identical to function 18. Called by the BDOS when simulating INT 13h.

Under Personal CP/M-86 v2.0/4, this call does nothing and returns AX=0.

36. Absolute sector write

Identical to function 19. Called by the BDOS when simulating INT 13h.

Under Personal CP/M-86 v2.0/4, this call does nothing and returns AX=0.

37. AUXIST

Identical to function 16.

Under Personal CP/M-86 v2.0/4, this call does nothing and returns AX=0.

36. AUXOST

Identical to function 17.

Under Personal CP/M-86 v2.0/4, this call does nothing and returns AX=0.

39. Read/write a block of data
Enter with:
		SP+0:	Far return address
		SP+4:	Address of buffer to read/write (far pointer)
		
If successful returns 0. If not all bytes were transferred, returns number of bytes not transferred. If no bytes transferred, returns 0FFFFh.
42. Character blit function for windowing
Enter with parameters on stack:
		SP+0:	Far return address
		SP+4:	Far pointer to parameter struct:
				DW	planes	;Bit 0 set to copy characters
						;Bit 1 set to copy attributes
				DD	Far pointer to destination window
					     (segment = 0 to use screen)
				DD	Far pointer to destination rect.
				DD	Far pointer to source window
					     (segment = 0 to use screen)
				DD	Far pointer to source rect.

		Window definitions are formed:	
				DD	plane1	;Data for characters
				DD	plane2	;Data for attributes
				DD	?	;Pointer to window settings?
				DW	?	;Unknown
				DW	fh	;Height, bytes
				DW	fwb	;Width, bytes
		Rectangles are formed:
				DW	top_row
				DW	left_col
				DW	height
				DW	width
		

Returns AX=0FFFFh if not implemented. The Amstrad XIOS implements this function; the BBC Master XIOS and PCP/M-86 do not.

Functions numbered above 128 vary from version to version.

128. Return OEM version.
Returns BX -> OEM version string, 0-terminated.
On the PC versions, leaves CX unchanged.
On the BBC Master 512, returns CX=512. Apparently the Master 512 port of Concurrent DOS returned CX=256.
On Apricot CP/M-86 Plus and PCP/M-86, this formats a disk track. Parameters are passed on the stack.
Not implemented on other Personal CP/M-86 versions.
129. Retrieve XIOS variables (PC versions only).

Gets the addresses of system-specific variables. Enter with CX = variable to retrieve. Returns the address in BX.

The reason there is a function to return the original INT 13h vector is that the DOS module of DOSPLUS provides its own INT 13h handler. This only supports functions 2, 3 and 4; so programs which want to use INT 13h for anything else will have to get the original pointer and use that.

129. Does drive exist? (Apricot systems)
Passed a drive number in DL, will return AX=DPH address of drive if it exists, AX=2*drive if failed.

Functions 81h and above on the BBC Master are listed briefly at 8bs.com, and described in detail at cowsarenotpurple.co.uk.

XIOS Equipment Table

The address of this equipment table is returned (on PCs) by function 129.. Its format is as described below; but I don't know how much of it is consistent across versions.

	DW number_of_floppies
	DW number_of_hard_drives
	DW number_of_LPT_ports
	DW number_of_COM_ports
	DW 0	;?
	DW 0	;?
	DW numeric_coprocessor_flag	;Nonzero if 8087 present
	DW 0	;?
	DW kbytes_in_RAMdrive
	DW RAMdrive_letter		;0=>A:, 1=>B: etc.
	DW is_drive_zero_shared		;0 if A: and B: are separate drives.
					;0FFFFh if they map to the same drive.
	DW equipment_word		;As returned by INT 11h
	DB machine_type			;0 => PC or XT
					;1 => AT
					;2 => Compaq
					;3 => Olivetti
					;4 => Amstrad PC1512
					;5 => Jasmin Turbo
	DB at_flag			;Nonzero if on an AT
	DW memory_buffer_list		;Offset in ES of a list of 32 memory 
					;buffers. Each entry is 6 bytes:
					; DW segment
					; DW paragraphs
					; DB owner PID
					;	0FDh => Owner terminating
					; 	0FEh => Free
					;	0FFh => Unused entry
					; DB temporary flag
					;	If 1, memory can be freed if 
					;	another process needs it.

Return to archive listing