#####################################################################
Sections 5 and 6 have been corrected, using a hardcopy manual (second
printing, June 1981).
Freek Heite, 04Mar2001
#####################################################################

CP/M-86 TM
System Guide

Copyright (C) 1981

Digital. Research
P.O. Box 579
801 Lighthouse Avenue
Pacific Grove, CA 93950
(408) 649-3896
TWX 910 360 5001

All Rights Reserved

Foreword

        The CP/M-86 System Guide presents the system programming
aspects of CP/M-86 TM, a single-user operating system for the Intel
8086 and 8088 16-bit microprocessors. The discussion assumes the
reader is familiar with CP/M  the Digital Research 8-bit operating
system. To clarify specific differences with CP/M-86, this document
refers to the 8-bit version of CP/M as CP/M-80 TM. Elements common
to both systems are simply called CP/M features.

CP/M-80 and CP/M-86 are equivalent at the user interface level
and thus the Digital Research documents:

        . An Introduction to CP/M Features and Facilities
        . ED: A Context Editor For the CP/M Disk System
        . CP/M 2 User's Guide

are shipped with the CP/M-86 package. Also included is the CP/M-86
Programmer's Guide, which describes ASM-86 TM and DDT-86 TM, Digital
Research's 8086 assembler and interactive debugger.

        This System Guide presents an overview of the CP/M-86
programming interface conventions. It also describes procedures for
adapting CP/M-86 to a custom hardware enviornment. This information
parallels that presented in the CP/M 2 Interface Guide and the CP/M
2 Alteration Guide.

        Section 1 gives an overview of CP/M-86 and summarizes its
differences with CP/M-80. Section 2 describes the general execution
environment while Section 3 tells how to generate command files.
Sections 4 and 5 respectively define the programming interfaces to
the Basic Disk Operating System and the Basic Input/Output System.
Section 6 discusses alteration of the BIOS to support custom disk
configurations, and Section 7 descrihes the loading operation and
the organization of the CP/M-86 system 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             GENDEEF 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 groups 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 groups 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 groups. 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 segment 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 Digital 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 group 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 System 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 tvping 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 group 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 segment. 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 segment 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 segment, 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 segments when no segment 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 segment 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 group'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 nigital 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 Digital 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 Digital 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 segment 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 segment (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 System 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 I/O System (BIOS) Organization

The distribution version of CP/M-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 I/O
System, or BIOS. A CP/M-86 system implementor can modify these
subroutines, as described below, to tailor CP/M-86 to fit nearly any
8086 or 8088 operating environment. This section describes the
actions of each BIOS entry point, and defines variables and tables
referenced within the BIOS. The discussion of Disk Definition
Tables is, however, treated separately in the next section of this
manual.

5.1 Organization of the BIOS

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

CS, DS, ES, SS:      +------------------------+
                     |      Console           |
                     |      Command           |
                     |      Processor         |
                     |                        |
                     |         and            |
                     |      Basic             |
                     |      Disk              |
                     |      Operating         |
                     |      System            |
                     +------------------------+
        CS + 2500H:  |  BIOS Jump Vector      |
                     +------------------------+
        CS + 253FH:  |                        |
                     |  BIOS Entry 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

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

55


As described in the following sections, the CCP and BDOS are
supplied with CP/M-86 in hex file form as CPM.H86. In order to
implement CP/M-86 on non-standard hardware, you must create a BIOS
which performs the functions listed below and concatenate the
resulting hex file to the end of the CPM.H86 file. The GENCMD
utility is then used to produce the CPM.SYS file for subsequent load
by the cold start loader. The cold start loader that loads the
CPM.SYS file into memory contains a simplified 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 listing 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" BIOS called CBIOS that contains
the essential elements with the device drivers removed. You may
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 "jump vector" located at offset
2500H from the base of the operating system. The jump vector is a
sequence of 21 three-byte jump instructions which transfer program
control to the individual BIOS entry points. Although some non-
essential BIOS subroutines may contain a single return (RET)
instruction, the corresponding jump vector element must be present
in the order shown below in Table 5-1. An example of a BIOS jump
vector may be found in Appendix D, in the standard CP/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; DX is used for a second argument. Return values
are passed in the registers according to type: Byte values are
returned in AL. Word values (16 bits) are returned in BX. Specific
parameters and returned values are described with each subroutine.


All Information Presented Here is Proprietary 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 BIOS

2500H           JMP     INIT    0       Arrive Here from Cold Boot
2503H           imp     WBOOT   1       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 Listing Character Out
2512H           JMP     PUNCH   6       Write Char to Punch Device
2515H           JMP     READER  7       Read Reader Device
2518H           JMP     HOME    8       Move to Track 00
251BH           JMP     SELDSK  9       Select Disk Drive
251EH           JMP     SETTRK  10      Set 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      Get MEM DESC Table Offset
2539H           JMP     GETIOB9 19      Get I/O Mapping Byte
253CH           JMP     SETIOB  20      Set I/O Mapping Byte
---------------------------------------------------------------------

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

5.3 Simple Peripheral Devices

All simple character I/O 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
BIOS. 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 Devices


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

CONSOLE         The principal interactive console which
                communicates with the operator, accessed through
                CONST, CONIN, and CONOUT. Typically, the CONSOLE
                is a device such as a CRT or Teletype.

LIST            The principal listing device, if it exists on your
                system, which is usually a hard-copy device, such
                as a printer or Teletype.

PUNCH           The principal tape punching device, if it exists,
                which is normally a high-speed Paper tape punch or
                Teletype.

READER          The principal tape reading device, such as a
                simple optical reader or Teletype.
---------------------------------------------------------------------

Note that a single peripheral can be assigned as the LIST,
PUNCH, and READER device simultaneously. If no peripheral device is
assigned as the LIST, PUNCH, or READER device, your BIOS should
give an appropriate error message so that the system does not "hang"
if the device is accessed by PIP or some other transient program.
Alternately, the PUNCH and LIST subroutines can just simply return,
and the READER subroutine can return with a 1AH (ctl-Z) in reg A to
indicate immediate end-of-file.

For added flexibility, you can optionally implement the
"IOBYTE" function which allows reassignment of physical and logical
devices. The IOBYTE function creates a mapping of logical to
physical devices which can be altered during CP/M-86 processing (see
the STAT command). The definition of the IOBYTE function
corresponds to the Intel standard as follows: a single location in
the BIOS is maintained, called IOBYTE, which defines the logical to
physical device mapping which is in effect at a particular time.
The mapping is performed by splitting the IOBYTE into four distinct
fields of two bits each, called the CONSOLE, READER, PUNCH, and LIST
fields, as shown below:

          most significant        least significant
          +-------+---------+----------+----------+
IOBYTE    | LIST  |  PUNCH  |  READER  |  CONSOLE |
          +-------+---------+----------+----------+
           bits 6,7 bits 4,5  bits 2,3  bits 0,1


All Information Presented Here is Proprietary to Digital Research

58

CP/M-86 System Guide    5.3       Simple eripheral Devices


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

           Table 5-3. IOBYTE Field Definitions
---------------------------------------------------------------------
CONSOLE field (bits 0,1)
0 - console is assigned to the console printer (TTY:)
1 - 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 (BAT:)
3 - user defined console device (UC1:)

READER  field (bits 2,3)
0 - READER is the teletype device (TTY:)
1 - READER is the high-speed reader device (RDR:)
2 - user defined reader # 1 (UR1:)
3 - user defined reader # 2 (UR2:)

PUNCH field (bits 4,5)
0 - PUNCH is the teletype device (TTY:)
1 - PUNCH is the high speed punch device (PUN:)
2 - user defined punch # 1 (UP1:)
3 - user defined ounch # 2 (UP2:)

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

Note again that the implementation of the IOBYTE is optional,
and affects only the organization of your CBIOS. No CP/M-86
utilities use the IOBYTE except for PIP which allows access to the
physical devices, and STAT which allows logical-physical assignments
to be made and displayed. In any case, you should omit the IOBYTE
implementation until your basic CBIOS 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 System Guide    5.4            BIOS Subroutine Entry Points


5.4 BIOS Subroutine Entry Points

The actions which must take place upon entry to each BIOS
subroutine are given below. It should be noted that disk I/O is
always performed through a sequence of calls on the various disk
access subroutines. These setup the disk number to access, the
track and sector on a particular disk, and the direct memory access
(DMA) offset and segment addresses involved in the I/O operation.
After all these parameters have been setup, a call is made to the
READ or WRITE function to perform the actual I/O operation. Note
that there is often a single call to SELDSK to select a disk drive,
followed by a number of read or write operations to the selected
disk before selecting another drive for subsequent operations.
Similarly, there may be a call to set the DMA segment base and a
call to set the DMA offset followed by several calls which read or
write from the selected DMA address before the DMA address is
changed. The track and sector subroutines are always called before
the READ or WRITE operations are performed.

The READ and WRITE subroutines should perform several retries
(10 is standard) before reporting the error condition to the BDOS.
The HOME subroutine may or may not actually perform the track 00
seek, depending upon your controller characteristics; the important
point is that track 00 has been selected for the next operation, and
is often treated in exactly the same manner as SETTRK with a
parameter of 00.

      Table 5-4. BIOS Subroutine Summary

+------------+---------------------------------------------+
| Subroutine |              Description                    |
+------------+---------------------------------------------+
INIT    This subroutine is called directly by the CP/M-86
        loader  after the CPM.SYS file has been read into
        memory. The procedure is responsible for any
        hardware initialization not performed by the
        bootstrap loader, setting initial values for BIOS
        variables (including IOBYTE), printing a sign-on
        message, and initializing the interrupt vector to
        point to the BDOS offset (0B11H) and base. When
        this routine completes, it jumps to the CCP
        offset (0H).  All segment registers should be
        initialized at this time to contain the base of
        the operating system.

WBOOT   This subroutine is called whenever a program
        terminates by performing a BDOS function #0 call.
        Some re-initialization of the hardware or
        software may occur here. When this routine
        completes, it jumps directly to the warm start
        entry point of the CCP (06H).

CONST   Sample the status of the currently assigned
        console device and return 0FFH in register AL if
        a character is ready to read, and 00H in register
        AL if no console characters are ready.


All Information Presented Here is Proprietary to Digital Research

60

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


CONIN   Read the next console character into register AL,
        and set the parity bit (high order bit) to zero.
        If no console character is ready, wait until a
        character is typed before returning.

CONOUT  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 may 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
        line (such as a TI 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 CL to the
        currently assigned listing device. The character
        is in ASCII with zero parity.

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 currently
        assigned reader device into register AL with zero
        parity (high order bit must be zero). An end of
        file condition is reported by returning an ASCII
        CONTROL-Z (1AH).

HOME    Return the disk head of the currently selected
        disk to the track 00 position. If your
        controller does not have a special feature for
        finding 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 Entry Points


SELDSK  Select the disk drive given by register CL for
        further operations, where register CL contains 0
        for drive A, 1 for drive B, and so on until 16
        for drive P (the standard (CP/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.
        For standard floppy disk drives, the content of
        the header and associated tables does not change.
        The sample BIOS included with CP/M-86 called
        CBIOS, contains an example program segment that
        performs the SELDSK function. If there is an
        attempt to select a non-existent drive, SELDSK
        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 I/O
        function (seek, read or write) is performed.
        This is due to the fact that disk select
        operations may take place without a subsequent
        disk operation and thus disk access may be
        substantially slower using some disk controllers.
        On entry to SELDSK it is possible to determine
        whether it is the first time the specified disk
        has been selected. Register DL, bit 0 (least
        significant bit) is a zero if the drive has not
        been previously selected. This information is of
        interest in systems which read configuration
        information from the disk in order to set up 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 delay 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 delay sector selection
        until a read or write operation occurs.


All Information Presented Here is Proprietary to Digital Research

62

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


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 0FFH 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
        SETDMAB occur. Note that the controller need not
        actually support direct memory access. If, for
        example, all data is received and sent through
        I/O 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
        following read or write operations.

READ    Assuming the drive has been selected, the track
        has been set, the sector has been set, and the
        DMA offset and segment base have been specified,
        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 CP/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 BDOS will print the message "BDOS ERR ON x:
        BAD SECTOR". The operator then has the option of
        typing  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 0FFH 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


SECTRAN Performs logical to physical sector translation
        to improve the overall response of CP/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 time
        between sectors for most programs to load their
        buffers without missing the next sector. In
        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 single
        density IBM compatible version of CP/M-86 for
        information transfer into and out of your
        computer system, using a skew factor of 6. In
        general, SECTRAN receives a logical sector number
        in CX. This logical sector number may range 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 = 0000H no
        translation takes place, and CX is simply copied
        to BX before returning. Otherwise, SECTRAN
        computes and returns the translated sector number
        in BX. Note that SECTRAN is called when no
        translation is specified in the Disk Parameter
        Header.

SETDMAB Register CX contains the segment base for
        subsequent DMA 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 Region Table
        (MRT) in BX. The returned value is the offset of
        the table relative to the start of the operating
        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 Entry Points


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

                  8-bit
                +-------+
           MRT: | R-Cnt |
                +---------------------------------+
             0: |     R-Base     |     R-Length   |
                +---------------------------------+
             1: |     R-Base     |     R-Length   |
                +---------------------------------+
                                 . . .
                +---------------------------------+
             n: |     R-Rase     |     R-Length   |
                +---------------------------------+
                |     16-bit     |     16-bit     |
                +---------------------------------+

        where R-Cnt is the number of Memory Region
        Descriptors (equal to n+1 in the diagram above),
        while R-Base and R-Length give the paragraph base
        and length of each physically contiguous area of
        memory. Again, the reserved interrupt locations,
        normally 0-3FFH, and the CP/M-86 operating system
        are not included in this map, because the map
        contains regions, available to transient programs.
        If all memory is contiguous, the R-Cnt field is 1
        and n = 0, with only a single Memory Region
        Descriptor which defines the region.

GETIOB  Returns the current value of the logical to
        physical input/output device byte (IOBYTE) in AL.
        This eight-bit value is used to associate
        physical devices with CP/M-86's four logical
        devices.

SETIOB  Use the value in CL to set the value of the
        IOBYTE stored in the BIOS.

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 Proprietary to Digital Research

65

Section 6

BIOS Disk Definition Tables

Similar to CP/M-80, CP/M-86 is a table-driven operating system
with a separate field-configurable Basic I/O System (BIOS). By
altering specific subroutines in the BIOS presented in the previous
section, CP/M-86 can be customized for operation on any RAM-based
8086 or 8088 microprocessor system.

The purpose of this section is to present the organization and
construction of tables within the BIOS that define the
characteristics of a particular disk system used with CP/M-86.
These tables can be either hand-coded or automatically generated
using the GENDEF utility provided with CP/M-86. The elements of
these tables are presented below.

6.1 Disk Parameter Table Format

In general, each disk drive has an associated (16-byte) disk
parameter header which both contains information about the disk
drive and provides a scratchpad area for certain BDOS operations.
The format of the disk parameter header for each drive is shown
below.

                Disk Parameter Header
+----------------------------------------------------------------+
| XLT  |  0000  | 0000  | 0000  | DIRBUF | DPB  |  CSV  |  ALV   |
+----------------------------------------------------------------+
| 16b  |   16b  |  16b  |  l6b  |   16b  | 16b  |  16b  |  16b   |
+----------------------------------------------------------------+

where each element is a word (16-bit) value. The meaning of each
Disk Parameter Header (DPH) element is given in Table 6-1.

         Table 6-1. Disk Parameter Header Elements

Element Description

XLT     Offset of the logical to physical translation vector,
        if used for this particular drive, or the value 0000H
        if no sector translation takes place (i.e, the
        physical and logical sector numbers are the same).
        Disk drives with identical sector skew factors share
        the same translate tables.

0000    Scratchpad values for use within the BDOS (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


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

DPB     Offset of a disk parameter block for this drive.
        Drives with identical disk characteristics address the
        same disk parameter block.

CSV     Offset of a scratchpad area used for software check for
        changed disks. This offset is different for each DPH.

ALV     Offset of a scratchpad area used by the BDOS to keep
        disk storage allocation information. This offset is
        different for each DPH.

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

DPBASE
    +------------------------------------------------------------------+
00  |  XLT-00   0000   0000   0000   DIRBUF   DBP 00   CSV 00   ALV 00 |
    +------------------------------------------------------------------+
01  |  XLT-01   0000   0000   0000   DIRBUF   DBP 01   CSV 01   ALV 01 |
    +------------------------------------------------------------------+
                        (and so-forth through)
    +------------------------------------------------------------------+
n-1 |  XLTn-1   0000   0000   0000   DIRBUF   DBPn-1   CSVn-1   ALVn-1 |
    +------------------------------------------------------------------+

where the label DPBASE defines the offset of the DPH table relative
to the beginning of the operating system.

A responsibility of the SELDSK subroutine, defined in the
previous section, is to return the offset of the DPH from the
beginning of the operating system for the selected drive. The
following sequence of operations returns the table offset, with a
0000H 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


NDISKS  EQU     4               ;NUMBER OF DISK DRIVES
......
SELDSK:
        ;SELECT DISK N GIVEN BY CL
        MOV BX,0000H            ;READY FOR ERR
        CMP 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
        SHL BX,CL               ;N = N * 16
        MOV CX,OFFSET DPBASE    ;DPBASE
        ADD BX,CX               ;DPBASE + N * 16
RETURN: RET                     ;BX - .DPH (N)

The translation vectors (XLT 00 through XLTn-l) are located
elsewhere in the BIOS, and simply 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
DPB, which is addressed bv one or more DPH's, takes the general
form:

      +-----------------------------------------------------------+
      | SPT | BSH | BLM | EXM | DSM | DRM | AL0 | AL1 | CKS | OFF |
      +-----------------------------------------------------------+
        16b    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.

BLM     is the block mask which is also determined by 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.

DRM     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 System Guide    6.1            Disk Parameter Table Format


            Table 6-2. (continued)

AL0,AL1 determine reserved directory blocks.

CKS     is the size of the directory check vector.

OFF     is the number of reserved tracks at the beginning of
        the (logical) disk.

Although these table values are produced automatically by GENDEF, it
is worthwhile reviewing the derivation of each field so that the
values may be cross-checked when necessary. The values of BSH and
BLM determine (implicitly) the data allocation size BLS, which is
not an entry in the disk parameter block. Given that you have
selected a value for BLS, the values of BSH 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

               +------------------------------+
               |   BLS        BSH         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 upon 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. Maximum EXM Values

               +-------------------------------------+
               |   BLS      DSM < 256      DSM > 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+1) 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            Disk Parameter Table Format


The DRM entry is one less than the total number of directory
entries, which can take on a 16-bit value. The values of AL0 and
AL1, however, are determined by DRM. The two values AL0 and AL1 can
together be considered a string of 16-bits, as shown below.

   +-----------------------+-----------------------+
   |          AL0          |          AL1          |
   +-----------------------------------------------+
   |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
   +-----------------------------------------------+
    00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15

where position 00 corresponds to the high order bit of the byte
labeled AL0, and 15 corresponds to the low order bit of the byte
labeled AL1. Each bit position reserves a data block for a number
of directory entries, thus allowing a total of 16 data blocks to be
assigned for directory entries (bits are assigned starting at 00 and
filled to the right until position 15). Each directory entry
occupies 32 bytes, as shown in Table 6-5.

        Table 6-5. BLS and Number of Directory Entries

        +---------+--------------------+
        |   BLS   |  Directory Entries |
        +---------+--------------------+
        |  1,024     32  times #  bits |
        |  2,048     64  times #  bits |
        |  4,096     128 times #  bits |
        |  8,192     256 times #  bits |
        | 16,384     512 times #  bits |
        +------------------------------+

Thus, if DRM= 127 (128 directory entries) , and BLS = 1024, then
there are 32 directory entries per block, requiring 4 reserved
blocks. In this case, the 4 high order bits of AL0 are set,
resulting in the values AL0 = 0F0H and AL1 = 00H.

The CKS value is determined as follows: if the disk drive
media is removable, then CKS = (DRM+1)/4, where DRM is the last
directory entry number. If the media is fixed, 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 beginning 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 segmented sections.

To complete the discussion of the DPB, recall that several
DPH's can address the same DPB if their drive characteristics are
identical. Further, the DPB can be dynamically changed when a new
drive is addressed by simply changing the pointer in the DPH since
the BDOS copies the DPB values to a local area whenever the SELDSK
function is invoked.


All Information Presented Here is Proprietary to Digital Research

71

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


Returning back to the DPH for a particular drive, note that the
two address values CSV and ALV remain. Both addresses reference an
area of uninitialized memory following the BIOS. The areas must be
unique for each drive, and the size of each area is determined by
the values in the DPB.

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 = (DRM+1)/4, then you must reserve
(DRM+1)/4 bytes for directory 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 (DSM/8)+1.

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

6.2 Table Generation Using GENDEF

The GENDEF utility supplied with CP/M-86 greatly simplifies the
table construction process. GENDEF reads a file

        x.DEF

containing the disk definition statements, and produces an output
file

        x.LIB

containing assembly language statements which define the tables
necessary to support a particular drive configuration. The form of
the GENDEF command is:

        GENDEF x parameter list

where x has an assumed (and unspecified) filetype of DEF. The
parameter list may contain zero or more of the symbols defined in
Table 6-6.

        Table 6-6. GENDEF Optional Parameters

        +-----------+---------------------------------+
        | Parameter |             Effect              |
        +-----------+---------------------------------+
        |    $C      Generate Disk Parameter Comments |
        |    $O      Generate DPBASE OFFSET $         |
        |    $Z      Z80, 8080, 8085 Override         |
        |    $COZ    (Any of the Above)               |
        +---------------------------------------------+


All Information Presented Here 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

        DPBASE  EQU     $

which requires a MOV CX,OFFSET DPBASE in the SELDSK subroutine shown
above. For convenience, the $O parameter produces the definition

        DPBASE  EQU     OFFSET $

allowing a MOV CX,DPBASE 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.DEF 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/M-
80 Version 2. A BIOS disk definition consists of the following
sequence of statements:

        DISKS           n
        DISKDEF         0,...
        DISKDEF         1,...
        ......
        DISKDEF         n-1
        ......
        ENDEF

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

The DISKS statement defines the number of drives to be
configured with your system, where n is an integer in the range 1
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, tvpically at the end of your BIOS,
before the start of uninitialized RAM.

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


All Information Presented Here is Proprietary to Digital Research

73

CP/M-86 System Guide    6.2            Table Generation Using GENDEF


The form of the DISKDEF statement is

        DISKDEF         dn,fsc,lsc,[skf],bls,dks,dir,cks,ofs,[0]

where

dn      is the logical disk number, 0 to n-1
fsc     is the first physical sector number (0 or 1)
lsc     is the last sector number
skf     is the optional sector skew factor
bls     is the data allocation block size
dks     is the disk size in bls units
dir     is the number of directory entries
cks     is the number of "checked" directory entries
ofs     is the track offset to logical track 00
[0]     is an optional 1.4 compatibility flag

The value "dn" is the drive number being defined with this DISKDEF
statement. The "fsc" parameter accounts for differing sector
numbering systems, and is usually 0 or 1. The "lsc' is the last
numbered sector on a track. When present, the "skf" parameter
defines the sector skew factor which is used to create a sector
translation table according to the skew. If the number of sectors
is less than 256, a single-byte table is created, otherwise each
translation table element occupies two bytes. No translation table
is created if the skf parameter is omitted or equal to 0.

The "bls" parameter specifies the number of bytes allocated to
each data block, and takes on the values 1024, 2048, 4096, 8192, or
16384. Generally, performance increases with larger data block
sizes because there are fewer directory references. Also, logically
connected data records are physically close on the disk. Further,
each directory entry addresses more data and the amount of BIOS work
space is reduced. The "dks" specifies the total disk size in "bls"
units. That is, if the bls = 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 directory entries which may exceed
255, if desired.

The "cks" parameter determines the number of directory items to
check on each directory scan, and is used internally to detect
changed disks during system operation, where an intervening cold
start or system reset has not occurred (when this situation is
detected, CP/M-86 automatically marks the disk read/only so that
data is not subsequently destroyed). As stated in the previous
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 typically 0, since the
probability of changing disks without a restart is quite low.


All Information Presented Here is Proprietary to Digital Research

74

CP/M-86 System Guide    6.2            Table Generation Using GENDEF


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 logical
drives on a single large capacity physical drive. Finally, the [0]
parameter is included when file compatibility is required with
versions of CP/M-80, version 1.4 which have been modified for higher
density disks (typically double density). This parameter ensures
that no directory compression takes place, which would cause
incompatibilities with these non-standard CP/M 1.4 versions.
Normally, this parameter is not included.

For convenience and economy of table space, the special form

        DISKDEF i,j

gives disk i the same characteristics as a previously defined drive
j. A standard four-drive single density system, which is compatible
with CP/M-80 Version 1.4, and upwardly compatible with CP/M-80
Version 2 implementations, is defined using the following
statements:

        DISKS   4
        DISKDEF 0,1,26,6,1024,243,64,64,2
        DISKDEF 1,0
        DISKDEF 2,0
        DISKDEF 3,0
        ENDEF

with all disks having the same parameter values of 26 sectors per
track (numbered 1 through 26), with a skew of 6 between sequential
accesses, 1024 bytes per data block, 243 data blocks for a total of
243 K byte disk capacity, 64 checked directory entries, and two
operating system tracks.

The DISKS statement generates n Disk Parameter Headers (DPH's)
starting at the DPH table address DPBASE generated by the statement.
Each disk header block contains sixteen bytes, as described above,
and corresponds one-for-one to each of the defined drives. In the
four drive standard system, for example, the DISKS statement
generates a table of the form:

DPBASE  EQU     $
DPE0    DW      XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV0,ALV0
DPE1    DW      XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV1,ALV1
DPE2    DW      XLT0,0000H,0000H,0000H,DIRBUF,DPB0,CSV2,ALV2
DPE3    DW      XLT0,0000H,0000H,0000H,DIRBUF,DPB0,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 Proprietary to Digital Research

75

CP/M-86 System Guide    6.2            Table Generation Using GENDEF


Note that if the "skf" (skew factor) parameter is omitted (or
equal to 0), the translation table is omitted, and a 0000H value is
inserted in the XLT position of the disk parameter header for the
disk. In a subsequent call to perform the logical to physical
translation, SECTRAN receives a translation table address of DX =
0000H, and simply returns the original logical 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 placed
into the corresponding DPH's. The table shown below, for example,
is constructed when the standard skew factor skf = 6 is specified in
the DISKDEF statement call:

        XLT0    EQU     OFFSET $
                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 are defined. These data areas need not be a part of the BIOS
which is loaded upon cold start, but must be available between the
BIOS and the end of operating system memory. The size of the
uninitialized RAM area is determined by EQU statements generated by
the ENDEF statement. For a standard four-drive svstem, the ENDEF
statement might produce

        1C72 =          BEGDAT EQU OFFSET $
                        (data areas)
        1DB0 =          ENDDAT EQU OFFSET $
        013C =          DATSIZ EQU OFFSET $-BEGDAT

which indicates that uninitialized RAM begins at offset 1C72H, ends
at 1DB0H-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 your
drive characteristics, since STAT uses the disk parameter block to
decode the drive information. The comment included in the LIB file
by the $C parameter to GENCMD will match the output from STAT. The
STAT command form

        STAT d:DSK:

decodes the disk parameter block for drive d (d=A,...,P) and
displays the values shown below:

        r: 128 Byte Record Capacity
        k: Kilobyte Drive 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 Digital Research

76

CP/M-86 System Guide    6.3             GENDEF Output


6.3 GENDEF Output

GENDEF 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). Each 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 files 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 binary, octal, decimal, or hexadecimal as   |
|           in ASM-86.                                     |
|                                                          |
| Delimit   Missing delimiter between parameters.          |
|                                                          |
| Duplic    Duplicate definition for a disk drive.         |
|                                                          |
| Extra     Extra Parameters occur at the end of line.     |
|                                                          |
| Length    Keyword or data item is too long.              |
|                                                          |
| 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 many files on LIB    |
|                                disk.                       |
|                                                            |
| Premature End-of-File          End of DEF file encountered |
|                                unexpectedly.               |
+------------------------------------------------------------+

Given the file TWO.DEF 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             GENDEF Output


                        ;       Sample Program Including TWO.Ll
                        ;
                        ;SELDSK:
                        ;       ....
  0000 B9 03 00                 MOV CX,OFFSET DPBASE
                        ;       ....
=                               INCLUDE TWO.LIB
=                       ;               DISK 2
= 0003                  dpbase  equ     $               ;Bseo 0
= 0003 32 00 00 00      dpe0    dw      xlt0,0000h      ;Transl
= 0007 00 00 00 00              dw      0000h,0hhhhh    ;Scratc
= 000B 5B 00 23 00              dw      dirbuf,dpb0     ;Dir Bu
= 000F FB 00 DB 00              dw      csv0,alv0       ;Check,
= 0013 00 00 00 00      dpe1    dw      xlt1,0000h      ;Transl
= 0017 00 00 00 00              dw      0000h,0000h     ;Scratc
= 001B 5B 00 4C 00              dw      dirbuf,dpb1     ;Dir Bu
= 00IF 9B 01 1B 01              dw      csv1,alv1       ;Check,
=                                       DISKDEF 0,1,26,6,2048,2
=                       ;
=                       ;       Disk 0 is CP/M 1.4 Single Densi
=                       ;        4096:  128 Byte Record Capacit
=                       ;         512:  Kilobyte Drive  Capacit
=                       ;         128:  32 Byte Directory Entri
=                       ;         128:  Checked Directory Entri
=                       ;         256:  Records / Extent
=                       ;          16:  Records / Block
=                       ;          26:  Sectors / Track
=                       ;           2:  Reserved  Tracks
=                       ;           6:  Sector Skew Factor
=                       ;
=   0023                dpbp0   equ     offset $        ;Disk P
= 0023 1A 00                    dw      26              ;Sector
= 0025 04                       db      4               ;Block
= 0026 0F                       db      15              ;Block
= 0027 01                       db      1               ;Extnt
= 0028 FF 00                    dw      255             ;Disk S
= 002A 7F 00                    dw      127             ;Direct
= 002C C0                       db      192             ;Alloc0
= 002D 00                       db      0               ;Alloc1
= 002E 20 00                    dw      32              ;Check
= 0030 02 00                    dw      2               ;Offset
=   0032                x1t0    equ     offset          ;Transl
= 0032 01 07 0D 13              db      1,7,13,19
= 0036 19 05 0B 11              db      25,5,11,17
= 003A 17 03 09 0F              db      23,3,9,15
= 003E 15 02 08 0E              db      21,2,8,14
= 0042 14 1A 06 0C              db      20,26,6,12
= 0046 12 18 04 0A              db      18,24,4,10
= 004A 10 16                    db      16,22
=   0020                als0    equ     32              ;Alloca
=   0020                css0    equ     32              ;Check
=                       ;               DISKDEF 1,1,58,,2048,10
=                       ;
=                       ;       Disk 1 is CP/M 1.4 Single Densi
=                       ;       16384:  128 Byte Record Capacit


All Information Presented Here is Proprietary to Digital Research

79

CP/M-86 System Guide            6.3             GENDEF Output


=                       ;        2048:  Kilobyte Drive  Capacit
=                       ;         300:  32 Byte Directory Entri
=                       ;           0:  Checked Directory Entri
=                       ;         128:  Records / Extent
=                       ;          16:  Records / Block
=                       ;          58:  Sectors / Track
=                       ;           2:  Reserved  Tracks
=                       ;
=   004C                dpb1    equ     offset $        ;Disk P
= 004C 3A 00                    dw      58              ;Sector
= 004E 04                       db      4               ;Block
= 004F 0F                       db      15              ;Block
= 0050 00                       db      0               ;Extnt
= 0051 FF 03                    dw      1023            ;Disk S
= 0053 2B 01                    dw      299             ;Direct
= 0055 F8                       db      248             ;Alloc0
= 0056 00                       db      0               ;Alloc1
= 0057 00 00                    dw      0               ;Check
= 0059 02 002                   dw      2               ;Offset
=   0000                xlt1    equ     0               ;No Tra
=   0080                als1    equ     128             ;Alloca
=   0000                css1    equ     0               ;Check
=                       ;               ENDEF
=                       ;
=                       ;       Uninitialized Scratch Memory Fo
=                       ;
=   005B                begdat  equ     offset $        ;Start
= 005B                  dirbuf  rs      128             ;Direct
= 00DB                  alv0    rs      als0            ;Alloc
= 00FB                  csv0    rs      css0            ;Check
= 011B                  alv1    rs      als1            ;Alloc
= 019B                  csv1    rs      css1            ;Check
=   019B                enddat  equ     offset $        ;End of
=   0140                datsiz  equ     offset $-begdat ;Size o
= 019B 00                       db      0               ;Marks
                                END


All Information Presented Here is Proprietary to Digital Research

80


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 adaoting (-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" group 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 System 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 mapping between CP/M and the host system, and
        must be chanqed if other than the sample host system is involved.

        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 nigital 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 segment 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 System 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)igital Research

92
CP/M-86 System 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 segment 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 Droprietary to T)igital 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 segment
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)igital- 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 Proprietary 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 group 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)igital 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, message 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 nigital- 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 System 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)igital- Research

100
CP/M-86 System 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 nigital- 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 segment*
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 Digital 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    frlcsegment     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 segment 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 nigital Research

109
CP/M-86 System 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       ;segment        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 segment,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 Proprietary to Digital 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 nigital 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 fdcsegment,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 nigital 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 nigital- 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)igital 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 segment
124C B80000             mov ax,O
124F 8ED8               mov ds,ax       ;point to segment zero
                ;BDOS interrupt offset
1251 C70680030604                       mov bdos - offset,bdos_ofst
1257 8COE8203           mov bdos-segment,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 message
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 Digital- 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 Proprietary to nigital. Research

117
(-P/M-86 System (,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 Digital 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 Oigital 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)igital 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 nigital 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                  ;segment 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)igital 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 message 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 segment,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 System 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 segment,(7S ;bdos interrupt segment
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 messages

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)igital 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 nigital 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 message
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 System 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 segment,al ;send 1-ow bvte of seqmen
2724            8AC4            mov     al-,~;h
2726            E6AA            out     fdc-segment,al ;then high segment 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 Digital 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 segment 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 segments
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-segment    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 segment,(7q ;bdos interruot segment
(additional LOAr)FR initialization)
Pot) (IS        ;restore data segment

------------------------------------------
        '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)igital 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)igital 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 message
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 Proprietary to Digital Research

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

2633            890EAD26                mov dma-adr,rX
2637            C73             ret
                SFTDmAR:                        ;set T)MA segment 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 segment        (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)igital 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

System Memory qeqment Table

26F8 02 seqtabl.e 1b 2  ;2 segments
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 nigital Research

143
CP/M-86 System 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_segment    rw      I
                END

All Information Presented Here is Proprietarv to Digital 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 group memorv
        requirements, 17
segment reqister chanqe, 11
segment 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
