home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / DRI-archive / roche / cpm80_86.txt < prev    next >
Text File  |  2009-12-11  |  24KB  |  514 lines

  1. CCGFCU.WS4
  2. ----------
  3.  
  4. CP/M-86 Compatibility Guide For CP/M-80 Users   (= CCGFCU...)
  5.  
  6. Copyright (c) 1980 Digital Research
  7. Pacific Grove, California
  8.  
  9. (Revision of 10/21/80)  (= 21 October 1980)
  10.  
  11. (Retyped by Emmanuel ROCHE. Posted in comp.os.cpm in 2003)
  12.  
  13. CP/M-86  is  a single-user operating system for the  Intel  8086
  14. microprocessor.  Since  the  Intel  8088  CPU  is   functionally
  15. equivalent  to the 8086, CP/M-86 is suitable for use  with  both
  16. processors.  The  design philosophy of CP/M-86 follows  that  of
  17. CP/M  for  the  8080,  8085,  and  Z-80  microprocessors,   with
  18. additional facilities to account for the increased address space
  19. of  the  8086 family. The new features  also  allow  application
  20. programs  to  easily  upgrade  to  the  MP/M-86  and   CP/NET-86
  21. environment, where multi-programming and computer networking  is
  22. supported.  This document assumes basic familiarity with the  8-
  23. bit  CP/M  software  product,  and  specifically  describes  the
  24. differences and extensions found in CP/M-86.
  25.  
  26. 1.  CP/M-86 Operational Differences
  27. -----------------------------------
  28.  
  29. CP/M-86   maintains  file  compatibility  with   previous   CP/M
  30. versions,  and provides a familiar environment for the  operator
  31. and  programmer.  Utility programs, such as ED, PIP,  STAT,  and
  32. SYSGEN  operate in the same manner as their 8-bit  counterparts,
  33. while ASM and DDT provide the basic tools for assembly  language
  34. development using the 8086 microprocessor.
  35.  
  36. Under  CP/M-86,  multiple programs are loaded in  "stack  order"
  37. into  memory  for  execution.  Programs  themselves  can   cause
  38. additional programs to be loaded for subsequent execution. Thus,
  39. for  example,  the background DESPOOLing utility  can  first  be
  40. loaded,  followed by execution of DDT. DDT may, in turn, load  a
  41. test  program for a debugging session, and transfer  control  to
  42. the test program between breakpoints. In general, CP/M-86  keeps
  43. account  of  the order in which programs are  loaded  and,  upon
  44. encountering  the  program abort key  (Control-C),  discontinues
  45. execution  of the most recent program activated at  the  console
  46. command  level.  Thus,  in the above case, a  Control-C  at  the
  47. command level first discards DDT and the test program, while the
  48. second  Control-C  aborts  DESPOOL. At  this  point,  subsequent
  49. Control-C  characters are ignored, since there are no  executing
  50. programs activated at the console level.
  51.  
  52. 2.  Memory Organization
  53. -----------------------
  54.  
  55. The  8086 memory addresses range from 00000H to  0FFFFFH,  where
  56. each  memory location holds an 8-bit value, resulting in  a  one
  57. megabyte address space. The following terms are used  throughout
  58. this document when 8086 memory organization is discussed:
  59.  
  60.         Nibble          4-bit half-byte
  61.         Byte            8-bit value
  62.         Word            16-bit value
  63.         Double Word     32-bit value
  64.         Paragraph       16 contiguous bytes
  65.         Segment         Up to 64K contiguous bytes
  66.         Offset          16-bit displacement in a segment
  67.         Group           one or more segments
  68.  
  69. Word  values  are  standard Intel format, with  low  order  byte
  70. stored first in memory. Double words consist of two word  values
  71. in standard format, and often represent an offset followed by  a
  72. paragraph  address. All paragraph addresses are on even  16-byte
  73. boundaries,  and  thus a paragraph address has an  assumed  low-
  74. order nibble value of 0, in order that the address can be stored
  75. in  a word location. The paragraph address 0000H,  for  example,
  76. represents   the  actual  memory  location  00000H,  while   the
  77. paragraph address 0001H becomes the memory location 00010H.
  78.  
  79. CP/M-86 itself consists of the Console Command Processor  (CCP),
  80. the   Basic  Disk  Operating  System  (BDOS),  and   the   user-
  81. configurable  Basic  I/O System (BIOS). All three  portions  are
  82. resident, and are not available as data space after a program is
  83. loaded. CP/M-86 memory consists of a sequence of (possibly) non-
  84. contiguous  areas,  which are addressed by a  memory  management
  85. scheme  within CP/M-86. Up to eight non-contiguous memory  areas
  86. can  be  defined  within the BIOS, in  order  to  provide  basic
  87. allocation  information.  When non-contiguous memory  areas  are
  88. mapped in this manner, the base memory addresses must be on  16-
  89. byte  paragraph  boundaries.  Normally,  however,  8086   memory
  90. consists of contiguous RAM beginning at location zero, and  thus
  91. only one memory area is defined within the BIOS.
  92.  
  93. The  Boot  Loader resides on the first two  system  tracks.  For
  94. future  expansion,  however, the CP/M-86 system itself  is  read
  95. from the CPM.SYS file stored on the system disk. Thus, the  Boot
  96. Loader  contains  a simple version of the  CP/M-86  BDOS,  which
  97. allows  the  CPM.SYS  file to be opened and  read  into  memory,
  98. similar  to  the operation of MP/M. The actual load  address  is
  99. determined  when the Boot Loader is configured. CP/M-86  is  not
  100. normally  operated  in the area from location  0  through  3FFH,
  101. since this area is often used for interrupt vector  information.
  102. For  standardization,  it is suggested that  CP/M-86  be  loaded
  103. beginning  at  location 400H. In any case, the BIOS  memory  map
  104. specifically  excludes the interrupt vector area and the  memory
  105. area  in  which  CP/M-86  resides, so  that  this  area  is  not
  106. available for allocation to user or system programs.
  107.  
  108. 3.  Memory Models
  109. -----------------
  110.  
  111. CP/M-86  loads programs into the Transient Program  Area  (TPA),
  112. using  three  different  memory models  corresponding  to  three
  113. popular memory segmentation techniques. The three models are:
  114.  
  115.         8080 Model
  116.         Small Model
  117.         Compact Model
  118.  
  119. The  8080 Model supports programs which are directly  translated
  120. from  the 8-bit CP/M environment, where code and data areas  are
  121. intermixed. The Small Model is similar to that defined by Intel,
  122. where code and data spaces are separated into two segments of up
  123. to  64K  bytes  each. The Small Model is  suitable  for  use  by
  124. translated  8-bit  programs  where  code  and  data  are  easily
  125. separated. The Compact Model allows execution of programs  which
  126. perform  their  own segment management, allowing  programs  with
  127. code  and data segments which reach the addressing  capacity  of
  128. the host memory configuration. The three models differ primarily
  129. in  the  manner in which the segment registers  are  initialized
  130. upon program loading.
  131.  
  132. In  all  three models, the DS register addresses a  "base  page"
  133. area,  similar  to 8-bit CP/M where various default  values  are
  134. stored.  The base page extends from offset 0000H through  offset
  135. 00FFH  from  the DS register, and contains  the  following  pre-
  136. defined areas:
  137.  
  138.                     +-----+-----+-----+
  139.         DS + 0000H: | LC0 | LC1 | LC2 |
  140.                     +-----+-----+-----+
  141.         DS + 0003H: | BC0 | BC1 | M80 |
  142.                     +-----+-----+-----+
  143.         DS + 0006H: | LD0 | LD1 | LD2 |
  144.                     +-----+-----+-----+
  145.         DS + 0009H: | BD0 | BD1 | xxx |
  146.                     +-----+-----+-----+
  147.         DS + 000CH: | LE0 | LE1 | LE2 |
  148.                     +-----+-----+-----+
  149.         DS + 000FH: | BE0 | BE1 | xxx |
  150.                     +-----+-----+-----+
  151.         DS + 0012H: | LS0 | LS1 | LS2 |
  152.                     +-----+-----+-----+
  153.         DS + 0015H: | BS0 | BS1 | xxx |
  154.                     +-----+-----+-----+
  155.         DS + 0018H: | LX0 | LX1 | LX2 |
  156.                     +-----+-----+-----+
  157.         DS + 001BH: | BX0 | BX1 | xxx |
  158.                     +-----+-----+-----+
  159.         DS + 001EH: | LX0 | LX1 | LX2 |
  160.                     +-----+-----+-----+
  161.         DS + 0021H: | BX0 | BX1 | xxx |
  162.                     +-----+-----+-----+
  163.         DS + 0024H: | LX0 | LX1 | LX2 |
  164.                     +-----+-----+-----+
  165.         DS + 0027H: | BX0 | BX1 | xxx |
  166.                     +-----+-----+-----+
  167.         DS + 002AH: | LX0 | LX1 | LX2 |
  168.                     +-----+-----+-----+
  169.         DS + 002DH: | BX0 | BX1 | xxx |
  170.                     +-----+-----+-----+
  171.         DS + 0030H:         Not
  172.           ...            Currently
  173.         DS + 005BH:         Used
  174.                     +-----------------+
  175.         DS + 005CH: |   Default FCB   |
  176.                     +-----------------+
  177.         DS + 0080H: |  Default Buffer |
  178.                     +-----------------+
  179.         DS + 0100H: | Begin User Data |
  180.                     +-----------------+
  181.  
  182. where each byte is indexed by 0, 1, and 2, corresponding to  the
  183. standard Intel storage convention of low, middle, and high-order
  184. (most significant) byte, and "xxx" marks unused bytes. LC is the
  185. last  code  group  location  (24-bits), while  BC  is  the  base
  186. paragraph  address  of  the code group (16-bits).  In  the  8080
  187. Model, the low order bytes of the LC (LC0 and LC1) never  exceed
  188. 0FFFFH, and the high order byte (LC2) is always zero. It  should
  189. be  noted  that bytes LD0 and LD1 appear in  the  same  relative
  190. positions  of  the base page in both 8-bit  CP/M-80  and  16-bit
  191. CP/M-86, thus easing the program translation task.
  192.  
  193. LD  and BD provide the last position and paragraph base  of  the
  194. data  group. Note that the last position is one byte  less  than
  195. the  group  length.  The M80 byte is equal to 1  when  the  8080
  196. Memory  Model  is  in  use. LE and BE  provide  the  length  and
  197. paragraph  base of the (optional) extra group, while LS  and  BS
  198. give  the  (optional)  stack group length and  base.  The  bytes
  199. marked  LX  and  BX  correspond to  a  set  of  four  (optional)
  200. independent  groups,  which may be required for  programs  which
  201. execute  using the Compact Model. The initial values  for  these
  202. descriptors  are  derived from the header record in  the  memory
  203. image file, described below.
  204.  
  205. 4.  Memory Image File Format
  206. ----------------------------
  207.  
  208. Similar  to 8-bit CP/M, CP/M-86 loads and executes memory  image
  209. files,  with  the  file type "CMD"  corresponding  to  "command"
  210. files.  The command file results from the GENCMD program,  which
  211. accepts  either  Intel  L-modules, or  Intel  8086  "hex"  files
  212. produced using Intel translators or the Digital Research  ASM-86
  213. assembler. A CMD file begins with a header record created by the
  214. GENCMD  program. The header record is a total of 128 bytes,  and
  215. begins with a sequence of one or more group descriptors of  nine
  216. bytes each, with zero fill to the end of the record. The  format
  217. of each descriptor is shown below.
  218.  
  219.           8-bit   16-bit     16-bit     16-bit     16-bit
  220.         +------+----------+----------+----------+----------+
  221.         |G-Form| G-Length |  A-Base  |  G-Min   |  G-Max   |
  222.         +------+----------+----------+----------+----------+
  223.  
  224. where G-Form describes the group form, or has the value zero  if
  225. no  more descriptors follow. If G-Form is non-zero, then the  8-
  226. bit value is decomposed into two fields:
  227.  
  228.                G-Form:
  229.            4-bit    4-bit
  230.         +---------+--------+
  231.         | x x x x | G-Type |
  232.         +---------+--------+
  233.  
  234.         G-Type  Group Type
  235.         ------  ----------
  236.           1     Program Code Group
  237.           2     Independent Data Group
  238.           3     Independent Extra Group
  239.           4     Independent Stack Group
  240.           5     Independent Auxiliary Group #1
  241.           6     Independent Auxiliary Group #2
  242.           7     Independent Auxiliary Group #3
  243.           8     Independent Auxiliary Group #4
  244.          9-14   Unused, but Reserved
  245.           15    Escape Code for Additional Types
  246.  
  247. All  remaining  values  in the group  descriptor  are  given  in
  248. increments of 16-bytes. That is, each value is the high order 16
  249. bits  of  the 20-bit base or length, with an assumed  low  order
  250. nibble  of  zero.  Thus,  allocation  requests  are  always   in
  251. "paragraph"  increments. G-Length gives the actual size  of  the
  252. group.  Given a G-length of 0080H, for example, the size of  the
  253. group is 00800H = 2048 bytes. A-Base defines the base  paragraph
  254. address  for  a  non-relocatable group.  The  group  is  assumed
  255. relocatable  if  A-Base  is 0000H. G-Min and  G-Max  define  the
  256. minimum  and maximum size of the memory area to allocate to  the
  257. group.  Normally,  the value of G-Length, G-Min, and  G-Max  are
  258. identical  for  a group containing object code, but  may  differ
  259. when the group designates a data area. A program which  performs
  260. I/O  processing, for example, may contain a data area  used  for
  261. buffers where the size of the allocated area may vary, depending
  262. upon available storage.
  263.  
  264. The  particular  memory  model used by a  transient  program  is
  265. determined  implicitly by the group descriptors. The 8080  Model
  266. occurs when only a code group is included, since no  independent
  267. data  group  is  named.  The  Small  Model  is  implied  by  the
  268. occurrence  of a code group and a data group, but no  additional
  269. group descriptors. Otherwise, the Compact Model is implied.
  270.  
  271. 5.  Program Initialization
  272. --------------------------
  273.  
  274. Following  program  load, the CCP transfers control  through  an
  275. 8086  Far  Call. The Stack Segment register (SS) is set  to  the
  276. base paragraph address of CP/M-86, while the Stack Pointer  (SP)
  277. references  the current base of the CCP stack. Similar to  8-bit
  278. CP/M,  the  transient program must save these  registers  before
  279. switching to a local stack if return to the CCP is  anticipated.
  280. In this case, the transient program must reinstate the SS and SP
  281. registers,  and execute an 8086 Far Return.  Alternatively,  the
  282. program  may  return control to CP/M-86 through a  call  to  the
  283. BDOS,  using  function code 0, as described below.  The  initial
  284. values of the remaining segment registers upon program load  are
  285. determined by the memory model.
  286.  
  287. When  the  8080 Model is used, the Code Segment  register  (CS),
  288. Data Segment register (DS), and Extra Segment register (ES)  are
  289. set  to the base of the transient program area. The  Instruction
  290. Pointer (IP) is initialized to 0100H. The reserved locations and
  291. initial values for maximum memory size, default FCB, and default
  292. buffer in the base page are in the same relative position as  8-
  293. bit  CP/M.  In particular, the base page is a part of  both  the
  294. code and data space, with the size of memory provided at address
  295. DS+0006H.
  296.  
  297. In  the case of the Small Model, the CS register is set  to  the
  298. base  of  the  code  area, while the DS  and  ES  registers  are
  299. initialized  to  the base paragraph address of  the  data  area.
  300. Again,  the base page addressed by DS and ES correspond  closely
  301. to 8-bit CP/M, in order to simplify translation to CP/M-86. Note
  302. that  the only essential difference between the 8080  Model  and
  303. the Small Model is that code and data must be separate, which is
  304. often  the case with well-structured 8-bit programs.  The  Small
  305. Model  has  the advantage that the code and data  space  is  not
  306. limited to a total of 64K bytes.
  307.  
  308. Finally,  in the case of the Compact Model, the CS, DS,  and  ES
  309. registers are initialized to the base paragraph addresses of the
  310. code,   data,  and  extra  groups,  respectively.  It   is   the
  311. responsibility  of the transient program to manage  the  various
  312. segment  registers from the base page values filled-in when  the
  313. program is loaded by the CCP if any group exceeds 64K bytes,  or
  314. if auxiliary groups are included.
  315.  
  316. 6.  BDOS Function Calls
  317. -----------------------
  318.  
  319. Programmatic interface to CP/M-86 corresponds to 8-bit CP/M with
  320. only  a  few  exceptions, thus allowing  simple  translation  of
  321. existing 8-bit programs to the 8086 environment.
  322.  
  323. The  BDOS  is entered using 8086 interrupt 224,  which  overlaps
  324. that  of Intel's RMX-86 monitor. Register values upon  entry  to
  325. the BDOS are given below:
  326.  
  327.         Function Code   CX
  328.         Byte Parameter  DL
  329.         Word Parameter  DX
  330.  
  331. Addresses  passed  to the BIOS are offset from the  DS  register
  332. which  is positioned at the base of the CP/M-86 data area.  Note
  333. that  the total code and data space required by the  CCP,  BDOS,
  334. and  BIOS is considerably less than 64K, and thus CS and DS  are
  335. placed at the first address of the region occupied by CP/M.
  336.  
  337. Register  content  is not preserved through BDOS  calls.  Values
  338. resulting  from  BDOS  calls  are  returned  in  the   following
  339. registers:
  340.  
  341.         Byte Value              AL
  342.         Word Value              AX and BX
  343.         Double Word Offset      BX
  344.         Segment Address         ES
  345.  
  346. A  number of additional function codes are provided in  CP/M-86.
  347. Note  also that function code (0) has a single  parameter  value
  348. under CP/M-86.
  349.  
  350.         (0) System Reset (Warm Start)
  351.         Restores CP/M-86 to the reset state, with a standard CCP
  352.         prompt.  The parameter value in the DL register has  two
  353.         possible values: if DL = 00H, then the currently  active
  354.         program   is  terminated  (equivalent   to   Control-C).
  355.         Otherwise,  DL  must be 01H, in which case  the  program
  356.         remains  in  memory,  and the  memory  allocation  state
  357.         remains  unchanged. (If DL is neither 00H or 01H, it  is
  358.         currently treated as if it were 00H.)
  359.  
  360.         (50) Direct BIOS Call
  361.         Transfers control through the BDOS to the BIOS, with the
  362.         DX  addressing  a five-byte memory area  containing  the
  363.         BIOS call parameters:
  364.  
  365.                   8-bit    16-bit       16-bit
  366.                 +------+------------+------------+
  367.                 | Func | Value (CX) | Value (DX) |
  368.                 +------+------------+------------+
  369.  
  370.         where  Func  is the BIOS function  number,  starting  at
  371.         zero,  and  Value  (CX) and Value (DX)  are  the  16-bit
  372.         values which would normally be passed directly in the CX
  373.         and  DX  registers  with the BIOS call. The  CX  and  DX
  374.         values  are  loaded into the 8086 registers  before  the
  375.         BIOS call is initiated.
  376.  
  377.         (51) Set DMA Segment Base
  378.         Sets the base register for subsequent DMA transfers. The
  379.         word  parameter  gives  the  paragraph  address  of  the
  380.         referenced  segment.  Note that,  upon  initial  program
  381.         loading, the default segment base is set to DS, and  the
  382.         DMA offset is set to 0080H, which provides access to the
  383.         base page.
  384.  
  385.         (52) Get DMA Base
  386.         Returns  the  double  word value  corresponding  to  the
  387.         current DMA segment base and offset.
  388.  
  389. Several  of  the codes given below reference  a  Memory  Control
  390. Block  (MCB), defined in the transient program, which takes  the
  391. form:
  392.  
  393.                 16-bit     16-bit    8-bit
  394.              +----------+----------+-------+
  395.         MCB: |  M-Base  | M-Length | M-Ext |
  396.              +----------+----------+-------+
  397.  
  398. where  M-Base  and M-Length are either input  or  output  values
  399. expressed  in 16-byte paragraph units, and M-Ext is  a  returned
  400. byte  value, as defined with each function below. Note  that  an
  401. error condition is normally flagged with a 0FFH returned  value,
  402. in order to match the file error conventions of CP/M.
  403.  
  404.         (53) Get Max Mem
  405.         Allocate  the  largest contiguous area of  memory.  Upon
  406.         entry, DX addresses a MCB which will be filled-in by the
  407.         BDOS. If successful, M-Base is set to the base paragraph
  408.         address  of  the  allocated area, and  M-Length  is  the
  409.         paragraph  length  of the allocation. AL has  the  value
  410.         0FFH  upon  return  if  the  requested  memory  is   not
  411.         available, and 00H if the request was successful.  M-Ext
  412.         is   set  to  1  if  there  is  additional  memory   for
  413.         allocation, and 0 if no additional memory is available.
  414.  
  415.         (54) Get Abs Max
  416.         Allocate  the  largest  contiguous memory  area  at  the
  417.         absolute  address given by M-Base. Returned  values  are
  418.         the same as those of function (53).
  419.  
  420.         (55) Get Mem
  421.         Allocate a memory area according to the MCB addressed by
  422.         DX.  In  this  case,  the  allocation  request  size  is
  423.         obtained from M-Length on input. The resulting values of
  424.         the MCB fields are identical to function (53).
  425.  
  426.         (56) Get Abs Mem
  427.         Allocate memory at the absolute address given by M-Base,
  428.         for  the length given by M-Length. The resulting  values
  429.         are identical to function (53).
  430.  
  431.         (57) Free Mem
  432.         Release  the memory area of length M-Length at  location
  433.         M-Base given in the MCB addressed by DX.
  434.  
  435.         (58) Free All
  436.         Release all memory in the CP/M-86 environment  (normally
  437.         used only by the CCP upon initialization).
  438.  
  439.         (59) Program Load
  440.         Load  the  program  in the file  described  by  the  FCB
  441.         addressed  by DX. AX has the value 0000H if the  program
  442.         load was unsuccessful. Otherwise, AX and BX both contain
  443.         the paragraph address of the base page belonging to  the
  444.         loaded program. Note that, upon program load at the  CCP
  445.         level,  the default paragraph address is initialized  to
  446.         the base page of the loaded program, and the default DMA
  447.         address  is initialized to offset 0080H. Note,  however,
  448.         that this is a function of the CCP, and thus a  function
  449.         59 does not initialize these registers. In this case, it
  450.         is  the  responsibility of the  program  which  executes
  451.         function 59 to first execute function 51 to set the  DMA
  452.         base, and then initialize the DS register before passing
  453.         control to the loaded program.
  454.  
  455. In addition to these functions, two specific differences between
  456. 8-bit CP/M and CP/M-86 exist. First, the IOBYTE function is only
  457. accessible  through  the BDOS, as described in  the  8-bit  CP/M
  458. documentation.  Second,  Direct  BIOS calls  are  provided  only
  459. through the BDOS.
  460.  
  461. 7.  BIOS Interface
  462. ------------------
  463.  
  464. The  interface to the CP/M-86 BIOS is identical to  8-bit  CP/M,
  465. with  the addition of four jump vector elements. The  BIOS  jump
  466. vector  consists of a sequence of 3-byte 8086 Near Jumps to  the
  467. individual  subroutines.  The additional BIOS entry  points  are
  468. listed  below,  and  immediately  follow  the  SECTRAN   (Sector
  469. Translate) entry point defined in 8-bit CP/M version 2:
  470.  
  471.         JMP     SETDMAB         ; Set DMA Base segment address
  472.         JMP     GETSEGT         ; Return address of SEGment Table
  473.         JMP     GETIOB          ; Get I/O Byte
  474.         JMP     SETIOB          ; Set I/O Byte
  475.  
  476. Entry points receive their first parameter in CX, and (optional)
  477. second parameter in DX. Values are returned as described in  the
  478. BDOS interface, above.
  479.  
  480. SETDMAB  (Set  DMA  Base) sets the base  paragraph  address  for
  481. subsequent DMA operations.
  482.  
  483. The  GETSEGT  returns  the offset to  the  BIOS-resident  Memory
  484. Region Table (MRT). The Memory Region Table has the form:
  485.  
  486.                8-bit
  487.              +-------+
  488.         MRT: | R-Cnt |
  489.              +---------------+---------------+
  490.           0: |     R-Base    |    R-Length   |
  491.              +---------------+---------------+
  492.           1: |     R-Base    |    R-Length   |
  493.              +---------------+---------------+
  494.                             ...
  495.              +---------------+---------------+
  496.           n: |     R-Base    |    R-Length   |
  497.              +---------------+---------------+
  498.                    16-bit         16-bit
  499.  
  500. where R-Cnt is the number of memory region descriptors (equal to
  501. n+1  in the above diagram), while R-Base and R-Length  give  the
  502. paragraph base and length of each physically contiguous area  of
  503. memory,  not including the interrupt vector addresses  (0-3FFH),
  504. or  the area of memory where CP/M-86 resides. If all  memory  is
  505. physically  contiguous, R-Cnt = 1 and n = 0. In this  case,  the
  506. single region descriptor normally addresses the first  paragraph
  507. beyond  the  last BIOS address, with an  R-Length  which  allows
  508. access to the highest paragraph address in the region.
  509.  
  510. The GETIOB and SETIOB entry points return and change the IOBYTE,
  511. as defined in 8-bit CP/M. The IOBYTE value itself is  maintained
  512. in the BIOS.
  513.  
  514. EOF