This is a project notes thread. Feel free to add a note if it
contributes to this particular project.
; bdos ( register_DE register_C -- register_A )
; Call CP/M BDOS fuction.
This is the bdos keyword, which would be used to extend hForth for CP/
M to provide a full ANS FILES wordset.
The highest priority first step is to include an INCLUDED in the
Assembly source, so that the result is a version of hForth that can
INCLUDE extension source right off the bat.
INCLUDED can be used from Forth-94 CORE in minimalist-Forth-94 style,
that is:
BL PARSE FILE-EXT.FS INCLUDED
The following bdos calls are from:
http://www.seasip.demon.co.uk/Cpm/bdos.html
******************************* 0 ***********************
BDOS function 0 (P_TERMCPM) - System Reset
Supported by: CP/M 1, 2, 3; MP/M; Concurrent CP/M.
Entered with C=0. Does not return.
Quit the current program, return to command prompt. This call is
hardly ever used in 8-bit CP/M since the RST 0 instruction does the
same thing and saves four bytes.
******************************* 1 ***********************
BDOS function 1 (C_READ) - Console input
Supported by: All versions
Entered with C=1. Returns A=L=character.
Wait for a character from the keyboard; then echo it to the screen and
return it.
******************************* 2 ***********************
BDOS function 2 (C_WRITE) - Console output
Supported by: All versions
Entered with C=2, E=ASCII character.
Send the character in E to the screen. Tabs are expanded to spaces.
Output can be paused with ^S and restarted with ^Q (or any key under
versions prior to CP/M 3). While the output is paused, the program can
be terminated with ^C.
BDOS function 3 (A_READ) - Auxiliary (Reader) input
Supported by: All CP/M versions except MP/M and Concurrent CP/M
Entered with C=3. Returns A=L=ASCII character
Note that this call can hang if the auxiliary input never sends data.
******************************* 6 ***********************
BDOS function 6 (C_RAWIO) - Direct console I/O
Supported by: CP/M 1.4 and later, with variations
Entered with C=6, E=code. Returned values (in A) vary.
E=0FFh
Return a character without echoing if one is waiting; zero if none
is available. In MP/M 1, this works like E=0FDh below and waits for a
character.
E=0FEh
[CP/M3, NovaDOS, Z80DOS, DOS+] Return console input status. Zero
if no character is waiting, nonzero otherwise.
E=0FDh
[CP/M3, DOS+] Wait until a character is ready, return it without
echoing.
E=0FCh
[DOS+] One-character lookahead - return the next character waiting
but leave it in the buffer.
Values of E not supported on a particular system will output the
character. Under CP/M 2 and lower, direct console functions may
interact undesirably with non-direct ones, since certain buffers may
be bypassed. Do not mix them.
******************************* 7 ***********************
BDOS function 7 - Get I/O byte
Supported by: CP/M 2 and lookalikes. Not supported in MP/M.
Entered with C=7. Returns I/O byte.
Here's a description of how the IOBYTE works.
CP/M 2 Input/Output mapping
Under CP/M 2, input and output device selection are performed by the
BIOS. Some BIOSes may implement a feature called the IOBYTE which
allows the user to change which device the screen, printer etc. output
go to.
The IOBYTE lives at address 3 (in the Zero Page) and should be changed
using BDOS calls 7 and 8 (get/set IOBYTE). The value is bitmapped:
Bits Bits 6,7 Bits 4,5 Bits 2,3 Bits 0,1
Device LIST PUNCH READER CONSOLE
Value
00 TTY: TTY: TTY: TTY:
01 CRT: PTP: PTR: CRT:
10 LPT: UP1: UR1: BAT:
11 UL1: UP2: UR2: UC1:
* BAT = batch mode. Use the current Reader for console input, and
he current List (printer) device as the console output.
* CRT = Standard console (keyboard and terminal screen).
* LPT = Standard line printer.
* PTP = Standard Paper Tape Punch.
* PTR = Standard Paper Tape Reader.
* TTY = Teletype device, eg a serial port.
* UC1 = User defined (ie implementation dependent) console device.
* UL1 = User defined (ie implementation dependent) printer device.
* UPn = User defined (ie implementation dependent) output device.
* URn = User defined (ie implementation dependent) input device.
******************************* 9 ***********************
BDOS function 9 (C_WRITESTR) - Output string
Supported by: All versions
Entered with C=9, DE=address of string.
Display a string of ASCII characters, terminated with the $ character.
Thus the string may not contain $ characters - so, for example, the
VT52 cursor positioning command ESC Y y+32 x+32 will not be able to
use row 4.
Under CP/M 3 and above, the terminating character can be changed using
BDOS function 110.
BDOS function 10 (C_READSTR) - Buffered console input
Supported by: All versions, with variations
Entered with C=0Ah, DE=address or zero.
This function reads characters from the keyboard into a memory buffer
until RETURN is pressed. The Delete key is handled correctly. In later
versions, more features can be used at this point; ZPM3 includes a
full line editor with recall of previous lines typed.
On entry, DE is the address of a buffer. If DE=0 (in CP/M-86 versions
DX=0FFFFh), the DMA address is used (CP/M 3 and later) and the buffer
already contains data:
DE=address: DE=0 / DX=0FFFFh:
buffer: DEFB size buffer: DEFB size
DEFB ? DEFB len
DEFB bytes DEFB bytes
The value at buffer+0 is the amount of bytes available in the buffer.
Once the limit has been reached, no more can be added, although the
line editor can still be used.
If DE=0 (in 16-bit versions, DX=0FFFFh) the next byte contains the
number of bytes already in the buffer; otherwise this is ignored. On
return from the function, it contains the number of bytes present in
the buffer.
The bytes typed then follow. There is no end marker.
BDOS function 11 (C_STAT) - Console status
Supported by: All versions
Entered with C=0Bh. Returns A=L=status
Returns A=0 if no characters are waiting, nonzero if a character is
waiting.
BDOS function 12 - Lift head
Supported by: Version 1
Entered with C=0Ch. Returns HL=0
Has no effect except to return HL=0.
******************************* 12 ***********************
BDOS function 12 (S_BDOSVER) - Return version number
Supported by: Versions 2.0 and later
Entered with C=0Ch. Returns B=H=system type, A=L=version number.
The system type is subdivided into a machine type and a CP/M type. The
machine type occupies the high nibble of the byte; the CP/M type is a
bitmapped field stored in the low nibble.
Machine types: CP/M types: Version numbers:
0 - 8080 Bit 0 set for MP/M 00h - Version 1 (see Lift
Head above)
1 - 8086 Bit 1 set for CP/Net 20h - Version 2.0
2 - 68000/Z8000 (ie:network present) 21h - Version 2.1
Bit 2 set in 16-bit 22h - Version 2.2
multi-user OSes 25h - Version 2.5 (DOS +)
28h - Version 2.8 (Personal
CP/M-80)
For plain CP/M, 30h - Version 3.0 (MP/M II,
MP/M-86)
the CP/M type is 0. 31h - Version 3.1 (CP/M
Plus)
33h - Version 3.3 (Apricot
PCP/M-86)
41h - Version 4.1 (DOSPLUS
1)
50h - Version 5.0 (DOSPLUS
2)
Sources differ on the value returned by DOSPLUS 2. Most sources follow
the Interrupt List and say 60h; my experiments on the real thing say
50h.
Confusingly, CP/M-86 v1.1 returns 0022h (ie, "8080 CP/M v2.2").
It is interesting to note that the version numbers returned by DRDOS
and Novell DOS follow this system; DRDOS 3, 5 and 6 are version 6.x,
Novell DOS 7 is version 7.2 and DR-OpenDOS is version 7.3. However
these systems rather unsportingly fail to provide an INT 0E0h call to
get the version number; you have to use INT 21h with AX=4452h.
BDOS function 13 (DRV_ALLRESET) - Reset discs
Supported by: All versions.
Entered with C=0Dh. Returned values vary.
Resets disc drives. Logs out all discs and empties disc buffers. Sets
the currently selected drive to A:. Any drives set to Read-Only in
software become Read-Write; replacement BDOSses tend to leave them
Read-Only.
In versions 1 and 2, logs in drive A: and returns 0FFh if there is a
file present whose name begins with a $, otherwise 0. Replacement
BDOSses may modify this behaviour.
In multitasking versions, returns 0 if succeeded, or 0FFh if other
processes have files open on removable or read-only drives.
BDOS function 14 (DRV_SET) - Select disc
Supported by: All versions
Entered with C=0Eh, E=drive number. Returns L=A=0 or 0FFh.
The drive number passed to this routine is 0 for A:, 1 for B: up to 15
for P:.
Sets the currently selected drive to the drive in A; logs in the disc.
Returns 0 if successful or 0FFh if error. Under MP/M II and later
versions, H can contain a physical error number.
******************************* 15 ***********************
BDOS function 15 (F_OPEN) - Open file
Supported by: All versions
Entered with C=0Fh, DE=FCB address. Returns error codes in BA and HL.
This function opens a file to read or read/write. The FCB is a 36-byte
data structure, most of which is maintained by CP/M. Look here for
details.
The FCB should have its DR, Fn and Tn fields filled in, and the four
fields EX, S1, S2 and RC set to zero. Under CP/M 3 and later, if CR is
set to 0FFh then on return CR will contain the last record byte count.
Note that CR should normally be reset to zero if sequential access is
to be used.
Under MP/M II, the file is normally opened exclusively - no other
process can access it. Two bits in the FCB control the mode the file
is opened in:
* F5' - set to 1 for "unlocked" mode - other programs can use the
file.
* F6' - set to 1 to open the file in read-only mode - other
programs can use the file read-only. If both F6' and F5' are set, F6'
wins.
If the file is opened in "unlocked" mode, the file's identifier (used
for record locking) will be returned at FCB+21h.
Under MP/M II and later versions, a password can be supplied to this
function by pointing the DMA address at the password.
On return from this function, A is 0FFh for error, or 0-3 for success.
Some versions (including CP/M 3) always return zero; others return 0-3
to indicate that an image of the directory entry is to be found at (80h
+20h*A).
If A=0FFh, CP/M 3 returns a hardware error in H and B. It also sets
some bits in the FCB:
* F7' is set if the file is read-only because writing is password
protected and no password was supplied;
* F8' is set if the file is read-only because it is a User 0
system file opened from another user area.
******************************* 16 ***********************
BDOS function 16 (F_CLOSE) - Close file
Supported by: All versions
Entered with C=10h, DE=FCB address. Returns error codes in BA and HL.
This function closes a file, and writes any pending data. This
function should always be used when a file has been written to.
On return from this function, A is 0FFh for error, or 0-3 for success.
Some versions always return zero; others return 0-3 to indicate that
an image of the directory entry is to be found at (80h+20h*A).
Under CP/M 3, if F5' is set to 1 then the pending data are written and
the file is made consistent, but it remains open.
If A=0FFh, CP/M 3 returns a hardware error in H and B.
******************************* 17 ***********************
BDOS function 17 (F_SFIRST) - search for first
Supported by: All versions
Entered with C=11h, DE=address of FCB. Returns error codes in BA and
HL.
Search for the first occurrence of the specified file; the filename
should be stored in the supplied FCB. The filename can include ?
marks, which match anything on disc. If the first byte of the FCB
is ?, then any directory entry (including disc labels, date stamps
etc.) will match. The EX byte is also checked; normally it should be
set to zero, but if it is set to ? then all suitable extents are
matched.
Returns A=0FFh if error (CP/M 3 returns a hardware error in H and B),
or A=0-3 if successful. The value returned can be used to calculate
the address of a memory image of the directory entry; it is to be
found at DMA+A*32.
Under CP/M-86 v4, if the first byte of the FCB is '?' or bit 7 of the
byte is set, subdirectories as well as files will be returned by this
search.
******************************* 18 ***********************
BDOS function 18 (F_SNEXT) - search for next
Supported by: All versions
Entered with C=12h, (DE=address of FCB)?. Returns error codes in BA
and HL.
This function should only be executed immediately after function 17 or
another invocation of function 18. No other disc access functions
should have been used.
Function 18 behaves exactly as number 17, but finds the next
occurrence of the specified file after the one returned last time. The
FCB parameter is not documented, but Jim Lopushinsky states in
LD301.DOC:
In none of the official Programmer's Guides for any version of CP/
M does it say that an FCB is required for Search Next (function 18).
However, if the FCB passed to Search First contains an unambiguous
file reference (i.e. no question marks), then the Search Next function
requires an FCB passed in reg DE (for CP/M-80) or DX (for CP/M-86).
******************************* 19 ***********************
BDOS function 19 (F_DELETE) - delete file
Supported by: All versions
Entered with C=13h, DE=address of FCB. Returns error codes in BA and
HL.
Deletes all directory entries matching the specified filename. The
name can contain ? marks. Returns A=0FFh if error, otherwise 0-3 (CP/M
3 returns a hardware error in H and B).
Under CP/M 3, if bit F5' is set to 1, the file remains but any
password protection is removed. If the file has any password
protection at all, the DMA address must be pointing at the password
when this function is called.
BDOS function 19 - remove directory
Supported by: CP/M-86 v4.
Entered with C=13h, DE=address of FCB. Returns error codes in BA and
HL.
This function is called with bit 7 of the FCB drive byte set, to
distinguish it from a normal Delete File call.
If the specified subdirectory exists and is empty, removes it.
******************************* 20 ***********************
BDOS function 20 (F_READ) - read next record
Entered with C=14h, DE=address of FCB. Returns error codes in BA and
HL.
Supported by: All versions
Load a record (normally 128 bytes, but under CP/M 3 this can be a
multiple of 128 bytes) at the previously specified DMA address. Values
returned in A are:
0
OK,
1
end of file,
9
invalid FCB,
10
(CP/M) media changed; (MP/M) FCB checksum error,
11
(MP/M) unlocked file verification error,
0FFh
hardware error.
If on return A is not 0FFh, H contains the number of 128-byte records
read before the error (MP/M II and later).
******************************* 21 ***********************
BDOS function 21 (F_WRITE) - write next record
Supported by: All versions
Entered with C=15h, DE=address of FCB. Returns error codes in BA and
HL.
Write a record (normally 128 bytes, but can be a multiple of 128
bytes) to be found at previously specified DMA address. Values
returned in A are:
0
OK,
1
directory full,
2
disc full,
8
(MP/M) record locked by another process,
9
invalid FCB,
10
(CP/M) media changed; (MP/M) FCB checksum error,
11
(MP/M) unlocked file verification error,
0FFh
hardware error.
If on return A is not 0FFh, H contains the number of 128-byte records
written before the error (CP/M 3 only).
******************************* 22 ***********************
BDOS function 22 (F_MAKE) - create file
Supported by: All versions
Entered with C=16h, DE=address of FCB. Returns error codes in BA and
HL.
Creates the file specified. Returns A=0FFh if the directory is full.
If the file exists already, then the default action is to return to
the command prompt, but CP/M 3 may return a hardware error instead.
Under MP/M II, set F5' to open the file in "unlocked" mode.
Under MP/M II and later versions, set F6' to create the file with a
password; the DMA address should point at a 9-byte buffer:
DEFS 8 ;Password
DEFB 1 ;Password mode
******************************* 23 ***********************
BDOS function 23 (F_RENAME) - Rename file
Supported by: All versions
Entered with C=17h, DE=address of FCB. Returns error codes in BA and
HL.
Renames the file specified to the new name, stored at FCB+16. This
function cannot rename across drives so the "drive" bytes of both
filenames should be identical. Returns A=0-3 if successful; A=0FFh if
error. Under CP/M 3, if H is zero then the file could not be found; if
it is nonzero it contains a hardware error number.
Under Concurrent CP/M, set F5' if an extended lock on the file should
be held through the rename. Otherwise the lock will be released.
BDOS function 24 (DRV_LOGINVEC) - Return bitmap of logged-in drives
Supported by: All versions
Entered with C=18h. Returns bitmap in HL.
Bit 7 of H corresponds to P: while bit 0 of L corresponds to A:. A bit
is set if the corresponding drive is logged in.
In DOSPLUS v2.1, the three top bits (for the floating drives) will
mirror the status of the corresponding host drives). This does not
happen in earlier DOSPLUS / Personal CP/M-86 systems.
******************************* 25 ***********************
BDOS function 25 (DRV_GET) - Return current drive
Supported by: All versions
Entered with C=19h. Returns drive in A. Returns currently selected
drive. 0 => A:, 1 => B: etc.
BDOS function 26 (F_DMAOFF) - Set DMA address
Supported by: All versions
Entered with C=1Ah, DE=address.
Set the Direct Memory Access address; a pointer to where CP/M should
read or write data. Initially used for the transfer of 128-byte
records between memory and disc, but over the years has gained many
more functions.
BDOS function 27 (DRV_ALLOCVEC) - Return address of allocation map
Supported by: All versions, but differs in banked versions.
Entered with C=1Bh. Returns address in HL (16-bit versions use ES:BX).
Return the address of the allocation bitmap (which blocks are used and
which are free) in HL. Under banked CP/M 3 and MP/M, this will be an
address in bank 0 (the system bank) and not easily accessible.
Under previous versions, the format of the bitmap is a sequence of
bytes, with bit 7 of the byte representing the lowest-numbered block
on disc, and counting starting at block 0 (the directory). A bit is
set if the corresponding block is in use.
Under CP/M 3, the allocation vector may be of this form (single-bit)
or allocate two bits to each block (double-bit). This information is
stored in the SCB.
BDOS function 28 (DRV_SETRO) - Software write-protect current disc
Supported by: All versions, with differences
Entered with C=1Ch.
Temporarily set current drive to be read-only; attempts to write to it
will fail. Under genuine CP/M systems, this continues until either
call 13 (disc reset) or call 37 (selective disc reset) is called; in
practice, this means that whenever a program returns to the command
prompt, all drives are reset to read/write. Newer BDOS replacements
only reset the drive when function 37 is called.
Under multitasking CP/Ms, this can fail (returning A=0FFh) if another
process has a file open on the drive.
******************************* 29 ***********************
BDOS function 29 (DRV_ROVEC) - Return bitmap of read-only drives
Supported by: All versions
Entered with C=1Dh. Returns bitmap in HL.
Bit 7 of H corresponds to P: while bit 0 of L corresponds to A:. A bit
is set if the corresponding drive is set to read-only in software.
BDOS function 30 - set echo mode for function 1
Supported by: CP/M 1.3 only
Entered with C=1Eh, E=echo mode (0=no echo, else echo).
******************************* 30 ***********************
BDOS function 30 (F_ATTRIB) - set file attributes
Supported by: All versions
Entered with C=1Eh, DE=address of FCB. Returns error codes in BA and
HL.
Set and reset the bits required. Standard CP/M versions allow the bits
F1', F2', F3', F4', T1' (read-only), T2' (system) and T3' (archive) to
be changed. Some alternative BDOSses allow F5', F6', F7' and F8' to be
set, but this is not to be encouraged since setting these bits can
cause CP/M 3 to behave differently.
Under Concurrent CP/M, if the F5' bit is not set and the file has an
extended file lock, the lock will be released when the attributes are
set. If F5' is set the lock stays.
Under CP/M 3, the Last Record Byte Count is set by storing the
required value at FCB+32 (FCB+20h) and setting the F6' bit.
The code returned in A is 0-3 if the operation was successful, or 0FFh
if there was an error. Under CP/M 3, if A is 0FFh and H is nonzero, H
contains a hardware error.
******************************* 31 ***********************
BDOS function 31 (DRV_DPB) - get DPB address
Supported by: CP/M 2 and later.
Entered with C=1Fh. Returns address in HL.
Returns the address of the Disc Parameter Block for the current drive.
See the formats listing for details of the DPBs under various CP/M
versions.
BDOS function 32 (F_USERNUM) - get/set user number
Supported by: CP/M 2 and later.
Entered with C=20h, E=number. If E=0FFh, returns number in A.
Set current user number. E should be 0-15, or 255 to retrieve the
current user number into A. Some versions can use user areas 16-31,
but these should be avoided for compatibility reasons.
DOS+ returns the number set in A.
******************************* 33 ***********************
BDOS function 33 (F_READRAND) - Random access read record
Supported by: CP/M 2 and later.
Entered with C=21h, DE=FCB address. Returns error codes in BA and HL.
Read the record specified in the random record count area of the FCB,
at the DMA address. The pointers in the FCB will be updated so that
the next record to read using the sequential I/O calls will be the
record just read. Error numbers returned are:
0
OK
1
Reading unwritten data
4
Reading unwritten extent (a 16k portion of file does not exist)
6
Record number out of range
9
Invalid FCB
10
Media changed (CP/M); FCB checksum error (MP/M),
11
Unlocked file verification error (MP/M),
0FFh
[MP/M II, CP/M 3] hardware error in H.
******************************* 34 ***********************
BDOS function 34 (F_WRITERAND) - Random access write record
Supported by: CP/M 2 and later.
Entered with C=22h, DE=FCB address. Returns error codes in BA and HL.
Write the record specified in the random record count area of the FCB,
at the DMA address. The pointers in the FCB will be updated so that
the next record to write using the sequential I/O calls will be the
record just written. Error numbers returned are:
0
OK
2
Disc full
3
Cannot close extent
5
Directory full
6
Record number out of range
8
Record is locked by another process (MP/M)
9
Invalid FCB
10
Media changed (CP/M); FCB checksum error (MP/M)
11
Unlocked file verification error (MP/M)
0FFh
[MP/M II, CP/M 3] hardware error in H.
If the record indicated is beyond the end of the file, the record will
be written and the file may contain a gap; attempting to read this gap
may give "reading unwritten data" errors, or nonsense.
******************************* 40 ***********************
BDOS function 35 (F_SIZE) - Compute file size
Supported by: CP/M 2 and later.
Entered with C=23h, DE=FCB address. Returns error codes in BA and HL.
Set the random record count bytes of the FCB to the number of 128-byte
records in the file. Returns A=0FFh if error (file not found, or CP/M
3 hardware error); otherwise A=0.
******************************* 36 ***********************
BDOS function 36 (F_RANDREC) - Update random access pointer
Supported by: CP/M 2 and later.
Entered with C=24h, DE=FCB address.
Set the random record count bytes of the FCB to the number of the last
record read/written by the sequential I/O calls.
BDOS function 37 (DRV_RESET) - Selectively reset disc drives
Supported by: CP/M 2 and later.
Entered with C=25h, DE=bitmap of drives to reset. Returns A=0 if OK,
0FFh if error.
Bit 7 of D corresponds to P: while bit 0 of E corresponds to A:. A bit
is set if the corresponding drive should be reset. Resetting a drive
removes its software read-only status.
BDOS function 38 (DRV_ACCESS) - Access drives
Supported by: MP/M, Concurrent CP/M, CP/Net redirector.
Entered with C=26h, DE=drive bitmap.
Locks one or more disc drives. Processes will not be able to reset
these drives; the effect is the same as if there were open files on
the drives.
Returns A=0 if OK, and 0FFh if there is an error. If there is, H will
contain the error code.
******************************* 40 ***********************
BDOS function 40 (F_WRITEZF) - Write random with zero fill
Supported by: CP/M 2.2 and later.
Entered with C=28h, DE=FCB address. Returns error codes in BA and HL.
As function 34, but if the write is to a newly allocated disc block
the remainder of the block is filled with zeroes.