CP/M-86
System Guide

Cooyriqht @ 1981

Diqital. Research
P.O. Box 579
901 Tiqhthouse Avenue
Pacific Grove, CA 43950
(408) 649-3896
TWX 910 360 5001

All 'Riqhts Reserved
Foreword

	The CP/M-86 ';ystem (-uile oresents the svstem programming
	asoects of CP/m-861) , a si.nqle-user ooeratinq system for the Intel
	8086 and 9088 16-bit microprocessors. The (9iscussion assumes the
	reader is famil iar with ("D/M the niqitaT Research 9-bit ooeratinq
	system. To clarifv snecif ic dif ferences with CP/m-86, this document
	refers to the 8-bit version of (--P/M as (-p/NI-90TM. Elements common
	to both systems are si,molv calle-i (-P/m features.

	(-P/M-90 and (-P/M-96 are eauivalent at the user interface level
	and thus the Diqital Research documents:

		I\n Introduction to r'P/M Peatures and Pacilitip-,
		ED: A Context Editor For the CP1m nisk Svstem
0		CP14 2 TTse r ' s ru ide

are shipped with the C-D/1-1-86 oacl-aqe. -11,190 included is the (P/M-R6
Proqrammer's Guide, which riescri - bes A1;%11-86T"" and DnT-q671% niqital
Research's 8086 assembler and interactive (lehuqqp-r.
	This 1,vstern r,uile oresents an overview of the(P/m-96
Programming interface conventinris. Tt -il-so riescrihes orocelures for
adaotinq CP/M-86 to a custom harriware enviornment. This information
oarall-els that oresented in the ('TD/m ? Interface (-uirle an.'9 the ('T)/"
2 Alteration Guide.

	Sectinn 1 gives an overview of (-T)/"-86 and SLImmarizps it-,
	differences with ('-?/M-90. Section 2 describes the qeneral execution
	environment while qection 3 tells how to generate command
Sections 4 and 5 resoectivel-v define the proqramminq interfaces to
the Basic Disk Operatinq qvstem and the Rasic Trir)tlt/()utr)ut qvstpm.
Section 6 discusses alteration of the RIOS to suooort custom cliqk
configurations, and Section 7 (lescrihes the loadinq operatinn anrl
the organization of the (-?,/M-86 svst4m file.

i- i i-
Table of Contents

1		CP/M-86 System Overview

1.1		CP/M-86 reneral. Characteristics .

1.2		CP/M-80 and CP/M-86 differences .

2		Command Setup and Execution Under CP/M-86

2.1 CCP Built-in and Transient Commands . . . . . . . . 		7

2.2 Transient Program Execution Models . . . . . . . . 8
2.3 The 8080 Memory Model . . . . . . . . . . . . . . . 9
2.4 The Small Memory Model . . . . . . . . . . . . . . 10
2.5 The Compact Memory model . . . . . . . . . . . . . 11
2.6 Base Paqe Initialization . . . . . . . . . . . . . 13
2.7 Transient ProqraM T,oad and Pxit . . . . . . . . . . 14

3		Command (CMD) File Generation

3.1		Intel Hex File Format . . . . . . . . . . . . . . . 	15

3.2 Operation of cFNcmn . . . . . . . . . . . . . . . . 16
3.3 Operation of TMCmT) . . . . . . . . . . . . . . . . 19
3.4 Command (CMO) File Format . . . . . . . . . . . . . 20

4		Basic Disk Overating System (BDOS) Functions

4.1		BDOS Parameters and Function Codes

4.2 Simple BOOS Calls . . . . . .
4.3 BOOS File Operations . . . . .
4.4 BOOS Memorv Manaqement and Load

5		Basic 1/0 System (BIOS) Organization

5.1		organization of the BIOS . . .

5.2		The BIOS Jump Vector . . . . .
5.3		Simple Peripheral Oevices
5.4		BIOS Subroutine Pntrv Points

6		BIOS Disk Definition Tables

6.1		Disk Parameter Tahle Format . . . . . . . . . . . . 	67

6.2		Table Generation Using GENDEF . . . . . . . . . . . 72
6.3		r,'PNOEF Output . . . . . . . . . . . . . . . . . . . 77

7		CP/N-86 Bootstrap and Adaptation Procedures

7.1		The Cold Start Load Operation . . . . . . . . . . 	81

7.2		Orqanization of CPM.SYS . . . . . . . . . . . . . 	84

V



Appendixes

A T3!ockinq and Deblockinq Alqorithms . . . . . . . . . . . R7
B Random Accec;s gamT)le Proqram . . . . . . . . . . . . . . ql;
C Listing of the Boot Rom . . . . . . . . . . . . . . . . . 103
D LDBIOS Listing . . . . . . . . . . . . . . . . . . . . . 113
E BIOS Listing . . . . . . . . . . . . . . . . . . . . . . 121
F CT3IO.c; Listing . . . . . . . . . . . . . . . . . . . . . . 137

vi
	Section 1
CP/M-86 System Overview

1.1		CP/M-86 General Characteristics

	("P/M-86 contains all facilities of CP/m-80 with ad(liti-onal.
	features to account For increased Processor address space of un to a
	megabyte (1,048,576) of main memory. Further, CP/M-86 maintains
	file compatibility with all Previous versions of CP/M. The file
	structure of version 2 of CP/M is used, allowing as many as sixteen
	drives with up to eight meqabvtes on each drive. Thus, CP/m-80 and
	(7P/M-86 svstems may exchange files without modifying the file
	format.

	CP/M-86 resides in the file CPM.SYS, which is loaded into
	memory by a cold start loader during system initialization. The
	cold start loader resides on the first two tracks of the system
	disk. CPM.I;Yl; contains three program modul-es: the Console Command
	Processor (CCP), the Basic Disk Operating System (BOOS), and the
	user-conf iqurable Basic 1/0 System (BIOS) . The CCP and BDOS
	Portions occupy approximately 10K bytes, while the size of the BIOS
	varies with the implementation. The operating system executes in
	any portion of memory above the reserved interrupt locations, while
	the remainder of the address space is partitioned into as many as
	eight non-contiquous regions, as defined in a BIOS table. Unlike
	CP/M-80, the CCP area cannot be used as a data area subsequent to
	transient program load; all CP/M-86 modules remain in memory at all
	times, and are not reloaded at a warm start.

	Similar to CP/M-80, CP/M-86 loads and executes memory image
	files from disk. memory image files are Preceded by a "header
	record," defined in this document, which provides information
	required for proper Program loading and execution. Memorv.image
	files under CP/M-86 are identified by a "CMD" file type.

	Unlike CP/M-80, CP/M-86 does not use absolute locations for
	system entry or default variables. The BOOS entry takes Place
	through a reserved software interrupt, while entry to the BIOS is
	provided by a new BDOS call. Two variables maintained in low memory
	under CP/M-80, the default disk number and 1/0 Byte, are placed in
	the CCP and BIOS, respectively. nependence upon absolute addresses
	is minimized in CP/M-86 by maintaining initial "base Page" values,
	such as the default FCB and default command buffer, in the transient
	program data area.

	Utility proqrams such as ED, PIP, STAT and SUBMIT operate in
	the same manner under CP/M-86 and CP/M-80. In its operation, ODT-86
	resembles DDT suopl ied with CP/M-80. It allows interactive
	debugging of 8086 and 8088 machine code. Similarly, ASM-86 allows
	assembly language programminq and development for the 8086 and 8088
	using Intel-like mnemonics.

All Information Presented Here is Proorietarv to Digital Research
CP/M-86 System Guide	1.1		CP/M-86 General Characteristics

	The GENCMD (Generate CMD) utility replaces the LOAD program of
	CP/M-80, and converts the hex f iles produced by ASM-86 or Intel
	utilities into memory image format suitable for execution under
	CP/M-86. Further, the LDCOPY (Loader Copy) program replaces SYSGEN,
	and is used to copy the cold start loader from a system disk for
	replication. In addition, a variation of GENCMD, called TMCMD,
	converts output from the Intel LOC86 utility into CMD format.
	Finall.y, GENT)EF (Generate DISKDEF) is 6rovided as an aid in
	producing custom disk narameter tables. ASM-86, GENCMD, LMCMD, and
	GENDEF are also supplied in "COM" file format for cross-development
	under CP/M-80.

	Several terms used throughout this manual are defined in Table
	1-1 below:

Table 1-1. CP/M-86 Terms

Term	Meaning

'Nibble	4-bit half-byte
Bvte	8-bit value
Word	16-bit value
Double Word	32-bit value
Paragraph	16 contiguous bytes

Paragraph Boundary		An address divisible evenly
by 16 (low order nibble 0)

Segment	Up to 64K contiguous bytes
Segment Register	One of CS, DS, ES, or SS
Offset	16-bit displacement from a
	segment register
Group	A segment-register-relative
	relocatable program unit
Address	The effective memory address
	derived from the composition
	of a segment register value
	with an offset value

A group consists of segments that are loaded into memory as a single
unit. Since a group may consist of more than 64K bytes, it is the
responsibility ot the application program to manage segment
registers when code or data beyond the first 64K segment is
accessed.

All Information Presented Here is Proprietary to Digital Research

2
CP/M-86 System Guide		1.1	CP/M-86 General Characteristics

	CP/M-86 supoorts eight program groups: the code, data, stack
	and extra qroups as well as four auxil-iarv groups. When a code,
	data, stack or extra group is loaded, CP/M-86 sets the respective
	segment register (CS, DS, SS or ES) to the base of the group. CP/M
	86 can also load four auxiliarv qrouos. A transient Program manaqes
	the location of the auxili.arV qroups using values stored by CP/M-86
	in the user's base paqe.

1.2		CP/M-80 and CP/M-86 Differences

	The structure of CP/M-86 is as close to CP/m-80 as possible in
	order to Provide a familiar programming environment which allows
	application programs to be transoorted to the 8086 and 8088
	o rocessors with minimum effort. This section points out the
	specific differences between CP/M-80 and CP/M-86 in order to reduce
	your time in scanning this manual if you are al-readv familiar with
	CPI/M-80. The terms and concepts presented in this section are
	explained in detail- throuqhout this manual , so you wi 1.1 need to
	refer to the Table of Contents to find relevant sections which
	provide specific definitions and information.

	Due to the nature of the 8086 Processor, the fundamental
	difference between CP/M-90 and CP/M-86 is found in the management of
	the various relocatable qroups. Al-thouqh (P/M-80 references
	absolute memory locations by necessity, (P/~A-86 takes a,1vantaqe of
	the static relocation inherent in the 8086 orocessor. The ooeratinq
	system itself is usual.l.v loaded directly above the interrupt
	locations, at location 0400H, and relocatable transient proqram,-,
	load in the best fit memory region. However, you can load (-P/'A-96
	into any portion of memory without changinq the ooeratinq svstem
	(thus, there is no MOVCPM utility with r7P/114-86), and transient
	programs will load and run in any non-reserved reqion.

	Three qeneral memorv models are presented below, but if you are
	converting 8080 proqrams to CP/M-86, you can use either the 8080
	Model or Small. Model and leave the Compact model for later when your
	addressing needs increase. You'll use GENCMD, described in Section
	3.2, to Produce an executable program file from a hex file. rENCMr.)
	Parameters allow you to sQecify which memory model vour proqram
	requires.

	CP/M-86 itself is constructed as an 8080 Model. This means
	that all. the segment registers are Placed at the base of CP/M-86,
	and vour customized BIOS is iaenti-cal, in most resoects, to that of
	CP/M-80 (with changes in instruction mnemonics, of course). In
	fact, the only additions are found in the SETDMAB, GETSEGB, SETIOR,
	and GETIOB entrv Points in the 1310S. Your warm start subroutine is
	simpler since you are not required to reload the CCP and BDOS under
	CP/M-86. One other point: if you implement the IOBYTE facility,
	you'll have to define the variable in vour BIOS. Takinq these
	changes into account, you need only perform a simple translation of
	your CP/M-80 BIOS into 8086 code in order to implement your 8086
	BIOS.

All Information Presented Here is Proprietarv to Digital- Research

3
CP/M-86 System Guide	1.2		CP/M-80 and CP/M-86 Differences

	If you've implemented CP/M-80 Version 2, you already have disk
	definition tables which will operate properly with CP/M-86. You may
	wish to attach different disk drives, or experiment with sector skew
	factors to increase performance. If so, you can use the new GENDEF
	utility which performs the same function as the DISKDEF macro used
	by MAC under CP/M-80. You'll find, however, that GENDEF provides
	you with more information and checks error conditions better than
	the DISKDEF macro.

	Although generatinq a CP/M-86 system is qenerallv easier than
	generatinq a CP/M-80 system, complications arise if you are using
	single-densitv floppy disks. CP/M-86 is too large to fit in the
	two-track system area of a single-density disk, so the bootstrap
	operation must perform two steps to load CP/M-86: f irst the
	bootstrap must load the cold start loader, then the cold start
	loader loads CP/M-86 from a system file. The cold start loader
	includes a LDBIOS which is identical to your CP/M-86 BIOS with the
	exception of the INIT entry point. You can simplify the LDBIOS if
	you wish because the loader need not write to the disk. If you have
	a double-density disk or reserve enough tracks on a single-density
	disk, you can load CP/M-86 without a two-step boot.

	To make a BDOS system call, use the reserved software interrupt
	#244. The jump to the BDOS at location 0005 found in CP/M-80 is not
	present in CP/M-86. However, the address field at offset 0006 is
	present so that programs which "size" available memory using this
	word value will operate without change. CP/M-80 BDOS functions use
	certain 8080 registers for entry parameters and returned values.
	CP/M-86 BDOS functions use a table of correspondinq 8086 registers.
	For example, the 8086 registers CH and CL correspond to the 8080
	registers B and C. Look through the list of BDOS function numbers
	in Table 4-2. and you'll find that functions 0, 27, and 31 have
	changed slightly. Several new functions have been added, but they
	do not affect existing proqrams.

	One major philosophical difference is that in CP/M-80, all
	addresses sent to the BDOS are simply 16-bit values in the range
	OOOOH to OFFFFH. In CP/M-86, however, the addresses are really just
	16-bit offsets from the DS (Data Seqment) register which is set to
	the base of your data area. If you translate an existinq CP/M-80
	program to the CP/M-86 environment, your data seqment will be less
	than 64K bytes. In this case, the DS register need not be changed
	followinq initial load, and thus all CP/M-80 addresses become simple
	DS-relative offsets in CP/M-86.

	Under CP/M-80, programs terminate in one of three ways: by
	returning directly to the C-CP, by calling BOOS function 0, or by
	transferring control to absolute location OOOOH. CP/M-86, however,
	supports only the first two methods of program termination. rrh i s
	has the side effect of not providing the automatic disk system reset
	following the jump to 0000H which, instead, is accomplished by
	entering a CONTROL-C at the CCP level.

All Information Presented Here is Proprietary to Diqital Research

4
CP/M-86 System Guide		1.2	CP/M-80 and CP/M-86 r)ifferences

	You'll find many new facilities in CP/M-86 that will simol ify
	your Programming and expand your application Programming caPabilitv.
	But, we've designed CP/M-86 to make it easy to get started: in
	short, if you are converting from CP/M-80 to CP/M-86, there will be
	no major changes bevond the translation to 8086 machine code.
	Further, programs you design for CP/M-86 are uoward compatible with
	MP/M-86, our multitasking ooerating system, as well as (P/NET-86
	which provides a distributed operating system in a network
	environment.

All Information Presented Here is Proprietary to Digital Research

5
	Section 2
Command Setup and Execution Under CP/M-86

	This section discusses the operation of the Console Command
	Processor (('-CP), the format of transient aroqrams, (P/M-86 memory
	models, and memory image formats.

2.1		CCP Built-in and Transient Commands

	The ooeration of the CP/M-86 CCP is similar to that of CP/M-80.
	upon initial cold start, the CP/M sign-on message is printed, drive
	A is automatically logged in, and the standard prompt is issued at
	the console. CP/M-86 then waits for input command lines from the
	console, which mav include one of the built-in commands

DIR			ERA	REN	TYPF 	USER

(note that SAVE is not supported under CP/M-86 since the equivalent
function is performed by DDT-86).

	Alternatively, the command line mav begin with the name of a
	transient proqram with the assumed file type "CMT)" denoting a
	"command file." The CMO file type differentiates transient command
	files used under CP/M-86 from COM files which operate under (P/M-80.

	The CCP allows multiple programs to reside in memory, providing
	facilities for background tasks. A transient program such as a
	debugger may load additional programs for execution under its own
	control. Thus, for example, a background printer spooler could
	first be loaded, followed by an execution of DDT-86. DOT-86 may, in
	turn, load a test program for a debugging session and transfer
	control to the test program between breakpoints. CP/M-86 keeps
	account of the order in which proqrams are loaded and, uoon
	encountering a CONTROL-C, discontinues execution of the most recent
	program activated at the CCP level. A CONTROL-C at the DDT-86
	command level aborts. DDT-86 and its test program. A second CONTROL
	C at the CCP level aborts the backqround printer spooler. A third
	CONTROL-C resets the disk system. Note that proqram abort due to
	CONTROL-C does not reset the disk system, as is the case in CP/M-80.
	A disk reset does not occur unless the CONTROL-C occurs at the CCP
	command input level with no programs residing in memory.

	When CP/M-86 receives a request to load a transient proqram
	from the CCP or another transient program, it checks the program's
	memory requirements. If sufficient memorv is available, r-P/M-86
	assigns the required amount of memory to the program and loads the
	program. Once loaded, the program can request additional memory
	from the BDOS for buffer space. When the program is terminated,
	CP/M-86 frees both the program memory area and any additional buffer
	space.

All Information Presented Here is Proprietary to Digital Research

7
CP/M-86 System Guide	2.2	Transient Program Execution Models

2.2	Transient Program Execution Models

	The initial values of the segment reqisters are determined by
	one of three "memorv models" used by the transient Program, and
	described in the CMD file header. The three memorv models are
	summarized in Table 2-1 below.

Table 2-1. CP/M-86 Memory Models

Model	Group Relationships

8080 Model	Code and Data Groups Overlap

Small Model	Independent Code and Data Groups

Compact Model	Three or More Independent Groups

	The 8080 Model supports programs which are directly translated
	from CP/M-80 when code and data areas are intermixed. The 8080
	model consists of one group which contains all the code, data, and
	stack areas. Segment registers are initialized to the starting
	address of the region containing this group. The segment registers
	can, however , be managed by the avp! icat ion program dur i ng execut ion
	so that multiple segments within the code group can be addressed.

	The Small Model is similar to that defined by Intel, where the
	program consists of an independent code group and a data group. The
	Small Model is suitable for use by programs taken from CP/M-80 where
	code and data is easily separated. Note again that the code and
	data groups often consist of, but are not restricted to, single 64K
	byte segments.

	The Compact Model occurs when any of the extra, stack, or
	auxiliary groups are present in program. Each group may consist of
	one or more segments, but if any group exceeds one segment in size,
	or if auxiliary groups are present, then the application program
	must manage its own segment registers during execution in order to
	address all code and data areas.

	The three. models differ primarily in the manner in which
	segment registers are initialized upon transient proqram loading.
	The operating system program load function determines the memory
	model used by a transient Program by examining the program group
	usage, as described in the following sections.

All Information Presented Here is Proprietary to Digital Research

8
CP/M-86-System Guide	2.3		The 8080 Memory Model

2.3		The 8080 Memory Model

	The 8080 Model is assumed when the transient program contains
	only a code group. In this case, the CS, DS, and ES reqisters are
	initialized to the beginning of the code group, while the SS and SP
	registers remain set to a 96-byte stack area in the CCP. The
	Instruction Pointer Register (IP) is set to 100H, similar to CP/M
	80, thus allowing base page values at the beginning of the code
	group. Following program load, the 8080 Model appears as shown in
	Pigure 2-1, where low addresses are shown at the top of the diaqram:

SS:
	CCP

	SS + SP:			CCP Stack
	CS DS ES:
	DS+OOOOH:			base
			oaqe

CS+0100H:			IP	= 0100H
		code
		data
		code
		data

Figure 2-1.CP/M-86 8080 Memory Model

The intermixed code and data regions are indistinguishable. The
"base page" values, described below, are identical to CP/M-80,
allowing simple translation from 8080, 8085, or Z80 code into the
8086 and 8088 environment. The following ASM-86 example shows how
to code an 8080 model transient program.

	eseg
	org		100h
		(code)
endcs		equ	$
	dseg
	org		offset endcs

	(data)
end

All Information Presented Here		is Proprietary to nigital Research
	9
CP/M-86 System Guide	2.4	The Small Memory Model

2.4	The Small Memory Model

	The Small Model is assumed when the transient program contains
	both a code and data group. (In ASM-86, all code is generated
	following a CSEG directive, while data is defined followinq a DSEG
	directive with the origin of the data segment independent of the
	code segment.) In this model, CS is set to the beqinninq of the
	code group, the DS and ES are set to the start of the data group,
	and the SS and SP registers remain in the CCP's stack area as shown
	in Figure 2-2.

CCP

SS + SP:	CCP Stack

CS:	IP = OOOOH
	code

	DS ES:			base
			page
	T)S+0 10 OH:
		I	data

Figure 2-2. CP/14-86 Small Memory Model

The machine code begins at C'3+OOOOH, the "base page" values beqin at
DS+OOOOH, and the data area starts at DS+0100H. The followinq ASM
86 example shows how to code a small model transient r)rogram.

cseg
	(code)
dseq
org	100h

	(lata)
	end

All Information Presented Here is Proprietary to Digital Research

10
CP/M-86 System Guide	2.5		The Compact Memorv Model

2.5		The Compact Memory Model

	The Compact Model is assumed when code and data groups are
	present, along with one or more of the remaining stack, extra, or
	auxiliary groups. In this case, the CS, DS, and ES registers are
	set to the base addresses of their respective areas. Figure 2-3
	shows the initial. configuration of segment registers in the ComPact
	Model. The values of the various segment registers can be
	Programmatically changed durinq execution by loading from the
	initial values Placed in base Page by the CCP, thus allowing access
	to the entire memory space.

	If the transient program intends to use the stack group as a
	stack area, the SS and SP registers must be set upon entrv. The SS
	and SP registers remain in the CCP area, even if a stack group is
	defined. Although it may appear that the SS and SP registers should
	be set to address the stack group, there are two contradictions.
	First, the transient program mav be using the stack qroup as a aata
	area. In that case, the Far Call instruction used by the CCP to
	transfer control to the transient program could overwrite (iata in
	the stack area. Second, the SS register would loqicall-v be set to
	the base of the group, while the SP would be set to the offset of
	the end of the group. However, if the stack group exceeds 64K the
	address range from the base to the end of the group exceeds a 16-bit
	offset value.

	The following ASM-86 example shows how to code a compact model
	transient program.

cseg

	(code)
dseq
orq 		100h

	(data)
	eseq

	(more data)
	sseg

	(stack area)
	end

All Information Presented Here is ProDrietary to Digital Research

11
CP/M-86 Svstem Guide	2.5	The ComDact Memory model

SS:
CCP

SS + SP:		CCP Stack

CS:		IP = OOOOH
	code

	DS:		base
		page
DS+0100H:
		data
	ES:
		data

Figure 2-3. CP/N-86 Compact memory Model

All Information Presented Here is Proprietary to Digital Research

12
CP/M-86 System Guide	2.6		Base Page Initialization

2.6		Base Page Initialization

	Similar to CP/M-80, the CP/M-86 base page contains default
	values and locations initialized by the CCP and used by the
	transient orogram. The base paqe occupies the regions from offset
	OOOOH through OOFFH relative to the DS reqister. The values in the
	base page for CP/M-86 include those of CP/M-80, and appear in the
	same relative oositions, as shown in Figure 2-4.

OS + 0000:

T)S + 0 0 0 3 :

DS + 0006:

DS + 0009:

DS + OOOC:

DS + OOOF:

DS + 0012:

DS + 0015:

OS + 0018:

T)S + 001B:

DS + 001E:

DS + 0021:

DS + 0024:

DS + 0027:

T)S + 002A:

DS + 002D:

DS			+	0030:		Not
. . .							Currently
DS			+	005B:		Used
DS			+	005C:		Default FCB
DS			+	0080:		Default Buffer
DS			+	0100:		Begin User Data

Figure 2-4. CP/14-86 Base Page Values

All Information Presented Here is Proiorietarv to Digital Research

13

LCO			LC1	LC2
BCO			BC1	M80
LDO			LDI	LD2
BDO			BDl	xxx
LEO			LE1	LE2
BEO			BE1	xxx
LSO			LS1	L13 2
BSO			BSI	xxx
LXO			LX1	LX2
BXO			BX1	xxx
LXO			LX1	LX2
BXO			BX1	xxx
LXO			LX1	LX2
BXO			BX1	xxx
LXO			LXI	LX2
BXO			BX1	xxx
rP,'M-86 System Guide	2.6		Rase Page Initialization

Each byte is indexed by 0, 1, and 2, corresponding to the standard
Intel storage convention of low, middle, and high-order (most
siqnificant) byte. "xxx" in Figure 2-4 marks unused bytes. TC is
the last code group location (24-bits, where the 4 high-order bits
equal zero).

	In the 8080 model , the low order byte,; of LC (LCO anrl LC1)
	never exceed OFFFFH and the high order byte (L(72) is always zero.
	BC is base naraaraph address of the code group (16-bits). LD and BT)
	provide the last oosition and paragraph base of the data group. The
	last Dosition is one byte less than the group length. Tt should be
	noted that bytes TDO and TDl appear in the same relative uositions
	of the base page in both CP/M-80 and CP/M-86, thus easing the
	program translation task. The M80 byte is equal to I when the 8080
	Memory Model is in use. LE and BE lDrovirle the length and paragraph
	base of the optional extra group, while U', and BS give the optional
	stack group length and base. The bytes marked TX and RX corresoond
	to a set of four optional indeoendent groups which may he required
	for Proqrams which execute using the CornTDact Memorv Model . The
	initial values for these descriptors are derived from the header
	record in the memory image file, descrihed in the foTlowinq section.

2.7		Transient Program Load and Exit

	Similar to CP/M-80, the CCP parses up to two f iTenames
	f ol lowing the command and ol aces the r)ror)erl-y f ormatte(I FCB's -at
	locations 005CH and 006CH in the base page relative to the r)c;
	register. Tinder (P/M-80, the default DMA address is initialized to
	0080H in the base page. T)ue to the segmented memory of the 8G86 anrl
	8088 lDrocessors, the OMA address is divided into two narts: the T)MA
	segment address and the T)MA offset. Therefore, under (7P/M-R6, the
	default T)MA base is initialized to the value of DS, and the default
	DMA of f set is initial ized to 008014. Thus, r7P/M-80 and rP/T,1-86
	operate in the same way: both assume the default T)MA buffer
	occuiDies the second half of the base page.

	The CCP transfers control to the transient oroqram through an
	8086 "Far Cal-I." The transient Qroqram may choose to use the 96-bvte
	CCP stack and optionally return directly to the ((,P upon program
	termination by executing a "Far Return." Program termination also
	occurs when BDOS function zero is executed. Note that function zero
	can terminate a program without removing the r)roqram from memory or
	changing the memory allocation state (see Section 4.2) . The
	operator may terminate program execution by tvpinq a sinql-e CONTROL
	C during line edited input which has the same effect as the oroqram
	executing BDOS function zero. TJnlike the operation of r.P/M-80, no
	disk reset occurs and the CCP and T3DOS modules are not reloaded from
	disk upon program termination.

All Information Presented Here is Proprietary to Digital Research
	Section 3
Command (CMD) File Generation

	As mentioned previously, two utility programs are provided with
	CP/M-86, called GENCMD and LMCMD, which are used to produce CMD
	memory image files suitable for execution under CP/M-86. GENCMD
	accepts Intel 8086 "hex" format files as input, while LMCMD reads
	Intel L-module files output from the standard Tntel LOC-86 object
	Code Locator utility. GENCMT) is used to process output from the
	Digital Research ASM-86 assembler and Intel's OH86 utility, while
	LMCMD is used when Intel compatible developmental software is
	available for generation of programs targeted for CP/M-86 operation.

3.1		Intel 8086 Hex File Format

	GENCMD i~out is in Intel "hex" format produced by both the
	Digital Research ASM-86 assembler and the standard Intel OH96
	utility program (see Intel document #9800639-03 entitled "MCS-86
	Software Development Utitities Operating Instructions for ISIS-II
	Users"). The CMD file produced by GENCMD contains a header record
	which defines the memory model and memory size requirements for
	loading and executing the CMD file.

	An Intel "hex" file consists of the traditional sequence of
	ASCII records in the following format:

1 :1 lJlJaJaJaJaJtJtJdJdJdJ 		F Mcc

where the beginning of the record is marked by an ASCII colon, and
each subsequent digit position contains an ASCII hexadecimal digit
in the range 0-9 or A-F. The fields are defined in Table 3-1.

All Information Presented Here is Proorietarv to Digital. Research

15
CP/M-86 System Guide	3.1		Intel Hex File Format

Table 3-1. Intel Hex Field Definitions

Field	Contents

11	Record Length 00-FF (0-255 in decimal)
aaaa	Load Address
	t	Record Type:
		00 data record, loaded starting at offset
			aaaa from current base paragraph
		01 end of file, cc = FF
		02 extended address, aaaa is paragraph
			base for subsequent data records
		03 start address is aaaa (ignored, IP set
			according to memory model in use)
		The following are output from ASM-86 only:
		81 same as 00, data belongs to code segment
		82 same as 00, data belongs to data segment
		83 same as 00, data belongs to stack segment
		84 same as 00, data beionqs to extra segment
		85 paragraph address for absolute code segment
		86 paragraph address for absolute data segment
		87 paragraph address for absolute stack segment
		88 paragraph address for absolute extra segment
		Data Byte
cc	Check Sum (00 - Sum of Previous Digits)

All characters preceding the colon for each record are ignored.
(Additional hex file format information is included in the ASM-86
User's Guide, and in Intel's document #9800821A entitled "MCS-86
Absolute Object File Formats.")

3.2 Operation of GENCND
	The GENCMD utility is invoked at the CCP level by typing
		GENCMD filename parameter-list

where the filename corresponds to the hex input file with an assumed
(and unspecified) file type of H86. GENCMD accepts optional
parameters to specifically identify the 8080 Memory Model and to
describe memory requirements of each segment group. The GENCMD
parameters are listed following the filename, as shown in the
command line above where the parameter-l-ist consists of a sequence
of keywords and values separated by commas or blanks. The keywords
are:

8080		CODE	DATA EXTRA	STACK	X1	X2	X3 	X4

All Information Presented Here		is Proprietary to Digital Research
	16
CP/M-86 System Guide	3.2		operation of GENCMD

The 8080 keyword forces a single code qroup so that the BDOS load
function sets up the 8080 memory Model for execution, thus al-lowinq
intermixed code and data within a sinql-e seqment. The form of this
command is

r,ENCMD	filename 8080

The remaining keywords follow the filename or the 8080 option and
define soecif ic memory requirements for each seqment group,
corresponding one-to-one with the segment qrouos defined in the
previous section. In each case, the values corresponding to each
group are enclosed i.n square brackets and separated by commas. Fach
value is a hexadecimal number reoresentinq a paragraph address or
segment length in oaraqraph units aenoted by hhhh, prefixed by a
sinql-e letter which defines the meaninq of each value:

Ahhhh		Load the group at absolute location hhhh
Bhhhh		The group starts at hhhh in the hex file
Mhhhh		The group requires a minimum of hhhh * 16 bytes
Xhhhh		The group ca~n address a maximum of hhhh * 16 bvtes

Generally, the CMD file header values are derived directly from the
hex file and the Parameters shown above need not be included. The
following situations, however, require the use of GENCMD parameters.

		The 8080 keyword is included whenever ASM-86 is used in
the conversion of 8080 proqrams to the 8086/8088
environment when code and data are intermixed within a
sinqle 64K seqment, reqardless of the use of C,13F(, and
DSEG directives in the source proqram.

		An absolute address (A value) must be given for any group
which must be located at an absolute location. Normally,
this value is not soecif ied since CP/M-86 cannot
generally ensure that the required memory reqion is
available, in which case the CMD file cannot be loaded.

		The B value is used when GENCMD Processes a hex file
produced by Intel's OH86, or similar utility proqram that
contains more than one group. The output from OH86
consists of a sequence of data records with no
information to identify code, data, extra, stack, or
auxiliary groups. In this case, the B value marks the
beginninq address of the group named by the keyword,
causing GENCMD to load data following this address to the
named group (see the examples below). Thus, the B value
is normally used to mark the boundary between code and
data seqments when no seqment information is included in
the hex file. Files produced by ASM-86 do not require
the use of the B value since segment information is
included in the hex file.

All Information Presented Here is Proprietary to Digital Research

17
CP/M-86 System Guide	3.2		Operation of (,EN('Mn

		The minimum memory value (M value) is included only when
the hex records do not def ine the minimum memorv
requirements for the named group. Generally, the code
group size is determinel precisely by the data records
loaded into the area. That is, the total space required
for the group is defined by the range between the lowest
and highest data byte addresses. The data group,
however, may contain uninitialized storage at the end of
the group and thus no data records are present in the hex
file which define the highest referenced data item. The
highest address in the data group can be defined within
the source program by including a "T)B 011 as the I-ast data
item. Alternatively, the M value can be included to
allocate the additional space at the end of the group.
Similarly, the stack, extra, and auxiliarv group sizes
must be defined using the M value unless the highest
addresses within the groups are implicitly defined by
data records in the hex file.

		The maximum memory size, given by the X value, is
generally used when additional free memory may be needed
for such purposes as 1/0 buffers or svmbol tables. If
the data area size is fixed, then the X parameter need
not be included. In this case, the X value is assumed to
be the same as the M value. The value XFFPF allocates
the largest memory region available but, if used, the
transient program must be aware that a three-byte l.enqth
field is produced in the base page for this group where
the high order byte mav be non-zero. Programs converted
directly from CP/M-80 or programs that use a 2-byte
pointer to address buffers should restrict this value to
XFFF or less, producing a maximum allocation length of
OFFFOH bytes.

	The following GENCMD commahd line transforms the fil-e X.R86
	into the file X.CMD with the proper header record:

gencmd x codefa401 datafm30,xfff]

In this case, the code group is forced to paragraph address 40H, or
equivalently, byte address 400H. The data group requires a minimum
of 300H bytes, but can use up to OPFFOH bytes, if available.

All Information Presented Here is Proprietary to nigital Research

18
CP/M-86 System Guide	3.2		operation of GENCMD

	Assuming a file Y.H86 exists on drive 1B containing Intel hex
	records with no intersiDersed segment information, the command

gencmd b:v data[b30,m201 extra[b501 stack[m401 x1[m40l

produces the fil-e Y.(MD on drive B bv selectinq records beginning
at address OOOOH for the code segment, with records starting at
300H allocated to the data segment. The extra seqment is filled
from records beginning at 500H, while the stack and auxiliarv
segment #1 are uninitialized areas requirinq a minimum of 400H
bytes each. In this example, the data area reciuires a minimum of
200H bytes. Note aqain, that the B value need not be incluOed if
the Digital Research ASM-86 assembler is used.

3.3		Operation of LMCMD

	The LMCMD utility ocerates in exactly the same manner as
GENCMD, with the exception that LMCMD accepts an Intel L-module
file as input / . The orimarv advantage of the L-module format is
that the file contains internall.v coded information which defines
values which would otherwise be required as Parameters to r7FNCMr),
such the beginning address of the qroup's data segment. (7-urrent'v,
however, the only lanquage processor-, which use this Format are the
standard Intel, development oackaqes, although various in3e0endent
vendors will, most likely, take advantage of this Format in the
f uture .

All Information Presented Here is Proprietary to niqital Research

19
CP/M-86 System Guide	3.4	Command (CMD) File Format

3.4	Command (CMD) File Format

	The CMD file produced by GENCMD and LMCMD consists of the
	128-byte header record followed immediately by the memory image.
	Under normal circumstances, the format of the header record is of
	no consequence to a programmer. For completeness, however, the
	various fields of this record are shown in Figure 3-1.

1	1

GD# 1 [GD# 72GD# 3 1 GD# 4 JGD# 5-GD# 8 . . .

Code,
	Data,
		Extra,
		Stack,
		Auxiliary

Figure 3-1. CMD File Header Format

In Figure 3-1, GD#2 through GD#8 represent "Group Descriptors."
Each Group Descriptor corresponds to an independently loaded
program unit and has the following fields:

8-bit	16-bit	16-bit	16-bit	16-bit

I G-Form G-Length	A-Base	G-Min	G-Max
I	I	I	-_ I	- - I

where G-Form describes the group format, or has the value zero if
no more descriptors follow. If G-Form is non-zero, then the 8-bit
value is parsed as two fields:

	G-Form:
4-bit 	4-bit
x x x x I G-Typel

The G-Type field determines the Group Descriptor type. The valid
Group Descriptors have a G-Type in the range 1 through 9, as shown
in Table 3-2 below.

All Information Presented Here is Proprietary to Digital Research

20
CP/M-86 System Guide	3.4		Command (CMD) File Format

Table 3-2. Group Descriptors
G-Type		I	Group Type

	1	Code Group
	2	Data Group
	3	Extra Group
	4	Stack Grour)
	5	Auxiliary Group #1
	6	Auxiliary Group #2
	7	Auxiliary Group #3
	8	Auxiliary Group #4
	9	Shared Code rroup
	10 - 14		unused, but Reserved
	15	Escape Code for Additional Types
L

	All remaining values in the group descriotor are given in
	increments of 16-byte Paragraph units with an assumed low-order 0
	nibbl(~ to complete the 20-bit address. G-Length gives the number
	of paragraphs in the group. Given a G-length of 0080H, for
	example, the size of the grouD is 00800H = 2048D bytes. A-Base
	defines the base paragraph address for a non-relocatable group
	while G-Min and G-Max define the minimum and maximum size of the
	memory area to allocate to the group. G-Type 9 marks a "pure" code
	group for use under MP/M-86 and future versions of CP/M-86.
	Presently a Shared Ccde Group is treated as a non-shared Program
	Code Group under (P/M-86.

	The memory model described by a header record is implicitly
	determined bv the Group Descriptors. The 8080 Memory Model is
	assumed when only a code group is present, since no independent
	data group is named. The Small Model is implied when both a code
	and data group are present, but no additional group descriptors
	occur. Otherwise, the Compact Model is assumed when the CMD file
	is loaded.

All Information Presented Here is Proprietary to Digital Research

21
	Section 4
Basic Disk Operating System Functions

	This section presents the interface conventions which allow
	transient program access to CP/M-86 BDOS and BIOS functions. The
	BDOS calls correspond closely to CP/M-80 Version 2 in order to
	simplify translation of existing CP/M-80 programs for operation
	under CP/M-86. BDOS entry and exit conditions are described first,
	followed by a presentation of the individual 9DOS function calls.

4.1		BDOS Parameters and Function Codes

	Entry to the BOOS is accomplished through the 8086 software
	interrupt #224, which is reserved by Intel Corporation for use by
	CP/M-86 and MP/M-86. The function code is Passed in register CL
	with byte parameters in DL and word parameters in DX. Single byte
	values are returned in AL, word values in both AX and BX, and double
	word values in ES and BX. All segment registers, except ES, are
	saved upon entry and restored upon exit from the BDOS (corresponding
	to PL/M-86 conventions). Table 4-1 summarizes input and output
	parameter passing:

Table 4-1. BDOS Parameter Summary

BDOS Entry Registers	BDOS Return Registers

CL		Function Code	Bvte value returned in AL
DL		Byte Parameter	word value returned in both AX and BX
DX		Word Parameter	Double-word value returned with
DS		Data Segment	offset in BX and
			segment in ES

Note that the CP/M-80 BDOS requires an "information address" as
input to various functions. This address usually provides buffer or
File Control Block information used in the system call. In CP/M-86,
however, the information address is derived from the current DS
register combined with the offset given in the DX register. That
is, the DX register in CP/K-86 performs the same function as the DE
pair in CP/M-80, with the assumption that DS is properly set. This
poses no particular problem for programs which use only a single
data segment (as is the case for programs converted from CP/M-80),
but when the data group exceeds a single segment, you must ensure
that the DS register is set to the segment containing the data area
related to the call. It should also be noted that zero values are
returned for function calls which are out-of-range.

All Information Presented Here is Proprietary to Digital Research

23
CP/M-86 System Guide	4.1	BDOS Parameters and Function Codes

	A list of CP/M-86 calls is given in Table 4-2 with an asterisk
	followinq functions which differ from or are added to the set of
	CP/M-80 Version 2 functions.

Table 4-2. CP/M-86 BDOS Functions

F#		I Result	F# 	I Resul t
0*		System Reset	24	Return Loqin Vector
	1	Console Input	25	Return Current Disk
	2	Console Output	26	Set DMA Address
	3	Reader Input	27*		Get Addr(All-oc)
	4	Punch Outnut	28	Write Protect Disk
	5	List Outout	29	Get Aldr(R/0 Vector)
6*		Direct Console 1/0	30	Set Pile Attributes
	7	Get 1/0 Byte	31*		Get Addr(Disk Parms)
	8	Set 1/0 Byte	32	Set/Get User rode
	9	Print String	33	Read Random
	10	Read Console Buffer	34	Write Random
11	Get Console Status	35	Compute File Size
	12	Return Version Number	36	Set Random Record
	13	Reset Disk System	37*		Reset drive
	14	Select Disk	40	Write Random with Zero Fill
	15	Ooen File	50*		Direct BIOS Call.
	16	close File	51*		Set DMA Seqment Base
	17	Search for First	52*		Get DMA Seqment Base
	18	Search for Next	53*		Get Max Memory Avail-able
	19	Delete File	54*		Get Max mem at Abs Location
	20	Read Sequential	55*		Get Memorv Reqion
21	Write Sequential	56*		Get Absolute Memory Region
	22	Make File	57*		Free memorv reqion
	23	Rename File	58*		Free all memory
			59*		Program load

	The individual BDOS functions are described below in three
	sections which cover the simple functions, f ile operations, and
	extended operations for memorv management and program loading.

All Information Presented Here is Proprietary to Digital Research

24
CP/M-86 System Guide	4.2		Simple BOOS r7alls

4.2		Simple BDOS Calls

	The first set of BOOS functions cover the range 0 through 12,
	and perform simple functions such as system reset and single
	character 1/0.

Entrv			eturn
CL: 00H	FUNCTION 		0
DL: Abort		IN	SYSTEM RESET
	Code

	The system reset function returns control to the CPIM operating
	system at the CCP command level. The abort code in DL has two
	possible values: if DL = OOH then the currently active program is
	terminated and control is returned to the CCP. If DL is a 01H, the
	program remains in memory and the memory/allocation state remains
	unchanged.

Entry 	Return

CL: 01H	FUNCTION		1	AL: ASCII Character

CONSOLE INPUT

	The console input function reads the next character from the
	logical console device (CONSOLE) to reqister AL. Graphic
	characters, along with carriage return, line feed, and backspace
	(CONTROL-H) are echoed to the console. Tab characters (CONTROL-I)
	are expanded in columns of eight characters. The BOOS does not
	return to the calling program until a character has been typed, thus
	suspending execution if a character is not ready.

Entry	Return

CL: 02H	FUNCTION 		2

DL:		ASCII	CONSOLE OUTPUT
	Character

	The ASCII character from OL is sent to the logical console.
	Tab characters expand in columns of eight characters. In addition,
	a check is made for start/stop scroll (CONTROL-S).

All Information Presented Here is Proprietary to Digital, Research

25
CP/M-86 System Guide	4.2			Simple BDOS Calls
	Entry		Return
	CL: 03H	FUNCTION 3		AL: ASCII Character

READER INPUT I

	The Reader Input function reads the next character from the
	logical reader (READER) into register hL. Control does not return
	until the character has been read.

Entry	Return

CL: 04H	FUNCTION 		4

DL:		ASCII	PUNCH OUTPUT
	Character 		I

	The Punch OutDut function sends the character from register DL
	to the logical punch device (PUNCH).

Entry	Return

CL: 05H	FUNCTION 		5

DL:		ASCII	LIST OUTPUT
	Character

	The List Output function sends the ASCII character in register
	DL to the logical list device (LIST).

All Information Presented Here is Proprietary to Digital Research

26
CP/M-86 System Guide	4.2			Simple BDOS Calls
	Entry		Return
	CL: 06H	FUNCTION 6			AL: char or status

DL: OFFH (input) N DIRECT CONSOLE 1/0		(no value)
	or
	OFEH		(status)
	or
	char 		(output)

	Oirect console 1/0 is supported under CP/M-86 for those
	specialized applications where unadorned console input and output is
	required. Use of this function should, in general, be avoided since
	it bypasses all of CP/M-Ws normal control character functions
	(e.g., CONTROL-S and CONTROL-P) . Programs which perform direct 1/0
	through the BIOS under previous releases of CP/M-80, however, should
	be changed to use direct 1/0 under the BOOS so that they can be
	fully supported under future releases of MP/M and CP/M.

	Upon entry to function 6, register OL either contains (1) a
	hexadecimal FF, denoting a CONSOLE input request, or (2) a
	hexadecimal FE, denoting a CONSOLE status request, or (3) an ASCII
	character to be output to CONSOLE where CONSOLE is the logical
	console device. If the input value is FF, then function 6 directly
	calls the BIOS console input primitive. The next console input
	character is returned in AL. If the input value is FE, then function
	6 returns AL = 00 if no character is ready and AL = FF otherwise.
	If the input value in DL is not FE or FF, then function 6 assumes
	that DL contains a valid ASCII character which is sent to the
	console.

Entry 	Return

CL: 07H	FUNCTION		7	AL: 1/0 Byte Value

GET 1/0 BYTE

	The Get 1/0 Byte function returns the current value of IOBYTE
	in register AL. The IOBYTE contains the current assignments for the
	logical devices CONSOLE, READER, PUNCH, and LIST provided the IOBYTE
	facility is implemented in the BIOS.

All Information Presented Here is Proprietary to Digital Research

27
CP/M-86 System Guide	4.2			Simple 1RDOS Calls
	Entry		Return

CL: 08H	FUNCTION 		8

	DL: 1/0 Byte	SET 1/0 BYTE
	Value

	The Set 1/0 Byte function changes the svstem IOBYTF value to
	that given in register T)L. This function allows transient proqram
	access to the IOBYTE in order to modify the current assiqnments for
	the logical devices CONSOLE, READER, PUNCH, and LIST.

Entry	N	%, 	Return

CL: 09H	FUNCTION 		9

	DX: String		Is	PRINT STRING
	Offset

	The Print String function sends the character strinq stored in
	memory at the location given by DX to the loqical console device
	(CONSOLE) , until a "$" is encountered in the strinq. Tabs are
	expanded as in function 2, and checks are made for start/stop scroll
	and printer echo.

Entry	Return
CL: 04H	FUNCTION 10	Console Characters

	DX: Buffer	READ CONSOLE BUFFER		in Buffer
	offset

All Information Presented Here is Proprietarv to Digital Research

28
CP/M-86 System Guide	4.2		Simol,e 900S Cal-Is

The Read Buffer function reads a line of edited console inaut into a
buffer addressed bv register r)X from the 1-oqical console device
(CONSOLE) . Console input is terminated when either the input buffer
is filled or when a return (CONTROL-M) or a line feed (C-ONTRnL-J)
character is entered. The inout buffer addressed by DX takes the
form:

T)X: +0 +1 +2 +3 +4 +5 +6 +7 +8 . . . 		+n
I mx I nc I cl I c2 I c3 I c4 1 C5 1 C6 1 c7	? -) I

where "mx" is the maximum number of characters which the buffer will
hold, and "nc" is the number of characters placed in the buffer.
The characters entered by the ooerator follow the "nc" value. The
value "mx" must be set prior to making a function 10 call and Mav
range in value from I to 255. Settinq mx to zero is eauivalent to
setting mx to one. The value "nc" is returned to the user and may
range from 0 to mx. If nc < mx, then uninitialized oositions foll-ow
the last character, denoted bv /	in the above figure. Note that
a terminating return or line feed character is not olaced in the
buffer and not included in the count "nc".

	A number of editing control functions are supported durinq
	console input under function 10. These are summarized in Table 4-3.

Table 4-3. Line Editing Controls

Kevstroke 	Result

rub/del		removes and echoes the last character
CONTROL-C		reboots when at the beginning of line
CONTROL-E		causes physical end of line
CONTROL-H		backspaces one character position
CONTROL-J		(line feed) terminates input line
CONTROL-M		(return) terminates input line
CONTROL-R		retvpes the current line after new line
CONTROL-U		removes current line after new line
CONTROL-X		backspaces to beqinning of current line

Certain functions which return the carriage to the leftMOSt position
(e.g. , CONTROL-X) do so only to the column position where the prompt
ended. This convention makes operator data input and line
correction more legible.

All Information Presented Here is Proprietary to Diqital Research

29
CP/M-86 System Guide	4.2			Simple T3T)Oq Calls
	P,ntrv		Return
	rL: 09H	FTINCTTON 11	AL: Console Status

GET CONSOLE STATUS

	The Console Status function checks to see if a character has
	been typed at the logical console device (COMS OLE) if a character
	is readv, the value 01H is returned in register AL. Otherwise a OOH
	value is returned.

Entrv	Return
CL: OC9	FUNCTION 12	BX: Versior~Number

RPTURN VERSION NUMBER
1%

	Function 12 provides information which allows version
	independent programming. A two-bvte value is returned, with BH = 00
	designatinq the CP/M release (BF = 01 for MP/M) , and BL = 00 for all
	releases previous to 2.0. CP/M 2.0 returns a hexadecimal 20 in
	register BL, with subsequent version 2 releases in the hexadecimal
	range 21, 22, through 2F. To provide version number compatibility,
	the initial release of CP/M-86 returns a 2.2.

4.3		BDOS File Operations

	Functions 12 through 52 are related to disk f ile operations
	under rP/M-86. In many of these operations, DX provides the T)S
	r elat ive of f set to a f i le control block (FCB) . The File Control
	T31-ock (FCT3) data area consists of a sequence of 33 bytes for
	sequential. access, or a sequence of 36 bytes in the case that the
	file is accessed randomlv. The default file control block normally
	located at offset 005CH from the DS register can be used for random
	access files, since bytes 007T)H, 007EH, and 007FH are available for
	this ouroose. Here is the FCB format, followed by definitions of
	each of its fields:

All Information Presented Here is Proprietary to Digital Research

30
CP/M-86 System Guide	4.3		BDOS File Operations

[dr I fl If2j/ /I f8 I ti I t2 I t31ex1sl1s21rc1d0 I/ /I dn I cr I rO I rljr2j

	00 01 02 ... 08 09 10 11 12 13 14 15 16 ... 31 32 33 34 35
	where

dr	drive code (0 - 16)
	0 => use default drive for file
	1 => auto disk select drive A,
	2 => auto disk select drive B,
	i~=*> auto disk select drive P.
fl f8		contain the file name in ASCII
	upper case, with high bit = 0

tl,t2,t3		contain the file type in ASCII
	upper case, with high bit = 0
	tl', tV, and t3/' denote the high
	bit of these positions,
	tl' = 1 => Read/Only file,
	t2' = 1 => SYS file, no DIR list

ex	contains the current extent number,
	normally set to 00 by the user, but
	in range 0 - 31 durinq file 1/0
	reserved for internal system use
	reserved for internal system use, set
	to zero on call to OPEN, MAKE, SEARCH
	record count for extent "ex,"
	takes on values from 0 - 128

dO ... dn		filled-in by CP/M, reserved for
system use

cr	current record to read or write in
a sequential file operation, normally
set to zero by user

rO,rl,r2		optional random record number in the
range 0-65535, with overflow to r2,
rO,rl constitute a 16-bit value with
low byte rO, and high byte rl

	For users of earlier versions of CP/M, it should be noted in
	passing that both CP/M Version 2 and CP/M-86 perform directory
	operations in a reserved area of memory that does not affect write
	buffer content, except in the case of Search and Search Next where
	the directory record is copied to the current DMA address.

All Information Presented Here		is Proprietary to Digital Research
	31
CP/M-86 System Guide	4.3		BDOS File Operations

There are three error situations that the BDOS may encounter durinq
file processing, initiated as a result of a BT)OS_ File 1/0 function
call. When one of these conditions is detected, the BDOS issues the
following message to the console:

BDOS ERR ON x: error

where x is the drive name of the drive selected when the error
condition is detected, and "error" is one of the three messages:

BAD SECTOR	SELECT	R/O

These error situations are trapped by the BDOS, and thus the
executing transient program is temporarily halted when the error is
detected. No indication of the error situation is returned to the
transient t)roqram.

	The "BAD SECTOR" error is issued as the result of an error
	condition returned to the BDOS from the BIOS module. The BOOS makes
	BIOS sector read and write commands as part of the execution of BDOS
	f ile related system calls. If the BIOS read or write routine
	detects a hardware error, it returns an error code to the BOOS
	resulting in this error message. The operator may respond to this
	error in two ways: a CONTROL-C terminates the executing programy
	while a RETURN instructs CP/M-86 to ignore the error and allow the
	program to continue execution.

	The "SELECT" error is also issued as the result of an error
	condition returned to the BDOS from the BIOS module. The BY)OS makes
	a BIOS disk select call prior to issuing any BIOS read or write to a
	particular drive. if the selected drive is not supported in-the
	BIOS module, it returns an error code to the BDOS resulting in this
	error message. r-P/M-86 terminates the currently running program and
	returns to the command level of the CCP following any input from the
	console.

	The "R/O" message occurs when the BDOS receives a command to
	write to a drive that is in read-only status. Drives may be placed
	in read-only status explicitly as the result of a STAT command or
	BDOS function call, or implicitly if the BDOS detects that disk
	media has been changed without performing a "warm start." The
	ability to detect changed media is optionally included in the BIOS,
	and exists only if a checksum vector is included for the selected
	drive. Upon entry of any character at the keyboard, the transient
	program is aborted, and control returns to the CCP.

All Information Presented Here is Proprietary to Digital Research

32
CP/M-86 System Guide	4.3			BDOS File Operations
	Entry			Return
	CL: ODH	FUNCTION 13

RESET DISK SYSTEM

	The Reset Disk Function is used to programmatically restore the
file system to a reset state where all disks are set to read/write
(see functions 28 and 29) , only disk drive A is selected. This
function can be used, for examT * )le, by an application program which
requires disk changes during operation. Function 37 (Reset Drive)
can also be used for this purpose.

Entry	Return

CL: OEH	FUNCTION 14

	DL: Selected		SELECT DISK
	Disk

	The Select Disk function designates the disk drive named in
	register DL as the default disk for subsequent file operatiofis, with
	DL = 0 for drive A, 1 for drive B, and so-forth through 15
	corresponding to drive P in a full sixteen drive system. In
	addition, the designated drive is logged-in if it is currently in
	the reset state. Logging-in a drive places it in "on-line" status
	which activates the drive's directory until the next cold start,
	warm start, disk system reset, or drive reset operation. FCB's
	which specify drive code zero (dr = OOH) automatically reference the
	currently selected default drive. Drive code values between 1 and
	16, however, ignore the selected default drive and directly
	reference drives A through P.

Entry	N			X		Return
CL: OFH			FUNCTION 15	AL: Return Code

DX:			FCB	OPEN FILE
	0 		set

	The Open File operation is used to activate a FCB specifying a
	file which currently exists in the disk directory for the currently
	active user number. The BDOS scans the disk directory of the drive
	specified by byte 0 of the FCB referenced by DX for a match in
	positions 1 t~rough 12 of the referenced FCB, where an ASCII
	question mark (3FH) matches any directory character in any of these
	positions. Normally, no question marks are included and, further,
	byte "ex" of the FCB is set to zero before making the open call.

All Information Presented Here is Proprietary to Digital Research

33
CP/M-86 System Guide	4.3		BDOS File Operations

	If a directory element is matched, the relevant directory
	information is copied into bytes dO through dn of the FCB, thus
	allowing access to the files through subsequent read and wri-te
	operations. Note that an existing file must not be accessed until. a
	successful open operation is completed. Further, an FCT3 not
	activated by either an open or make function must not be used in
	BDOS read or write commands. TJDon return, the open function returns
	a "directory code" with the value 0 through 3 if the open was
	successful, or OFFH (255 decimal) if the file cannot be found. if
	question marks occur in the FCB then the first matchinq FCB is
	activated. Note that the current record ("cr") must be zeroed by
	the program if the file is to be accessed sequentially from the
	first record.

Entry			Return
('-L: 10H	FUNCTION 16	AL: Return Code
DX: FCB	CLOSE FILE
	Offset

	The Close File function oerforms the inverse of the open file
	function. Given that the FCB addressed by DX has been previously
	activated through an open or make function (see functions 15 and
	22) , the close function permanently records the new FCB in the
	referenced disk directory. The FCB matching process for the close
	is identical to the open function. The directory code returned for
	a successful close operation is 0, 1, 2, or 3, while a OPFH (255
	decimal) is returned if the file name cannot be found in the
	directory. A file need not be closed if only read operations have
	taken place. If write operations have occurred, however, the close
	opeFation is necessary to permanently record the new directory
	information.

All Information Presented Here is Proprietary to Digital Research

34
CP/M-86 System Guide					4.3 BDOS File Operations
	Entry				Return
	CL: 11H			FUNCTION 17	AL: Directory
						Code
	DX: FCB		SEARCH FOR FIRST
		Offset 			IN

	Search First scans the directory for a match with the file
	given by the FCB addressed by DX. The value 255 (hexadecimal FF) is
	returned if the file is not found, otherwise 0, 1, 2, or 3 is
	returned indicating the file is present. In the case that the file
	is found, the buffer at the current DMA address is filled with the
	record containing the directory entry, and its relative starting
	Position is AL * 32 (i.e., rotate the AL register left 5 bits).
	Although not normally required for application programs, the
	directorv information can be extracted from the buffer at this
	position.

	An ASCII question mark (63 decimal, 3~ hexadecimal) in any
	position from "fl" through "ex" matches the corresponding field of
	any directory entry on the default or auto-selecte(i disk drive. If
	the "dr" field contains an ASCII question mark, then the auto disk
	select function is disabled, the default disk is searched, with the
	search function returninq any matched entry, allocated or free,
	belonging to any user number. This latter function is not normally
	used by application Programs, but does allow complete flexibility to
	scan all current directory values. if the "dr" field is not a
	question mark, the "s2" byte is automatically zeroed.

Entry 	Return

CL: 12H	FUNCTION IS		AL:	Directory
			Code
	SEARCH FOR NEXT

	The Search Next function is similar to the Search First
	function, except that the directory scan continues from the last
	matched entry. Similar to function 17, function 18 returns the
	decimal value 255 in A when no more directory items match. In terms
	of execution sequence, a function 18 call must follow either a
	function 17 or function 18 call with no other intervening BDOS disk
	related function calls.

All Information Presented Here is Proprietary to Digital Research

35
CP/M-86 System Guide

Entry		Return
CL: 13H	FUNCTION 19	AL: Return Code
DX: FCB	DELETE FILE
	Offset

	The Delete File function removes files which match the FCB
	addressed by DX. The filename and type may contain ambiquous
	references (i.e., question marks in various positions), but the
	drive select code cannot be ambiguous, as in the Search and Search
	Next functions. Function 19 returns a 0VFH (decimal 255) if the
	referenced file or files cannot be found, otherwise a value of zero
	is returned.

Entry		Return
CL: 14H	FUNCTION 20	AL: Return Code
DX: FCB	READ SEOUENTIAL
	Offset

	Given that the FCB addressed by DX has been activated through
	an open or make function (numbers 15 and 22), the Read Sequential
	function reads the next 128 byte record from the file into memory at
	the current DMA address. The record is read from position "cr" of
	the extent, and the "cr" field is automatically incremented to the
	next record Position. If the "cr" field overflows then the next
	logical extent is automatically opened and the "cr" field is reset
	to zero in Preparation for the next read operation. The "cr" field
	must be set to zero followdng the open call by the user if the
	intent is to read sequentially from the beginninq of the file. The
	value OOH is returned in the AL register if the read operation was
	successful, while a value of 01H is returned if no data exists at
	the next record position of the file. Normally, the no data
	situation is encountered at the end of a file. However, it can also
	occur if an attempt is made to read a data block which has not been
	previously written, or an extent which has not been created. These
	situations are usually restricted to files created or appended by
	use of the BDOS Write Random commmand (function 34).

All Information Presented Here is Proprietary to Digital Research

36
CP/M-86 System Guide			4.3 BDOS File Operations
	Entry			Return
	CL: 15H	FUNCTION 21		AL:	Return Code

DX:		FCB	WRITE SEOUENTIAL
	Offset

	Given that the FCB addressed by OX has been activated through
	an open or make function (numbers 15 and 22), the Write Sequential
	function writes the 128 byte data record at the current DMA address
	to the file*named by the FCB. The record is placed at position "cr"
	of the file, and the "cr" field is automatically incremented to the
	next record position. If the "cr" field overflows then the next
	logical extent is automatically opened and the "cr" field is reset
	to zero in preparation for the next write operation. Write
	operations can take place into an existing file, in which case newly
	written records overlay those which already exist in the file. The
	"cr" field must be set to zero following an open or make call by the
	user if the intent is to write sequentially from the beginning of
	the file. Register AL = OOH upon return from a successful write
	operation, while a non-zero value indicates an unsuccessful write
	due to one of the following conditions:

01		No available directory space - This condition occurs when
the write command attempts to create a new extent that
requires a new directory entry and no available directory
entries exist on the selected disk drive.

02		No available data block - This condition is encountered
when the write command attempts to allocate a new data
block to the file and no unallocated data blocks exist on
the selected disk drive.

Entry		Return
CL: 16H	FUNCTION 22	AL: Return Code

DX:		FrB	MAKE FILE
	Offset

	The Make File operation is similar to the open file operation
	except that the FCB must name a file which does not exist in the
	currently referenced disk directory (i.e., the one named explicitly
	by a non-zero "dr" code, or the default disk if "dr" is zero) . The
	BDOS creates the file and initializes both the directory and main
	memory value to an empty file. The programmer must ensure that no
	duplicate file names occur, and a preceding delete operation is
	sufficient if there is any possibility of duplication. Upon return,
	register A = 0, 1, 2, or 3 if the operation was successful and OFFH
	(255 decimal) if no more directory space is available. The make
	function has the side-effect of activating the FCB and thus a
	subsequent open is not necessary.

All Information Presented Here is Proprietary to Diqital Research

37
CP/M-86 System Guide	4.3		BDOS File Ooerations
	Entry			Return

CL:		17H	FUNCTION 23	AL: Return Code
DX:		FCB	RENAME FILE
	Offset

	The Rename function uses the FCB addressed by DX to change all
	directory entries of the file specified by the file name in the
	first 16 bytes of the FCB to the file name in the second 16 bytes.
	It is the user's responsibility to insure that the file names
	specified are valid CP/M unambiguous file names. The drive code
	"dr" at position 0 is used to select the drive, while the drive code
	for the new file name at position 16 of the FCB is ignored. Upon
	return, register AL is set to a value of zero if the rename was
	successful, and OFFH (255 decimal) if the first file name could not
	be found in the directorv scan.

Entrv		Return
CL: 18H	FUNCTION 24	BX: Login Vector

BX: Login	RETURN LOGIN
Vector	VECTOR

	The login vector value returned by CP/M-86 is a 16-bit value in
	BX, where the least significant bit corresponds to the first drive
	A, and the high order bit corresponds to the sixteenth drive,
	labelled P. A "0" bit indicates that the drive is not on-line,
	while a "l" bit marks an drive that is actively on-line due to an
	explicit disk drive selection, or an implicit drive select caused by
	a file operation which specified a non-zero "dr" field.

Entry	Return
%
CL: 19H	FUNCTION 25	AL: Current Disk

RETURN CURRENT
	DISK

	Function 25 returns the currently selected default disk number
	in register AL. The disk numbers range from 0 through 15
	corresponding to drives A through P.

All Informatior Presented Here is Proprietary to Digital Research

38
CP/M-86 System Guide	4.3			BDOS File Operations
	Entrv			Return

CL:		1AH	FUNCTION 26
OX:		DMA	SET DMA
	Offset	ADDRESS

	"DMA" is an acronvm for Direct Memorv Address, which is often
	used in connection with disk controllers which directly access the
	memory of the mainframe comPuter to transfer data to and from the
	disk subsystem. Although many comouter systems use non-OMA access
	(i.e., the data is transfered through programmed 1/0 ooerations),
	the DMA address has, in CP/M, come to mean the address at which the
	128 byte data record resides before a disk write and after a disk
	read. In the CP/M-86 environment, the Set DMA function is used to
	specify the offset of the read or write buffer from the current DMA
	base. Therefore, to soecify the DMA address, both a function 26
	call and a function 51 call are required. Thus, the DMA address
	becomes the value specified by DX plus the DMA base value until it
	is chanqed bv a subsequent Set DMA or set DMA base function.

Entry	X 		Return

CL: IBH	FUNCTION 27		BX: ALLOC Offset
I GET ADDR(ALLOC)		ES: Segment base

	An "allocation vector" is maintained in main memory for each
	on-line disk drive. Various system proqrams use the information
	provided by the allocation vector to determine the amount of
	remaining storage (see the STAT program). Function 27 returns the
	segment base and the offset address of the allocation vector for the
	currently selected disk drive. The allocation information may,
	however, be invalid if the selected disk has been marked read/only.

Entry 	Return

FUNCTION 28

WRITE PROTECT DISK

	The disk write protect function provides temporary write
	Protection for the currently selected disk. Any attempt to write to
	the disk, before the next cold start, warm start, disk system reset,
	or drive reset operation produces the message:

Bdos Err on d: R/O

All Information Presented Here is Proprietary to Digital Research

39
CP/M-86 System Guide	4.3		BDOS File Operations
	Entry			Return

CL: IDH	FUNCTION 29	BX: R/O Vector Value

GET READ/ONLY
	VECTOR

	Function 29 returns a bit vector in register T3X which indicates
	drives which have the temporary read/onlv bit set. Similar to
	function 24, the least significant bi-t corresponds to drive A, while
	the most significant bit corresponds to drive P. The R/O bit is set
	either by an explicit call to function 28, or by the automatic
	software mechanisms within CP/M-86 which detect changed disks.

Entry 	Return

CL: 1EH	FUNCTION 30	AL: Return rode

DX: FCB	SET FILE
Offset	ATTRIBTJTES

	The Set File Attributes function allows programmatic
	manipulation of permanent indicators attached to files. Tn
	particular, the R/0, System and Archive attributes (tl', t2', and
	t3') can be set or reset. The DX pair addresses a Trj3 containing a
	file name with the approoriate attributes set or reset. it is the
	user's responsibility to insure that an ambiguous file name is not
	specified. Function 30 searches the default disk drive directory
	area for directory entries that belong to the current user number
	and that match the FCB specified name anI tvoe fields. All matching
	directorv entries are updated to contain the selected indicators.
	Indicators fl' through f4' are not oresentl.v used, but may he useful
	for applications programs, since thev are not involved in the
	matching process during file open and close operations. Indicators
	f5' through f8' are reserved for future system expansion. The
	currently assigned attributes are defined as follows:

tl':		The.R/O attribute indicates if set that the file
is in read/only status. BDOS will not allow write
commands to be issued to files in R/O status.

t2':		The System attri bute is referenced by the CP/M DIR
utility. If set, DIR will not display the file in
a directory display.

All Information Presented Here is Proprietary to Digital Research

40
CP/M-86 System Guide	4.3		9r)OS File Operations

t3':		The Archive attribute is reserved but not actually
used bv OP/M-86 If set it indicates that the fi-l-e
has been written to back ur) storage bv a user
written archive program. To implement this
facilitv, the archive Program sets this attribute
when it copies a file to back up storage; anv
programs updating or creating f ilps reset this
attribute. Purther, the archive Program backs uo
only those files that have the Archive attribute
reset. Thus , an automati c back ur) facil i-tv
r estr icted to modif i.ed f il es can be eas i I v
i-molemented.

Function 30 returns with register AL set to OPPH (255 r1ecimal
if the referenced file cannot be found, otherwise a value of zero is
returned.

Entrv			Return
CL: IFH	7UNCTION 31		Rx:	npq r)f f set
	C.PT Anr)R	Fq:		Segment Rase
	(nTSK PAR-MS)

The offset and the seqment base of the RT01; re,
	,;i(lent r1isk
parameter block of the currenti-v sel-ectel 9rive are returned in RX
and ES as a result of this function call.. Thi.s control block can be
used for either of two ourooses. Pirst, the disk oarameter values
can be extracted for disolav and soace computation Purposes, or
transient programs can dvnami-cal 1 v change the value-, of current disk
Parameters when the disk environment changes,		i f reauired.
Normally, application oroqram.s wi - 1 - I riot recru i re th is, f ac i 1 i ty.
qection 6.3 define-, the 33InS disk Parameter block.

7ntrv	1~eturn
CL: 2014	FTJM(7TTnN 32	AT,: Current (ode
					or		no value
OL: OPFP(qet)	SET/C-FT
			or	TTqFR r7ODE
	User Code
		(set)

	An application proqram can change or interrogate the current1v
	active user number by calling function 32. If register r)L = OFPH,
	then the value of the current user number is returned in register
	AL, where the value is i-n the range 0 to I';. If reqi-ster T)L is not
	OFFH, then the current user number is changed to the value of OT,
	(modulo 16).

All Information Presented Pere is Proorietarv to Digital. Research

41
	CP/M-86 System Guide	4.3	BDOS File Operations
	Entrv		Return
X
CL:		21H	FUNCTION 33	AL: Return Code
DX:		FCB	READ RANDOM
	Offset I

	The Read 'Random function is similar to the sequential file read
	operation of previous releases, except that the read operation takes
	place at a particular record number, selected by the 24-bit value
	constructed from the three byte field following the FCB (byte
	positions rO at 33, rl at 34, and r2 at 35). Note that the sequence
	of 24 bits is stored with least significant byte first (rO) , middle
	byte next (rl), and hiqh byte last (r2). CP/M does not reference
	byte r2, except in computing the size of a file (function 35) . Byte
	r2 must be zero, however, since a non-zero value indicates overflow
	past the end of file.

	Thus, the rO,rl byte pair is treated as a double-byte, or
	"word" value, which contains the record to read. This value ranges
	from 0 to 65535, providing access to any particular record of any
	size f ile. In order to access a file usinq the Read Random
	function, the base extent (extent 0) must first be opened. Although
	the base extent may or may not contain any allocated data, this
	ensures that the FCB is properly initialized for subsequent random
	access operations. The selected record number is then stored into
	the random record field (rO,rl) , and the BDOS is called to read the
	record. Upon return from the call, register AL either contains an
	error code, as listed below, or the value 00 indicating the
	operation was successful. In the latter case, the buffer at the
	current DMA address contains the randomly accessed record. Note
	that contrary to the sequential read operation, the record number is
	not advanced. Thus, subsequent random read operations continue to
	read the same record.

	Upon each random read operation, the logical extent and current
record values are automatically set. Thus, the f ile can be
sequentially re ' ad or written, starting from the current randomly
accessed position. Note, however, that in this case, the last
randomly read record will be re-read as you switch from random mode
to sequential read, and the last record will be re-written as you
switch to a sequential write operation. You can, of course, simply
advance the random record position following each random read or
write to obtain the effect of a sequential 1/0 operation.

All Information Presented Here is Proprietary to Digital Research

42
CP/M-86 System Guide	4.3		BDOS File Operations

Error codes returned in register AL following a random read are
listed in Table 4-4, below.

Table 4-4. Function 33 (Read Random) Error Codes

Code  	Meaning

01		Reading unwritten data - This error code is returned when a
random read operation accesses a data block which has not been
previously written.

02		(not returned by the Random Read command)

03		Cannot close current extent - This error code is returned
when BDOS cannot close the current extent prior to moving to the new
extent containing the record specified by bytes rO,rl of the FCB.
This error can be caused by an overwritten FCB or a read ranaom
operation on an F(7B that has not been opened.

04		Seek to unwritten extent - This error code is returned when
a random read operation accesses an extent that has not been created.
This error situation is equivalent to error 01.

05		(not returned by the Random Read command)

06		Random record number out of range - This error code is
returned whenever byte r2 of the FCB is non-zero.

Normally, non-zero return codes can be treated as missing data, with
zero return codes indicating operation complete.

All Information Presented Here is Proprietary to Digital Research

43
CP/M-86 System Guide		4.3 BDOS File Operations
	Entry			Return
	CL: 22H	FUNCTION 34	AL:	Return Code
	DX: FCB	WRITE RANDOM
		Offset

	The Write Random operation is initiated similar to the Read
	Random call, except that data is written to the disk from the
	current DMA address. Purther, if the disk extent or data block
	which is the tarqet of the write has not yet been allocated, the
	allocation is performed before the write operation continues. ks in
	the Read Random operation, the random record number is not changed
	as a result of the write. The logical extent number and current
	record positions of the file control block are set to correspond to
	the random record which is beinq written. Sequential read or write
	operations can commence followinq a random write, with the note that
	the currently addressed record is either read or rewritten again as
	the sequential operation begins. You can also simply advance the
	random record position following each write to get the effect of a
	sequential write operation. In particular, reading or writing the
	last record of an extent in random mode does not cause an automatic
	extent switch as it does in sequential mode.

	In order to access a file using the Write Random function, the
	base extent (extent 0) must first be opened. As in the Read Random
	function, this ensures that the FCB is properly initialized for
	subsequent random access operations. If the file is empty, a Make
	File function must be issued for the base extent. Although the base
	extent may or may not contain any allocated data, this ensures that
	the file is properly recorded in the directory, and is visible in
	DIR requests.

	Upon return from a Write Random call, reqister AL either
	contains an error code, as listed in Table 4-5 below, or the value
	00 indicating the operation was successful.

Table 4-5. Function 34 (WRITE RANDOM) Error Codes
Code I 	Meaning

01	(not returned by the Random Write command)

02	No available data block - This condition is encountered
when the Write Randob command attempts to allocate a new
data block to the file and no unallocated data blocks
exist on the selected disk drive.

All information Presented Here is Proprietary to 'Digital Research

44
CP/M-86 System Guide	4.3		BDOS File Operations

Table 4-5. (continued)

Code	Meaninq

03		Cannot close current extent - This error code is
returned when BOOS cannot close the current extent prior
to moving to the new extent containing the record
specified by bytes rO,rl of the FCB. This error can be
caused by an overwritten FCB or a write random operation
on an PCB that has not been opened.

04		(not returned by the Random Write command)

05		No available directory space - This condition occurs
when the write command attempts to create a new extent
that requires a new directory entry and no available
3irectory entries exist on the selected disk drive.

06		Random record number out of range - This error code is
returned whenever byte r2 of the FC9 is non-zero.

Entry		Return
CL: 23H	FUNCTION 35	Random Record
			Field Set
DX: FC8	COMPUTE FILE
	Offset	SIZE

	When computing the size of a file, the DX register addresses an
	FCB in random mode format (bytes rO, rl, and r2 are present). The
	FCB contains an unambiguous file name which is used in the directory
	scan. Upon return, the random record bytes contain the "virtual"
	file size which is, in effect, the record address of the record
	following the end of the file. If, following a call to function 35,
	the high record byte r2 is 01, then the file contains the maximum
	record count 65536. Otherwise, bytes rO and rl constitute a 16-bit
	value (rO is the least significant byte, as before) which is the
	file size.

	Data can be appended to the end of an existing file by simply
	calling function 35 to set the random record position to the end of
	file, then performinq a sequence of random writes starting at the
	preset record address.

	The virtual size of a file corresponds to the physical size
	when the file is written sequentially. if, instead, the file was
	created in random mode and "holes" exist in the allocation, then the
	f ile may in fact contain fewer records than the size indicates. If,
	for example, a single record with record number 65535 (CP/M's
	maximum record number) is written to a file using the Write Random
	function, then the virtual size of the file is 65536 records,
	although only one block of data is actually allocated.

All Information Presented Here is Proprietary to Digital Research

45
CP/M-86 System Guide		4.3		BOOS File Operations
	Entrv				Return
	CL: 24H	FUNCTION 36		Random Record
						Field get
	DX: FCB	SET RANDOM
		Offset	RECORD

	The Set Random Record function causes the BDOS to automatically
	produce the random record position of the next record to be accessed
	f rom a file which has been read or written sequentially to a
	particular point. The function can be useful in two wavs.

	First, it is often necessary to initially read and scan a
	sequential file to extract the positions of various "kev" fields.
	As each key is encountered, function 36 is called to compute the
	random record position for the data corresponding to this kev. if
	the data unit size is 128 bytes, the resulting record position minus
	one is placed into a table with the key for later retrieval. After
	scanning the entire file and tabularizing the kevs and their record
	numbers, you can move instantly to a particul.ar keyed record by
	performing a random read using the corresponding random record
	number which was saved earlier. The scheme is easily generalized
	when variable record lengths are involved since the program need
	only store the buffer-relative bvte position along with the key and
	record number in order to find the exact starting position of the
	keyed data at a later time.

	A second use of function 36 occurs when switching from a
	sequential read or write over to random read or write. A file is
	sequentially accessed to a particular point in the file, function 36
	is called which sets the record number, and subsequent random read
	and write operations continue from the next record in the file.

Entry 	'Return

CL: 25H	FUNCTION 17	AL: OOH

DX:		Drive	RESET DRIVE
	Vector 	"I

	The Reset Drive function is used to programmatically restore
	specified drives to the reset state (a reset drive is not loqqed-in
	and is in read/write status). The passed parameter in register T)X
	is a 16 bit vector of drives to be reset, where the least
	significant bit corresponds to the first drive, A, and the high
	order bit corresponds to the sixteenth drive, labelled P. Bit
	values of "111 indicate that the specified drive is to be reset.

	In order to maintain compatibility with MP/M, C_P/M returns a
	zero value for this function.

All Information Presented Here is Proprietary to Digital Research

46
CP/M-86 System Guide

Entrv	Return
N
CL:		28q	FUNCTION 40	AL: Return Code
DX:		FCB	WRITE RANDOM
	Offset	WITH ZERO FILL

	The Write Random With Zero Fill function is similar to the
	Write Random function (function 34) with the exception that a
	greviously unall-ocated data block is initialized to records filled
	with zeros before the record is written. If this function has been
	used to create a file, records accessed bv a read random operation
	that contain all zeros identify unwritten random record numbers.
	Unwritten random records in allocated data blocks of files created
	using the write Ranlom function contain uninitialized data.

Entrv 	'Return

('L: 32H	FUNCTION 50

DX: BIOS		DIRECT BIOS CALL
Descriptor

	Punction 50 provides a direct BIOS call and transfers control
	through the BDOS to the BIOS. The DX register addresses a five-byte
	memory area containing the BIOS call parameters:

9-bit		16-bit 	16-bit
I Func I value(CX) I value

where Func is a BIOS function number, (see Table 5-1) , and value (CX)
and value(DX) are the 16-bit values which would normally be passed
directly in the CX and OX registers with the BIOS call. The CX and
OX values are loaded into the 8086 registers before the BIOS call is
initiated.

All Information Presented Here is Proprietary to Digital Research

47
CP/M-86 System GuiMe	4.3	BDOS File Operations
	Entry			Return
	CL: 33H	FUNCTION 51
	DX: Base	SET DM4 BASE
		Aadress

	Function 51 sets the base register for subsequent DMA
	transfers. The word parameter in DX is a oaraqraT)h address and is
	used with the DMA offset to sPecify the address of a 128 byte buffer
	area to be used in the disk read and write functions. Note that
	upon initial program loadinq, the default T)MA base is set to the
	address of the user's data seqment (the initial value of T)S) anI the
	DMA offset is set to 0080H, which Provides access to the lefault
	buffer in the base page.

Entrv 	Return

FUNCTION 52	RX: DMA Offset

GFT DMA BASE	ES: DMA Seqment

	Function 52 returns the current DMA Base Segment address in ES,
	with the current DMA Offset in T)X.

4.4	BDOS Memory Management and Load

	Memorv is allocated in two distinct ways under r-P/M-86. The
	first is through a static allocation map, located within the BIOS,
	that defines the physical memory which is available on the host
	system. In this way, it is possible to oper4te CP/M-86 in a memory
	configuration which is a mixture of up to eight non-contiguous areas
	of RAM or ROM, al.ong with reserved, missing, or faulty memory
	regions. in a simple RAM-based system with contiguous memory, the
	static map defines a single region, usual-1-y starting at the end of
	the BIOS and extendinq up to the end of available memory.

	Once memory is physically mapped in this manner, CP/M-86
	performs the second level of dynamic allocation to support transient
	program loading and execution. CP/M-86 allows dynamic allocation of
	memory into, again, eight regions. A request for allocation takes
	place either implicitly, through a program load ooeration, or
	explicitly through the BT)OS calls given in this section. Proqrams
	themselves are loaded in two ways: through a command entered at the
	CCP level, or through the BDOS Program Load operation (function 59) .
	Multiple programs can be loaded at the CCP level, as long as each
	program executes a System Reset (function 0) and remains in memory
(T)L = 01H) . Multiple Programs of this type only receive control by
intercepting interrupts, and thus under normal circumstances there

All Information Presented Here is Proprietary to Digital Research

48
CP/M-86 Svstem Guide	4.4		BDOS Memory Management and Load

is only one transient proqram in memory at any given time. if,
however, multiple programs are present in memory, then CONTROL-C
characters entered by the operator delete these programs in the
opposite order in which they were loaded no matter which oroqram is
actively reading the console.

	Any given program loaded through a CCP command can, itself,
	load additional programs and allocate data areas. Suppose four
	regions of memory are allocated in the following order: a proqram
	is loaded at the CCP level through an operator command. The CMD
	file header is read, and the entire memorv image consistinq of the
	program and its data is loaded into region A, and execution beqins.
	This program, in turn, calls the BOOS Proqram Load function (59) to
	load another proqram into region B, and transfers control to the
	loaded program. The region B proqram then allocates an additional
	region C, followed by a region D. The order of allocation is shown
	in Figure 4-1 below:

Region A

Reqion B

Region C

Reqion D

Figure 4-1. Example Memory Allocation

There is a hierarchical ownership of these regions: the program in
A controls all memory from A through T). The program in B also
controls regions B through D. The program in A can release regions
B through D, if desired, and reload yet another program. ODT-86,
for example, operates in this manner by executing the Free Memory
call (function 57) to release the memory used by the current program
before loading another test proqram. Further, the program in B can
release regions C and 0 if required by the application. It must be
noted, however, that if either A or B terminates by a System Reset
(BDOS function 0 with DL = OOH) then all four regions A through D
are released.

All Information Presented Here is Proprietary to Digital Research

49
CP/M-86 System Guide	4.4	BOOS Memorv Management and Load

	A trans ient/program may release a portion of a region, allowinq
	the released Portion to be assigned on the next allocation request.
	The released portion must, however, be at the beqinninq or end of
	the region. Suppose, for example, the program in reqion 73 above
	receives 800H Paragraphs at paragraph location 100H following its
	first allocation request as shown in Figure 4-2 below.

1000H:

Length
8000H	Region 	C

Figure 4-2. Example Memory Region

Suppose further that region D is then allocated. The last 200H
paragraphs in region C can be returned without affecting region D by
releasing the 200H paragraphs beginning at paraqraoh base 700H,
resulting in the memory arrangement shown in Figure 4-3.

		10 0 OH:
Length =
6000H			Region C
Length =			700OH:
200011	1

Figure 4-3. Example Memory Regions

The region beginning at paragraph address 700H is now available for
allocation in the next request. Note that a memorv request will
fail if eight memory regions have already been allocated. Normally,
if all program units can regide in a contiguous region, the system
allocates only one region.

All Information Presented Here is Proprietary to Digital 'Research

50
CP/M-86 System Guide	4.4 BDOS Memory Management and Load

	Memory management functions beginning at 53 reference a Memory
	Control Block (MCB) , def ined in the calling program, which takes the
	form:

16-bit		16-bit	8-bit
MCB:		M-Base	M-Length I M-EF~]

where M-Base and M-Length are either inr ' )ut or output values
expressed in 16-byte paragraph units, and M-Ext is a returned byte
value, as defined specifically with each function code. An error
condition is normally flagged with a OFFH returned value in order to
match the file error conventions of CP/M.

Entry		Return
CL: 35H	FUNCTION 53	AL: Return Code

	DX: Offset		GET MAX MEM
	of MCB

	Function 53 finds the larqest avail-able memory region which is
	less than or equal to M-Length paragraphs. If successful, M-Base is
	set to the base paragraph address of the available area, and M
	Length to the paragraph length. AL has the value OFFH upon return
	if no memory is available, and OOH if the request was successful.
	M-Ext is set to I if there is additional memory for allocation, and
	0 if no additional memory is available.

Entry	Return

CL: 36H		FUNCTION 54	AL: Return Code

	DX: Offset		GET ABS 14AX
	of MCB

	Function 54 is used to find the largest possible region at the
	absolute paragraph boundary given by M-Base, for a maximum of M
	Lenqth paragraphs. M-Lenqth is set to the actual Tength if
	successful. AL has the value OFFH upon return if no memory is
	available at the absolute address, and OOH if the request was
	successful.

All. Information Presented Here is Proprietary to Digital Research

51
CP/M-86 System Guide	4.4	BDOS Memory Management and Load

	Entry		Return
	CL: 37H	FUNCTION 55	AL: Return Code
	DX: Offset	ALLOC MEM
		of MCB 


The allocate memory function allocates a memory area according to the
MCB addressed by DX. The allocation request size is obtained f rom M
Length. Function 55 returns in the user's MCB the base paragraph
address of the allocated region. Register AL contains a OOH if the
request was successful and a OFFH if the memory could not be
allocated.

Entry				Return
CL: 38H		FUNCTION 56	AL:	Return Code
DX: Offset		ALLOC ABS MEM
	of MCB

The allocate absolute memory function allocates a memory area
according to the MCB addressed by nX. The allocation request size is
obtained from M-Length and the absolute base address from M-Base.
Register AL contains a OOH if the request was successful and a OFFH
if the memory could not be allocated.

Entry	%	Return

CL: 39H	FUNCTION 57

	DX: Offset	FREE MEM
	of MCB

Function 57 is used to release memory areas allocated to the program.
The value of the M-Ext field controls the operation of this function:
if M-Ext = OFFH then all memory areas allocated by the calling
program are released. Otherwise, the memory area of length M-Length
at location M-Base given in the MCB addressed by T)X is released (the
M-Ext field -should be set to OOH in this case) . As described above,
either an entire allocated region must be released, or the end of a
region must be released: the-middle section cannot be returned under
CP/M-86.

All Information Presented Here is Proprietary to Digital Research

52


CP/M-86 System Guide		4.4		BDOS	Memory Management and Load
	Entry			'S, 		Return
	CL: 3AH		FUNCTION 58

FREE ALL MEM

	Function 58 is used to release all memory in the (P/M-86
	environment (normally used only by the CCP upon initialization).

Entry				Return
	-	N			0

CL:		3BH	FUNCTION 59	AX:	Return Code/
				Base Page Addr
OX:		Offset	PROGRAM LOAD	BX:	Base Page Addr
	of PCs

	Function 59 loads a CMD file. Upon entry, register T)X contains
	the DS relative offset of a successfully opened FCB which names the
	input CMD file. AX has the value OFFFFH if the program load was
	unsuccessful. Otherwise, AX and BX both contain the paragraph
	address of the base page belonqing to the loaded program. The base
	address and segment length of each segment is stored in the base
	page. Note that upon program load at the CCP level, the DMA base
	address is initialized to the base page of the loaded program, and
	the DMA offset address is initialized to 0080H. However, this is a
	function of the CCP, and a function 59 does not establish a default
	OMA address. It is the responsibility of the program which executes
	function 59 to execute function 51 to set the DMA base and function
	26 to set the DMA offset before passing control to the loaded
	program.

All Information Presented Here is Proprietary to Digital Research

53
	Section 5
Basic 1/0 System (BIOS) Organization

	The distribution version of CIDIM-86 is setup for operation with
	the Intel SBC 86/12 microcomputer and an Intel 204 diskette
	controller . All hardware dependencies are, however, concentrated in
	subroutines which are collectively referred to as the Basic T/O
	System, or BIOS. A CP/M-86 svstem implementor can modify these
	subroutines, as described below, to tailor CP/M-86 to fit nearly anv
	8086 or 8088 operatinq environment. This section describes the
	actions of each BIOS entry point, and defines variables and tables
	referenced within the BIOS. The discussion of Disk Oefinition
	Tables is, however, treated separately in the next section of thi.s
	manual.

5.1		Organization of the 'BIOS

	The BIOS portion of CP/M-86 resiles in the topmost portion of
	the operating system (hiqhest addresses) , and takes the qeneral form
	shown in Figure 5-1, below:

CS, DS, ES, SS:

Console
Command
Processor

	and
Basic
Disk
Operatinq
System

CS + 250OH:	BIOS Jump Vector

CS + 253PH:
BIOS Pntrv Points

BIOS:
		Disk
Parameter
	Tables

Uninitialized
	Scratch RAM

Figure 5-1. General CP/M-86 organization

All Information Presented Here is Proprietary to Digital Research

55
CP/M-86 System Guide	5.1	Organization of the BIOS

As described in the following sections, the CCP and RDOS are
supplied with CP/M-86 in hex file form as CPM.T186. In order to
implement CP/M-86 on non-standard hardware, you must create a 1310S
which performs the functions listed below and concatenate the
resulting hex file to the end of the (7PM.1486 file. The GENCMD
utilitv is then used to produce the CPM.SYS f ile for subsequent load
by the cold start loader. The cold start loader that loads the
CPM.SYS f ile into memory contains a simpl if ied form of the BIOS,
called the LDBIOS (Loader BIOS). It loads CPM.SYS into memory at
the location defined in the CPM.SYS header (usually 0400H). The
procedure to follow in construction and execution of the cold start
loader and the CP/M-86 Loader is given in a later section.

	Appendix D contains a listinq of the standard CP/M-86 BIOS for
	the Intel SBC 86/12 system using the Intel. 204 Controller Board.
	Appendix E shows a sample "skeletal" RIOS called CBIOS that contains
	the essential elements with the device drivers removed. You mav
	wish to review these listings in order to determine the overall
	structure of the BIOS.

5.2	The BIOS Jump Vector

	Entry to the BIOS is through a "iump vector" located at offset
	2500H from the base of the oneratinq system. The jump vector is a
	sequence of 21 three-byte jumo instructions which transfer proqram
	control to the individual BIOS entrv uoints. Although some non
	essential BIOS subroutines may contain a sinql-e return (RFT)
	instruction, the corresponding jumo vector element must be present
	in the order shown below in Table 5-1. An example of a BIOS ~iumn
	vector mav be found in Appendix D, in the standard (P/M-86 BIOS
	listing.

	Parameters for the -individual subroutines in the BIOS are
	passed in the CX and DX registers, when required. CX receives the
	first parameter; T)X is used for a seconp argument. Return values
	are passed in the registers acco dinq to tvoe: T3vte values are
	returned in AL. Word values (1-6 bits) are returned in IRX. qpecific
	oarameters and returned values are described with each suhroutine

All Information Presented Here is ProDrietarv to Digital- Research

56
CP/M-86 System Guide	5.2		The BIOS Jump Vector

Table 5-1. BIOS Jump Vector

	Offset from	Suggested		BIOS
	Beginning	Instruction		F#	Description
	of 9IOS

2500H		JMP	INIT	0	Arrive Here from Cold Boot
2503H		imp	WBOOT	I	Arrive Here for Warm Start
2506H		JMP	CONST	2	Check for Console Char Ready
2509H		imp	CONIN	3	Read Console Character In
250CH		JMP	CONOUT	4	Write Console Character Out
250FH		JMP	LIST	5	Write Listinq Character Out
2512H		JMP	PUNCH	6	Write (7har to Punch Device
2515H		JMP	READER	7	Read Reader Device
2518q		JMP	HOME	8	Move to Track 00
25113H		JMP	SELDSK	9	Select Disk Drive
251EH		JMP	SETTRK	10	get Track Number
2521H		JMP	SETSEC	11	Set Sector Number
2524H		JMP	SETDMA	12	Set DMA Offset Aodress
2527H		JMP	READ	13	Read Selected Sector
252AH		JMP	WRITE	14	Write Selected Sector
252DH		JMP	LISTST	15	Return List Status
2530H		JMP	SECTRAN	16	Sector Translate
2533H		JMP	SETDMAB	17	Set DMA Segment Address
2536H		JMP	GETSEGB	18	Cet MEM DESC Table Offset
2539H		JMP	13ETIO9	19	Get 1/0 Mapping Byte
253CH		JMP	SETIOB	20	qet 1/0 Mapping Byte

	There are three major divisions in the BIOS jump table: system
	(re)initialization subroutines, simple character 1/0 subroutines,
	and disk 1/0 subroutines.

5.3		Simple Peripheral Devices

	All. simple character 1/0 operations are assumed to be performed
	in ASCII, upper and lower case, with high order (parity bit) set to
	zero. An end-of-file condition for an input device is given bv an
	ASCII control--z (1AH). Peripheral devices are seen by CP/M-86 as
	"logical-" devices, and are assigned to physical devices within the
	BIO S. Device characteristics are defined in Table 5-2.

All Information Presented Here is Proprietary to Digital Research

57
CP/M-86 System Guide	5.3	Simple Peripheral T)evices

Table 5-2. CP/M-86 Logical Device Characteristics

Device Name	rharacteristics

CONSOLE	The Principal interactive console which
communicates with the operator, accessed throuqh
CONST, CONIN, and CONOITT. Typically, the rONqOLF
is a device such as a CRT or Teletype.

L IS T	The principal I istinq device, if it exists on your
	system, which is usually a hard-copv device, such
	as a printer or Teletype.
PUNCH	The principal tape ounchinq device, if it exists,
	which is normally a hiqh-soeed Paper tape punch or
	Teletype.
RFADER	The Principal tape readinq device, such as a
	simple optical reader or tel-etyoe.

	Note that a sinql-e peripheral can be assiqnerl as the LIST,
	PUNCH, and READER device simultaneously. If no peripheral device is
	assiqned as the LIST, PUNCH, or READER device, your (7BIOS should
	qive an appropriate error messaqe so that the svstem does not "hanq"
	if the device is accessed by PIP or some other transient oroqram.
	Alternately, the PTJNCH and LIST subroutines can just simr)lv return,
	and the READER subroutine can return with a 1AH (cti-7) in req A to
	indicate immediate end-of-file.

	Por added flexibility, vou can ootionall.v implement the
	"IOBYTE" function which allows reassignment of Physical and loqical
	devices. The IOBYTE function creates a maoPinq of l.oqical to
	physical devices which can be altered durinq CP/M-86 orocessinq (see
	the STAT command) . The definition of the I01BYTE function
	corresponds to the Intel standard as foll-ows: a single location in
	the BIOS is maintained, called IOBYTF, which defines the 1-oc(i-cal to
	physical device mappinq which is in effect at a particular time.
	The maPpinq is Performed by solitti-nq the IOBYTE into four distinct
	fields of two bits each, called the (7.0NSOTE, READER, PTINCH, and LIST
	fields, as shown below:

most significant	least significant
IOBYTE	LIST	1	PUNCH	READER	I CONSOLE

bits 6,7 bits 4,5 bits 2,3 bits 0,1

All Information Presented Here is Provrietarv to T)iqital Research

58
CP/M-86 System ruide	5.3		Simple Peripheral Devices

The value in each field can be in the ranqe 0-3, defininq the
assigned source or destination of each logical device. The values
which can be assiqned to each field are given in Table 5-3, below.

Table 5-3. 10BYTE Field Definitions

CONSOLE field (bits 0,1)
0 - console is assigned to the console printer (TrrY:)
I - console is assigned to the CRT device (CRT:)
2 - batch mode: use the READER as the CONSOLE input,
and the LIST device as the CONSOLE output (RATO
3 - user defined console device (UC.I:)

READER		field (bits 2,3)
	0		- READER is the Teletype device (TTY:)
	I		- READER is the hiqh-soeed reader device (RDR:)
	2		- user defined reader # I (URI:)
	3		- user defined reader # 2 (UR2:)

PUNCH fiel.d (bits 4,5)
0 - PUNCH is the Teletype device (TTY:)
I - PUNCH is the hiqh speed punch device (PUN:)
2 - user defined punch # 1 (UPI:)
3 - user defined ounch # 'I (UP2:)

	LIST field (bits		6,7)
	0 - LIST is		the Teletype device (TqY:)
	I - LIST is		the CRT device (CRT:)
	2 - LIST is		the line printer device (LPT:)
	3 - user defined list device (UL1:)

	Note aqain that the implementation of the IOBYTE is optional,
	and affects only the orqanization of your rBIOS. No CP/M-86
	utilities use the IOBYTE except for PIP which allows access to the
	physical devices, and STAT which allows loqical--physical assiqnments
	to be made and d i siol ayed. In any case, you should omit the IOBYTE
	implementation until your basic C-BIOS is fully implemented and
	tested, then add the IOBYTE to increase your facilities.

All Information Presented Here is Proprietary to Digital Research

59
CP/M-86 Svstem Guide	5.4	BIOq Subroutine Pntrv Points

5.4	BIOS Subroutine Entry Points

	The actions which mu9t take place upon entrv to each Rinq
	subroutine are given below. It should be noted that disk 110 is
	alwavs Performed throuqh a secruence of calls on the various lisk
	access subroutines. These setuD the disk number to access, the
	track and sector on a Particular disk, and the direct memorv access
	(DMA) offset and seqment addresses involved in the 1/0 oPeration.
	After all these Parameters have been setur), a call is made to the
	READ or WRITE function to Perform the actual 1/0 oDeration. Note
	that there is often a single call to SELDSK to select a disk 9rive,
	followed by a number of read or write onerations to the selected
	disk before selectinq another drive for subsequent ooerations.
	Similarly, there mav be a call to set the DMA seqnent base and a
	call to set the DMA offset followed bv several calls which read or
	write from the selected DMA address before the T)MA address is
	chanqed. The track and sector subroutines are always call,ed before
	the READ or WRITE or)erations are Performed.

	The READ and WRITE subroutines should Perform several retries
	(10 is standard) before reDortinq the error condition to the BDOS.
	The HOME subroutine mav or may not actually perform. the track 00
	seek, deoending upon your controller characteristics; the imoortant
	point is that track 00 has been selected for the next ooeration, and
	is often treated in exactlv the same manner as OPTTRT< with a
	parameter of 00.

Table 5-4. BIOS Subroutine Sumnary

Subroutine		Description
	INIT	This subroutine is calle3 directly by the CP/M-86
		loader	after the ('-PM.SYS file has been read into
		memory. The Procedure is	responsibl.e for anv
		hardware initialization not Performed by	the
		bootstrao	loader, setting initial values for "~TOq
		variables	(including IOBYTE), printinq a siqn-on
		messaqe,	and initializing the interrupt vector to
		Point to the BOOS offset (OB11H) and base.	when
		this routine completes, it jumPs to	the CCP
		of f set (OH) . All seqment registers	shoul-d be
		initialized	at this time to contain the base of
		the ooeratinq system.
	WBOOT	This subroutine is called whenever	a vroqram
		terminates	by performinq a 13DOS function 40 call.
		Some re-initialization of the hardware	or
		software m~y occur here. When this	routi - ne
		completes,	it jumps directl.v to the warm start
		entry point of the CCP (06H).
	CONST	Samole the status of the currently	assiqned
		console	device and return OFFH in reqister AL if
		a	character is ready to read, and OOH in reqister
		AL if no console characters are ready.

All Information Presented Here is Proorietary to Digital Research

60
CP/M-86 System Guide	5.4		13IOS Subroutine Entrv Points

Table 5-4. (continued)

Subroutine			Description
	(IONIN		Read the next console character into reqister AL,
		and set the Daritv bit (high order bit) to zero.
		if no console character is ready, wait until a
		character	is tvped before returning.
	CONOTJT		Send the character from	register CL	to the
		console output device. The character			is in
		ASCII, with high order parity bit set to zero.
		You mav	want to include a time-out on a line feed
		or carriage return, if your console			device
		requires some time interval at the end of the
		1 ine (such as a MI Silent 700 terminal) . You
		can,	if you wish, filter out control		characters
		which	have undesirable effects on		the console
		device.
	LIST		Send the character	from /register (L	to the
		currently assigned listing rievice. The character
		is in ASMI with zero paritv.
	PUNCH		Send the character from	register CL	to the
		currently assigned punch device.			The character
		is in ASCII with zero parity.
	READER		Read the next character from	the	currentlv
		assigned reader device into register AL with zero
		paritv (high order bit must be zero). An end of
		file condition is reported bv returning an ASCII
		CONTROL-Z (1AH) .
	90ME		Return the disk head of the currently selected
		disk to the track 00	position.		If your
		controller does not have a special feature for
		f indinq track 00, vou can translate the call into
		a	call to SETTRK with a parameter of 0.

All Information Presented Here is Proprietary to Digital Research

61
CP/M-86 System Guide	5.4		BIOS Subroutine Entrv Points

Table 5-4. (continued)

	Subroutine		Description
	SELDSK	Select the disk drive given by reqister CL for
		further operations, where register CL contains 0
		for drive A,	1 for drive B, and so on un to IS
		for drive P	(the standard (7P/M-86 distribution
		version supports two drives). on each disk
		select, SELDSK must return in BX the base address
		of the selected drive's Disk Parameter Header.
		Por standard floppy disk drives, the content of
		the header and associated tables does not chanqe.
		The sample BIOS included	with CP/M-86 callel
		CBIO,q contains an example program segment that
		performs the SELDSK function. If there is an
		attempt to select a non-existent drive, S"ELDSK
		returns BX=0000H as an error indicator. Although
		SELDSK must	return the header address on each
		call-, it is advisable	to postpone the actual
		physical disk select operation until an T10
		Function (seek, read or	write) is nerformed.
		This is due to the fact	that r3is-k select
		operations	mav take place without a subsequent
		disk operation and thus	disk access mav be
		substantiall v	slower usinq some disk control I ers.
		On entry to SELDSK it is possible to determine
		whether it is the first time the specified disk
		has been selected. Register T)T,, bit 0 (least
		significant bit)	is a zero if the drive has not
		been previously selected. This information is of
		interest in svstems which	read configuration
		information	from the disk in order to set ur) a
		dynamic disk definition table.
	SETTRK	Register CX contains the	track number for
		subsequent disk accesses	on the currently
		selected drive. You can	choose to seek the
		selected track at this time, or aelav the seek
		until the next read or write actually occurs.
		Register CX can take on values in the range 0-76
		corresponding	to valid track numbers for standard
		floppy disk drives, and 0-65535 for non-standard
		disk subsystems.
	SETSEC	Register CX contains the translated sector number
		for subsequent disk accesses on the currently
		selected drIve (see SECTRAN, below) . You can
		choose to send this information to the controller
		at this point, or instead del-ay sector selection
		until. a read or write operation occurs.

All Information Presented Here is Proprietary to T)iqital Research

62
CP/M-86 System Guide	5.4		BIOS Subroutine Entry Points

Table 5-4. (continued)
Subroutine		F 	Description

SETDMA			Register			CX contains the DMA (disk memory access)
	offset			for subsequent read or write overations.
	For example,			if CX = 80H when	SETDMA is called,
	then			all subsequent read operations read their
	data		into	80H	through	OFFH offset from the
	current		DMA segment base,			and	all subsequent
	write			operations	get their	data from that
	address,		until the next		calls	to SETDMA and
	SETDMA13 occur.			Note that the controller need not
	actually support direct memory access. If, for
	example,		all data			is received and sent through
	1/0 ports,				the CBIOS which you construct will use
	the 128 byte area starting at the selected DMA
	offset and base for the memory buffer during the
	followinq		read or	write	operations.
READ	Assuming		the drive	has	been selected, the teack
	has been set, the sector has been set, and the
	DMA of f set			and seqment base have been spec if ied,
	the READ subroutine attempts to read one sector
	based upon			these parameters,	and returns the
	following error codes in register AL:
		0		no errors occurred
		1		non-recoverable				error condition occurred
	Currently,				CP/M-86 responds only to a zero or
	non-zero		value as the return code. That is, if
	the		value	in	register AL	is	0 then rP/M-86
	assumes		that the	disk	operation completed
	properly.				If an error occurs, however, the CBIOS
	should attempt at least 10 retries to see if the
	error		is recoverable.		When an error is reported
	the BOOS will print the message "BDOS ERR ON x:
	BAD SECTOR".				The operator then has the option of
	typinq			RETURN to ignore the error, or CONTROL-C
	to abort.

WRITE		write the data from the currently selected DMA
	buffer to the currently selected drive, track,
	and sector. The data should be marked as "non
	deleted data" to maintain compatibility with
	other CP/M systems. The error codes given in the
	READ command are returned in register AL, with
	error recovery attempts as described above.
LISTST		Return the ready status of the list device. The
	value 00 is returned in AL if the list device is
	not ready to accept a character, and OFFH if a
	character can be sent to the printer.

All Information Presented Here is Proprietary to Digital Research

63
CP/M-86 System Guide	5.4	BIOS Subroutine Entry Points

Table 5-4. (continued)

Subroutine			Description
	SECTRAN	Performs	logical		to		physical sector translation
		to improve		the	overall	response of (7P/M-86.
		Standard CP/M-86 systems are shipped with a "skew
		factor" of	6, where five physical			sectors	are
		skipped	between sequential		read	or	write
		operations. This			skew factor allows enough	ti - me
		between sectors for	most oroqrams to load their
		buffers	without		missing the	next		sector.	Tn
		computer	systems		that		use fast processors, memory
		and disk subsystems, the	skew factor may		be
		changed to improve overall			response.	Note,
		however,	that	you should		maintain		a sinqle
		density IBM compatible	version of	CP/M-86	for
		information transfer into		and	out	of	your
		computer	system,			usinq a skew factor of 6.	In
		general,	SECTRAN		receives a logical sector number
		in CX.	This logical		sector number may ranqe from
		0 to'the	number		of sectors	-1.		Sectran also
		receives a translate table offset			in DX.	The
		sector	number	is used as	an	index into	the
		translate	table, with the		resulting physical
		sector	number in BX.		For standard systems, the
		tables	and indexing	code is provided in the CBIOS
		and need	not	be changed.	If	DX = OOOOH no
		translation takes place, and CX is simply copied
		to BX before		returninq.		Otherwise, 13ECTRAN
		computes and returns	the translated sector number
		in BX. Note that SECTRAN	is	caller] when no
		translation is specified in the Disk Parameter
		Header.
	SETDMAB	Register	CX contains the		seqment	base	for
		subsequent D%4A read	or write operations.	The
		BIOS will use the 128		byte buffer at the memory
		address determined	by the DMA base and the DMA
		offset	during read	and write operations.
	GETSEGB	Returns the address		of the Memory Reqion Table
		(MRT) in BX. The		returned	value is the offset of
		the	table relative to		the start of the operati.nq
		system.	The	table defines the			location	and
		extent	of physical memory which is available for
		transient programs.

All Information Presented Here is Proprietary to Digital Research

64
CP/M-86 System Guide	5.4		BIOS Subroutine Fntrv Points

Table 5-4. (continued)

Subroutine	Description

Memorv areas reserved for interrupt vectors and
the CP/M-86 operating system are not included in
the MRT. The Memorv Region Table takes the form:

8-bit

	MPT: 		R-Cnt
	0:			R-Base	R-Lenqth
	1:			R-Base	R-Lenqth

n:			R-Rase	R-Lenqth
	16-bit		16-bit

where R-Cnt is the number of Memorv Peqion
Descriptors (equal to n+l in the diaqram above),
While R-Base and R-Lenqth give the paragraph base
and length of each ohysicallv contiguous area of
memorv. '\gain, the reserved interrupt locations,
normall-v 0-3PFH, and the CP/M-86 operating svstem
are not included in this map, because the mat)
contains region-, avail-able to transient programs.
If all. mem.orv is contiquous, the R-C-nt fiell is I
and n = 0, with only a single Memorv Region
Descriptor which defines the region.

GETIOB		Returns	the current	value	of the logical to
	Phvsical			input/output device byte (IOBYTE~ in AL.
	This		eiqht-bit value	i-s	used toassociate
	ohvsical ievices with CP/M-86's four		logical
	devices.
SETIOR		Use the value in CL to set the value of	the
	IOBYTE stored in the BIOS.
		-ma

	The following section describes the exact layout and
	construction of the disk parameter tables referenced bv various
	subroutines in the BIOS.

All Information Presented Here is Proorietarv to Digital Research

65
	Section 6
BIOS Disk Definition Tables

	Similar to (7P/M-80, (7?/M-86 is a tabl-e-,Iriven operating system
	w i th a seaarate f ipld-conf iqurable Basic T/O Svstem (BIOS) . By
	altprinq soecific subroutines in the RIOq Presented in the Previous
	section, (-P/M-86 can be customized for operation on any RAM-based
	S086 or 9088 microorocessor svstem.

	The Puroose of this section is to Present the organization and
construction of tables within the BIn; that define the
characteristics of a Darti - cular disk svstern used with rP/M-86.
These tables can be either hand-coded or automatically generated
usinq the rFNlnFF utilitv orovided with CP/M-86. The elements of
these tables are oresente(i below.

6.1		Disk Parameter Table Format

	In qeneral-, each disk drive has an associated (16-bvte) disk
	oarameter header which both contains information about the ~9isk
	drive and oroviles a scratchoad area for certain BDOS ooerations.
	The format of the disk oarameter header for each drive is shown
	below.

r)i.qk Parameter Header
XLT		0000	0000		oooo	nTRBTJP	OPB	C";V 	ALV
1.6b		16b	16h	l6b	16b	16b	16b	16b

where each element is a word (16-bit) value. The meaning of each
nisk Parameter Reader (T)PH) element is given in Table 6-1.

Table 6-1. nisk Parameter-Header Elements
Plemen -I	nescription
t

XLT		Offset of the logical to Phvsical- translation vector,
	if used for this Particular drive, or the value OOOOH
	if no sector translation takes Place (i.e, the
	ohvsical and logical sector numbers are the same).
	nisk drives with identical sector skew factors share
	the same translate tables.
0000		Scratchoad values for use within the BT)OS (initial
	value is unimportant).

All Information Presented Here is Proprietary to Digital Research

67
CP/M-86 System Guide	6.1	Disk Parameter Table Format

Table 6-1. (continued)

Element 	Description

DIRBUF	Offset of a 128 byte scratchoad area for directory
operations within BDOS. All DPH's address the same
scratchpad area.

T)PB	Offset of a disk parameter block for this rlrivt,.
	Drives with identical disk character i. stics address the
	same disk parameter block.
rSV	Offset of a scratchoad area used for software check for
	changed disks. This offset is different for each T)P".
ALV	Offset of a scratchoad area used by the BDOS to keer)
	disk storage allocation information. This offset is
	different for each DP".

Given n disk drives, the DPF's are arranqed in a table whose first
row of 16 bytes corresponds to drive 0, with the last row
corresponding to drive n-l. The table thus appears as

DPBASE

00		XLT 00	0000	0000	0000	r)TRBUP 	DBP 00 	CSV 00 	ATW 00
01		XLT 01	0000	0000	0000	DIRBTIF 	DBP 01 	CSV 01 	ALV 01

(and so-forth throuqh)
n-l I XLTn-1 1 0000 1 0000 1 0000 1 DIRBTJF I DBPn-1 I (7SVn-1 I ALN7n- 1

where the label T)PBASF def ines the of f set of the DPH table rel ative
to the beginninq of the operating system.

	A responsibili.tv of the SELDSK subroutine, defined in the
	previous section, is to return the offset of the DDH from the
	beginninq of the ooeratinq system for the selected drive. The
	followinq seque*nce of operations returns the table offset, with a
	OOOOH returned if the selected drive does not exist.

All Information Presented Here is Proprietary to Digital Research

68
CP/M-86 System Guide	6.1		Disk Parameter Table Format

NIDISKS		EOU		4	;NUMBER OF DISK DRIVES

SELDSK:
;SELECT DISK N GIVEN BY CL
MOV		BX,OOOOH	;READY FOR ERR
	rPf4 CL,NDISKS		;N BEYOND MAX DISKS?
	JNB RETURN		;RETURN IF SO
		;0 <= N < NDISKS
	MOV CH'0		;DOUBLE (N)
	MOV BX'CX		;BX = N
	MOV CL,4		;READY FOR 16
	'; HL RX,rL		;N = N * 16
	MOV CX,OFFSET		DPBASE
	ADD 13X,CX		;DPBASE + N 16
RETURN: RET ;BX - OPH (N)

The translation vectors (XLT 00 through XLTn-l) are located
elsewhere in the BIOS, and simolv correspond one-for-one with the
logical sector numbers zero through the sector count-1. The Disk
Parameter Block (DPB) for each drive is more complex. A particular
OPB, which is addressed bv one or more DPH's, take / s the general
form:

SPT I 313H I BLM JEXM I DSM I DRM I ALO JALI I CKS I OFF

l6b			8b	8b	8b	l6b	l6b	8b	8b	l6b 	l6b

where each is a byte or word value, as shown by the "8b" or "16b"
indicator below the field. The fields are defined in Table 6-2.

Table 6-2. Disk Parameter Block Fields

	Field			Definition
	-SPT		is the total number of sectors per track
	BSH		is the data allocation block shift factor, determined
		by the data block allocation size.
	B LM		is the bl-ock mask which is also determined bV the data
		block allocation size.
	EXM		is the extent mask,	determined by the data block
		allocation size and the number of disk blocks.
	DSM		determines the total storage capacity of the disk drive
	D P-M		determines the total number of directory entries which
		can be stored on this drive

All Information Presented Here is Proprietary to Digital Research

69
CP/M-86 Svstem Guir3e	6.1		Disk Parameter Table Format

Table 6-2. (continued)

Field 	Definition

ALO,AL1	aetermine reserved airectorv blocks.

(7K',;	is the size of the directory check vector

OPP	is the number of reserved tracks at the beqinninq of
the (logical) disk.

A,lthouqh these table values are produced automatically by GENDEF, it
is worthwhile reviewinq the derivation of each field so that the
values may be cross-checked when necessary. The values of 13SH and
RLM determine (implicitly) the data allocation size 13LS, which is
not an entrv in the disk parameter block. riven that you have
selected a value for BLS, the values of T3SH and BLM are shown in
Table 6-3 below, where all values are in decimal.

Table 6-3. BSH and BLM Values for Selected BLS
B L S -7	B-13H	BLM

	1,024	3	7
	2,048	4	15
	4,096	5	31
	8,192	6	63
	16,384	7	127

The value of EXM depends uoon both the BLS and whether the DSM value
is less than 256 or greater than 255, as shown in the following
table.

Table 6-4. 14aximum EXM Values
BLS _TDSM < 256 1 DS'M > 255

	1,024	0	N/A
	2,048	1	0
	4,096	3	1
	8,192	7	3
	16,384	15	7

	The value of DSM is the maximum data block number supported by
	this particular drive, measured in BLS units. The product BLS times
	(DSM+l) is the total number of bytes held by the drive and, of
	course, must be within the capacity of the physical disk, not
	counting the reserved operating system tracks.

All Information Presented Here is Proprietary to Digital Research

70
CP/M-86 System Guide	6.1		r)isk Parameter -able Pormat

The DRM entrv is one less than the total number of directory
entries, which can take on a 16-bit value. The values of ALO and
AL1, however, are determined bv DRM. The two values ALO anrl ATA can
together be considered a strinq of 16-bits, as shown below.

ALO 	ALl
FTI I I I I 1=1 I I 1=
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15

where position 00 corresponds to the hiqh order bit of the byte
labeled ALO, and 15 corresponds to the low order bi.t of the hvte
labeled AL1. Each bit position reserves a lata block For a number
of directory entries, thus al-lowinq a total of 16 data bl.ocks to he
assigned for directorv entries (bits are assiqne(I startinq at 00 and
filled to the right until oosition 15). Each lirectorv entrv
occupies 32 bytes, as shown in Table 6-5.

Table 6-5. BLS and Number of Directory Entries

	BLI;		Directorv		Entries
	1,024		32		times	#	bits
	2,048		64		times	4	bits
	4,096		128		times	#	bits
	8,192		256		times	# 	bits
16,384		512 times #	bits

Thus, if DRM 127 (128 directory entries) , and 13LS = 1024, then
there are 32 directory entries per block, requirinq 4 reserved
blocks. In this case, the 4 h-iqh order bits of ALO are set,
resulting in the values ALO = OFOH and AL1 = OOH.

	The CKS value is determined as follows: if the disk drive
	media is removable, then CKS = (DRM+1)/4, where DRUM is the last
	directory entrv number. If the media is f ixed, then set CKS = 0 (no
	directory records are checked in this case).

	Finally, the OFF field determines the number of tracks which
	are skipped at the beqinninq of the physical disk. This value is
	automatically added whenever SETTRK is called, and can be used as a
	mechanism for skipping reserved operating system tracks, or for
	partitioning a large disk into smaller seqmented sections.

	To complete the discussion of the nPB, recall that several
	DPH's can address the same DPB if their drive characteristics are
	identical. Further, the DPB can be dvnamical-l-v chanqed when a new
	drive is addressed by simply changing the Pointer in the r)PH since
	the BDOS copies the DPB values to a local area whenever the SELDSK
	function is invoked.

All Information Presented Here is Proprietarv to niqital Research

71
CP/M-86 System Guide	6.1		T)isk Parameter Table Pormat

	Returning back to the nPH for a Particular drive, note that the
	two address values CSV and ALW remain. Both addresses reference an
	area of uninitialized memory foll-owinq the BInS. The areas must be
	unique for each drive, and the size of each area is determined by
	the values in the r)PB.

	The size of the area addressed by CSV is CKS bytes, which is
	sufficient to hold the directory check information for this
	particular drive. If CKS = (r)Rm+l)/4, then vou must reserve
	(DRM+I)/4 bytes for directorv check use. If CKS = 0, then no
	storage is reserved.

	The size of the area addressed by ALV is determined by the
	maximum number of data blocks allowed for this Particular disk, and
	is computed as (T)SM/8)+l.

	The BIOS shown in Appendix r) demonstrates an instance of these
	tables for standard 8" single density drives. It mav be useful- to
	examine this program, and comoare the tabular values with the
	definitions given above.

6.2		Table Generation Using GENDEF

	The GENr)EF utility supplied with CP/M-86 greatly simol if ies the
	table construction Process. GENDEF reads a fil-e

x.DP,F

containing the disk definition statements, and Produces an output
file

x.LIB

containing assembly language statements which def ine the tabl.es
necessarv to support a particula/r drive conf iquration. The form of
the GENDEF command is:

GENDEF x parameter list

where x has an assumed (and unsDecif ied) f iletvpe of DEP. The
parameter list may contain zero or more of the symbols defined in
Table 6-6.

Table 6-6. GENDEF Optional Parameters
Parameter		I 	Effect

$C	Generate Disk Parameter Comments
$0	Generate I)PBASE OFFSET $
$Z	Z80, 8080, 8085 Override
$r-0Z	(Any of the Above)

All Information Presented Pere		is Proprietary to Digital Research
	72
CP/M-86 System Guide	6.2		Table Generation Using GENDEF

	The C parameter causes GENDEF to produce an accompanying
	comment line, similar to the output from the "STAT DSK:" utility
	which describes the characteristics of each defined disk. Normally,
	the DPBASE is defined as

T)PBASE			EQU 	$

which requires a MOV CX,OFFSET DPBASE in the SELDSK subroutine shown
above. For convenience, the $0 Parameter Produces the definition

DPBASE			EQU	OFFSET $

allowing a MOV CX,r)PBASE in SELDSK, in order to match your
particular programming practices. The $Z parameter is included to
override the standard 8086/8088 mode in order to generate tables
acceptable for operation with Z30, 8080, and 8085 assemblers.

	The disk definition contained within x.r)EF is composed with the
	CP/M text editor, and consists of disk definition statements
	identical to those accepted by the DISKDEF macro supplied with CP/M4
	80 Version 2. A BIOS disk definition consists of the following
	sequence of statements:

DISKS		n
DISKDEF		0,...
OISKDEF		I ....

OISKDEF		n-1

ENDE_

Each statement is placed on a sinqle line, with optional embedded
comments between the keywords, numbers, and delimiters.

	The DISKS statement def ines the number of drives to be
	configured with your system, where n is an integer in the range I
	through 16. A series of DISKDEF statements then follow which define
	the characteristics of each logical disk, 0 through n-1,
	corresponding to logical drives A through P. Note that the DISKS
	and DISKDEF statements generate the in-line fixed data tables
	described in the previous section, and thus must be placed in a non
	executable portion of your BIOS, tvpical-Tv at the enl of your BIOS,
	before the start of uninitialized RAM.

	The ENDEF (End of Diskdef) statement generates the necessarv
	uninitialized RAM areas which are located bevond initialized RAM in
	your BIOS.

All Information Presented Here is Proprietary to Digital Research

73
CP/M-86 System ruide	6.2		Table qeneration Using rPNT)EF

The form of the T)TSKDEF statement is

DISKDEF		dn,fsc,lsc,fskfl,bls,dks,dir,cks,ofs,fOI

where

dn	is		the logical disk number, 0 to n-l
fsc	is		the first r)hvsical sector number (0 or 1)
Isc	is		the last sector number
skf	is		the optional sector skew factor
bis	is		the data allocation block size
dks	is		the disk size in bl-s units,
dir	is		the number of directorv entries
cks	is		the number of "checked" directorv entries
ofs	is		the track offset to logical track 00
[01	is		an optional 1.4 comoatibilitv flag

The value "dn" is the drive number being defined with this T)TSKT)PF
statement. The "fsc" parameter accounts for differing sector
numbering systems, and is usual-l,v 0 or 1. The "Iscl' is the 1-ast
numbered sector on a track. when present, the "skf" parameter
defines the sector skew factor which is used to create a sector
translation tabl-e according to the skew. If the number of sectors
is less than 256, a single-bvte table is created, otherwise each
translation table element occupies two bytes. No translation table
is created if the skf iDarameter is omitted or equal to 0.

	The "bls" parameter soecifies the number of bvtes allocated to
	each data block, and takes on the values 1024, 2048, 4096, 8192, or
	16384. Generally, performance increases with l.arger data block
	sizes because there are fewer directorv references. Also, logically
	connected data records are physicall-v close on the disk. 'Purther,
	each directorv entry addresses more data and the amount of 1310.17, work
	space is reduced. The "dks" snecifies the total disk size in "bTs"
	units. That is, if the bis = 2048 and dks = 1000, then the total
	disk capacity is 2,048,000 bytes. If dks is greater than 255, then
	the block size parameter bls must be greater than 1024. The value
	of "dir" is the total number of directorv entries which may exceed
	255, if desired.

	The "cks" oarameter determines the number of directorv items to
	check on each directorv scan, and is used internal.1-y to detect
	changed disks durinq system operation, where an intervening cold
	start or svstem reset has not occurred (when this situation is
	detected, CP/M-86 automatically marks the disk read/only so that
	data is not subsequently destroved) . As stated in the orevious
	section, the value of cks = dir when the media is easily changed, as
	is the case with a floppy disk subsystem. If the disk is
	permanently mounted, then the value of cks is typical-ly 0, since the
	t)robabilitv of changing disks without a restart is quite low.

All Information Presented Here is Proprietarv to T)igital Research

74
CP/M-86 Svstem Guide	6.2		Table Generation Using rFNnFF

	The "ofs" value determines the number of tracks to skip when
this particular drive is addressed, which can be used to reserve
additional operating system space or to simulate several loqical
drives on a single large canacitv physical drive. Finall-v, the [01
parameter is included when file compatibility is required with
versions of CP/M-80, version 1.4 which have been modified for hiqher
density disks (typically louble aensitv). This parameter ensures
that			no	directorv	compression takes place, which would cause
incompatibilities		with these non-standard CP/m 1.4 versions.
Normallv, this narameter is not included.
	For convenience and economy of table space, the special form
		OISKDEP 		i'l

gives disk i the same characteristics as a oreviouslv defined drive
1. Astandard four-1rive single Iensitv svstem, which is comoatible
with (P/M-SO Version 1.4, and ur)wardlv comoatible with CP/M-90
Version 2 imolementat ions, is -lefined usinq the followinq
statements:

DISKI;		4
DISKOEF		0,1,26,6,1024,243,64,64,2
T)ISKnFF		1,0
T)ISKDEF		2,0
DISKOEP		3,0
ENDEP

with al-1- disks having the same parameter values of 26 sectors per
track (num~)ered I through 26), with a skew of 6 between sequential
accesses, 1024 bytes per data block, 243 data blocks for a total- of
243Y, byte disk caoacitv, 64 checked directorv entries, and two
operating system tracks.

	The DISKS statement generates n Disk Parameter 9eaders (T)PH's)
	starting at the DPH table address T)PBASP generated by the statement.
	vach disk header bl-ock contains sixteen bytes, as described above,
	and corresponds one-for-one to each of the defined drives. In the
	four drive standard svstem, for example, the T)ISKS statement
	generates a table of the form:

DPBASE			EOU	$
T)PRO		DW	XLTO,OOOOH,OOOOH,OOOOH,DTRBTTP,OPBO,CSVO,ALITO
DPE1		T)W	XLTO,OOOOH,OOOOH,OOOOH,DTRBITF,T)PBO,CSVI,ALV1
DPE2		DW	XLTO,OOOOH,OOOOH,OOOOTi,DIRBTTP,DP90,C-.;N/2,ALV2
DPE3		T)W	XLTO,OOOOH,OOOOT4,0000H,DIRBTJP,OPBO,csv3,ALv3

where the DPH labels are included for reference purposes to show the
beginning table addresses for each drive 0 through 3. The values
contained within the disk parameter header are described in detail
earlier in this section. The check and allocation vector addresses
are generated by the ENDEF statement for inclusion in the RAM area
following the BIOS code and tables.

All Information Presented Here		is Proorietarv to r)iqital Research
	75
CP/m-86 System Guide	6.2	Table (,eneration TISing (7,FNIDIEF

	Note that if the "skf" (skew factor) parameter is ornitted (or
	equal to 0) , the translation tahle is omitted, and a 00009 value is
	inserted in the XLT position of the disk parameter header for the
	d i s -, . In a subsequent call to nerform the loqical to ohysical
	translation, SECTRAN receives a translation table address of T)X =
	OOOOH, and simply returns the original. loqical sector from CX in the
	BX register . A translate table is constructed when the skf
	parameter is present, and the (non-zero) table address is olaced
	into the corresponding DP9's. The table shown below, for example,
	is constructed when the standard skew factor skf = 6 is soeci f ied in
	the DISKDEF statement call:

XLTO	FOU	OFFSET S
DB	1,7,13,19,25,5,11,17,23,3,9,15,21
DB	2,8,14,20,26,6,12,18,24,4,10,16,22

	Following the ENDEF statement, a number of uninitialized data
	areas a-e def ined. These data areas need not be a part of the T3IOS
	which is loaded upon cold start, but must be available between the
	T310S and the end of operatinq svstem memory. The size of the
	uninitialized RAM 'area is determined by EOTJ statements generated by
	the ENDEF statement. For a standard four-drive svstem, the ENDEF
	statement, might produce

1(772 =	BEGT)AT FOU OFFSET 9
	(data areas)
10BO =	ENDT)AT EOU OFFSET $
013C =	DATSIZ FOU OFFqET $-RP(,DAT

which indicates that uninitialized RAM beqins at offset J(772H, ends
at 10BOH-1, and occupies 013CH bytes. You must ensure that these
addresses are free for use after the system is loaded.

	After modification, you can use the STAT program to check vour
	drive characteristics, since STAT uses the disk parameter block to
	decode the drive information. The comment included in the LIB file
	by the $(7 parameter to GENCMT) will- match the output from ';TAT. The
	STAT command form

STAT d:DSK:

decodes the disk parameter block for drive d (d=A,.-.,T)) and
displavs the values shown below:

r:		128 Byte	Record Capacity
k:		Kilobyte	T)rive Capacity
d:		32 Byte	Directory Entries
c:		Checked	Directory Entries
e:		Records/	Extent
b:		Records/	Block
s:		Sectors/	Track
t:		Reserved 	Tracks

All Information Presented Here is Proprietary to Diqital Research

76
CP/M-86 System Guide	6.3		GENDEF Output

6.3		GENDEF Output

	GENDFP produces a listing of the statements included in the DEF
	file at the user console (CONTROL-P can be used to obtain a printed
	listing, if desired) . Fach source line is numbered, and any errors
	are shown below the line in error, with a "?" beneath the item which
	caused the condition. The source errors produced by GENCMD are
	listed in Table 6-7, followed by errors that can occur when
	Producing input and output riles in Table 6-8.

Table 6-7. GENDEF Source Error Messages

Message			Meaning
Bad Val		More than 16 disks defined in DISKS statement.
Convert		Number cannot be converted, must be constant
	in binarv, octal, decimal, or hexadecimal as
	in ASM-86.
Delimit		Missing del-imiter between Parameters.
r)uPlic		Duplicate definition for a disk drive.
Extra		Extra Parameters occur at the end of line.
Length		Keyword or data item is too Tonq.
Missing		Parameter required in this position.
No Disk		Referenced disk not Previously defined.
No Stmt		Statement keyword not recognized.
Numeric		Number required in this position
Range		Number in this position is out of range.
Too Few		Not enough parameters provided.
Quote		missing end quote on current line.

All Information Presented Here is Proprietary to Digital Research

77
CP/M-86 System Guide	6.3	GENDEF Output

Table 6-8. GENDEF Input and Output Error Messages

Message	Meaning
Cannot Close ".LIB" File	LIB file close operation
	unsuccessful, usually due
	to hardware write protect.
"LIB" Disk Full	No space for LIB file.
No Input File Present	Specified DEF file not
	found.
No ".LIB" Directory Space	Cannot create LIB file due
	to too manv files on LTB
	disk.
Premature End-of-File	End of DEF file encountered
	unexpectedly.

Given the file TWO.T)EF containing the following statements

	disks	2
	diskdef		0,1,26,6,2048,256,128,128,2
	diskdef		1,1,58,,2048,1024,300,0,2
	endef
the command

	gencmd two $c
	produces the console output

DISKDEF Table Generator, Vers 1.0
1	DISKS	2
2	DISKDEF 0,1,58,,2048,256,128,128,2
3	DISKDEF 1,1,58,,2048,1024,300,0,2
4	ENDEF
No Error(s)

The resulting TWO.LIB file is brought into the following skeletal
assembly language program, using the ASM-86 INCLUDE directive. The
ASM-86 output listing is truncated on the right, but can be easily
reproduced using GENDEF and ASM-86.

All Information Presented Here		is Proprietary to Digital Research
	78
CP/M-86 System Guide	6.3		GENT)EP Output

	Sample Proqram includinq TUJO.Ll
	SELDSK:

0000 B9 03 00	MOV		(-X,OFPSETnPRASE

INCTTTDE TWO. T, 113
			D I,'; K q		2
0003	dpbase		equ	$		;13ase o
=			0003	32	00	00	00	dpeO	dw	xltO,OOOOh	;Transl
=			0007	00	00	00	00		r3w	OOOOh,OOOOh	;Scratc
=			OOOB	59	00	23	00		r1w	dirbuf,dpbO	;r)ir Ru
=			0 0 OV	F13	00	r) 13	00		d w	csvO'alv0	;Check,
=			0013	00	00	00	00	doel	dw	x!t!,OOOOh	;Transl.
=			0017	00	00	00	00		dw	OOOOh,OOOOh	;Scratc
=			001B	5B	00	4 C	00		dw	dirbuf,(3obl	;nir Bu
= OOIF 9B 01 IB 01	dw		csvl,al-vl	;(7heck,
DISKDFF 0,1,26,6,2048,2

r)isk 0 is (7P/M 1.4 Sinale 9ensi
			4096:		128 Bvte Recorl (ar)acit
			512:		Kilobyte T)rive	Caoacit
			128:		32 9vte nirectorv Pntri -
			128:		(hecked nirectorv Entri
			256:		Records	Pxtent
			16:		Records	Block
			2 6 :		Sectors	Track
			2:		Reserved	Tracks
			6:		Sector Skew Pactor
0023	dr)bO		equ			offset $	;r)isk P
=			0023	1A 00	dw	26	;Sector
=			0025	04	dh	4	;Block
=			0026	OF	db	15	;T31-ock
=			0027	01	rib	1	;Pxtnt
=			0028	FF 00	dw	255	;Disk S
=			002A	7F 00	dw	127	;T)irect
002C CO		db		192	;A.Iloco
002D 00		d b		0	;Allocl
002E 20 00		dw		32	;(7heck
0030 02 00		dw		2	;Offset
	0032	x1to		equ	offset	;Transl
	0032				01	07	OD 13	db	1,7,13,19
	0036				19	05	OB 11	dh	25,5,11,17
	003A				17	03	09 OF	db	23,3,9,15
	003E				15	02	08 OE	db	21,2,8,14
	= 0042				14	1A	06 OC	db	20,26,6,12
	= 0046				12	18	04 OA	db	18,24,4,10
	= 004A				10	16	db	16,22
0020	alsO		equ	32	;Al-loca
0020	csso		equ	32	;rheck
r)TSKDPP 1,1,58,,2048,10

Disk I is (7P/M 1.4 Sinqle nensi
16384: 128 T3vte Record (-ar)acit

All Information Presented Here is ProDrietarv to Diqital Research

79
CP/M-86 Svstem Guide		6.3		r.7ND7P nutout
	2 0 4 9	Ki I obvte T)r ive		Ca T)a c i t
	300:		32 Bvte r)irectorv	Fntri
	0 :		Checked r)irectorv 	Fntri,
				128:		Recor(9s	Fxtent
				16 :		',~ecord s	Block
				58:		Sectors	Track
				2:		Pe,;erved	Tracks
	)04C	dT)b 1	equ			offset 5		;r)isk P
01 4(7 3A 00		d w		58		; ~; e c t o r
004F 04		(3b		4		;!Block
004F OF		db		15		;'Block
0050		00		rl b	0	;Extnt
0051		Fr	03	dw	1023	;nisk S
0053		2B	01	dw	2q9	;r)i rect
0055		F8		(9b	248	;Alloco
0056		00		db	0	;Allocl
0057		00	00	dw	0	;rheck
0059		02	00	dw	2	; Of f- set
0000	xTtl	equ	0	;No Mra
0080	a I -, 1	equ	128	;k1loca
0000	cssl	equ	0	;Check
			ENDEF

Uninitialized Scratch Memorv Fo

005B	beqdat		equ	offset	;qtart
	005B	rl i r ~)u f		r s	129	;T)i rect
	OODB	al-vO	r s	a Ts 0	;Alloc
	= OOPB	csvo	rs	csso	;Check
	= 011B	a1v1-	rs	alsl	;Al-loc
	= 019B	csvl	rs	cssl	;Check
	0191B	endOat		eat)	offset $	;T1-nd of
	0140	datsiz		equ	offset $-beqdat	;qize o
019B 00		dh	0	;Marks
			ENT)

All Information Presented Here is Proorietary to Diqital Research

so
	Section 7
CP/M-86 Bootstrap and Adaption Procedures

	This section describes the components of the standard (-P/M-86
	distribution disk, the operation of each component, an-I the
	procedures to follow in adaotinq (-P/M-86 to non-standard harlware

	CP/M-86 is distributed on a sinql-e-densitv 113M compatible 8"
	diskette using a file format which is compatible with all previous
	CP/M-80 operating systems. Tn particular, the first two tracks are
	reserved for operating system and bootstrap oroqrams, while the
	remain,ler of the diskette contains directory information which leads
	to program and data files. CP/M-96 is distributed for ooeration
	with the Tntel SBC 86/12 sinqle-board computer connected to flooov
	disks through an Intel 204 Controller. The operation of CP/M-86 on
	this configuration serves as a mode! for other 8086 an,9 8088
	environments, and is presented below.

	The principal components of the distribution system are listed
	below:

 The 86/12 Bootstrap ROM (BOOT ROM)
 The Cold Start Loader 		(LOADER)
 The CP/M-86 System 	(CPM.SYS)

	T,Ihen installed in the SIFIC 86/12, the T300T ROM becomes a part of
	the memory address space, beqinninq at byte location OPFOOOH, and
	receives control when the system reset button is depressed. Tn a
	non-standard environment, the BnOT ROM is replaced by an equivalent
	initial loader and, therefore, the ROM itself is not included with
	CP/M-86. The BOOT ROM can be obtained from Digital Research or,
	alternatively, it can be programmed from the listinq qiven in
	Appendix C or directly frori the -source file which is included on the
	distribution disk as BOOT.A86. The resoonsibilitv of the 1300T ROM
	is to read the LOADER from the first two system tracks into memory
	and pass oroqram control to the LOADER for execution.

7.1		The Cold Start Load Operation

	The LOADER program is a simple version of CP/M-86 that contains
	sufficient file processing caoabilitv to read CPM.I;Y'; from the
	system disk to memory. When LOADER completes its operation, the
	('_PM.SYS program receives control and proceeds to process operator
	input commands.

	Both the LOADER and (PM.SYS r)roqrams are preceded by the
	standard CMn header record. The 128-bvte LOADER header record
	contains the following sinqle group descriptor.

All Tnformation Presented qere is Proprietary to Digital Research

81
CP/M-86 System Guide	7.1		The Cold Start Load Operation

8b	l6b	l6b	l6b	16b

where G-Form = 1 denotes a code group, "x" fields are ignored, and
A-Base defines the paragraph address where the T300T 'ROM begins
fillinq memory (A-Base is the word value which is offset three bytes
from the beqinninq of the header). Note that since only a code
group is present, an 8080 memory model is assumed. Further,
although the A-Base defines the base paragranh address for LOADER
(byte address 04000H), the LOADER can, in fact be loaded and
executed at any paragraph boundarv that does not overlap CP/M-86 or
the BOOT ROM.

	The LOADER itself consists of three parts: the Load CPM
	program (LDCPM) , the Loader Basic nisk System (LDBDOS) , and the
	Loader Basic 1/0 System (LDBIOS). Although the LOADER is setup to
	initialize CP/M-86 usinq the Intel 86/12 configuration, the LDBIOS
	can be field-altered to account for non-standard hardware using the
	same entry points described in a orevious section for BIO.S
	modification. The organization of LOADER is shown in Figure 7-1
	below:

CS DS ES SS 0000

G-Form		G-Lenqth	A-Base	G-Min 	G-Max
1		xxxxxxxxx	0400	xxxxxxx 	xxxxxxx

GD#1 		0
JMP 	1200H
(LDCPM)
JMPF CPM
(LDBDOS)
JMP 		INIT
JMP 		SETTOB
INIT: .. JMP 0003H
(LDBIOS)

0400

1200

170OH:

Figure 7-1. LOADER organization

All Information Presented Here		is Proprietary to Digital Research
	82
CP/M-86 System Guide	7.1		The Cold Start Load Operation

Byte offsets from the base registers are shown at the left of the
diagram. GD#l is the Grouo T)escriptor for the LOADER code group
described above, followed immediately by a "0" qroup terminator.
The entire LOADER program is read bv the BOOT ROM, excluding the
header record, starting at byte location 04000H as given by the A
Field. Upon completion of the read, the BOOT ROM passes control to
location 04000H where the LOADER vrogram commences execution. The
JMP 1200H instruction at the base of LDCPM transfers control to the
beginning of the LDBIOS where control then transfers to the INIT
subroutine. The subroutine starting at INIT performs device
initialization, prints a sign-on message, and transfers back to the
LDCPM program at byte offset 0003H. The LDCPM module opens the
CPM.SYS file, loads the CP/M-86 system into memorv and transfers
control to CP/M-86 through the JMPF CPM instruction at the end of
LDCPM execution, thus completing the cold start sequence.

	The files LDCPM.H86 and LT)BDOS.H86 are included with CP/M-86 so
	that you can append your own modified LDBIOS in the construction of
	a customized loader. In fact, BIOS.A86 contains a conditional
	assembly switch, called "loader bios," which, when enabled, produces
	the distributed LDBIOS. The INIT subroutine portion of LDBIOS is
	listed in Appendix C for reference purposes. To construct a custom
	LT)BIOS, mod i f y your standard BIOS to star t the, code at of f set 1200H,
	and change your initialization subroutine beginninq at INIT to
	perform disk and device initialization. Include a JMP to offset
	0003H at the end of your INIT subroutine. Use ASM-86 to assemble
	your LDBIOS.A86 proqram:

ASM86 LOBIOS

to produce the LDBIOS.H86 machine code file. Concatenate the three
LOADER modules using PIP:

PIP LOADER. H86=LDCPM.H86,LDBr)OS.H86, LDBIOS. H86

to produce the machine code file for the LOADER program. Although
the standard LOADER program ends at offset 1700H, vour modified
LDBIOS may differ from this last address with the restriction that
the LOADER must fit within the first two tracks and not overlaP
CP/M-86 areas. Generate the command (CMD) file for LOADER usinq the
GENCMD utilitv:

GENCMT) LOADER 8080 CODE(A4001

resulting in the file LOAT)ER.CMD with a header record defininq the
8080 Memory Model with an absolute T)aragraph address of 400H, or
byte address 4000H. Use DOT to read LOADER.CMD to location 900H in
your 8080 system. Then use the 8080 utilitv SYSGEN to copy the
loader to the first two tracks of a disk.

All Information Presented Here		is Proprietarv to Digital Research
	83
CP/M-86 System Guide	7.1		The ('old Start Load Overation

A>DDT
-ILOADER.CMD
-R800
- C
A>SYSGEN
SOURCE DRIVE NAME (or return to skip) <cr>
DESTINATION DRIVE NAME (or return to skip) B

Alternatively, if you have access to an operational Cp/m-86 system,
the command

LDCOPY LOADER

copies LOADER to the system tracks. You now have a diskette with a
LOADER program which incornorates your custom LDBIOS cavable of
reading the CPM.SYS file into memory. 'For standardization, we
assume LOADER executes at location 4000H. LOADER is staticallv
relocatable, however, and its operating address is determined on1v
by the value of A-Base in the header record.

	You must, of course, perform the same function as the BOOT ROM
	to get LOADER into memory. The boot operation is usuall-v
	accomplished in one of two ways. First, you can program vour own
	ROM (or PROM) to perform a function similar to the BOOT ROM when
	your computer's reset button is pushed. As an alternative, most
	controllers provide a T)ower-on "boot" oDeration that reads the first
	disk sector into memory. This one-sector Droqram, in turn, reads
	the LOADER from the remaining sectors and transfers to LOADER upon
	completion, thereby performing the same actions as the BOOT ROM.
	Either of these alternatives is hardware-specific, so vou'll need to
	be familiar with the operating environment.

7.2		Organization of CPM.SYS

	/The CPM.SYS file, read by the LOADER program, consists of the
	CCP, BDOS, and BIOS in CMD file format, with a 128-byte header
	record similar to the LOADER program:

G-Form		G-Length	A-Bas	G-min 	G-Max
1		xxxxxxxxx	040	xxxxxxx 	xxxxxxx

8b	l6b	l6b	l6b	l6b

where, instead, the A-Base load address is paragraph 040H, or byte
address 0400H, immediately following the 8086 interrupt locations.
The entire CPM.SYS file appears on disk as shown in Piqure 7-2.

All Information Presented Here is Pror)rietary to Digital Research

84
CP/M-86 Svstem Guide	7.2		organization of CPM-SYS

GD#1 10

(0040:0) CS DS ES SS OOOOH:

WCP and BDOS)

(0040:) 250OH:		JMP INIT

JMP SETIOB

(BIOS)

INIT: .. JMP OOOOH

(004002_A00H:

Figure 7-2. CPM.SYS File Organization

where (-,D#l is the Group Descriptor containing the A-Base value
followed by a "0" terminator. The distributed 86/12 BIOS is listed
in Aopendix D, with an "include" statement that reads the
SINGLES.LIB file containing the disk definition tables. The
SINGLES.LIB file is created by GENDEF using the SINGLES.DEF
statements shown below:

disks 2
diskdef 0,1,26,6,1024,243,64,64,2
diskdef 1,0
endef

	The CPM.SYS file is read by the LOADER program beginning at the
	address given by A-Base (byte address 0400H) , and control is passed
	to the INIT entry point at offset address 2500H. Any additional
	initialization, not performed by LOADER, takes place in the INIT
	subroutine and, upon completion, INIT executes a JMP OOOOH to begin
	execution of the rCP. The actual load address of CPM.SYS is
	determined entirely by the address given in the A-Base Irield which
	can be changed if you wish to execute CP/M-86 in another region of
	memory. Note that the region occupied by the operating system must
	be excluded from the BIOS memory region table.

	Similar to the LOADER program, you can modify the BIOS by
	altering either the BIOS.A86 or skeletal CBIOS.A86 assembly language
	f iles which are included on your source disk. In either case,
	create a customized BIOS which includes your specialized 1/0
	drivers, and assemble using ASM-86:

ASM86 BIOS

to produce the file BIOS.H86 containing your BIOS machine code.

All Information Presented Here is Proprietary to Digital Research

85
CP/N-86 System Gui6e	7.2		Or9Fn,1za-_ion of CPr..SYSz

C o ri,_-	c n T -_ 1- -- t h -i s n c- v.17 B:01~ to th,~ CPN.H83 f ~ --c or. yojr	s-, i ibu! ion
6 isk

PIP CPMX.HeG = CPM.1166,B:0S.h66

Thr_ L		SU: 'Ling CPNX hLX f il'C- i S	Iic~n	I tE_(~ tO C!'	f 1	f		by
i				~:~ 		I i - _		C) ri
excCuting
GENCMD CPNiX 8080 	CODE7LA40]

. Ln otdcr Lo produce the CMD m.mory iml--ge %JiLh 7~ - b c~	4 0 1,'
FinElly, rename the CPMX filc using the command

REN CPI,*,.SYS = CPMX.CMD

and place this file on your 6066 system disk. Now the t&iloring
process is complete: you hEve replaced the BOOT ROM by either your
own customized BOOT ROM, or a one-sector cold start loader which
brings the LOADER program, with your custom LDBIOS, into memory at
byte location b4000H. The LOADER program, in turn, reads the
CPM.SYS file, with your custom BIOS, into memory at. byte location
04001f. Control transfers to CP/M-86, and you are up F.nd operating.
CP/M-86 remains in memory until the next cold start operation takes
place.

	You can avoid the two-step boot operation if you construct a
	non-stEndard disk with sufficient space to hold the entire CPM.SYS
	file on the system tracks. In this case, the cold start brings the
	CP/M-86 memory image into memory at the location given by A-Base,
	and control transfers to the INIT entry point at offset 2500H.
	Thus, the intermediate LOADER program is eliminated entirely,
	although the initialization found in the LDBIOS must, of course,
	take place instead within the BIOS.

	Since ASM-86, GENCMD and GENDEF are provided in both COM and
	CMD formats, either CP/M-80 or CP/M-86 can be used/to aid the
	customizing process. If CP/M-80 ot CP/M-86 is not available, but
	you have minimal editing and debugging tools, you can write
	specialized disk 1/0 routines to re~,d and write the system tracks,
	as well as the CPM.SYS file.

	The two system tracks are simple to access, but the CPM.SYS
	file is somewhat more difficult to read. CPM.SYS is the first file
	on the disk and thus it appears immediately following the directory
	on the diskette. The directory begins on the third track, and
	occupies the first sixteen logical sectors of the diskette, while
	the CPM.SYS is found starting at the seventeenth sector. Sectors
	are "skewed" by a factor of six beginning with the directory track
	(the system tracks are sequential), so that you must load every
	sixth sector in reading the CPM.SYS file. Clearly, it is worth the
	time and effort to use an existing CP/M system to aid the conversion
	process.

All Information Presented Here is Proprittary to Digital Research

86
	Appendix A
Sector Blocking and Deblocking

	UDon each call t,-) the RTns 1,7PIT7 entrv or) i nt , the r~P /M-R6 T3T)0,1;
includes information that allows effective sector blockinq and
deblockinq where the host -lisk subsvst--,m has a sector size which is
a multiolp of the basic 122-bvte Linit. Th i anoendix orpsents a
qeneral-Diiroosp alqori-thm that can be inclu-1-(I w i - thin vour RTOq and
t ha. t		u .9 e s the B DO 1; i ri F n r ma t i o n to oerl:or-n t h ~- o --) e r a t i r) n s,
automaticalIv.

	T-TtDon each call to I~RJ'PF, the Rnnq r)r-)v;,rje,~; the Followinq
	inFnrmati,)n in re(iistpr (T.:

0	normal sector write
wri,te to ~Jjr-Ct(-)r~'7 ~;eCtnr
write to the First ~ect-r
nF a new (~ata hInc-k

Condition 0 occurq whenever 0~- noxt write ooeriti,)n i~-- i r) to a
oreviouslv written area, such -is a ran,!om mo,~e --cnrci	When
the ~,.,rite is to other thin the Fi-rz;t ~,Pctor -F an -inalloc,-it-d ~-Ilock,
or when the write is not into the -1irectnrv area. (' on,i i t i n ri I
occurs when a write into the directory ar~,a is oerFr)rme-1. r-r)nl i t i nn
2 occu r s when the F i r s, t record (on 1 v) o F a new 1 v a I I oca t-(4 da t a
block is written. Tn most cases, aor)l ic-itinn nrc),4rams rpa'~ -)r Write
multiole 129-hvte sectors in sequence, and th~j~, there i,7 1 ;ttl,,
overhead invol-ve,' in either noeration when lhlnckinq anl (I-hlockin"--I
records since ore-read onerations c,-an he 3vni(Ipci when writinq
records .

	This inpendix Tists the hlockinq and Oeblockinq alrinrithm in
	skeletal form (the f i 1 e i s i n c 1 Li d e (I o ri vo u r (-P PI - 9 6 d i s k ) .
	r',eneL ally, the al-qor i thms map al I (7P /M soctor rea(9 ooe rat i ons nn'Cr)
	the host disk throuqh an intermediate buffer which is the ;i-zp nF
	the host disk sector . Throuqhout the oroqram, values and variahl-es
	which relate to the CPM sector involved in a seek ooeratior are
	orefixed by "sek," while those related to the hos-t disk system are
	orefixed by "hSt." The equate statements heginrii.nq on line 24 --)f
	-Apr)pndix F define the manpinq between CP/M and the host system, and
	must be chanqed if other than the sample host system is invnlved.

	The SELnSK entry tDoint clears the host buFF--r Flaq whenever a
	new disk is loqqed-in. Note that althouqh the qELOSK (~ntrv noint
	computes and returns the Disk Parameter Reader address, it does not
	ohysically sel-ect the host di-sk at this ooint (it is selected later
	at REAWST or WRITERI;T) . Further, ';FTTRK, ';FTqFr, and qETnmA si.Mr)lv
	store the values, but do not take any other action at this noint.
	SP.CTRAN oerforms a trivial function of returninq the ohv9ical sector
	number.

All. rnformatinn Presented Herf- is Proorietarv to niqital Research

87
>	0. W W W w w w W W W W NJ W M t~j ~j tJ tJ m N) W H H H ~~ r- ~-j ~~ ~-j H H
r,	C) ~o OD j aN Ln A~b LA)	C) %D OD -,j m Ln j:b W N)	(D ~o W _j aN t_n ob w w ~-j o ~o w _j ai Ln ob w tj ~-j	7 ::r rr En rt rr s-:'	0 (n
		La -;- (D ~:r -3- ~j	_0 C:
		rr rD 0 (D (D	(D
rt.	rr	~-3
(n In cn	:X	" 0 :::r ::r M	0
rr rr ril x	0)	M	C:	0 0 X		3	rr C; -3	OD
	< ul	cr (n In La	0 (D I A	H	W cn U) _r	)-		ril	a)
	0) (D	r~ 10 H. P-	0	A	H. 0 - :3 1-0 :3,	0		rD	0 W. rD
	0	x rt N N	rt	I-r	4 ti r- 0 N~, ~-	~_h			:j	~n
	a rf)				Di (D :K (n		Cl 0			In :3
(D - i W
rt	(D ::r	* (n	In	rt 0) (D	1	0 ~D 0	() cn	(D
Fj.	ul r-h	(D (D (D (D	(D *		(D	D)		0) 0 0, 1~ CD w	(n (D		r" x	A 0	En	rt
0				0 (D			(D		C c)	r-t	0	-4 rt
									L
	0 F-			::r x	0 rl .a	rt			rl	> C
r-h cn	::r	0 0)			:j	0	cn	:3, -r		(n		0
	rt	cn ~3	10	(D		rD rl	(D	5	(D
::Y'	"	&.0	"1	(n	U)	" H-	0	U) zr		0	C 7 M
(D	(n	cn 0	w	~x	(D 0) 0 (D U) rr	rr	(n rr	a (D -3	(D w
En	w ~_j	rt	rt .0	* w 0 cn (D	0) 0 C: (A H.	0	rt.0 0 cy
(D	CD 0 un rj U)	U) tj	Cr * < X (D	0	L,)	C: (D	(D
::3	0. to F- Ln H-	tl- -	(n	~_j m	l<	0	0	0 :1	<
rt	OC) lob w 0) N	N ::r	rt	t1i LA)	r-l-	& Lo		:3 -	cn	rD (D
(D		(n	(n	00	(D	_Y'	0	0 10		1~	En	rD C;	in (D	-	:3

DA	Z rr	H.	'P.		D) w "		En	0	rh 0)	0)	0		w U)	rt " 0	rt
		N		7LI	:3	(D	cn	0 rt	:3 0)	0		Qj	::r rt (D gi	t-I
				rt	4 X cn		rr	rt		0A	x	>		F~	<
(D	rt x	H	(D U)	C;	0 OD	CL	H-	o	o x
rl	cn	0 -	~j	~-	'a	.3 a) A ~- ~-	~_4 "	_r

(D	rr	00	(D	0 ul	_-r U) "	U)
00		a,		-h	co	rr	Cli (D	(D	0 :c (D	En	(D	(D 0
OD	H	H	C) 0)	0 0	X			0	& '1 11	<	0)		>

ON 00 P. w x	Ath :1					U)					::Y. .,.		rr
											(D rt.				:x
	00 aj	aj (n		0	(D	X			0								-h
			t--- r1c Ln		0	U) 0		r- rt	(D		(D 0	(D			0			(D
				'd				(D		C	0~			0 (D	(D			ul
		LO	1-h H	i	En	0	0)			aj w	I			~14	in		l<		~l
							"' (D c;		0		0
U)	LX	(D N	rt	~-h		0	:3	cn
					w aj LA 0, cn	0			:3-	C:	x
(D		V 0 0 I'd	0)		7	0)				rt		ri-	(D
0		-, cn cn	~l	(D	<	::$	r_ l< ju	-		o
cn	En	& rt rt.	(D	:3	rt F~	rr	U)	1.4 .3, 0)	pl.		(D 		-r
(D							r, (D rt
rr		;::r			rt. cn (D 0	cn	aj !C 0' 0 (D rr	Z)		rr rt.	(D
	ob	rb	(D	co 04 ai 0)	ril U) 0		0) --0 ') " ,-	a	0		:r ti 0)
					H. ~- r~	0	M X		rr U) C; X (D 0			cr
D	rh	I" W 0 (D	(D
<	0 U) U) r~	rl	w			(D _r ~-j		C:	cn :3 x	rr
	rr x x 0			rr 0) cn		L-4 rh			(D			0
								cn			0
rr	(D	ul			rt	H 0 0		_ c	(D	0
0	~_j	*	I-, co cn 0)		t	Qj N	0 0-	rr rr 0	39 0
	0		:3' (D (D rt	lt	0) ::r	(D	(D	H.		U)	C
								0	r-r ~7 " 			Ln
		0 0 0	(D		(n F-	0	rt	0	:~ 		" (D 	(D
(A rr rlr 0		(D		rr W 0	0 C; U)	(D 0'	:1	rt	o t,	0 '0	-0
rr 0 0 ;:5	W		cr	:3 in	_h (D	cn		:3	w
	0		"		"		rl"		~__ U)	rr	(D	(D		VC	t-I	W
rt	m		U)			Lo			X (D F-	W	(1	tl	0) rt	-V rt 0)	(D	0 	~Dl
	(n Fl-	LO	0 C)	0	1	1	" 'r 1- 0	(D
-h rt	N	x					(D (D 0
" N (D	::r w
X (D	'0 cr	0) 	(D
(D	(D C: 10 '0 (n cn
U)	" --ti (D :Dr rr rt
(D	_h "		" -< U)	a (D		0
	0 (D		~-h En (D	U) e-	A	0
	tl	0 Fl-	X rt'	_r 	X
o	A	0	;31	-4 (lD	H.
	D 0)	0)	(D	-3 cn	:3
	Oj rr in		r- cn cA	"	Lil (D 	4
CP/M-86 System nuide	Appendix A		Blocking ancl T)ebl-ockinq

41:
42: secshf		equ	2	;l-oq2(hstbl.k)
43: cpmspt		equ	hstblk * hstsot ;(P/M sectors/track
44: secmsk		equ	hstblk-1	;sector mask
45:
46:
47:
48:	RDOS constants on entry to write
49:
50:
51: wrall		ecru	0	;write to allocated
52: wrdir		equ	I	;write to directorv
53: wrual		equ	2	;write to unallocated
54:
55:
56:
57:	The BIOS entry Points given below show the
58:	code which is relevant to dehlockinq only.
59:
60:
61: seldsk:
62:	;select disk
63:	;is this the first activation of the drive?
64:	test T)L,l	;lsb = 0?
65:	Inz selset
66:	;this is the first activation, clear host buff
67:	mov hstact,O
68:	mov unacnt,O
69: selset:
70:	mov al,cl ! cbw	;Put in AX
71:	mov sekdsk,al	;seek r1isk number
72:	mov cl,4 ! shl al,cl		;times 16
73:	add ax,offset dPbase
74:	mov bx,ax
75:	ret
76:
77: home:
78:	;home the selected disk
79:	mov a!-,hstwrt	;check for pending write
80:	test al,al
81:	inz homed
82:	mov hstact,O	;clear host active flag
83: homed:
84:	mov cx,O	;now, set track zero
85:	(continue HOME routine)
86:	ret
87:
88: settrk:
89:	;set track given by registers CX
90:	mov sektrk,CX	;track to seek
91:	ret
92: ;
93: setsec:
94:	;set sector given by register cl
95:	mov seksec,cl	;sector to seek

All Information Presented Here is PrODrietarv to Digital Pesearch

89
CP/M-86 System Guide	Nopendix A		Blockinq and r)pblockinq

	q6:	ret
	97: ;
	98: setdma:
	99:	;set dma address given bv CX
100: mov dma-off,(7x
101: ret
102: ;
103: setdmab:
104:	;set seqment address qiven bv C.X
105:	mov dma-seq,CX
106:	ret
107: ;
108: sectran:
109:	;translate sector number (X with table at [r)XI
110:	test r)X,T)X	;test for hard skewed
111:	jz notran	;(blocked must he hard skewed)
112:	mov BX,CX
113:	add 13X,r)X
114:	mov BL, [T3Xj
115:	ret
116: no-tran:
117:	;hard skewed 6isk, r)hvsical = logical sector
118:	MOV Bx,r7x
119:	ret
120: ;
121: read:
122:	;read the selected (7P/m sector
123:	mov		unacnt,O	;clear unallocated counter
124:	mov		readon,1	;read ooeration
125:	mov		rsflag,l	;must read data
126:	mov		wrtyDe,wrual	;treat as unalloc
127:	jmp		rwoper	;to oerform the read
128: ;
129: write:
130:	;write the selected rP/M sector
131:	mov		readoT),O	;write ooeration
132:	mov		wrtype,cl
133:	cmp		cl,wrual	;write unall-ocated>
134:	jnz		chkuna	;check for unal.1-oc
135:
136:	write to unallocated, set oarameters
137:
138:	mov unacnt,(blksiz/128) ;next unall-oc recs
139:	mov		al-,sekdsk	;disk to seek
140:	mov		unadsk,al	;unadsk = sekdsk
141:	mov		ax,sektrk
142:	mov		unatrk,ax	;unatrk = sektrk
143:	mov		al,seksec
144:	mov		unasec,al	;unasec = seksec
145:
146: chkuna:
147:	;check for write to unall-ocated sector
148: ;
149:	mov bx,offset unacnt	;point "UNA" at TJNAr.',IT
150:	mov al,una ! test a!-,al		;any unal-loc remain?

All Information Presented Here is Proprietary to Digital Research

90
CP/M-86 Svstem Guide	Ar)r)endix A		13lockinq an(9 Deblockinq

151:	jz al.loc	;skip i.-' not
152:
153:	more unallocated records remain
154:	dec a!	;unacnt = unacnt-1
155:	mov una,al
156:	mov al,sekdsk	;same disk?
157:	mov BX,offset unadsk
158:	cmQ al,una	;sekdsk = una(~skl'
159:	inz alloc	;skio if not
1-60:
161:	disks are the same
162:	mov AX, unatrk
163:	cmp AX, sektrk
164:	inz alloc	;skio if not
165:
166:	tracks are the same
167:	mov al-,seksec	;same sector'
168:
169:	mov RX,offset unasec		;ooint una at unasec
170:
171:	cmr) al,una	;seksec/= unasec"'
172:	jnz all-oc	;skio if not
1-73:
174:	match, move to next sector for future ref
175:	inc una	;unasec = unasec+1
176:	mov al,una	;end of track?
177:	cmp al,cpmspt	;count CP/M sectors
178:	lb noovf	;skio if below
179:
180:	overflow to next track
181:	mov una,O	;unasec = 0
182:	inc unatrk	;unatrk=unatrk+l
183:
184: noovf:
185:	;match found, mark as unnecessarv real
186:	mov rsflag,O	;rsflag = 0
187:	imps rwoper	;to aerform the write
188: ;
189: alloc:
190:	;not an unallocated record, requires ore-read
191:	mov unacnt,O	;unacnt = 0
192:	mov rsflaq,l	;rsfl-aq = 1
193:		;drop throuqh to rwooer
194:
195:
196:
197:	(ommon code for REAn and WRITE follows
198:
199:
200: rwoper:
201:	;enter here to perform the read/write
202:	mov erflaq,O	;no errors (vet)
203:	mov al, seksec	;comvute host sector
204:	mov cl, secshf
205:	shr al,cl

All Information Presented Here is Proori.etarv to nigital Research

91
CP/M-86 System (-uide	Appendix A		Rlockinq and T)eblockinq

2 0 6	mov sekhst,al	;host sector to seek
2 0 7
208:	active host sector-)
209:	mov al'I
210:	xchq al,hstact	;alwavs becomes 1
211:	test al,al	;was it al-readv?
212:	1z filhst	;fill host if not
213:
214:	host buffer active, same as seek buffer",
215:	mov al,sekdsk
216:	cmiD al. hst(lsk	;sekdsk = hstlsk"'
217:	inz nomatch
218:
211):	same disk, same track'~'
220:	mov ax,hsttrk
221:	cmp ax,sektrk	;host track same as seek track
922:	inz nomatch
2 2 3 :
224:	same disk, same track, same buffer)
225:	mov al.,sekhst
2 2 6 :	cmn al-,hstsec	;sekhst = hstsec"
227:	1z match	;skir) if match
228: nomatch:
229:	;nrooer disk, but not correct sector
230:	mov al, hstwrt
231:	test al,al	;"r3i rtv" hu'Ffer '>
2 3 2 :	1z fil-hst	;no, (9on't nee(9 to write
233:	call writehst	;yes, clear host buff
234:	(check errors here)
2 3 5 :
236: riThst:
237:	;mav have to Fill the host buffer
238:	mov al,sek-Isk ! mov hstrisk,al
239:	mov ax,sektrk ! mov hsttrk,ax
240:	mov al,sekhst ! mov hstsec,al
241:	mov al-'rsflaq
242:	test al-,al-	;need to rOad'~'
243:	jz filhstl
2 4 4 : ;
2 4 5 :	cal.1- readhst		ves , i f 1
246:	(check errors here)
2 4 7 :
248: filhstl:
249:	mov hstwrt,O	;no pendinq write
250: ;
251: match:
2 5 2 :	;copy data to or from buffer deDendinq on "readon"
253:	mov al,seksec	;mask buffer number
254:	and ax,secmsk	;least siqnif bits are masked
2 5 5:	mov cl, 7 ! shl. ax,cl	;shift left 7 (* 128 = 2**7)
256:
257:	ax has relative host buffer offset
2 58 :
259:	add ax,offset hstbuf	;ax has buffer address
260:	mov si,ax	;put in source index reqister

All Information Presented Fere is Proprietary to T)iqital Research

92
CP/M-86 Svstem Guide	Appendix A		Blocking and T)eblockinq

261:	mov di,dma-off	;user buffer is dest if readop
262: ;
263:	push OS ! push ES	;save seqment registers
2 6 4
265:	mov "FS,dma-seq	;set destseq to the users seg
266:			;SI/T)l and DS/ES is swapped
267:			;if write op
268:	mov cx,128/2	;length of move in words
269:	mov al,readop
270:	test al,al	;which way?
271:	inz		rwmove	;skip if read
27 2:
273:	write oueration, mark and switch direction
274:	mov hstwrt,1	;hstwrt = I (dirty buffer now)
275:	xchq si,di	;source/dest index swap
276:	mov ax,nS
277:	mov ES,ax
278:	mov DS,dma-seq	;setuD nS,ES for write
279:
280: rwmove:
281:	c1d !/rep movs AX,AX		;move as 16 bit words
282:	pop ES ! oop DS	;restore segment registers
283 : ;
284:	data has been moved to/from host buffer
285:	cmD wrtype,wrdir	;write type to directorv?
286:	mov al,erflag	;in case of errors
287:	jnz return-rw	;no further orocessinq
288:
289:	clear host buffer for directory write
290:	test al,al.	;errors?
291:	jnz return_rw	;skip if so
292:	mov hstwrt,O	;buffer written
293:	call writehst
294:	mov al,erflaq
295: return-rw:
29-5:			ret
2 97 : ;
298:
299:
300:		WRITFHST performs the physical write to the host
301:		disk, while READHST reads the physical disk.
302:
303:
304: writehst:
305: 	ret
30 6 : ;
307: readhst:
308:	ret
309:
310:
311:
312:		Use the GENnEF utilitv to create disk def tables
313:
314:
315: dpbase equ		offset $

All Tnformation Presented Here is Droorietary to T)iqital Research

93
CP/M-86 System ruide	Apoendix A		Blocki-nq and T)ehlockinq

316:		disk i)arameter tables qo here
3 17:
318:
3 19:
320:	Uninitialized RAM areas follow, includinq the
321:	areas created bv the rE-NDFP util-itv listed above.
322:
323:
324:		sek dsk rh	I	;seek disk number
325:		sek trk rw	1	;seek track number
326:		sek-sec rb	1	;seek sector number
3 2 7 :		;
328:		hst dsk rb	1	;host disk number
329:		hst trk rw	1	;host track number
330:		hst-sec rb	I	;host sector number
331:		;
332:		sek hst rb	1	;seek shr secshf
333:		hst act rb	1	;host active fl-aq
334:		hst-wrt rb	1	;host written flaq
335:		;
336:		una cnt rb	1	;unall.oc rec cnt
337:		una risk rb	1	;last unalloc disk
338:		una trk rw	1	;I-ast unalloc track
339:		una sec rb	1	;last unalloc sector
340 : 		;
341:		erflag	rb	I	;error reoortinq
342:		rsflaq	rb	1	;read sector flaq
343:		readop	rb	1	;1 if read or)eration
344:		wrtvpe	rb	1	;write or)eration tvr)e
345: dma seq		rw	1	;last (Ima seqment
346: dma off		rw	1	;Tast r3ma offset
347: hstSuf		rb	hstsiz	;host buffer
348: 	end

AU Information Presented Here is Pror)rietarv to T)iqital- Research

94
	Appendix B
Sample Random Access Program

	This appendix contains a rather extensive and comol-pte examole
of random access ooeration.	The r)roqram listed here oerforms the
	function of readinq or writinq random records upon command
f rom the terminal. (7-iven that the oroqram has been	created,
assembled, and placed into a	lahell-ed PzkNr)nm.c"n, the rrv level
c,:)mmand :

RANMOM X.DAT

,;tarts the test orogram. The oroqram looks For a Fil~,- hv the name
X.r)AT (in this oartictilar case) and, if Foiind, oroce~eds to promot
the console for innut. If not found, the cile is create,-', before the
orompt is given. Each prompt takes the form

next command?

and is fol-lowed by ooerator input, terminated bv a carri-aqe return.
The inout commands take the form

nTq		nR 	n

where n is an inteqer value in the ranqe 0 to 65535, and W, R, and
are simple command characters corresponding to random wri.te, random
read, and quit processinq, re-,oectivelv. If the T.7 command is
issued, the RANMOM proqram issues the prompt

tvoe data:

The ooerator then resoonds by tvninq ur) to 127 characters, foll.owed
by a carriaqe return. RANT)OM then writes the character stri'riq i.nto
the X.r)AT f ile at record n. If the R command is issued, RAW)OM
reads record number n and displays the strinq value at the console.
If the Q command is issued, the X.T)AT file is closed, and the
program returns to the console command processor. The onlv error
message is

error, trv again

	The program beqins with an initialization section where the
	input file is onened or created, followed by a continuous loop at
	the label "ready" where the individual commands are interoreted.
	The default file control block at offset 005CH and the default
	buffer at offset 0080H are used in al-I disk operations. The uti.litv
	subroutines then follow, which contain the principal input 1-ine
	processor, called "readc." This particular groqram shows the
	elements of random access processinq, and can be used as the basis
	for further proqram development. In fact, with some work, this
	orogram could evolve into a simple data base management svstem.

All Information Presented Here		is Proorietary to Digital Research
	95
CP/M-86 qystem Guide	Appendix 'B	qamDle Random Access Droaram

	One could, for example, assume a standard record size of 12P
	bytes, consisting of arbitrarv fields within the recorl. A oroaram,
	called GETIKEY, could be developed which first reads a seauential
	file and extracts a soecific fie'(! defined bv the ooerator. Por
	example, the command

GETKEY NAMES.T)AT T,W;TNAME 10 20

would cause GETKFY to read the data base file NAMPS.T)AT and extract
the "LASTNAMP" field from each record, starting at position 10 and
ending at character 20. rE1"KFY builds a table in memorv consistinq
of each particular LASTNAME field, alonq with its 16-bit record
number location within the file. The rErKFY proqram then sorts this
1 i s t , a nd wr i tes a new f i Te , ca 1. 1 ed LAC;TNAMF. KEY, wh i ch i C, an
alphabetical list of LASTNAMT1. f ields with their corresoondinq record
numbers. (This list is cal-led an "inverted index" in information
retrieval parlance.)

	Rename the proqram shown above as OTTPRY, and enhance it a bit
	so that it reads a sorted key file into memory. rrhe commanrl I i.ne
	might appear as:

OUFRY NAIMES.nAT LASTNAME.KPY

Instead of reading a number, the nT7ERY proqram reads an alphanumeric
string which is a particular kev to find in the NAMES.T)AT data base.
Since the LASTNAME.KEY list is sorted, vou can find a particular
entry quite rapidly by performing a "binary search," similar to
looking up a name in the telephone book. That is, starting at both
ends of the list, you examine the entry halfwav in between and, if
not matched, split either the upper half or the lower half for the
next search. You'll quickly reach the item you're Tooking for (in
log2(n) steps) where you'll find the corresoondinq record number.
Fetch and display this record at the console, lust as we have done
in the proqram shown above.

	At this point you're just qettinq started. With a little more
	work, you can all-ow a fixed grouping size which differs from the 128
	byte record shown above. This is accomplished by keeoi.nq track of
	the record number as well as the byte offset within the record.
	Knowing the group size, you randomly access the record containinq
	the proper grout), offset to the beqinninq of the qroup within the
	record read sequentiall-v until- the group size has been exhausted.

	Finally, you can improve QUERY considerably by allowing boolean
	expressions which compute the set of records which satisfy several
	relationships, such as a LASTNAME between HARDY and LAUTZEL, and an
	ACE 1 ess than 45. T) i sp! av all the records which fit this
	description. Finally, if your lists are gettinq too biq to fit into
	memory, randomly access your key files from the disk as well.

All Information Presented Here is Proprietary to r)iqital Research

96
CP/M-86 System Guide		Appendix B	Random Access SamDl-e Proqram

2:
3:
4:		qamr)le Random Access 'Proqram for (7P/M-86
5:
6:
7:
8:		BOOS Punctions
	9:
	10:		coninp	equ	I	;consol.e inout function
	11:		conout	equ	2	;console outout ftinction
	12:		astrinq	equ	9	;orint strinq until
	13:		rstrinq	equ	10	;read console buffer
	14:		vers ion	eclu	12	;return version number
1-9:		or)enf	equ	15	;file ooen function
16:		closef	equ	16	;cl.ose function
17:		makef	equ	22	;make File Function
18:		readr	equ	33	;rea(i random
19:		writer	equ	34	;write random
20: 		;
21: ;					7cruates for non qVaohic characters
22: cr						equ	Odh	;carriaqe return
2 3 : If						eCrU	Oah	;line Feed
24:
25:
26:			load qP, readv fi.le for random access
2 7 :
28:					cseq
29:	pushf			;oush flaq-q in ((P stack
30:	OOD		ax	;save flaqs in AX
31:	cl.i			;(iisahle interruots
32:	mov		bx,ds	;set Sq reqister to base
33:	mov		ss,bx	;set SS, qP with interru
34:	mov		so,offset stack	;	for 80888
35:	push		ax	;restore the FTaqs
3 6 :	DOIDf
37:
38:	CP/M-86 initial release returns the fi.le
39:	system version number of 2.2: check is
40:	shown bel-ow for illustration ourooses.
41:
42:	mov		cl,version
4 3 :	ca I- I		bdos
44:	CMP		al,20h	;version 2.0 or later?
45:	inb		versok
46:		bad version, messaqe and qo back
47:	mov		dx,offset hadver
48:	call		print
49:	imp		abort
50:
51: versok:
52:	correct		version for random access
53:	mov		cl,openf	;ooen default fct
54:	mov		dx,offset fcb
55:	call 		hdos

All Information Presented Rere is Proprietarv to niqital- Research

97
CP/M-86 System Guide	Avvendix B	Random Access Sample Program

56:	inc	al	;err 255 becomes zero
57:	jnz	readv
58:
59:	cannot or)en file, so create it
60:	mov	cl,makef
61:	mov	dx,offset fcb
62:	call.	bdos
63:	inc	al	;err 255 becomes zero
64:	inz	ready
65:
66:		cannot create file, directorv full.
67:		mov	dx,offset nospace
68:		call	print
69:		imp	abort	;back to ccp
70:
71:	Toor) back to "ready" after each command
72:
73: ready:
74:	file is ready for vrocessinq
75:
76:	call	readcom	;read next command
77:	mov	ranrec,dx	;store input record#
78:	mov	ranovf,Oh	;clear high byte if set
79:	CMP	al,'O'	;quit?
80:	inz	notq
81:
82:	quit processing, close file
83:		mov	cl,closef
84:		mov	dx,offset fcb
85:		call	bdos
86:		inc	al	;err 255 becomes 0
87:		jz	error	;error message, retry
88:		jmps	abort	;back to ccp
89:
90:
91:	end of quit command, process write
92:
93:
94: notq:
	95:	not the		auit command, random write?
	96:	cmp	al,'T,?'
	97:	inz	notw
	98:
	99:	this is		a random write, fill buffer until cr
	100:	mov	dx,offset datmsq
	101:	call	print	;data prompt
	102:	mov	cx,127	;up to 127 characters
	103:	mov	bx,offset buff 	;destination
104: r1oop: ;read next character to buff
105:	push	cx	;save loop conntrol
106:	push	bx	;next destination
107:	call	getchr	;character to AL
108:	pot)	bx	;restore destination
109:	POP	cx	;restore counter
110:	cmp	al,cr	;end of line?

All Information Presented Here is Proprietary to Digital Research

98
CP/M-86 Svstem Guide	Ar)t)endix 11:3	Panlom Access qaMOle PrOOraT

166:	pop	cx
167:	loon	W, o0p	;decrement rX and check
168:	imp	readv
169:
170:
171:	end of read command, all errors end-ur) here
172:
173:
174: error:
175:	mov	dx,offset errmsq
176:	call-	Orint
177:	imp	ready
178: ;
179: ; T3DOS entrv subroutine
-80: bdos:
181:	int	224	;entrv to 'Rnnq if by TNT
182:	ret.
183: ;
184: abort:			;return to ((7P
185:	mov	c]'O
186:	call	bdos	;use function 0 to end e
187: ;
188:	utility subroutines for console i/o
189:
190: getchr:
191:	;read next console character to a
192:	mov	cl,conino
193:	call	bdos
lq4:	ret
195: ;
196: outchr:
197:	;write character from, a to console
198:	mov	cl.,conout
199:	mov	(11-,al	;character to send
200:	call	bdos	;send character
201:	ret
2 0 2 : ;
20 3 : crif:
204:	;send carriaqe return line feed
205:	mov	al,cr	;carriaqe return
206:	call	putchr
207:	mov	al,lf	;line feed
208:	call	outchr
2 09 :	ret
210:
211: print:
212:	;print the buffer addressed by dx until 8
213:	push	dx
214:	call	crlf
215:	POP	dx	;new Tine
216:	mov	cl,vstrinq
217:	call	bdos	;print the strinq
218:	ret
219:
220: readcom:

All Information Presented Here is Pronrietarv to T)iqital- Research

100
CP/M-86 Svstem Guide		Appendix 9	Random Access Samale Program

221:	;read the next command line to the conbuf
222:	mov		dx,offset promot
223:	call		r)rint	;command)
224:	mov		cl,rstrinq
225:	mov		dx,offset conbuf
226:	call		bdo.s	;rea(3 command line
227:	command line is present, scan it
228:	mov		ax,O	;start with 0000
229:	MOV		bx,offset conlin
230: readc:		mov	(91,[bxl	;next command character
231:	inc		bx	;to next command onsitir)
232:	Mov		dh,O	;zero high bvte for add
233:	or		(11'ril	;check for end of comman
234:	~nz		getnum
2 3 5	ret
236:	not zero, numeric"
237: qetnum:
238:	-,ub		al'-0
239:	CMD		(31,10	;carrv if numeric
240:	~nb		endrd
2 4 1 :	Mov		cl , 10
242:	mul			cl	;multipv accumulator bv
2 4 3 :	add			ax,dx	; +d i-q i t
244:	imps				readc	;for another char
245: endrd:
246:	end of read, restore value in a and return value
2 4 7 :	mov		dx,ax	;return value in nx
248:	mov		al,-I(bxl
249:	CMP		al,'a'	;check for lower case
250:	!nb		transl
251:	ret
252: transl: and		al.,5fT4	;transl.ate to uoper case
253:				ret
254:
255:
256:			Template for Page 0 of r)ata GrOUD
257:				Contains default FCB and OMA buffer
258:
259:				dseq
260:	org		05ch
261: fcb		rb	33	;rlefault file control bl
262: ranrec		rw	I	;random record oositinn
263: ranovf		rb	I	;high order (overflow) b
264: buff		rb	128	;default DMA buffer
265: ;
266: ; string data area for console messages
267:		badver	(lb	sorrv, vou need cn/m version 2q'
268:		nospace	db	no r1irectorv soace$A
269:		datmsq	db	'tvpe (lata: $A
270:		errmsq	1b	A error, trv aqain.SA
271:		prompt	rib	next command? 5'
2 7 2
27 3
274:		fixed and variable data area
275:

All Information Presented Here is Proorietarv to niqital- Research

101
CP/M-86 qystem ruide	Ar)npn(9ix B	Random Access qamDle Proqram

276:		conhuf dh	conlen	;'--nath of console huffer
277:		consiz rs	1	;re~,ulti-nq size after read
278:		conlin rs	32	;Ipnqth 32 buffer
279:		conlen equ	offset S - offset consiz
2 8 0 : 	;
281:	rs	31	;16 level stack
282: stack	rb	1
283:	db	0	;en,9 byte for rPN(-Mn
284: 	end

All Information Presented Here is Proprietarv to T)iqi,tal Research

102
	Appendix C
Listing of the Boot ROM

~his is the original- 1300T ROM distributed with CP/M
for the SBC 86/12 and 204 Controller. The listing
is truncated on the right, but can be reproduced by
assembling ROPI.A86 from the distribution disk. Note
that the distributed source file should alwavs be
referenced for the latest version

ROM bootstrap		for CP/M-86 on an iSB('86/12
with the
Intel SBC 204 Floppy Disk Controller

(7opvright (c) 1980,1981
Digital Research, Inc.
Box 579, Pacific rrove
California, 93950

This is the BOOT ROM which is initiated *
by a svstem reset. Pirst, the ROM moves *
a copy of its data area to RAM at I-oca- *
tion OOOOOH, then initializes the seqment*
registers and the stack pointer. The
various peripheral interface chips on the*
SBr 86/12 are initialized. The 8251
serial interface is configured for a 9600*
baud asvnchronous terminal, and the in
terrupt controller is setup for inter
ruots 1OH-17H (vectors at 000404-0005FH)
and edqe-triqqered'auto-POI (end of in
terruot) mode with all interrupt levels
masked-off. Next, the SBC 204 Diskette
controller is initialized, and track 1
sector I is read to determine the target
paragraph address for LOADER. Finall-v,
the LOADER on track 0 sectors 2-26 and
track 1 sectors 1-26 is read into the
target address. Control then transfers
to LOADER. This program resides in two
2716 FPROM's (2K each) at location
OFFOOOH on the SBC 86/12 CPU board. ROM
0 contains the even memorv locations, and*
ROM 1 contains the odd addresses. 1300T
ROM uses RAM between OOOOOH and OOOFFT;
(absolute) for a scratch area, alonq with*
the sector I buffer.

All Information Presented Here is Propri-etary to Diqital Research

103
CT~'"-86 ';Ystem ruide	Anpenriix C		Listinq of the BOOT Rr)M

OOF7	true	Pau	OF f h
FFOO	false	equ	not true
OOFV	debuq	equ	true
	;debuq = true indicates			bootstrao is in same roms
	;with SBC 957 "Execution Vehicle" monitor
	;at FIE00:0 instead of 'PPOO:O

000D	cr	equ	13
OOOA	if	equ. 	1.0

disk norts and commands

OOAO	base204	equ	OaOh
OOAO	friccom	equ	base204+0
OOAO	fdcstat	equ	base204+0
OOA1	fdcoarm	equ	base204+1
OOA1	fdcrslt	eau	base204+1
OOA2	fdcrst	ecru	base204+2
OOA4	dmacadr	equ	base204+4
OOA5	dmaccont	equ,	base204+5
0OA6	dmacscan	equ	base204+6
OOA7	dmacsadr	equ	base204+7
OOA8	dmacmode	equ	base204+8
OOA8	dmacstat.	equ	base204+8
OOA9	fdcsel	equ	base204+q
OOAA	frlcseqment	equ	base204+10
OOAF	reset204	equ.	base204+15

	;actual console		baud rate
2580	baud rate	P-CfU 	9600
	;value for 8253 baud counter
0008	baud	eau	768/(baud-rate/100)

OOT)A	cst,,-	equ	Or)Ah	;i8251 status oort
OOD8	cdata	equ	OT)8h		data oort
OODO	tchO	equ	Or)Oh	;8253 PIC channel 0
OOD2	tchl	equ	tchO+2		;ch 1 Dort
OOD4	tch2	equ	tchO+4		;ch 2 port
OOD6	tcm(9		equ	tchO+6		;8253 commanrl oort
00CO	icpl		equ	OCOh	;8259a i)ort 0
OOC2	ico2		equ	0(72h	;8259a oort 1
		TP NnT DV,13TTr,
	ROMSEr,			EOU	OF17009	;normal
		ENDIF
		IF DEBUG			;share orom with qR
FEOO	ROMSEr.			EM	OPPOOR
		PNT)TF

All Information Presented Here is 'Proorietarv to T)i.qital Research

104
CP/M-86 System Guide	AiDpendix 17		Listing of the 900T POM

'Phis long jump orom'd in by hand
cseg		Offffh		;reset qoes to here
JMPF		90TTONI		;boot is at bottom
EA 00 00 00 PF			;CS = ~Dottom of Oro
				ip = 0
WPIN PROM		ODn PROM
7P8 - FA		7PR - 00
779 - 00		7F9 - 00
7PA - PP			;this is not done i

FFOO		cseq		romseq
	;Pirst,		move our data area into RAM at 0000:0200
0000 8C(-8	mov ax,cs
0002 8Fn8	mov (9s,ax	;ooint r)S to Cq for source
0004 9E3FOI	mov ST,drnmbeqin			;start of (lata
0007 BF0002	mov T)T,offset ram-start ;offset of destinat
OOOA B80000	mov ax'0
0000 8ECO	mov es,ax	;cIestination seqment is 000
OOOP		B9F600	mov	(".~,rlata-lenqth	;how much to movp
0012		F3A4	reo	movs al,al		;,nove out of eDrom
0014		380000	mov	ax,O
0017		8PT)8	mov	09'ax	;,Iata qeament now in PANI
0019		9EDO	mov	ss,ax
0019		BC2AO3	mov	so,stack-offset	;Tnitiali-ze stack s
001p		PC	c1d			;clear the di-recti-o

IF NOT nEmjr.

;Now, initialize the console T713ARM and bauc3 rate

mov		a1,07h
out		csts,al	;qi-ve 8251 dummv mode
mov		al,40h
out		csts'al	;reset 8251 to acceOt mode
mov		al,4Ph
out		csts,al	;normal 8 bit asvnch mode,
mov		al,37h
out		csts,al-	;enable TX & PX
mov		al-,OB6h
out		tcmd,al	;8253 ch.2 square wave mode
mov		ax,baud
out		tch2,al-	;1-ow of the baud rate
mov		al,ah
out		tch2,al	;high of the baud rate

ENDIP

;qetur) the 8259 Programmable Tnterrupt Controller

001F B013	mov al,13h
0021 r-6C-0	out icpl,al-	;8259a TC-Tq 1 8086 mode
0023 13010	mov al,10h

All Information Presented Here is ProDrietary to niqital Research

109
CP/M-86 Svstem ruide	Aor)enlix C		Listinq of the Rnr),r Rom

0025		F6(72	out	icp2,al	;825c)a 1(",,, 2	vector (a 40-9
0027		B01F	mov	al,lPh
0029		E6r2	out	icp2,al	;P25qa I(-TN7 4	auto rni mast
002B		BOFF	m.ov 	al,OPPh

002T) F6(72	out icp2,al	;8259a r)(-To 1		mask all'eve

;Reset and i-nitial,ize the iqTY' 204 diskette interface

restart:	;al-so come back here on fatal error

002'P E6AF	out reset204,AT,		;reset iSTV- 204 loaic and
0031 B001	mov AL,1
0033 E6A2	out frlcrst,AL	;qive 8271 FDC

0035		BOOO		mov al,O
0037		E6A2		out fdcrst,AL	a reset command
0039		BB1502		mov BX,offset suecsl
003C		E8ElOO		CALL sendcom	;proaram
003F		BBlB02		mov T3X,offset specs2
0042		E8DBOO		CALL sendcom ;	qhugart SA-ROO drive
0045		BB2102		mov BX,offset soecs3
0048		E8D500		call sendcom	characteristics
004B		BB1002	homer:	mov RX,offset home
004E		E85800		CALL execute	;home drive 0
0051		BB2AO3		mov bx,sectorl	;offset for first sector r)m
0054		B80000		mov ax,O

0057 8RC0	mov es,ax	;seqment	it	of	of
0059 E8A700	call setup-dma

005C RT30202	mov bx,offset readO

005F E84700	cal-1. execute	;qet TO q1
0062 BE062DO3	mov es,ARR
0066 BBOOOO	mov bx,O	;qet loader load a,-3aress

0069 E89700	call setur)-dma		;setuo nvA to read loader
006C BB0602	mov bx,offset rea,91

006F E83700	call execute	;readtrack 0

0072 BBOB02	mov bx,offset read2

0075 E83100	call execute	;readtrack I

0078 8C06P,802	mov lean seqment,PS
	setup far iumn vector
007C C706P,6020000'	mov !ear) offset,O

	enter LOADER
0082 FF2EE602	jmpf dword otr lear)-offset

pmsg:

0086		8AOF	mov cl,rBxl
0088		84C9	test cl,cl
008A		7476	iz return
008C		E80400	call conout
008F		43	inc T3X
0090		'P,9F3FP	imp pmsq

All Information Presented Here is Proorietary to Diqital Research

106
CP/M-86 System (,uide	Appendix r		Listinq of the BOOT ROM
	conout:
0093 F4DA		in al,csts
0095 A901		test a1,1
0097 74FA		jz conout
0099 8ACI		mov al.,cl
009B E6D8		out cdata,al
0 0 9r) (73		ret
	conin:
009E E4T)A		in al,csts
OOAO A802		test al,2
OOA2 74FA		1z conin
0OA4 74n8		in al,cdata
0OA6 247F		and al-,7Ph
0OA8 C3		ret
	execute:			;execute command strinq 9 fRX1
			;<IIX> ooints to lenqth,
			;Followed hv command bvte
;followed bv lencith-1 oaram-tor hvt

OOA9 89170002			mov	1---istcom,RX	;remember what it w
	retrv:				;retrv if not rea,9v
HAD E87000	call		sendcom	;execute the Cnmman
			;now, let'-, gep wl~a
			;o,' status oo,' was
			;for that command t
0090 8B1F0002	m()V		9X,lastcom	;ooint to command s
0OB4 8A4701	Mov		AT', I [11xi	;qet command or) cod
OOB7		243F	and	AL,3fh	;dron	Iriv- code hi
0 OT39	990008	mov	(Y,0800h	; m a s k i. F i t w i I I	")"
OORC		3(72C	CMD	AL,2ch	;see	if i.nterruot t
OORE		7209	ib	execooll
OOCO		B98080	mov	r-X,8090h	;else we use "not c
0OC3		240P	and	AT, , Of h	;unless , , *
OOC5		3(70('	cm0	AT,, Och	;there isn-t
00(77		BOOO	mov AL,O
00(79 7737	ia return	;anv result at all

execooll.:	;noll For hit in h, to(:iqlPd with c
OOCB		E4AO	in AL,Pn('S'rAT
O0(7-D		22(75	and AL,('H
00(7F		32(7174F8	xor AT,,("L ! JZ execooll
OOn3		E4A1	in	AL,rdcrslt	;qet result reqiste
OOD5		241E	and	AL,leh	;look onlv at resul
OOD7		7429	iz	return	;zero means it was
OOD9		3C10	cmr) al-,10h
OOnR		7513	ine fatal	;i-f other than "',lot
OOnD		BB1302	mov hx,offset rdstat
OOFO		F83DOO	call sendcom	;oerform read statu

All Information Presented Here is Proprietary to niqital Research

107
CP/M-86 System Guiae	Appendix r		Listinq of the BOOT Rr)M

OOE3		F4A0	rd-poll: in al,fdc-stat
00F5		A880		test al,80h	;wait for command n
OOP,7		75FA		Inz ra poll
OOP,9		8B1E0002		mov bx,last com	;recover last attem
OOED		E9BDFF		imp retry	;and trv it over aq
		fatal:			fatal- error
OPFO		B400		mov ah,O
0OF2		8BT)8		mov bx,ax	;make 16 bits
0OF4		BB9F2702		mov bx,errtbl-IT3XI
print aDproi)riate error message
0OF8		E88BFF		call pmsq
OOFB		E8AOPF		call conin	;wait for key strik
OOPE		58		pop ax	;discard unused i.te
OOFF		E92DFF		imp restart	;then start all ove
		return:
0102		C.3		RET	;return from EXrrUT
		setundma:
0103		13004		mov AL,04h
0105		E6A8		out dmacmode,AL	;enable dmac
0107		BOOO		mov al-,O
0109		E6A5		out dmaccont,AL	;set first (dummy)
010B		B040		mov AL,40h
010D		E6A5		out dmaccont,AL	;force read data mo
01OF		8CCO		mov AX,PS
0111		E6AA		out fdcsegment,AT,
0113		8AC4		mov AL,AH
0115		E6AA		out fdcseqment,AL
0117		8BC3		mov AX,13X
0119		F6A4		out dmacadr,AL
011B		8AC4		mov AL,AH
011D		E6A4		out amacadr,AL
011F		C3		'RET

sendcom:	;routine to send a command string t
0120		E4AO	in AL,fdcstat
0122		2480	and AL,80h
0124		75FA	inz sendcom	;insure command not busv
0126		BAOF	mov CL,[RXI	;get count
0128		43	inc BX
0129		BA07	mov al,[BX1	;poi.nt to and fetch command
012B E6AO		out fdccom,AL	;send command
	oarmloop:
012D FEC9	dec CL
012F		74T)l		jz return	;see if anv (more) varamete
0131		43		inc BX	;point to next parameter
		parmpoll:
0132		E4AO		in AL,fricstat
0134		2420		and AL,20h
0136		75FA		inz parmpoll	;1oor) until- parm. not ful.1

All Information Presented 'Here is Proprietarv to r)igital. 'Research
108
CP/M-86 System Guide	Appendix (7,		lAstinq of the 900'r ROM
0138 8AO7	Tnov AL, rRX1
013A E6A1	out fdcr)arm,AL		;outout next Parameter
013C E9EEFF	Jmp oarml-ooo		;go see about another

Image of data to he moved to RAM

013F	drombeqin ecru offset

013F		0000	clastcom	dw	0000h	;last command
0141		03	creadstrinq	rib	3	;I.enqth
0142		52		db	52h	;read function co(le
0143		00		db	0	;track 4
0144		01		dh	I	;sector 4
0145		04	creadtrkO	db	4
0146		53		db	53h	;read multiple
0147		00		d b	0	;track 0
0148		02		(lb	2	;sectors 2
0149		19		rib	25	;through 26
014A		04	creadtrkl	(lb	4
014B		53		Ob	53h
014C'		01		qb	1	;track I
014D		01		db	I	;sectors I
014E		1A		lb	26	;through 26
014F		026900	chomeO	db	2,69h,O
0152		016C	crdstatO	(9b	1,6ch
0154		05350T)	csPecs1	db	5,35h,Odh
0157		0808E9		(lb	08h,08h,Oe9h
015A		053510	csPecs2	d b	5,35h,10h
015D		FPFFFF		db	255,255,255
0160		053518	csoecs3	(lb	5,35h,19h
0163		FFFFFF		db	255,255,255

0166		4702	cerrtbl-	dw	offset,erO
0168		4702		dw	offset erl
016A		4702		dw	offset er2
016C		4702		dw	offset er3
016E		5702		(9w	offset er4
0170		6502		dw	offset er5
0172		7002		dw	offset er6
0174		7FO2		dw	offset er7
0176		9002		dw	offset er8
0178		A202		dw	offset er9
017A		B202		dw	offset erA
017C		C502		dw	offset erR
017E		D302		dw	offset erC
0180		4702		dw	offset err)
0182		4702		dw	offset erP,
0184		4702		dw	offset erF

0186 ODOA4E756C6C CerO	db	cr,lf,'Nul-l- Frror ??',0

All. Information Presented Here is Proprietary to niqital Research

109
CP/M-86 System Guide	7%noen,,~ix	Listinq of the IR00r P"W,

	204572726F72
	203r3POO
0186		Cerl	equ	cerO
0186		(er2	equ	cero
0186		(er3	equ	cerO
0196		ODOA436(-,6P63 (-er4	Ob	cr,IF,'('Iock Frror',O
	6rQ041~72726F
	7200
OIA4		Or)OA4(7617465 Ce r 5	(3 b	c r , I f , ' T, a t e r)m A 0
	20444D4100
0 1AF		OT)OA49442043 Oe r 6	cr If,' TD CR(' TI.rror 0
	524320457272
	6F7200
01BF		OT)OA44617461- (7e r 7	rl b	cr , 1 f , 'nata r7Rr7 Pr ror 0
	204352432045
	72726F7200
	OICF OnOA44726976 (-e r 8	(9	cr I "P,'T)rive Not Readv' 0
	65204F6F7420
	526561647900
OlEl		ODOA57726974 Cerq	r9h	cr,lf,AWrite Protecto,O
	652-050726F74
	65637400
01F1		OT)OA,54726B20 (7erA	(9h	cr,l-f,'-rk 00 Not PoundA,0
	303020476F74
	20466F756764
	00
0204		OT)OA57726974 (7 e rR	d h	cr jf,'T-Jrite Paul t' 0
	65204661756r
	7400
0212		ODOA53656374 Cer('	r1b	cr,lf,'qector Not Found',O
	6F72204T~6F74
	20466IP756P,64
	00
0186	CerD	equ	cerO
0186	CerF,	equ	cerO
0186	CerF	equ	cerO

0225	r1romend equ offset 5
OOE6	data lenqth	equ dromend-drombegin

reserve space in RAM for data area
(no hex records qenerated here)

	0000		dseq	0
			orq	0200h
	0200	ram start		equ	$
0200		lastcom			rw	1	;last command
0202		readO		rb	4	;read track 0 secto
0206		readl		rb	5	;read TO S2-26
020B	read2		rb	5	;read Irl 91-26
0210		home		rb	3	;home drive 0
0213		rdstat			rb	2	;read status
0215		specsl			rb	6

All Information PresenteM Here is Proprietary to T)i-gital Research

110
CP/M-86 System ruide	Aopendix C		Listinq of the BOOT ROM

02113	sDecs2	rb	6
0221	sDecs3	rb	6
0227	errtbl	rw	16
0247	erO	rb	lenqth cerO	;16
	0247	er!	equ	erO
	0247	er2	equ	erO
	0247	er3	ea ' u	erO
0257	er4	rb	lenqth		cer4	14
0265	er5	rb	I-enqth		cer5	;1i
0270	er6	rb	lenqth		cer6	;15
027F	er7	rb	Ienqth		cer7	;17
0290	er8	rb	lenqth cerq	;1p
02A2	er9	rb	iength cer9	;16
02132	erA	rb	lenqth cer4.	;jq
02C5	er13	rb	lenqth cerR	;14
0 2T)3	er('	rb	lenqth cerC	1C)
	0247	ern	eCTu	ern
	0247	erF	eCTu	erO
	0247	erF	equ	erO
02F6	lear) offset	rw	I
02E8	I-ear)-seqmen'L-		rw	I

02EA		rw	32	;local. stack
	032A	stack-offset		ecru	offset -~;qtack from here do

		TO S1 read in here
032A	sectorl	equ offset

032A	Tv	rb	1
03213	Len	rw
032T)	Abs	rw		is all- we care
032F	Min	rw
0331	Max	rw
		end

All Information Presented Here is Proorietarv to niqital- Resoarch

ill
	Appendix D
LDBIOS Listing

This the the T,OAT)ER gins, ~eriverl From the RJnq
,)rc)qram by ena~Dl i ncl the " loader bios" condi
tionaT a~,semblv switch. The li-,tinq has been
P-dit,::?l to remove nortions which are (luolica.to-9
in the 910S li.sl--inq wh
	I			. ich -3noear~, in Annendix r)	*
where eltoses			rienote, the (1oTPtPd )orti()ng		*
(the 1-istinq is truricate~l on the riqht, hut cari		*
be reoroducerl hv assemblinq the RTnq.z\86 File
oroviled with ('D/M-86)

Rasic Troi-1t In,_, tout qvstem (RTn,;) For
1"T)/R1-q6		-on':ikjur-n(i For tq9r' 86/12 wi h
the i qR(7 204 71 c)r)pv nisk (ontrol I er

(N r) t e		t h is f i 1. e cn n ta i n -; bn t h e- h erl r' r'
tabs
	a nd b I a ri k s t n rn i ri i m i z e t h	t
wiith For orintinq nurnoses. Vnu rnav wi~-'h*
to exoanri the blanks before nerforTinq
major erlitinq.)

('oovriqht (r-) 1980,1081
Digital Des(-arch, Tn(--.
Rox 57q, Pacific Grove
Cal i Forn i a, 93950

(Permission is hereby qrantp(i to usf
or abstract the fol-lowinq orogram in
the imolementation of (-P/M, NIP/m or
r7P/NFT for the 8086 or 8088 micro
orocessor)

FFFF	trup	eau -1
0000	false	ecru not true

All Information ?resentei Uere is Pronrietarv to T)iqital Pesoar(-h

I i 3
CP/M-86 System Guide	ApT)endix D		LDBIOS Listi-nq

Loader bios is true if assemblinq the
LOADER BIOS, otherwise BIOS is for the
rPM.SYS file. Blc list is true if we
have a serial PrinTer attached to BLC8538
T3dos-int is interrupt used for earlier
vers'
ions.

FFFF	loader bios		equ		true
FFFF	b1c list			equ	true
OOEO	bdos-int			equ	224 ;reserved BDOS Interrupt
		IF	not 		loader-bios

ENDIF	;not loader-bios
IF	loader bios

1200	bios code	eau 1200h ;start of LT)BIOS
0003	ccp 6ffset	equ 0003h ;base of CPMLOADER
0406	bdos-ofst	equ 0406h ;stripped BDOS entrv

---------------------------------------------
ENDIF	;loader-bi-os
cseq
org	ccpoffset
CCID:
orq	bios-code

BIOS Jump Vector for Individual Routines

1200 E93COO	jmp INIT	;Enter from BOOT ROM or LOADER
1203 E96100	imp T%MOOT	;Arrive here from BDOS cal.1 0

1239 E96400	imp GETIOBF	;return 1/0 mar) bvte (IOBYTE)
123C E96400	imp SETIOBF	;set 1/0 mar) byte (IOBYTE)

All Information Presented Here is ProorietarV to Digital Research

114
CP/M-86 System Guide	Appendix D		LDRIOq Listing

		MIT		Entry Point, Differs for LOBIOq and
		RIOS, according to "Loader-Bios" value
	INIT:		;print siqnon message and initialize hardwa
123F 8CC8			mov ax,cs	;we entered with a JMPF so
1241 SEDO			mov ss'ax		PS: as the initial vaTue
1243 8ED8			mov ds'aX			ns:,
1245 8ECO			mov es,ax			and FS:
			;use local stack durinq initialization
1247 BCA916			mov so,offset stkbase
124A FC			c1d	;set forward direction

IF	not loader bios
------------------------- 7 -------------------

This is a BIOS for the CPM.SYS file.
I
--------------------------------------------
7NDIF		;not loader-bi-os

		TF	loader bios
	-------------------- 7 ----------------------
					I
		;This is a BIOS for the LOADER
124B IV,		push ds			;save data seqment
124C B80000		mov ax,O
124F 8ED8		mov ds,ax	;point to seqment zero
		;BDOS interrupt offset
1251 C70680030604			mov bdos - offset,bdos_ofst
1257 8COE8203		mov bdos-seqment,CS ;bdos interrupt segment
125B IF		pop As			;restore data segment I

-- - ------------ ----- - -

ENDTP		;loader-bios

125C BB1514	mov bx,offset siqnon
125F E85AOO	call pmsq	;print siqnon messaqe
1262 B100	mov c1'0	;default to dr A: on coldst
1264 E99CED		imp ccp	;jump to cold start entry o
1267 E99FED	WBOOT:		imp ccp+6	;direct entry to CCP at com

IF	not loader bios
------------------------- 7 -------------------
K

---------------------------------------------
FNnIF		;not loader-bios

All Information Presented Rere is Proorietarv to Digital Research

115
CP/M-86 System Gu i a e	Anoendix r)	T,r)R 101; T- i t i n a

(P/m (haracter I/() Interface Poutines
Console is Usart (i8251a) on iqB(' 86/12
at oorts T)8/nA

	CONIC;",:		;console status
1261\ E4DA		in al csts

const-ret:
1272 C3		ret	;T~eceiver Data Available
	CONIN:		;console inout
1273 E8F4FF		call const

(7r)NOUT:	-consolp outr)ut
127T) E4DA		in al-,cst.~
	LlqTO!TrP:			;list -levice outout

	Tv	b1c list
---------------------------------------------

1288 E80700	cal I TTSTST

--------------------------------------------
	ENDIP 	;bl.c-.Ii-st

1291 C3	ret

LISTqT:	;Pol,l list status

	IF	bl.c Tist
---------------------------------------------

1292 E441	in al,Tsts

--------------------------------------------
	FNDIF 	;bl-c-list

129C C3		ret
	PUNCH:	;not implemented in this confiquration
READER:
129D B01A	mov al-,lah
129F C3	ret	;return EOF for now

All Information Presented Here is Proprietary to Diqital- Research

116
CP/M-86 System Cuide	Aopendix 0		LOBIOS Listing
	r
	,PTIORF:
12AO 8000		mov al,O	;TTV: for consistencv
12A2 C3		ret	;JORYTE not imolemented
	SETIOBF:
12A3 (73		ret	;iobvte not imr)lemented

zero-ret:
12A4 2400	and a!-,O
12A6 C3	ret	;return zero in AL and Flag

Routine to get and echo a console character
and shift it to upper case

	uconecho:
12A7 E8C9PF		call CONTIN	;get a console character

nisk Tnput/Outout Routines

	SFLnSK:					;select disk given bv register CT,
12CA BBOOOO		mov hx,noo0h
	HOMF:		;move selected disk to home oosition (Mrack
12EB (7,606311500			mov trk,O	;set disk i/o to track zero
	SETTRK:			;set track address given bv rx
1300 880P3115		mov trk,cl-	;we only use 9 bits of trac
1304 C3		ret
	SF,TS'P,(':	;set sector number given bv cx
1305 880E3215		mov sect,cl-.	;we only use 8 bits of sect
1309 (73		r e- t
	qT,;'(7TRAN:	;translate sector (X usinq table at fnxl
130A 8BT)9		mov bx,cx
	SETDMA:			;set DMA offset given by CX
1311 890P,2A15		mov Ima-adr,CX
1315 C3		ret
	SPTDMAB:			;set nMA segment given bv (X
1316 890E2C15		mov dma-seq,CX
131A C3		ret
	GETSEGT:			;return address of ohvsical- memorv table
131B BT33815		mov bx,offset seq-table
131E C3		ret

All Tnformation Presented Here is Proorietary to niqital. Research

117
(-P/M-86 Svstem (,uir9e	Apoendix r)	T,r)BlOq Listinq

All disk T/O Darameters are	setur):	the
Read and Write entrv Doints	transfer one
sector of 128 bvtes to/from	the current
T)MA aridress usinq the current r1isk drive

READ:
131F B012	mov al.,12h	;basic read sector command
1321 EB02	~mT)s r-w-common
1323 BOOA	mov al,Oah	;basic write sector cr)mman(9

	r-w-common:
1325 BB2P15		mov bx,offset io-com ;ooint to command stri

nata Areas

1415	data-offset	equ offset 5
		(9seq
		orq	data-offset	;contiauous with co

	TV	loader bios
---------------------------------------------
		;1			1
1415	ODOAODOA	siqnon	db	cr,lf,cr,l.f
1419	43502F4D2r)38		db	'(-P/M-86 Version 2.?',cr,l.f,O
	362056657273
	696P6E20322F
	320T)OAOO

--------------------------------------------
	PNT)TF 	;loader-bios

IP	not loader-bios,

'PIMIDIP	;not loader-bi.os

142F ODOA486F6T)65 bad-hom db	cr,lf,'Mome Prror',cr,lf,O

include	sinqles.lib ;read in di-sk definitio
	T)TSKq 2

All- Information 'Presented Rere is Proprietary to Diqital Research

118
CP/M-86 System Guide	Anpendix T)		LDBIOS Listinq

		1541	dobase		equ	$	;'R-ase of nisk Param
=1668 00		db	0	;Marks End of Modul
	1669	loc stk		rw 32	;local. stack for initialization
		16A9	stkSase		equ offset S
	16A9 00		db 0	;fill- last address for rENr.MT)

T)ummy Data Section

0000	dseq	0	;absolute low memory
	orq	0	;(interrupt vectors)

FNT)

All Information Presented 9ere is Proprietary to Oiqital Research

119
Appendix E
BIOS Listing

 This is the CP/M-86 BIOS, derived from the RIOS
 proqram by disablinq the "loader bios" condi-
 tional assembly switch. The 1-istiriq has been
 truncated on the riqht, but can be reoroduced
 by assembling the BIOS.A86 file provided with
 CP/M-86. This BIOS allows CP/M-96 ooeration
 with the Intel	86/12 with the SBC 204 con-
 troller. Use this RIOS, or the skeletal (79IOq
 listed in A.Poendix E, as the basis for a cus-
 tomized implementation of (7P/M-86.
 Drovided with CPPI-86)

Basic Input/OutT)ut qvstem (Rins) for
CP/M-86 ronfiqured for iqB(' 86/12 with
the iqB(7 204 Ploonv Oisk Controll-er

(Note: this file contains both embedded
tabs and blanks to minimize the list file
width for orintinq purooses. You may v7ish*
to exoand the blanks before Derforminq
major editinq.)

Cooyright (C) 1980,1981
T)iqital Research, Inc.
Box 579, Pacific Grove
California, 93950

(Permission is hereby qranted to use
or abstract the followinq oroqram in
the implementation of C-P/M, MP/M or
(P/NPrr for the 8086 or 8088 mi-cro
processor)

FFFF	true	ecru -1
0000	false	equ not true

All Information Presented Here is Proorietarv to niqital Research
CP/M-86 System Guide	Annenr9 i x F		Rlr)q l,i,,-tinq

Loader bios is true if assemblina the
LOADER BIOq, otherwise B101; is for the
(PM.cYq file. T31-c-list is true if we
have a serial- orinter attached to 13L(-853R
Bdos-int is interrunt use(9 for (:~arlipr
versions.

0000	1 oader - bios	equ false
FF'FF	blc list	equ true
00plo	hdos-int	equ 224 ;reserved Br)O(; Interrunt

	IF	not loader-hios
---------------------------------------------
	;1		1
2500	bios corle	ecia 2500h
0000	ccp offset	equ 0000h
OB06	bdos ofst	equ OT306h ;Rr)OS entry ooint
	;I -		I
---------------------------------------------

T"
"MIF	;not loader-bios

IF	loader bios
---------------------------------------------
;I		I
bios code	equ 1200h ;start of LDRIOS
ccp offset	equ 0003h ;base of (7PMLOAT)TIR
bdos ofst	equ 0406h ;stri-oped T3T)r)c; entrv
;I -	I

ENDIF	;loader-bios

OODA	csts	equ OT)Ah		;iS251	status nort
OOD8	cdata	equ 008h			data oort
		IF	b1c list

	------------------	-------------------------
;1	i
0041	Ists	equ.41h ;2651 No. 0 on T3LC8538 stat
0040	Idata	equ 40h ; "	11	It		of	of	r1ata
0060	b1c reset	equ60h ;reset selected TTI;ARTC.; on B

,NDTF	;blc-].ist

Intel iST3C 204 Disk Controller Ports

All Information Presented Mere is Proprietarv to Digital Research

122
CP/M-86 System Guide	APoendix E		BTnq Listinq

OOAO	base204	equ OaOh	;SRr204 assiqned a-]

OOAO	fdc com	equ		base204+0	;8271	Fr)(- out comma
OOAO	fdc stat	ecru		base204+0	;R271	in status
00A,1	fdc oarm	equ		base204+1	;8271	out oarameter
00A1	frlc-rsl-t	equ		base204+1	;8271	in result
0OA2	fdc rst	eau base204+2		;8271out reset
0OA4	dmac		adr	equ	base204+4	;8257	nMA	base a0cir
0OA5	dmac		cont	eau	base204+9	;8257	out	control
0OA6	dmac		scan	ec - ru	base204+6	;8257	out	scan cont
0OA7	dmac		sadr	equ	base204+7	;8257	out	scan addr
0OA8	dmac		mode	equ	base204+8	;8257	out	mode
0OA8	dmac stat	equ base204+8		;8257in status
0OA9	fdc -sel-			ecru base204+9	;Fr)(' select oort (n
OOAA	fdc-segment		equ hase204+10			;seqment address re
OOAF	reset-204		eciu hase204+15			;reset entire inter
OOOA	max-retries		equ 10	;max retries on dis
				;before aerm error
000r)	cr		equ Odh	;carriaqe return
OOOA	if		eau Oah		line feed
		cseq
		orq	ccpoffset
	ccp:
		orq	hios-code

BIOS Jumo Vector for Individual Routines

2500		E93COO	imp	INIT	;P.nter from BOOT ROM or TOAnl-'R
2503		E98400	imp	WBOOT	;Arrive here from BT)Oq call 0
2506		E99000	imp	CONST	;return console kevboard status
2509		E99600	imp	CONIN	;return console keyboard char
250C		E99T)OO	imp	rONOUT	;write char to consol.e device
250F		R,9A500	imp	LISTOUT	;write character to list device
2512		E9B700	imp	PUNCH	;write character to ounch device
2515		E9B400	imp	READER	;return char from reader device
2518		P9FFOO	imp	FOME	;move to trk 00 on cur se! drive
2518		R9DB00	jTnp	SELDSK	;select disk for next rl/write
251E		E90F.01	Imp	SETTRK	;set track for next rd/write
2521		E91001	Imp	SETSEC	;set sector for next rd/write
2524		E91901	I mr)	SETDMA	;set offset for user buff (r)'14A)
2527		V92401	imp	RFAD	;read a 128 byte sector
252A		E92501	imp	WRTTP,	;write a 128 byte sector
252D		E99100	imp	LISTST	;return list status
2530		E90601	imp	SECTRAM	;xlate l.ogir--al->r)hysical- sector
2533		E90FOI	jmp	SETDMAB	;set seq base for buff (nMA)
2536		E91101	imp	GETSFGT	;return offset of Mem nesc Tabl.e
2539		E99300	imp	GETIOBF	;return 1/0 map byte (IOBYTE)
253r		E99300	jmp	SETIOBF	;set 1/0 map byte (JOBYTP-)

All Information Presented Here is TroDrietarv to r)iqital Research

123
CP/M-86 qvstem Guide	Appendix F		RIOS Listinq

		MIT		Pntrv Point, niffers for LOBTOq and
		9TOS, accordinq to "Loader-Bios" value
	TNIT:	;orint siqnon messaqe and initialize harlwa
253r 8CC8			mov ax,cs	;we entered with a JMPF so
2541 8EDO			mov ss,ax		rS: as the initial value
2543 8ED8			mov As'ax			IS:,
2545 8FC0			mov es,ax			and PS:
			;use local stack durinq initialization
2547 ROF429			mov sp,offset stkbase
254A F(-			cld	;set forward direction

	TF	not loader hios
------------------------- i -------------------
P		I
	mhis is a BIOS for the Wv.9Yq file.
	Setup all interrupt vectors in low
memorv to address tran

254B IE	push as	;save the nq reqister
254C B80000	mov ax'0
254F 8ED8	mov ds,ax
2551 8FC0	mov es,ax	;set FS and nS to zero
	netun interrupt 0 to address trap routine
2553 C70600008n25	mov intO offset,offset int-trar)
2559 8COR0200	mov intO seqment,rq
255D BF0400	mov di,4
2560 BF0000	mov si'0	;then orooaqate
2563 BUM	mov cx'510	;trap vector to
2566 F3A5	rep movs ax,ax		;all 296 interrupts
	;BnOR offset to prooer interrupt
2568 C7068003060B	mov bdos offset,hlos ofst
256E 1F	Pon As	Vestore the Dq reqister

National "ILC 8538" Channel 0 for a serial*
9600 baud printer - this board uses 8 Piq-*
netics 2651 Usarts which have on-chip baud*
rate generators.

256F BOFF	mov a1,0FPh
2571 E660	out bTc reset,al ;reset all usarts on 8538
2573 B04E	mov al-JEh
2575		E642	out	Idata+2,al	;set usart. 0 in asvnc 8 bit
2577		B03E	mov	al,311h
2579		E642	out	ldata+2,al	;set usart 0 to 9600 baud
257B		B037	mov	al,37h
257D		E643	out	Idata+3,al	;enable Tx/Rx, and set up R

All Information Presented Here is Proprietary to Digital Research

124
CP/M-86 Svstem Guide	Appendix E		BIOS Listinq

---------------------------------------------
ENDIF		;not loader-bios

IF 	loader-bios

;This is a BIOS for the LOADER
push ds	;save data segment
mov ax,O
mov ds,ax	;ooint to segment zero
;9DOS interruot offset
mov bdos offset,bdos ofst
mov baos seqment,(7S ;bdos interrupt seqment
pop ds	-,restore data segment

ENDIF 		;loader-bios

257F BB4427	mov bx,offset siqnon
2582 E86600	call omsq	;print signon message
2585 B100	Tnov C I , 0	;rlefaul.t to dr A: on coldst
2587 E976DA		jMp ccp	;jump to cold start entrv o
258A E979DA	T%TBOOT:		imp ccD+6	;direct entrv to CCP at com

	IF	not loader bios
---------------------------------------------
	;I			I
	int-trar):
258D FA		cli	;bl.ock interrupts
258E 8CC8		mov ax,cs
2590 8ED8		mov ds,ax	;get our data segment
2592 BB7927	mov bx,offset int-trT.)
2595 E85300	call T)msq
2598 F4	hlt 	;hardstoD

	--------------------------------------------
ENDIF 	;not loader-bios

CP/M Character 1/0 Interface Routines
Console is TJsart (i8251a) on iSBC 86/12
at iDorts D8/T)A

	CONST:			;console status
2599 E4DA		in al,csts
2599 2402		and al,2
259r) 7402		jz const ret
259F 0CFF		or al,25			;return non-zero if RnA
	const-ret:
25AI C3		ret		;Receiver Data Available

All Information Presented Here is ProT)rietarv to Digital, Research

125
CP/M-86 System		Guide	Apnendix F	RTOS Listinq
	CONIN:	;console inout
25A2 E8F4FF	call const
25A5 74FB	v cnNiN	;wait for RDA
25A7 E408	in al,cdata
25A9 247P	and al,7fh	;read data and remove oarit
25AB C3	ret

	CONOUT:			;console output
25AC E4DA		in al,csts
25AE		2401		and al,l	;get console status
25BO		74FA		jz CONOUT	;wait for TAF
25B2		BAC1		mov al,cl
25B4		E6D8		out cdata,al	Mansmitter Buffer Empty
25B6		C3		ret	;then return data
		LISTOUT:			Mst device output

IF	b1c list

-		- --------------------------

25B7		E80700		call LISTST
25BA		74FB		1z LISTOUT	;wait for printer not busv
25BC		8AC1		mov al,c!
25BE		E640	d	out Idata,al	;send char to TT 810

--------------------------------------------
	ENDIF 	;blc-list

25CO C3		ret
	LISTST:				woll list status
		III	b1c list

25C1		E441		in al,lsts
25M		2481		and aT,81h	;look at both TxRDY and DTR
25C5		W81		cmo al,81h
25C7		750A		inz zero ret	;either false, printer is b
25C9		OCFF		or al,251	;both true, LPT is ready
		K			I
--------------------------------------------
	ENDIF 	;blc-list

25CB C3	ret

PUNCH:	;not implemented in this configuration
		READER:
25CC		B01A		mov al,lah
25CE		C3		ret	;return EOP for now
		GETIOBF:
25CF		BOOO		mov al,O	;TTY: for consistency
25D1		C3		ret	JOBYTE not implemented

All Information Presented Here is Proprietary to Digital Research

126
CP/M-86 System		Guide	Appendix F	BIOS Listing
	SETIOBF:
25D2 C3	ret	;iobyte not implemented

zero-ret:
25D3 2400	and al,O
25n5 (73	ret	;return zero in AL and flag

Routine to get and echo a console character
and shift it to upper case

		uconecho:
25D6		E8C9FF		call CONIN	;get a console character
2 5r)9	50		push ax
25r)A		8AC8		mov cl,al	;save and
25r)r		E8CDFF		call CONOUT
250F		58		pop ax	;echo to console
25EO		3C61		cmo al,'a'
25F2		7206		lb uret	;less than 'a' is ok
25E4		3(77A		cmv al,'z'
25E6		7702		!a uret	;greater than 'z' is ok
25'E8		2(720		sub al,'a'-'A'	;else shift to caps
		uret:
25FA		C3		ret

utili-tv subrouti.ne to print messaqes

pmsq:
25ER		8A07	mov al.,flIX1	;get next char from message
25ED		84CO	test al,al
25EF		7428	jz return	;if zero return
25PI		8A(78	mov rI,,AL
25R3		E8B6FF	call CONOUT	;print it
25F6		43	inc BX
25F7		EBF2	!MPS pmsq	;next character and loot)

Disk input/Outout Routines

	SELT)SK:			;sel-ect	disk given bv register (M
25F9 BBOOOO		mov bx,0000h
25FC, 80F902		cmp cl,2			;this BIOq on1v supports 2
25FF 7318		jnb return	;return wl 0000 in 13X if ba
2601 B080		mov al, 80h
2603 8OF900		CMD c1'0
2606 7502		jne sell			;drive 1 if not zero
2608 B040		mov al, 40h	;el-se drive is 0
260A A26928	sell:	mov sel--mask,al		;save drive select mask
				;now, we need disk oaramete
260D B500		mov ch,O
260F 8BT)9		mov bx,cx	;RX = word(rL)
2611 B104		mov cl,4

All Information Presented Rere is Proprietary to Digital Research

127
	CP/M-86 System Guide			ADoendix F		BTnl-- Listinq
2613 D3E3	shl bx,c!	;multiolv drive cole * 1A
		;create offset from T)isk Parameter Base
2615 8IC37(728		add bx,offset do-base
	return:
2619 C3		ret

HOME:	;move selected disk to home nosition (rrrack
261A		C6066C-2800	mov trk,O	;set disk i/o to track zero
261F		BB6r-28	mov bx,offset hom_com
2622		P-83500	call execute
2625		74F2	1z return	;home drive and return if 0
2627		BB6A27	Tnov bx,offset bad hom	;else orint
262A		EBBEFF	call pmsq	;7Home 'Prror"
262D		EBEB	imps home	;and retrv

SETTRK:		;set track adaress given by CX
262F 88OE6(-28	mov trk,cl	;we onlv use 8 bits of trac
2633 C3	ret

SETSEC:		;set sector number given bv cx
2634 88OE6o28	mov sect,cl-	;we onlv use 8 bits of sect
2638 C3	ret

SECTRAN: ;translate sector rX usinq table at [T)X1
2639		8BD9	mov	bx,cx
263B		03DA	add	bx,dx	;add sector to tran table a
263D		8AlF	mov	hl,fbxl	;get logical sector
263F		C3	ret

SETT)MA:		;set T)MA offset given bv CX
2640 890r,6528	mov dma-adr,CX
2644 C3	ret

SETDMAB: ;set DMA segment given bv (7X
2645 890E6728	mov dma-seq,(7X
2649 C3	ret

GETSEOT:	;return address of ohysical memorv table
264A BB7328	mov bx,offset seq-tabl.e
264D C3	ret

All disk 1/0 varameters are		setuD: the
Read and Write entrv points		transfer one
sector of 128 bytes to/from		the current
DMA address using the current disk drive

READ:
264E B012	mov al,12h	;basic read sector command
2650 EB02	imr)s r-w-common

WRITE:

All Information Presented Here is Proorietarv to T)iqital Research

128
	CP/M-86 System Quide				Appendix E	RIOS Listinq
2652 BOOA	mov al,Oah	;basic write sector command

r-w-common:
2654 B86A28	mov bx,offset io com ;ooint to command stri
2657 884701	mov byte otr l(RXJ,al ;out command into str
	fall into execute and return

execute: ;execute command string.
KBX1 Points to length,
followed by rommand byte,
followed bv length-1 parameter byte

265A 891F6328	mov last-com,RX ;save command address for r
outer-retrv:
		;allow some retrvinq
265E C60662280A			mov rtrv-cnt,max-retries
	retrv:
2663 8BlE6328		mov RX,last-com
2667 E88900		call send-com	;transmit command to i8271.
		check status ooll
266A 881E6328		mov 9x,last com
266E		8A4701		mov al,lfbxT	;iet command oo code
2671		B90008		mov cx,080oh	vask if it will	be "int re
2674		3C2(7		cmo al,2ch
2676		7208		ib exec Poll	;ok if	it is an interrupt t
2678		B98080		mov cx,i08Oh	;e1se	we use "not command ID
267B		240F		and al,Ofh
267D		3COr		cmp al,Och	;unless there isn't
267F		BOOO		mov al,O
2681		7736		Q exec-exit	anv result
				;0011 for bits in CF,
		exec-ooll:	; 	toggled with bits in PT,

2683 MAO	in aT,flc_stat		;read status
2685 An	and al,ch
2687		32C1	xor al,cl	isolate	what we want to
2689		74F8	iz exec-poll	;and looo until	it is done
			;nPeration complete,
268B		E4Al	in al,Fdc_rslt	see	if result code inlica
268D		241E	and al,leh
268F		7428	Q exec-exit	;no error, then exit
			nome	tvpe of error occurre
2691		3CIO	cmp al,lOh
2693		7425	le dr-nrOy	;was	it a not ready drive
			;no,
dr_rdy: ; then we just retrv read or write
2695 PEOE6228	dec rtry cnt
2699 75C8	inz retrv	up to TO times

retries do not recover from the
hard error

269B B400	mov ah,O

All Information Presented Fere is Proprietary to niqital Research

129
CP/M-86 System Guide	Aor)endix F		BIOq Listinq
269D 8BD8	mov bx,ax	;make error code 16 bits
269F 8B9F9127	mov bx,errtbl[T3xl
26A3 E845FF	call pmsq	;i)rint appropriate messaqe
26A6 E4D8	in al,cdata	;flush usart receiver buffe
26A8 E82BFF	call uconecho		;read ur)per case console ch
26AB 3C43	cmp al,'C'
26AD		7425		ie wboot 1	;cancel
26AF		3C52		cmp al,`K'
26B1		74AB		le outer retrv	;retry 10 more times
26B3		3C49		cmp aT,'f
26B5		741A		ie z ret	;iqnore error
26B7		OCFF		or a'T,255	;set code for permanent err
		exec-exit:
26B9		C3		ret

dr-nrdy:	;here to wait for drive ready
26BA E81AOO	call test ready
26BD		75A4	jnz retrv	;if it's ready now we are
26BF		E81500	call test ready
26C2		759F	inz retry	;if not ready twice in row,
26C4		BB0228	mov bx,offset nrdymsq
26C7		E821FF	call. pmsg ;"Drive Not Ready"
nrdy0l:
26CA E80AOO	call test ready
26CT)		74FB		iz nrdy0l	;now loop until drive ready
26CF		EB92		imps retrv	;then go retrv without decr
		zret:
26D1		2400		and al,O
2603		C3		ret	;return with no error code
		wboot-1:			;can't make it w/ a short 1
2604		E9B3FE		jMp TqBOOT

The i8271 requires a read status command
to reset a drive-not-ready after the
drive becomes ready

		test-ready:
26D7		B640		mov dh, 40h	;prooer mask if dr 1
26D9		F606692880	test sel mask,80b
26DE		7502		jnz nrdy7
26EO		B604		mov dh, 04h	;mask for dr 0 status bit
		nrdy2:
26E2		BB7128		mov bx,offset rds-com
26E5		EBOBOO		call send-com
		dr-poll:
26E8		E4AO		in al,fdc stat	;qet status word
26EA		A880		test al,86h
26EC		75FA		jnz dr poll	;wait for not command busy
26EE		E4A1		in al,Tdc rsTt	;get "special result"
26FO		84C6		test al,dF	;look at bit for this drive

All Information Presented Here is Proprietarv to Digital Research

130
CP/M-86 Svstem Guide	Anvendix E		RIOS Listing

26F2 C3	ret	;return status of readv

Send com sends a command and oarameters
to t~ie i8271: 13X addresses parameters.
The T)MA controller is also initialized
if this is-a read or write

send-com:
26F3		F4A0	in al-,fdc stat
26F5		A880	test al-,Sdh	;insure command not busy
26F7		75FA	jnz send com	;1ooo until- readv

;see if we have to initialize for a nmA one

26F9		8A4701		mov al-,I[bxl	;get command bvte
26FC		3C12		cmp al,12h
26FE		7504		jne write mavbe ;if not a rearl it could be
2700		T3140		mov cl.,40
2702		EB06		Imps init-dma	;is a read command, go set
		write-mavbe:
2704		3COA		cmr) al-,Oah
2706 7520		jne dma exit	;I-eave TWA alone if not rea
2708 B180		mov cl-,'~Oh	;we have write, not read
	init dma:
;we 'Eave a read or write ooeration, setup nMA contr
	(CL contains proper direction bit)
270A		B004	mov	al,04h
270C		E6A8	out	dmac mode,al-	;enable dmac
270E		BOOO	mov	al,O
2710		E6A5	out	1mac cont,al-	;send first bvte to con
2712		8AC1	mov	al.,CT
2714		E6A5	out	dmac cont,al	;1oad direction register
2716		A16528	mov	ax,dma a ' dr
2719		F,6A4	out	dmac a;~r,al.	;send low bvte of DMA
271B		8AC4	mov	al,aF
2710		E6A4	out	dmac adr,al-	;send hiqh bvte
271F		A16728	mov	ax,dma seq
2722		E6AA		out	fdc seqment,al ;send 1-ow bvte of seqmen
2724		8AC4		mov	al-,~;h
2726		E6AA		out	fdc-seqment,al ;then high seqment addre
		dma-exit:
2728		8AOF	mov cl,[13xl	;get count
272A		43	inc BX
272B		8A07	mov al,[BXI	;get command
272D		OA066928	or al.,sel mask	;merqe command and drive co
2731 E6AO		out fdc-com,al		;send command byte
	Parm-loop:
2733 FEC9	dec cl
2735 7482		iz exec exit	;no (more) oarameters, retu
2737 43		inc BX	;Doint to (next) 'Parameter
	oarm-poll:

All Information Presented Here is Proorietarv to Diqital Research

131
CP/M-86 System Guide	AT)nendix F	RIOq Listinq
2738 E4AO	in al-,fdc-stat
273A A820	test al,20h	;test "parameter reqister f
273C 75FA	~nz oarm noll	;idle until parm req not fu
273E 8A07	mov al,['~Xl
2740 E6A1	out fdc Parm,al		;send next oarameter
2742 EBPEP	imps T)arrn-l-oor)	;qo see if there are more o

Data Areas

2744	data-offset	equ offset $
		r1seq
		orq	data-offset	;contiquous with co

	TF	loader bios
---------------------------------------------

siqnon	db 	cr,l-f,cr,lf
r1b	'rP/M-86 Version 2.2',cr,lf,O

-		----	----- 	---

7NDIF 	;loader-bios

IP	not loader-bios

2744 ODOAODOA	siqnon		db	cr,lf,cr,I'F
2748 202053797374			db		System Generated	- 11 Jan 81',c
	656D2047656E
	657261746564
	20202D203131
	204A616'F,2038
	310DOA00

--------------------------------------------
	ENT)TV	;not I-oader-bios

276A		ODOA486F6D65 bad-hom db	cr,!f,AT;ome Error',cr,if,O
	204572726F72
	OOOAOO
2779		ODOA496E7465 int-trv db	cr,I-F,AInterrupt Trap 14-al-tA,cr,!-f,O
	727275707420
	547261702048
	616C740DOA00

2791		B127B127B127 errtbl	Iw erO,erl,er2,er3
	B127
2799		C127D127DE27	dw er4,er5,er6,er7
	EF27
27A1		022816282828	dw er8,er9,erA,erB
	3D28
27A9		4D28Bl27Bl27	dw erC,erD,erE,erF

All Tnformation Presented Here is Proprietary to Digital Research

132
CP/M-86 System Guide	Aonendix E		BIOq Listinq

B127

27BI		ODOA47756C6C erO	(ib cr,if,'Null Frror ?'>',O
	204572726F72
	203P3FOO
27131	erl	equ erO
27T31	er2	equ erO
27B1	er3	equ erO
27C1		ODOA436(76P63 er4	db cr,lf,'rlock Error :',0
	6B204572726F
	72203AOO
27Dl		OT)OA4C617465 er5	db cr,l-f,'Late r)MA :',0
	20444T)41203k
	00
27DE		OT)OA49442043 er6	db cr,I.F,'IT) (R(7 Frror :',0
	524320457272
	6F72203AOO
27EF		ODOA44617461 er7	db cr,if,'nata ('R(' Error :',0
	204352432045
	72726P72203A
	00
2802		OT)OA44726976 er8	db cr,if,'nrive Not Peadv :',0
	65204'P,6P7420
	526561647920
	3AOO
2816		ODOA57726974 er9	db cr,lF,'Write Drotect :',0
	652050726P74
	656374203AOO
2828		ODOA54726B20 erA	~b cr,!.f,'rPrk 00 Not Pound :',0
	3030204E6P74
	20466F756F64
	203AOO
283D		ODOA57726974 erB	(lb cr,lf,'Write Fault :',0
	65204661756C
	74203AOO
284D		ODOA53656374 err	db cr,!-f,'qe-ctor Not Found :',0
	6F72204E6F74
	20466?756P,64
	20 3AO 0
	27B1	erT)	equ		erO
	27B1	erE	equ		erO
	27B1	erF	equ		erO
	2802	nrdvmsq		equ	er8
	2862 00	rtrv	cnt db		0	;disk error retrv counter
2863 0000	last	com dw		0	;address of last command strinq
2865 0000	dma adr		r1w	0	;(Ima offset stored here
2867 0000	dma seq		dw	0	;dma seqment stored here
2869 40	sel-mask db 40h ;select mask, 40h or 80h

Various command stri.nqS for i8271

286A 03	io com		db 3	;Tenqth
286B 00	rd. wr		db 0	;read/write function code
286C 00	trli~ 	(9b 0		;track #

All Information Presented Here is ProDrietary to njqita' Research

133
CP/M-86 System Guide	ADoendix F		BTOq Lieftinq

286r) 00	sect	dh 0	;sector 4

286E 022900	hom com db 2,29h,O	;home drive command
2871 012C	rds-com db 1,2ch	;read status commanO

System Memorv Seqment Table

2873 02	se9table db 2		;2 seqments
2874		DF02	dw tva seq	;1st seq starts after PTOS
2876		2105	dw tDa len	;and extends to 08000
2878		0020	dw 200'ffh	;second i - s 20000 -
287A		0020	dw 2000h	;3PFPP (128k)

		incl.urle		sinql.es.lib	;rea(9 in disk definitio
			T)TSKS 2
287C	dobase		eau	1-11 	;Rase of Disk Param
	287C AB280000	diDeO	dw	x1to'0000h	;Translate Table
	=2880 00000000		dw	0000h,0000h	;qcratch Area
	=2884 C5289r728		d w	dirbuf,dt)bO	;T)ir Ruff, Parm Blo
	=2888 64294529		dw	csvO,alvO	;(7heck, Alloc Vecto
	288C AB280000	dDel	dw	xl-tl,0000h	;Translate Table
	=2890 00000000		d w	0000h,0000h	;qcratch Area
	=2894 C5289C28		dw	Oirbuf rlDbl-	; T)i - r Buf f , Parm 91 o
	=2898 93297429		dw	csvl,al-vl	;(7heck, Al-loc Vecto
				T)TRKT)PP 0,1,26,6,1024,243,64,64,?
289C	dr)bO	equ	offset S	;nisk Parameter Blo
289C		1A00	dw	26	;qectors Per Track
289E		03	db	3	;Block Shift
289F		07	db	7	;Block Mask
28AO		00	r1b	0	;7xtnt Mask
28A1		F200	dw	242	;T)isk Size - I
28A3		3FOO	dw	63	;T)irectorv Max
28A5		CO	r3b	192	;1\1-loco
28A6		00	db	0	;Allocl
28A7		1000	dw	16	;rheck Size
28A9		0200	d w	2	;nlfset
28AB	x1to	equ	offset 5	;Tran-,Iate -ahle
28AB 01070D13		db	1,7,13,19
28AF 1905OB11		r1b	25,5,11,17
28B3 170309OF		rib	23,3,9,15
28B7 1502080F,		db	21,2,8,14
28BB 141AO60(--		db	20,26,6,12
28BF 1218040A		db	18,24,4,10
28C3 1016		rib	16,22
	001F	also	eclu	31	;Allocation 17ector
0010	csso	equ	16	;rheck Vector Size
			T)ISKDFP 1,0
289C	dpbl	equ	dobO	;Fquivalent Paramet
001F	al-sl	equ	also	;Same Al-location lie
0010	cssl	equ	csso	;Same Checksum Vect
28AB	X1t1	equ	x1to	;Same Translate Tab
			ENDEP

Uninitial-ized Scratch Memorv Pollows:
28C5	begdat. equ	offset S	;Start of Scratch A

All- Information Presented Here is Pror)rietary to Digital Research

134
CP/M-86 System Guide	Appendix V,		BIOS Listing

=28C5	dirbuf		rs	128	;Directory Buffer
=2945	alvO	rs	alsO	;Al-l-oc Vector
=2964	csvo	rs	csso	;Check Vector
=2974	a1v1	rs	alsl	;AlJoc 'lector
=2993	csvl	rs	cssl	;r7heck Vector
= 29A3	enddat		equ	offset q	-,'End of Scratch Are
=		OODE	datsiz	equ	offset $-beg(iat	;Size of Scratch Ar
=29A3 00		db	0	-Marks End of Modul

29A4	loc stk rw		32	;local stack for initialization
	29E4	stkFase		equ offset $
	29E4	lastoff		equ offset $
	02DF	tpa seq		equ (lastoff+0400h+15) / 16
	0521	tpa-len		equ 0800h - tT3a seq
	29E4 00		db 0	;fill 1--ast address for (,ENrMT)

T)ummy Data Section

0000	dseq	0	;absolute low memory
		org	0	;(interrupt vectors)
0000	intO offset	rw	1
0002	intO-segment	rw	1
		pad to svstem call vector
0004		rw	2*(bdos_int-l)
0380	bdos offset	rw	1
0382	bdos-seqment	rw	1
		END

All Information Presented Here is Proprietarv to nigital. Research

135
	Appendix F
	CB10S Listing

This is the listing of the skeletal CRIOS which
you can use as the basis for a customized Ring
for non-standard hardware. The essential oor
tions of the BIOS remain, with "rs" statements
marking the routines to be inserted.

This Customized BIOS adapts W/M-86 to
the		foTTowinq hardware configuration
	Processor:
	Brand:
	Controller:

Programmer:
Revisions

FFFF	true	equ -1
0000	false	eau not true
0000	cr	equ 01h ;carriage return
OOOA	if	equ Oah ;Tine feed

Loader bios is true if assemblinq the
LOADER BIOS, otherwise BIOS is for the
CPM.SYS file.

0000	loader bios		equ false
OOEO	bdos-int	equ 224 ;reserved MOS interrupt

	IF	not loader bios
------------------------- 2 -------------------
	d
2500	bios code	eQu 2500h
0000	cco offset	equ 0000h
OB06	bdos ofst	equ 0906h ;BOOS entrv point
	d -		I
; ---------------------------------------------

All Information Presented Here is Proprietary to Digital Research

137
CP/M-86 System Guide	Appendix P		r9TO4 Listinq

	ENDIF	;not loader-hios
	IV	loader bios
--------------------- i -----------------------

P
bios-code	eau		1200h	;start of LnBInq
ccp_offset	equ		0003h	;base of CPMLOADER
bdos ofst	equ		0406h	;stripped BOOS entr
K -				T
---------------------------------------------
7NDIP 	;loader-hios

cseq
	orq	ccooffset
ccp:
orq 	bios-code

BIOS Jump Vector for Indiviaual Routines

2500		E93COO	imp	IMIT	;Fnter from BOOT POM or LOADFR
2503		E97900	jmp	WBOOT	;Arrive here from BOOS call 0
2506		F98500	Imp	CONST	;return console keyboara status
2509		E98DOO	imp	CONIN	;return consoTe kevboarl char
250C		E99AOO	Imp	cnNn"T	;write char to console device
250P		E9A200	Imp	LTSTOUT	;write character to list aevice
2512		E9B500	imp	P"NCH	;write character to punch aevice
2515		EM00	imp	REAOFR	;return char from reader device
2518		E9F600	imp	MOME	;move to trk 00 on-cur sel arive
251B		E9D900	imp	SELDSK	;select disk for next rd/write
251E		E90101	Imp	SETTRK	;set track for next r6/write
2521		E90301	Imp	SETSEC	;set sector for next rd/write
2524		E90COl	imp	SFTDMA	;set offset for user buff (OmA)
2527		E91701	Imp	READ	;read a 128 byte sector
252A		E94701	Imp	WRITE	;write a 128 byte sector
2525		E98POO	Imp	LISTST	;return list status
2530		E9F900	Imp	SECTRAN	;x1ate 1oqicaT->vhvsicaT sector
2533		E90201	Imp	SETDMAR	;set seq base for buff (nMA)
2536		E90401	Imn	GETSEGT	;return offset of Mem Desc Table
2539		E9A400	Imp	GFTIOBP	;return 1/0 map byte (JORYTE)
253C		E9A500	Imp	SETIOBF	;set 1/0 map byte (TORYTE)

		INIT		Entrv Point, Differs for LDBIOS and
		BIOS, according to "Loader-Bios" value
	INIT:	;print siqnon message and initialize hardwa.
253F SCC8			mov ax,cs	;we entered with a JMPF so

All Information Presented Here is Proprietary to Digital Research

138
CP/M-86 System Guide	Aopendi-x P		CBTnq Listinq
2541 8EDO	mov ss,ax	;CS: as the initial value o
2543 8ED8	mov 1s,ax	;n,,3:,
2545 8ECO	mov es,ax	;and FS:
	;use local- stack durinq initialization
2547 BC5928	mov so,offset stkhase
254A PC	cld	;set forward direction

	TP	not loader bios
---------------------------------------------

This is a RIOS 4or the (PM.SvS file.
Setup all interrupt vectors in low
memory to address trar)

25433 IE		push ds	;save the r)'; register
254C C606A72600		mov I09YTF,O	;clear IORYTP
2551 980000		mov ax,O
2554 8FO8		mov r1s,ax
2556 8FCO		mov es,ax	;set Fq and nS to zero
		;setup interruat 0 to address trao routine
2558 (770600008225			m.ov intO offset,offset int-trao
255E 8COE0200		mov intO segment,CS
2562 BF0400		mov (1i,4
2565 BEOOOO		mov si'O	;then orooaqate
2568 39FP,01		mov cx,510	;trao vector to
256B F3A5		reo m.ovs ax,ax		;al-l- 256 interruots
		;BnOS offset to orooer interruot
256D (7-706800306013		mov bdos offset,bdos ofst
2573 1F		T)o r) d s -	,res-Fore the r)q reqister
		(additional- C.P/M-86 ini-ttalization)
	;I			I
--------------------------------------------
	FNDIP ;not loader-bios

IF 	loader-bios

;This is a BIOS for the LOV)PR
oush ds	;save data segment
mov ax,O
mov ds,ax	;r)oint to segment zero
;RDOS interruDt offset
mov bdos offset,bdos ofst
mov bdos seqment,(7q ;bdos interruot seqment
(additional LOAr)FR initialization)
Pot) (IS	;restore data seqment

------------------------------------------
	'PNT)IF 		;loader-bios

2574		BBB126	mov bx,ofFset siqnon
2577		E86FOO	call pmsq	;print siqnon message
257A		B100	Mov cl-,O	riefault to Ir A: on col-(9st
257C		E981DA	imp cco	;iumr) to cold start entrv o

All Tnformation Presented Fere is Proprietarv to r)iqital Pesearch

139
rP,/M-86 System ruide	AiDoendix F		rB-lOq Tjstinq

257F E984T)A	~,,MnnT:		~Mo ccr)+6	;direct entrv to rrP at com
		TF	not loader bios
	---------------------------------------------
;I	I
int-trar):
2582		FA	cli	;block interruiDt-,
258-1		8(-C8	mov ax,cs
258c		BPD8	mov ds,ax	;get our data segment
2587		BBr)126	mov hx,offset int tro
258A		E85(-00	call r)msq
258D		F4	h I t	h a rdstor)

--------------------------------------------
	7NMIF		;not loader-hios

("'P/M Character T/n Tnterface Routines

(',ONqT:	;console status
258F~		rs	10	;(fill--in)
2598 C3		ret
	MNIN:				;console inoiit
2599 F8F2FF		call, rr)NqT
259c 74FB		iz CONIN		;wait for RnA
259P		rs	in	;(fill-in)
25A8 C3		ret
	('ONOUT:			;console output
25A9		r s,	To	;(fill-in)
25B3 C3		ret		;then return data
	L11			;list device output
		~,TOJTT:
25T34			rs	10	;(fill-in)
25BE C 3			ret
	LTSTST:				;ooll list status
2 5T3F			r s	10	;ffill-in)
25(79 (73		ret
	PUNCH:			;wri.te punch device
25CA	rs	10	Hfill-in)
25D4 C3	ret

R'F,Ar)P R:
25D5	rs	10	;(fill-in)
25DF C3	ret

GETIOBP:
25EO AOA726	mov al,IOBYTF

All Information Presented Here is Proprietary to T)iqital Research

140
CP/M-86 System Guide	Appendix F		CBIOS Listing
25E3 C3		ret
	SETIOBF:
25E4 880EA726		mov I013YTE,cl	;set iobyte
25ES C3		ret	;iobvte not implemented

Qmsq:
25E9 BA07	mov al,[13X]	;qet next char from messaqe
25EB		84CO	test al,al
25F,T)		7421	1z return	;if zero return
25EF		8AC8	mov rL,AL
25F1		E8B5FF	call COMOUT	;print it
25F4		43	inc BX
25F5		EBF2	jmps pmsg	;next character and loop

Disk Tnput/Output Routines

	SELDSK:			;sel-ect disk given by reqister r!L
0002	ndisks		equ	2 ;number of disks (un to 16)
25F7 880EA826		mov disk,cl-		;save disk number
25FB BBOOOO		mov bx,0000h	;ready for error return
25FE 8OF902		cmp cl,ndisks		;n beyond max disks?
2601 730T)		inb return		;return if so
2603 B500		mov ch,O		;double(n)
2605 8BD9		mov bx,cx		;bx = n
2607		B104		mov	cl,4	;ready for *16
2609		D3E3		shl	bx,cl	;n = n * 16
260T3		B9F126		mov	cx,offset dpbase
260E		03D9		add	bx,cx	;dpbase + n * 16
2610		C3	return:	ret		;bx = .(IT)h

HOME:	;move selected disk to home position (Track
2611 r-706A9260000			mov trk,O	;set disk i/o to track zero
2617		rs	10	;(fil-l-in)
2621 C3		ret
	SETTRK:		;set track address given by rX
2622 890FA926		mov trk,rX
2626 C3		ret
	SETSEC:		;set sector number qiven by cx
2627 890EAB26		mov sect,(7X
26213 C3		ret

	SECTRAN:		;transl.ate sector rX usinq table at (r)XI
262C 8BD9		mov bx,cx
262P, 03DA		add bx,dx	;add sector to tran table a
2630 8AlF		mov bl,fbxl.	;get loqical- sector
2632 C3		ret

S'PTDMA:		;set DMA offset given by rX

All Information Presented Here is Proorietary to I)iqital Research

141
CP/M-86 Svstem Guide	AiDpend i x P		CRI01; Listina

2633		890EAD26		mov dma-adr,rX
2637		C73		ret
		SFTDmAR:			;set T)MA seqment qiven bv rX
2638		890EAF26		mov dma-seq,(7X
263C		(73		ret
		r,PTSPGT:			;return address of Physical memr)rv table
2631)		BBE826		mov bx,offset seq-table
2640		C3		ret

All aisk 1/0 t)arameters are setur):
MSK	is		disk number	(~;FLnqK)
TRK	is		track number
C;F C rr	i s		sector number
DMA AT)R		is	the DMA offset	(1;FTDMA)
DMA SEG	is		the T)mA seqment	(SPIPT)MAT3)
READ reads the selected sector to the T)MA*
address, and WRITF writes the data from
the DMA address to the selected sector
(return 00 if successful, 01 if perm err)*

READ:
2641	rs	50	;fill-in
2673 C3	ret

WRITE:
2674	rs	50	;(fill-in)
26A6 C3	ret

T)ata Areas

	26A7	data-offset		equ offset $
			dseq
			org	data offset	;contiquous with co
	26A7 00	IOBYTE		db	0
26A8		00	disk	9b	0	;disk number
26A9		0000	trk	dw	0	;track number
26AB		0000	sect	dw	0	;sector number
26AD		0000	dma adr	dw	0	;DMA offset from T)S
26AF		0000	dma-seq	dw	0	;T)MA Base Seqment

IP	loader bios
---------------------------------------------

signon		db	cr,lf,cr,lf

All. Information Presented Here is Proprietary to r)iqital Research

142
CP/M-86 System Guide				Apoendix P	rBIOq Listinq
	db	'rP/M-86		Version 1.0',c-.r,I-F,O
	;I	I

FNDIP 	;1-oader-bios

	I'p	not loader bi.os
---------------------------------------------

26111		ODOAOT)OA	signon	db	cr,lf,cr,lf
26B5		537973746560	db	'System renerated 00/00/00'
	2047656E6572
	617465642030
	302F30302730
	30
26CE		Or)OAOO		lb	cr,lf,O

--------------------------------------------
	7,Nn IF	;not loader-bios

26r)l		OnOA	int-trp db	cr , If
2603		496F74657272	c1b	Tnterrupt "'rao TialtA
	757074205472
	617020486167
	74
26F6		OnOA	db	cr,lf

Svstem Memory qeqment Table

26F8 02	seqtabl.e 1b 2	;2 seqments
26P,9		r602	dw toa seq	;1st seq starts after RIOS
26PI3		3405	dw toa len	;and extends to 08000
26ED		0020	dw 200~h	;second is 20000 -
26FP		0020	r3w 2000h	;3FFFP (128k)

include		sinql.es.1-ib ;read in disk definitio
			DISKS 2
26FI	dpbase		equ	8	;Base of ni-sk Param
=26171		20270000	dDeO	dw	xl-tO,0000h	;Translate Table
=26P5		00000000		dw	0000h,0000h	;Scratch Area
=26F9		3A271127		dw	dirbuf,dpbO	;r)ir Buff, Parm 131o
=26PD		0927TIA27	dw	csvO,alvO	;rheck, A1.1oc Vecto
=2701		20270000	dpel	dw	x1t1,0000h	;Translate Table
=2705		00000000		dw	0000h,0000h	;Scratch Area
=2709		3A271127		dw	dirhuf,dubl	;Dir Buff, Parm Rlo
=270D		0828P-927	dw	csvl,alvl	;(7heck, All-oc Vecto
DISKDEF 0,1,26,6,1024,243,64,64,2
2711	dobO	equ	offset	;Disk Parameter R1.o
=2711 1AO0	dw	26	;Sectors Per Track
=2713 03	db	3	;T31ock Shift
=2714 07	db	7	;T31ock Mask
=2715 00	db	0	;Pxtnt Mask
=2716 F200	dw	242	;r)isk Size
=2718 3FOO	dw	63	;T)irectorv Max
=271A CO	db	192	;A11ocO
=271B 00	db	0	;A110cl

All Information Presented Here is Proorietarv to niqital Research

143
CP/M-86 Svstem Guide	Aopendix P	rRIOq Listinq

	=271C 1000		dw	I f;	;Check Size
	=271E 0200		dw	2	Qffset
	2720	x1to	equ	offset 5	;Translate Table
=2720 01070D13		db	1,7,13,19
=2724 1905OB11		db	25,5,11,17
=2728 170309OF		1b	23,1,9,15
=272C 1502080F,		db	21,2,8,14
=2730 141AO60C		db	20,26,6,12
=2734 1218040A		db	18,24,4,10
	=2738 1016		db	16,22
	001F	alsO	equ	31	;Allocation Vector
	0010	csso	equ	16	;Check Vector Size
				nISKDF7 110
	2711	dobl	equ	dobO	;Pquivalent Paramet
	001F	alsl	equ	alsO	;Same Allocation ve
	0010	cssl	equ.	csso	;Same rhecksum Vect
	2720	xitl	equ	x1to	;Same Translate lab
				ENDEF

TIninitialized Scratch Memorv Follows:

273A	beqdat	equ	offset $	;Start of Scratch A
=273A	dirbuf	rs	128	;nirectorv Ruffer
=27BA	a1v0	rs	alsO	;Alloc Vector
=27D9	csvo	rs	csso	;Check Vector
=27E9	alvl	rs	alsl	;Alloc Vector
=2808	csv1	rs	cssl	;Check Vector
= 2818	enddat	equ	offset	;End of Scratch Are
=	OODE	datsiz	equ	offset S-beqdat		;Size of Scratch Ar
=2818 00		db	0	;Marks End of Modul

2819	loc st.k rw	32	Qocal- stack for initialization
	2859	stkEase		equ offset 5
	2859	lastoff		equ. offset 1,'
	02C6	tpa_seg		equ (lastoff+0400h+15) / 16
	053A	tpa_len		equ 0800h - tpa_seq
	2859 00		db 0	;fill last address for GEFCMr)

Dummy nata Section

0000	dseg	0	;absolute low memorv
		org	0	;(interrupt vectors)
0000	intO offset	rw	1
0002	intO_segment	rw	1
		pad to svstem call vector
0004		rw	2*(bdos-int-1)
0380	bdos offset	rw	1
0382	bdos_seqment	rw	I
		END

All Information Presented Here is Proprietarv to Diqital Research

144
Index

A	G
allocate ahqolute memorv, 52	(-,T-,~4(-mn, 2, 3, 15, 17
allocate memorv, 52		2
	aet address nf disk oarameter
B		hlo(-k, 41
	n-t- allocation vectnr
base nane, I	ad(-Irps-,, 39
BIO-,, 121	q-t nMA hase, 48
bootstraTD, 4	q-t T/n bvte, 27
bootstrao Rnm, 81	apt maximum Memorv, 91
	qet		or -,et user cn(9e, 41
C	qet		read/onlv vector, 40
	(7, Fr T n,3 , (; 5
CBMS, 56,	1-37	r'1F1pqF(7R' 65
close file,	34	2
r"IT), 1, 15
col(4 start loader, 1, 56, 81
comTDact memorv model, 11, ?1
comoute fi-le size, 45	hearlpr recorH, 20
('ON'TN, 61	QO~171' r1i
C01-MITT,		61
console		inout, 25
console		outiDut, 25
console		status, 30	TNT- , 4, r)O
CONST, 60	Tntp' utilitip-, 17
convertinq 8080 iDroarams	TnByplp,, c;R
	to (-P/M-86, 3, 17, 23
cross develooment tool-,, 2

D			L-module	Format, Iq
		T,T)('OPV , 2
data block, 72, 74	J.jqT, 61
,9el-ete file, 36	list output,	26
r9ir-ct BMS cal-T, 47	T,I,-,T-,T, 63
direct consol.e T/n, 27		10
directorv entries, 71	loqi.cal- to nhvsical -,-ctr)r
disk definition tables, 4, 67		translation, 64
disk parameter hlock, 6q
disk narameter header, Q,	14
	6,7, 75
DMA buffer, 14, 39, 60, 63	make file, 37
	Tnemorv, 14
F	memorv reqion table, 65
	memorv reqions, I
far call, 11, 14
file control block, 30	0
file structure, I
free all memorv, 93	offset, 2
	oyDen 'File, 33

145
Index

P		T
print strinq, 28	translation vectors, 6q
Droqram load, 53
PUNCH, 61	U
punch output, 26	utility oroqram noeration, 2
R
		W
random access, 95
READ, 63	WBOOT, 60
read buffer, 29	WRITE, 63
read random, 42	write protect disk, 39
read sequential, 36	write random, 44
READER, 61	write random with zero
reader input, 26		fill, 47
release all memory, 53
release memory, 52
rename, 38	R080 memorv model, 3, 10,
reserved software interrupt,		14, 21
	1, 23
reset disk, 33
reset drive, 46
return current disk, 38
return Toqin vector, 38
return version numher, 30
S
search for first, 35
search for next, 35
sector blocking and
	deblockinq, 87
SEC-RAN, 64
sewent, 2
seqmeht qroup memorv
	requirements, 17
seqment reqister chanqe, 11
seqment reqister
	initialization, 9
MLOSX, 62
select disk, 33
set DMA address, 39
set DMA base, 48
set file attributes, 41
set T/O byte, 28
set random record, 46
MTOMA, 63
SFTDMAB, 64
SWIM, 65
qETSEC, 62
SETTRX, 62
small memorv model, 10, 21
system reset, 4, 7, 14, 25
	49, 60, 74

146
