Last: 11:56 AM 10/8/2009
PREV: 3:57 PM 8/1/2006
INIT: 7:57 AM 10/30/2005
File: CPM_NOTE.TXT
BY: s_dubrovich@yahoo.com

Implementation notes:  Note that the early filesystem was
based on the IBM 8" floppy disk geometry of 128 byte sectors,
by 26 SPT by 77 Tracks.  This is 2002 sectors, or 256256 
bytes of potential storage, or 250.25 K.  Since a byte can
represent a value in the range of 0..255, a one byte block 
number is sufficient if a block represents a size of 1K,
which was the early design.  The early filesystem had
1 byte block numbers in the FCB disk map structure, with
a storage block size of 1 k.  So a single FCB entry in the
disk directory represented 16k of disk storage space
potentially, and that 16k size is, by design, the fixed
size of an FCB 'extent'.  For a file larger than 16k,
another 'extent' is opened, meaning that another additonal
FCB is created in the directory.  Thus, in the early version
of the filesystem, there is a FCB directory entry for each
16k of a file's size, that is, each 'extent'.

Initially 5 1/4" floppy drives came single sided with 160k of
potential storage as: 512 byte sectors by 8 sectors per track
by 40 tracks.

When 5 1/5" floppy drives became available in double sided
form of 8 sectors per track, 40 track, 512 bytes sectors, 2
sides, the potential storage went to 320k.  This is too large
for single byte block numbers of 1k block size to be
represented as original in the FCB entry.

Version 2 of CP/M-80 incorporated an algorithm to scale-up
to larger storage sizes of media.  'Extents' still held their
absolute size of 16k.  Single byte block numbers in the FCB
disk map could now be double byte.  Additional block sizes 
were allowed to be represented; 2k, 4k, 8k, or 16k in size.
The link between 1 FCB per extent was vanquished, actually,
with a 16k block size and word sized block numbers, 8 extents
per FCB would result in the FCB disk map area.  The other
constant kept was the CP/M Record Size of 128 bytes.  The 
internals of CP/M are dependent on this data size in many
ways.  Larger data sets, say 512 byte sectors, must be 'de-
chunked', (deblocked) down into the CP/M record size of 80h.

Per CP/M-80 File Control Blocks, and CP/M Record Size:
------------------------------------------------------
8 meg file size max is 65536 records of 128 bytes each.
  = 8 x 1K x 1K.  65536 = FFFFh + 1.
However, the random record number could be > FFFFh.
Which it is in later versions.

The Word_sz block number x the Block Size is the maximum 
addressable storage issue. At 4k blksz, 64k blks X 4k =
 256MB per Volume.

Reel number == Extent number @fcb[12d], max val 0-31.
Reel constant size @ 16k x 32 max = 512k, ck MOD max ?= 16d?
internal division of file into 16k extents.

If max MOD is 64 then == 32mb.  Max mod = 16d for 8mb.

FCB's are stored in a directory on disk and brought into working
 memory by OPEN or MAKE file functions.


-= Early Version Filesystem =-

cp/m80 v1 - FDOS V.3 based on 1K blksz, 
floppy w/ 26spt x 77trks x 128 byte sectors -- 8" diskettes.
This is the IBM format type that is the original standard.
Because the Floppy Controller moved data by this sector size,
the standard CP/M record size is 128 bytes.

ARECORD = (trk# x 26 spt) + offset record[sector of 128 bytes].
  -Originally equated to the sector number on media with 128
   byte sectors and equaled the dma buffer size required by
   the diskette controller.

VRECORD [NR] is File Record Number @FCB[32], a byte, this is a
  relative index and is outside the directory record for the file, 
  so if another fcb for the same file is required to be read
  in from the disk, it won't overlay the record index value.
  This value is a pre-increment index into the current Extent
  and has a max value of 80h [128d], such that an extent
  represents 16K.

-= FCB v1.3 =-

ET db 0 ;Entry Type, assumed zero, currently not used.
FN db 'filename' ;8 bytes ascii file name
FT db 'typ'      ;3 bytes ascii file type
EX db 0 ;Extent Value, in this version each directory entry
        ; is an extent because the allocation block size is
        ; 1K, and there are 16 entries in the FCB Disk Map.
        ; The cp/m holds to the constant of an extent = 16k.
na db 0,0 ; 2 bytes unused in this version.
RC db 0   ; Record Count is current extent size. 0-128 cpm 
          ;  records, of 128 bytes each (constant).
DM db by 16 ; is the Disk Map of storage blocks for this FCB.
NR db 0 ; This byte is a scratch byte index of the next
        ;  Record of the current extent to read or write to.
        ; This byte isn't recorded when the FCB is rewritten 
        ; back to the Disk Directory.
  ;;Not discussed in this early version is the following 3 byte
  ;; random record number.
R0,R1,R2 db 0.

;;-----------------------
;; Important Calculations  Ref. 3.4 Random Access.

Given an Absolute (CP/M) Record number [AR], the Extent [E]
 number, within which to look for it, is given as:

  [E] = (AR / 128) or, [E] = SHR (AR by 7).

This Extent Number is then placed in the EX field before the 
 FCB Segment is opened.

The NR (index) [NI] of the Extent is then computed as:
  [NI] = AR MOD 128 or, [NI] = AR AND 7Fh.
 
Hint: "When the programmer expects considerable cross_segment
       [extent] accesses, it may save time to create an FCB 
      for each of the 16K segments, open all segments for
      access, and compute the relevant FCB from the 
      absolute record number" AR.

;;Note:  Later Versions are complicated by variable disk
  storage types with parameters other than the 8 inch IBM
  Format, which require additional calculations to map other
  track numbers, sector sizes larger than 128 bytes, sectors 
  per track, and storage block sizes beyond 1K, to the CP/M
  FCB scheme.

;;Vote: Version 3.  allows a 3 byte Random Record Number at
   FCB[33,34,35] with a valid range of 0..262,143 (0..3FFFFh)
   and a maximum file size of 32 megabytes, and a max drive
   capacity of 128MB for a 4K block size.

;;-----------------------

RCount @FCB[15] holds the max cpm_record of the last extent
 addressed by this FCB record, if the block size is 1K then 
this FCB record pertains to 1 extent [16 entries in the 
Disk Map Field with single byte block numbers].  On other 
storage sizes, which require word size block numbers, there 
are 8 entries in the DM Field, so for 4k blksz, there are 2 
extents represented in the Disk Map by that FCB record.  When
more than one 16K extent is represented by a FCB record, then
an Extent Mask calculation comes into play.

[cpm80 V2,+] The RCount value pertains to the latter Extent, 
the prior extent is full.  Because 16K is an Extent size 
constant, the max value for RCount is 80h, and actually
indicates that the next extent needs to be opened. (Limit
overflow). [0..7Fh, 80h cpm_records of 128 bytes = 16K].

Another view of RC is that it is the size of the currently
addressed extent.  The file size is the product of 16K times
the number of prior [full] extents, Plus, the current extent
RC times 128 bytes.

;;----------------------

See CP/M-80 Operating System Manual, Section 5, Sys Interface -
 -V2-

CP/M is logically divided into 4 parts:
  BIOS,BDOS,CCP,TPA.

The BIOS and BDOS are logically combined into a single module
 with a common entry point and referred to as the FDOS.

The CCP is a distinct program that uses the FDOS to provide a 
human-oriented interface with the information that is cataloged
on the back-up storage device.  The TPA is an area of memory, 
not used by the FDOS and CCP, where various nonresident 
operating system commands and user programs are executed. 
[i.e. Loaded and Ran in the TPA space. NOTE: Because the CCP 
is a distinct program, it can be modified, replaced.]

The BDOS has at least the primitives:
-SEARCH for disk file.
-OPEN open a file for further processing.
-CLOSE
-RENAME
-READ  reads a record from a particular file.
-WRITE writes a record to a particular file.
-SELECT selects a particular drive.

The CCP provides these builtin commands:
-ERA erase
-DIR lists files
-REN rename a file
-SAVE save a block of memory to a file.
-TYPE lists the contents of a file on the logged disk,
      regarding printable Text files.

=======eof=======