Subject: Re: CP/M survey
From: Sridhar Ayengar <ploopster at gmail.com>
Date: Thu, 19 Apr 2007 03:20:51 -0400
To: General Discussion: On-Topic and Off-Topic Posts <cctalk at
classiccmp.org>
Dave McGuire wrote:
On Apr 18, 2007, at 4:43 PM, Jules Richardson
wrote:
Interesting; did CP/M ship with a range of UART
and FDC drivers then,
so you just tell it what particular ICs you're using and at what port
addresses, and away it goes? Or was it more complex than that, and
realistically you'd have to write your own comms / FDC driver which
exposed some defined interface to CP/M itself?
The CP/M distribution, as shipped only boots & runs on one particular
type of machine: an Intel MDS-800 development system. If you (or a
computer manufacturer, say Kaypro for example) wanted your machine to
run CP/M, and it wasn't exactly like the MDS-800 in terms of what I/O
chips were used and at what addresses, you had to write the drivers to
support your hardware. These drivers form the BIOS. CP/M was shipped
with the intention that users would write their own BIOS code to support
their own systems.
In truth it is really not all that difficult. The BIOS interface is
very simple and well-defined. Under the tutelage of an experienced
mentor, I was writing BIOS code on my Imsai when I was about fourteen.
It's nothing like the complexity of, say, a device driver system for an
implementation of UNIX.
How does it differ? Aren't all drivers just fundamentally open, close,
read, write and ioctl?
Not under CP/M.
this is the bios call entry table.
;
; perform following functions
; boot cold start
; wboot warm start (save i/o byte)
; (boot and wboot are the same for mds)
; const console status
; reg-a = 00 if no character ready
; reg-a = ff if character ready
; conin console character in (result in reg-a)
; conout console character out (char in reg-c)
; list list out (char in reg-c)
; punch punch out (char in reg-c)
; reader paper tape reader in (result to reg-a)
; home move to track 00
;
; (the following calls set-up the io parameter block for the
; mds, which is used to perform subsequent reads and writes)
; seldsk select disk given by reg-c (0,1,2...)
; settrk set track address (0,...76) for subsequent read/write
; setsec set sector address (1,...,26) for subsequent read/write
; setdma set subsequent dma address (initially 80h)
;
; (read and write assume previous calls to set up the io parameters)
; read read track/sector to preset dma address
; write write track/sector from preset dma address
;
; jump vector for indiviual routines
jmp boot
wboote: jmp wboot
jmp const
jmp conin
jmp conout
jmp list
jmp punch
jmp reader
jmp home
jmp seldsk
jmp settrk
jmp setsec
jmp setdma
jmp read
jmp write
jmp listst ;list status
jmp sectran
;
The relevent ones for char IO are conin, conout, constat, list, listst,
punch, reader.
Disk or any block addressable device is seldsk, settrk, setsec, setdma,
read, write and sectran. While the names are descriptive they do not
adaquately tell you what the task is. For example SELDSK selects a disk
and to do that was do several things like save the number of the drive
to be used and return a pointer to a table (DPH or disk parameter table)
of addresses of information and scratch areas needed for that disk. One
very important address in that table is the DPblock which actually descibes
the size, CHS organization and allocation block size of the reference drive.
The BDOS uses these to compute the calls to seltrk(set track) and
selsec(set sector) that will be used for reading or writing.
These are in unix terms the very rawest level device calls.
What CP/M is/does is provice three major functions.
CCP, console command processor and simple monitor that is the user
interface.
BDOS, this does "high level" stuff like open a file, get a char, put a char
put a char to list device and other filesystem and IO sundries.
BIOS, this is the layer that translates a standard set of calls from the
BDOS to perform things that are very hardware specific. Modern term
is hardware abstraction layer. The bios tried to make the various
different disk controllers and connected disks and serial/parallel
devices looks like very standardized but elementary IO.
What you call a driver in *nix is the BDOS level calls in CP/M for equivilent
level of functionality.
included is the BDOS command dispatch table from CP/M2 (8080):
;
; command dispatch table
DISTBL: DEFW WBOOTF ; 0: System reset
DEFW REDCON ; 1: Console input
DEFW WRTCON ; 2: Console output
DEFW XRQ ; 3: Reader input
DEFW XRQ ; 4: Punch output
DEFW LISTF ; 5: List output
DEFW DIRTIO ; 6: Direct console I/O
DEFW GETIOB ; 7: Get I/O Byte
DEFW PUTIOB ; 8: Set I/O Byte
DEFW PRNBUF ; 9: Print string
DEFW REDBUF ; 10: Read console buffer
DEFW GCSTAT ; 11: Get console status
DEFW GETVER ; 12: Return version number
DEFW RESET ; 13: Reset disk system
DEFW LOGIN ; 14: Select disk
DEFW OPEN ; 15: Open file
DEFW CLOSE ; 16: Close file
DEFW SEAR1 ; 17: Search for first
DEFW SEARN ; 18: Search for next
DEFW DELETE ; 19: Delete file
DEFW READ ; 20: Read sequential
DEFW WRITE ; 21: Write sequential
DEFW CREATE ; 22: Make file
DEFW RENAME ; 23: Rename file
DEFW GLOGIN ; 24: Return login vector
DEFW GETDRV ; 25: Return current disk
DEFW DMASET ; 26: Set DMA address
DEFW GALLOC ; 27: Get addr (alloc)
DEFW MAKRO ; 28: Write protect disk
DEFW GROVEC ; 29: Get R/O vector
DEFW SETATT ; 30: Set file attributes
DEFW GETPAR ; 31: Get addr (disk parms)
DEFW MODUSR ; 32: Set/Get user code
DEFW REDRND ; 33: Read random
DEFW WRTRND ; 34: Write random
DEFW FILSIZ ; 35: Compute file size
DEFW SETRND ; 36: Set random record
DEFW RESDRV ; 37: Reset drive
DEFW XRQ ; 38: Undefined - go back
DEFW XRQ ; 39: Undefined - go back
DEFW ZERRND ; 40: Fill random file w/ zeros
;
To wrap up:
The cpm prompt A:>edit fred.txt causes the CCP to do this>>
call bdos open and see if edit exists, if it does it does several read
sequential andd loads the read file startin at 100h in memory and
jumps to it. *runs edit*
That program calls the bdos open to see if fred.txt exits, if yes it
loads it's buffer(s) as needed with further bdos calls. IF not then it
may create a file entry and allocate a block to it for future storage use.
Of course the bdos makes a pile of calls to gets and put characters, check
the console device for any keys pressed and outputting characters as well
as disk related IO.
Very un *nix like. Likely more than anyone wanted to know but while
CP/M is pervasive not everyone is familiar or familiar to the code
level.
Allison