6 <-- Increment revision number when making changes This file contains information and modifications for the CP/M operating system. Pages and/or items are separated with FORMFEEDS (^L) with no more than 60 printed lines per page. List with PIP. A PATCH FOR DDT From Dr. Dobb's Journal, Apr 1983, p. 76 When DDT is invoked it normally relocates itself to high memory just under BDOS. DDT can be modified so that it relocates to a specific address. If you know where you want DDT to load itself, the most direct way is to alter its code. Use DDT to modify DDT.COM. Look at the instructions around 0150h; you should find 0150 SUB A 0151 MOV D,A If you replace those two instructions with the single instruction 0150 MVI D,xx you will have a version of DDT that will always load itself at xx00h in memory. A PATCH FOR DDT / SID From Microsystems, May 1983, p. 82 The Dump command of DDT and SID was designed for use with an 80 column terminal and makes a poor display if used with a 64 column terminal. The following patches allow DDT or SID to give a better appearance on a 64 column terminal. Do the following for DDT vers 2.2: A>ddt ddt.com DDT VER 2.2 NEXT PC 1400 0100 -sa17 0A17 05 08 ...08 instead of 05 0A18 08. -g0 A>save 19 ddt64.com Do the following for SID vers 1.4 A>sid sid.com SID VER 1.4 NEXT PC END 1D00 0100 B3FF #saa5 0AA5 93 96 ... 96 instead of 93 0AA6 08 . #g0 A>save 28 sid64.com What these patches do is throw out the space characters between each display of the hexadecimal representation of each memory content of the DDT or SID "Dump" display. The following is an alternate patch for SID vers 1.4 A>SID SID VERS 1.4 #SA51 0A51 F0 F8 0A52 6F 0A53 11 0A54 BF 5F 0A55 00 . #SAA3 0AA3 0F 7 0AA4 C2 . #G0 A>SAVE 28 SID.COM CP/M BUGS The CP/M BDOS fails to clear Archive Bit t3 in the FCB on Close or Rename of a file. See DDJ, June 1985, p. 14 The values returned by the Rename and Erase function calls are not as described in the CP/M Interface Guide. See DDJ, Nov. 1984, p. 50 BDOS Function 37 (Reset Drive) is unreliable. If Function 37 is called for the DEFAULT (currently logged-in) drive, it is not re logged-in. If the disk in that drive has been changed, the bit map for the former disk is still used and can result in the loss of files. Substitute Function 13 (Reset Disk System) instead. See BYTE, Mar. 1984, p. 70 There is a difference in character processing between standard keyboard I/O and SUBMIT-file I/O. When you enter a command line directly from the keyboard, all control characters (except for several that serve as immediate commands) are echoed back to the terminal in a two character ^x format. However, if the same command line is taken from a submit file, the control characters are sent straight through to the terminal. If that character happens to correspond to a cursor movement or control command for your particular terminal, you may find your output at strange positions or even overlaying previous output thus making it difficult to read. For example, the ^Z end-of-string indicator used by PIP.COM and ED.COM will send the cursor to the top of the screen on some terminals. You could revise your BIOS console output routine to filter the offending characters but this may cause problems with a screen editor or word processor that needs to use cursor positioning commands. ZSID BUGS From DDJ, Oct. 1982, p. 7 ZSID doesn't interpret the LDIR instruction correctly when the operands (the two strings defined by the HL, DE and BC registers) overlap on each other. The LDIR (long move) instruction of the Z-80 copies a source string into a target string. When the target string overlaps on the source string (as when the source begins at 200h, the target at 201h and the length is 255 bytes) LDIR becomes a Replicate instruction, duplicating the leading byte of the source into the target over and over. ZSID doesn't handle it right, though; it stops after copying one byte. Also, the disassembler in ZSID doesn't seem to handle the LD A,R and LD R,A instructions. Its List command won't display them and its Assemble command won't accept them. The number -1 is not correctly interpreted. For example, LD HL,-1 is interpreted as LD HL,00FF. A PATCH FOR ZSID From DDJ, Dec. 1981, p. 4 There is a small hidden bug in ZSID version 1.4. It is easily demonstrated when trying the following: in the direct assembly mode, try to assemble three 16-bit loads with the values of (hex): FF7F, FF80, FFFF Afterwards list the product. The false values are not only used in the assembler, but in the F(ill), M(ove) and D(ump) command as well. The cure is very simple: change the byte at 02AE (hex) in ZSID from "C2" to "C3". SID version 1.4 does not have this "feature", so it may be that the routine starting at 02A1H is, at some place, necessary in the Z-80 specific parts, e.g. for error checking in relative jumps. There are no apparent problems after this patch is installed but, even so, care should be taken if it is used. The following demonstrates the bug and fix: A>ZSID ZSID VERS 1.4 #A100 0100 LD HL,0FF7F 0103 LD HL,0FF80 0106 LD HL,0FFFF 0109 . #L100,108 0100 LD HL,FF7F 0103 LD HL,0080 0106 LD HL,00FF 0109 #IZSID.COM #R NEXT PC END 2900 0100 B9FF #L2A1,2BC 02A1 PUSH DE 02A2 CP 41 02A4 JP NC,0BCF 02A7 CALL 0EAA 02AA LD B,D 02AB LD A,B 02AC CP FF 02AE JP NZ,00B8 02B1 LD A,E 02B2 OR A 02B3 JP P,00B8 02B6 LD B,00 02B8 LD A,E 02B9 POP DE 02BA DEC B 02BB INC B 02BC RET 02BD #S2AE 02AE C2 C3 02AF B8 . #L2AE,2B0 02AE JP 00B8 02B1 #G0 A>SAVE 40 ZSIDP.COM A>ZSIDP ZSID VERS 1.4 #A100 0100 LD HL,0FF7F 0103 LD HL,0FF80 0106 LD HL,0FFFF 0109 . #L100,108 0100 LD HL,FF7F 0103 LD HL,FF80 0106 LD HL,FFFF 0109 #G0 A PATCH FOR ASM.COM ASM.COM permits the use of the dollar sign, "$", as a separator in labels. However, the underline character ,"_", will make a more readable label if it is used as the separator. To use the underline in place of the dollar sign load ASM.COM with DDT and change the byte at address 116CH from 24H to 5FH. Exit DDT and "SAVE 20 ASM1.COM". From XSUB.PAT The following patch to XSUB.COM will eliminate its nasty habit of inserting extra line feeds after each command line which it displays on the console. After installation of the patch, console output will look just like it would if it were actually typed in, instead of double-spaced. Do the following: A>DDT XSUB.COM ;Load old file to memory DDT VERS 2.2 ;Program signs on with version NEXT PC 0400 0100 ; and displays size -S2CF ;Substitute at 2CFH 02CF 0A 24 ;Confirm that 0A is the old value! 02D0 23 . ;Confirm that 23 is the next value! -G0 ;Reboot A>SAVE 3 XSUB1.COM ;Save new file from memory. A PATCH FOR ED.COM From Dr Dobb's Journal, Aug. 1981, p.4 ED.COM interprets an ASCII FORMFEED (0CH) as an imbedded carriage return. ED may be altered to treat FORMFEEDs normally provided some other control character is substituted for control-L (0CH), e.g. ^N. The new control character must be inserted at the following addresses: 0528H, 162FH, and 1A12H The following assembly language program will substitute ^N for ^L and also add a sign-on message to ED.COM. ; EDPATCH.ASM ORG 100H JMP 1B00H ;PRINT SIGNON MESSAGE ORG 0528H DB 0EH ;SUBSTITUTE ^N FOR ^L ORG 162FH DB 0EH ; " ORG 1A12H DB 0EH ; " ORG 1B00H LXI D,IDMESG MVI C,9 ;PRINT STRING CALL 5 JMP 01C0H ;ORIGINAL JUMP AT 0100H, ENTER ED IDMESG: DB 'ED.COM with FORMFEED' DB 0DH,0AH,0DH,0AH DB '$' END Assemble EDPATCH.ASM to generate EDPATCH.HEX and install it with DDT as follows: A>DDT ED.COM DDT VERS 2.2 NEXT PC 1B00 0100 -IEDPATCH.HEX -R G0 A>SAVE 27 ED1.COM A PATCH FOR PIP.COM From 'MICROSYSTEMS', MAY/JUNE 1982, p.6 The PIP feature that will optionally filter all FORMFEEDs (0CH) from a file as it is copied may be altered so that any desired character may be removed during a copy operation. The character to be removed must be patched into PIP.COM (version 1.5) at two locations using DDT as follows: DDT PIP.COM DDT VERS 2.2 NEXT PC 1E00 0100 -SE54 0E54 0C hh hh = unwanted code to be removed 0E55 C2 . -SE64 0E64 0C hh hh = unwanted code to be removed 0E65 CA . -G0 A>SAVE 29 PIPhh.COM A> A PATCH FOR PIP.COM From DDJ, Nov. 1984, p.16 The following patch can be used to force the verify (V) option on at all times. Load PIP.COM with DDT and verify that you have version 1.5 by displaying the memory contents between 0200H and 0240H. Next change the single byte at 0B34H from 1FH to 37H and save as follows: -SB34 0B34 1F 37 0B35 D2 . -G0 A>SAVE 29 PIPV.COM IMPLEMENTING INP: AND OUT: DEVICES IN PIP.COM This is a composite of several variations of the same concept for modifying PIP.COM as found in one or more of the following: From MICROSYSTEMS, July 1983, p.48 From DDJ, May 1984, p. 18 PIPXFR.ASM PIP-I/O.ASM PIP can be used to transfer data between two computers that are connected by serial or parallel ports (or modem). PIP must be modified to perform this function by creating machine language I/O routines and patching them into PIP, so that you may use the INP: and OUT: functions. When you are ready to transmit data, initiate the receiving computer first with the command: PIPIO d:filename.typ=INP: Activate the sending computer with the command: PIPIO OUT:=d:filename.typ,EOF: This method will send only 7-bit ASCII data, so you cannot send 8-bit files or programs without first turning them into .HEX files by using the public domain program UNLOAD.COM or other similar utility. The following routine demonstrates implementing the INP: and OUT: function using a Signetics 2661 USART and will have to be modified for your specific hardware. This example also includes echo handshaking so that the sender does not overrun the receiver. Each time a character is received, it is returned to the sender which waits for the echo before sending the next character. If this is not done, PIP will lose characters at higher baud rates or when it pauses to write it's memory buffer out to disk. The handshaking may not be needed if you use low baud rates, only send files small enough to fit in the buffer and/or use the PIP [B] option. The patch should be installed as follows: Assemble I/OPATCH.ASM to generate I/OPATCH.HEX and install it with DDT.COM as follows A>DDT PIP.COM DDT VERS 2.2 NEXT PC 1E00 0100 -II/OPATCH.HEX -R -G0 A>SAVE 29 PIPIO.COM ;I/OPATCH.ASM ; ;THIS FILE WILL PATCH THE I/O ROUTINES INTO ;PIP FOR CP/M VERSIONS 2.2 AND 3.0 (INP: AND OUT:). ; FALSE EQU 0 TRUE EQU NOT FALSE ; PIP22 EQU TRUE PIP30 EQU FALSE ; IF PIP22 PATCH EQU 110H PATCHEND EQU 1FFH INPJMP EQU 103H OUTJMP EQU 106H INPCHR EQU 109H ENDIF ; IF PIP30 PATCH EQU 188H PATCHEND EQU 1FFH INPJMP EQU 180H OUTJMP EQU 184H ENDIF ; ORG INPJMP JMP INPUT ; ORG OUTJMP JMP OUTPUT ; ORG PATCH ; DATA EQU 84H ;2661 USART PORTS STAT EQU 85H MODE EQU 86H COMM EQU 87H ; INPUT: ;INPUT A CHARACTER LDA INITFLG ORA A CZ INIT ;INIT. USART MAYBE CALL INPLOP ;GET A CHARACTER ANI 7FH ;HIGH BIT MUST BE ZERO ; IF PIP22 STA INPCHR ;SAVE IF CP/M 2.2 ENDIF ; STA SAVCHR ;SAVE HERE ALSO CALL OUTLOP ;RETURN CHAR. TO SENDER IF PIP30 LDA SAVCHR ;NEED CHAR. IN A FOR CP/M 3. ENDIF RET ; ; OUTPUT: ;OUTPUT A CHARACTER MOV A,C STA SAVCHR LDA INITFLG ORA A CZ INIT ;INIT. USART MAYBE ; CALL OUTLOP ;SEND A CHARACTER CALL INPLOP ;AND WAIT FOR ECHO RET ; INPLOP: IN STAT CMA ANI 3 JNZ INPLOP ;LOOP TIL WE HAVE A CHARACTER IN DATA ;THEN GET IT RET ; OUTLOP: IN STAT ANI 1 JZ OUTLOP ;LOOP TIL USART READY FOR CHAR. LDA SAVCHR OUT DATA RET ; INIT: ;OPTIONAL USART INITIALIZATION MVI A,0CEH ;INIT 2661 TO 9600 BAUD, 8 BITS STA INITFLG ;MAKE FLAG NON-ZERO OUT MODE MVI A,03H OUT MODE MVI A,27H OUT COMM IN DATA IN DATA ;CLEAR BUFFER MVI C,9 LXI D,SIGNON ;PRINT THE PATCHED MESSAGE JMP 5 ; SIGNON: DB '2661 SERIAL PORT AT 9600 BAUD', 0DH, 0AH, '$' INITFLG: DB 0 SAVCHR: DB 0 ; LAST EQU $ ; IF (PATCHEND-LAST) SHR 15 ;TEST FOR OVERFLOW ERROR EQU 1/0 ;!PATCH IS TOO LONG !!! ENDIF ; END The following patch for PIP.COM may also be known by several other names: e.g. PIPPATCH.ASM, RPIP.ASM or PIPPTCH2.ASM ; ; XPIP ; ; From a listing in the public domain (SIGM V 44) ; entered and debugged by ; Noor Singh Kalsha ; ; An extension of PIP the standard CP/M utility we've all learned to curse. ; This has all of the features of PIP as well as giving you the ability to ; R(eset) the disk to R/W and do a Q(uick) repeat of the copy. This is very ; good if you need to make several copies of the same file onto different ; disks or if you get an error message on the first copy. ; ; R resets the disks and Q repeats the copy command last given to PIP. ; To use, enter XPIP ; You will get: ; PIP v1.5 with (R)eset disks and (Q)uick repeat ; and the usual "*" prompt ; Enter your normal PIP command line. ; Upon completion if you wish to make another copy to another disk, change the ; disks and hit R. This will reset the disks to R/W without exiting PIP. If ; you then want to duplicate the last PIP command line enter "Q" . The program will then repeat your last command. ; ;INSTALLATION OF XPIP: ; ;ASSEMBLE THIS FILE TO GET XPIP.HEX ;OVERLAY XPIP.HEX ON PIP.COM AS FOLLOWS: ; A>DDT PIP.COM ; IXPIP.HEX ; R ; G0 ; SAVE 29 XPIP.COM ; BDOS EQU 0005H DBUFF EQU 0080H BUFF EQU 1ECBH ;PIP'S INPUT BUFFER CRLF EQU 082EH ;PIP'S INTERNAL CR-LF ROUTINE ; ORG 100H ; JMP SIGNON ; ORG 010AH ; SIGNON: LDA DBUFF ;WAS A COMMAND GIVEN ON THE COMMAND LINE? ORA A LXI D,MSG1 CZ PSTRING ;SIGN ON IF NO COMMAND LINE. JMP 04CEH ;JOIN MAINLINE CODE. ; GETCON: LXI H,BUFF MVI M,80H ;SPECIFY MAX LENGTH OF REPLY XCHG ;BUFFER ADDRESS TO DE MVI C,10 ;BDOS COMMAND TO READ CONSOLE BUFFER CALL BDOS ;ASK BDOS TO DO IT LDA BUFF+1 ;LENGTH OF REPLY CPI 1 ;JUST 1 CHARACTER ENTERED? JNZ GOBAK ;LET PIP PROCESS THE COMMAND IF NOT LDA BUFF+2 ;FIRST (AND ONLY) CHAR TYPED ANI 5FH ;CONVERT LOWER TO UPPER CASE CPI 'Q' ;WAS IT THE REPEAT COMMAND? JNZ GETC1 ;JUMP IF NOT ; ; ; REPEAT COMMAND - RESTORE FIRST 4 CHARS OF THE CONSOLE BUFFER TO ; THEIR FORMER CONTENTS, ECHO THE OLD COMMAND TO ; CONSOLE, RESET DISK SYSTEM, AND LET PIP REPROCESS IT. ; LHLD STASH ;RESTORE LENGTH AND FIRST CHAR TYPED SHLD BUFF+1 LXI D,MSG2 ;'REPEATING...' MESSAGE CALL PSTRING ;WRITE IT TO CONSOLE LXI H,BUFF+1 ;GET LENGTH BYTE MOV C,M ;TO REG BC MVI B,0 INX H ;SET BUFFER START ADDRESS TO HL DAD B ;POINT TO FIRST FREE POSITION IN BUFFER MVI M,'$' ;FLAG END OF LINE WITH A "$" LXI D,BUFF+2 CALL PSTRING ;ECHO LINE MVI C,13 ;BDOS COMMAND TO RESET JMP BDOS ; GETC1: CPI 'R' ;IS IT THE USER SPECIFIED RESET COMMAND? JNZ GOBAK ;LET PIP PROCESS IF NOT ; ; RESET COMMAND - MAKE ALL DISKETTES R/W ; LXI D,MSG3 ;'DISK SYSTEM RESET' MSG CALL PSTRING MVI C,13 ;BDOS COMMAND TO RESET CALL BDOS POP H ;CLEAR STACK JMP 53CH ;REJOIN COMMAND LOOP WITHIN PIP ; GOBAK: LHLD BUFF+1 SHLD 1D6H RET ; PSTRING: MVI C,9 JMP BDOS ; MSG1: DB 0DH,0AH DB 'PIP 1.5 with (R)eset Disks and (Q)uick Repeat' DB 0DH,0AH,'$' ; MSG3: DB 0DH,0AH DB 'Resetting all disks to R/W' DB 0DH,0AH,'$' ; MSG2: DB 0DH,0AH DB 'Repeating: ' DB '$' ; STASH: DW 0000H ;NO INITIAL COMMAND ; ORG 96FH ;PATCH PIP TO VECTOR TO THIS ROUTINE ; JMP GETCON END A PATCH FOR MOVCPM.COM If the version of MOVCPM for CP/M 2.2 is run on a CP/M 1.4 system then a "SYNCHRONIZATON ERROR" will result. To eliminate this problem make the following change at address 0234H: instructions were: change to: 0234 C2 NOP 0235 5A NOP 0236 02 NOP When MOVCPM is run, it compares it's serial number with the serial number of the system it is running on. If the two do not match then a "SYNCHRONIZATION ERROR" will result. To eliminate this problem make the following change at address 02CBH: instructions were: change to: 02CB C2 NOP 02CC 5A NOP 02CD 02 NOP The various modules of CP/M may be found within MOVCPM.COM as follows. This assumes that MOVCPM has the CCP located at 0A00H. If it does not, then change the CCPBIAS equate to whereever it is in your system. If your BIOS is a non-standard size, you will have to change the SIZE equate. You can determine your system size by examining locations 0802 and 0801 of your movcpm program with ddt, then set the SIZE equate accordingly. (Derived from MOVPATCH.ASM by Ron Fowler) SIZE EQU 1A00H CCPBIAS EQU 0A00H MODULE ADDRESS BITMAP ADDRESS ---------------------------------------------------------------- BOOT CCPBIAS-80H CCPBIAS+SIZE-0F0H CCP CCPBIAS CCPBIAS+SIZE-0E0H BDOS CCPBIAS+800H CCPBIAS+SIZE+020H BIOS CCPBIAS+1600H CCPBIAS+SIZE+1E0H A PATCH FOR THE CP/M 2.2 BDOS From Dr. Dobb's Journal, Nov. 1984, p.50 Although the CP/M 2.2 Interface Guide states that the Rename and Erase functions return the values 0, 1, 2, or 3 on a successful operation, in fact CP/M 2.2 returns only 0 on success (and 0FFH on failure). Moreover, the Set Attribute function uses the same exit code, yet the Guide omits any mention of this function's return status value. It is desirable to make the following patch since a program that uses one of these functions may occasionally wish to access the BIOS directory buffer to retrieve the directory fcb for the matched entry. ORG CCP+0F8EH INSTRUCTIONS WERE: NOP MOV A,M NOP RAL NOP RNC NOP XRA A UNDOCUMENTED CP/M FUNCTIONS From DDJ, May 1984, p.16 PIP contains a built-in hardware driver for the physical device IRD: (Intel ReaDer) which was used with the Intel Intellec-8 MDS system. The following actions are performed when each byte is read from the IRD: device during a PIP transfer: 1) The value 0CH is output to port 01H. 2) The value 08H is output to port 01H. This strobes the paper tape reader mechanism. 3) PIP loops until bit 5 of port 01H is set to 1. This is the Ready bit. 4) Finally, the lower 7 bits of port 03H are returned as the input value. Note that if a system does not contain I/O ports 1 or 3, the net effect of all this will be to return a neverending string of 7Fh's. The following IRD: driver code can be found in PIP.COM at address 0996H. MVI A,0CH ;TURN READER ON OUT 01H MVI A,08H ;TURN READER OFF OUT 01H WAIT: IN 01H ;WAIT UNTIL READER HAS CHARACTER RLC RLC RLC RAR JC INPUT ;IF CARRY, THEN DONE (GET CHAR), ELSE LOOP JMP WAIT ;LOOP BACK INPUT: IN 03H ;GET CHARACTER ANI 07FH ;MASK PARITY BIT RET UNDOCUMENTED CP/M FUNCTIONS cont. From DDJ, May 1984, p.17 There is an unfortunate interaction between BDOS funtion 6 console I/O and the rest of the BDOS console I/O calls. Programs should never mix 'normal' BDOS calls with function 6 or BIOS calls. Otherwise, input characters may 'vanish' mysteriously, only to reappear at a later input prompt. Digital Research has a stop-gap patch for the latter problem, but only for MPM II 2.1. They have apparently taken a completely different approach in CP/M 3. In 3.0 they appear to examine characters as they do in 2.2; but if it is not an appropriate control character it is discarded. This is why type-ahead routines which worked with 2.2 will not function at the CCP level in CP/M 3. In CP/M 2.2 there are three sanctioned ways to perform console I/O: via 'normal' BDOS console I/O calls, via BDOS function number 6, and by calling the BIOS directly. In fact, the last two methods do exactly the same thing. We presume Digital Research was preparing us for systems like MP/M and CP/M 3, where accessing the BIOS is a definite 'no-no'. Normal BDOS I/O works as follows: whenever a character is sent out to the console, a check is made for an input character being available; it is tested to see if it is a Control-S. Note that this is the only character that the BDOS is looking for at this time. If it is a Control-S, the BDOS enters a tight loop looking for the next character, which may be for example, a Control-Q to resume output or a Control-C to warm boot. However, if the input character was not a Control-S, it is stored in a one-byte buffer in the BDOS, and the BDOS no longer performs any status checks during output. When the .COM program terminates with a RET to the CCP (as in STAT.COM), the character is still in the BDOS's buffer, and the next BDOS input call will retrieve it first, before calling the BIOS for more characters. If, however, the .COM program terminates with a warm boot, the BDOS is re-loaded, leaving the character buffer empty; hence, one character is gone. The CP/M 2.2 'Raw Console I/O' BDOS function 6 has an additional option. An E register argument of 0FEH merely checks the status of the console, and does not return or delete any pending characters. This is consistent with raw character handling in CP/M 3.0 and MP/M II. However, this function does not work properly because the status is not saved prior to execution of the BDOS exit code. A patch must be made to the BDOS to restore the intended function. The CP/M 2.2 'Reset Disk System' BDOS function 13 returns a result parameter in the A register. A is 0 if no $$$.SUB file is active; otherwise it is nonzero. This is how the CCP knows whether or not to continue from a submit file. However, the function only looks at whether or not the first character of any filename is a dollar sign. This is why you may have noticed some strange extra disk activity and a general sluggishness if you have, for example, a filename beginning with a '$' in your directory. It appears that the CCP attempts to open $$$.SUB, fails, and then attempts to delete $$$.SUB. UNDOCUMENTED CP/M FUNCTIONS cont. From Microsystems, May 1983, p.70 CP/M issues a dummy call to the BIOS 'HOME' routine prior to a directory read. Early versions of the 'CP/M 2.2 Alteration Guide' did not include the following sentence in the description of the SELDSK function of the BIOS: The least significant bit of register E is zero if this is the first occurrence of the drive select since the last cold or warm start. This information can provide a clue to the BIOS that it may need to log-in a disk that has been changed. CP/M SPACE MANAGEMENT by Don Wiss CP/M does not require that the size of a file be specified at the time of creation as space is allocated dynamically as needed. Space that is released as the result of closing a file from which space has been deleted can immediately be used by another file. CP/M maintains three mechanisms for this: the Allocation Bit Map, the File Control Block (FCB) and the File Directory. This description applies to a standard 8 inch SS/SD disk with 241K data space and 2K directory. 1. Allocation Bit Map When a disk is logged-on the BDOS creates an Allocation Bit Map. This is a matrix of 1's and 0's representing each Allocation Unit on the disk. An Allocation Unit is eight logically consecutive sectors (records) or 1024 bytes. The BDOS creates this matrix by searching the Disk Allocation Map area in each FCB (see next paragraph). When BDOS receives a request to create a file it searches the Allocation Bit Map until it finds a bit containing a 0. BDOS then sets the map bit to 1 and places the Allocation Unit number in the map area of the newly created FCB. Each time a write operation is performed the BDOS examines the last alloca- tion unit number and the Next Record number (byte 32) in the FCB. When all eight records (sectors) of an allocation unit have been filled the BDOS searches the Allocation Bit Map for the first bit containing a 0. 2. File Control Block The File Control Block (sometimes called descriptor) is a 36-byte block of RAM containing all the information needed by BDOS to find a file on the disk and to access any specified record. Each FCB corresponds to one extent, which is a logical block of data containing 128 records or 16 Allocation Units. A file is com- prised of at least one, and often more than one, extent. The FCB has a default location in the bottom 256 bytes of memory. If a large file has more than one extent reading operations will cause each directory entry to be brought into this location. However a user program may allocate enough memory in the TPA to hold all of the FCB's of a file simultaneously and include the address of the appropriate FCB as one argument of each access request. 3. File Directory The file directory is on Track 2 of the diskette and contains an entry for each extent of each file. The directory entries are copies of the first 32 bytes of the FCB's. When booting CP/M the contents of the directory are read sequentially from the logged- in disk and the Allocation Bit Map for that drive is recalcu- lated. A request to open a file causes the appropriate directory entry to be copied into the FCB area. If the file has been opened for writing, closing the file causes the BDOS to copy the FCB back to the directory area. The ERAse command does not modify the disk file. It issues a Delete request to BDOS which places an E5 in the first byte of the directory entry to mark it as deleted. BDOS also scans the allocation units in the disk map area of the entry and sets the corresponding bits in the Alloca- tion Bit Map to 0, thereby freeing these units for reuse. UNUSED DISK SECTORS When configuring for 8-inch single-sided single-density disks, CP/M reserves the first two tracks (track 0 and track 1) for the operating system, and the first 16 logical sectors on track 2 for the disk directory. It allocates the remaining disk space to files. The remaining disk space- ten 128 byte sectors on track 2 plus 26 128 byte sectors on tracks 3 through 76, totals 241.75 K. File allocation is done in 1K increments, however. Therefore, on a standard CP/M disk there are 0.75K or six sectors that are never written to or read from by the operating system. The unused sectors are physical sectors 18, 24, 4, 10, 16, and 22 on track 76 (assuming the standard sector skew factor of 6 is employed), corresponding to the last six logical sectors on the disk. These sectors can be very useful for BIOS expansion, disk ID, data encription, or other system level functions. If they are used for BIOS expansion, the cold-start loading and sysgen procedures must be appropriately rewritten.